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
This commit is contained in:
drh 2002-06-28 01:02:38 +00:00
parent ac83f718fc
commit 83dcb1ad37
5 changed files with 74 additions and 23 deletions

View File

@ -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

View File

@ -1 +1 @@
16552a7a29450a23765f0f05a9f4058638eafd74
c07e493b62125e85eaea36b6945f1e146e2792b8

View File

@ -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 <ctype.h>
@ -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;

View File

@ -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 ROWID<X or ROWID<=X */
int iDirectGt[32]; /* Term of the form ROWID>X 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<nExpr; i++){

View File

@ -13,7 +13,7 @@
# This file implements tests for miscellanous features that were
# left out of other test files.
#
# $Id: misc1.test,v 1.9 2002/06/21 23:01:51 drh Exp $
# $Id: misc1.test,v 1.10 2002/06/28 01:02:39 drh Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
@ -258,4 +258,47 @@ do_test misc1-9.1 {
}
} {0 {a 12345678901234567890 b 12345678911234567890 c 12345678921234567890}}
# A WHERE clause is not allowed to contain more than 99 terms. Check to
# make sure this limit is enforced.
#
do_test misc1-10.0 {
execsql {SELECT count(*) FROM manycol}
} {9}
do_test misc1-10.1 {
set ::where {WHERE x0>=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