From 5b88bc4bec6a66d61d1819a69f2c306e3d328e03 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 7 Dec 2013 23:35:21 +0000 Subject: [PATCH] Do not allow cursor hints to use expressions containing subqueries. This change fixes the problem seen in the previous check-in. FossilOrigin-Name: bfefc57554853e467ee6aeaba8d08331406fa216 --- manifest | 21 +++++++++------------ manifest.uuid | 2 +- src/expr.c | 16 ++++++++++++++++ src/select.c | 6 +++--- src/sqliteInt.h | 2 ++ src/where.c | 1 + 6 files changed, 32 insertions(+), 16 deletions(-) diff --git a/manifest b/manifest index 5b7ad9402f..03b9a88b67 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C If\sthe\sSQLITE_ENABLE_CURSOR_HINTS\smacro\sis\sdefined,\sthen\sinvoke\sthe\nsqlite3BtreeCursorHint()\sinterface\sto\sprovide\shints\sto\sthe\sstorage\sengine\nabout\srows\sthat\sneed\snot\sbe\sreturned.\s\sHints\scan\sbe\sdisabled\susing\nSQLITE_TESTCTRL_OPTIMIZATIONS\swith\sSQLITE_CursorHints\s(0x2000).\s\sCursor\nhints\sare\snot\sused\sby\sthe\sbuilt-in\sstorage\sengine\sof\sSQLite\sbut\smight\nbe\suseful\sto\sapplications\sthat\sprovide\stheir\sown\sstorage\sengine.\s\sThe\ncurrent\scode\sis\swork-in-progrss\sand\scontains\sbugs. -D 2013-12-07T20:39:19.762 +C Do\snot\sallow\scursor\shints\sto\suse\sexpressions\scontaining\ssubqueries.\s\sThis\nchange\sfixes\sthe\sproblem\sseen\sin\sthe\sprevious\scheck-in. +D 2013-12-07T23:35:21.843 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -175,7 +175,7 @@ F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 77779efbe78dd678d84bfb4fc2e87b6b6ad8dccd F src/date.c 593c744b2623971e45affd0bde347631bdfa4625 F src/delete.c b36db1f79ee50eaca979660c9dd36437f5410b93 -F src/expr.c 31a2b65339f6c3795d4cfa5e99798cd72f9fdfdf +F src/expr.c cdfc50b604ea9c9bbaa44f1f0a5c6cc835e84a32 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 2ab0f5384b70594468ef3ac5c7ed8ca24bfd17d5 F src/func.c ef30d26ae4d79bbc7300c74e77fd117a0ba30235 @@ -219,12 +219,12 @@ F src/printf.c da9119eb31a187a4b99f60aa4a225141c0ebb74b F src/random.c 0b2dbc37fdfbfa6bd455b091dfcef5bdb32dba68 F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 -F src/select.c d41381d80a22d3a83352aeca274cccf264ac277a +F src/select.c 44fa5a4a270ce70b59acb616b01bc897e6d1e7ac F src/shell.c 936a72ff784efff3832cce274a96ed0b036e6758 F src/sqlite.h.in 125dc0b76f0116f1cd6f13536db52ba981e1c5bd F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc -F src/sqliteInt.h 081102b2fb2aedc0c67d7a631d16a1fb34accc85 +F src/sqliteInt.h ccf72d12670132233750c6275a8ed978a95839aa F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -293,7 +293,7 @@ F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c e9e593d5bb798c3e67fc3893dfe7055c9e7d8d74 -F src/where.c c3bdcd3886e93c129d0ed5a8db17cabde6ea7e73 +F src/where.c 34cf76979535b933b39403f81c8c757cf3c4fe9f F src/whereInt.h 96a75c61f1d2b9d4a8e4bb17d89deb0cf7cba358 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1146,10 +1146,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 23d00f22872a907a8ebf5b80689ff7aa66686a07 -R d784a3d34f33a329aefe46bc5926417e -T *branch * cursor-hints -T *sym-cursor-hints * -T -sym-trunk * +P 3a9bec524ef2de44028b4058e67dc962082888d3 +R e725a27255f076e1cf88ead0905058a7 U drh -Z c7784e25ec311e9981c59aaad7fb1809 +Z 572bab5aee8e2ee9e755c685fab22b9b diff --git a/manifest.uuid b/manifest.uuid index f94f4e8d01..1397cacead 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3a9bec524ef2de44028b4058e67dc962082888d3 \ No newline at end of file +bfefc57554853e467ee6aeaba8d08331406fa216 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 6c8a8cce77..8601d4a9b9 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1264,6 +1264,22 @@ int sqlite3ExprIsConstantOrFunction(Expr *p){ return exprIsConst(p, 2); } +#ifdef SQLITE_ENABLE_CURSOR_HINTS +/* +** Walk an expression tree. Return 1 if the expression contains a +** subquery of some kind. Return 0 if there are no subqueries. +*/ +int sqlite3ExprContainsSubquery(Expr *p){ + Walker w; + memset(&w, 0, sizeof(w)); + w.u.i = 1; + w.xExprCallback = sqlite3ExprWalkNoop; + w.xSelectCallback = selectNodeIsConstant; + sqlite3WalkExpr(&w, p); + return w.u.i==0; +} +#endif + /* ** If the expression p codes a constant integer that is small enough ** to fit in a 32-bit integer, return 1 and put the value of the integer diff --git a/src/select.c b/src/select.c index aa8e54b02f..bb979b8f0e 100644 --- a/src/select.c +++ b/src/select.c @@ -3689,7 +3689,7 @@ static int selectExpander(Walker *pWalker, Select *p){ ** Walker.xSelectCallback is set to do something useful for every ** subquery in the parser tree. */ -static int exprWalkNoop(Walker *NotUsed, Expr *NotUsed2){ +int sqlite3ExprWalkNoop(Walker *NotUsed, Expr *NotUsed2){ UNUSED_PARAMETER2(NotUsed, NotUsed2); return WRC_Continue; } @@ -3710,7 +3710,7 @@ static int exprWalkNoop(Walker *NotUsed, Expr *NotUsed2){ static void sqlite3SelectExpand(Parse *pParse, Select *pSelect){ Walker w; memset(&w, 0, sizeof(w)); - w.xExprCallback = exprWalkNoop; + w.xExprCallback = sqlite3ExprWalkNoop; w.pParse = pParse; if( pParse->hasCompound ){ w.xSelectCallback = convertCompoundSelectToSubquery; @@ -3774,7 +3774,7 @@ static void sqlite3SelectAddTypeInfo(Parse *pParse, Select *pSelect){ Walker w; memset(&w, 0, sizeof(w)); w.xSelectCallback = selectAddSubqueryTypeInfo; - w.xExprCallback = exprWalkNoop; + w.xExprCallback = sqlite3ExprWalkNoop; w.pParse = pParse; w.bSelectDepthFirst = 1; sqlite3WalkSelect(&w, pSelect); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 45d78f5663..8cb7820e3d 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2617,6 +2617,7 @@ int sqlite3WalkExprList(Walker*, ExprList*); int sqlite3WalkSelect(Walker*, Select*); int sqlite3WalkSelectExpr(Walker*, Select*); int sqlite3WalkSelectFrom(Walker*, Select*); +int sqlite3ExprWalkNoop(Walker*, Expr*); /* ** Return code from the parse-tree walking primitives and their @@ -2971,6 +2972,7 @@ void sqlite3LeaveMutexAndCloseZombie(sqlite3*); int sqlite3ExprIsConstant(Expr*); int sqlite3ExprIsConstantNotJoin(Expr*); int sqlite3ExprIsConstantOrFunction(Expr*); +int sqlite3ExprContainsSubquery(Expr*); int sqlite3ExprIsInteger(Expr*, int*); int sqlite3ExprCanBeNull(const Expr*); void sqlite3ExprCodeIsNullJump(Vdbe*, const Expr*, int, int); diff --git a/src/where.c b/src/where.c index bbe5939ed2..9d6679a866 100644 --- a/src/where.c +++ b/src/where.c @@ -2745,6 +2745,7 @@ static void codeCursorHint( pTerm = &pWC->a[i]; if( pTerm->prereqAll & msk ) continue; if( ExprHasProperty(pTerm->pExpr, EP_FromJoin) ) continue; + if( sqlite3ExprContainsSubquery(pTerm->pExpr) ) continue; for(j=0; jnLTerm && pWLoop->aLTerm[j]!=pTerm; j++){} if( jnLTerm ) continue; pExpr = sqlite3ExprAnd(db, pExpr, sqlite3ExprDup(db, pTerm->pExpr, 0)); -- 2.47.2