/ Check-in [179ef816]
Login

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

Overview
Comment:Fix the OFFSET clause so that it works correctly on queries that lack a FROM clause. Ticket [07d6a0453d4ed8].
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 179ef81648b0ad557df78b7712f216b876b6fb65
User & Date: drh 2014-03-21 18:16:23
Context
2014-03-21
19:27
Avoid leaking memory in an obscure case where the flattener adds an ORDER BY clause to the recursive part of a recursive query. check-in: 1f413aca user: dan tags: trunk
18:45
Merge the OFFSET-on-query-without-FROM fix from trunk. check-in: 71e9ae72 user: drh tags: orderby-planning
18:16
Fix the OFFSET clause so that it works correctly on queries that lack a FROM clause. Ticket [07d6a0453d4ed8]. check-in: 179ef816 user: drh tags: trunk
2014-03-20
19:04
Remove a testcase() that is now always true due to the "x IN (?)" optimization. Add an ALWAYS() around a conditional in the parser that cannot be false. check-in: d5a1530b user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/select.c.

   469    469   ** Add code to implement the OFFSET
   470    470   */
   471    471   static void codeOffset(
   472    472     Vdbe *v,          /* Generate code into this VM */
   473    473     int iOffset,      /* Register holding the offset counter */
   474    474     int iContinue     /* Jump here to skip the current record */
   475    475   ){
   476         -  if( iOffset>0 && iContinue!=0 ){
          476  +  if( iOffset>0 ){
   477    477       int addr;
   478    478       sqlite3VdbeAddOp2(v, OP_AddImm, iOffset, -1);
   479    479       addr = sqlite3VdbeAddOp1(v, OP_IfNeg, iOffset); VdbeCoverage(v);
   480    480       sqlite3VdbeAddOp2(v, OP_Goto, 0, iContinue);
   481    481       VdbeComment((v, "skip OFFSET records"));
   482    482       sqlite3VdbeJumpHere(v, addr);
   483    483     }
................................................................................
   575    575     int iParm = pDest->iSDParm; /* First argument to disposal method */
   576    576     int nResultCol;             /* Number of result columns */
   577    577   
   578    578     assert( v );
   579    579     assert( pEList!=0 );
   580    580     hasDistinct = pDistinct ? pDistinct->eTnctType : WHERE_DISTINCT_NOOP;
   581    581     if( pOrderBy==0 && !hasDistinct ){
          582  +    assert( iContinue!=0 );
   582    583       codeOffset(v, p->iOffset, iContinue);
   583    584     }
   584    585   
   585    586     /* Pull the requested columns.
   586    587     */
   587    588     nResultCol = pEList->nExpr;
   588    589   

Changes to src/where.c.

    43     43   }
    44     44   
    45     45   /*
    46     46   ** Return the VDBE address or label to jump to in order to continue
    47     47   ** immediately with the next row of a WHERE clause.
    48     48   */
    49     49   int sqlite3WhereContinueLabel(WhereInfo *pWInfo){
           50  +  assert( pWInfo->iContinue!=0 );
    50     51     return pWInfo->iContinue;
    51     52   }
    52     53   
    53     54   /*
    54     55   ** Return the VDBE address or label to jump to in order to break
    55     56   ** out of a WHERE loop.
    56     57   */
................................................................................
  5449   5450     }
  5450   5451     pWInfo->aiCurOnePass[0] = pWInfo->aiCurOnePass[1] = -1;
  5451   5452     pWInfo->nLevel = nTabList;
  5452   5453     pWInfo->pParse = pParse;
  5453   5454     pWInfo->pTabList = pTabList;
  5454   5455     pWInfo->pOrderBy = pOrderBy;
  5455   5456     pWInfo->pResultSet = pResultSet;
  5456         -  pWInfo->iBreak = sqlite3VdbeMakeLabel(v);
         5457  +  pWInfo->iBreak = pWInfo->iContinue = sqlite3VdbeMakeLabel(v);
  5457   5458     pWInfo->wctrlFlags = wctrlFlags;
  5458   5459     pWInfo->savedNQueryLoop = pParse->nQueryLoop;
  5459   5460     pMaskSet = &pWInfo->sMaskSet;
  5460   5461     sWLB.pWInfo = pWInfo;
  5461   5462     sWLB.pWC = &pWInfo->sWC;
  5462   5463     sWLB.pNew = (WhereLoop*)(((char*)pWInfo)+nByteWInfo);
  5463   5464     assert( EIGHT_BYTE_ALIGNMENT(sWLB.pNew) );

Changes to test/limit.test.

   611    611   } {32}
   612    612   do_test limit-13.72 {
   613    613     db eval {SELECT z FROM v13c LIMIT 2 OFFSET 7}
   614    614   } {32}
   615    615   do_test limit-13.81 {
   616    616     db eval {SELECT z FROM v13c LIMIT 1 OFFSET 8}
   617    617   } {}
          618  +
          619  +do_execsql_test limit-14.1 {
          620  +  SELECT 123 LIMIT 1 OFFSET 0
          621  +} {123}
          622  +do_execsql_test limit-14.2 {
          623  +  SELECT 123 LIMIT 1 OFFSET 1
          624  +} {}
          625  +do_execsql_test limit-14.3 {
          626  +  SELECT 123 LIMIT 0 OFFSET 0
          627  +} {}
          628  +do_execsql_test limit-14.4 {
          629  +  SELECT 123 LIMIT 0 OFFSET 1
          630  +} {}
          631  +do_execsql_test limit-14.6 {
          632  +  SELECT 123 LIMIT -1 OFFSET 0
          633  +} {123}
          634  +do_execsql_test limit-14.7 {
          635  +  SELECT 123 LIMIT -1 OFFSET 1
          636  +} {}
          637  +
   618    638   
   619    639   finish_test