/ Check-in [85247880]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Merge the latest changes, and the stmtvtab1.test fix, from trunk.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | apple-osx
Files: files | file ages | folders
SHA3-256: 85247880a68ab5b7b296a71661b4326250d6ecaa58982e7f8197da52c66dde0a
User & Date: drh 2017-11-16 19:17:45
Context
2017-11-17
13:23
Merge latest changes from trunk, including the temporary db/ATTACH/master-journal fix. check-in: 162c7543 user: dan tags: apple-osx
2017-11-16
19:17
Merge the latest changes, and the stmtvtab1.test fix, from trunk. check-in: 85247880 user: drh tags: apple-osx
19:04
Add a missing "finish_test" to the end of the stmtvtab1.test script. check-in: e0b5c058 user: drh tags: trunk
2017-11-14
21:06
Fix a typo that prevented successful builds on macs. check-in: adf83060 user: drh tags: apple-osx
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/attach.c.

   500    500       }
   501    501       if( sqlite3FixExprList(pFix, pSelect->pOrderBy) ){
   502    502         return 1;
   503    503       }
   504    504       if( sqlite3FixExpr(pFix, pSelect->pLimit) ){
   505    505         return 1;
   506    506       }
   507         -    if( sqlite3FixExpr(pFix, pSelect->pOffset) ){
   508         -      return 1;
   509         -    }
   510    507       pSelect = pSelect->pPrior;
   511    508     }
   512    509     return 0;
   513    510   }
   514    511   int sqlite3FixExpr(
   515    512     DbFixer *pFix,     /* Context of the fixation */
   516    513     Expr *pExpr        /* The expression to be fixed to one database */

Changes to src/delete.c.

    88     88   */
    89     89   void sqlite3MaterializeView(
    90     90     Parse *pParse,       /* Parsing context */
    91     91     Table *pView,        /* View definition */
    92     92     Expr *pWhere,        /* Optional WHERE clause to be added */
    93     93     ExprList *pOrderBy,  /* Optional ORDER BY clause */
    94     94     Expr *pLimit,        /* Optional LIMIT clause */
    95         -  Expr *pOffset,       /* Optional OFFSET clause */
    96     95     int iCur             /* Cursor number for ephemeral table */
    97     96   ){
    98     97     SelectDest dest;
    99     98     Select *pSel;
   100     99     SrcList *pFrom;
   101    100     sqlite3 *db = pParse->db;
   102    101     int iDb = sqlite3SchemaToIndex(db, pView->pSchema);
................................................................................
   106    105       assert( pFrom->nSrc==1 );
   107    106       pFrom->a[0].zName = sqlite3DbStrDup(db, pView->zName);
   108    107       pFrom->a[0].zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zDbSName);
   109    108       assert( pFrom->a[0].pOn==0 );
   110    109       assert( pFrom->a[0].pUsing==0 );
   111    110     }
   112    111     pSel = sqlite3SelectNew(pParse, 0, pFrom, pWhere, 0, 0, pOrderBy, 
   113         -                          SF_IncludeHidden, pLimit, pOffset);
          112  +                          SF_IncludeHidden, pLimit);
   114    113     sqlite3SelectDestInit(&dest, SRT_EphemTab, iCur);
   115    114     sqlite3Select(pParse, pSel, &dest);
   116    115     sqlite3SelectDelete(db, pSel);
   117    116   }
   118    117   #endif /* !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER) */
   119    118   
   120    119   #if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY)
................................................................................
   128    127   */
   129    128   Expr *sqlite3LimitWhere(
   130    129     Parse *pParse,               /* The parser context */
   131    130     SrcList *pSrc,               /* the FROM clause -- which tables to scan */
   132    131     Expr *pWhere,                /* The WHERE clause.  May be null */
   133    132     ExprList *pOrderBy,          /* The ORDER BY clause.  May be null */
   134    133     Expr *pLimit,                /* The LIMIT clause.  May be null */
   135         -  Expr *pOffset,               /* The OFFSET clause.  May be null */
   136    134     char *zStmtType              /* Either DELETE or UPDATE.  For err msgs. */
   137    135   ){
   138    136     sqlite3 *db = pParse->db;
   139    137     Expr *pLhs = NULL;           /* LHS of IN(SELECT...) operator */
   140    138     Expr *pInClause = NULL;      /* WHERE rowid IN ( select ) */
   141    139     ExprList *pEList = NULL;     /* Expression list contaning only pSelectRowid */
   142    140     SrcList *pSelectSrc = NULL;  /* SELECT rowid FROM x ... (dup of pSrc) */
................................................................................
   145    143   
   146    144     /* Check that there isn't an ORDER BY without a LIMIT clause.
   147    145     */
   148    146     if( pOrderBy && pLimit==0 ) {
   149    147       sqlite3ErrorMsg(pParse, "ORDER BY without LIMIT on %s", zStmtType);
   150    148       sqlite3ExprDelete(pParse->db, pWhere);
   151    149       sqlite3ExprListDelete(pParse->db, pOrderBy);
   152         -    sqlite3ExprDelete(pParse->db, pLimit);
   153         -    sqlite3ExprDelete(pParse->db, pOffset);
   154    150       return 0;
   155    151     }
   156    152   
   157    153     /* We only need to generate a select expression if there
   158    154     ** is a limit/offset term to enforce.
   159    155     */
   160    156     if( pLimit == 0 ) {
   161         -    /* if pLimit is null, pOffset will always be null as well. */
   162         -    assert( pOffset == 0 );
   163    157       return pWhere;
   164    158     }
   165    159   
   166    160     /* Generate a select expression tree to enforce the limit/offset 
   167    161     ** term for the DELETE or UPDATE statement.  For example:
   168    162     **   DELETE FROM table_a WHERE col1=1 ORDER BY col2 LIMIT 1 OFFSET 1
   169    163     ** becomes:
................................................................................
   202    196     pSrc->a[0].pTab = 0;
   203    197     pSelectSrc = sqlite3SrcListDup(pParse->db, pSrc, 0);
   204    198     pSrc->a[0].pTab = pTab;
   205    199     pSrc->a[0].pIBIndex = 0;
   206    200   
   207    201     /* generate the SELECT expression tree. */
   208    202     pSelect = sqlite3SelectNew(pParse, pEList, pSelectSrc, pWhere, 0 ,0, 
   209         -      pOrderBy,0,pLimit,pOffset
          203  +      pOrderBy,0,pLimit
   210    204     );
   211    205   
   212    206     /* now generate the new WHERE rowid IN clause for the DELETE/UDPATE */
   213    207     pInClause = sqlite3PExpr(pParse, TK_IN, pLhs, 0);
   214    208     sqlite3PExprAddSelect(pParse, pInClause, pSelect);
   215    209     return pInClause;
   216    210   }
................................................................................
   225    219   **                  pTabList              pWhere
   226    220   */
   227    221   void sqlite3DeleteFrom(
   228    222     Parse *pParse,         /* The parser context */
   229    223     SrcList *pTabList,     /* The table from which we should delete things */
   230    224     Expr *pWhere,          /* The WHERE clause.  May be null */
   231    225     ExprList *pOrderBy,    /* ORDER BY clause. May be null */
   232         -  Expr *pLimit,          /* LIMIT clause. May be null */
   233         -  Expr *pOffset          /* OFFSET clause. May be null */
          226  +  Expr *pLimit           /* LIMIT clause. May be null */
   234    227   ){
   235    228     Vdbe *v;               /* The virtual database engine */
   236    229     Table *pTab;           /* The table from which records will be deleted */
   237    230     int i;                 /* Loop counter */
   238    231     WhereInfo *pWInfo;     /* Information about the WHERE clause */
   239    232     Index *pIdx;           /* For looping over indices of the table */
   240    233     int iTabCur;           /* Cursor number for the table */
................................................................................
   299    292   # undef isView
   300    293   # define isView 0
   301    294   #endif
   302    295   
   303    296   #ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT
   304    297     if( !isView ){
   305    298       pWhere = sqlite3LimitWhere(
   306         -        pParse, pTabList, pWhere, pOrderBy, pLimit, pOffset, "DELETE"
          299  +        pParse, pTabList, pWhere, pOrderBy, pLimit, "DELETE"
   307    300       );
   308    301       pOrderBy = 0;
   309         -    pLimit = pOffset = 0;
          302  +    pLimit = 0;
   310    303     }
   311    304   #endif
   312    305   
   313    306     /* If pTab is really a view, make sure it has been initialized.
   314    307     */
   315    308     if( sqlite3ViewGetColumnNames(pParse, pTab) ){
   316    309       goto delete_from_cleanup;
................................................................................
   354    347   
   355    348     /* If we are trying to delete from a view, realize that view into
   356    349     ** an ephemeral table.
   357    350     */
   358    351   #if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER)
   359    352     if( isView ){
   360    353       sqlite3MaterializeView(pParse, pTab, 
   361         -        pWhere, pOrderBy, pLimit, pOffset, iTabCur
          354  +        pWhere, pOrderBy, pLimit, iTabCur
   362    355       );
   363    356       iDataCur = iIdxCur = iTabCur;
   364    357       pOrderBy = 0;
   365         -    pLimit = pOffset = 0;
          358  +    pLimit = 0;
   366    359     }
   367    360   #endif
   368    361   
   369    362     /* Resolve the column names in the WHERE clause.
   370    363     */
   371    364     memset(&sNC, 0, sizeof(sNC));
   372    365     sNC.pParse = pParse;
................................................................................
   605    598   delete_from_cleanup:
   606    599     sqlite3AuthContextPop(&sContext);
   607    600     sqlite3SrcListDelete(db, pTabList);
   608    601     sqlite3ExprDelete(db, pWhere);
   609    602   #if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) 
   610    603     sqlite3ExprListDelete(db, pOrderBy);
   611    604     sqlite3ExprDelete(db, pLimit);
   612         -  sqlite3ExprDelete(db, pOffset);
   613    605   #endif
   614    606     sqlite3DbFree(db, aToOpen);
   615    607     return;
   616    608   }
   617    609   /* Make sure "isView" and other macros defined above are undefined. Otherwise
   618    610   ** they may interfere with compilation of other functions in this file
   619    611   ** (or in another file, if this file becomes part of the amalgamation).  */

Changes to src/expr.c.

   659    659     }
   660    660   }
   661    661   static void heightOfSelect(Select *p, int *pnHeight){
   662    662     if( p ){
   663    663       heightOfExpr(p->pWhere, pnHeight);
   664    664       heightOfExpr(p->pHaving, pnHeight);
   665    665       heightOfExpr(p->pLimit, pnHeight);
   666         -    heightOfExpr(p->pOffset, pnHeight);
   667    666       heightOfExprList(p->pEList, pnHeight);
   668    667       heightOfExprList(p->pGroupBy, pnHeight);
   669    668       heightOfExprList(p->pOrderBy, pnHeight);
   670    669       heightOfSelect(p->pPrior, pnHeight);
   671    670     }
   672    671   }
   673    672   
