Add code to enforce the MAX_EXPR_DEPTH limit. (CVS 3968)
FossilOrigin-Name: 2c9c94a24d52a1c9f5d1b32cbdff794a2dd74126
This commit is contained in:
parent
e305f43f17
commit
fc9760654a
26
manifest
26
manifest
@ -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
|
||||
|
@ -1 +1 @@
|
||||
66954bdd81dabfb60306de8480b5477a4acb1d9e
|
||||
2c9c94a24d52a1c9f5d1b32cbdff794a2dd74126
|
92
src/expr.c
92
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 */
|
||||
|
15
src/limits.h
15
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
|
||||
|
||||
/*
|
||||
|
@ -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);
|
||||
}
|
||||
|
15
src/select.c
15
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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user