Changeset: 0685c9d0e19d for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/0685c9d0e19d
Modified Files:
        sql/server/sql_atom.c
        sql/server/sql_parser.y
        sql/storage/store.c
Branch: cleanup_types
Log Message:

merged with default


diffs (truncated from 9253 to 300 lines):

diff --git a/clients/ChangeLog b/clients/ChangeLog
--- a/clients/ChangeLog
+++ b/clients/ChangeLog
@@ -1,3 +1,12 @@
 # ChangeLog file for clients
 # This file is updated with Maddlog
 
+* Wed Jan 10 2024 Sjoerd Mullender <sjo...@acm.org>
+- Implemented interrupt handling in mclient.  When using mclient
+  interactively, an interrupt (usually control-C) stops whatever the
+  client is doing.  When editing a line, the line is discarded; when
+  editing a second or later line of a query, the whole query is discarded;
+  when a query is being executed, the server is asked to stop the query
+  at its earliest convenience.  Stopping a running query can only be
+  done with an up-to-date server.  All of this does not work on Windows.
+
diff --git a/clients/Tests/MAL-signatures-hge.test 
b/clients/Tests/MAL-signatures-hge.test
--- a/clients/Tests/MAL-signatures-hge.test
+++ b/clients/Tests/MAL-signatures-hge.test
@@ -31845,12 +31845,12 @@ MTIMEdate_sub_msec_interval_bulk_p2;
 (empty)
 batmtime
 date_to_str
-pattern batmtime.date_to_str(X_0:bat[:str], X_1:bat[:str]):bat[:str] 
+pattern batmtime.date_to_str(X_0:bat[:date], X_1:bat[:str]):bat[:str] 
 MTIMEdate_to_str_bulk;
 (empty)
 batmtime
 date_to_str
-pattern batmtime.date_to_str(X_0:bat[:str], X_1:bat[:str], X_2:bat[:oid], 
X_3:bat[:oid]):bat[:str] 
+pattern batmtime.date_to_str(X_0:bat[:date], X_1:bat[:str], X_2:bat[:oid], 
X_3:bat[:oid]):bat[:str] 
 MTIMEdate_to_str_bulk;
 (empty)
 batmtime
@@ -47967,7 +47967,7 @@ mtime
 epoch
 command mtime.epoch(X_0:lng):timestamp 
 MTIMEtimestamp_frommsec_epoch;
-convert milli seconds since epoch into a timestamp
+convert milliseconds since epoch into a timestamp
 mtime
 epoch
 command mtime.epoch(X_0:int):timestamp 
diff --git a/clients/Tests/MAL-signatures.test 
b/clients/Tests/MAL-signatures.test
--- a/clients/Tests/MAL-signatures.test
+++ b/clients/Tests/MAL-signatures.test
@@ -23040,12 +23040,12 @@ MTIMEdate_sub_msec_interval_bulk_p2;
 (empty)
 batmtime
 date_to_str
-pattern batmtime.date_to_str(X_0:bat[:str], X_1:bat[:str]):bat[:str] 
+pattern batmtime.date_to_str(X_0:bat[:date], X_1:bat[:str]):bat[:str] 
 MTIMEdate_to_str_bulk;
 (empty)
 batmtime
 date_to_str
-pattern batmtime.date_to_str(X_0:bat[:str], X_1:bat[:str], X_2:bat[:oid], 
X_3:bat[:oid]):bat[:str] 
+pattern batmtime.date_to_str(X_0:bat[:date], X_1:bat[:str], X_2:bat[:oid], 
X_3:bat[:oid]):bat[:str] 
 MTIMEdate_to_str_bulk;
 (empty)
 batmtime
@@ -36397,7 +36397,7 @@ mtime
 epoch
 command mtime.epoch(X_0:lng):timestamp 
 MTIMEtimestamp_frommsec_epoch;
-convert milli seconds since epoch into a timestamp
+convert milliseconds since epoch into a timestamp
 mtime
 epoch
 command mtime.epoch(X_0:int):timestamp 
diff --git a/clients/Tests/exports.stable.out b/clients/Tests/exports.stable.out
--- a/clients/Tests/exports.stable.out
+++ b/clients/Tests/exports.stable.out
@@ -681,6 +681,7 @@ MapiMsg mapi_ping(Mapi mid) __attribute_
 MapiHdl mapi_prepare(Mapi mid, const char *cmd) 
__attribute__((__nonnull__(1)));
 MapiMsg mapi_prepare_handle(MapiHdl hdl, const char *cmd) 
__attribute__((__nonnull__(1)));
 MapiHdl mapi_query(Mapi mid, const char *cmd) __attribute__((__nonnull__(1)));
