/ Check-in [72be33f9]
Login

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

Overview
Comment:Omit some extra code from non-SQLITE_ENABLE_UPDATE_DELETE_LIMIT builds.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | update-delete-limit-fix
Files: files | file ages | folders
SHA3-256: 72be33f9c84de3ec4afc40549482417456ca82c1d16b473dc034b144055271e5
User & Date: dan 2017-11-10 20:13:14
Context
2017-11-14
17:06
Fix the SQLITE_ENABLE_UPDATE_DELETE_LIMIT functionality so that it works with views and WITHOUT ROWID tables. check-in: dae4a97a user: dan tags: trunk
2017-11-10
20:13
Omit some extra code from non-SQLITE_ENABLE_UPDATE_DELETE_LIMIT builds. Closed-Leaf check-in: 72be33f9 user: dan tags: update-delete-limit-fix
17:47
Add further tests for the code on this branch. check-in: f8c4e33f user: dan tags: update-delete-limit-fix
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/delete.c.

   220    220   /*
   221    221   ** Generate code for a DELETE FROM statement.
   222    222   **
   223    223   **     DELETE FROM table_wxyz WHERE a<5 AND b NOT NULL;
   224    224   **                 \________/       \________________/
   225    225   **                  pTabList              pWhere
   226    226   */
   227         -void sqlite3DeleteFromLimit(
          227  +void sqlite3DeleteFrom(
   228    228     Parse *pParse,         /* The parser context */
   229    229     SrcList *pTabList,     /* The table from which we should delete things */
   230    230     Expr *pWhere,          /* The WHERE clause.  May be null */
   231         -  ExprList *pOrderBy,
   232         -  Expr *pLimit,
   233         -  Expr *pOffset
          231  +  ExprList *pOrderBy,    /* ORDER BY clause. May be null */
          232  +  Expr *pLimit,          /* LIMIT clause. May be null */
          233  +  Expr *pOffset          /* OFFSET clause. May be null */
   234    234   ){
   235    235     Vdbe *v;               /* The virtual database engine */
   236    236     Table *pTab;           /* The table from which records will be deleted */
   237    237     int i;                 /* Loop counter */
   238    238     WhereInfo *pWInfo;     /* Information about the WHERE clause */
   239    239     Index *pIdx;           /* For looping over indices of the table */
   240    240     int iTabCur;           /* Cursor number for the table */
................................................................................
   602    602       sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows deleted", SQLITE_STATIC);
   603    603     }
   604    604   
   605    605   delete_from_cleanup:
   606    606     sqlite3AuthContextPop(&sContext);
   607    607     sqlite3SrcListDelete(db, pTabList);
   608    608     sqlite3ExprDelete(db, pWhere);
          609  +#if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) 
   609    610     sqlite3ExprListDelete(db, pOrderBy);
   610    611     sqlite3ExprDelete(db, pLimit);
   611    612     sqlite3ExprDelete(db, pOffset);
          613  +#endif
   612    614     sqlite3DbFree(db, aToOpen);
   613    615     return;
   614    616   }
   615    617   /* Make sure "isView" and other macros defined above are undefined. Otherwise
   616    618   ** they may interfere with compilation of other functions in this file
   617    619   ** (or in another file, if this file becomes part of the amalgamation).  */
   618    620   #ifdef isView

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);
          728  +    sqlite3DeleteFrom(pParse, sqlite3SrcListDup(db, pName, 0), 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       **

Changes to src/parse.y.

   749    749   /////////////////////////// The DELETE statement /////////////////////////////
   750    750   //
   751    751   %ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT
   752    752   cmd ::= with(C) DELETE FROM fullname(X) indexed_opt(I) where_opt(W) 
   753    753           orderby_opt(O) limit_opt(L). {
   754    754     sqlite3WithPush(pParse, C, 1);
   755    755     sqlite3SrcListIndexedBy(pParse, X, &I);
   756         -  sqlite3DeleteFromLimit(pParse,X,W,O,L.pLimit,L.pOffset); 
          756  +  sqlite3DeleteFrom(pParse,X,W,O,L.pLimit,L.pOffset); 
   757    757   }
   758    758   %endif
   759    759   %ifndef SQLITE_ENABLE_UPDATE_DELETE_LIMIT
   760    760   cmd ::= with(C) DELETE FROM fullname(X) indexed_opt(I) where_opt(W). {
   761    761     sqlite3WithPush(pParse, C, 1);
   762    762     sqlite3SrcListIndexedBy(pParse, X, &I);
   763         -  sqlite3DeleteFrom(pParse,X,W);
          763  +  sqlite3DeleteFrom(pParse,X,W,0,0,0);
   764    764   }
   765    765   %endif
   766    766   
   767    767   %type where_opt {Expr*}
   768    768   %destructor where_opt {sqlite3ExprDelete(pParse->db, $$);}
   769    769   
   770    770   where_opt(A) ::= .                    {A = 0;}
................................................................................
   774    774   //
   775    775   %ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT
   776    776   cmd ::= with(C) UPDATE orconf(R) fullname(X) indexed_opt(I) SET setlist(Y)
   777    777           where_opt(W) orderby_opt(O) limit_opt(L).  {
   778    778     sqlite3WithPush(pParse, C, 1);
   779    779     sqlite3SrcListIndexedBy(pParse, X, &I);
   780    780     sqlite3ExprListCheckLength(pParse,Y,"set list"); 
   781         -  sqlite3UpdateLimit(pParse,X,Y,W,R,O,L.pLimit,L.pOffset);
          781  +  sqlite3Update(pParse,X,Y,W,R,O,L.pLimit,L.pOffset);
   782    782   }
   783    783   %endif
   784    784   %ifndef SQLITE_ENABLE_UPDATE_DELETE_LIMIT
   785    785   cmd ::= with(C) UPDATE orconf(R) fullname(X) indexed_opt(I) SET setlist(Y)
   786    786           where_opt(W).  {
   787    787     sqlite3WithPush(pParse, C, 1);
   788    788     sqlite3SrcListIndexedBy(pParse, X, &I);
   789    789     sqlite3ExprListCheckLength(pParse,Y,"set list"); 
   790         -  sqlite3Update(pParse,X,Y,W,R);
          790  +  sqlite3Update(pParse,X,Y,W,R,0,0,0);
   791    791   }
   792    792   %endif
   793    793   
   794    794   %type setlist {ExprList*}
   795    795   %destructor setlist {sqlite3ExprListDelete(pParse->db, $$);}
   796    796   
   797    797   setlist(A) ::= setlist(A) COMMA nm(X) EQ expr(Y). {

Changes to src/resolve.c.

   593    593       ** clause processing on UPDATE and DELETE statements.
   594    594       */
   595    595       case TK_ROW: {
   596    596         SrcList *pSrcList = pNC->pSrcList;
   597    597         struct SrcList_item *pItem;
   598    598         assert( pSrcList && pSrcList->nSrc==1 );
   599    599         pItem = pSrcList->a;
   600         -      if( !HasRowid(pItem->pTab) || pItem->pTab->pSelect!=0 ){
   601         -         sqlite3ErrorMsg(pParse, "ORDER BY and LIMIT not support for table %s",
   602         -                                 pItem->pTab->zName);
   603         -      }
          600  +      assert( HasRowid(pItem->pTab) && pItem->pTab->pSelect==0 );
   604    601         pExpr->op = TK_COLUMN;
   605    602         pExpr->pTab = pItem->pTab;
   606    603         pExpr->iTable = pItem->iCursor;
   607    604         pExpr->iColumn = -1;
   608    605         pExpr->affinity = SQLITE_AFF_INTEGER;
   609    606         break;
   610    607       }

Changes to src/sqliteInt.h.

  3760   3760   void sqlite3SelectDelete(sqlite3*, Select*);
  3761   3761   Table *sqlite3SrcListLookup(Parse*, SrcList*);
  3762   3762   int sqlite3IsReadOnly(Parse*, Table*, int);
  3763   3763   void sqlite3OpenTable(Parse*, int iCur, int iDb, Table*, int);
  3764   3764   #if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY)
  3765   3765   Expr *sqlite3LimitWhere(Parse*,SrcList*,Expr*,ExprList*,Expr*,Expr*,char*);
  3766   3766   #endif
  3767         -void sqlite3DeleteFromLimit(Parse*, SrcList*, Expr*, ExprList*, Expr*, Expr*);
  3768         -#define sqlite3DeleteFrom(x,y,z) sqlite3DeleteFromLimit(x,y,z,0,0,0)
  3769         -void sqlite3UpdateLimit(Parse*, SrcList*, ExprList*, Expr*, int,
  3770         -                        ExprList*,Expr*,Expr*);
  3771         -#define sqlite3Update(v,w,x,y,z) sqlite3UpdateLimit(v,w,x,y,z,0,0,0)
         3767  +void sqlite3DeleteFrom(Parse*, SrcList*, Expr*, ExprList*, Expr*, Expr*);
         3768  +void sqlite3Update(Parse*, SrcList*, ExprList*,Expr*,int,ExprList*,Expr*,Expr*);
  3772   3769   WhereInfo *sqlite3WhereBegin(Parse*,SrcList*,Expr*,ExprList*,ExprList*,u16,int);
  3773   3770   void sqlite3WhereEnd(WhereInfo*);
  3774   3771   LogEst sqlite3WhereOutputRowCount(WhereInfo*);
  3775   3772   int sqlite3WhereIsDistinct(WhereInfo*);
  3776   3773   int sqlite3WhereIsOrdered(WhereInfo*);
  3777   3774   int sqlite3WhereOrderedInnerLoop(WhereInfo*);
  3778   3775   int sqlite3WhereIsSorted(WhereInfo*);

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
          714  +          pParse->eOrconf, 0, 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)
          730  +          sqlite3ExprDup(db, pStep->pWhere, 0), 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.

    82     82   /*
    83     83   ** Process an UPDATE statement.
    84     84   **
    85     85   **   UPDATE OR IGNORE table_wxyz SET a=b, c=d WHERE e<5 AND f NOT NULL;
    86     86   **          \_______/ \________/     \______/       \________________/
    87     87   *            onError   pTabList      pChanges             pWhere
    88     88   */
    89         -void sqlite3UpdateLimit(
           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         -  ExprList *pOrderBy,
    96         -  Expr *pLimit,
    97         -  Expr *pOffset
           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 */
    98     98   ){
    99     99     int i, j;              /* Loop counters */
   100    100     Table *pTab;           /* The table to be updated */
   101    101     int addrTop = 0;       /* VDBE instruction address of the start of the loop */
   102    102     WhereInfo *pWInfo;     /* Information about the WHERE clause */
   103    103     Vdbe *v;               /* The virtual database engine */
   104    104     Index *pIdx;           /* For looping over indices */
................................................................................
   741    741   
   742    742   update_cleanup:
   743    743     sqlite3AuthContextPop(&sContext);
   744    744     sqlite3DbFree(db, aXRef); /* Also frees aRegIdx[] and aToOpen[] */
   745    745     sqlite3SrcListDelete(db, pTabList);
   746    746     sqlite3ExprListDelete(db, pChanges);
   747    747     sqlite3ExprDelete(db, pWhere);
          748  +#if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) 
   748    749     sqlite3ExprListDelete(db, pOrderBy);
   749    750     sqlite3ExprDelete(db, pLimit);
   750    751     sqlite3ExprDelete(db, pOffset);
          752  +#endif
   751    753     return;
   752    754   }
   753    755   /* Make sure "isView" and other macros defined above are undefined. Otherwise
   754    756   ** they may interfere with compilation of other functions in this file
   755    757   ** (or in another file, if this file becomes part of the amalgamation).  */
   756    758   #ifdef isView
   757    759    #undef isView