Changeset: 1b472b7d254c for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/1b472b7d254c Modified Files: clients/mapiclient/mclient.c clients/mapilib/mapi.c common/stream/stream.c sql/server/sql_parser.y sql/server/sql_scan.c Branch: client_interrupts Log Message:
When reading a continuation of a query without readline, abort on interrupt. This uses a terrible hack: we send an invalid byte (\200) to the server which traps that which causes parsing to fail. The server does give a decent error message, though. diffs (109 lines): diff --git a/clients/mapiclient/mclient.c b/clients/mapiclient/mclient.c --- a/clients/mapiclient/mclient.c +++ b/clients/mapiclient/mclient.c @@ -2363,6 +2363,9 @@ doFile(Mapi mid, stream *fp, bool useins } do { +#ifndef HAVE_LIBREADLINE + repeat: +#endif bool seen_null_byte = false; if (prompt) { @@ -2383,13 +2386,25 @@ doFile(Mapi mid, stream *fp, bool useins ssize_t l; char *newbuf; #ifndef HAVE_LIBREADLINE - do { - state = READING; - mnstr_clearerr(fp); + state = READING; #endif - l = mnstr_readline(fp, buf + length, bufsiz - length); + l = mnstr_readline(fp, buf + length, bufsiz - length); #ifndef HAVE_LIBREADLINE - } while (l == -1 && state == IDLING); + if (l == -1 && state == IDLING) { + /* we were interrupted */ + mnstr_clearerr(fp); + if (hdl) { + /* on interrupt when continuing a query, force an error */ + buf[0] = '\200'; + buf[1] = '\n'; + l = 2; + length = 0; + } else { + /* not continuing; just repeat */ + mnstr_write(toConsole, "\n", 1, 1); + goto repeat; + } + } state = IDLING; #endif if (l <= 0) diff --git a/clients/mapilib/mapi.c b/clients/mapilib/mapi.c --- a/clients/mapilib/mapi.c +++ b/clients/mapilib/mapi.c @@ -1731,8 +1731,7 @@ mapi_close_handle(MapiHdl hdl) /* don't use mapi_check_hdl: it's ok if we're not connected */ mapi_clrError(hdl->mid); - if (finish_handle(hdl) != MOK) - return MERROR; + (void) finish_handle(hdl); hdl->npending_close = 0; if (hdl->pending_close) free(hdl->pending_close); diff --git a/common/stream/stream.c b/common/stream/stream.c --- a/common/stream/stream.c +++ b/common/stream/stream.c @@ -608,7 +608,7 @@ mnstr_putoob(const stream *s, char val) { if (s->putoob) return s->putoob(s, val); - return 0; + return -1; } @@ -647,6 +647,8 @@ mnstr_error_kind_name(mnstr_error_kind k return "MNSTR_READ_ERROR"; case MNSTR_WRITE_ERROR: return "MNSTR_WRITE_ERROR"; + case MNSTR_INTERRUPT: + return "MNSTR_INTERRUPT"; case MNSTR_TIMEOUT: return "MNSTR_TIMEOUT"; default: diff --git a/sql/server/sql_parser.y b/sql/server/sql_parser.y --- a/sql/server/sql_parser.y +++ b/sql/server/sql_parser.y @@ -7320,9 +7320,9 @@ sqlformaterror(mvc * sql, _In_z_ _Printf } static int -sqlerror(mvc * sql, const char *err) +sqlerror(mvc *sql, const char *err) { - return sqlformaterror(sql, "%s", err); + return sqlformaterror(sql, "%s", sql->scanner.errstr ? sql->scanner.errstr : err); } static void *ma_alloc(sql_allocator *sa, size_t sz) diff --git a/sql/server/sql_scan.c b/sql/server/sql_scan.c --- a/sql/server/sql_scan.c +++ b/sql/server/sql_scan.c @@ -711,6 +711,12 @@ scanner_read_more(struct scanner *lc, si /* we asked for more data but didn't get any */ (more && b->eof && b->len < b->pos + lc->yycur + n)) return EOF; + if (more && b->pos + lc->yycur + 2 == b->len && b->buf[b->pos + lc->yycur] == '\200' && b->buf[b->pos + lc->yycur + 1] == '\n') { + lc->errstr = "Query aborted"; + b->len -= 2; + b->buf[b->len] = 0; + return EOF; + } } return 1; } _______________________________________________ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org