/ Check-in [36bcc9cb]
Login

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

Overview
Comment:Report an error when trying to resolve column name "rowid" in a WITHOUT ROWID table.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | omit-rowid
Files: files | file ages | folders
SHA1: 36bcc9cb885523fba2f3b0d152de9e08073668c1
User & Date: drh 2013-10-23 17:39:41
Context
2013-10-23
22:23
Construct secondary indices on WITHOUT ROWID tables. check-in: 2c028ddc user: drh tags: omit-rowid
17:39
Report an error when trying to resolve column name "rowid" in a WITHOUT ROWID table. check-in: 36bcc9cb user: drh tags: omit-rowid
16:03
Get VACUUM and the xfer optimization working with WITHOUT ROWID. check-in: 579815ff user: drh tags: omit-rowid
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/resolve.c.

   222    222     int cntTab = 0;                   /* Number of matching table names */
   223    223     int nSubquery = 0;                /* How many levels of subquery */
   224    224     sqlite3 *db = pParse->db;         /* The database connection */
   225    225     struct SrcList_item *pItem;       /* Use for looping over pSrcList items */
   226    226     struct SrcList_item *pMatch = 0;  /* The matching pSrcList item */
   227    227     NameContext *pTopNC = pNC;        /* First namecontext in the list */
   228    228     Schema *pSchema = 0;              /* Schema of the expression */
   229         -  int isTrigger = 0;
          229  +  int isTrigger = 0;                /* True if resolved to a trigger column */
          230  +  Table *pTab = 0;                  /* Table hold the row */
          231  +  Column *pCol;                     /* A column of pTab */
   230    232   
   231    233     assert( pNC );     /* the name context cannot be NULL. */
   232    234     assert( zCol );    /* The Z in X.Y.Z cannot be NULL */
   233    235     assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) );
   234    236   
   235    237     /* Initialize the node to no-match */
   236    238     pExpr->iTable = -1;
................................................................................
   263    265     /* Start at the inner-most context and move outward until a match is found */
   264    266     while( pNC && cnt==0 ){
   265    267       ExprList *pEList;
   266    268       SrcList *pSrcList = pNC->pSrcList;
   267    269   
   268    270       if( pSrcList ){
   269    271         for(i=0, pItem=pSrcList->a; i<pSrcList->nSrc; i++, pItem++){
   270         -        Table *pTab;
   271         -        Column *pCol;
   272         -  
   273    272           pTab = pItem->pTab;
   274    273           assert( pTab!=0 && pTab->zName!=0 );
   275    274           assert( pTab->nCol>0 );
   276    275           if( pItem->pSelect && (pItem->pSelect->selFlags & SF_NestedFrom)!=0 ){
   277    276             int hit = 0;
   278    277             pEList = pItem->pSelect->pEList;
   279    278             for(j=0; j<pEList->nExpr; j++){
................................................................................
   325    324         }
   326    325       } /* if( pSrcList ) */
   327    326   
   328    327   #ifndef SQLITE_OMIT_TRIGGER
   329    328       /* If we have not already resolved the name, then maybe 
   330    329       ** it is a new.* or old.* trigger argument reference
   331    330       */
   332         -    if( zDb==0 && zTab!=0 && cnt==0 && pParse->pTriggerTab!=0 ){
          331  +    if( zDb==0 && zTab!=0 && cntTab==0 && pParse->pTriggerTab!=0 ){
   333    332         int op = pParse->eTriggerOp;
   334         -      Table *pTab = 0;
   335    333         assert( op==TK_DELETE || op==TK_UPDATE || op==TK_INSERT );
   336    334         if( op!=TK_DELETE && sqlite3StrICmp("new",zTab) == 0 ){
   337    335           pExpr->iTable = 1;
   338    336           pTab = pParse->pTriggerTab;
   339    337         }else if( op!=TK_INSERT && sqlite3StrICmp("old",zTab)==0 ){
   340    338           pExpr->iTable = 0;
   341    339           pTab = pParse->pTriggerTab;
................................................................................
   350    348             if( sqlite3StrICmp(pCol->zName, zCol)==0 ){
   351    349               if( iCol==pTab->iPKey ){
   352    350                 iCol = -1;
   353    351               }
   354    352               break;
   355    353             }
   356    354           }
   357         -        if( iCol>=pTab->nCol && sqlite3IsRowid(zCol) ){
          355  +        if( iCol>=pTab->nCol && sqlite3IsRowid(zCol) && HasRowid(pTab) ){
   358    356             iCol = -1;        /* IMP: R-44911-55124 */
   359    357           }
   360    358           if( iCol<pTab->nCol ){
   361    359             cnt++;
   362    360             if( iCol<0 ){
   363    361               pExpr->affinity = SQLITE_AFF_INTEGER;
   364    362             }else if( pExpr->iTable==0 ){
................................................................................
   377    375         }
   378    376       }
   379    377   #endif /* !defined(SQLITE_OMIT_TRIGGER) */
   380    378   
   381    379       /*
   382    380       ** Perhaps the name is a reference to the ROWID
   383    381       */
   384         -    if( cnt==0 && cntTab==1 && sqlite3IsRowid(zCol) ){
          382  +    assert( pTab!=0 || cntTab==0 );
          383  +    if( cnt==0 && cntTab==1 && sqlite3IsRowid(zCol) && HasRowid(pTab) ){
   385    384         cnt = 1;
   386    385         pExpr->iColumn = -1;     /* IMP: R-44911-55124 */
   387    386         pExpr->affinity = SQLITE_AFF_INTEGER;
   388    387       }
   389    388   
   390    389       /*
   391    390       ** If the input is of the form Z (not Y.Z or X.Y.Z) then the name Z

Changes to test/tableopts.test.

    29     29   } {1 {unknown table option: unknown2}}
    30     30   
    31     31   do_execsql_test tableopt-2.1 {
    32     32     CREATE TABLE t1(a, b, c, PRIMARY KEY(a,b)) WITHOUT rowid;
    33     33     INSERT INTO t1 VALUES(1,2,3),(2,3,4);
    34     34     SELECT c FROM t1 WHERE a IN (1,2) ORDER BY b;
    35     35   } {3 4}
           36  +do_test tableopt-2.1.1 {
           37  +  catchsql {
           38  +    SELECT rowid, * FROM t1;
           39  +  }
           40  +} {1 {no such column: rowid}}
           41  +do_test tableopt-2.1.2 {
           42  +  catchsql {
           43  +    SELECT _rowid_, * FROM t1;
           44  +  }
           45  +} {1 {no such column: _rowid_}}
           46  +do_test tableopt-2.1.3 {
           47  +  catchsql {
           48  +    SELECT oid, * FROM t1;
           49  +  }
           50  +} {1 {no such column: oid}}
    36     51   do_execsql_test tableopt-2.2 {
    37     52     VACUUM;
    38     53     SELECT c FROM t1 WHERE a IN (1,2) ORDER BY b;
    39     54   } {3 4}
    40     55   do_test tableopt-2.3 {
    41     56     sqlite3 db2 test.db
    42     57     db2 eval {SELECT c FROM t1 WHERE a IN (1,2) ORDER BY b;}