................................................................................
  1458   1457       pNew->pGroupBy = sqlite3ExprListDup(db, p->pGroupBy, flags);
  1459   1458       pNew->pHaving = sqlite3ExprDup(db, p->pHaving, flags);
  1460   1459       pNew->pOrderBy = sqlite3ExprListDup(db, p->pOrderBy, flags);
  1461   1460       pNew->op = p->op;
  1462   1461       pNew->pNext = pNext;
  1463   1462       pNew->pPrior = 0;
  1464   1463       pNew->pLimit = sqlite3ExprDup(db, p->pLimit, flags);
  1465         -    pNew->pOffset = sqlite3ExprDup(db, p->pOffset, flags);
  1466   1464       pNew->iLimit = 0;
  1467   1465       pNew->iOffset = 0;
  1468   1466       pNew->selFlags = p->selFlags & ~SF_UsesEphemeral;
  1469   1467       pNew->addrOpenEphm[0] = -1;
  1470   1468       pNew->addrOpenEphm[1] = -1;
  1471   1469       pNew->nSelectRow = p->nSelectRow;
  1472   1470       pNew->pWith = withDup(db, p->pWith);
................................................................................
  2095   2093     if( p->selFlags & (SF_Distinct|SF_Aggregate) ){
  2096   2094       testcase( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct );
  2097   2095       testcase( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Aggregate );
  2098   2096       return 0; /* No DISTINCT keyword and no aggregate functions */
  2099   2097     }
  2100   2098     assert( p->pGroupBy==0 );              /* Has no GROUP BY clause */
  2101   2099     if( p->pLimit ) return 0;              /* Has no LIMIT clause */
  2102         -  assert( p->pOffset==0 );               /* No LIMIT means no OFFSET */
  2103   2100     if( p->pWhere ) return 0;              /* Has no WHERE clause */
  2104   2101     pSrc = p->pSrc;
  2105   2102     assert( pSrc!=0 );
  2106   2103     if( pSrc->nSrc!=1 ) return 0;          /* Single term in FROM clause */
  2107   2104     if( pSrc->a[0].pSelect ) return 0;     /* FROM is not a subquery or view */
  2108   2105     pTab = pSrc->a[0].pTab;
  2109   2106     assert( pTab!=0 );
................................................................................
  2735   2732         **
  2736   2733         ** In both cases, the query is augmented with "LIMIT 1".  Any 
  2737   2734         ** preexisting limit is discarded in place of the new LIMIT 1.
  2738   2735         */
  2739   2736         Select *pSel;                         /* SELECT statement to encode */
  2740   2737         SelectDest dest;                      /* How to deal with SELECT result */
  2741   2738         int nReg;                             /* Registers to allocate */
         2739  +      Expr *pLimit;                         /* New limit expression */
  2742   2740   
  2743   2741         testcase( pExpr->op==TK_EXISTS );
  2744   2742         testcase( pExpr->op==TK_SELECT );
  2745   2743         assert( pExpr->op==TK_EXISTS || pExpr->op==TK_SELECT );
  2746   2744         assert( ExprHasProperty(pExpr, EP_xIsSelect) );
  2747   2745   
  2748   2746         pSel = pExpr->x.pSelect;
................................................................................
  2756   2754           sqlite3VdbeAddOp3(v, OP_Null, 0, dest.iSDParm, dest.iSDParm+nReg-1);
  2757   2755           VdbeComment((v, "Init subquery result"));
  2758   2756         }else{
  2759   2757           dest.eDest = SRT_Exists;
  2760   2758           sqlite3VdbeAddOp2(v, OP_Integer, 0, dest.iSDParm);
  2761   2759           VdbeComment((v, "Init EXISTS result"));
  2762   2760         }
  2763         -      sqlite3ExprDelete(pParse->db, pSel->pLimit);
  2764         -      pSel->pLimit = sqlite3ExprAlloc(pParse->db, TK_INTEGER,
  2765         -                                  &sqlite3IntTokens[1], 0);
         2761  +      pLimit = sqlite3ExprAlloc(pParse->db, TK_INTEGER,&sqlite3IntTokens[1], 0);
         2762  +      if( pSel->pLimit ){
         2763  +        sqlite3ExprDelete(pParse->db, pSel->pLimit->pLeft);
         2764  +        pSel->pLimit->pLeft = pLimit;
         2765  +      }else{
         2766  +        pSel->pLimit = sqlite3PExpr(pParse, TK_LIMIT, pLimit, 0);
         2767  +      }
  2766   2768         pSel->iLimit = 0;
  2767   2769         pSel->selFlags &= ~SF_MultiValue;
  2768   2770         if( sqlite3Select(pParse, pSel, &dest) ){
  2769   2771           return 0;
  2770   2772         }
  2771   2773         rReg = dest.iSDParm;
  2772   2774         ExprSetVVAProperty(pExpr, EP_NoReduce);

Changes to src/fkey.c.

   721    721         }
   722    722         if( !p ) return;
   723    723         iSkip = sqlite3VdbeMakeLabel(v);
   724    724         sqlite3VdbeAddOp2(v, OP_FkIfZero, 1, iSkip); VdbeCoverage(v);
   725    725       }
   726    726   
   727    727       pParse->disableTriggers = 1;
   728         -    sqlite3DeleteFrom(pParse, sqlite3SrcListDup(db, pName, 0), 0, 0, 0, 0);
          728  +    sqlite3DeleteFrom(pParse, sqlite3SrcListDup(db, pName, 0), 0, 0, 0);
   729    729       pParse->disableTriggers = 0;
   730    730   
   731    731       /* If the DELETE has generated immediate foreign key constraint 
   732    732       ** violations, halt the VDBE and return an error at this point, before
   733    733       ** any modifications to the schema are made. This is because statement
   734    734       ** transactions are not able to rollback schema changes.  
   735    735       **
................................................................................
  1279   1279         if( pRaise ){
  1280   1280           pRaise->affinity = OE_Abort;
  1281   1281         }
  1282   1282         pSelect = sqlite3SelectNew(pParse, 
  1283   1283             sqlite3ExprListAppend(pParse, 0, pRaise),
  1284   1284             sqlite3SrcListAppend(db, 0, &tFrom, 0),
  1285   1285             pWhere,
  1286         -          0, 0, 0, 0, 0, 0
         1286  +          0, 0, 0, 0, 0
  1287   1287         );
  1288   1288         pWhere = 0;
  1289   1289       }
  1290   1290   
  1291   1291       /* Disable lookaside memory allocation */
  1292   1292       db->lookaside.bDisable++;
  1293   1293   

Changes to src/insert.c.

  2003   2003     ** there is no ORDER BY, we will get an error. */
  2004   2004     if( pSelect->pGroupBy ){
  2005   2005       return 0;   /* SELECT may not have a GROUP BY clause */
  2006   2006     }
  2007   2007     if( pSelect->pLimit ){
  2008   2008       return 0;   /* SELECT may not have a LIMIT clause */
  2009   2009     }
  2010         -  assert( pSelect->pOffset==0 );  /* Must be so if pLimit==0 */
  2011   2010     if( pSelect->pPrior ){
  2012   2011       return 0;   /* SELECT may not be a compound query */
  2013   2012     }
  2014   2013     if( pSelect->selFlags & SF_Distinct ){
  2015   2014       return 0;   /* SELECT may not be DISTINCT */
  2016   2015     }
  2017   2016     pEList = pSelect->pEList;

