/ Check-in [f68c6c4d]
Login

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

Overview
Comment:Remove some code from resolve.c that was only required for recursive cte references in sub-queries. Also a stray "finish_test" command in pagerfault.test.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | common-table-expr
Files: files | file ages | folders
SHA1:f68c6c4d36481526a9348244adc571ea282dc9eb
User & Date: dan 2014-01-17 11:48:24
Context
2014-01-17
14:59
Fix some problems to do with WITH clauses and name resolution. Closed-Leaf check-in: 6a549187 user: dan tags: common-table-expr
11:48
Remove some code from resolve.c that was only required for recursive cte references in sub-queries. Also a stray "finish_test" command in pagerfault.test. check-in: f68c6c4d user: dan tags: common-table-expr
2014-01-16
22:40
Add the ability for the authorizer callback to disallow recursive queries. check-in: 9efc120a user: drh tags: common-table-expr
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/resolve.c.

498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
  pExpr->op = (isTrigger ? TK_TRIGGER : TK_COLUMN);
lookupname_end:
  if( cnt==1 ){
    assert( pNC!=0 );
    if( pExpr->op!=TK_AS ){
      sqlite3AuthRead(pParse, pExpr, pSchema, pNC->pSrcList);
    }

#ifndef SQLITE_OMIT_CTE
    /* If this expression reads a column value from a recursive CTE 
    ** reference, then this is equivalent to reading from the outermost
    ** available name-context.  */
    if( pMatch && pMatch->isRecursive ){
      while( pNC->pNext ) pNC = pNC->pNext;
    }
#endif

    /* Increment the nRef value on all name contexts from TopNC up to
    ** the point where the name matched. */
    for(;;){
      assert( pTopNC!=0 );
      pTopNC->nRef++;
      if( pTopNC==pNC ) break;
      pTopNC = pTopNC->pNext;







<
<
<
<
<
<
<
<
<
<







498
499
500
501
502
503
504










505
506
507
508
509
510
511
  pExpr->op = (isTrigger ? TK_TRIGGER : TK_COLUMN);
lookupname_end:
  if( cnt==1 ){
    assert( pNC!=0 );
    if( pExpr->op!=TK_AS ){
      sqlite3AuthRead(pParse, pExpr, pSchema, pNC->pSrcList);
    }










    /* Increment the nRef value on all name contexts from TopNC up to
    ** the point where the name matched. */
    for(;;){
      assert( pTopNC!=0 );
      pTopNC->nRef++;
      if( pTopNC==pNC ) break;
      pTopNC = pTopNC->pNext;

Changes to src/select.c.

1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815










1816
1817
1818
1819
1820
1821
1822
....
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
        " do not have the same number of result columns", selectOpName(p->op));
    }
    rc = 1;
    goto multi_select_end;
  }

#ifndef SQLITE_OMIT_CTE
  /* If this is a recursive query, check that there is no ORDER BY or
  ** LIMIT clause. Neither of these are supported.  */
  assert( p->pOffset==0 || p->pLimit );
  if( (p->selFlags & SF_Recursive) && (p->pOrderBy || p->pLimit) ){
    sqlite3ErrorMsg(pParse, "%s in a recursive query is not allowed",
        p->pOrderBy ? "ORDER BY" : "LIMIT"
    );
    goto multi_select_end;
  }

  if( p->selFlags & SF_Recursive ){
    SrcList *pSrc = p->pSrc;
    int nCol = p->pEList->nExpr;
    int addrNext;
    int addrSwap;
    int iCont, iBreak;
    int tmp1;                     /* Intermediate table */
    int tmp2;                     /* Next intermediate table */
    int tmp3 = 0;                 /* To ensure unique results if UNION */
    int eDest = SRT_Table;
    SelectDest tmp2dest;
    int i;











    if( sqlite3AuthCheck(pParse, SQLITE_RECURSIVE, 0, 0, 0) ){
      goto multi_select_end;
    }
    iBreak = sqlite3VdbeMakeLabel(v);
    iCont = sqlite3VdbeMakeLabel(v);

................................................................................
      sqlite3ErrorMsg(pParse, pCte->zErr, pCte->zName);
      return WRC_Abort;
    }

    pFrom->pTab = pTab = sqlite3DbMallocZero(db, sizeof(Table));
    if( pTab==0 ) return WRC_Abort;
    pTab->nRef = 1;
    pTab->zName = sqlite3MPrintf(db, "%s", pCte->zName);
    pTab->iPKey = -1;
    pTab->nRowEst = 1048576;
    pTab->tabFlags |= TF_Ephemeral;
    pFrom->pSelect = sqlite3SelectDup(db, pCte->pSelect, 0);
    if( db->mallocFailed ) return SQLITE_NOMEM;
    assert( pFrom->pSelect );








<
<
<
<
<
<
<
<
<
<












>
>
>
>
>
>
>
>
>
>







 







|







1787
1788
1789
1790
1791
1792
1793










1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
....
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
        " do not have the same number of result columns", selectOpName(p->op));
    }
    rc = 1;
    goto multi_select_end;
  }

