Changeset: 8d5c88c3ed0d for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/8d5c88c3ed0d Modified Files: clients/Tests/MAL-signatures.stable.out clients/Tests/MAL-signatures.stable.out.int128 monetdb5/modules/mal/oltp.c monetdb5/optimizer/opt_oltp.c sql/test/SQLancer/Tests/sqlancer17.test Branch: Jan2022 Log Message:
Fix for OLTP optimizer. When an error is found, re-throw it after catching it diffs (163 lines): diff --git a/clients/Tests/MAL-signatures.stable.out b/clients/Tests/MAL-signatures.stable.out --- a/clients/Tests/MAL-signatures.stable.out +++ b/clients/Tests/MAL-signatures.stable.out @@ -9077,6 +9077,7 @@ [ "netcdf", "importvar", "unsafe command netcdf.importvar(X_0:str, X_1:int):str ", "NCDFimportVarStmt;", "Import variable: compose create array string" ] [ "netcdf", "importvariable", "unsafe pattern netcdf.importvariable(X_0:int, X_1:str):void ", "NCDFimportVariable;", "Import variable: create array and load data from variable varname of file fileid" ] [ "netcdf", "test", "command netcdf.test(X_0:str):int ", "NCDFtest;", "Returns number of variables in a given NetCDF dataset (file)" ] +[ "oltp", "assert", "pattern oltp.assert(X_0:bit, X_1:str):void ", "OLTPassert;", "Generate an exception when b==true" ] [ "oltp", "disable", "unsafe pattern oltp.disable():void ", "OLTPdisable;", "Disable the OLTP delay monitor" ] [ "oltp", "enable", "unsafe pattern oltp.enable():void ", "OLTPenable;", "Enable the OLTP delay monitor" ] [ "oltp", "init", "unsafe pattern oltp.init():void ", "OLTPinit;", "Initialize the lock table" ] diff --git a/clients/Tests/MAL-signatures.stable.out.int128 b/clients/Tests/MAL-signatures.stable.out.int128 --- a/clients/Tests/MAL-signatures.stable.out.int128 +++ b/clients/Tests/MAL-signatures.stable.out.int128 @@ -12377,6 +12377,7 @@ [ "netcdf", "importvar", "unsafe command netcdf.importvar(X_0:str, X_1:int):str ", "NCDFimportVarStmt;", "Import variable: compose create array string" ] [ "netcdf", "importvariable", "unsafe pattern netcdf.importvariable(X_0:int, X_1:str):void ", "NCDFimportVariable;", "Import variable: create array and load data from variable varname of file fileid" ] [ "netcdf", "test", "command netcdf.test(X_0:str):int ", "NCDFtest;", "Returns number of variables in a given NetCDF dataset (file)" ] +[ "oltp", "assert", "pattern oltp.assert(X_0:bit, X_1:str):void ", "OLTPassert;", "Generate an exception when b==true" ] [ "oltp", "disable", "unsafe pattern oltp.disable():void ", "OLTPdisable;", "Disable the OLTP delay monitor" ] [ "oltp", "enable", "unsafe pattern oltp.enable():void ", "OLTPenable;", "Enable the OLTP delay monitor" ] [ "oltp", "init", "unsafe pattern oltp.init():void ", "OLTPinit;", "Initialize the lock table" ] diff --git a/monetdb5/modules/mal/oltp.c b/monetdb5/modules/mal/oltp.c --- a/monetdb5/modules/mal/oltp.c +++ b/monetdb5/modules/mal/oltp.c @@ -255,6 +255,33 @@ OLTPis_enabled(int *ret) { return MAL_SUCCEED; } +static str +OLTPassert(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci) +{ + bool flg = (bool) *getArgReference_bit(stk, pci, 1); + str msg = *getArgReference_str(stk, pci, 2); + + (void) cntxt; + (void) mb; + if (flg) { + if (strlen(msg) > 6 && + msg[5] == '!' && + (isdigit((unsigned char) msg[0]) || + isupper((unsigned char) msg[0])) && + (isdigit((unsigned char) msg[1]) || + isupper((unsigned char) msg[1])) && + (isdigit((unsigned char) msg[2]) || + isupper((unsigned char) msg[2])) && + (isdigit((unsigned char) msg[3]) || + isupper((unsigned char) msg[3])) && + (isdigit((unsigned char) msg[4]) || + isupper((unsigned char) msg[4]))) + throw(OPTIMIZER, "assert", "%s", msg); /* includes state */ + throw(OPTIMIZER, "assert", SQLSTATE(M0M29) "%s", msg); + } + return MAL_SUCCEED; +} + #include "mel.h" mel_func oltp_init_funcs[] = { pattern("oltp", "init", OLTPinit, true, "Initialize the lock table", noargs), @@ -265,6 +292,7 @@ mel_func oltp_init_funcs[] = { pattern("oltp", "release", OLTPrelease, true, "Release for all write locks needed", args(1,2, arg("",void),vararg("lck",int))), pattern("oltp", "table", OLTPtable, true, "Show status of lock table", args(4,4, batarg("start",timestamp),batarg("usr",str),batarg("unit",int),batarg("cnt",int))), command("oltp", "isenabled", OLTPis_enabled, true, "Query the OLTP state", args(1,1, arg("",int))), + pattern("oltp", "assert", OLTPassert, false, "Generate an exception when b==true", args(1,3, arg("",void),arg("b",bit),arg("msg",str))), { .imp=NULL } }; #include "mal_import.h" diff --git a/monetdb5/optimizer/opt_oltp.c b/monetdb5/optimizer/opt_oltp.c --- a/monetdb5/optimizer/opt_oltp.c +++ b/monetdb5/optimizer/opt_oltp.c @@ -30,7 +30,7 @@ addLock(Client cntxt, OLTPlocks locks, M str OPToltpImplementation(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci) { int i, limit, slimit, updates=0; - InstrPtr p, q, lcks; + InstrPtr p, q, r, lcks; int actions = 0; InstrPtr *old; OLTPlocks wlocks, rlocks; @@ -102,7 +102,20 @@ OPToltpImplementation(Client cntxt, MalB for (i = 1; i < limit; i++) { p = old[i]; if( p->token == ENDsymbol){ - // unlock all if there is an error + /* path when no errors are found, just release the lock */ + q= copyInstruction(lcks); + if( q == NULL){ + for(; i<slimit; i++) + if( old[i]) + freeInstruction(old[i]); + GDKfree(old); + throw(MAL,"optimizer.oltp", SQLSTATE(HY013) MAL_MALLOC_FAIL); + } + setFunctionId(q, releaseRef); + getArg(q,0) = newTmpVariable(mb, TYPE_void); + pushInstruction(mb,q); + pushEndInstruction(mb); + /* path when errors are found, catch error, release lock and re-throw the error */ q= newCatchStmt(mb,"MALException"); q= newExitStmt(mb,"MALException"); q= newCatchStmt(mb,"SQLException"); @@ -118,6 +131,12 @@ OPToltpImplementation(Client cntxt, MalB setFunctionId(q, releaseRef); getArg(q,0) = newTmpVariable(mb, TYPE_void); pushInstruction(mb,q); + /* At the moment I cannot figure out a way to get the exception error. + A MAL expert could improve this to throw the original message. + This also happens with remote plans (check sql_gencode.c) */ + r = newStmt(mb, oltpRef, assertRef); + r = pushBit(mb, r, TRUE); + r = pushStr(mb, r, "Exception occurred in the OLTP plan, please check the server log"); } pushInstruction(mb,p); } diff --git a/sql/test/SQLancer/Tests/sqlancer17.test b/sql/test/SQLancer/Tests/sqlancer17.test --- a/sql/test/SQLancer/Tests/sqlancer17.test +++ b/sql/test/SQLancer/Tests/sqlancer17.test @@ -431,6 +431,45 @@ statement ok DROP TABLE t1 statement ok +SET "optimizer"='oltp_pipe' + +statement ok +START TRANSACTION + +statement ok +CREATE TABLE t0(c0 boolean) + +statement ok +CREATE TABLE t1(LIKE t0) + +statement ok +CREATE TABLE t2(LIKE t0) + +statement ok rowcount 1 +INSERT INTO t1(c0) VALUES(FALSE) + +statement ok rowcount 2 +INSERT INTO t2(c0) VALUES(TRUE), (TRUE) + +statement ok rowcount 1 +INSERT INTO t0(c0) VALUES(TRUE) + +statement ok +CREATE VIEW v0(vc0) AS (SELECT 5 FROM t0, t2 WHERE t0.c0) + +statement ok +CREATE VIEW v1(vc0) AS (SELECT t0.c0 FROM t0, v0 WHERE TRUE) + +statement error M0M29!Exception occurred in the OLTP plan, please check the server log +UPDATE t1 SET c0 = TRUE FROM v1 + +statement ok +ROLLBACK + +statement ok +SET "optimizer"='default_pipe' + +statement ok CREATE TABLE t2(c0 INTERVAL DAY) statement ok rowcount 1 _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list