+MapiMsg mapi_query_abort(MapiHdl hdl, int reason) 
__attribute__((__nonnull__(1)));
 MapiMsg mapi_query_done(MapiHdl hdl) __attribute__((__nonnull__(1)));
 MapiMsg mapi_query_handle(MapiHdl hdl, const char *cmd) 
__attribute__((__nonnull__(1)));
 MapiMsg mapi_query_part(MapiHdl hdl, const char *cmd, size_t size) 
__attribute__((__nonnull__(1)));
@@ -797,7 +798,7 @@ BUN SQLload_file(Client cntxt, Tablet *a
 str TABLETcollect(BAT **bats, Tablet *as);
 str TABLETcreate_bats(Tablet *as, BUN est);
 void TABLETdestroy_format(Tablet *as);
-int TABLEToutput_file(Tablet *as, BAT *order, stream *s);
+int TABLEToutput_file(Tablet *as, BAT *order, stream *s, bstream *in);
 int TRACEtable(Client cntxt, BAT **r);
 int TYPE_xml;
 int UTF8_strlen(const char *restrict s);
@@ -1643,6 +1644,7 @@ stream *block_stream(stream *s);
 stream *bs_stream(stream *s);
 bstream *bstream_create(stream *rs, size_t chunk_size);
 void bstream_destroy(bstream *s);
+int bstream_getoob(bstream *s);
 ssize_t bstream_next(bstream *s);
 ssize_t bstream_read(bstream *s, size_t size);
 buffer *buffer_create(size_t size);
@@ -1682,12 +1684,14 @@ int mnstr_fsetpos(stream *restrict s, fp
 int mnstr_fsync(stream *s);
 buffer *mnstr_get_buffer(stream *s);
 bool mnstr_get_swapbytes(const stream *s);
+int mnstr_getoob(const stream *s);
 int mnstr_init(void);
 int mnstr_isalive(const stream *s);
 bool mnstr_isbinary(const stream *s);
 const char *mnstr_name(const stream *s);
 const char *mnstr_peek_error(const stream *s);
 int mnstr_printf(stream *restrict s, _In_z_ _Printf_format_string_ const char 
*restrict format, ...) __attribute__((__format__(__printf__, 2, 3)));
+int mnstr_putoob(const stream *s, char val);
 ssize_t mnstr_read(stream *restrict s, void *restrict buf, size_t elmsize, 
size_t cnt);
 int mnstr_readBte(stream *restrict s, int8_t *restrict val);
 int mnstr_readBteArray(stream *restrict s, int8_t *restrict val, size_t cnt);
diff --git a/clients/mapiclient/ReadlineTools.c 
b/clients/mapiclient/ReadlineTools.c
--- a/clients/mapiclient/ReadlineTools.c
+++ b/clients/mapiclient/ReadlineTools.c
@@ -35,6 +35,9 @@
 #include <sys/stat.h>
 #endif
 
+#include <signal.h>
+#include <setjmp.h>
+
 static const char *sql_commands[] = {
        "SELECT",
        "INSERT",
@@ -421,6 +424,30 @@ bailout:
        return 1;
 }
 
+static sigjmp_buf readline_jumpbuf;
+static volatile sig_atomic_t mayjump;
+
+void
+readline_int_handler(void)
+{
+       if (mayjump) {
+               mayjump = false;
+               siglongjmp(readline_jumpbuf, 1);
+       }
+}
+
+char *
+call_readline(const char *prompt)
+{
+       char *res;
+       if (sigsetjmp(readline_jumpbuf, 1) != 0)
+               return (char *) -1;             /* interrupted */
+       mayjump = true;
+       res = readline(prompt);         /* normal code path */
+       mayjump = false;
+       return res;
+}
+
 void
 init_readline(Mapi mid, const char *lang, bool save_history)
 {
@@ -501,5 +528,4 @@ save_line(const char *s)
                append_history(1, _history_file);
 }
 
-
 #endif /* HAVE_LIBREADLINE */
diff --git a/clients/mapiclient/ReadlineTools.h 
b/clients/mapiclient/ReadlineTools.h
--- a/clients/mapiclient/ReadlineTools.h
+++ b/clients/mapiclient/ReadlineTools.h
@@ -22,6 +22,8 @@ void deinit_readline(void);
 void save_line(const char *s);
 rl_completion_func_t *suspend_completion(void);
 void continue_completion(rl_completion_func_t * func);
+void readline_int_handler(void);
+char *call_readline(const char *prompt);
 
 #endif /* HAVE_LIBREADLINE */
 #endif /* READLINETOOLS_H_INCLUDED */
diff --git a/clients/mapiclient/mclient.1 b/clients/mapiclient/mclient.1
--- a/clients/mapiclient/mclient.1
+++ b/clients/mapiclient/mclient.1
@@ -107,6 +107,9 @@ To disable reading the
 file, set the variable
 .B DOTMONETDBFILE
 to the empty string in the environment.
+.PP
+When working interactively, an interrupt (usually control-C) will clear
+any query being edited and will stop any running query.
 .SH OPTIONS
 .SS
 General Options
diff --git a/clients/mapiclient/mclient.c b/clients/mapiclient/mclient.c
--- a/clients/mapiclient/mclient.c
+++ b/clients/mapiclient/mclient.c
@@ -126,9 +126,9 @@ static timertype t0, t1;    /* used for tim
 #ifdef HAVE_POPEN
 static char *pager = 0;                /* use external pager */
 #endif
-#ifdef HAVE_SIGACTION
-#include <signal.h>            /* to block SIGPIPE */
-#endif
+
+#include <signal.h>
+
 static int rowsperpage = -1;   /* for SQL pagination */
 static int pagewidth = 0;      /* -1: take whatever is necessary, >0: limit */
 static int pageheight = 0;     /* -1: take whatever is necessary, >0: limit */
@@ -1402,11 +1402,17 @@ SQLpagemove(int *len, int fields, int *p
        mnstr_printf(toConsole, "next page? (continue,quit,next)");
        mnstr_flush(toConsole, MNSTR_FLUSH_DATA);
        sz = mnstr_readline(fromConsole, buf, sizeof(buf));
-       if (sz > 0) {
+       if (sz < 0 && mnstr_errnr(fromConsole) == MNSTR_INTERRUPT) {
+               /* interrupted, equivalent to typing 'q' */
+               mnstr_clearerr(fromConsole);
+               mnstr_printf(toConsole, "\n");
+               *skiprest = true;
+       } else if (sz > 0) {
                if (buf[0] == 'c')
                        *ps = 0;
                if (buf[0] == 'q')
                        *skiprest = true;
+               /* make sure we read the whole line */
                while (sz > 0 && buf[sz - 1] != '\n')
                        sz = mnstr_readline(fromConsole, buf, sizeof(buf));
        }
@@ -1414,6 +1420,24 @@ SQLpagemove(int *len, int fields, int *p
                SQLseparator(len, fields, '-');
 }
 
+static volatile sig_atomic_t state;
+#define READING                1
+#define WRITING                2
+#define QUERYING       3
+#define IDLING         0
+#define INTERRUPT      (-1)
+
+static void
+sigint_handler(int signum)
+{
+       (void) signum;
+
+       state = INTERRUPT;
+#ifdef HAVE_LIBREADLINE
+       readline_int_handler();
+#endif
+}
+
 static void
 SQLrenderer(MapiHdl hdl)
 {
@@ -1448,6 +1472,15 @@ SQLrenderer(MapiHdl hdl)
                exit(2);
        }
 
+       if (state == INTERRUPT) {
+               free(len);
+               free(hdr);
+               free(rest);
+               free(numeric);
+               return;
+       }
+       state = WRITING;
+
        total = 0;
        lentotal = 0;
        vartotal = 0;
@@ -1628,16 +1661,23 @@ SQLrenderer(MapiHdl hdl)
 
                if (ps > 0 && lines >= ps && fromConsole != NULL) {
                        SQLpagemove(len, printfields, &ps, &skiprest);
-                       lines = 0;
                        if (skiprest) {
                                mapi_finish(hdl);
                                break;
                        }
+                       lines = 0;
+               }
+
+               if (state == INTERRUPT) {
+                       skiprest = true;
+                       mapi_finish(hdl);
+                       break;
                }
 
                nrows++;
                lines += SQLrow(len, numeric, rest, printfields, 2, 0);
        }
+       state = IDLING;
        if (fields && !skiprest)
                SQLseparator(len, printfields, '-');
        if (skiprest)
@@ -1942,6 +1982,8 @@ format_result(Mapi mid, MapiHdl hdl, boo
                        SQLdebugRendering(hdl);
                        continue;
                }
+               if (state == INTERRUPT)
+                       break;
                if (debugMode())
                        RAWrenderer(hdl);
                else {
@@ -1986,7 +2028,7 @@ format_result(Mapi mid, MapiHdl hdl, boo
 
_______________________________________________
checkin-list mailing list -- checkin-list@monetdb.org
To unsubscribe send an email to checkin-list-le...@monetdb.org

Reply via email to