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