/ Check-in [2bd4b62a]
Login

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

Overview
Comment:Change the coding of PRAGMA count_changes so that it uses memory cells of the VM rather than the stack, to avoid problems with leftovers on the stack interfering with other operations. Ticket #2217. (CVS 3632)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:2bd4b62a20219f939ac2ac22440dc7fc0449f766
User & Date: drh 2007-02-07 01:06:53
Context
2007-02-07
13:09
Explicit collations always override implicit collations. This is backwards compatible since SQLite has not previously supported explicit collations. Need to add tests of this new behavior. (CVS 3633) check-in: 3638823a user: drh tags: trunk
01:06
Change the coding of PRAGMA count_changes so that it uses memory cells of the VM rather than the stack, to avoid problems with leftovers on the stack interfering with other operations. Ticket #2217. (CVS 3632) check-in: 2bd4b62a user: drh tags: trunk
01:01
http://www.sqlite.org/cvstrac/tktview?tn=2219

When creating fts tables in an attached database, the backing tables are created in database 'main'. This change propagates the appropriate database name to the routines which build sql statements.

Note that I propagate the database name and table name separately. I briefly considered just making the table name be "db.table", but it didn't fit so well in the model used to store the table name and other information, and having the db name passed separately seemed a bit more transparent. (CVS 3631) check-in: 283385d2 user: shess tags: trunk

Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/delete.c.

     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** This file contains C code routines that are called by the parser
    13     13   ** in order to generate code for DELETE FROM statements.
    14     14   **
    15         -** $Id: delete.c,v 1.127 2006/06/19 03:05:10 danielk1977 Exp $
           15  +** $Id: delete.c,v 1.128 2007/02/07 01:06:53 drh Exp $
    16     16   */
    17     17   #include "sqliteInt.h"
    18     18   
    19     19   /*
    20     20   ** Look up every table that is named in pSrc.  If any table is not found,
    21     21   ** add an error message to pParse->zErrMsg and return NULL.  If all tables
    22     22   ** are found, return a pointer to the last table.
................................................................................
   102    102     WhereInfo *pWInfo;     /* Information about the WHERE clause */
   103    103     Index *pIdx;           /* For looping over indices of the table */
   104    104     int iCur;              /* VDBE Cursor number for pTab */
   105    105     sqlite3 *db;           /* Main database structure */
   106    106     AuthContext sContext;  /* Authorization context */
   107    107     int oldIdx = -1;       /* Cursor for the OLD table of AFTER triggers */
   108    108     NameContext sNC;       /* Name context to resolve expressions in */
   109         -  int iDb;
          109  +  int iDb;               /* Database number */
          110  +  int memCnt = 0;        /* Memory cell used for change counting */
   110    111   
   111    112   #ifndef SQLITE_OMIT_TRIGGER
   112    113     int isView;                  /* True if attempting to delete from a view */
   113    114     int triggers_exist = 0;      /* True if any triggers exist */
   114    115   #endif
   115    116   
   116    117     sContext.pParse = 0;
