Add better test case for the issue with dropping RETURNING triggers when the schema is reset while preparing a statement.

FossilOrigin-Name: 6a9fdde109865b23888f099d066721404e8b853f3dacd55ce08c8bbda2491ec3
This commit is contained in:
dan
2025-11-13 17:42:55 +00:00
parent 388c1da56e
commit 826bebdb31
4 changed files with 174 additions and 20 deletions
+8 -8
View File
@@ -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.
+1 -1
View File
@@ -1 +1 @@
e8b34b4178be621102dac165b716283055fad90b3edc2394f56a24f9f0149448
6a9fdde109865b23888f099d066721404e8b853f3dacd55ce08c8bbda2491ec3
+103 -10
View File
@@ -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;
}
+62 -1
View 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