Changes to src/parse.y.

    80     80   
    81     81   /*
    82     82   ** Alternative datatype for the argument to the malloc() routine passed
    83     83   ** into sqlite3ParserAlloc().  The default is size_t.
    84     84   */
    85     85   #define YYMALLOCARGTYPE  u64
    86     86   
    87         -/*
    88         -** An instance of this structure holds information about the
    89         -** LIMIT clause of a SELECT statement.
    90         -*/
    91         -struct LimitVal {
    92         -  Expr *pLimit;    /* The LIMIT expression.  NULL if there is no limit */
    93         -  Expr *pOffset;   /* The OFFSET expression.  NULL if there is none */
    94         -};
    95         -
    96     87   /*
    97     88   ** An instance of the following structure describes the event of a
    98     89   ** TRIGGER.  "a" is the event type, one of TK_UPDATE, TK_INSERT,
    99     90   ** TK_DELETE, or TK_INSTEAD.  If the event is of the form
   100     91   **
   101     92   **      UPDATE ON (a,b,c)
   102     93   **
................................................................................
   466    457     Select *pLhs = A;
   467    458     if( pRhs && pRhs->pPrior ){
   468    459       SrcList *pFrom;
   469    460       Token x;
   470    461       x.n = 0;
   471    462       parserDoubleLinkSelect(pParse, pRhs);
   472    463       pFrom = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&x,pRhs,0,0);
   473         -    pRhs = sqlite3SelectNew(pParse,0,pFrom,0,0,0,0,0,0,0);
          464  +    pRhs = sqlite3SelectNew(pParse,0,pFrom,0,0,0,0,0,0);
   474    465     }
   475    466     if( pRhs ){
   476    467       pRhs->op = (u8)Y;
   477    468       pRhs->pPrior = pLhs;
   478    469       if( ALWAYS(pLhs) ) pLhs->selFlags &= ~SF_MultiValue;
   479    470       pRhs->selFlags &= ~SF_MultiValue;
   480    471       if( Y!=TK_ALL ) pParse->hasCompound = 1;
................................................................................
   489    480   multiselect_op(A) ::= EXCEPT|INTERSECT(OP).  {A = @OP; /*A-overwrites-OP*/}
   490    481   %endif SQLITE_OMIT_COMPOUND_SELECT
   491    482   oneselect(A) ::= SELECT(S) distinct(D) selcollist(W) from(X) where_opt(Y)
   492    483                    groupby_opt(P) having_opt(Q) orderby_opt(Z) limit_opt(L). {
   493    484   #if SELECTTRACE_ENABLED
   494    485     Token s = S; /*A-overwrites-S*/
   495    486   #endif
   496         -  A = sqlite3SelectNew(pParse,W,X,Y,P,Q,Z,D,L.pLimit,L.pOffset);
          487  +  A = sqlite3SelectNew(pParse,W,X,Y,P,Q,Z,D,L);
   497    488   #if SELECTTRACE_ENABLED
   498    489     /* Populate the Select.zSelName[] string that is used to help with
   499    490     ** query planner debugging, to differentiate between multiple Select
   500    491     ** objects in a complex query.
   501    492     **
   502    493     ** If the SELECT keyword is immediately followed by a C-style comment
   503    494     ** then extract the first few alphanumeric characters from within that
................................................................................
   520    511   #endif /* SELECTRACE_ENABLED */
   521    512   }
   522    513   oneselect(A) ::= values(A).
   523    514   
   524    515   %type values {Select*}
   525    516   %destructor values {sqlite3SelectDelete(pParse->db, $$);}
   526    517   values(A) ::= VALUES LP nexprlist(X) RP. {
   527         -  A = sqlite3SelectNew(pParse,X,0,0,0,0,0,SF_Values,0,0);
          518  +  A = sqlite3SelectNew(pParse,X,0,0,0,0,0,SF_Values,0);
   528    519   }
   529    520   values(A) ::= values(A) COMMA LP exprlist(Y) RP. {
   530    521     Select *pRight, *pLeft = A;
   531         -  pRight = sqlite3SelectNew(pParse,Y,0,0,0,0,0,SF_Values|SF_MultiValue,0,0);
          522  +  pRight = sqlite3SelectNew(pParse,Y,0,0,0,0,0,SF_Values|SF_MultiValue,0);
   532    523     if( ALWAYS(pLeft) ) pLeft->selFlags &= ~SF_MultiValue;
   533    524     if( pRight ){
   534    525       pRight->op = TK_ALL;
   535    526       pRight->pPrior = pLeft;
   536    527       A = pRight;
   537    528     }else{
   538    529       A = pLeft;
................................................................................
   635    626           pOld->zName = pOld->zDatabase = 0;
   636    627           pOld->pSelect = 0;
   637    628         }
   638    629         sqlite3SrcListDelete(pParse->db, F);
   639    630       }else{
   640    631         Select *pSubquery;
   641    632         sqlite3SrcListShiftJoinType(F);
   642         -      pSubquery = sqlite3SelectNew(pParse,0,F,0,0,0,0,SF_NestedFrom,0,0);
          633  +      pSubquery = sqlite3SelectNew(pParse,0,F,0,0,0,0,SF_NestedFrom,0);
   643    634         A = sqlite3SrcListAppendFromTerm(pParse,A,0,0,&Z,pSubquery,N,U);
   644    635       }
   645    636     }
   646    637   %endif  SQLITE_OMIT_SUBQUERY
   647    638   
   648    639   %type dbnm {Token}
   649    640   dbnm(A) ::= .          {A.z=0; A.n=0;}
................................................................................
   722    713   groupby_opt(A) ::= GROUP BY nexprlist(X). {A = X;}
   723    714   
   724    715   %type having_opt {Expr*}
   725    716   %destructor having_opt {sqlite3ExprDelete(pParse->db, $$);}
   726    717   having_opt(A) ::= .                {A = 0;}
   727    718   having_opt(A) ::= HAVING expr(X).  {A = X.pExpr;}
   728    719   
   729         -%type limit_opt {struct LimitVal}
          720  +%type limit_opt {Expr*}
   730    721   
   731    722   // The destructor for limit_opt will never fire in the current grammar.
   732    723   // The limit_opt non-terminal only occurs at the end of a single production
   733    724   // rule for SELECT statements.  As soon as the rule that create the 
   734    725   // limit_opt non-terminal reduces, the SELECT statement rule will also
   735    726   // reduce.  So there is never a limit_opt non-terminal on the stack 
   736    727   // except as a transient.  So there is never anything to destroy.
   737    728   //
   738         -//%destructor limit_opt {
   739         -//  sqlite3ExprDelete(pParse->db, $$.pLimit);
   740         -//  sqlite3ExprDelete(pParse->db, $$.pOffset);
   741         -//}
   742         -limit_opt(A) ::= .                    {A.pLimit = 0; A.pOffset = 0;}
   743         -limit_opt(A) ::= LIMIT expr(X).       {A.pLimit = X.pExpr; A.pOffset = 0;}
          729  +//%destructor limit_opt {sqlite3ExprDelete(pParse->db, $$);}
          730  +limit_opt(A) ::= .       {A = 0;}
          731  +limit_opt(A) ::= LIMIT expr(X).
          732  +                         {A = sqlite3PExpr(pParse,TK_LIMIT,X.pExpr,0);}
   744    733   limit_opt(A) ::= LIMIT expr(X) OFFSET expr(Y). 
   745         -                                      {A.pLimit = X.pExpr; A.pOffset = Y.pExpr;}
          734  +                         {A = sqlite3PExpr(pParse,TK_LIMIT,X.pExpr,Y.pExpr);}
   746    735   limit_opt(A) ::= LIMIT expr(X) COMMA expr(Y). 
   747         -                                      {A.pOffset = X.pExpr; A.pLimit = Y.pExpr;}
          736  +                         {A = sqlite3PExpr(pParse,TK_LIMIT,Y.pExpr,X.pExpr);}
   748    737   
   749    738   /////////////////////////// The DELETE statement /////////////////////////////
   750    739   //
   751    740   %ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT
   752    741   cmd ::= with(C) DELETE FROM fullname(X) indexed_opt(I) where_opt(W) 
   753    742           orderby_opt(O) limit_opt(L). {
   754    743     sqlite3WithPush(pParse, C, 1);
   755    744     sqlite3SrcListIndexedBy(pParse, X, &I);
   756         -  sqlite3DeleteFrom(pParse,X,W,O,L.pLimit,L.pOffset); 
          745  +  sqlite3DeleteFrom(pParse,X,W,O,L);
   757    746   }
   758    747   %endif
   759    748   %ifndef SQLITE_ENABLE_UPDATE_DELETE_LIMIT
   760    749   cmd ::= with(C) DELETE FROM fullname(X) indexed_opt(I) where_opt(W). {
   761    750     sqlite3WithPush(pParse, C, 1);
   762    751     sqlite3SrcListIndexedBy(pParse, X, &I);
   763         -  sqlite3DeleteFrom(pParse,X,W,0,0,0);
          752  +  sqlite3DeleteFrom(pParse,X,W,0,0);
   764    753   }
   765    754   %endif
   766    755   
   767    756   %type where_opt {Expr*}
   768    757   %destructor where_opt {sqlite3ExprDelete(pParse->db, $$);}
   769    758   
   770    759   where_opt(A) ::= .                    {A = 0;}
