mirror of https://github.com/sqlite/sqlite
Reorganize some of the code that detects expression trees with a depth greater than EXPR_MAX_DEPTH so that they are detected earlier. This further reduces the opportunities for stack overflow. (CVS 5189)
FossilOrigin-Name: 16d4c53a8e4d3cfc1abac3b8bb44d8bfd9471e32
This commit is contained in:
parent
861f74563d
commit
4b5255ac31
16
manifest
16
manifest
|
@ -1,5 +1,5 @@
|
||||||
C Modify\sthe\ssignatures\sof\sthe\ssqlite3_vfs.xAccess\sand\ssqlite3_vfs.xCheckReservedLock\sfunctions.\s(CVS\s5188)
|
C Reorganize\ssome\sof\sthe\scode\sthat\sdetects\sexpression\strees\swith\sa\sdepth\sgreater\sthan\sEXPR_MAX_DEPTH\sso\sthat\sthey\sare\sdetected\searlier.\sThis\sfurther\sreduces\sthe\sopportunities\sfor\sstack\soverflow.\s(CVS\s5189)
|
||||||
D 2008-06-05T11:39:11
|
D 2008-06-05T16:47:39
|
||||||
F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7
|
F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7
|
||||||
F Makefile.in ce92ea8dc7adfb743757794f51c10d1b0d9c55e4
|
F Makefile.in ce92ea8dc7adfb743757794f51c10d1b0d9c55e4
|
||||||
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
||||||
|
@ -104,7 +104,7 @@ F src/callback.c 77b302b0d41468dcda78c70e706e5b84577f0fa0
|
||||||
F src/complete.c 4cf68fd75d60257524cbe74f87351b9848399131
|
F src/complete.c 4cf68fd75d60257524cbe74f87351b9848399131
|
||||||
F src/date.c b305ced9f4da66b51ef020d9bf31c6c92fc0c6bb
|
F src/date.c b305ced9f4da66b51ef020d9bf31c6c92fc0c6bb
|
||||||
F src/delete.c d3fc5987f2eb88f7b9549d58a5dfea079a83fe8b
|
F src/delete.c d3fc5987f2eb88f7b9549d58a5dfea079a83fe8b
|
||||||
F src/expr.c 52fbb644cf5e9b70329e95c67552e74c3cba81b7
|
F src/expr.c ecb3b23d3543427cba3e2ac12a6c6ae4bb20d39b
|
||||||
F src/fault.c 1f6177188edb00641673e462f3fab8cba9f7422b
|
F src/fault.c 1f6177188edb00641673e462f3fab8cba9f7422b
|
||||||
F src/func.c 77a910a1ca7613d291fd0b5cba3be14c02f0dce0
|
F src/func.c 77a910a1ca7613d291fd0b5cba3be14c02f0dce0
|
||||||
F src/hash.c fd8cb06fb54c2fe7d48c9195792059a2e5be8b70
|
F src/hash.c fd8cb06fb54c2fe7d48c9195792059a2e5be8b70
|
||||||
|
@ -135,7 +135,7 @@ F src/os_unix.c bea384cc48cc03630703fbf3afbc9ee4b5442663
|
||||||
F src/os_win.c 9ac4e4e9c864b16e5dd087eed5770c960a5b1f09
|
F src/os_win.c 9ac4e4e9c864b16e5dd087eed5770c960a5b1f09
|
||||||
F src/pager.c 912792937cba5838c4515a7a284c9f57f56d603e
|
F src/pager.c 912792937cba5838c4515a7a284c9f57f56d603e
|
||||||
F src/pager.h 71c58cd613174a91b50ed66edad6148639aa064a
|
F src/pager.h 71c58cd613174a91b50ed66edad6148639aa064a
|
||||||
F src/parse.y fc4bd35c6088901f7c8daead26c6fb11c87d22e7
|
F src/parse.y 8c2c3145eebe1964eb279cb3c4e502eae28bb0fa
|
||||||
F src/pragma.c 70e7c865dce85fdf9df81848af2169009a56ed08
|
F src/pragma.c 70e7c865dce85fdf9df81848af2169009a56ed08
|
||||||
F src/prepare.c cbc9301aba1d0fc3d05fae576f2eb667c189cb36
|
F src/prepare.c cbc9301aba1d0fc3d05fae576f2eb667c189cb36
|
||||||
F src/printf.c f2d4f6c5b0ec24b643e85fe60258adad8b1f6acc
|
F src/printf.c f2d4f6c5b0ec24b643e85fe60258adad8b1f6acc
|
||||||
|
@ -144,7 +144,7 @@ F src/select.c da43ce3080112aa77863e9c570c1df19a892acb8
|
||||||
F src/shell.c a12ea645271b7876c8f080146f48e20b00d367ec
|
F src/shell.c a12ea645271b7876c8f080146f48e20b00d367ec
|
||||||
F src/sqlite.h.in 0f4f33b54824cc8077c028a85a1dbd8a3df4fa73
|
F src/sqlite.h.in 0f4f33b54824cc8077c028a85a1dbd8a3df4fa73
|
||||||
F src/sqlite3ext.h faacd0e6a81aabee0861c6d7883c9172e74ef5b3
|
F src/sqlite3ext.h faacd0e6a81aabee0861c6d7883c9172e74ef5b3
|
||||||
F src/sqliteInt.h cfcb83222431108aa51565efecf3a084360ad4a6
|
F src/sqliteInt.h debc576f4476cde358f3c7d8214b0c2f47b24555
|
||||||
F src/sqliteLimit.h f435e728c6b620ef7312814d660a81f9356eb5c8
|
F src/sqliteLimit.h f435e728c6b620ef7312814d660a81f9356eb5c8
|
||||||
F src/table.c 1fa8f8113ac9cbc09ae4801c6d2a7f0af82c5822
|
F src/table.c 1fa8f8113ac9cbc09ae4801c6d2a7f0af82c5822
|
||||||
F src/tclsqlite.c c57e740e30bd6dda678796eed62c7f0e64689834
|
F src/tclsqlite.c c57e740e30bd6dda678796eed62c7f0e64689834
|
||||||
|
@ -591,7 +591,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81
|
||||||
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
||||||
F tool/speedtest8.c 1dbced29de5f59ba2ebf877edcadf171540374d1
|
F tool/speedtest8.c 1dbced29de5f59ba2ebf877edcadf171540374d1
|
||||||
F tool/speedtest8inst1.c c65494ca99d1e09c246dfe37a7ca7a354af9990f
|
F tool/speedtest8inst1.c c65494ca99d1e09c246dfe37a7ca7a354af9990f
|
||||||
P 9ab87b7b0d0195787f1527b5be1475fb89330f08
|
P 4226ac54beea1b58de8ab7b9d768d999f50438a6
|
||||||
R f736eee5959ea7b2b1c25bb8c6d7f381
|
R 15114df36c8c1f1e10e6cc53ddf8867c
|
||||||
U danielk1977
|
U danielk1977
|
||||||
Z 8a3aacae4ecc1da5df29c6db6f201b0d
|
Z b0654222f29652b857476f2b1403ea27
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
4226ac54beea1b58de8ab7b9d768d999f50438a6
|
16d4c53a8e4d3cfc1abac3b8bb44d8bfd9471e32
|
182
src/expr.c
182
src/expr.c
|
@ -12,7 +12,7 @@
|
||||||
** This file contains routines used for analyzing expressions and
|
** This file contains routines used for analyzing expressions and
|
||||||
** for generating VDBE code that evaluates expressions in SQLite.
|
** for generating VDBE code that evaluates expressions in SQLite.
|
||||||
**
|
**
|
||||||
** $Id: expr.c,v 1.372 2008/05/28 13:49:36 drh Exp $
|
** $Id: expr.c,v 1.373 2008/06/05 16:47:39 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
@ -253,6 +253,101 @@ static int codeCompare(
|
||||||
return addr;
|
return addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if SQLITE_MAX_EXPR_DEPTH>0
|
||||||
|
/*
|
||||||
|
** Check that argument nHeight is less than or equal to the maximum
|
||||||
|
** expression depth allowed. If it is not, leave an error message in
|
||||||
|
** pParse.
|
||||||
|
*/
|
||||||
|
static int checkExprHeight(Parse *pParse, int nHeight){
|
||||||
|
int rc = SQLITE_OK;
|
||||||
|
int mxHeight = pParse->db->aLimit[SQLITE_LIMIT_EXPR_DEPTH];
|
||||||
|
if( nHeight>mxHeight ){
|
||||||
|
sqlite3ErrorMsg(pParse,
|
||||||
|
"Expression tree is too large (maximum depth %d)", mxHeight
|
||||||
|
);
|
||||||
|
rc = SQLITE_ERROR;
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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.
|
||||||
|
*/
|
||||||
|
static void exprSetHeight(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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Set the Expr.nHeight variable using the exprSetHeight() function. If
|
||||||
|
** the height is greater than the maximum allowed expression depth,
|
||||||
|
** leave an error in pParse.
|
||||||
|
*/
|
||||||
|
void sqlite3ExprSetHeight(Parse *pParse, Expr *p){
|
||||||
|
exprSetHeight(p);
|
||||||
|
checkExprHeight(pParse, p->nHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** 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;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#define checkExprHeight(x,y)
|
||||||
|
#define exprSetHeight(y)
|
||||||
|
#endif /* SQLITE_MAX_EXPR_DEPTH>0 */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Construct a new expression node and return a pointer to it. Memory
|
** Construct a new expression node and return a pointer to it. Memory
|
||||||
** for this node is obtained from sqlite3_malloc(). The calling function
|
** for this node is obtained from sqlite3_malloc(). The calling function
|
||||||
|
@ -297,7 +392,7 @@ Expr *sqlite3Expr(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sqlite3ExprSetHeight(pNew);
|
exprSetHeight(pNew);
|
||||||
return pNew;
|
return pNew;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -312,7 +407,11 @@ Expr *sqlite3PExpr(
|
||||||
Expr *pRight, /* Right operand */
|
Expr *pRight, /* Right operand */
|
||||||
const Token *pToken /* Argument token */
|
const Token *pToken /* Argument token */
|
||||||
){
|
){
|
||||||
return sqlite3Expr(pParse->db, op, pLeft, pRight, pToken);
|
Expr *p = sqlite3Expr(pParse->db, op, pLeft, pRight, pToken);
|
||||||
|
if( p ){
|
||||||
|
checkExprHeight(pParse, p->nHeight);
|
||||||
|
}
|
||||||
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -391,7 +490,7 @@ Expr *sqlite3ExprFunction(Parse *pParse, ExprList *pList, Token *pToken){
|
||||||
pNew->token = *pToken;
|
pNew->token = *pToken;
|
||||||
pNew->span = pNew->token;
|
pNew->span = pNew->token;
|
||||||
|
|
||||||
sqlite3ExprSetHeight(pNew);
|
sqlite3ExprSetHeight(pParse, pNew);
|
||||||
return pNew;
|
return pNew;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -738,75 +837,6 @@ void sqlite3ExprListCheckLength(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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.
|
|
||||||
*/
|
|
||||||
#if SQLITE_MAX_EXPR_DEPTH>0
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif /* SQLITE_MAX_EXPR_DEPTH>0 */
|
|
||||||
|
|
||||||
/*
|
|
||||||
** 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.
|
|
||||||
*/
|
|
||||||
#if SQLITE_MAX_EXPR_DEPTH>0
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
#endif /* SQLITE_MAX_EXPR_DEPTH>0 */
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Return the maximum height of any expression tree referenced
|
|
||||||
** by the select statement passed as an argument.
|
|
||||||
*/
|
|
||||||
#if SQLITE_MAX_EXPR_DEPTH>0
|
|
||||||
int sqlite3SelectExprHeight(Select *p){
|
|
||||||
int nHeight = 0;
|
|
||||||
heightOfSelect(p, &nHeight);
|
|
||||||
return nHeight;
|
|
||||||
}
|
|
||||||
#endif /* SQLITE_MAX_EXPR_DEPTH>0 */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Delete an entire expression list.
|
** Delete an entire expression list.
|
||||||
*/
|
*/
|
||||||
|
@ -1536,11 +1566,7 @@ int sqlite3ExprResolveNames(
|
||||||
if( pExpr==0 ) return 0;
|
if( pExpr==0 ) return 0;
|
||||||
#if SQLITE_MAX_EXPR_DEPTH>0
|
#if SQLITE_MAX_EXPR_DEPTH>0
|
||||||
{
|
{
|
||||||
int mxDepth = pNC->pParse->db->aLimit[SQLITE_LIMIT_EXPR_DEPTH];
|
if( checkExprHeight(pNC->pParse, pExpr->nHeight + pNC->pParse->nHeight) ){
|
||||||
if( (pExpr->nHeight+pNC->pParse->nHeight)>mxDepth ){
|
|
||||||
sqlite3ErrorMsg(pNC->pParse,
|
|
||||||
"Expression tree is too large (maximum depth %d)", mxDepth
|
|
||||||
);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
pNC->pParse->nHeight += pExpr->nHeight;
|
pNC->pParse->nHeight += pExpr->nHeight;
|
||||||
|
|
14
src/parse.y
14
src/parse.y
|
@ -14,7 +14,7 @@
|
||||||
** the parser. Lemon will also generate a header file containing
|
** the parser. Lemon will also generate a header file containing
|
||||||
** numeric codes for all of the tokens.
|
** numeric codes for all of the tokens.
|
||||||
**
|
**
|
||||||
** @(#) $Id: parse.y,v 1.243 2008/04/17 20:59:38 drh Exp $
|
** @(#) $Id: parse.y,v 1.244 2008/06/05 16:47:39 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// All token codes are small integers with #defines that begin with "TK_"
|
// All token codes are small integers with #defines that begin with "TK_"
|
||||||
|
@ -773,7 +773,7 @@ expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
|
||||||
A = sqlite3PExpr(pParse, TK_IN, X, 0, 0);
|
A = sqlite3PExpr(pParse, TK_IN, X, 0, 0);
|
||||||
if( A ){
|
if( A ){
|
||||||
A->pList = Y;
|
A->pList = Y;
|
||||||
sqlite3ExprSetHeight(A);
|
sqlite3ExprSetHeight(pParse, A);
|
||||||
}else{
|
}else{
|
||||||
sqlite3ExprListDelete(Y);
|
sqlite3ExprListDelete(Y);
|
||||||
}
|
}
|
||||||
|
@ -784,7 +784,7 @@ expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
|
||||||
A = sqlite3PExpr(pParse, TK_SELECT, 0, 0, 0);
|
A = sqlite3PExpr(pParse, TK_SELECT, 0, 0, 0);
|
||||||
if( A ){
|
if( A ){
|
||||||
A->pSelect = X;
|
A->pSelect = X;
|
||||||
sqlite3ExprSetHeight(A);
|
sqlite3ExprSetHeight(pParse, A);
|
||||||
}else{
|
}else{
|
||||||
sqlite3SelectDelete(X);
|
sqlite3SelectDelete(X);
|
||||||
}
|
}
|
||||||
|
@ -794,7 +794,7 @@ expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
|
||||||
A = sqlite3PExpr(pParse, TK_IN, X, 0, 0);
|
A = sqlite3PExpr(pParse, TK_IN, X, 0, 0);
|
||||||
if( A ){
|
if( A ){
|
||||||
A->pSelect = Y;
|
A->pSelect = Y;
|
||||||
sqlite3ExprSetHeight(A);
|
sqlite3ExprSetHeight(pParse, A);
|
||||||
}else{
|
}else{
|
||||||
sqlite3SelectDelete(Y);
|
sqlite3SelectDelete(Y);
|
||||||
}
|
}
|
||||||
|
@ -806,7 +806,7 @@ expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
|
||||||
A = sqlite3PExpr(pParse, TK_IN, X, 0, 0);
|
A = sqlite3PExpr(pParse, TK_IN, X, 0, 0);
|
||||||
if( A ){
|
if( A ){
|
||||||
A->pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0);
|
A->pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0);
|
||||||
sqlite3ExprSetHeight(A);
|
sqlite3ExprSetHeight(pParse, A);
|
||||||
}else{
|
}else{
|
||||||
sqlite3SrcListDelete(pSrc);
|
sqlite3SrcListDelete(pSrc);
|
||||||
}
|
}
|
||||||
|
@ -818,7 +818,7 @@ expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
|
||||||
if( p ){
|
if( p ){
|
||||||
p->pSelect = Y;
|
p->pSelect = Y;
|
||||||
sqlite3ExprSpan(p,&B,&E);
|
sqlite3ExprSpan(p,&B,&E);
|
||||||
sqlite3ExprSetHeight(A);
|
sqlite3ExprSetHeight(pParse, A);
|
||||||
}else{
|
}else{
|
||||||
sqlite3SelectDelete(Y);
|
sqlite3SelectDelete(Y);
|
||||||
}
|
}
|
||||||
|
@ -830,7 +830,7 @@ expr(A) ::= CASE(C) case_operand(X) case_exprlist(Y) case_else(Z) END(E). {
|
||||||
A = sqlite3PExpr(pParse, TK_CASE, X, Z, 0);
|
A = sqlite3PExpr(pParse, TK_CASE, X, Z, 0);
|
||||||
if( A ){
|
if( A ){
|
||||||
A->pList = Y;
|
A->pList = Y;
|
||||||
sqlite3ExprSetHeight(A);
|
sqlite3ExprSetHeight(pParse, A);
|
||||||
}else{
|
}else{
|
||||||
sqlite3ExprListDelete(Y);
|
sqlite3ExprListDelete(Y);
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
*************************************************************************
|
*************************************************************************
|
||||||
** Internal interface definitions for SQLite.
|
** Internal interface definitions for SQLite.
|
||||||
**
|
**
|
||||||
** @(#) $Id: sqliteInt.h,v 1.705 2008/05/28 13:49:36 drh Exp $
|
** @(#) $Id: sqliteInt.h,v 1.706 2008/06/05 16:47:39 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
#ifndef _SQLITEINT_H_
|
#ifndef _SQLITEINT_H_
|
||||||
#define _SQLITEINT_H_
|
#define _SQLITEINT_H_
|
||||||
|
@ -2196,10 +2196,10 @@ int sqlite3FindInIndex(Parse *, Expr *, int);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if SQLITE_MAX_EXPR_DEPTH>0
|
#if SQLITE_MAX_EXPR_DEPTH>0
|
||||||
void sqlite3ExprSetHeight(Expr *);
|
void sqlite3ExprSetHeight(Parse *pParse, Expr *p);
|
||||||
int sqlite3SelectExprHeight(Select *);
|
int sqlite3SelectExprHeight(Select *);
|
||||||
#else
|
#else
|
||||||
#define sqlite3ExprSetHeight(x)
|
#define sqlite3ExprSetHeight(x,y)
|
||||||
#define sqlite3SelectExprHeight(x) 0
|
#define sqlite3SelectExprHeight(x) 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue