/ Check-in [8658574e]
Login

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

Overview
Comment:Avoid an excess register allocation in UPDATE, when possible. This improves speed (slightly) and reduces the code footprint.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 8658574e3f435f03a87c04f398bd05078ebc53ecb4a477d3b24902d701d935c4
User & Date: drh 2019-05-08 19:06:59
Context
2019-05-08
19:32
Simplification to the logic underlying PRAGMA case_sensitive_like. check-in: ef0015fd user: drh tags: trunk
19:06
Avoid an excess register allocation in UPDATE, when possible. This improves speed (slightly) and reduces the code footprint. check-in: 8658574e user: drh tags: trunk
18:49
Add tests to improve code coverage of the RBU module. check-in: ecb56b75 user: dan tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/update.c.

   151    151     Table *pTab;           /* The table to be updated */
   152    152     int addrTop = 0;       /* VDBE instruction address of the start of the loop */
   153    153     WhereInfo *pWInfo;     /* Information about the WHERE clause */
   154    154     Vdbe *v;               /* The virtual database engine */
   155    155     Index *pIdx;           /* For looping over indices */
   156    156     Index *pPk;            /* The PRIMARY KEY index for WITHOUT ROWID tables */
   157    157     int nIdx;              /* Number of indices that need updating */
          158  +  int nAllIdx;           /* Total number of indexes */
   158    159     int iBaseCur;          /* Base cursor number */
   159    160     int iDataCur;          /* Cursor for the canonical data btree */
   160    161     int iIdxCur;           /* Cursor for the first index */
   161    162     sqlite3 *db;           /* The database structure */
   162    163     int *aRegIdx = 0;      /* Registers for to each index and the main table */
   163    164     int *aXRef = 0;        /* aXRef[i] is the index in pChanges->a[] of the
   164    165                            ** an expression for the i-th column of the table.
................................................................................
   351    352     hasFK = sqlite3FkRequired(pParse, pTab, aXRef, chngKey);
   352    353   
   353    354     /* There is one entry in the aRegIdx[] array for each index on the table
   354    355     ** being updated.  Fill in aRegIdx[] with a register number that will hold
   355    356     ** the key for accessing each index.
   356    357     */
   357    358     if( onError==OE_Replace ) bReplace = 1;
   358         -  for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
          359  +  for(nAllIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nAllIdx++){
   359    360       int reg;
   360    361       if( chngKey || hasFK>1 || pIdx==pPk
   361    362        || indexWhereClauseMightChange(pIdx,aXRef,chngRowid)
   362    363       ){
   363    364         reg = ++pParse->nMem;
   364    365         pParse->nMem += pIdx->nColumn;
   365    366       }else{
................................................................................
   371    372             if( onError==OE_Default && pIdx->onError==OE_Replace ){
   372    373               bReplace = 1;
   373    374             }
   374    375             break;
   375    376           }
   376    377         }
   377    378       }
   378         -    if( reg==0 ) aToOpen[j+1] = 0;
   379         -    aRegIdx[j] = reg;
          379  +    if( reg==0 ) aToOpen[nAllIdx+1] = 0;
          380  +    aRegIdx[nAllIdx] = reg;
   380    381     }
   381         -  aRegIdx[j] = ++pParse->nMem;  /* Register storing the table record */
          382  +  aRegIdx[nAllIdx] = ++pParse->nMem;  /* Register storing the table record */
   382    383     if( bReplace ){
   383    384       /* If REPLACE conflict resolution might be invoked, open cursors on all 
   384    385       ** indexes in case they are needed to delete records.  */
   385    386       memset(aToOpen, 1, nIdx+1);
   386    387     }
   387    388   
   388    389     /* Begin generating code. */
................................................................................
   389    390     v = sqlite3GetVdbe(pParse);
   390    391     if( v==0 ) goto update_cleanup;
   391    392     if( pParse->nested==0 ) sqlite3VdbeCountChanges(v);
   392    393     sqlite3BeginWriteOperation(pParse, pTrigger || hasFK, iDb);
   393    394   
   394    395     /* Allocate required registers. */
   395    396     if( !IsVirtual(pTab) ){
   396         -    regRowSet = ++pParse->nMem;
          397  +    /* For now, regRowSet and aRegIdx[nAllIdx] share the same register.
          398  +    ** If regRowSet turns out to be needed, then aRegIdx[nAllIdx] will be
          399  +    ** reallocated.  aRegIdx[nAllIdx] is the register in which the main
          400  +    ** table record is written.  regRowSet holds the RowSet for the
          401  +    ** two-pass update algorithm. */
          402  +    assert( aRegIdx[nAllIdx]==pParse->nMem );
          403  +    regRowSet = aRegIdx[nAllIdx];
   397    404       regOldRowid = regNewRowid = ++pParse->nMem;
   398    405       if( chngPk || pTrigger || hasFK ){
   399    406         regOld = pParse->nMem + 1;
   400    407         pParse->nMem += pTab->nCol;
   401    408       }
   402    409       if( chngKey || pTrigger || hasFK ){
   403    410         regNewRowid = ++pParse->nMem;
................................................................................
   519    526   
   520    527     if( HasRowid(pTab) ){
   521    528       /* Read the rowid of the current row of the WHERE scan. In ONEPASS_OFF
   522    529       ** mode, write the rowid into the FIFO. In either of the one-pass modes,
   523    530       ** leave it in register regOldRowid.  */
   524    531       sqlite3VdbeAddOp2(v, OP_Rowid, iDataCur, regOldRowid);
   525    532       if( eOnePass==ONEPASS_OFF ){
          533  +      /* We need to use regRowSet, so reallocate aRegIdx[nAllIdx] */
          534  +      aRegIdx[nAllIdx] = ++pParse->nMem;
   526    535         sqlite3VdbeAddOp2(v, OP_RowSetAdd, regRowSet, regOldRowid);
   527    536       }
   528    537     }else{
   529    538       /* Read the PK of the current row into an array of registers. In
   530    539       ** ONEPASS_OFF mode, serialize the array into a record and store it in
   531    540       ** the ephemeral table. Or, in ONEPASS_SINGLE or MULTI mode, change
   532    541       ** the OP_OpenEphemeral instruction to a Noop (the ephemeral table