Changeset: b5057f357e87 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/b5057f357e87
Modified Files:
        clients/mapilib/mapi.c
        sql/backends/monet5/sql_statement.c
Branch: default
Log Message:

Merge with Aug2024 branch.


diffs (198 lines):

diff --git a/clients/mapilib/mapi.c b/clients/mapilib/mapi.c
--- a/clients/mapilib/mapi.c
+++ b/clients/mapilib/mapi.c
@@ -519,7 +519,7 @@
  * zero is returned upon encountering an error or when the database value
  * is NULL; this can be analyzed in using @code{mapi\_error()}.
  *
- * @item size_t mapi_fetch_fiels_len(MapiHdl hdl, int fnr)
+ * @item size_t mapi_fetch_field_len(MapiHdl hdl, int fnr)
  *
  * Return the length of the C-string representation excluding trailing NULL
  * byte of the value.  Zero is returned upon encountering an error, when the
diff --git a/documentation/source/manual_pages/monetdbd.rst.in 
b/documentation/source/manual_pages/monetdbd.rst.in
--- a/documentation/source/manual_pages/monetdbd.rst.in
+++ b/documentation/source/manual_pages/monetdbd.rst.in
@@ -251,6 +251,17 @@ using the **set** command. The following
    use redirects instead of proxies. Changing this property takes effect
    immediately at runtime.
 
+**keepalive**
+   Specifies the keepalive interval for incoming connections. If this is
+   set to a positive number, *monetdbd* configures the system to send
+   automatic periodic keepalive probes on all client connections. This
+   can help keep firewalls from killing connections that seem idle but
+   are in fact waiting for a long running query to finish. The default
+   is 60 seconds. When 127 consecutive probes have failed, the
+   connection is closed. With the default setting of 60 seconds this
+   means the connection is closed when the client has been unreachable
+   for more than two hours.
+
 REMOTE DATABASES
 ================
 
diff --git a/sql/backends/monet5/sql_statement.c 
b/sql/backends/monet5/sql_statement.c
--- a/sql/backends/monet5/sql_statement.c
+++ b/sql/backends/monet5/sql_statement.c
@@ -698,7 +698,7 @@ stmt_bat(backend *be, sql_column *c, int
                sqlstore *store = tr->store;
 
                if (c && isTable(c->t)) {
-                       BUN rows = (BUN) store->storage_api.count_col(tr, c, 
QUICK);
+                       BUN rows = (BUN) store->storage_api.count_col(tr, c, 
RDONLY);
                        setRowCnt(mb,getArg(q,0),rows);
                }
        }
