From 83dcb1ad37dfd4e45983ca1604cd14d32e06f8a6 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 28 Jun 2002 01:02:38 +0000 Subject: [PATCH] Fix for ticket #84: If the WHERE clause is too complex, issue an error message and refuse to do the SELECT. The cutoff is a WHERE clause with 100 terms. (CVS 650) FossilOrigin-Name: c07e493b62125e85eaea36b6945f1e146e2792b8 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/vdbe.c | 4 +++- src/where.c | 30 ++++++++++++++++++------------ test/misc1.test | 45 ++++++++++++++++++++++++++++++++++++++++++++- 5 files changed, 74 insertions(+), 23 deletions(-) diff --git a/manifest b/manifest index 0cbd82b635..c9029b73cf 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sfor\sticket\s#88:\sA\stypo\sin\sthe\sdocumention\sof\sthe\s"sqlite"\sshell\scommand.\s(CVS\s649) -D 2002-06-27T13:21:02 +C Fix\sfor\sticket\s#84:\sIf\sthe\sWHERE\sclause\sis\stoo\scomplex,\sissue\san\serror\smessage\nand\srefuse\sto\sdo\sthe\sSELECT.\s\sThe\scutoff\sis\sa\sWHERE\sclause\swith\s100\sterms.\s(CVS\s650) +D 2002-06-28T01:02:38 F Makefile.in 6291a33b87d2a395aafd7646ee1ed562c6f2c28c F Makefile.template 4e11752e0b5c7a043ca50af4296ec562857ba495 F README a4c0ba11354ef6ba0776b400d057c59da47a4cc0 @@ -52,9 +52,9 @@ F src/tokenize.c ac4c46f190346b87da54ec3e2605d160af80c619 F src/trigger.c d88ab4d68d68955c217b38fb6717e090fbbf54a4 F src/update.c 6f6a4dcd71cd9ff730b7f12c83de5498cde4924f F src/util.c 876b259f9186e84b944b72e793dd3dad50e63e95 -F src/vdbe.c 2d9e418e45b75ac361e8e3ba96d84ce0a1ff9139 +F src/vdbe.c 0c7783ba52b1bd9e40331937c32d3aa3351ff4a3 F src/vdbe.h a9292f2b5fcecef924fa255fb74609e9cbc776c2 -F src/where.c 913fa33977c8dddfc259d9b2c38504b475738c43 +F src/where.c e692b238fa0b45c159ab736da3fad2703800a0ca F test/all.test e4d3821eeba751829b419cd47814bd20af4286d1 F test/bigrow.test 8ab252dba108f12ad64e337b0f2ff31a807ac578 F test/btree.test bf326f546a666617367a7033fa2c07451bd4f8e1 @@ -77,7 +77,7 @@ F test/lock.test f1b55dc61632e99d241643cc8e7c03774f09f623 F test/main.test c66b564554b770ee7fdbf6a66c0cd90329bc2c85 F test/malloc.test 7ba32a9ebd3aeed52ae4aaa6d42ca37e444536fd F test/minmax.test 29bc5727c3e4c792d5c4745833dd4b505905819e -F test/misc1.test 18c74cdfa6cc920f1c51827ccb23a442c62caefb +F test/misc1.test 13584dda012d7d10b5163c2cecd60ab25496b987 F test/misuse.test a3aa2b18a97e4c409a1fcaff5151a4dd804a0162 F test/notnull.test b1f3e42fc475b0b5827b27b2e9b562081995ff30 F test/null.test 5c2b57307e4b6178aae825eb65ddbee01e76b0fd @@ -137,7 +137,7 @@ F www/speed.tcl da8afcc1d3ccc5696cfb388a68982bc3d9f7f00f F www/sqlite.tcl ae3dcfb077e53833b59d4fcc94d8a12c50a44098 F www/tclsqlite.tcl 1db15abeb446aad0caf0b95b8b9579720e4ea331 F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218 -P 9ca6368525fe81fe9c78c6911f4d23009ce858d5 -R 64604f95a1ca21aa191d2c12711489ff +P 16552a7a29450a23765f0f05a9f4058638eafd74 +R 0b306828319c3c6ac72442b55b9bb1d4 U drh -Z 124e1d748152c1b96bd4bcf09a107eb2 +Z cd2730365c5ef98d487b1c111506dfad diff --git a/manifest.uuid b/manifest.uuid index 787f7af51d..3449317de9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -16552a7a29450a23765f0f05a9f4058638eafd74 \ No newline at end of file +c07e493b62125e85eaea36b6945f1e146e2792b8 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 415ad5f044..1d3cbd9fa2 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -30,7 +30,7 @@ ** But other routines are also provided to help in building up ** a program instruction by instruction. ** -** $Id: vdbe.c,v 1.161 2002/06/26 02:45:04 drh Exp $ +** $Id: vdbe.c,v 1.162 2002/06/28 01:02:38 drh Exp $ */ #include "sqliteInt.h" #include @@ -2845,6 +2845,8 @@ case OP_Commit: { if( rc==SQLITE_OK ){ sqliteCommitInternalChanges(db); }else{ + if( db->pBeTemp ) sqliteBtreeRollback(db->pBeTemp); + sqliteBtreeRollback(pBt); sqliteRollbackInternalChanges(db); } break; diff --git a/src/where.c b/src/where.c index 9a90f6269d..0d271fa9a5 100644 --- a/src/where.c +++ b/src/where.c @@ -13,7 +13,7 @@ ** the WHERE clause of SQL statements. Also found here are subroutines ** to generate VDBE code to evaluate expressions. ** -** $Id: where.c,v 1.56 2002/06/25 01:09:12 drh Exp $ +** $Id: where.c,v 1.57 2002/06/28 01:02:38 drh Exp $ */ #include "sqliteInt.h" @@ -304,12 +304,28 @@ WhereInfo *sqliteWhereBegin( int iDirectEq[32]; /* Term of the form ROWID==X for the N-th table */ int iDirectLt[32]; /* Term of the form ROWIDX or ROWID>=X */ - ExprInfo aExpr[50]; /* The WHERE clause is divided into these expressions */ + ExprInfo aExpr[101]; /* The WHERE clause is divided into these expressions */ /* pushKey is only allowed if there is a single table (as in an INSERT or ** UPDATE statement) */ assert( pushKey==0 || pTabList->nSrc==1 ); + + /* Split the WHERE clause into separate subexpressions where each + ** subexpression is separated by an AND operator. If the aExpr[] + ** array fills up, the last entry might point to an expression which + ** contains additional unfactored AND operators. + */ + memset(aExpr, 0, sizeof(aExpr)); + nExpr = exprSplit(ARRAYSIZE(aExpr), aExpr, pWhere); + if( nExpr==ARRAYSIZE(aExpr) ){ + char zBuf[50]; + sprintf(zBuf, "%d", ARRAYSIZE(aExpr)-1); + sqliteSetString(&pParse->zErrMsg, "WHERE clause too complex - no more " + "than ", zBuf, " terms allowed", 0); + pParse->nErr++; + return 0; + } /* Allocate space for aOrder[] */ aOrder = sqliteMalloc( sizeof(int) * pTabList->nSrc ); @@ -337,16 +353,6 @@ WhereInfo *sqliteWhereBegin( pWhere = 0; } - /* Split the WHERE clause into as many as 32 separate subexpressions - ** where each subexpression is separated by an AND operator. Any additional - ** subexpressions are attached in the aExpr[32] and will not enter - ** into the query optimizer computations. 32 is chosen as the cutoff - ** since that is the number of bits in an integer that we use for an - ** expression-used mask. - */ - memset(aExpr, 0, sizeof(aExpr)); - nExpr = exprSplit(ARRAYSIZE(aExpr), aExpr, pWhere); - /* Analyze all of the subexpressions. */ for(i=0; i=0} + for {set i 1} {$i<=99} {incr i} { + append ::where " AND x$i<>0" + } + catchsql "SELECT count(*) FROM manycol $::where" +} {0 9} +do_test misc1-10.2 { + catchsql "SELECT count(*) FROM manycol $::where AND rowid>0" +} {1 {WHERE clause too complex - no more than 100 terms allowed}} +do_test misc1-10.3 { + regsub "x0>=0" $::where "x0=0" ::where + catchsql "DELETE FROM manycol $::where" +} {0 {}} +do_test misc1-10.4 { + execsql {SELECT count(*) FROM manycol} +} {8} +do_test misc1-10.5 { + catchsql "DELETE FROM manycol $::where AND rowid>0" +} {1 {WHERE clause too complex - no more than 100 terms allowed}} +do_test misc1-10.6 { + execsql {SELECT x1 FROM manycol WHERE x0=100} +} {101} +do_test misc1-10.7 { + regsub "x0=0" $::where "x0=100" ::where + catchsql "UPDATE manycol SET x1=x1+1 $::where" +} {0 {}} +do_test misc1-10.8 { + execsql {SELECT x1 FROM manycol WHERE x0=100} +} {102} +do_test misc1-10.9 { + catchsql "UPDATE manycol SET x1=x1+1 $::where AND rowid>0" +} {1 {WHERE clause too complex - no more than 100 terms allowed}} +do_test misc1-10.10 { + execsql {SELECT x1 FROM manycol WHERE x0=100} +} {102} + finish_test