]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Add better test case for the issue with dropping RETURNING triggers when the schema...
authordan <Dan Kennedy>
Thu, 13 Nov 2025 17:42:55 +0000 (17:42 +0000)
committerdan <Dan Kennedy>
Thu, 13 Nov 2025 17:42:55 +0000 (17:42 +0000)
FossilOrigin-Name: 6a9fdde109865b23888f099d066721404e8b853f3dacd55ce08c8bbda2491ec3

manifest
manifest.uuid
src/test_bestindex.c
test/bestindexE.test

index 36bdd47c4ab5d60e45666f8fd1d5fd7e1bebbfb7..7c362646c87e8b37d7657a10e1d014722cc66700 100644 (file)
--- 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.
index 527950af6f6fbaedc1a40c57debb939a3bfae4f7..6488f255784ea5f6dd30a380fa00c2c0b1434dee 100644 (file)
@@ -1 +1 @@
-e8b34b4178be621102dac165b716283055fad90b3edc2394f56a24f9f0149448
+6a9fdde109865b23888f099d066721404e8b853f3dacd55ce08c8bbda2491ec3
index 2f9203d85ed69c7c63df7aea5306583a8e8194c9..d2c9d65386f9fcaa9167c6a445a5dcbd8f77144f 100644 (file)
 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;
 }
index 48397fc7b3b6fc7ab2028b470eaa974a69a6c153..d225d74aef6f0633d7000ac4750e20e5866629a6 100644 (file)
@@ -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
+