diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/attach.c | 3 | ||||
-rw-r--r-- | src/delete.c | 22 | ||||
-rw-r--r-- | src/expr.c | 14 | ||||
-rw-r--r-- | src/fkey.c | 4 | ||||
-rw-r--r-- | src/insert.c | 1 | ||||
-rw-r--r-- | src/parse.y | 45 | ||||
-rw-r--r-- | src/resolve.c | 3 | ||||
-rw-r--r-- | src/select.c | 60 | ||||
-rw-r--r-- | src/sqliteInt.h | 11 | ||||
-rw-r--r-- | src/treeview.c | 13 | ||||
-rw-r--r-- | src/trigger.c | 4 | ||||
-rw-r--r-- | src/update.c | 12 | ||||
-rw-r--r-- | src/walker.c | 1 |
13 files changed, 73 insertions, 120 deletions
diff --git a/src/attach.c b/src/attach.c index 68a9a77c6..fa38e8415 100644 --- a/src/attach.c +++ b/src/attach.c @@ -504,9 +504,6 @@ int sqlite3FixSelect( if( sqlite3FixExpr(pFix, pSelect->pLimit) ){ return 1; } - if( sqlite3FixExpr(pFix, pSelect->pOffset) ){ - return 1; - } pSelect = pSelect->pPrior; } return 0; diff --git a/src/delete.c b/src/delete.c index 5c96fdfb8..8e25b36f5 100644 --- a/src/delete.c +++ b/src/delete.c @@ -92,7 +92,6 @@ void sqlite3MaterializeView( Expr *pWhere, /* Optional WHERE clause to be added */ ExprList *pOrderBy, /* Optional ORDER BY clause */ Expr *pLimit, /* Optional LIMIT clause */ - Expr *pOffset, /* Optional OFFSET clause */ int iCur /* Cursor number for ephemeral table */ ){ SelectDest dest; @@ -110,7 +109,7 @@ void sqlite3MaterializeView( assert( pFrom->a[0].pUsing==0 ); } pSel = sqlite3SelectNew(pParse, 0, pFrom, pWhere, 0, 0, pOrderBy, - SF_IncludeHidden, pLimit, pOffset); + SF_IncludeHidden, pLimit); sqlite3SelectDestInit(&dest, SRT_EphemTab, iCur); sqlite3Select(pParse, pSel, &dest); sqlite3SelectDelete(db, pSel); @@ -132,7 +131,6 @@ Expr *sqlite3LimitWhere( Expr *pWhere, /* The WHERE clause. May be null */ ExprList *pOrderBy, /* The ORDER BY clause. May be null */ Expr *pLimit, /* The LIMIT clause. May be null */ - Expr *pOffset, /* The OFFSET clause. May be null */ char *zStmtType /* Either DELETE or UPDATE. For err msgs. */ ){ sqlite3 *db = pParse->db; @@ -149,8 +147,6 @@ Expr *sqlite3LimitWhere( sqlite3ErrorMsg(pParse, "ORDER BY without LIMIT on %s", zStmtType); sqlite3ExprDelete(pParse->db, pWhere); sqlite3ExprListDelete(pParse->db, pOrderBy); - sqlite3ExprDelete(pParse->db, pLimit); - sqlite3ExprDelete(pParse->db, pOffset); return 0; } @@ -158,8 +154,6 @@ Expr *sqlite3LimitWhere( ** is a limit/offset term to enforce. */ if( pLimit == 0 ) { - /* if pLimit is null, pOffset will always be null as well. */ - assert( pOffset == 0 ); return pWhere; } @@ -206,7 +200,7 @@ Expr *sqlite3LimitWhere( /* generate the SELECT expression tree. */ pSelect = sqlite3SelectNew(pParse, pEList, pSelectSrc, pWhere, 0 ,0, - pOrderBy,0,pLimit,pOffset + pOrderBy,0,pLimit ); /* now generate the new WHERE rowid IN clause for the DELETE/UDPATE */ @@ -229,8 +223,7 @@ void sqlite3DeleteFrom( SrcList *pTabList, /* The table from which we should delete things */ Expr *pWhere, /* The WHERE clause. May be null */ ExprList *pOrderBy, /* ORDER BY clause. May be null */ - Expr *pLimit, /* LIMIT clause. May be null */ - Expr *pOffset /* OFFSET clause. May be null */ + Expr *pLimit /* LIMIT clause. May be null */ ){ Vdbe *v; /* The virtual database engine */ Table *pTab; /* The table from which records will be deleted */ @@ -303,10 +296,10 @@ void sqlite3DeleteFrom( #ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT if( !isView ){ pWhere = sqlite3LimitWhere( - pParse, pTabList, pWhere, pOrderBy, pLimit, pOffset, "DELETE" + pParse, pTabList, pWhere, pOrderBy, pLimit, "DELETE" ); pOrderBy = 0; - pLimit = pOffset = 0; + pLimit = 0; } #endif @@ -358,11 +351,11 @@ void sqlite3DeleteFrom( #if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER) if( isView ){ sqlite3MaterializeView(pParse, pTab, - pWhere, pOrderBy, pLimit, pOffset, iTabCur + pWhere, pOrderBy, pLimit, iTabCur ); iDataCur = iIdxCur = iTabCur; pOrderBy = 0; - pLimit = pOffset = 0; + pLimit = 0; } #endif @@ -609,7 +602,6 @@ delete_from_cleanup: #if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) sqlite3ExprListDelete(db, pOrderBy); sqlite3ExprDelete(db, pLimit); - sqlite3ExprDelete(db, pOffset); #endif sqlite3DbFree(db, aToOpen); return; diff --git a/src/expr.c b/src/expr.c index 0a5dc913f..5027f994d 100644 --- a/src/expr.c +++ b/src/expr.c @@ -663,7 +663,6 @@ static void heightOfSelect(Select *p, int *pnHeight){ 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); @@ -1462,7 +1461,6 @@ Select *sqlite3SelectDup(sqlite3 *db, Select *pDup, int flags){ pNew->pNext = pNext; pNew->pPrior = 0; pNew->pLimit = sqlite3ExprDup(db, p->pLimit, flags); - pNew->pOffset = sqlite3ExprDup(db, p->pOffset, flags); pNew->iLimit = 0; pNew->iOffset = 0; pNew->selFlags = p->selFlags & ~SF_UsesEphemeral; @@ -2099,7 +2097,6 @@ static Select *isCandidateForInOpt(Expr *pX){ } assert( p->pGroupBy==0 ); /* Has no GROUP BY clause */ if( p->pLimit ) return 0; /* Has no LIMIT clause */ - assert( p->pOffset==0 ); /* No LIMIT means no OFFSET */ if( p->pWhere ) return 0; /* Has no WHERE clause */ pSrc = p->pSrc; assert( pSrc!=0 ); @@ -2739,6 +2736,7 @@ int sqlite3CodeSubselect( Select *pSel; /* SELECT statement to encode */ SelectDest dest; /* How to deal with SELECT result */ int nReg; /* Registers to allocate */ + Expr *pLimit; /* New limit expression */ testcase( pExpr->op==TK_EXISTS ); testcase( pExpr->op==TK_SELECT ); @@ -2760,9 +2758,13 @@ int sqlite3CodeSubselect( sqlite3VdbeAddOp2(v, OP_Integer, 0, dest.iSDParm); VdbeComment((v, "Init EXISTS result")); } - sqlite3ExprDelete(pParse->db, pSel->pLimit); - pSel->pLimit = sqlite3ExprAlloc(pParse->db, TK_INTEGER, - &sqlite3IntTokens[1], 0); + pLimit = sqlite3ExprAlloc(pParse->db, TK_INTEGER,&sqlite3IntTokens[1], 0); + if( pSel->pLimit ){ + sqlite3ExprDelete(pParse->db, pSel->pLimit->pLeft); + pSel->pLimit->pLeft = pLimit; + }else{ + pSel->pLimit = sqlite3PExpr(pParse, TK_LIMIT, pLimit, 0); + } pSel->iLimit = 0; pSel->selFlags &= ~SF_MultiValue; if( sqlite3Select(pParse, pSel, &dest) ){ diff --git a/src/fkey.c b/src/fkey.c index 44ef3c7c7..c366c1b3a 100644 --- a/src/fkey.c +++ b/src/fkey.c @@ -725,7 +725,7 @@ void sqlite3FkDropTable(Parse *pParse, SrcList *pName, Table *pTab){ } pParse->disableTriggers = 1; - sqlite3DeleteFrom(pParse, sqlite3SrcListDup(db, pName, 0), 0, 0, 0, 0); + sqlite3DeleteFrom(pParse, sqlite3SrcListDup(db, pName, 0), 0, 0, 0); pParse->disableTriggers = 0; /* If the DELETE has generated immediate foreign key constraint @@ -1283,7 +1283,7 @@ static Trigger *fkActionTrigger( sqlite3ExprListAppend(pParse, 0, pRaise), sqlite3SrcListAppend(db, 0, &tFrom, 0), pWhere, - 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0 ); pWhere = 0; } diff --git a/src/insert.c b/src/insert.c index 3a531495c..f0af0fbd1 100644 --- a/src/insert.c +++ b/src/insert.c @@ -2007,7 +2007,6 @@ static int xferOptimization( if( pSelect->pLimit ){ return 0; /* SELECT may not have a LIMIT clause */ } - assert( pSelect->pOffset==0 ); /* Must be so if pLimit==0 */ if( pSelect->pPrior ){ return 0; /* SELECT may not be a compound query */ } diff --git a/src/parse.y b/src/parse.y index 18f587c05..0867d1e0c 100644 --- a/src/parse.y +++ b/src/parse.y @@ -85,15 +85,6 @@ #define YYMALLOCARGTYPE u64 /* -** An instance of this structure holds information about the -** LIMIT clause of a SELECT statement. -*/ -struct LimitVal { - Expr *pLimit; /* The LIMIT expression. NULL if there is no limit */ - Expr *pOffset; /* The OFFSET expression. NULL if there is none */ -}; - -/* ** An instance of the following structure describes the event of a ** TRIGGER. "a" is the event type, one of TK_UPDATE, TK_INSERT, ** TK_DELETE, or TK_INSTEAD. If the event is of the form @@ -470,7 +461,7 @@ selectnowith(A) ::= selectnowith(A) multiselect_op(Y) oneselect(Z). { x.n = 0; parserDoubleLinkSelect(pParse, pRhs); pFrom = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&x,pRhs,0,0); - pRhs = sqlite3SelectNew(pParse,0,pFrom,0,0,0,0,0,0,0); + pRhs = sqlite3SelectNew(pParse,0,pFrom,0,0,0,0,0,0); } if( pRhs ){ pRhs->op = (u8)Y; @@ -493,7 +484,7 @@ oneselect(A) ::= SELECT(S) distinct(D) selcollist(W) from(X) where_opt(Y) #if SELECTTRACE_ENABLED Token s = S; /*A-overwrites-S*/ #endif - A = sqlite3SelectNew(pParse,W,X,Y,P,Q,Z,D,L.pLimit,L.pOffset); + A = sqlite3SelectNew(pParse,W,X,Y,P,Q,Z,D,L); #if SELECTTRACE_ENABLED /* Populate the Select.zSelName[] string that is used to help with ** query planner debugging, to differentiate between multiple Select @@ -524,11 +515,11 @@ oneselect(A) ::= values(A). %type values {Select*} %destructor values {sqlite3SelectDelete(pParse->db, $$);} values(A) ::= VALUES LP nexprlist(X) RP. { - A = sqlite3SelectNew(pParse,X,0,0,0,0,0,SF_Values,0,0); + A = sqlite3SelectNew(pParse,X,0,0,0,0,0,SF_Values,0); } values(A) ::= values(A) COMMA LP exprlist(Y) RP. { Select *pRight, *pLeft = A; - pRight = sqlite3SelectNew(pParse,Y,0,0,0,0,0,SF_Values|SF_MultiValue,0,0); + pRight = sqlite3SelectNew(pParse,Y,0,0,0,0,0,SF_Values|SF_MultiValue,0); if( ALWAYS(pLeft) ) pLeft->selFlags &= ~SF_MultiValue; if( pRight ){ pRight->op = TK_ALL; @@ -639,7 +630,7 @@ seltablist(A) ::= stl_prefix(A) nm(Y) dbnm(D) LP exprlist(E) RP as(Z) }else{ Select *pSubquery; sqlite3SrcListShiftJoinType(F); - pSubquery = sqlite3SelectNew(pParse,0,F,0,0,0,0,SF_NestedFrom,0,0); + pSubquery = sqlite3SelectNew(pParse,0,F,0,0,0,0,SF_NestedFrom,0); A = sqlite3SrcListAppendFromTerm(pParse,A,0,0,&Z,pSubquery,N,U); } } @@ -726,7 +717,7 @@ groupby_opt(A) ::= GROUP BY nexprlist(X). {A = X;} having_opt(A) ::= . {A = 0;} having_opt(A) ::= HAVING expr(X). {A = X.pExpr;} -%type limit_opt {struct LimitVal} +%type limit_opt {Expr*} // The destructor for limit_opt will never fire in the current grammar. // The limit_opt non-terminal only occurs at the end of a single production @@ -735,16 +726,14 @@ having_opt(A) ::= HAVING expr(X). {A = X.pExpr;} // reduce. So there is never a limit_opt non-terminal on the stack // except as a transient. So there is never anything to destroy. // -//%destructor limit_opt { -// sqlite3ExprDelete(pParse->db, $$.pLimit); -// sqlite3ExprDelete(pParse->db, $$.pOffset); -//} -limit_opt(A) ::= . {A.pLimit = 0; A.pOffset = 0;} -limit_opt(A) ::= LIMIT expr(X). {A.pLimit = X.pExpr; A.pOffset = 0;} +//%destructor limit_opt {sqlite3ExprDelete(pParse->db, $$);} +limit_opt(A) ::= . {A = 0;} +limit_opt(A) ::= LIMIT expr(X). + {A = sqlite3PExpr(pParse,TK_LIMIT,X.pExpr,0);} limit_opt(A) ::= LIMIT expr(X) OFFSET expr(Y). - {A.pLimit = X.pExpr; A.pOffset = Y.pExpr;} + {A = sqlite3PExpr(pParse,TK_LIMIT,X.pExpr,Y.pExpr);} limit_opt(A) ::= LIMIT expr(X) COMMA expr(Y). - {A.pOffset = X.pExpr; A.pLimit = Y.pExpr;} + {A = sqlite3PExpr(pParse,TK_LIMIT,Y.pExpr,X.pExpr);} /////////////////////////// The DELETE statement ///////////////////////////// // @@ -753,14 +742,14 @@ cmd ::= with(C) DELETE FROM fullname(X) indexed_opt(I) where_opt(W) orderby_opt(O) limit_opt(L). { sqlite3WithPush(pParse, C, 1); sqlite3SrcListIndexedBy(pParse, X, &I); - sqlite3DeleteFrom(pParse,X,W,O,L.pLimit,L.pOffset); + sqlite3DeleteFrom(pParse,X,W,O,L); } %endif %ifndef SQLITE_ENABLE_UPDATE_DELETE_LIMIT cmd ::= with(C) DELETE FROM fullname(X) indexed_opt(I) where_opt(W). { sqlite3WithPush(pParse, C, 1); sqlite3SrcListIndexedBy(pParse, X, &I); - sqlite3DeleteFrom(pParse,X,W,0,0,0); + sqlite3DeleteFrom(pParse,X,W,0,0); } %endif @@ -778,7 +767,7 @@ cmd ::= with(C) UPDATE orconf(R) fullname(X) indexed_opt(I) SET setlist(Y) sqlite3WithPush(pParse, C, 1); sqlite3SrcListIndexedBy(pParse, X, &I); sqlite3ExprListCheckLength(pParse,Y,"set list"); - sqlite3Update(pParse,X,Y,W,R,O,L.pLimit,L.pOffset); + sqlite3Update(pParse,X,Y,W,R,O,L); } %endif %ifndef SQLITE_ENABLE_UPDATE_DELETE_LIMIT @@ -787,7 +776,7 @@ cmd ::= with(C) UPDATE orconf(R) fullname(X) indexed_opt(I) SET setlist(Y) sqlite3WithPush(pParse, C, 1); sqlite3SrcListIndexedBy(pParse, X, &I); sqlite3ExprListCheckLength(pParse,Y,"set list"); - sqlite3Update(pParse,X,Y,W,R,0,0,0); + sqlite3Update(pParse,X,Y,W,R,0,0); } %endif @@ -1189,7 +1178,7 @@ expr(A) ::= expr(A) between_op(N) expr(X) AND expr(Y). [BETWEEN] { } expr(A) ::= expr(A) in_op(N) nm(Y) dbnm(Z) paren_exprlist(E). [IN] { SrcList *pSrc = sqlite3SrcListAppend(pParse->db, 0,&Y,&Z); - Select *pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0); + Select *pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0); if( E ) sqlite3SrcListFuncArgs(pParse, pSelect ? pSrc : 0, E); A.pExpr = sqlite3PExpr(pParse, TK_IN, A.pExpr, 0); sqlite3PExprAddSelect(pParse, A.pExpr, pSelect); diff --git a/src/resolve.c b/src/resolve.c index 17dbbccfc..f735fffa0 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -1196,8 +1196,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ */ memset(&sNC, 0, sizeof(sNC)); sNC.pParse = pParse; - if( sqlite3ResolveExprNames(&sNC, p->pLimit) || - sqlite3ResolveExprNames(&sNC, p->pOffset) ){ + if( sqlite3ResolveExprNames(&sNC, p->pLimit) ){ return WRC_Abort; } diff --git a/src/select.c b/src/select.c index 46c69d71f..97eaf21b4 100644 --- a/src/select.c +++ b/src/select.c @@ -74,7 +74,6 @@ static void clearSelect(sqlite3 *db, Select *p, int bFree){ sqlite3ExprDelete(db, p->pHaving); sqlite3ExprListDelete(db, p->pOrderBy); sqlite3ExprDelete(db, p->pLimit); - sqlite3ExprDelete(db, p->pOffset); if( OK_IF_ALWAYS_TRUE(p->pWith) ) sqlite3WithDelete(db, p->pWith); if( bFree ) sqlite3DbFreeNN(db, p); p = pPrior; @@ -107,8 +106,7 @@ Select *sqlite3SelectNew( Expr *pHaving, /* the HAVING clause */ ExprList *pOrderBy, /* the ORDER BY clause */ u32 selFlags, /* Flag parameters, such as SF_Distinct */ - Expr *pLimit, /* LIMIT value. NULL means not used */ - Expr *pOffset /* OFFSET value. NULL means no offset */ + Expr *pLimit /* LIMIT value. NULL means not used */ ){ Select *pNew; Select standin; @@ -141,10 +139,7 @@ Select *sqlite3SelectNew( pNew->pPrior = 0; pNew->pNext = 0; pNew->pLimit = pLimit; - pNew->pOffset = pOffset; pNew->pWith = 0; - assert( pOffset==0 || pLimit!=0 || pParse->nErr>0 - || pParse->db->mallocFailed!=0 ); if( pParse->db->mallocFailed ) { clearSelect(pParse->db, pNew, pNew!=&standin); pNew = 0; @@ -1874,7 +1869,7 @@ Vdbe *sqlite3GetVdbe(Parse *pParse){ /* ** Compute the iLimit and iOffset fields of the SELECT based on the -** pLimit and pOffset expressions. pLimit and pOffset hold the expressions +** pLimit expressions. pLimit->pLeft and pLimit->pRight hold the expressions ** that appear in the original SQL statement after the LIMIT and OFFSET ** keywords. Or NULL if those keywords are omitted. iLimit and iOffset ** are the integer memory register numbers for counters used to compute @@ -1882,15 +1877,15 @@ Vdbe *sqlite3GetVdbe(Parse *pParse){ ** iLimit and iOffset are negative. ** ** This routine changes the values of iLimit and iOffset only if -** a limit or offset is defined by pLimit and pOffset. iLimit and -** iOffset should have been preset to appropriate default values (zero) +** a limit or offset is defined by pLimit->pLeft and pLimit->pRight. iLimit +** and iOffset should have been preset to appropriate default values (zero) ** prior to calling this routine. ** ** The iOffset register (if it exists) is initialized to the value ** of the OFFSET. The iLimit register is initialized to LIMIT. Register ** iOffset+1 is initialized to LIMIT+OFFSET. ** -** Only if pLimit!=0 or pOffset!=0 do the limit registers get +** Only if pLimit->pLeft!=0 do the limit registers get ** redefined. The UNION ALL operator uses this property to force ** the reuse of the same limit and offset registers across multiple ** SELECT statements. @@ -1900,6 +1895,8 @@ static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){ int iLimit = 0; int iOffset; int n; + Expr *pLimit = p->pLimit; + if( p->iLimit ) return; /* @@ -1909,12 +1906,13 @@ static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){ ** no rows. */ sqlite3ExprCacheClear(pParse); - assert( p->pOffset==0 || p->pLimit!=0 ); - if( p->pLimit ){ + if( pLimit ){ + assert( pLimit->op==TK_LIMIT ); + assert( pLimit->pLeft!=0 ); p->iLimit = iLimit = ++pParse->nMem; v = sqlite3GetVdbe(pParse); assert( v!=0 ); - if( sqlite3ExprIsInteger(p->pLimit, &n) ){ + if( sqlite3ExprIsInteger(pLimit->pLeft, &n) ){ sqlite3VdbeAddOp2(v, OP_Integer, n, iLimit); VdbeComment((v, "LIMIT counter")); if( n==0 ){ @@ -1924,15 +1922,15 @@ static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){ p->selFlags |= SF_FixedLimit; } }else{ - sqlite3ExprCode(pParse, p->pLimit, iLimit); + sqlite3ExprCode(pParse, pLimit->pLeft, iLimit); sqlite3VdbeAddOp1(v, OP_MustBeInt, iLimit); VdbeCoverage(v); VdbeComment((v, "LIMIT counter")); sqlite3VdbeAddOp2(v, OP_IfNot, iLimit, iBreak); VdbeCoverage(v); } - if( p->pOffset ){ + if( pLimit->pRight ){ p->iOffset = iOffset = ++pParse->nMem; pParse->nMem++; /* Allocate an extra register for limit+offset */ - sqlite3ExprCode(pParse, p->pOffset, iOffset); + sqlite3ExprCode(pParse, pLimit->pRight, iOffset); sqlite3VdbeAddOp1(v, OP_MustBeInt, iOffset); VdbeCoverage(v); VdbeComment((v, "OFFSET counter")); sqlite3VdbeAddOp3(v, OP_OffsetLimit, iLimit, iOffset+1, iOffset); @@ -2062,7 +2060,7 @@ static void generateWithRecursiveQuery( int i; /* Loop counter */ int rc; /* Result code */ ExprList *pOrderBy; /* The ORDER BY clause */ - Expr *pLimit, *pOffset; /* Saved LIMIT and OFFSET */ + Expr *pLimit; /* Saved LIMIT and OFFSET */ int regLimit, regOffset; /* Registers used by LIMIT and OFFSET */ /* Obtain authorization to do a recursive query */ @@ -2073,10 +2071,9 @@ static void generateWithRecursiveQuery( p->nSelectRow = 320; /* 4 billion rows */ computeLimitRegisters(pParse, p, addrBreak); pLimit = p->pLimit; - pOffset = p->pOffset; regLimit = p->iLimit; regOffset = p->iOffset; - p->pLimit = p->pOffset = 0; + p->pLimit = 0; p->iLimit = p->iOffset = 0; pOrderBy = p->pOrderBy; @@ -2169,7 +2166,6 @@ end_of_recursive_query: sqlite3ExprListDelete(pParse->db, p->pOrderBy); p->pOrderBy = pOrderBy; p->pLimit = pLimit; - p->pOffset = pOffset; return; } #endif /* SQLITE_OMIT_CTE */ @@ -2205,7 +2201,6 @@ static int multiSelectValues( assert( p->selFlags & SF_Values ); assert( p->op==TK_ALL || (p->op==TK_SELECT && p->pPrior==0) ); assert( p->pLimit==0 ); - assert( p->pOffset==0 ); assert( p->pNext==0 || p->pEList->nExpr==p->pNext->pEList->nExpr ); if( p->pPrior==0 ) break; assert( p->pPrior->pNext==p ); @@ -2332,11 +2327,9 @@ static int multiSelect( pPrior->iLimit = p->iLimit; pPrior->iOffset = p->iOffset; pPrior->pLimit = p->pLimit; - pPrior->pOffset = p->pOffset; explainSetInteger(iSub1, pParse->iNextSelectId); rc = sqlite3Select(pParse, pPrior, &dest); p->pLimit = 0; - p->pOffset = 0; if( rc ){ goto multi_select_end; } @@ -2358,7 +2351,7 @@ static int multiSelect( p->pPrior = pPrior; p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow); if( pPrior->pLimit - && sqlite3ExprIsInteger(pPrior->pLimit, &nLimit) + && sqlite3ExprIsInteger(pPrior->pLimit->pLeft, &nLimit) && nLimit>0 && p->nSelectRow > sqlite3LogEst((u64)nLimit) ){ p->nSelectRow = sqlite3LogEst((u64)nLimit); @@ -2373,7 +2366,7 @@ static int multiSelect( int unionTab; /* Cursor number of the temporary table holding result */ u8 op = 0; /* One of the SRT_ operations to apply to self */ int priorOp; /* The SRT_ operation to apply to prior selects */ - Expr *pLimit, *pOffset; /* Saved values of p->nLimit and p->nOffset */ + Expr *pLimit; /* Saved values of p->nLimit */ int addr; SelectDest uniondest; @@ -2385,7 +2378,6 @@ static int multiSelect( ** right. */ assert( p->pLimit==0 ); /* Not allowed on leftward elements */ - assert( p->pOffset==0 ); /* Not allowed on leftward elements */ unionTab = dest.iSDParm; }else{ /* We will need to create our own temporary table to hold the @@ -2421,8 +2413,6 @@ static int multiSelect( p->pPrior = 0; pLimit = p->pLimit; p->pLimit = 0; - pOffset = p->pOffset; - p->pOffset = 0; uniondest.eDest = op; explainSetInteger(iSub2, pParse->iNextSelectId); rc = sqlite3Select(pParse, p, &uniondest); @@ -2438,7 +2428,6 @@ static int multiSelect( } sqlite3ExprDelete(db, p->pLimit); p->pLimit = pLimit; - p->pOffset = pOffset; p->iLimit = 0; p->iOffset = 0; @@ -2466,7 +2455,7 @@ static int multiSelect( default: assert( p->op==TK_INTERSECT ); { int tab1, tab2; int iCont, iBreak, iStart; - Expr *pLimit, *pOffset; + Expr *pLimit; int addr; SelectDest intersectdest; int r1; @@ -2502,8 +2491,6 @@ static int multiSelect( p->pPrior = 0; pLimit = p->pLimit; p->pLimit = 0; - pOffset = p->pOffset; - p->pOffset = 0; intersectdest.iSDParm = tab2; explainSetInteger(iSub2, pParse->iNextSelectId); rc = sqlite3Select(pParse, p, &intersectdest); @@ -2513,7 +2500,6 @@ static int multiSelect( if( p->nSelectRow>pPrior->nSelectRow ) p->nSelectRow = pPrior->nSelectRow; sqlite3ExprDelete(db, p->pLimit); p->pLimit = pLimit; - p->pOffset = pOffset; /* Generate code to take the intersection of the two temporary ** tables. @@ -2992,8 +2978,6 @@ static int multiSelectOrderBy( } sqlite3ExprDelete(db, p->pLimit); p->pLimit = 0; - sqlite3ExprDelete(db, p->pOffset); - p->pOffset = 0; regAddrA = ++pParse->nMem; regAddrB = ++pParse->nMem; @@ -3457,7 +3441,7 @@ static int flattenSubquery( ** became arbitrary expressions, we were forced to add restrictions (13) ** and (14). */ if( pSub->pLimit && p->pLimit ) return 0; /* Restriction (13) */ - if( pSub->pOffset ) return 0; /* Restriction (14) */ + if( pSub->pLimit && pSub->pLimit->pRight ) return 0; /* Restriction (14) */ if( (p->selFlags & SF_Compound)!=0 && pSub->pLimit ){ return 0; /* Restriction (15) */ } @@ -3605,16 +3589,13 @@ static int flattenSubquery( Select *pNew; ExprList *pOrderBy = p->pOrderBy; Expr *pLimit = p->pLimit; - Expr *pOffset = p->pOffset; Select *pPrior = p->pPrior; p->pOrderBy = 0; p->pSrc = 0; p->pPrior = 0; p->pLimit = 0; - p->pOffset = 0; pNew = sqlite3SelectDup(db, p, 0); sqlite3SelectSetName(pNew, pSub->zSelName); - p->pOffset = pOffset; p->pLimit = pLimit; p->pOrderBy = pOrderBy; p->pSrc = pSrc; @@ -4080,7 +4061,6 @@ static int convertCompoundSelectToSubquery(Walker *pWalker, Select *p){ assert( pNew->pPrior!=0 ); pNew->pPrior->pNext = pNew; pNew->pLimit = 0; - pNew->pOffset = 0; return WRC_Continue; } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 95a66b4fe..058fee146 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2749,7 +2749,6 @@ struct Select { Select *pPrior; /* Prior select in a compound select statement */ Select *pNext; /* Next select to the left in a compound */ Expr *pLimit; /* LIMIT expression. NULL means not used. */ - Expr *pOffset; /* OFFSET expression. NULL means not used. */ With *pWith; /* WITH clause attached to this select. Or NULL. */ }; @@ -3756,16 +3755,16 @@ void sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*, void sqlite3DropIndex(Parse*, SrcList*, int); int sqlite3Select(Parse*, Select*, SelectDest*); Select *sqlite3SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList*, - Expr*,ExprList*,u32,Expr*,Expr*); + Expr*,ExprList*,u32,Expr*); void sqlite3SelectDelete(sqlite3*, Select*); Table *sqlite3SrcListLookup(Parse*, SrcList*); int sqlite3IsReadOnly(Parse*, Table*, int); void sqlite3OpenTable(Parse*, int iCur, int iDb, Table*, int); #if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY) -Expr *sqlite3LimitWhere(Parse*,SrcList*,Expr*,ExprList*,Expr*,Expr*,char*); +Expr *sqlite3LimitWhere(Parse*,SrcList*,Expr*,ExprList*,Expr*,char*); #endif -void sqlite3DeleteFrom(Parse*, SrcList*, Expr*, ExprList*, Expr*, Expr*); -void sqlite3Update(Parse*, SrcList*, ExprList*,Expr*,int,ExprList*,Expr*,Expr*); +void sqlite3DeleteFrom(Parse*, SrcList*, Expr*, ExprList*, Expr*); +void sqlite3Update(Parse*, SrcList*, ExprList*,Expr*,int,ExprList*,Expr*); WhereInfo *sqlite3WhereBegin(Parse*,SrcList*,Expr*,ExprList*,ExprList*,u16,int); void sqlite3WhereEnd(WhereInfo*); LogEst sqlite3WhereOutputRowCount(WhereInfo*); @@ -3889,7 +3888,7 @@ int sqlite3SafetyCheckSickOrOk(sqlite3*); void sqlite3ChangeCookie(Parse*, int); #if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER) -void sqlite3MaterializeView(Parse*, Table*, Expr*, ExprList*,Expr*,Expr*,int); +void sqlite3MaterializeView(Parse*, Table*, Expr*, ExprList*,Expr*,int); #endif #ifndef SQLITE_OMIT_TRIGGER diff --git a/src/treeview.c b/src/treeview.c index ba9fa7b2f..8d171a473 100644 --- a/src/treeview.c +++ b/src/treeview.c @@ -153,7 +153,6 @@ void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){ if( p->pHaving ) n++; if( p->pOrderBy ) n++; if( p->pLimit ) n++; - if( p->pOffset ) n++; } sqlite3TreeViewExprList(pView, p->pEList, (n--)>0, "result-set"); if( p->pSrc && p->pSrc->nSrc ){ @@ -210,12 +209,12 @@ void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){ } if( p->pLimit ){ sqlite3TreeViewItem(pView, "LIMIT", (n--)>0); - sqlite3TreeViewExpr(pView, p->pLimit, 0); - sqlite3TreeViewPop(pView); - } - if( p->pOffset ){ - sqlite3TreeViewItem(pView, "OFFSET", (n--)>0); - sqlite3TreeViewExpr(pView, p->pOffset, 0); + sqlite3TreeViewExpr(pView, p->pLimit->pLeft, p->pLimit->pRight!=0); + if( p->pLimit->pRight ){ + sqlite3TreeViewItem(pView, "OFFSET", (n--)>0); + sqlite3TreeViewExpr(pView, p->pLimit->pRight, 0); + sqlite3TreeViewPop(pView); + } sqlite3TreeViewPop(pView); } if( p->pPrior ){ diff --git a/src/trigger.c b/src/trigger.c index a17769ae9..a64fb291a 100644 --- a/src/trigger.c +++ b/src/trigger.c @@ -711,7 +711,7 @@ static int codeTriggerProgram( targetSrcList(pParse, pStep), sqlite3ExprListDup(db, pStep->pExprList, 0), sqlite3ExprDup(db, pStep->pWhere, 0), - pParse->eOrconf, 0, 0, 0 + pParse->eOrconf, 0, 0 ); break; } @@ -727,7 +727,7 @@ static int codeTriggerProgram( case TK_DELETE: { sqlite3DeleteFrom(pParse, targetSrcList(pParse, pStep), - sqlite3ExprDup(db, pStep->pWhere, 0), 0, 0, 0 + sqlite3ExprDup(db, pStep->pWhere, 0), 0, 0 ); break; } diff --git a/src/update.c b/src/update.c index 4cfa4019e..15e8f4a6c 100644 --- a/src/update.c +++ b/src/update.c @@ -93,8 +93,7 @@ void sqlite3Update( Expr *pWhere, /* The WHERE clause. May be null */ int onError, /* How to handle constraint errors */ ExprList *pOrderBy, /* ORDER BY clause. May be null */ - Expr *pLimit, /* LIMIT clause. May be null */ - Expr *pOffset /* OFFSET clause. May be null */ + Expr *pLimit /* LIMIT clause. May be null */ ){ int i, j; /* Loop counters */ Table *pTab; /* The table to be updated */ @@ -182,10 +181,10 @@ void sqlite3Update( #ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT if( !isView ){ pWhere = sqlite3LimitWhere( - pParse, pTabList, pWhere, pOrderBy, pLimit, pOffset, "UPDATE" + pParse, pTabList, pWhere, pOrderBy, pLimit, "UPDATE" ); pOrderBy = 0; - pLimit = pOffset = 0; + pLimit = 0; } #endif @@ -358,10 +357,10 @@ void sqlite3Update( #if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER) if( isView ){ sqlite3MaterializeView(pParse, pTab, - pWhere, pOrderBy, pLimit, pOffset, iDataCur + pWhere, pOrderBy, pLimit, iDataCur ); pOrderBy = 0; - pLimit = pOffset = 0; + pLimit = 0; } #endif @@ -748,7 +747,6 @@ update_cleanup: #if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) sqlite3ExprListDelete(db, pOrderBy); sqlite3ExprDelete(db, pLimit); - sqlite3ExprDelete(db, pOffset); #endif return; } diff --git a/src/walker.c b/src/walker.c index ae7545bf5..60bf8226f 100644 --- a/src/walker.c +++ b/src/walker.c @@ -91,7 +91,6 @@ int sqlite3WalkSelectExpr(Walker *pWalker, Select *p){ if( sqlite3WalkExpr(pWalker, p->pHaving) ) return WRC_Abort; if( sqlite3WalkExprList(pWalker, p->pOrderBy) ) return WRC_Abort; if( sqlite3WalkExpr(pWalker, p->pLimit) ) return WRC_Abort; - if( sqlite3WalkExpr(pWalker, p->pOffset) ) return WRC_Abort; return WRC_Continue; } |