................................................................................
   200    201       sqlite3SelectDelete(pView);
   201    202     }
   202    203   
   203    204     /* Initialize the counter of the number of rows deleted, if
   204    205     ** we are counting rows.
   205    206     */
   206    207     if( db->flags & SQLITE_CountRows ){
   207         -    sqlite3VdbeAddOp(v, OP_Integer, 0, 0);
          208  +    memCnt = pParse->nMem++;
          209  +    sqlite3VdbeAddOp(v, OP_MemInt, 0, memCnt);
   208    210     }
   209    211   
   210    212     /* Special case: A DELETE without a WHERE clause deletes everything.
   211    213     ** It is easier just to erase the whole table.  Note, however, that
   212    214     ** this means that the row change count will be incorrect.
   213    215     */
   214    216     if( pWhere==0 && !triggers_exist && !IsVirtual(pTab) ){
................................................................................
   217    219         ** entries in the table. */
   218    220         int endOfLoop = sqlite3VdbeMakeLabel(v);
   219    221         int addr2;
   220    222         if( !isView ){
   221    223           sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenRead);
   222    224         }
   223    225         sqlite3VdbeAddOp(v, OP_Rewind, iCur, sqlite3VdbeCurrentAddr(v)+2);
   224         -      addr2 = sqlite3VdbeAddOp(v, OP_AddImm, 1, 0);
          226  +      addr2 = sqlite3VdbeAddOp(v, OP_MemIncr, 1, memCnt);
   225    227         sqlite3VdbeAddOp(v, OP_Next, iCur, addr2);
   226    228         sqlite3VdbeResolveLabel(v, endOfLoop);
   227    229         sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
   228    230       }
   229    231       if( !isView ){
   230    232         sqlite3VdbeAddOp(v, OP_Clear, pTab->tnum, iDb);
   231    233         if( !pParse->nested ){
................................................................................
   247    249       if( pWInfo==0 ) goto delete_from_cleanup;
   248    250   
   249    251       /* Remember the rowid of every item to be deleted.
   250    252       */
   251    253       sqlite3VdbeAddOp(v, IsVirtual(pTab) ? OP_VRowid : OP_Rowid, iCur, 0);
   252    254       sqlite3VdbeAddOp(v, OP_FifoWrite, 0, 0);
   253    255       if( db->flags & SQLITE_CountRows ){
   254         -      sqlite3VdbeAddOp(v, OP_AddImm, 1, 0);
          256  +      sqlite3VdbeAddOp(v, OP_MemIncr, 1, memCnt);
   255    257       }
   256    258   
   257    259       /* End the database scan loop.
   258    260       */
   259    261       sqlite3WhereEnd(pWInfo);
   260    262   
   261    263       /* Open the pseudo-table used to store OLD if there are triggers.
................................................................................
   350    352   
   351    353     /*
   352    354     ** Return the number of rows that were deleted. If this routine is 
   353    355     ** generating code because of a call to sqlite3NestedParse(), do not
   354    356     ** invoke the callback function.
   355    357     */
   356    358     if( db->flags & SQLITE_CountRows && pParse->nested==0 && !pParse->trigStack ){
          359  +    sqlite3VdbeAddOp(v, OP_MemLoad, memCnt, 0);
   357    360       sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
   358    361       sqlite3VdbeSetNumCols(v, 1);
   359    362       sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows deleted", P3_STATIC);
   360    363     }
   361    364   
   362    365   delete_from_cleanup:
   363    366     sqlite3AuthContextPop(&sContext);

Changes to src/update.c.

     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** This file contains C code routines that are called by the parser
    13     13   ** to handle UPDATE statements.
    14     14   **
    15         -** $Id: update.c,v 1.133 2006/06/27 13:20:21 drh Exp $
           15  +** $Id: update.c,v 1.134 2007/02/07 01:06:53 drh Exp $
    16     16   */
    17     17   #include "sqliteInt.h"
    18     18   
    19     19   #ifndef SQLITE_OMIT_VIRTUALTABLE
    20     20   /* Forward declaration */
    21     21   static void updateVirtualTable(
    22     22     Parse *pParse,       /* The parsing context */
................................................................................
    99     99                            ** aXRef[i]==-1 if the i-th column is not changed. */
   100    100     int chngRowid;         /* True if the record number is being changed */
   101    101     Expr *pRowidExpr = 0;  /* Expression defining the new record number */
   102    102     int openAll = 0;       /* True if all indices need to be opened */
   103    103     AuthContext sContext;  /* The authorization context */
   104    104     NameContext sNC;       /* The name-context to resolve expressions in */
   105    105     int iDb;               /* Database containing the table being updated */
          106  +  int memCnt = 0;        /* Memory cell used for counting rows changed */
   106    107   
   107    108   #ifndef SQLITE_OMIT_TRIGGER
   108    109     int isView;                  /* Trying to update a view */
   109    110     int triggers_exist = 0;      /* True if any row triggers exist */
   110    111   #endif
   111    112   
   112    113     int newIdx      = -1;  /* index of trigger "new" temp table       */
................................................................................
   307    308     /* End the database scan loop.
   308    309     */
   309    310     sqlite3WhereEnd(pWInfo);
   310    311   
   311    312     /* Initialize the count of updated rows
   312    313     */
   313    314     if( db->flags & SQLITE_CountRows && !pParse->trigStack ){
   314         -    sqlite3VdbeAddOp(v, OP_Integer, 0, 0);
          315  +    memCnt = pParse->nMem++;
          316  +    sqlite3VdbeAddOp(v, OP_MemInt, 0, memCnt);
   315    317     }
   316    318   
   317    319     if( triggers_exist ){
   318    320       /* Create pseudo-tables for NEW and OLD
   319    321       */
   320    322       sqlite3VdbeAddOp(v, OP_OpenPseudo, oldIdx, 0);
   321    323       sqlite3VdbeAddOp(v, OP_SetNumColumns, oldIdx, pTab->nCol);
................................................................................
   465    467       */
   466    468       sqlite3CompleteInsertion(pParse, pTab, iCur, aIdxUsed, chngRowid, 1, -1);
   467    469     }
   468    470   
   469    471     /* Increment the row counter 
   470    472     */
   471    473     if( db->flags & SQLITE_CountRows && !pParse->trigStack){
   472         -    sqlite3VdbeAddOp(v, OP_AddImm, 1, 0);
          474  +    sqlite3VdbeAddOp(v, OP_MemIncr, 1, memCnt);
   473    475     }
   474    476   
   475    477     /* If there are triggers, close all the cursors after each iteration
   476    478     ** through the loop.  The fire the after triggers.
   477    479     */
   478    480     if( triggers_exist ){
   479    481       if( !isView ){
................................................................................
   510    512   
   511    513     /*
   512    514     ** Return the number of rows that were changed. If this routine is 
   513    515     ** generating code because of a call to sqlite3NestedParse(), do not
   514    516     ** invoke the callback function.
   515    517     */
   516    518     if( db->flags & SQLITE_CountRows && !pParse->trigStack && pParse->nested==0 ){
          519  +    sqlite3VdbeAddOp(v, OP_MemLoad, memCnt, 0);
   517    520       sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
   518    521       sqlite3VdbeSetNumCols(v, 1);
   519    522       sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows updated", P3_STATIC);
   520    523     }
   521    524   
   522    525   update_cleanup:
   523    526     sqlite3AuthContextPop(&sContext);