-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
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
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
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.
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
TestFindFunction *pNext;
};
+struct TestVtabContext {
+ Tcl_Interp *interp;
+ Tcl_Obj *pDefault;
+};
/*
** Dequote string z in place.
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);
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.
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.
*/
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;
}
set testdir [file dirname $argv0]
source $testdir/tester.tcl
-set testprefix bestindex1
+set testprefix bestindexE
ifcapable !vtab {
finish_test
{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
+