-C Ensure\ssqlite3expert.c\sunregisters\sany\sSQL\suser-functions\sit\sregisters\swith\sthe\sdatabase\shandle\sbefore\sreturning.
-D 2024-08-08T15:26:11.708
+C If\sthere\sis\sany\squestion\sabout\swhether\sor\snot\sthe\sWHERE_IDX_ONLY\sflag\sin\sthe\nquery\splanner\sis\scorrect,\screate\sa\sbackup\snull-cursor\sfor\sthe\stable,\sso\sthat\nwe\snever\stry\sto\srun\san\sOP_Column\sagainst\san\sunopened\scursor.
+D 2024-08-09T01:38:14.598
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
F src/dbpage.c 80e46e1df623ec40486da7a5086cb723b0275a6e2a7b01d9f9b5da0f04ba2782
F src/dbstat.c 3b677254d512fcafd4d0b341bf267b38b235ccfddbef24f9154e19360fa22e43
F src/delete.c cb766727c78e715f9fb7ec8a7d03658ed2a3016343ca687acfcec9083cdca500
-F src/expr.c fe958028b36af640b70b2174354c044f75b8c4a4645c921592122aa2a022083a
+F src/expr.c 79ac19d455e14b3ca52812f4cc0b3d694b5b9074442e9e643601439f05086f20
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
F src/fkey.c 852f93c0ef995e0c2b8983059a2b97151c194cc8259e21f5bc2b7ac508348c2a
F src/func.c 1f61e32e7a357e615b5d2e774bee563761fce4f2fd97ecb0f72c33e62a2ada5f
F src/wal.c 887fc4ca3f020ebb2e376f222069570834ac63bf50111ef0cbf3ae417048ed89
F src/wal.h ba252daaa94f889f4b2c17c027e823d9be47ce39da1d3799886bbd51f0490452
F src/walker.c 7c7ea0115345851c3da4e04e2e239a29983b61fb5b038b94eede6aba462640e2
-F src/where.c 5bbe53db73ae6c8ee34a5eab693a5586ad8ff4f094ff0e524df965b683bec884
+F src/where.c b1c25ee0a1e9546a8929b00e59abc62c4421068ba74b1d20c87e448543506cef
F src/whereInt.h 002adc3aa2cc10733b9b27958fdbe893987cd989fab25a9853941c1f9b9b0a65
F src/wherecode.c c9cac0b0b8e809c5e7e79d7796918907fb685ad99be2aaa9737f9787aa47349c
F src/whereexpr.c 7d0d34b42b9edfd8e8ca66beb3a6ef63fe211c001af54caf2ccbcd989b783290
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 797b0a13fd7a42b0a48ecbf0cd1961aa932da3e9c9ccffd903a3a4d963d0cc54
-R 524433c41a8ffc46e95c387bd9dc2975
-U dan
-Z fa7382f01ce16aee65751b978df534e7
+P 123b154ce3b6fee1bbf483704812bd6f8538966f9687520b4470d700f0270719
+R 3ee712d9b08c2746de61c5d667402293
+T *branch * defensive-null-cursor
+T *sym-defensive-null-cursor *
+T -sym-trunk *
+U drh
+Z d76829c48a82072ec06d5f57872d0f44
# Remove this line to create a well-formed Fossil manifest.
}
#endif /* SQLITE_DEBUG */
+/*
+** Make arrangements to open cursor number iCur in the startup code of
+** the prepared statement. This cursor will always returns NULL
+** for any OP_Column opcode.
+*/
+static SQLITE_NOINLINE void sqlite3OpenNullCursor(Parse *pParse, int iCur){
+ Expr e;
+ memset(&e, 0, sizeof(e));
+ e.op = TK_TABLE;
+ e.iTable = iCur;
+ sqlite3ExprCodeRunJustOnce(pParse, &e, -1);
+}
+
+
/*
** Generate the end of the WHERE loop. See comments on
** sqlite3WhereBegin() for additional information.
assert( pIdx->pTable==pTab );
#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
if( pOp->opcode==OP_Offset ){
- /* Do not need to translate the column number */
+ x = 0;
}else
#endif
- if( !HasRowid(pTab) ){
- Index *pPk = sqlite3PrimaryKeyIndex(pTab);
- x = pPk->aiColumn[x];
- assert( x>=0 );
- }else{
- testcase( x!=sqlite3StorageColumnToTable(pTab,x) );
- x = sqlite3StorageColumnToTable(pTab,x);
+ {
+ if( !HasRowid(pTab) ){
+ Index *pPk = sqlite3PrimaryKeyIndex(pTab);
+ x = pPk->aiColumn[x];
+ assert( x>=0 );
+ }else{
+ testcase( x!=sqlite3StorageColumnToTable(pTab,x) );
+ x = sqlite3StorageColumnToTable(pTab,x);
+ }
+ x = sqlite3TableColumnToIndex(pIdx, x);
}
- x = sqlite3TableColumnToIndex(pIdx, x);
if( x>=0 ){
pOp->p2 = x;
pOp->p1 = pLevel->iIdxCur;
OpcodeRewriteTrace(db, k, pOp);
- }else{
- /* Unable to translate the table reference into an index
- ** reference. Verify that this is harmless - that the
- ** table being referenced really is open.
- */
-#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
- assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0
- || cursorIsOpen(v,pOp->p1,k)
- || pOp->opcode==OP_Offset
- );
-#else
- assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0
- || cursorIsOpen(v,pOp->p1,k)
- );
-#endif
+ }else if( pLoop->wsFlags & WHERE_IDX_ONLY ){
+ OpcodeRewriteTrace(db, k, pOp);
+ assert( cursorIsOpen(v,pOp->p1,k) );
+
+ /* This following call to sqlite3OpenNullCursor() is defensive
+ ** code. The null cursor should never be used, unless there is
+ ** a bug in the covering-index logic of the query planner, in
+ ** which case the null cursor might prevent a NULL-pointer
+ ** dereference in OP_Column. */
+ sqlite3OpenNullCursor(pParse, pLevel->iTabCur);
}
}else if( pOp->opcode==OP_Rowid ){
pOp->p1 = pLevel->iIdxCur;