#ifndef SQLITE_OMIT_CTE










  if( p->selFlags & SF_Recursive ){
    SrcList *pSrc = p->pSrc;
    int nCol = p->pEList->nExpr;
    int addrNext;
    int addrSwap;
    int iCont, iBreak;
    int tmp1;                     /* Intermediate table */
    int tmp2;                     /* Next intermediate table */
    int tmp3 = 0;                 /* To ensure unique results if UNION */
    int eDest = SRT_Table;
    SelectDest tmp2dest;
    int i;

    /* Check that there is no ORDER BY or LIMIT clause. Neither of these 
    ** are supported on recursive queries.  */
    assert( p->pOffset==0 || p->pLimit );
    if( p->pOrderBy || p->pLimit ){
      sqlite3ErrorMsg(pParse, "%s in a recursive query is not allowed",
          p->pOrderBy ? "ORDER BY" : "LIMIT"
      );
      goto multi_select_end;
    }

    if( sqlite3AuthCheck(pParse, SQLITE_RECURSIVE, 0, 0, 0) ){
      goto multi_select_end;
    }
    iBreak = sqlite3VdbeMakeLabel(v);
    iCont = sqlite3VdbeMakeLabel(v);

................................................................................
      sqlite3ErrorMsg(pParse, pCte->zErr, pCte->zName);
      return WRC_Abort;
    }

    pFrom->pTab = pTab = sqlite3DbMallocZero(db, sizeof(Table));
    if( pTab==0 ) return WRC_Abort;
    pTab->nRef = 1;
    pTab->zName = sqlite3DbStrDup(db, pCte->zName);
    pTab->iPKey = -1;
    pTab->nRowEst = 1048576;
    pTab->tabFlags |= TF_Ephemeral;
    pFrom->pSelect = sqlite3SelectDup(db, pCte->pSelect, 0);
    if( db->mallocFailed ) return SQLITE_NOMEM;
    assert( pFrom->pSelect );

Changes to test/pagerfault.test.

59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
} -test {
  faultsim_test_result {0 4} 
  faultsim_integrity_check
  if {[db one { SELECT count(*) FROM t1 }] != 4} {
    error "Database content appears incorrect"
  }
}
finish_test

#-------------------------------------------------------------------------
# Test fault-injection while rolling back a hot-journal file with a 
# page-size different from the current value stored on page 1 of the
# database file.
#
do_test pagerfault-2-pre1 {







<







59
60
61
62
63
64
65

66
67
68
69
70
71
72
} -test {
  faultsim_test_result {0 4} 
  faultsim_integrity_check
  if {[db one { SELECT count(*) FROM t1 }] != 4} {
    error "Database content appears incorrect"
  }
}


#-------------------------------------------------------------------------
# Test fault-injection while rolling back a hot-journal file with a 
# page-size different from the current value stored on page 1 of the
# database file.
#
do_test pagerfault-2-pre1 {