................................................................................
   774    763   //
   775    764   %ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT
   776    765   cmd ::= with(C) UPDATE orconf(R) fullname(X) indexed_opt(I) SET setlist(Y)
   777    766           where_opt(W) orderby_opt(O) limit_opt(L).  {
   778    767     sqlite3WithPush(pParse, C, 1);
   779    768     sqlite3SrcListIndexedBy(pParse, X, &I);
   780    769     sqlite3ExprListCheckLength(pParse,Y,"set list"); 
   781         -  sqlite3Update(pParse,X,Y,W,R,O,L.pLimit,L.pOffset);
          770  +  sqlite3Update(pParse,X,Y,W,R,O,L);
   782    771   }
   783    772   %endif
   784    773   %ifndef SQLITE_ENABLE_UPDATE_DELETE_LIMIT
   785    774   cmd ::= with(C) UPDATE orconf(R) fullname(X) indexed_opt(I) SET setlist(Y)
   786    775           where_opt(W).  {
   787    776     sqlite3WithPush(pParse, C, 1);
   788    777     sqlite3SrcListIndexedBy(pParse, X, &I);
   789    778     sqlite3ExprListCheckLength(pParse,Y,"set list"); 
   790         -  sqlite3Update(pParse,X,Y,W,R,0,0,0);
          779  +  sqlite3Update(pParse,X,Y,W,R,0,0);
   791    780   }
   792    781   %endif
   793    782   
   794    783   %type setlist {ExprList*}
   795    784   %destructor setlist {sqlite3ExprListDelete(pParse->db, $$);}
   796    785   
   797    786   setlist(A) ::= setlist(A) COMMA nm(X) EQ expr(Y). {
................................................................................
  1185   1174       A.pExpr = sqlite3PExpr(pParse, TK_IN, A.pExpr, 0);
  1186   1175       sqlite3PExprAddSelect(pParse, A.pExpr, Y);
  1187   1176       exprNot(pParse, N, &A);
  1188   1177       A.zEnd = &E.z[E.n];
  1189   1178     }
  1190   1179     expr(A) ::= expr(A) in_op(N) nm(Y) dbnm(Z) paren_exprlist(E). [IN] {
  1191   1180       SrcList *pSrc = sqlite3SrcListAppend(pParse->db, 0,&Y,&Z);
  1192         -    Select *pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0);
         1181  +    Select *pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0);
  1193   1182       if( E )  sqlite3SrcListFuncArgs(pParse, pSelect ? pSrc : 0, E);
  1194   1183       A.pExpr = sqlite3PExpr(pParse, TK_IN, A.pExpr, 0);
  1195   1184       sqlite3PExprAddSelect(pParse, A.pExpr, pSelect);
  1196   1185       exprNot(pParse, N, &A);
  1197   1186       A.zEnd = Z.z ? &Z.z[Z.n] : &Y.z[Y.n];
  1198   1187     }
  1199   1188     expr(A) ::= EXISTS(B) LP select(Y) RP(E). {

Changes to src/resolve.c.

  1192   1192       p->selFlags |= SF_Resolved;
  1193   1193   
  1194   1194       /* Resolve the expressions in the LIMIT and OFFSET clauses. These
  1195   1195       ** are not allowed to refer to any names, so pass an empty NameContext.
  1196   1196       */
  1197   1197       memset(&sNC, 0, sizeof(sNC));
  1198   1198       sNC.pParse = pParse;
  1199         -    if( sqlite3ResolveExprNames(&sNC, p->pLimit) ||
  1200         -        sqlite3ResolveExprNames(&sNC, p->pOffset) ){
         1199  +    if( sqlite3ResolveExprNames(&sNC, p->pLimit) ){
  1201   1200         return WRC_Abort;
  1202   1201       }
  1203   1202   
  1204   1203       /* If the SF_Converted flags is set, then this Select object was
  1205   1204       ** was created by the convertCompoundSelectToSubquery() function.
  1206   1205       ** In this case the ORDER BY clause (p->pOrderBy) should be resolved
  1207   1206       ** as if it were part of the sub-query, not the parent. This block

Changes to src/select.c.

    70     70       sqlite3ExprListDelete(db, p->pEList);
    71     71       sqlite3SrcListDelete(db, p->pSrc);
    72     72       sqlite3ExprDelete(db, p->pWhere);
    73     73       sqlite3ExprListDelete(db, p->pGroupBy);
    74     74       sqlite3ExprDelete(db, p->pHaving);
    75     75       sqlite3ExprListDelete(db, p->pOrderBy);
    76     76       sqlite3ExprDelete(db, p->pLimit);
    77         -    sqlite3ExprDelete(db, p->pOffset);
    78     77       if( OK_IF_ALWAYS_TRUE(p->pWith) ) sqlite3WithDelete(db, p->pWith);
    79     78       if( bFree ) sqlite3DbFreeNN(db, p);
    80     79       p = pPrior;
    81     80       bFree = 1;
    82     81     }
    83     82   }
    84     83   
................................................................................
   103    102     ExprList *pEList,     /* which columns to include in the result */
   104    103     SrcList *pSrc,        /* the FROM clause -- which tables to scan */
   105    104     Expr *pWhere,         /* the WHERE clause */
   106    105     ExprList *pGroupBy,   /* the GROUP BY clause */
   107    106     Expr *pHaving,        /* the HAVING clause */
   108    107     ExprList *pOrderBy,   /* the ORDER BY clause */
   109    108     u32 selFlags,         /* Flag parameters, such as SF_Distinct */
   110         -  Expr *pLimit,         /* LIMIT value.  NULL means not used */
   111         -  Expr *pOffset         /* OFFSET value.  NULL means no offset */
          109  +  Expr *pLimit          /* LIMIT value.  NULL means not used */
   112    110   ){
   113    111     Select *pNew;
   114    112     Select standin;
   115    113     pNew = sqlite3DbMallocRawNN(pParse->db, sizeof(*pNew) );
   116    114     if( pNew==0 ){
   117    115       assert( pParse->db->mallocFailed );
   118    116       pNew = &standin;
................................................................................
   137    135     pNew->pWhere = pWhere;
   138    136     pNew->pGroupBy = pGroupBy;
   139    137     pNew->pHaving = pHaving;
   140    138     pNew->pOrderBy = pOrderBy;
   141    139     pNew->pPrior = 0;
   142    140     pNew->pNext = 0;
   143    141     pNew->pLimit = pLimit;
   144         -  pNew->pOffset = pOffset;
   145    142     pNew->pWith = 0;
   146         -  assert( pOffset==0 || pLimit!=0 || pParse->nErr>0
   147         -                     || pParse->db->mallocFailed!=0 );
   148    143     if( pParse->db->mallocFailed ) {
   149    144       clearSelect(pParse->db, pNew, pNew!=&standin);
   150    145       pNew = 0;
   151    146     }else{
   152    147       assert( pNew->pSrc!=0 || pParse->nErr>0 );
   153    148     }
   154    149     assert( pNew!=&standin );
................................................................................
  1870   1865     }
  1871   1866     return sqlite3VdbeCreate(pParse);
  1872   1867   }
  1873   1868   
  1874   1869   
  1875   1870   /*
  1876   1871   ** Compute the iLimit and iOffset fields of the SELECT based on the
  1877         -** pLimit and pOffset expressions.  pLimit and pOffset hold the expressions
         1872  +** pLimit expressions.  pLimit->pLeft and pLimit->pRight hold the expressions
  1878   1873   ** that appear in the original SQL statement after the LIMIT and OFFSET
  1879   1874   ** keywords.  Or NULL if those keywords are omitted. iLimit and iOffset 
  1880   1875   ** are the integer memory register numbers for counters used to compute 
  1881   1876   ** the limit and offset.  If there is no limit and/or offset, then 
  1882   1877   ** iLimit and iOffset are negative.
  1883   1878   **
  1884   1879   ** This routine changes the values of iLimit and iOffset only if
  1885         -** a limit or offset is defined by pLimit and pOffset.  iLimit and
  1886         -** iOffset should have been preset to appropriate default values (zero)
         1880  +** a limit or offset is defined by pLimit->pLeft and pLimit->pRight.  iLimit
         1881  +** and iOffset should have been preset to appropriate default values (zero)
  1887   1882   ** prior to calling this routine.
  1888   1883   **
  1889   1884   ** The iOffset register (if it exists) is initialized to the value
  1890   1885   ** of the OFFSET.  The iLimit register is initialized to LIMIT.  Register
  1891   1886   ** iOffset+1 is initialized to LIMIT+OFFSET.
  1892   1887   **
  1893         -** Only if pLimit!=0 or pOffset!=0 do the limit registers get
         1888  +** Only if pLimit->pLeft!=0 do the limit registers get
  1894   1889   ** redefined.  The UNION ALL operator uses this property to force
  1895   1890   ** the reuse of the same limit and offset registers across multiple
  1896   1891   ** SELECT statements.
  1897   1892   */
  1898   1893   static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){
  1899   1894     Vdbe *v = 0;
  1900   1895     int iLimit = 0;
  1901   1896     int iOffset;
  1902   1897     int n;
         1898  +  Expr *pLimit = p->pLimit;
         1899  +
  1903   1900     if( p->iLimit ) return;
  1904   1901   
  1905   1902     /* 
  1906   1903     ** "LIMIT -1" always shows all rows.  There is some
  1907   1904     ** controversy about what the correct behavior should be.
  1908   1905     ** The current implementation interprets "LIMIT 0" to mean
  1909   1906     ** no rows.
  1910   1907     */
  1911   1908     sqlite3ExprCacheClear(pParse);
  1912         -  assert( p->pOffset==0 || p->pLimit!=0 );
  1913         -  if( p->pLimit ){
         1909  +  if( pLimit ){
         1910  +    assert( pLimit->op==TK_LIMIT );
         1911  +    assert( pLimit->pLeft!=0 );
  1914   1912       p->iLimit = iLimit = ++pParse->nMem;
  1915   1913       v = sqlite3GetVdbe(pParse);
  1916   1914       assert( v!=0 );
  1917         -    if( sqlite3ExprIsInteger(p->pLimit, &n) ){
         1915  +    if( sqlite3ExprIsInteger(pLimit->pLeft, &n) ){
  1918   1916         sqlite3VdbeAddOp2(v, OP_Integer, n, iLimit);
  1919   1917         VdbeComment((v, "LIMIT counter"));
  1920   1918         if( n==0 ){
  1921   1919           sqlite3VdbeGoto(v, iBreak);
  1922   1920         }else if( n>=0 && p->nSelectRow>sqlite3LogEst((u64)n) ){
  1923   1921           p->nSelectRow = sqlite3LogEst((u64)n);
  1924   1922           p->selFlags |= SF_FixedLimit;
  1925   1923         }
  1926   1924       }else{
  1927         -      sqlite3ExprCode(pParse, p->pLimit, iLimit);
         1925  +      sqlite3ExprCode(pParse, pLimit->pLeft, iLimit);
  1928   1926         sqlite3VdbeAddOp1(v, OP_MustBeInt, iLimit); VdbeCoverage(v);
  1929   1927         VdbeComment((v, "LIMIT counter"));
  1930   1928         sqlite3VdbeAddOp2(v, OP_IfNot, iLimit, iBreak); VdbeCoverage(v);
  1931   1929       }
  1932         -    if( p->pOffset ){
         1930  +    if( pLimit->pRight ){
  1933   1931         p->iOffset = iOffset = ++pParse->nMem;
  1934   1932         pParse->nMem++;   /* Allocate an extra register for limit+offset */
  1935         -      sqlite3ExprCode(pParse, p->pOffset, iOffset);
         1933  +      sqlite3ExprCode(pParse, pLimit->pRight, iOffset);
  1936   1934         sqlite3VdbeAddOp1(v, OP_MustBeInt, iOffset); VdbeCoverage(v);
  1937   1935         VdbeComment((v, "OFFSET counter"));
  1938   1936         sqlite3VdbeAddOp3(v, OP_OffsetLimit, iLimit, iOffset+1, iOffset);
  1939   1937         VdbeComment((v, "LIMIT+OFFSET"));
  1940   1938       }
  1941   1939     }
  1942   1940   }
................................................................................
  2058   2056     int iQueue;                   /* The Queue table */
  2059   2057     int iDistinct = 0;            /* To ensure unique results if UNION */
  2060   2058     int eDest = SRT_Fifo;         /* How to write to Queue */
  2061   2059     SelectDest destQueue;         /* SelectDest targetting the Queue table */
  2062   2060     int i;                        /* Loop counter */
  2063   2061     int rc;                       /* Result code */
  2064   2062     ExprList *pOrderBy;           /* The ORDER BY clause */
  2065         -  Expr *pLimit, *pOffset;       /* Saved LIMIT and OFFSET */
         2063  +  Expr *pLimit;                 /* Saved LIMIT and OFFSET */
  2066   2064     int regLimit, regOffset;      /* Registers used by LIMIT and OFFSET */
  2067   2065   
  2068   2066     /* Obtain authorization to do a recursive query */
  2069   2067     if( sqlite3AuthCheck(pParse, SQLITE_RECURSIVE, 0, 0, 0) ) return;
  2070   2068   
  2071   2069     /* Process the LIMIT and OFFSET clauses, if they exist */
  2072   2070     addrBreak = sqlite3VdbeMakeLabel(v);
  2073   2071     p->nSelectRow = 320;  /* 4 billion rows */
  2074   2072     computeLimitRegisters(pParse, p, addrBreak);
  2075   2073     pLimit = p->pLimit;
  2076         -  pOffset = p->pOffset;
  2077   2074     regLimit = p->iLimit;
  2078   2075     regOffset = p->iOffset;
  2079         -  p->pLimit = p->pOffset = 0;
         2076  +  p->pLimit = 0;
  2080   2077     p->iLimit = p->iOffset = 0;
  2081   2078     pOrderBy = p->pOrderBy;
  2082   2079   
  2083   2080     /* Locate the cursor number of the Current table */
  2084   2081     for(i=0; ALWAYS(i<pSrc->nSrc); i++){
  2085   2082       if( pSrc->a[i].fg.isRecursive ){
  2086   2083         iCurrent = pSrc->a[i].iCursor;
................................................................................
  2165   2162     sqlite3VdbeGoto(v, addrTop);
  2166   2163     sqlite3VdbeResolveLabel(v, addrBreak);
  2167   2164   
  2168   2165   end_of_recursive_query:
  2169   2166     sqlite3ExprListDelete(pParse->db, p->pOrderBy);
  2170   2167     p->pOrderBy = pOrderBy;
  2171   2168     p->pLimit = pLimit;
  2172         -  p->pOffset = pOffset;
  2173   2169     return;
  2174   2170   }
  2175   2171   #endif /* SQLITE_OMIT_CTE */
  2176   2172   
  2177   2173   /* Forward references */
  2178   2174   static int multiSelectOrderBy(
  2179   2175     Parse *pParse,        /* Parsing context */
................................................................................
  2201   2197     int nRow = 1;
  2202   2198     int rc = 0;
  2203   2199     assert( p->selFlags & SF_MultiValue );
  2204   2200     do{
  2205   2201       assert( p->selFlags & SF_Values );
  2206   2202       assert( p->op==TK_ALL || (p->op==TK_SELECT && p->pPrior==0) );
  2207   2203       assert( p->pLimit==0 );
  2208         -    assert( p->pOffset==0 );
  2209   2204       assert( p->pNext==0 || p->pEList->nExpr==p->pNext->pEList->nExpr );
  2210   2205       if( p->pPrior==0 ) break;
  2211   2206       assert( p->pPrior->pNext==p );
  2212   2207       p = p->pPrior;
  2213   2208       nRow++;
  2214   2209     }while(1);
  2215   2210     while( p ){
................................................................................
  2328   2323       case TK_ALL: {
  2329   2324         int addr = 0;
  2330   2325         int nLimit;
  2331   2326         assert( !pPrior->pLimit );
  2332   2327         pPrior->iLimit = p->iLimit;
  2333   2328         pPrior->iOffset = p->iOffset;
  2334   2329         pPrior->pLimit = p->pLimit;
  2335         -      pPrior->pOffset = p->pOffset;
  2336   2330         explainSetInteger(iSub1, pParse->iNextSelectId);
  2337   2331         rc = sqlite3Select(pParse, pPrior, &dest);
  2338   2332         p->pLimit = 0;
  2339         -      p->pOffset = 0;
  2340   2333         if( rc ){
  2341   2334           goto multi_select_end;
  2342   2335         }
  2343   2336         p->pPrior = 0;
  2344   2337         p->iLimit = pPrior->iLimit;
  2345   2338         p->iOffset = pPrior->iOffset;
  2346   2339         if( p->iLimit ){
................................................................................
  2354   2347         explainSetInteger(iSub2, pParse->iNextSelectId);
  2355   2348         rc = sqlite3Select(pParse, p, &dest);
  2356   2349         testcase( rc!=SQLITE_OK );
  2357   2350         pDelete = p->pPrior;
  2358   2351         p->pPrior = pPrior;
  2359   2352         p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow);
  2360   2353         if( pPrior->pLimit
  2361         -       && sqlite3ExprIsInteger(pPrior->pLimit, &nLimit)
         2354  +       && sqlite3ExprIsInteger(pPrior->pLimit->pLeft, &nLimit)
  2362   2355          && nLimit>0 && p->nSelectRow > sqlite3LogEst((u64)nLimit) 
  2363   2356         ){
  2364   2357           p->nSelectRow = sqlite3LogEst((u64)nLimit);
  2365   2358         }
  2366   2359         if( addr ){
  2367   2360           sqlite3VdbeJumpHere(v, addr);
  2368   2361         }
................................................................................
  2369   2362         break;
  2370   2363       }
  2371   2364       case TK_EXCEPT:
  2372   2365       case TK_UNION: {
  2373   2366         int unionTab;    /* Cursor number of the temporary table holding result */
  2374   2367         u8 op = 0;       /* One of the SRT_ operations to apply to self */
  2375   2368         int priorOp;     /* The SRT_ operation to apply to prior selects */
  2376         -      Expr *pLimit, *pOffset; /* Saved values of p->nLimit and p->nOffset */
         2369  +      Expr *pLimit;    /* Saved values of p->nLimit  */
  2377   2370         int addr;
  2378   2371         SelectDest uniondest;
  2379   2372   
  2380   2373         testcase( p->op==TK_EXCEPT );
  2381   2374         testcase( p->op==TK_UNION );
  2382   2375         priorOp = SRT_Union;
  2383   2376         if( dest.eDest==priorOp ){
  2384   2377           /* We can reuse a temporary table generated by a SELECT to our
  2385   2378           ** right.
  2386   2379           */
  2387   2380           assert( p->pLimit==0 );      /* Not allowed on leftward elements */
  2388         -        assert( p->pOffset==0 );     /* Not allowed on leftward elements */
  2389   2381           unionTab = dest.iSDParm;
  2390   2382         }else{
  2391   2383           /* We will need to create our own temporary table to hold the
  2392   2384           ** intermediate results.
  2393   2385           */
  2394   2386           unionTab = pParse->nTab++;
  2395   2387           assert( p->pOrderBy==0 );
................................................................................
  2417   2409         }else{
  2418   2410           assert( p->op==TK_UNION );
  2419   2411           op = SRT_Union;
  2420   2412         }
  2421   2413         p->pPrior = 0;
  2422   2414         pLimit = p->pLimit;
  2423   2415         p->pLimit = 0;
  2424         -      pOffset = p->pOffset;
  2425         -      p->pOffset = 0;
  2426   2416         uniondest.eDest = op;
  2427   2417         explainSetInteger(iSub2, pParse->iNextSelectId);
  2428   2418         rc = sqlite3Select(pParse, p, &uniondest);
  2429   2419         testcase( rc!=SQLITE_OK );
  2430   2420         /* Query flattening in sqlite3Select() might refill p->pOrderBy.
  2431   2421         ** Be sure to delete p->pOrderBy, therefore, to avoid a memory leak. */
  2432   2422         sqlite3ExprListDelete(db, p->pOrderBy);
................................................................................
  2434   2424         p->pPrior = pPrior;
  2435   2425         p->pOrderBy = 0;
  2436   2426         if( p->op==TK_UNION ){
  2437   2427           p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow);
  2438   2428         }
  2439   2429         sqlite3ExprDelete(db, p->pLimit);
  2440   2430         p->pLimit = pLimit;
  2441         -      p->pOffset = pOffset;
  2442   2431         p->iLimit = 0;
  2443   2432         p->iOffset = 0;
  2444   2433   
  2445   2434         /* Convert the data in the temporary table into whatever form
  2446   2435         ** it is that we currently need.
  2447   2436         */
  2448   2437         assert( unionTab==dest.iSDParm || dest.eDest!=priorOp );
................................................................................
  2462   2451           sqlite3VdbeAddOp2(v, OP_Close, unionTab, 0);
  2463   2452         }
  2464   2453         break;
  2465   2454       }
  2466   2455       default: assert( p->op==TK_INTERSECT ); {
  2467   2456         int tab1, tab2;
  2468   2457         int iCont, iBreak, iStart;
  2469         -      Expr *pLimit, *pOffset;
         2458  +      Expr *pLimit;
  2470   2459         int addr;
  2471   2460         SelectDest intersectdest;
  2472   2461         int r1;
  2473   2462   
  2474   2463         /* INTERSECT is different from the others since it requires
  2475   2464         ** two temporary tables.  Hence it has its own case.  Begin
  2476   2465         ** by allocating the tables we will need.
................................................................................
  2498   2487         */
  2499   2488         addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, tab2, 0);
  2500   2489         assert( p->addrOpenEphm[1] == -1 );
  2501   2490         p->addrOpenEphm[1] = addr;
  2502   2491         p->pPrior = 0;
  2503   2492         pLimit = p->pLimit;
  2504   2493         p->pLimit = 0;
  2505         -      pOffset = p->pOffset;
  2506         -      p->pOffset = 0;
  2507   2494         intersectdest.iSDParm = tab2;
  2508   2495         explainSetInteger(iSub2, pParse->iNextSelectId);
  2509   2496         rc = sqlite3Select(pParse, p, &intersectdest);
  2510   2497         testcase( rc!=SQLITE_OK );
  2511   2498         pDelete = p->pPrior;
  2512   2499         p->pPrior = pPrior;
  2513   2500         if( p->nSelectRow>pPrior->nSelectRow ) p->nSelectRow = pPrior->nSelectRow;
  2514   2501         sqlite3ExprDelete(db, p->pLimit);
  2515   2502         p->pLimit = pLimit;
  2516         -      p->pOffset = pOffset;
  2517   2503   
  2518   2504         /* Generate code to take the intersection of the two temporary
  2519   2505         ** tables.
  2520   2506         */
  2521   2507         assert( p->pEList );
  2522   2508         iBreak = sqlite3VdbeMakeLabel(v);
  2523   2509         iCont = sqlite3VdbeMakeLabel(v);
................................................................................
  2988   2974                                     regLimitA);
  2989   2975       sqlite3VdbeAddOp2(v, OP_Copy, regLimitA, regLimitB);
  2990   2976     }else{
  2991   2977       regLimitA = regLimitB = 0;
  2992   2978     }
  2993   2979     sqlite3ExprDelete(db, p->pLimit);
  2994   2980     p->pLimit = 0;
  2995         -  sqlite3ExprDelete(db, p->pOffset);
  2996         -  p->pOffset = 0;
  2997   2981   
  2998   2982     regAddrA = ++pParse->nMem;
  2999   2983     regAddrB = ++pParse->nMem;
  3000   2984     regOutA = ++pParse->nMem;
  3001   2985     regOutB = ++pParse->nMem;
  3002   2986     sqlite3SelectDestInit(&destA, SRT_Coroutine, regAddrA);
  3003   2987     sqlite3SelectDestInit(&destB, SRT_Coroutine, regAddrB);
................................................................................
  3453   3437     assert( pSubSrc );
  3454   3438     /* Prior to version 3.1.2, when LIMIT and OFFSET had to be simple constants,
  3455   3439     ** not arbitrary expressions, we allowed some combining of LIMIT and OFFSET
  3456   3440     ** because they could be computed at compile-time.  But when LIMIT and OFFSET
  3457   3441     ** became arbitrary expressions, we were forced to add restrictions (13)
  3458   3442     ** and (14). */
  3459   3443     if( pSub->pLimit && p->pLimit ) return 0;              /* Restriction (13) */
  3460         -  if( pSub->pOffset ) return 0;                          /* Restriction (14) */
         3444  +  if( pSub->pLimit && pSub->pLimit->pRight ) return 0;   /* Restriction (14) */
  3461   3445     if( (p->selFlags & SF_Compound)!=0 && pSub->pLimit ){
  3462   3446       return 0;                                            /* Restriction (15) */
  3463   3447     }
  3464   3448     if( pSubSrc->nSrc==0 ) return 0;                       /* Restriction (7)  */
  3465   3449     if( pSub->selFlags & SF_Distinct ) return 0;           /* Restriction (4)  */
  3466   3450     if( pSub->pLimit && (pSrc->nSrc>1 || isAgg) ){
  3467   3451        return 0;         /* Restrictions (8)(9) */
................................................................................
  3601   3585     **
  3602   3586     ** We call this the "compound-subquery flattening".
  3603   3587     */
  3604   3588     for(pSub=pSub->pPrior; pSub; pSub=pSub->pPrior){
  3605   3589       Select *pNew;
  3606   3590       ExprList *pOrderBy = p->pOrderBy;
  3607   3591       Expr *pLimit = p->pLimit;
  3608         -    Expr *pOffset = p->pOffset;
  3609   3592       Select *pPrior = p->pPrior;
  3610   3593       p->pOrderBy = 0;
  3611   3594       p->pSrc = 0;
  3612   3595       p->pPrior = 0;
  3613   3596       p->pLimit = 0;
  3614         -    p->pOffset = 0;
  3615   3597       pNew = sqlite3SelectDup(db, p, 0);
  3616   3598       sqlite3SelectSetName(pNew, pSub->zSelName);
  3617         -    p->pOffset = pOffset;
  3618   3599       p->pLimit = pLimit;
  3619   3600       p->pOrderBy = pOrderBy;
  3620   3601       p->pSrc = pSrc;
  3621   3602       p->op = TK_ALL;
  3622   3603       if( pNew==0 ){
  3623   3604         p->pPrior = pPrior;
  3624   3605       }else{
................................................................................
  4076   4057     p->pWith = 0;
  4077   4058     p->selFlags &= ~SF_Compound;
  4078   4059     assert( (p->selFlags & SF_Converted)==0 );
  4079   4060     p->selFlags |= SF_Converted;
  4080   4061     assert( pNew->pPrior!=0 );
  4081   4062     pNew->pPrior->pNext = pNew;
  4082   4063     pNew->pLimit = 0;
  4083         -  pNew->pOffset = 0;
  4084   4064     return WRC_Continue;
  4085   4065   }
  4086   4066   
  4087   4067   /*
  4088   4068   ** Check to see if the FROM clause term pFrom has table-valued function
  4089   4069   ** arguments.  If it does, leave an error message in pParse and return
  4090   4070   ** non-zero, since pFrom is not allowed to be a table-valued function.

Changes to src/shell.c.in.

  5918   5918         sqlite3_snprintf(sizeof(p->zTestcase), p->zTestcase, "%s", azArg[1]);
  5919   5919       }else{
  5920   5920         sqlite3_snprintf(sizeof(p->zTestcase), p->zTestcase, "?");
  5921   5921       }
  5922   5922     }else
  5923   5923   
  5924   5924   #ifndef SQLITE_UNTESTABLE
  5925         -  if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 && nArg>=2 ){
         5925  +  if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 ){
  5926   5926       static const struct {
  5927   5927          const char *zCtrlName;   /* Name of a test-control option */
  5928   5928          int ctrlCode;            /* Integer code for that option */
         5929  +       const char *zUsage;      /* Usage notes */
  5929   5930       } aCtrl[] = {
  5930         -      { "prng_save",             SQLITE_TESTCTRL_PRNG_SAVE              },
  5931         -      { "prng_restore",          SQLITE_TESTCTRL_PRNG_RESTORE           },
  5932         -      { "prng_reset",            SQLITE_TESTCTRL_PRNG_RESET             },
  5933         -      { "bitvec_test",           SQLITE_TESTCTRL_BITVEC_TEST            },
  5934         -      { "fault_install",         SQLITE_TESTCTRL_FAULT_INSTALL          },
  5935         -      { "benign_malloc_hooks",   SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS    },
  5936         -      { "pending_byte",          SQLITE_TESTCTRL_PENDING_BYTE           },
  5937         -      { "assert",                SQLITE_TESTCTRL_ASSERT                 },
  5938         -      { "always",                SQLITE_TESTCTRL_ALWAYS                 },
  5939         -      { "reserve",               SQLITE_TESTCTRL_RESERVE                },
  5940         -      { "optimizations",         SQLITE_TESTCTRL_OPTIMIZATIONS          },
  5941         -      { "iskeyword",             SQLITE_TESTCTRL_ISKEYWORD              },
  5942         -      { "byteorder",             SQLITE_TESTCTRL_BYTEORDER              },
  5943         -      { "never_corrupt",         SQLITE_TESTCTRL_NEVER_CORRUPT          },
  5944         -      { "imposter",              SQLITE_TESTCTRL_IMPOSTER               },
         5931  +      { "always",             SQLITE_TESTCTRL_ALWAYS,        "BOOLEAN"            },
         5932  +      { "assert",             SQLITE_TESTCTRL_ASSERT,        "BOOLEAN"            },
         5933  +    /*{ "benign_malloc_hooks",SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS, ""          },*/
         5934  +    /*{ "bitvec_test",        SQLITE_TESTCTRL_BITVEC_TEST,   ""                },*/
         5935  +      { "byteorder",          SQLITE_TESTCTRL_BYTEORDER,     ""                   },
         5936  +    /*{ "fault_install",      SQLITE_TESTCTRL_FAULT_INSTALL, ""                }, */
         5937  +      { "imposter",           SQLITE_TESTCTRL_IMPOSTER,   "SCHEMA ON/OFF ROOTPAGE"},
         5938  +#ifdef SQLITE_N_KEYWORD
         5939  +      { "iskeyword",          SQLITE_TESTCTRL_ISKEYWORD,     "IDENTIFIER"         },
         5940  +#endif
         5941  +      { "localtime_fault",    SQLITE_TESTCTRL_LOCALTIME_FAULT,"BOOLEAN"           },
         5942  +      { "never_corrupt",      SQLITE_TESTCTRL_NEVER_CORRUPT, "BOOLEAN"            },
         5943  +      { "optimizations",      SQLITE_TESTCTRL_OPTIMIZATIONS, "DISABLE-MASK"       },
         5944  +      { "pending_byte",       SQLITE_TESTCTRL_PENDING_BYTE,  "OFFSET  "           },
         5945  +      { "prng_reset",         SQLITE_TESTCTRL_PRNG_RESET,    ""                   },
         5946  +      { "prng_restore",       SQLITE_TESTCTRL_PRNG_RESTORE,  ""                   },
         5947  +      { "prng_save",          SQLITE_TESTCTRL_PRNG_SAVE,     ""                   },
         5948  +      { "reserve",            SQLITE_TESTCTRL_RESERVE,       "BYTES-OF-RESERVE"   },
  5945   5949       };
  5946   5950       int testctrl = -1;
  5947         -    int rc2 = 0;
         5951  +    int iCtrl = -1;
         5952  +    int rc2 = 0;    /* 0: usage.  1: %d  2: %x  3: no-output */
         5953  +    int isOk = 0;
  5948   5954       int i, n2;
  5949   5955       open_db(p, 0);
         5956  +    const char *zCmd = nArg>=2 ? azArg[1] : "help";
         5957  +
         5958  +    /* The argument can optionally begin with "-" or "--" */
         5959  +    if( zCmd[0]=='-' && zCmd[1] ){
         5960  +      zCmd++;
         5961  +      if( zCmd[0]=='-' && zCmd[1] ) zCmd++;
         5962  +    }
         5963  +
         5964  +    /* --help lists all test-controls */
         5965  +    if( strcmp(zCmd,"help")==0 ){
         5966  +      utf8_printf(p->out, "Available test-controls:\n");
         5967  +      for(i=0; i<ArraySize(aCtrl); i++){
         5968  +        utf8_printf(p->out, "  .testctrl %s %s\n",
         5969  +                    aCtrl[i].zCtrlName, aCtrl[i].zUsage);
         5970  +      }
         5971  +      rc = 1;
         5972  +      goto meta_command_exit;
         5973  +    }
  5950   5974   
  5951   5975       /* convert testctrl text option to value. allow any unique prefix
  5952   5976       ** of the option name, or a numerical value. */
  5953         -    n2 = strlen30(azArg[1]);
         5977  +    n2 = strlen30(zCmd);
  5954   5978       for(i=0; i<ArraySize(aCtrl); i++){
  5955         -      if( strncmp(azArg[1], aCtrl[i].zCtrlName, n2)==0 ){
         5979  +      if( strncmp(zCmd, aCtrl[i].zCtrlName, n2)==0 ){
  5956   5980           if( testctrl<0 ){
  5957   5981             testctrl = aCtrl[i].ctrlCode;
         5982  +          iCtrl = i;
  5958   5983           }else{
  5959         -          utf8_printf(stderr, "ambiguous option name: \"%s\"\n", azArg[1]);
  5960         -          testctrl = -1;
  5961         -          break;
         5984  +          utf8_printf(stderr, "Error: ambiguous test-control: \"%s\"\n"
         5985  +                              "Use \".testctrl --help\" for help\n", zCmd);
         5986  +          rc = 1;
         5987  +          goto meta_command_exit;
  5962   5988           }
  5963   5989         }
  5964   5990       }
  5965         -    if( testctrl<0 ) testctrl = (int)integerValue(azArg[1]);
  5966         -    if( (testctrl<SQLITE_TESTCTRL_FIRST) || (testctrl>SQLITE_TESTCTRL_LAST) ){
  5967         -      utf8_printf(stderr,"Error: invalid testctrl option: %s\n", azArg[1]);
         5991  +    if( testctrl<0 ){
         5992  +      utf8_printf(stderr,"Error: unknown test-control: %s\n"
         5993  +                         "Use \".testctrl --help\" for help\n", zCmd);
  5968   5994       }else{
  5969   5995         switch(testctrl){
  5970   5996   
  5971   5997           /* sqlite3_test_control(int, db, int) */
  5972   5998           case SQLITE_TESTCTRL_OPTIMIZATIONS:
  5973   5999           case SQLITE_TESTCTRL_RESERVE:
  5974   6000             if( nArg==3 ){
  5975   6001               int opt = (int)strtol(azArg[2], 0, 0);
  5976   6002               rc2 = sqlite3_test_control(testctrl, p->db, opt);
  5977         -            raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
  5978         -          } else {
  5979         -            utf8_printf(stderr,"Error: testctrl %s takes a single int option\n",
  5980         -                    azArg[1]);
         6003  +            isOk = 3;
  5981   6004             }
  5982   6005             break;
  5983   6006   
  5984   6007           /* sqlite3_test_control(int) */
  5985   6008           case SQLITE_TESTCTRL_PRNG_SAVE:
  5986   6009           case SQLITE_TESTCTRL_PRNG_RESTORE:
  5987   6010           case SQLITE_TESTCTRL_PRNG_RESET:
  5988   6011           case SQLITE_TESTCTRL_BYTEORDER:
  5989   6012             if( nArg==2 ){
  5990   6013               rc2 = sqlite3_test_control(testctrl);
  5991         -            raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
  5992         -          } else {
  5993         -            utf8_printf(stderr,"Error: testctrl %s takes no options\n",
  5994         -                        azArg[1]);
         6014  +            isOk = testctrl==SQLITE_TESTCTRL_BYTEORDER ? 1 : 3;
  5995   6015             }
  5996   6016             break;
  5997   6017   
  5998   6018           /* sqlite3_test_control(int, uint) */
  5999   6019           case SQLITE_TESTCTRL_PENDING_BYTE:
  6000   6020             if( nArg==3 ){
  6001   6021               unsigned int opt = (unsigned int)integerValue(azArg[2]);
  6002   6022               rc2 = sqlite3_test_control(testctrl, opt);
  6003         -            raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
  6004         -          } else {
  6005         -            utf8_printf(stderr,"Error: testctrl %s takes a single unsigned"
  6006         -                           " int option\n", azArg[1]);
         6023  +            isOk = 3;
  6007   6024             }
  6008   6025             break;
  6009   6026   
  6010   6027           /* sqlite3_test_control(int, int) */
  6011   6028           case SQLITE_TESTCTRL_ASSERT:
  6012   6029           case SQLITE_TESTCTRL_ALWAYS:
         6030  +          if( nArg==3 ){
         6031  +            int opt = booleanValue(azArg[2]);
         6032  +            rc2 = sqlite3_test_control(testctrl, opt);
         6033  +            isOk = 1;
         6034  +          }
         6035  +          break;
         6036  +
         6037  +        /* sqlite3_test_control(int, int) */
         6038  +        case SQLITE_TESTCTRL_LOCALTIME_FAULT:
  6013   6039           case SQLITE_TESTCTRL_NEVER_CORRUPT:
  6014   6040             if( nArg==3 ){
  6015   6041               int opt = booleanValue(azArg[2]);
  6016   6042               rc2 = sqlite3_test_control(testctrl, opt);
  6017         -            raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
  6018         -          } else {
  6019         -            utf8_printf(stderr,"Error: testctrl %s takes a single int option\n",
  6020         -                            azArg[1]);
         6043  +            isOk = 3;
  6021   6044             }
  6022   6045             break;
  6023   6046   
  6024   6047           /* sqlite3_test_control(int, char *) */
  6025   6048   #ifdef SQLITE_N_KEYWORD
  6026   6049           case SQLITE_TESTCTRL_ISKEYWORD:
  6027   6050             if( nArg==3 ){
  6028   6051               const char *opt = azArg[2];
  6029   6052               rc2 = sqlite3_test_control(testctrl, opt);
  6030         -            raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
  6031         -          } else {
  6032         -            utf8_printf(stderr,
  6033         -                        "Error: testctrl %s takes a single char * option\n",
  6034         -                        azArg[1]);
         6053  +            isOk = 1;
  6035   6054             }
  6036   6055             break;
  6037   6056   #endif
  6038   6057   
  6039   6058           case SQLITE_TESTCTRL_IMPOSTER:
  6040   6059             if( nArg==5 ){
  6041   6060               rc2 = sqlite3_test_control(testctrl, p->db,
  6042   6061                             azArg[2],
  6043   6062                             integerValue(azArg[3]),
  6044   6063                             integerValue(azArg[4]));
  6045         -            raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
  6046         -          }else{
  6047         -            raw_printf(stderr,"Usage: .testctrl imposter dbName onoff tnum\n");
         6064  +            isOk = 3;
  6048   6065             }
  6049   6066             break;
  6050         -
  6051         -        case SQLITE_TESTCTRL_BITVEC_TEST:
  6052         -        case SQLITE_TESTCTRL_FAULT_INSTALL:
  6053         -        case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS:
  6054         -        default:
  6055         -          utf8_printf(stderr,
  6056         -                      "Error: CLI support for testctrl %s not implemented\n",
  6057         -                      azArg[1]);
  6058         -          break;
  6059   6067         }
  6060   6068       }
         6069  +    if( isOk==0 && iCtrl>=0 ){
         6070  +      utf8_printf(p->out, "Usage: .testctrl %s %s\n", zCmd, aCtrl[iCtrl].zUsage);
         6071  +      rc = 1;
         6072  +    }else if( isOk==1 ){
         6073  +      raw_printf(p->out, "%d\n", rc2);
         6074  +    }else if( isOk==2 ){
         6075  +      raw_printf(p->out, "0x%08x\n", rc2);
         6076  +    }
  6061   6077     }else
  6062   6078   #endif /* !defined(SQLITE_UNTESTABLE) */
  6063   6079   
  6064   6080     if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 ){
  6065   6081       open_db(p, 0);
  6066   6082       sqlite3_busy_timeout(p->db, nArg>=2 ? (int)integerValue(azArg[1]) : 0);
  6067   6083     }else

Changes to src/sqliteInt.h.

  2745   2745     Expr *pWhere;          /* The WHERE clause */
  2746   2746     ExprList *pGroupBy;    /* The GROUP BY clause */
  2747   2747     Expr *pHaving;         /* The HAVING clause */
  2748   2748     ExprList *pOrderBy;    /* The ORDER BY clause */
  2749   2749     Select *pPrior;        /* Prior select in a compound select statement */
  2750   2750     Select *pNext;         /* Next select to the left in a compound */
  2751   2751     Expr *pLimit;          /* LIMIT expression. NULL means not used. */
  2752         -  Expr *pOffset;         /* OFFSET expression. NULL means not used. */
  2753   2752     With *pWith;           /* WITH clause attached to this select. Or NULL. */
  2754   2753   };
  2755   2754   
  2756   2755   /*
  2757   2756   ** Allowed values for Select.selFlags.  The "SF" prefix stands for
  2758   2757   ** "Select Flag".
  2759   2758   **
................................................................................
  3752   3751   void sqlite3SrcListDelete(sqlite3*, SrcList*);
  3753   3752   Index *sqlite3AllocateIndexObject(sqlite3*,i16,int,char**);
  3754   3753   void sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*,
  3755   3754                             Expr*, int, int, u8);
  3756   3755   void sqlite3DropIndex(Parse*, SrcList*, int);
  3757   3756   int sqlite3Select(Parse*, Select*, SelectDest*);
  3758   3757   Select *sqlite3SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList*,
  3759         -                         Expr*,ExprList*,u32,Expr*,Expr*);
         3758  +                         Expr*,ExprList*,u32,Expr*);
  3760   3759   void sqlite3SelectDelete(sqlite3*, Select*);
  3761   3760   Table *sqlite3SrcListLookup(Parse*, SrcList*);
  3762   3761   int sqlite3IsReadOnly(Parse*, Table*, int);
  3763   3762   void sqlite3OpenTable(Parse*, int iCur, int iDb, Table*, int);
  3764   3763   #if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY)
  3765         -Expr *sqlite3LimitWhere(Parse*,SrcList*,Expr*,ExprList*,Expr*,Expr*,char*);
         3764  +Expr *sqlite3LimitWhere(Parse*,SrcList*,Expr*,ExprList*,Expr*,char*);
  3766   3765   #endif
  3767         -void sqlite3DeleteFrom(Parse*, SrcList*, Expr*, ExprList*, Expr*, Expr*);
  3768         -void sqlite3Update(Parse*, SrcList*, ExprList*,Expr*,int,ExprList*,Expr*,Expr*);
         3766  +void sqlite3DeleteFrom(Parse*, SrcList*, Expr*, ExprList*, Expr*);
         3767  +void sqlite3Update(Parse*, SrcList*, ExprList*,Expr*,int,ExprList*,Expr*);
  3769   3768   WhereInfo *sqlite3WhereBegin(Parse*,SrcList*,Expr*,ExprList*,ExprList*,u16,int);
  3770   3769   void sqlite3WhereEnd(WhereInfo*);
  3771   3770   LogEst sqlite3WhereOutputRowCount(WhereInfo*);
  3772   3771   int sqlite3WhereIsDistinct(WhereInfo*);
  3773   3772   int sqlite3WhereIsOrdered(WhereInfo*);
  3774   3773   int sqlite3WhereOrderedInnerLoop(WhereInfo*);
  3775   3774   int sqlite3WhereIsSorted(WhereInfo*);
................................................................................
  3885   3884   void sqlite3RegisterDateTimeFunctions(void);
  3886   3885   void sqlite3RegisterPerConnectionBuiltinFunctions(sqlite3*);
  3887   3886   int sqlite3SafetyCheckOk(sqlite3*);
  3888   3887   int sqlite3SafetyCheckSickOrOk(sqlite3*);
  3889   3888   void sqlite3ChangeCookie(Parse*, int);
  3890   3889   
  3891   3890   #if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER)
  3892         -void sqlite3MaterializeView(Parse*, Table*, Expr*, ExprList*,Expr*,Expr*,int);
         3891  +void sqlite3MaterializeView(Parse*, Table*, Expr*, ExprList*,Expr*,int);
  3893   3892   #endif
  3894   3893   
  3895   3894   #ifndef SQLITE_OMIT_TRIGGER
  3896   3895     void sqlite3BeginTrigger(Parse*, Token*,Token*,int,int,IdList*,SrcList*,
  3897   3896                              Expr*,int, int);
  3898   3897     void sqlite3FinishTrigger(Parse*, TriggerStep*, Token*);
  3899   3898     void sqlite3DropTrigger(Parse*, SrcList*, int);

Changes to src/treeview.c.

   149    149         n = 0;
   150    150         if( p->pSrc && p->pSrc->nSrc ) n++;
   151    151         if( p->pWhere ) n++;
   152    152         if( p->pGroupBy ) n++;
   153    153         if( p->pHaving ) n++;
   154    154         if( p->pOrderBy ) n++;
   155    155         if( p->pLimit ) n++;
   156         -      if( p->pOffset ) n++;
   157    156       }
   158    157       sqlite3TreeViewExprList(pView, p->pEList, (n--)>0, "result-set");
   159    158       if( p->pSrc && p->pSrc->nSrc ){
   160    159         int i;
   161    160         pView = sqlite3TreeViewPush(pView, (n--)>0);
   162    161         sqlite3TreeViewLine(pView, "FROM");
   163    162         for(i=0; i<p->pSrc->nSrc; i++){
................................................................................
   206    205         sqlite3TreeViewPop(pView);
   207    206       }
   208    207       if( p->pOrderBy ){
   209    208         sqlite3TreeViewExprList(pView, p->pOrderBy, (n--)>0, "ORDERBY");
   210    209       }
   211    210       if( p->pLimit ){
   212    211         sqlite3TreeViewItem(pView, "LIMIT", (n--)>0);
   213         -      sqlite3TreeViewExpr(pView, p->pLimit, 0);
   214         -      sqlite3TreeViewPop(pView);
   215         -    }
   216         -    if( p->pOffset ){
   217         -      sqlite3TreeViewItem(pView, "OFFSET", (n--)>0);
   218         -      sqlite3TreeViewExpr(pView, p->pOffset, 0);
          212  +      sqlite3TreeViewExpr(pView, p->pLimit->pLeft, p->pLimit->pRight!=0);
          213  +      if( p->pLimit->pRight ){
          214  +        sqlite3TreeViewItem(pView, "OFFSET", (n--)>0);
          215  +        sqlite3TreeViewExpr(pView, p->pLimit->pRight, 0);
          216  +        sqlite3TreeViewPop(pView);
          217  +      }
   219    218         sqlite3TreeViewPop(pView);
   220    219       }
   221    220       if( p->pPrior ){
   222    221         const char *zOp = "UNION";
   223    222         switch( p->op ){
   224    223           case TK_ALL:         zOp = "UNION ALL";  break;
   225    224           case TK_INTERSECT:   zOp = "INTERSECT";  break;

Changes to src/trigger.c.

   707    707   
   708    708       switch( pStep->op ){
   709    709         case TK_UPDATE: {
   710    710           sqlite3Update(pParse, 
   711    711             targetSrcList(pParse, pStep),
   712    712             sqlite3ExprListDup(db, pStep->pExprList, 0), 
   713    713             sqlite3ExprDup(db, pStep->pWhere, 0), 
   714         -          pParse->eOrconf, 0, 0, 0
          714  +          pParse->eOrconf, 0, 0
   715    715           );
   716    716           break;
   717    717         }
   718    718         case TK_INSERT: {
   719    719           sqlite3Insert(pParse, 
   720    720             targetSrcList(pParse, pStep),
   721    721             sqlite3SelectDup(db, pStep->pSelect, 0), 
................................................................................
   723    723             pParse->eOrconf
   724    724           );
   725    725           break;
   726    726         }
   727    727         case TK_DELETE: {
   728    728           sqlite3DeleteFrom(pParse, 
   729    729             targetSrcList(pParse, pStep),
   730         -          sqlite3ExprDup(db, pStep->pWhere, 0), 0, 0, 0
          730  +          sqlite3ExprDup(db, pStep->pWhere, 0), 0, 0
   731    731           );
   732    732           break;
   733    733         }
   734    734         default: assert( pStep->op==TK_SELECT ); {
   735    735           SelectDest sDest;
   736    736           Select *pSelect = sqlite3SelectDup(db, pStep->pSelect, 0);
   737    737           sqlite3SelectDestInit(&sDest, SRT_Discard, 0);

Changes to src/update.c.

    89     89   void sqlite3Update(
    90     90     Parse *pParse,         /* The parser context */
    91     91     SrcList *pTabList,     /* The table in which we should change things */
    92     92     ExprList *pChanges,    /* Things to be changed */
    93     93     Expr *pWhere,          /* The WHERE clause.  May be null */
    94     94     int onError,           /* How to handle constraint errors */
    95     95     ExprList *pOrderBy,    /* ORDER BY clause. May be null */
    96         -  Expr *pLimit,          /* LIMIT clause. May be null */
    97         -  Expr *pOffset          /* OFFSET clause. May be null */
           96  +  Expr *pLimit           /* LIMIT clause. May be null */
    98     97   ){
    99     98     int i, j;              /* Loop counters */
   100     99     Table *pTab;           /* The table to be updated */
   101    100     int addrTop = 0;       /* VDBE instruction address of the start of the loop */
   102    101     WhereInfo *pWInfo;     /* Information about the WHERE clause */
   103    102     Vdbe *v;               /* The virtual database engine */
   104    103     Index *pIdx;           /* For looping over indices */
................................................................................
   178    177   # undef isView
   179    178   # define isView 0
   180    179   #endif
   181    180   
   182    181   #ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT
   183    182     if( !isView ){
   184    183       pWhere = sqlite3LimitWhere(
   185         -        pParse, pTabList, pWhere, pOrderBy, pLimit, pOffset, "UPDATE"
          184  +        pParse, pTabList, pWhere, pOrderBy, pLimit, "UPDATE"
   186    185       );
   187    186       pOrderBy = 0;
   188         -    pLimit = pOffset = 0;
          187  +    pLimit = 0;
   189    188     }
   190    189   #endif
   191    190   
   192    191     if( sqlite3ViewGetColumnNames(pParse, pTab) ){
   193    192       goto update_cleanup;
   194    193     }
   195    194     if( sqlite3IsReadOnly(pParse, pTab, tmask) ){
................................................................................
   354    353   
   355    354     /* If we are trying to update a view, realize that view into
   356    355     ** an ephemeral table.
   357    356     */
   358    357   #if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER)
   359    358     if( isView ){
   360    359       sqlite3MaterializeView(pParse, pTab, 
   361         -        pWhere, pOrderBy, pLimit, pOffset, iDataCur
          360  +        pWhere, pOrderBy, pLimit, iDataCur
   362    361       );
   363    362       pOrderBy = 0;
   364         -    pLimit = pOffset = 0;
          363  +    pLimit = 0;
   365    364     }
   366    365   #endif
   367    366   
   368    367     /* Resolve the column names in all the expressions in the
   369    368     ** WHERE clause.
   370    369     */
   371    370     if( sqlite3ResolveExprNames(&sNC, pWhere) ){
................................................................................
   744    743     sqlite3DbFree(db, aXRef); /* Also frees aRegIdx[] and aToOpen[] */
   745    744     sqlite3SrcListDelete(db, pTabList);
   746    745     sqlite3ExprListDelete(db, pChanges);
   747    746     sqlite3ExprDelete(db, pWhere);
   748    747   #if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) 
   749    748     sqlite3ExprListDelete(db, pOrderBy);
   750    749     sqlite3ExprDelete(db, pLimit);
   751         -  sqlite3ExprDelete(db, pOffset);
   752    750   #endif
   753    751     return;
   754    752   }
   755    753   /* Make sure "isView" and other macros defined above are undefined. Otherwise
   756    754   ** they may interfere with compilation of other functions in this file
   757    755   ** (or in another file, if this file becomes part of the amalgamation).  */
   758    756   #ifdef isView

Changes to src/walker.c.

    87     87   int sqlite3WalkSelectExpr(Walker *pWalker, Select *p){
    88     88     if( sqlite3WalkExprList(pWalker, p->pEList) ) return WRC_Abort;
    89     89     if( sqlite3WalkExpr(pWalker, p->pWhere) ) return WRC_Abort;
    90     90     if( sqlite3WalkExprList(pWalker, p->pGroupBy) ) return WRC_Abort;
    91     91     if( sqlite3WalkExpr(pWalker, p->pHaving) ) return WRC_Abort;
    92     92     if( sqlite3WalkExprList(pWalker, p->pOrderBy) ) return WRC_Abort;
    93     93     if( sqlite3WalkExpr(pWalker, p->pLimit) ) return WRC_Abort;
    94         -  if( sqlite3WalkExpr(pWalker, p->pOffset) ) return WRC_Abort;
    95     94     return WRC_Continue;
    96     95   }
    97     96   
    98     97   /*
    99     98   ** Walk the parse trees associated with all subqueries in the
   100     99   ** FROM clause of SELECT statement p.  Do not invoke the select
   101    100   ** callback on p, but do invoke it on each FROM clause subquery

Changes to test/stmtvtab1.test.

    74     74   
    75     75   # Flushing the cache clears all of the prepared statements.
    76     76   #
    77     77   db cache flush
    78     78   do_execsql_test stmtvtab1-160 {
    79     79     SELECT * FROM sqlite_stmt WHERE NOT busy;
    80     80   } {}
           81  +
           82  +finish_test