diff options
author | danielk1977 <danielk1977@noemail.net> | 2007-05-10 10:46:56 +0000 |
---|---|---|
committer | danielk1977 <danielk1977@noemail.net> | 2007-05-10 10:46:56 +0000 |
commit | fc9760654ae33e2385d15fef23a77de0ce7ed05f (patch) | |
tree | 424facab1d365a44d7575058432716dfb4d17233 | |
parent | e305f43f1782896906e699fd67c2559daeca09a9 (diff) | |
download | sqlite-fc9760654ae33e2385d15fef23a77de0ce7ed05f.tar.gz sqlite-fc9760654ae33e2385d15fef23a77de0ce7ed05f.zip |
Add code to enforce the MAX_EXPR_DEPTH limit. (CVS 3968)
FossilOrigin-Name: 2c9c94a24d52a1c9f5d1b32cbdff794a2dd74126
-rw-r--r-- | manifest | 26 | ||||
-rw-r--r-- | manifest.uuid | 2 | ||||
-rw-r--r-- | src/expr.c | 92 | ||||
-rw-r--r-- | src/limits.h | 15 | ||||
-rw-r--r-- | src/parse.y | 8 | ||||
-rw-r--r-- | src/select.c | 15 | ||||
-rw-r--r-- | src/sqliteInt.h | 15 | ||||
-rw-r--r-- | src/test_config.c | 8 | ||||
-rw-r--r-- | test/sqllimits1.test | 67 |
9 files changed, 201 insertions, 47 deletions
@@ -1,5 +1,5 @@ -C Make\ssure\scompound\squeries\sinside\sa\ssubquery\sonly\sreturn\sa\ssingle\sresult\ncolumn.\s\sTicket\s#2347.\s(CVS\s3967) -D 2007-05-09T22:56:39 +C Add\scode\sto\senforce\sthe\sMAX_EXPR_DEPTH\slimit.\s(CVS\s3968) +D 2007-05-10T10:46:56 F Makefile.in 87b200ad9970907f76df734d29dff3d294c10935 F Makefile.linux-gcc 2d8574d1ba75f129aba2019f0b959db380a90935 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028 @@ -70,13 +70,13 @@ F src/complete.c 7d1a44be8f37de125fcafd3d3a018690b3799675 F src/date.c 6049db7d5a8fdf2c677ff7d58fa31d4f6593c988 F src/delete.c 5c0d89b3ef7d48fe1f5124bfe8341f982747fe29 F src/experimental.c 1b2d1a6cd62ecc39610e97670332ca073c50792b -F src/expr.c 1f3c365fc5aa2a03395cf470346f3646382469c2 +F src/expr.c 65b8a3dff2cdf1b21292996508688d5a1b93200f F src/func.c 6282d2025d8e0db80b43783a4778cbb04e98f2f6 F src/hash.c 67b23e14f0257b69a3e8aa663e4eeadc1a2b6fd5 F src/hash.h 1b3f7e2609141fd571f62199fc38687d262e9564 F src/insert.c e595ca26805dfb3a9ebaabc28e7947c479f3b14d F src/legacy.c 388c71ad7fbcd898ba1bcbfc98a3ac954bfa5d01 -F src/limits.h 6226e6157ee798b3f19c3fc969a0ae4832393476 +F src/limits.h cf772eb244aae5859fa1554394866c27d3f3639c F src/loadext.c afe4f4755dc49c36ef505748bbdddecb9f1d02a2 F src/main.c 797dc983716c1480f6af78a36be3add8806211a1 F src/malloc.c b89e31258a85158d15795bf87ae3ba007e56329b @@ -94,17 +94,17 @@ F src/os_win.c 3b6169038101d06c54b4f04662bfd44b6cf2f289 F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b F src/pager.c acfa86f50b71b7e289508b213bb88e68273d42a0 F src/pager.h 94110a5570dca30d54a883e880a3633b2e4c05ae -F src/parse.y fe7efcbf0ef1727cb2c08c1a10869b4ac9d5e71d +F src/parse.y 39b25cc7f9e1a1a999f367545192c35db644610d F src/pragma.c 0703152b9edd6601eea95e1d474b3bc2962d7920 F src/prepare.c 87c23644986b5e41a58bc76f05abebd899e00089 F src/printf.c 67de0dcb40ef3297f4a047b434b81585c0f7062d F src/random.c 6119474a6f6917f708c1dee25b9a8e519a620e88 -F src/select.c 87bcf7406ab55baec791c49f8926def7bb1c07e2 +F src/select.c d43bbdedb843a91b728531c831f3ed04846b920d F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96 F src/shell.c d07ae326b3815d80f71c69b3c7584382e47f6447 F src/sqlite.h.in 664b8702c27dc742584788823c548491ac8935d6 F src/sqlite3ext.h 7d0d363ea7327e817ef0dfe1b7eee1f171b72890 -F src/sqliteInt.h 2a4ec9eb67f7d1c634a5bfad9915549f9d3ac919 +F src/sqliteInt.h 7e7faee79b811ff54796d71bf8aa3dc76b1b1a95 F src/table.c a8de75bcedf84d4060d804264b067ab3b1a3561d F src/tclsqlite.c f425c7583665ef78dd8397b2de0b8e0028e80ce2 F src/test1.c 16938b7e76469abf957745743dd0287d5dee476d @@ -119,7 +119,7 @@ F src/test9.c c0f38f7795cc51d37db6c63874d90f40f10d0f0e F src/test_async.c 9d326ceda4306bcab252b8f7e8e480ed45d7ccb6 F src/test_autoext.c 855157d97aa28cf84233847548bfacda21807436 F src/test_btree.c 882d59acad48bab3b1fe3daf3645059b590cfc79 -F src/test_config.c 4c1db31befcbf6206766bbbb429d0e6a1254cdc7 +F src/test_config.c 14080fbd60d334c17bf9610c8ac31814a7ad3832 F src/test_hexio.c 32204b5ce281ebc85f789c69c4ec725129e7e7f5 F src/test_loadext.c 22065d601a18878e5542191001f0eaa5d77c0ed8 F src/test_md5.c 6c42bc0a3c0b54be34623ff77a0eec32b2fa96e3 @@ -340,7 +340,7 @@ F test/shared_err.test cc528f6e78665787e93d9ce3a782a2ce5179d821 F test/sort.test 0e4456e729e5a92a625907c63dcdedfbe72c5dc5 F test/speed1.test 22e1b27af0683ed44dcd2f93ed817a9c3e65084a F test/speed2.test 53177056baf6556dcbdcf032bbdfc41c1aa74ded -F test/sqllimits1.test d5d0047bd2d3f5a50c596cf0800cee223fe32ff9 +F test/sqllimits1.test 674866819ff42075a1cefbc4bd147f24a81e45e3 F test/subquery.test ae324ee928c5fb463a3ce08a8860d6e7f1ca5797 F test/subselect.test 974e87f8fc91c5f00dd565316d396a5a6c3106c4 F test/sync.test d05397b8f89f423dd6dba528692019ab036bc1c3 @@ -486,7 +486,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5 -P c0dbac46301039246afd4bebb71dd8184fc5c0c7 -R ce1d9a31f5642fc3adec7a89c841905a -U drh -Z f08cc8911b7b4f7d10aa7482cf6b823e +P 66954bdd81dabfb60306de8480b5477a4acb1d9e +R 22592093c0c06bde534ff11e74de00ec +U danielk1977 +Z 44dafc85e209c0119e527fcc4f0a9e17 diff --git a/manifest.uuid b/manifest.uuid index 3f940d335..24dc883fb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -66954bdd81dabfb60306de8480b5477a4acb1d9e
\ No newline at end of file +2c9c94a24d52a1c9f5d1b32cbdff794a2dd74126
\ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 828cf6050..e7358b554 100644 --- a/src/expr.c +++ b/src/expr.c @@ -12,7 +12,7 @@ ** This file contains routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions in SQLite. ** -** $Id: expr.c,v 1.288 2007/05/09 11:37:23 danielk1977 Exp $ +** $Id: expr.c,v 1.289 2007/05/10 10:46:56 danielk1977 Exp $ */ #include "sqliteInt.h" #include <ctype.h> @@ -247,6 +247,8 @@ Expr *sqlite3Expr(int op, Expr *pLeft, Expr *pRight, const Token *pToken){ pNew->pColl = pLeft->pColl; } } + + sqlite3ExprSetHeight(pNew); return pNew; } @@ -343,6 +345,8 @@ Expr *sqlite3ExprFunction(ExprList *pList, Token *pToken){ assert( pToken->dyn==0 ); pNew->token = *pToken; pNew->span = pNew->token; + + sqlite3ExprSetHeight(pNew); return pNew; } @@ -478,6 +482,9 @@ Expr *sqlite3ExprDup(Expr *p){ pNew->pList = sqlite3ExprListDup(p->pList); pNew->pSelect = sqlite3SelectDup(p->pSelect); pNew->pTab = p->pTab; +#if SQLITE_MAX_EXPR_DEPTH>0 + pNew->nHeight = p->nHeight; +#endif return pNew; } void sqlite3TokenCopy(Token *pTo, Token *pFrom){ @@ -671,6 +678,72 @@ void sqlite3ExprListCheckLength( } } + +#if SQLITE_MAX_EXPR_DEPTH>0 +/* The following three functions, heightOfExpr(), heightOfExprList() +** and heightOfSelect(), are used to determine the maximum height +** of any expression tree referenced by the structure passed as the +** first argument. +** +** If this maximum height is greater than the current value pointed +** to by pnHeight, the second parameter, then set *pnHeight to that +** value. +*/ +static void heightOfExpr(Expr *p, int *pnHeight){ + if( p ){ + if( p->nHeight>*pnHeight ){ + *pnHeight = p->nHeight; + } + } +} +static void heightOfExprList(ExprList *p, int *pnHeight){ + if( p ){ + int i; + for(i=0; i<p->nExpr; i++){ + heightOfExpr(p->a[i].pExpr, pnHeight); + } + } +} +static void heightOfSelect(Select *p, int *pnHeight){ + if( p ){ + heightOfExpr(p->pWhere, pnHeight); + heightOfExpr(p->pHaving, pnHeight); + heightOfExpr(p->pLimit, pnHeight); + heightOfExpr(p->pOffset, pnHeight); + heightOfExprList(p->pEList, pnHeight); + heightOfExprList(p->pGroupBy, pnHeight); + heightOfExprList(p->pOrderBy, pnHeight); + heightOfSelect(p->pPrior, pnHeight); + } +} + +/* +** Set the Expr.nHeight variable in the structure passed as an +** argument. An expression with no children, Expr.pList or +** Expr.pSelect member has a height of 1. Any other expression +** has a height equal to the maximum height of any other +** referenced Expr plus one. +*/ +void sqlite3ExprSetHeight(Expr *p){ + int nHeight = 0; + heightOfExpr(p->pLeft, &nHeight); + heightOfExpr(p->pRight, &nHeight); + heightOfExprList(p->pList, &nHeight); + heightOfSelect(p->pSelect, &nHeight); + p->nHeight = nHeight + 1; +} + +/* +** Return the maximum height of any expression tree referenced +** by the select statement passed as an argument. +*/ +int sqlite3SelectExprHeight(Select *p){ + int nHeight = 0; + heightOfSelect(p, &nHeight); + return nHeight; +} +#endif + /* ** Delete an entire expression list. */ @@ -1335,15 +1408,28 @@ static int nameResolverStep(void *pArg, Expr *pExpr){ ** If the expression contains aggregate functions then set the EP_Agg ** property on the expression. */ -int sqlite3ExprResolveNames( +int sqlite3ExprResolveNames( NameContext *pNC, /* Namespace to resolve expressions in. */ Expr *pExpr /* The expression to be analyzed. */ ){ int savedHasAgg; if( pExpr==0 ) return 0; +#if SQLITE_MAX_EXPR_DEPTH>0 + if( (pExpr->nHeight+pNC->pParse->nHeight)>SQLITE_MAX_EXPR_DEPTH ){ + sqlite3ErrorMsg(pNC->pParse, + "Expression tree is too large (maximum depth %d)", + SQLITE_MAX_EXPR_DEPTH + ); + return 1; + } + pNC->pParse->nHeight += pExpr->nHeight; +#endif savedHasAgg = pNC->hasAgg; pNC->hasAgg = 0; walkExprTree(pExpr, nameResolverStep, pNC); +#if SQLITE_MAX_EXPR_DEPTH>0 + pNC->pParse->nHeight -= pExpr->nHeight; +#endif if( pNC->nErr>0 ){ ExprSetProperty(pExpr, EP_Error); } @@ -1384,6 +1470,7 @@ void sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){ Vdbe *v = sqlite3GetVdbe(pParse); if( v==0 ) return; + /* This code must be run in its entirety every time it is encountered ** if any of the following is true: ** @@ -1521,6 +1608,7 @@ void sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){ if( testAddr ){ sqlite3VdbeJumpHere(v, testAddr); } + return; } #endif /* SQLITE_OMIT_SUBQUERY */ diff --git a/src/limits.h b/src/limits.h index ff7bdfde0..21c36680b 100644 --- a/src/limits.h +++ b/src/limits.h @@ -12,7 +12,7 @@ ** ** This file defines various limits of what SQLite can process. ** -** @(#) $Id: limits.h,v 1.5 2007/05/08 15:34:48 drh Exp $ +** @(#) $Id: limits.h,v 1.6 2007/05/10 10:46:56 danielk1977 Exp $ */ /* @@ -56,13 +56,14 @@ #endif /* -** The maximum number of terms in an expression. -** This is limited to some extent by SQLITE_MAX_SQL_LENGTH. -** But sometime you might want to place more severe limits -** on the complexity of an expression. +** The maximum depth of an expression tree. This is limited to +** some extent by SQLITE_MAX_SQL_LENGTH. But sometime you might +** want to place more severe limits on the complexity of an +** expression. A value of 0 (the default) means do not enforce +** any limitation on expression tree depth. */ -#ifndef SQLITE_MAX_EXPR_LENGTH -# define SQLITE_MAX_EXPR_LENGTH 5000 +#ifndef SQLITE_MAX_EXPR_DEPTH +# define SQLITE_MAX_EXPR_DEPTH 0 #endif /* diff --git a/src/parse.y b/src/parse.y index a7e07b9a7..991a93269 100644 --- a/src/parse.y +++ b/src/parse.y @@ -14,7 +14,7 @@ ** the parser. Lemon will also generate a header file containing ** numeric codes for all of the tokens. ** -** @(#) $Id: parse.y,v 1.224 2007/05/08 17:54:44 danielk1977 Exp $ +** @(#) $Id: parse.y,v 1.225 2007/05/10 10:46:57 danielk1977 Exp $ */ // All token codes are small integers with #defines that begin with "TK_" @@ -766,6 +766,7 @@ expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] { A = sqlite3Expr(TK_IN, X, 0, 0); if( A ){ A->pList = Y; + sqlite3ExprSetHeight(A); }else{ sqlite3ExprListDelete(Y); } @@ -776,6 +777,7 @@ expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] { A = sqlite3Expr(TK_SELECT, 0, 0, 0); if( A ){ A->pSelect = X; + sqlite3ExprSetHeight(A); }else{ sqlite3SelectDelete(X); } @@ -785,6 +787,7 @@ expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] { A = sqlite3Expr(TK_IN, X, 0, 0); if( A ){ A->pSelect = Y; + sqlite3ExprSetHeight(A); }else{ sqlite3SelectDelete(Y); } @@ -796,6 +799,7 @@ expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] { A = sqlite3Expr(TK_IN, X, 0, 0); if( A ){ A->pSelect = sqlite3SelectNew(0,pSrc,0,0,0,0,0,0,0); + sqlite3ExprSetHeight(A); }else{ sqlite3SrcListDelete(pSrc); } @@ -807,6 +811,7 @@ expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] { if( p ){ p->pSelect = Y; sqlite3ExprSpan(p,&B,&E); + sqlite3ExprSetHeight(A); }else{ sqlite3SelectDelete(Y); } @@ -818,6 +823,7 @@ expr(A) ::= CASE(C) case_operand(X) case_exprlist(Y) case_else(Z) END(E). { A = sqlite3Expr(TK_CASE, X, Z, 0); if( A ){ A->pList = Y; + sqlite3ExprSetHeight(A); }else{ sqlite3ExprListDelete(Y); } diff --git a/src/select.c b/src/select.c index 83c9d6b67..dd8b81d82 100644 --- a/src/select.c +++ b/src/select.c @@ -12,7 +12,7 @@ ** This file contains C code routines that are called by the parser ** to handle SELECT statements in SQLite. ** -** $Id: select.c,v 1.343 2007/05/09 22:56:39 drh Exp $ +** $Id: select.c,v 1.344 2007/05/10 10:46:57 danielk1977 Exp $ */ #include "sqliteInt.h" @@ -2940,8 +2940,21 @@ int sqlite3Select( }else{ needRestoreContext = 0; } +#if SQLITE_MAX_EXPR_DEPTH>0 + /* Increment Parse.nHeight by the height of the largest expression + ** tree refered to by this, the parent select. The child select + ** may contain expression trees of at most + ** (SQLITE_MAX_EXPR_DEPTH-Parse.nHeight) height. This is a bit + ** more conservative than necessary, but much easier than enforcing + ** an exact limit. + */ + pParse->nHeight += sqlite3SelectExprHeight(p); +#endif sqlite3Select(pParse, pItem->pSelect, SRT_EphemTab, pItem->iCursor, p, i, &isAgg, 0); +#if SQLITE_MAX_EXPR_DEPTH>0 + pParse->nHeight -= sqlite3SelectExprHeight(p); +#endif if( needRestoreContext ){ pParse->zAuthContext = zSavedAuthContext; } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 8daf349ba..fc2525f8f 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -11,7 +11,7 @@ ************************************************************************* ** Internal interface definitions for SQLite. ** -** @(#) $Id: sqliteInt.h,v 1.562 2007/05/08 21:45:28 drh Exp $ +** @(#) $Id: sqliteInt.h,v 1.563 2007/05/10 10:46:57 danielk1977 Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ @@ -998,6 +998,9 @@ struct Expr { ** right side of "<expr> IN (<select>)" */ Table *pTab; /* Table for OP_Column expressions. */ Schema *pSchema; +#if SQLITE_MAX_EXPR_DEPTH>0 + int nHeight; /* Height of the tree headed by this node */ +#endif }; /* @@ -1343,6 +1346,9 @@ struct Parse { u8 declareVtab; /* True if inside sqlite3_declare_vtab() */ Table *pVirtualLock; /* Require virtual table lock on this table */ #endif +#if SQLITE_MAX_EXPR_DEPTH>0 + int nHeight; /* Expression tree height of current sub-select */ +#endif }; #ifdef SQLITE_OMIT_VIRTUALTABLE @@ -1878,6 +1884,13 @@ void sqlite3InvalidFunction(sqlite3_context*,int,sqlite3_value**); int sqlite3Reprepare(Vdbe*); void sqlite3ExprListCheckLength(Parse*, ExprList*, int, const char*); +#if SQLITE_MAX_EXPR_DEPTH>0 + void sqlite3ExprSetHeight(Expr *); + int sqlite3SelectExprHeight(Select *); +#else + #define sqlite3ExprSetHeight(x) +#endif + u32 sqlite3Get2byte(const u8*); u32 sqlite3Get4byte(const u8*); void sqlite3Put2byte(u8*, u32); diff --git a/src/test_config.c b/src/test_config.c index 40c021557..7f4689e51 100644 --- a/src/test_config.c +++ b/src/test_config.c @@ -16,7 +16,7 @@ ** The focus of this file is providing the TCL testing layer ** access to compile-time constants. ** -** $Id: test_config.c,v 1.3 2007/05/09 11:37:23 danielk1977 Exp $ +** $Id: test_config.c,v 1.4 2007/05/10 10:46:57 danielk1977 Exp $ */ #include "sqliteInt.h" #include "tcl.h" @@ -382,9 +382,9 @@ static void set_options(Tcl_Interp *interp){ (char*)&sqlite_max_sql_length, TCL_LINK_INT|TCL_LINK_READ_ONLY); } { - static int sqlite_max_expr_length = SQLITE_MAX_EXPR_LENGTH; - Tcl_LinkVar(interp, "SQLITE_MAX_EXPR_LENGTH", - (char*)&sqlite_max_expr_length, TCL_LINK_INT|TCL_LINK_READ_ONLY); + static int sqlite_max_expr_depth = SQLITE_MAX_EXPR_DEPTH; + Tcl_LinkVar(interp, "SQLITE_MAX_EXPR_DEPTH", + (char*)&sqlite_max_expr_depth, TCL_LINK_INT|TCL_LINK_READ_ONLY); } { static int sqlite_max_vdbe_op = SQLITE_MAX_VDBE_OP; diff --git a/test/sqllimits1.test b/test/sqllimits1.test index 0dcbaa121..f962679d7 100644 --- a/test/sqllimits1.test +++ b/test/sqllimits1.test @@ -12,7 +12,7 @@ # This file contains tests to verify that the limits defined in # sqlite source file limits.h are enforced. # -# $Id: sqllimits1.test,v 1.6 2007/05/09 15:56:40 danielk1977 Exp $ +# $Id: sqllimits1.test,v 1.7 2007/05/10 10:46:57 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -33,7 +33,7 @@ source $testdir/tester.tcl # # Todo: # -# sqllimits-5.*: SQLITE_MAX_EXPR_LENGTH (sqlite todo) +# sqllimits-5.*: SQLITE_MAX_EXPR_DEPTH (sqlite todo) # sqllimits-6.*: SQLITE_MAX_VDBE_OP (sqlite todo) # @@ -237,25 +237,58 @@ do_test sqllimits-1.4.9 { } {1 {too many columns in result set}} #-------------------------------------------------------------------- -# These tests - sqllimits-5.* - test that the SQLITE_MAX_EXPR_LENGTH +# These tests - sqllimits-5.* - test that the SQLITE_MAX_EXPR_DEPTH # limit is enforced. The limit refers to the number of terms in # the expression. # -# TODO -do_test sqllimits-1.5.1 { - execsql { - PRAGMA max_page_count = 1000000; -- 1 GB - CREATE TABLE v0(a); - } - db transaction { - for {set i 1} {$i < 2000} {incr i} { - set expr "([string repeat {a AND } 50]a AND a) AS a" - execsql [subst { - CREATE VIEW v${i} AS SELECT $expr FROM v0 - }] +if {$::SQLITE_MAX_EXPR_DEPTH != 1000} { + puts -nonewline stderr "WARNING: Compile with -DSQLITE_MAX_EXPR_DEPTH to run " + puts stderr "tests sqllimits-1.5.X" +} else { + do_test sqllimits-1.5.1 { + set max $::SQLITE_MAX_EXPR_DEPTH + set expr "(1 [string repeat {AND 1 } $max])" + catchsql [subst { + SELECT $expr + }] + } "1 {Expression tree is too large (maximum depth $::SQLITE_MAX_EXPR_DEPTH)}" + + # Attempting to beat the expression depth limit using nested SELECT + # queries causes a parser stack overflow. + do_test sqllimits-1.5.2 { + set max $::SQLITE_MAX_EXPR_DEPTH + set expr "SELECT 1" + for {set i 0} {$i <= $max} {incr i} { + set expr "SELECT ($expr)" } - } -} {} + catchsql [subst { + SELECT $expr + }] + } "1 {parser stack overflow}" + + + do_test sqllimits-1.5.3 { + execsql { + PRAGMA max_page_count = 1000000; -- 1 GB + CREATE TABLE v0(a); + INSERT INTO v0 VALUES(1); + } + db transaction { + for {set i 1} {$i < 200} {incr i} { + set expr "(a [string repeat {AND 1 } 50]) AS a" + execsql [subst { + CREATE VIEW v${i} AS SELECT $expr FROM v[expr {$i-1}] + }] + } + } + } {} + + do_test sqllimits-1.5.4 { + catchsql { + SELECT a FROM v199 + } + } "1 {Expression tree is too large (maximum depth $::SQLITE_MAX_EXPR_DEPTH)}" +} #-------------------------------------------------------------------- # Test cases sqllimits-6.* test that the SQLITE_MAX_VDBE_OP |