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:
@@ -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
@@ -1 +1 @@
|
||||
e8b34b4178be621102dac165b716283055fad90b3edc2394f56a24f9f0149448
|
||||
6a9fdde109865b23888f099d066721404e8b853f3dacd55ce08c8bbda2491ec3
|
||||
|
||||
+103
-10
@@ -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
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user