diff --git a/sql/server/rel_unnest.c b/sql/server/rel_unnest.c
--- a/sql/server/rel_unnest.c
+++ b/sql/server/rel_unnest.c
@@ -3603,7 +3603,7 @@ rewrite_exists(visitor *v, sql_rel *rel,
                                exp_label(v->sql->sa, le, ++v->sql->label);
                        le = exp_ref(v->sql, le);
 
-                       if (depth == 1 && is_ddl(rel->op)) { /* exists is at a 
ddl statement, it must be inside a relation */
+                       if (depth >= 1 && is_ddl(rel->op)) { /* exists is at a 
ddl statement, it must be inside at least a relation */
                                sq = rel_groupby(v->sql, sq, NULL);
                                sql_subfunc *ea = sql_bind_func(v->sql, "sys", 
is_exists(sf)?"exist":"not_exist", exp_subtype(le), NULL, F_AGGR, true, true);
                                le = rel_groupby_add_aggr(v->sql, sq, 
exp_aggr1(v->sql->sa, le, ea, 0, 0, CARD_AGGR, 0));
diff --git a/sql/test/BugTracker-2024/Tests/7582-ddl-exists.test 
b/sql/test/BugTracker-2024/Tests/7582-ddl-exists.test
new file mode 100644
--- /dev/null
+++ b/sql/test/BugTracker-2024/Tests/7582-ddl-exists.test
@@ -0,0 +1,3 @@
+statement ok
+CREATE OR REPLACE FUNCTION test () RETURNS boolean
+BEGIN RETURN CASE WHEN EXISTS (SELECT id FROM sys._tables) THEN TRUE ELSE 
FALSE END; END;
diff --git a/sql/test/BugTracker-2024/Tests/All 
b/sql/test/BugTracker-2024/Tests/All
--- a/sql/test/BugTracker-2024/Tests/All
+++ b/sql/test/BugTracker-2024/Tests/All
@@ -91,3 +91,4 @@ 7572-max-length-changes
 7570-timestamp-str
 7574-startswith-bug
 7580-date-diff
+7582-ddl-exists
diff --git a/tools/merovingian/ChangeLog.Aug2024 
b/tools/merovingian/ChangeLog.Aug2024
--- a/tools/merovingian/ChangeLog.Aug2024
+++ b/tools/merovingian/ChangeLog.Aug2024
@@ -1,3 +1,8 @@
 # ChangeLog file for sql/src/backends/monet5/merovingian
 # This file is updated with mchangelog
 
+* Mon Oct  7 2024 Joeri van Ruth <joeri.van.r...@monetdbsolutions.com>
+- Tweak socket parameters to simulate network activity on client connections.
+  This prevents firewalls from killing connections that seem idle but are
+  actually waiting for a long-running query. Can be controlled with a new
+  'keepalive' option to monetdbd.
diff --git a/tools/merovingian/daemon/client.c 
b/tools/merovingian/daemon/client.c
--- a/tools/merovingian/daemon/client.c
+++ b/tools/merovingian/daemon/client.c
@@ -18,6 +18,7 @@
 #include <sys/un.h>
 #include <netdb.h>
 #include <netinet/in.h>
+#include <netinet/tcp.h>
 #ifdef HAVE_POLL_H
 #include <poll.h>
 #endif
@@ -57,6 +58,8 @@ struct clientdata {
        char challenge[32];
 };
 
+static void configureKeepAlive(int sock, int keepalive);
+
 static void *
 handleClient(void *data)
 {
@@ -80,6 +83,7 @@ handleClient(void *data)
        int sock;
        bool isusock;
        struct threads *self;
+       int keepalive;
 
 #ifdef HAVE_PTHREAD_SETNAME_NP
        pthread_setname_np(
@@ -94,6 +98,11 @@ handleClient(void *data)
        self = ((struct clientdata *) data)->self;
        memcpy(chal, ((struct clientdata *) data)->challenge, sizeof(chal));
        free(data);
+
+       keepalive = getConfNum(_mero_props, "keepalive");
+       if (keepalive > 0 && !isusock)
+               configureKeepAlive(sock, keepalive);
+
        fdin = socket_rstream(sock, "merovingian<-client (read)");
        if (fdin == NULL) {
                self->dead = true;
@@ -661,3 +670,37 @@ error:
        }
        return(newErr("accept connection: %s", msg));
 }
+
+static void
+configureKeepAlive(int sock, const int keepalive)
+{
+       // It seems that on MacOS, TCP_KEEPIDLE is called TCP_KEEPALIVE.
+       // (Not to be confused with SO_KEEPALIVE).
+       int flag;
+       #if !defined(TCP_KEEPIDLE) && defined(TCP_KEEPALIVE)
+       flag = TCP_KEEPALIVE;
+       #else
+       flag = TCP_KEEPIDLE;
+       #endif
+       if (setsockopt(sock, IPPROTO_TCP, flag, &keepalive, sizeof(keepalive)) 
< 0) {
+               Mlevelfprintf(WARNING, _mero_ctlerr, "could not set 
TCP_KEEPIDLE on socket: %s\n", strerror(errno));
+               return;
+       }
+
+       if (setsockopt(sock, IPPROTO_TCP, TCP_KEEPINTVL, &keepalive, 
sizeof(keepalive)) < 0) {
+               Mlevelfprintf(WARNING, _mero_ctlerr, "could not set 
TCP_KEEPINTVL on socket: %s\n", strerror(errno));
+               return;
+       }
+
+       const int keepcnt = 127; // fixed value, maximum allowed
+       if (setsockopt(sock, IPPROTO_TCP, TCP_KEEPCNT, &keepcnt, 
sizeof(keepcnt)) < 0) {
+               Mlevelfprintf(WARNING, _mero_ctlerr, "could not set TCP_KEEPCNT 
on socket: %s\n", strerror(errno));
+               return;
+       }
+
+       const int enabled = 1;
+       if (setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &enabled, 
sizeof(enabled)) < 0) {
+               Mlevelfprintf(WARNING, _mero_ctlerr, "could not set 
SO_KEEPALIVE on socket: %s\n", strerror(errno));
+               return;
+       }
+}
diff --git a/tools/merovingian/daemon/merovingian.c 
b/tools/merovingian/daemon/merovingian.c
--- a/tools/merovingian/daemon/merovingian.c
+++ b/tools/merovingian/daemon/merovingian.c
@@ -461,6 +461,7 @@ main(int argc, char *argv[])
 #else
                {"snapshotcompression", strdup(".tar"),     0,                 
STR},
 #endif
+               {"keepalive",     strdup("60"),            60,                 
INT},
 
                { NULL,           NULL,                    0,                  
INVALID}
        };
diff --git a/tools/merovingian/daemon/monetdbd.1.in 
b/tools/merovingian/daemon/monetdbd.1.in
--- a/tools/merovingian/daemon/monetdbd.1.in
+++ b/tools/merovingian/daemon/monetdbd.1.in
@@ -388,6 +388,20 @@ approach, but still hides away the mserv
 Hence, in practice it is only relevant for connections to remote
 databases to use redirects instead of proxies.
 Changing this property takes effect immediately at runtime.
+.TP
+.B keepalive
+Specifies the keepalive interval for incoming connections.
+If this is set to a positive number,
+.I monetdbd
+configures the system to send automatic periodic keepalive
+probes on all client connections. This can help keep firewalls
+from killing connections that seem idle but are in fact waiting
+for a long running query to finish.
+The default is 60 seconds.
+When 127 consecutive probes have failed, the connection is closed.
+With the default setting of 60 seconds this means the connection
+is closed when the client has been unreachable for more than two
+hours.
 .SH REMOTE DATABASES
 .B Deprecation notice:
 This feature is deprecated and may be removed in the future.
_______________________________________________
checkin-list mailing list -- checkin-list@monetdb.org
To unsubscribe send an email to checkin-list-le...@monetdb.org

Reply via email to