From: dan Date: Thu, 13 Nov 2025 17:42:55 +0000 (+0000) Subject: Add better test case for the issue with dropping RETURNING triggers when the schema... X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=826bebdb311d98d4c0a01b88ba6275a1adea200d;p=thirdparty%2Fsqlite.git Add better test case for the issue with dropping RETURNING triggers when the schema is reset while preparing a statement. FossilOrigin-Name: 6a9fdde109865b23888f099d066721404e8b853f3dacd55ce08c8bbda2491ec3 --- diff --git a/manifest b/manifest index 36bdd47c4a..7c362646c8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Generic\smakefile\scleanups\sand\sdoc\supdates. -D 2025-11-13T17:37:40.529 +C Add\sbetter\stest\scase\sfor\sthe\sissue\swith\sdropping\sRETURNING\striggers\swhen\sthe\sschema\sis\sreset\swhile\spreparing\sa\sstatement. +D 2025-11-13T17:42:55.573 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -752,7 +752,7 @@ F src/test8.c 206d8f3cc73950d252906656e2646b5de0d580b07187b635fcb3edd8c2c5fbc0 F src/test9.c df9ddc7db6ef1b8cf745866ee229090779728bcbe660c7f297d3127ab21d92af F src/test_autoext.c 14d4bbd3d0bd1eec0f6d16b29e28cf1e2d0b020d454835f0721a5f68121ac10f F src/test_backup.c a2bfd90d2ff2511b8635507bdb30fa9b605ade19c16b533066cae3077f5bdb72 -F src/test_bestindex.c 3401bee51665cbf7f9ed2552b5795452a8b86365e4c9ece745b54155a55670c6 +F src/test_bestindex.c 6ce12494177116a85ad11a0d6df7eef815e57176239b9e53df4258b3e86f68eb F src/test_blob.c 77b994e17f2c87055f44fd96c9a206c5a7155bae2cda2769af60c2f3582f962c F src/test_btree.c 28283787d32b8fa953eb77412ad0de2c9895260e4e5bd5a94b3c7411664f90d5 F src/test_config.c 18aa596d37de1d5968c439fd58ebf38bc4d9c9d1db63621504e241fde375cecd @@ -910,7 +910,7 @@ F test/bestindexA.test e1b5def6b190797cacf008e6815ffb78fb30261999030d60a728d572e F test/bestindexB.test 328b97b69cd1a20928d5997f9ecb04d2e00f1d18e19ab27f9e9adb44d7bc51ce F test/bestindexC.test 95b4a527b1a5d07951d731604a6d4cf7e5a806b39cea0e7819d4c9667e11c3fc F test/bestindexD.test 6a8f6f84990bcf17dfa59652a1f935beddb7afd96f8302830fbc86b0a13df3c3 -F test/bestindexE.test f0c7105d1e7facaa8f5e6c498849cc6dcadd533b35ea9e5e1176e54a9a2d70f1 +F test/bestindexE.test 297f3ea8500a8f3c17d6f78e55bdfee089064c6144ee84a110bd005a03338f49 F test/between.test e7587149796101cbe8d5f8abae8d2a7b87f04d8226610aa1091615005dcf4d54 F test/bigfile.test aa74f4e5db51c8e54a1d9de9fa65d01d1eb20b59 F test/bigfile2.test 1b489a3a39ae90c7f027b79110d6b4e1dbc71bfc @@ -2167,8 +2167,8 @@ F tool/version-info.c 33d0390ef484b3b1cb685d59362be891ea162123cea181cb8e6d2cf6dd F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh d924598cf2f55a4ecbc2aeb055c10bd5f48114793e7ba25f9585435da29e7e98 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P cb8fb01fe19ba3af536a662aed894b2b0eb2463c8d34c644c498234fd82122f3 -R 9c409c36a1cdc118cb78bcb027efe59a -U stephan -Z b596efc51c44a0649133e19d870d692f +P e8b34b4178be621102dac165b716283055fad90b3edc2394f56a24f9f0149448 +R 20aa046c40edd19c9eb0c123dec945ac +U dan +Z 4c6394f8af064a5c9e605294797a46bf # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 527950af6f..6488f25578 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e8b34b4178be621102dac165b716283055fad90b3edc2394f56a24f9f0149448 +6a9fdde109865b23888f099d066721404e8b853f3dacd55ce08c8bbda2491ec3 diff --git a/src/test_bestindex.c b/src/test_bestindex.c index 2f9203d85e..d2c9d65386 100644 --- a/src/test_bestindex.c +++ b/src/test_bestindex.c @@ -101,6 +101,7 @@ typedef struct tcl_vtab tcl_vtab; typedef struct tcl_cursor tcl_cursor; typedef struct TestFindFunction TestFindFunction; +typedef struct TestVtabContext TestVtabContext; /* ** A fs virtual-table object @@ -125,6 +126,10 @@ struct TestFindFunction { TestFindFunction *pNext; }; +struct TestVtabContext { + Tcl_Interp *interp; + Tcl_Obj *pDefault; +}; /* ** Dequote string z in place. @@ -178,25 +183,33 @@ static int tclConnect( sqlite3_vtab **ppVtab, char **pzErr ){ - Tcl_Interp *interp = (Tcl_Interp*)pAux; + TestVtabContext *pCtx = (TestVtabContext*)pAux; + Tcl_Interp *interp = pCtx->interp; tcl_vtab *pTab = 0; char *zCmd = 0; Tcl_Obj *pScript = 0; int rc = SQLITE_OK; - if( argc!=4 ){ + if( argc!=4 && (argc!=3 || pCtx->pDefault==0) ){ *pzErr = sqlite3_mprintf("wrong number of arguments"); return SQLITE_ERROR; } - zCmd = sqlite3_malloc64(strlen(argv[3])+1); + if( argc==4 ){ + zCmd = sqlite3_malloc64(strlen(argv[3])+1); + } pTab = (tcl_vtab*)sqlite3_malloc64(sizeof(tcl_vtab)); - if( zCmd && pTab ){ - memcpy(zCmd, argv[3], strlen(argv[3])+1); - tclDequote(zCmd); + if( (zCmd || argc==3) && pTab ){ memset(pTab, 0, sizeof(tcl_vtab)); - pTab->pCmd = Tcl_NewStringObj(zCmd, -1); + if( zCmd ){ + memcpy(zCmd, argv[3], strlen(argv[3])+1); + tclDequote(zCmd); + pTab->pCmd = Tcl_NewStringObj(zCmd, -1); + }else{ + pTab->pCmd = Tcl_DuplicateObj(pCtx->pDefault); + } + pTab->interp = interp; pTab->db = db; Tcl_IncrRefCount(pTab->pCmd); @@ -802,6 +815,39 @@ static int tclFindFunction( return iRet; } +static int tclUpdate( + sqlite3_vtab *tab, + int nArg, + sqlite3_value **apVal, + sqlite3_int64 *piRowid +){ + tcl_vtab *pTab = (tcl_vtab*)tab; + Tcl_Interp *interp = pTab->interp; + Tcl_Obj *pEval = Tcl_DuplicateObj(pTab->pCmd); + Tcl_Obj *pRes = 0; + int rc = TCL_OK; + + Tcl_IncrRefCount(pEval); + Tcl_ListObjAppendElement(interp, pEval, Tcl_NewStringObj("xUpdate",-1)); + + rc = Tcl_EvalObjEx(interp, pEval, TCL_EVAL_GLOBAL); + Tcl_DecrRefCount(pEval); + + if( rc==TCL_OK ){ + Tcl_Obj *pRes = Tcl_GetObjResult(interp); + Tcl_WideInt v; + rc = Tcl_GetWideIntFromObj(interp, pRes, &v); + *piRowid = (sqlite3_int64)v; + } + + if( rc!=TCL_OK ){ + tab->zErrMsg = sqlite3_mprintf("%s", Tcl_GetStringResult(pTab->interp)); + return rc; + } + + return SQLITE_OK; +} + /* ** A virtual table module that provides read-only access to a ** Tcl global variable namespace. @@ -833,12 +879,47 @@ static sqlite3_module tclModule = { 0, /* xShadowName */ 0 /* xIntegrity */ }; +static sqlite3_module tclModuleUpdate = { + 0, /* iVersion */ + tclConnect, + tclConnect, + tclBestIndex, + tclDisconnect, + tclDisconnect, + tclOpen, /* xOpen - open a cursor */ + tclClose, /* xClose - close a cursor */ + tclFilter, /* xFilter - configure scan constraints */ + tclNext, /* xNext - advance a cursor */ + tclEof, /* xEof - check for end of scan */ + tclColumn, /* xColumn - read data */ + tclRowid, /* xRowid - read data */ + tclUpdate, /* xUpdate */ + 0, /* xBegin */ + 0, /* xSync */ + 0, /* xCommit */ + 0, /* xRollback */ + tclFindFunction, /* xFindFunction */ + 0, /* xRename */ + 0, /* xSavepoint */ + 0, /* xRelease */ + 0, /* xRollbackTo */ + 0, /* xShadowName */ + 0 /* xIntegrity */ +}; /* ** Decode a pointer to an sqlite3 object. */ extern int getDbPointer(Tcl_Interp *interp, const char *zA, sqlite3 **ppDb); +static void delTestVtabCtx(void *p){ + TestVtabContext *pCtx = (TestVtabContext*)p; + if( pCtx->pDefault ){ + Tcl_DecrRefCount(pCtx->pDefault); + } + ckfree(pCtx); +} + /* ** Register the echo virtual table module. */ @@ -849,13 +930,25 @@ static int SQLITE_TCLAPI register_tcl_module( Tcl_Obj *CONST objv[] /* Command arguments */ ){ sqlite3 *db; - if( objc!=2 ){ - Tcl_WrongNumArgs(interp, 1, objv, "DB"); + if( objc!=2 && objc!=3 ){ + Tcl_WrongNumArgs(interp, 1, objv, "DB ?DEFAULT-CMD?"); return TCL_ERROR; } if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; #ifndef SQLITE_OMIT_VIRTUALTABLE - sqlite3_create_module(db, "tcl", &tclModule, (void *)interp); + { + sqlite3_module *pMod = &tclModule; + TestVtabContext *pCtx = (TestVtabContext*)ckalloc(sizeof(TestVtabContext)); + pCtx->interp = interp; + pCtx->pDefault = 0; + if( objc==3 ){ + pCtx->pDefault = objv[2]; + Tcl_IncrRefCount(pCtx->pDefault); + } + + if( objc==3 ){ pMod = &tclModuleUpdate; } + sqlite3_create_module_v2(db, "tcl", pMod, (void*)pCtx, delTestVtabCtx); + } #endif return TCL_OK; } diff --git a/test/bestindexE.test b/test/bestindexE.test index 48397fc7b3..d225d74aef 100644 --- a/test/bestindexE.test +++ b/test/bestindexE.test @@ -13,7 +13,7 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl -set testprefix bestindex1 +set testprefix bestindexE ifcapable !vtab { finish_test @@ -124,7 +124,68 @@ do_bestindex_test 2.2 { {Customer: oid=?} } +#-------------------------------------------------------------------------- +reset_db +register_tcl_module db eponymous_cmd +proc eponymous_cmd {method args} { + switch -- $method { + xConnect { + db eval { SELECT * FROM sqlite_schema } + return "CREATE TABLE t1 (a, b)" + } + xBestIndex { + return "idxnum 555" + } + + xFilter { + return [list sql {SELECT 123, 'A', 'B'}] + } + + xUpdate { + return 123 + } + + } + + return {} +} + +do_execsql_test 3.1.0 { + PRAGMA table_info = tcl +} { + 0 a {} 0 {} 0 1 b {} 0 {} 0 +} +do_execsql_test 3.1.1 { + SELECT rowid, * FROM tcl +} {123 A B} +do_execsql_test 3.1.2 { + INSERT INTO tcl VALUES('i', 'ii') RETURNING *; +} {i ii} +do_test 3.1.3 { + db last_insert_rowid +} {123} + +do_execsql_test 3.1.4 { + CREATE TABLE x1(x); +} + +db close +sqlite3 db test.db +register_tcl_module db eponymous_cmd +sqlite3 db2 test.db + +# Load the schema into connection [db] +do_execsql_test 3.2.1 { SELECT * FROM x1 } + +# Modify the schema on disk +do_execsql_test -db db2 3.2.2 { CREATE TABLE x2(x) } + +# Insert with RETURNING trigger on eponymous table. +do_execsql_test 3.2.3 { + INSERT INTO tcl VALUES('i', 'ii') RETURNING *; +} {i ii} finish_test +