Compare commits

...

1 Commits

Author SHA1 Message Date
drh c25cfcfa37 Experimental API sqlite3_stmt_refresh() to force a prepared statement to
recompile if it needs to due to a schema change or other factor.

FossilOrigin-Name: 10556ee454edf60dd6542fdf9017f713c783b9ca1b86f25f45e3c17ffb184e24
2017-07-20 16:55:51 +00:00
8 changed files with 104 additions and 13 deletions
+14 -12
View File
@@ -1,5 +1,5 @@
C Enhance\sthe\sbuilt-in\sdate/time\sfunctions\sso\sthat\sthey\scan\sbe\sused\sin\nCHECK\sconstraints,\sin\sthe\sWHERE\sclause\sor\spartial\sindexes,\sand\sindex\nexpressions,\sprovided\sthat\snone\sof\sthe\snon-deterministic\skeywords\n("now",\s"localtime",\s"utc")\sare\sused\sas\sarguments.
D 2017-07-20T15:08:43.378
C Experimental\sAPI\ssqlite3_stmt_refresh()\sto\sforce\sa\sprepared\sstatement\sto\nrecompile\sif\sit\sneeds\sto\sdue\sto\sa\sschema\schange\sor\sother\sfactor.
D 2017-07-20T16:55:51.434
F Makefile.in d9873c9925917cca9990ee24be17eb9613a668012c85a343aef7e5536ae266e8
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
F Makefile.msc 02b469e9dcd5b7ee63fc1fb05babc174260ee4cfa4e0ef2e48c3c6801567a016
@@ -455,7 +455,7 @@ F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac
F src/select.c c6bf96a7f9d7d68f929de84738c599a30d0a725ab0b54420e70545743cd5ee7b
F src/shell.c bd6a37cbe8bf64ef6a6a74fdc50f067d3148149b4ce2b4d03154663e66ded55f
F src/shell.c.in b5725acacba95ccefa57b6d068f710e29ba8239c3aa704628a1902a1f729c175
F src/sqlite.h.in dad804d4e1979a2ddec33cc8da6aa50c04e6ba0dcb4058e7b3609588d010e041
F src/sqlite.h.in d100c0942b5a6c20ec5c4a5a0b752be62530f80babd854544d1dbd2f23f91023
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F src/sqlite3ext.h 967154985ed2ae62f90d9029bb5b5071793d847f1696a2ebe9e8cc0b042ae60b
F src/sqliteInt.h 96197a18f041b9ab99e6cee0db39dbf771ac7762d9f0f63d9e719285f0478664
@@ -463,7 +463,7 @@ F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6
F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1
F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
F src/tclsqlite.c 2c29b0b76e91edfd1b43bf135c32c8674710089197327682b6b7e6af88062c3d
F src/test1.c cfb78b728b37ae3a2b14fe1b3a6c766e0da41370eda112594e698c94011b622e
F src/test1.c 84f9472ca24c2c2aa2d76256f19db3ce0bb0224c0553db793f0fb2c0969c869e
F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5
F src/test3.c b8434949dfb8aff8dfa082c8b592109e77844c2135ed3c492113839b6956255b
F src/test4.c 18ec393bb4d0ad1de729f0b94da7267270f3d8e6
@@ -520,10 +520,10 @@ F src/update.c c443935c652af9365e033f756550b5032d02e1b06eb2cb890ed7511ae0c051dc
F src/utf.c 810fbfebe12359f10bc2a011520a6e10879ab2a163bcb26c74768eab82ea62a5
F src/util.c fc081ec6f63448dcd80d3dfad35baecfa104823254a815b081a4d9fe76e1db23
F src/vacuum.c 874c0f2f15ab2908748297d587d22d485ea96d55aaec91d4775dddb2e24d2ecf
F src/vdbe.c 1e541ec7ff409bbabcc6b4f154957296fff5827c16c2ab0056348acae75685bf
F src/vdbe.c 53f3f4d1ee9bd4985cc0b199bdf6a6c5e99c526eb15f100fed59653c79cf8fa6
F src/vdbe.h d50cadf12bcf9fb99117ef392ce1ea283aa429270481426b6e8b0280c101fd97
F src/vdbeInt.h 19bd04a4211fe56c712ab35b48be77fd5a0579b851e9dea2cb8deade359b72b9
F src/vdbeapi.c 52844a5a71712197be45f1c63d730c48a745c7457c959465cfb2b969af40a266
F src/vdbeInt.h e202dc9f7b00722a85f609053610d40afa9b6a836a42810b2ef2d2a7b9e099ba
F src/vdbeapi.c d83d30e1130c96d5bb1132275275402502b17cd7434065ea93b4cd1eccab8c65
F src/vdbeaux.c 42e215cc6f69e91eebdd2b886ec1ff2b0d5e44331bd8b88a0a44e78bbeed7133
F src/vdbeblob.c 359891617358deefc85bef7bcf787fa6b77facb9
F src/vdbemem.c fe8fce1cdc258320b465934039fe4b1230d63f81d6b81b1eac775b6eec00af0d
@@ -632,7 +632,7 @@ F test/capi2.test 011c16da245fdc0106a2785035de6b242c05e738
F test/capi3.test 986e57cea8ab423b3fc8c2e3b69330394252d3d2a4496122ff3749e258305695
F test/capi3b.test efb2b9cfd127efa84433cd7a2d72ce0454ae0dc4
F test/capi3c.test 7ebed1d8fa2f3190149d556fe8cff5a006be62af437c5c4640db614470126098
F test/capi3d.test 485048dc5cd07bc68011e4917ad035ad6047ab82
F test/capi3d.test 876b9dda41f003aed30df91f0b8653e576a956ab46efa00eadd35d6920cb94e2
F test/capi3e.test 3d49c01ef2a1a55f41d73cba2b23b5059ec460fe
F test/cast.test 4c275cbdc8202d6f9c54a3596701719868ac7dc3
F test/cffault.test 9d6b20606afe712374952eec4f8fd74b1a8097ef
@@ -1637,8 +1637,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P d14fc621e918915bbf8e04597eb238ea78dff3d9c5eb4402cb88692d00dbdfee b7f70c7fcabc10b8b3e62fe5ac68476cec23acaee037c7250ff70bca3f3ab541
R 636bb2618e46215e27cfa1dc613ec36a
T +closed b7f70c7fcabc10b8b3e62fe5ac68476cec23acaee037c7250ff70bca3f3ab541
P a90c062d46c63a1e6f83064b1c5afb26a16e93b6ee8620ca46d169fdb325c488
R 25671fe00f59e885629fa15763c01ca2
T *branch * sqlite3_stmt_refresh
T *sym-sqlite3_stmt_refresh *
T -sym-trunk *
U drh
Z 8d21c041010891259262753e78bdd45f
Z 3a35a5d7b215280c71ff1c56378d2e53
+1 -1
View File
@@ -1 +1 @@
a90c062d46c63a1e6f83064b1c5afb26a16e93b6ee8620ca46d169fdb325c488
10556ee454edf60dd6542fdf9017f713c783b9ca1b86f25f45e3c17ffb184e24
+11
View File
@@ -3742,6 +3742,17 @@ int sqlite3_stmt_readonly(sqlite3_stmt *pStmt);
*/
int sqlite3_stmt_busy(sqlite3_stmt*);
/*
** CAPI3REF: Recompile A Prepared Statement If Needed
** METHOD: sqlite3_stmt
**
** ^The sqlite3_stmt_refresh(S) examines the [prepared statement] S
** and attempts to recompile it if it has expired, for example due
** to a schema change. ^If the prepared statement S is up-to-date and
** ready for use, then sqlite3_stmt_refresh(S) is a no-op.
*/
int sqlite3_stmt_refresh(sqlite3_stmt*);
/*
** CAPI3REF: Dynamically Typed Value Object
** KEYWORDS: {protected sqlite3_value} {unprotected sqlite3_value}
+27
View File
@@ -2638,6 +2638,32 @@ static int SQLITE_TCLAPI test_stmt_busy(
return TCL_OK;
}
/*
** Usage: sqlite3_stmt_refresh STMT
**
** Recompile the STMT prepared statement if it needs to be recompiled.
*/
static int SQLITE_TCLAPI test_stmt_refresh(
void * clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
sqlite3_stmt *pStmt;
int rc;
if( objc!=2 ){
Tcl_AppendResult(interp, "wrong # args: should be \"",
Tcl_GetStringFromObj(objv[0], 0), " STMT", 0);
return TCL_ERROR;
}
if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
rc = sqlite3_stmt_refresh(pStmt);
Tcl_SetObjResult(interp, Tcl_NewBooleanObj(rc));
return TCL_OK;
}
/*
** Usage: uses_stmt_journal STMT
**
@@ -7491,6 +7517,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
{ "sqlite3_next_stmt", test_next_stmt ,0 },
{ "sqlite3_stmt_readonly", test_stmt_readonly ,0 },
{ "sqlite3_stmt_busy", test_stmt_busy ,0 },
{ "sqlite3_stmt_refresh", test_stmt_refresh ,0 },
{ "uses_stmt_journal", uses_stmt_journal ,0 },
{ "sqlite3_release_memory", test_release_memory, 0},
+3
View File
@@ -3191,6 +3191,9 @@ case OP_Transaction: {
rc = SQLITE_SCHEMA;
}
if( rc ) goto abort_due_to_error;
if( p->stopAfterInit && pOp[1].opcode!=OP_Transaction ){
goto vdbe_return;
}
break;
}
+1
View File
@@ -392,6 +392,7 @@ struct Vdbe {
bft usesStmtJournal:1; /* True if uses a statement journal */
bft readOnly:1; /* True for statements that do not write */
bft bIsReader:1; /* True for statements that read */
bft stopAfterInit:1; /* Halt after running the last OP_Transaction */
yDbMask btreeMask; /* Bitmask of db->aDb[] entries referenced */
yDbMask lockMask; /* Subset of btreeMask that requires a lock */
u32 aCounter[7]; /* Counters used by sqlite3_stmt_status() */
+22
View File
@@ -1608,6 +1608,28 @@ int sqlite3_stmt_busy(sqlite3_stmt *pStmt){
return v!=0 && v->magic==VDBE_MAGIC_RUN && v->pc>=0;
}
/*
** Recompile the prepared statement if it has expired
*/
int sqlite3_stmt_refresh(sqlite3_stmt *pStmt){
int rc = SQLITE_OK;
if( !sqlite3_stmt_busy(pStmt) ){
VdbeOp *aOp;
Vdbe *v = (Vdbe*)pStmt;
sqlite3_mutex_enter(v->db->mutex);
aOp = v->aOp;
assert( aOp[0].opcode==OP_Init );
if( aOp[aOp[0].p2].opcode==OP_Transaction ){
v->stopAfterInit = 1;
rc = sqlite3_step(pStmt);
v->stopAfterInit = 0;
sqlite3_reset(pStmt);
}
sqlite3_mutex_leave(v->db->mutex);
}
return rc;
}
/*
** Return a pointer to the next prepared statement after pStmt associated
** with database connection pDb. If pStmt is NULL, return the first
+25
View File
@@ -179,5 +179,30 @@ do_test capi3d-4.2.6 {
sqlite3_finalize $::s1
} {SQLITE_OK}
# Tests for the sqlite3_stmt_refresh() interface
#
do_execsql_test capi3d-5.1 {
DROP TABLE IF EXISTS t5;
CREATE TABLE t5(a,b);
INSERT INTO t5 VALUES(1,2),(3,4);
}
do_test capi3d-5.2 {
set ::s1 [sqlite3_prepare_v2 db "SELECT * FROM t5" -1 notused]
sqlite3 db2 test.db
db2 eval {SELECT * FROM t5 ORDER BY a}
} {1 2 3 4}
do_test capi3d-5.3 {
sqlite3_column_count $::s1
} 2
do_test capi3d-5.4 {
db2 eval {ALTER TABLE t5 ADD COLUMN c DEFAULT 9}
sqlite3_column_count $::s1
} 2
do_test capi3d-5.5 {
sqlite3_stmt_refresh $::s1
sqlite3_column_count $::s1
} 3
sqlite3_finalize $::s1
db2 close
finish_test