Changeset: fcde0ab6f0f6 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=fcde0ab6f0f6 Modified Files: clients/ChangeLog.Mar2018 clients/odbc/driver/ODBCDbc.c clients/odbc/driver/ODBCDbc.h clients/odbc/driver/ODBCStmt.c clients/odbc/driver/ODBCStmt.h clients/odbc/driver/SQLExecDirect.c clients/odbc/driver/SQLExecute.c clients/odbc/driver/SQLGetStmtAttr.c clients/odbc/driver/SQLSetStmtAttr.c gdk/gdk_imprints.c gdk/gdk_orderidx.c gdk/gdk_private.h gdk/gdk_select.c monetdb5/mal/mal_interpreter.c monetdb5/modules/mal/clients.c Branch: default Log Message:
Merge with Mar2018 branch. diffs (truncated from 391 to 300 lines): diff --git a/clients/ChangeLog.Mar2018 b/clients/ChangeLog.Mar2018 --- a/clients/ChangeLog.Mar2018 +++ b/clients/ChangeLog.Mar2018 @@ -1,3 +1,6 @@ # ChangeLog file for clients # This file is updated with Maddlog +* Tue Jul 24 2018 Sjoerd Mullender <sjo...@acm.org> +- ODBC: Implemented SQL_ATTR_QUERY_TIMEOUT parameter in SQLSetStmtAttr. + diff --git a/clients/odbc/driver/ODBCDbc.c b/clients/odbc/driver/ODBCDbc.c --- a/clients/odbc/driver/ODBCDbc.c +++ b/clients/odbc/driver/ODBCDbc.c @@ -76,6 +76,7 @@ newODBCDbc(ODBCEnv *env) dbc->minor = 0; dbc->patch = 0; dbc->cachelimit = 0; + dbc->qtimeout = 0; dbc->Mdebug = 0; dbc->FirstStmt = NULL; diff --git a/clients/odbc/driver/ODBCDbc.h b/clients/odbc/driver/ODBCDbc.h --- a/clients/odbc/driver/ODBCDbc.h +++ b/clients/odbc/driver/ODBCDbc.h @@ -62,6 +62,7 @@ typedef struct tODBCDRIVERDBC { /* MonetDB connection handle & status information */ Mapi mid; /* connection with server */ int cachelimit; /* cache limit we requested */ + SQLULEN qtimeout; /* current query timeout */ short major, minor, patch; /* version of server */ int Mdebug; diff --git a/clients/odbc/driver/ODBCStmt.c b/clients/odbc/driver/ODBCStmt.c --- a/clients/odbc/driver/ODBCStmt.c +++ b/clients/odbc/driver/ODBCStmt.c @@ -76,6 +76,8 @@ newODBCStmt(ODBCDbc *dbc) stmt->querytype = -1; stmt->rowcount = 0; + stmt->qtimeout = dbc->qtimeout; /* inherit query timeout */ + /* add this stmt to the administrative linked stmt list */ stmt->next = dbc->FirstStmt; dbc->FirstStmt = stmt; diff --git a/clients/odbc/driver/ODBCStmt.h b/clients/odbc/driver/ODBCStmt.h --- a/clients/odbc/driver/ODBCStmt.h +++ b/clients/odbc/driver/ODBCStmt.h @@ -80,6 +80,8 @@ typedef struct tODBCDRIVERSTMT { int querytype; /* query type as returned by server */ + SQLULEN qtimeout; /* query timeout requested */ + SQLUINTEGER cursorType; SQLULEN cursorScrollable; SQLULEN retrieveData; diff --git a/clients/odbc/driver/SQLExecDirect.c b/clients/odbc/driver/SQLExecDirect.c --- a/clients/odbc/driver/SQLExecDirect.c +++ b/clients/odbc/driver/SQLExecDirect.c @@ -46,6 +46,14 @@ ODBCExecDirect(ODBCStmt *stmt, SQLCHAR * return SQL_ERROR; } + if (stmt->qtimeout != stmt->Dbc->qtimeout) { + char buf[48]; + snprintf(buf, sizeof(buf), "call sys.settimeout(%" PRIu64 ")", + (uint64_t) stmt->qtimeout); + if (mapi_query_handle(hdl, buf) == MOK) + stmt->Dbc->qtimeout = stmt->qtimeout; + } + query = ODBCTranslateSQL(stmt->Dbc, StatementText, (size_t) TextLength, stmt->noScan); if (query == NULL) { diff --git a/clients/odbc/driver/SQLExecute.c b/clients/odbc/driver/SQLExecute.c --- a/clients/odbc/driver/SQLExecute.c +++ b/clients/odbc/driver/SQLExecute.c @@ -447,6 +447,12 @@ MNDBExecute(ODBCStmt *stmt) addStmtError(stmt, "HY001", NULL, 0); return SQL_ERROR; } + if (stmt->qtimeout != stmt->Dbc->qtimeout) { + snprintf(query, querylen, "call sys.settimeout(%" PRIu64 ")", + (uint64_t) stmt->qtimeout); + if (mapi_query_handle(hdl, query) == MOK) + stmt->Dbc->qtimeout = stmt->qtimeout; + } querypos = snprintf(query, querylen, "execute %d (", stmt->queryid); /* XXX fill in parameter values */ if (desc->sql_desc_bind_offset_ptr) diff --git a/clients/odbc/driver/SQLGetStmtAttr.c b/clients/odbc/driver/SQLGetStmtAttr.c --- a/clients/odbc/driver/SQLGetStmtAttr.c +++ b/clients/odbc/driver/SQLGetStmtAttr.c @@ -123,7 +123,7 @@ MNDBGetStmtAttr(ODBCStmt *stmt, BufferLength, StringLengthPtr); case SQL_ATTR_QUERY_TIMEOUT: /* SQLULEN */ /* SQL_QUERY_TIMEOUT */ - WriteData(ValuePtr, 0, SQLULEN); + WriteData(ValuePtr, stmt->qtimeout, SQLULEN); break; case SQL_ATTR_RETRIEVE_DATA: /* SQLULEN */ /* SQL_RETRIEVE_DATA */ diff --git a/clients/odbc/driver/SQLSetStmtAttr.c b/clients/odbc/driver/SQLSetStmtAttr.c --- a/clients/odbc/driver/SQLSetStmtAttr.c +++ b/clients/odbc/driver/SQLSetStmtAttr.c @@ -195,6 +195,14 @@ MNDBSetStmtAttr(ODBCStmt *stmt, return MNDBSetDescField(stmt->ApplParamDescr, 0, SQL_DESC_ARRAY_SIZE, ValuePtr, StringLength); + case SQL_ATTR_QUERY_TIMEOUT: /* SQLULEN */ + if ((uintptr_t) ValuePtr > 0x7FFFFFFF) { + stmt->qtimeout = 0x7FFFFFFF; + addStmtError(stmt, "01S02", NULL, 0); + } else { + stmt->qtimeout = (SQLULEN) (uintptr_t) ValuePtr; + } + break; case SQL_ATTR_RETRIEVE_DATA: /* SQLULEN */ switch ((SQLULEN) (uintptr_t) ValuePtr) { case SQL_RD_ON: @@ -280,7 +288,6 @@ MNDBSetStmtAttr(ODBCStmt *stmt, case SQL_ATTR_CURSOR_SENSITIVITY: /* SQLULEN */ case SQL_ATTR_FETCH_BOOKMARK_PTR: /* SQLLEN* */ case SQL_ATTR_KEYSET_SIZE: /* SQLULEN */ - case SQL_ATTR_QUERY_TIMEOUT: /* SQLULEN */ case SQL_ATTR_SIMULATE_CURSOR: /* SQLULEN */ case SQL_ATTR_USE_BOOKMARKS: /* SQLULEN */ /* Optional feature not implemented */ diff --git a/gdk/gdk_imprints.c b/gdk/gdk_imprints.c --- a/gdk/gdk_imprints.c +++ b/gdk/gdk_imprints.c @@ -247,7 +247,7 @@ BATcheckimprints(BAT *b) close(fd); imprints->imprints.parentid = b->batCacheid; b->timprints = imprints; - ALGODEBUG fprintf(stderr, "#BATcheckimprints: reusing persisted imprints %d\n", b->batCacheid); + ALGODEBUG fprintf(stderr, "#BATcheckimprints(" ALGOBATFMT "): reusing persisted imprints\n", ALGOBATPAR(b)); MT_lock_unset(&GDKimprintsLock(b->batCacheid)); return true; @@ -262,7 +262,7 @@ BATcheckimprints(BAT *b) } ret = b->timprints != NULL; MT_lock_unset(&GDKimprintsLock(b->batCacheid)); - ALGODEBUG if (ret) fprintf(stderr, "#BATcheckimprints: already has imprints %d\n", b->batCacheid); + ALGODEBUG if (ret) fprintf(stderr, "#BATcheckimprints(" ALGOBATFMT "): already has imprints\n", ALGOBATPAR(b)); return ret; } @@ -299,9 +299,9 @@ BATimpsync(void *arg) #endif } close(fd); - ALGODEBUG fprintf(stderr, "#BATimpsync(%s): " + ALGODEBUG fprintf(stderr, "#BATimpsync(" ALGOBATFMT "): " "imprints persisted " - "(" LLFMT " usec)\n", BATgetId(b), + "(" LLFMT " usec)\n", ALGOBATPAR(b), GDKusec() - t0); } } @@ -343,6 +343,7 @@ BATimprints(BAT *b) if (VIEWtparent(b)) { /* views always keep null pointer and need to obtain * the latest imprint from the parent at query time */ + s2 = b; /* remember for ALGODEBUG print */ b = BBPdescriptor(VIEWtparent(b)); assert(b); if (BATcheckimprints(b)) @@ -356,8 +357,18 @@ BATimprints(BAT *b) const char *nme = BBP_physical(b->batCacheid); size_t pages; - ALGODEBUG fprintf(stderr, "#BATimprints(b=" ALGOBATFMT "): " - "creating imprints\n", ALGOBATPAR(b)); + ALGODEBUG { + if (s2) + fprintf(stderr, "#BATimprints(b=" ALGOBATFMT + "): creating imprints on parent " + ALGOBATFMT "\n", + ALGOBATPAR(s2), ALGOBATPAR(b)); + else + fprintf(stderr, "#BATimprints(b=" ALGOBATFMT + "): creating imprints\n", + ALGOBATPAR(b)); + } + s2 = NULL; imprints = GDKzalloc(sizeof(Imprints)); if (imprints == NULL) { diff --git a/gdk/gdk_orderidx.c b/gdk/gdk_orderidx.c --- a/gdk/gdk_orderidx.c +++ b/gdk/gdk_orderidx.c @@ -148,7 +148,7 @@ persistOIDX(BAT *b) if (MT_create_thread(&tid, BATidxsync, b, MT_THR_DETACHED) < 0) BBPunfix(b->batCacheid); } else - ALGODEBUG fprintf(stderr, "#BATorderidx(%s): NOT persisting index\n", BATgetId(b)); + ALGODEBUG fprintf(stderr, "#persistOIDX(" ALGOBATFMT "): NOT persisting order index\n", ALGOBATPAR(b)); #else (void) b; #endif diff --git a/gdk/gdk_private.h b/gdk/gdk_private.h --- a/gdk/gdk_private.h +++ b/gdk/gdk_private.h @@ -241,7 +241,7 @@ void BBPdump(void); /* never called: fo b->tnonil ? "N" : "", \ b->thash ? "H" : "", \ b->torderidx ? "O" : "", \ - b->timprints ? "I" : "" + b->timprints ? "I" : b->theap.parentid && BBP_cache(b->theap.parentid)->timprints ? "(I)" : "" /* use ALGOOPTBAT* when BAT is optional (can be NULL) */ #define ALGOOPTBATFMT "%s%s" BUNFMT "%s%s%s%s%s%s%s%s%s%s%s%s" #define ALGOOPTBATPAR(b) \ @@ -259,7 +259,7 @@ void BBPdump(void); /* never called: fo b && b->tnonil ? "N" : "", \ b && b->thash ? "H" : "", \ b && b->torderidx ? "O" : "", \ - b && b->timprints ? "I" : "" + b ? b->timprints ? "I" : b->theap.parentid && BBP_cache(b->theap.parentid)->timprints ? "(I)" : "" : "" #define BBP_BATMASK 511 #define BBP_THREADMASK 63 diff --git a/gdk/gdk_select.c b/gdk/gdk_select.c --- a/gdk/gdk_select.c +++ b/gdk/gdk_select.c @@ -1302,7 +1302,7 @@ BATselect(BAT *b, BAT *s, const void *tl anti = false; ALGODEBUG fprintf(stderr, "#BATselect(b=" ALGOBATFMT ",s=" ALGOOPTBATFMT ",anti=%d): " - "anti: switch ranges\n", + "anti: switch ranges...\n", ALGOBATPAR(b), ALGOOPTBATPAR(s), anti); } else if (!lval && !hval) { @@ -1325,7 +1325,7 @@ BATselect(BAT *b, BAT *s, const void *tl hval = false; ALGODEBUG fprintf(stderr, "#BATselect(b=" ALGOBATFMT ",s=" ALGOOPTBATFMT ",anti=0): " - "anti-nil\n", + "anti-nil...\n", ALGOBATPAR(b), ALGOOPTBATPAR(s)); } else if (equi) { equi = false; @@ -1339,7 +1339,7 @@ BATselect(BAT *b, BAT *s, const void *tl ALGODEBUG fprintf(stderr, "#BATselect(b=" ALGOBATFMT ",s=" ALGOOPTBATFMT ",anti=0): " - "anti-nothing\n", + "anti-nothing...\n", ALGOBATPAR(b), ALGOOPTBATPAR(s)); } @@ -1352,7 +1352,7 @@ BATselect(BAT *b, BAT *s, const void *tl hval = false; ALGODEBUG fprintf(stderr, "#BATselect(b=" ALGOBATFMT ",s=" ALGOOPTBATFMT ",anti=0): " - "anti-nil\n", + "anti-nil...\n", ALGOBATPAR(b), ALGOOPTBATPAR(s)); } } @@ -1804,9 +1804,9 @@ BATselect(BAT *b, BAT *s, const void *tl if (hash) { ALGODEBUG fprintf(stderr, "#BATselect(b=" ALGOBATFMT - ",s=" ALGOOPTBATFMT ",anti=%d): " + ",s=" ALGOOPTBATFMT "): " "hash select\n", - ALGOBATPAR(b), ALGOOPTBATPAR(s), anti); + ALGOBATPAR(b), ALGOOPTBATPAR(s)); bn = hashselect(b, s, bn, tl, maximum, phash); } else { /* use imprints if diff --git a/monetdb5/mal/mal_interpreter.c b/monetdb5/mal/mal_interpreter.c --- a/monetdb5/mal/mal_interpreter.c +++ b/monetdb5/mal/mal_interpreter.c @@ -355,8 +355,8 @@ str runMAL(Client cntxt, MalBlkPtr mb, M garbageCollector(cntxt, mb, stk, env != stk); if (stk && stk != env) freeStack(stk); - if (ret == MAL_SUCCEED && cntxt->qtimeout && GDKusec()- mb->starttime > cntxt->qtimeout) - throw(MAL, "mal.interpreter", RUNTIME_QRY_TIMEOUT); + if (ret == MAL_SUCCEED && cntxt->qtimeout && mb->starttime && GDKusec()- mb->starttime > cntxt->qtimeout) + throw(MAL, "mal.interpreter", SQLSTATE(HYT00) RUNTIME_QRY_TIMEOUT); return ret; } @@ -452,8 +452,8 @@ callMAL(Client cntxt, MalBlkPtr mb, MalS } if (stk) garbageCollector(cntxt, mb, stk, TRUE); - if ( ret == MAL_SUCCEED && cntxt->qtimeout && GDKusec()- mb->starttime > cntxt->qtimeout) - throw(MAL, "mal.interpreter", RUNTIME_QRY_TIMEOUT); + if ( ret == MAL_SUCCEED && cntxt->qtimeout && mb->starttime && GDKusec()- mb->starttime > cntxt->qtimeout) + throw(MAL, "mal.interpreter", SQLSTATE(HYT00) RUNTIME_QRY_TIMEOUT); return ret; } @@ -526,7 +526,7 @@ str runMALsequence(Client cntxt, MalBlkP _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list