/ Check-in [c3774c6a]
Login

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

Overview
Comment:Remove the internal sqlite3CodeOnce() interface, replacing it with a direct call to sqlite3VdbeAddOp0(v,OP_Once). Slightly smaller and faster.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: c3774c6a5fe48af91fda28e9e18c6ed9053ea992
User & Date: drh 2016-09-22 18:53:13
Context
2016-09-22
21:37
Fix a potential null-pointer dereference and crash in the case where one thread is calling sqlite3_column_text() and another thread is calling sqlite3_step() on the same prepared statement at the same instant. check-in: ee1382a3 user: drh tags: trunk
18:53
Remove the internal sqlite3CodeOnce() interface, replacing it with a direct call to sqlite3VdbeAddOp0(v,OP_Once). Slightly smaller and faster. check-in: c3774c6a user: drh tags: trunk
18:46
Makefile changes to support building winsqlite3.dll using STDCALL rather than CDECL. check-in: 5e892d60 user: mistachkin tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/delete.c.

   469    469       ** deleting from and all its indices. If this is a view, then the
   470    470       ** only effect this statement has is to fire the INSTEAD OF 
   471    471       ** triggers.
   472    472       */
   473    473       if( !isView ){
   474    474         int iAddrOnce = 0;
   475    475         if( eOnePass==ONEPASS_MULTI ){
   476         -        iAddrOnce = sqlite3CodeOnce(pParse); VdbeCoverage(v);
          476  +        iAddrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
   477    477         }
   478    478         testcase( IsVirtual(pTab) );
   479    479         sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, OPFLAG_FORDELETE,
   480    480                                    iTabCur, aToOpen, &iDataCur, &iIdxCur);
   481    481         assert( pPk || IsVirtual(pTab) || iDataCur==iTabCur );
   482    482         assert( pPk || IsVirtual(pTab) || iIdxCur==iDataCur+1 );
   483    483         if( eOnePass==ONEPASS_MULTI ) sqlite3VdbeJumpHere(v, iAddrOnce);

Changes to src/expr.c.

  1964   1964       if( pRes->op!=TK_COLUMN ) return 0;
  1965   1965       assert( pRes->iTable==pSrc->a[0].iCursor );  /* Not a correlated subquery */
  1966   1966     }
  1967   1967     return p;
  1968   1968   }
  1969   1969   #endif /* SQLITE_OMIT_SUBQUERY */
  1970   1970   
  1971         -/*
  1972         -** Code an OP_Once instruction and allocate space for its flag. Return the 
  1973         -** address of the new instruction.
  1974         -*/
  1975         -int sqlite3CodeOnce(Parse *pParse){
  1976         -  Vdbe *v = sqlite3GetVdbe(pParse);      /* Virtual machine being coded */
  1977         -  return sqlite3VdbeAddOp0(v, OP_Once);
  1978         -}
  1979         -
  1980   1971   #ifndef SQLITE_OMIT_SUBQUERY
  1981   1972   /*
  1982   1973   ** Generate code that checks the left-most column of index table iCur to see if
  1983   1974   ** it contains any NULL entries.  Cause the register at regHasNull to be set
  1984   1975   ** to a non-NULL value if iCur contains no NULLs.  Cause register regHasNull
  1985   1976   ** to be set to NULL if iCur contains one or more NULL values.
  1986   1977   */
................................................................................
  2146   2137       iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
  2147   2138       sqlite3CodeVerifySchema(pParse, iDb);
  2148   2139       sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
  2149   2140   
  2150   2141       assert(v);  /* sqlite3GetVdbe() has always been previously called */
  2151   2142       if( nExpr==1 && pEList->a[0].pExpr->iColumn<0 ){
  2152   2143         /* The "x IN (SELECT rowid FROM table)" case */
  2153         -      int iAddr = sqlite3CodeOnce(pParse);
         2144  +      int iAddr = sqlite3VdbeAddOp0(v, OP_Once);
  2154   2145         VdbeCoverage(v);
  2155   2146   
  2156   2147         sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead);
  2157   2148         eType = IN_INDEX_ROWID;
  2158   2149   
  2159   2150         sqlite3VdbeJumpHere(v, iAddr);
  2160   2151       }else{
................................................................................
  2229   2220               colUsed |= mCol;
  2230   2221               if( aiMap ) aiMap[i] = j;
  2231   2222             }
  2232   2223     
  2233   2224             assert( i==nExpr || colUsed!=(MASKBIT(nExpr)-1) );
  2234   2225             if( colUsed==(MASKBIT(nExpr)-1) ){
  2235   2226               /* If we reach this point, that means the index pIdx is usable */
  2236         -            int iAddr = sqlite3CodeOnce(pParse); VdbeCoverage(v);
         2227  +            int iAddr = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
  2237   2228   #ifndef SQLITE_OMIT_EXPLAIN
  2238   2229               sqlite3VdbeAddOp4(v, OP_Explain, 0, 0, 0,
  2239   2230                 sqlite3MPrintf(db, "USING INDEX %s FOR IN-OPERATOR",pIdx->zName),
  2240   2231                 P4_DYNAMIC);
  2241   2232   #endif
  2242   2233               sqlite3VdbeAddOp3(v, OP_OpenRead, iTab, pIdx->tnum, iDb);
  2243   2234               sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
................................................................................
  2404   2395     **    *  The right-hand side is an expression list containing variables
  2405   2396     **    *  We are inside a trigger
  2406   2397     **
  2407   2398     ** If all of the above are false, then we can run this code just once
  2408   2399     ** save the results, and reuse the same result on subsequent invocations.
  2409   2400     */
  2410   2401     if( !ExprHasProperty(pExpr, EP_VarSelect) ){
  2411         -    jmpIfDynamic = sqlite3CodeOnce(pParse); VdbeCoverage(v);
         2402  +    jmpIfDynamic = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
  2412   2403     }
  2413   2404   
  2414   2405   #ifndef SQLITE_OMIT_EXPLAIN
  2415   2406     if( pParse->explain==2 ){
  2416   2407       char *zMsg = sqlite3MPrintf(pParse->db, "EXECUTE %s%s SUBQUERY %d",
  2417   2408           jmpIfDynamic>=0?"":"CORRELATED ",
  2418   2409           pExpr->op==TK_IN?"LIST":"SCALAR",

Changes to src/select.c.

  1228   1228       nSortData = nColumn;
  1229   1229     }
  1230   1230     nKey = pOrderBy->nExpr - pSort->nOBSat;
  1231   1231     if( pSort->sortFlags & SORTFLAG_UseSorter ){
  1232   1232       int regSortOut = ++pParse->nMem;
  1233   1233       iSortTab = pParse->nTab++;
  1234   1234       if( pSort->labelBkOut ){
  1235         -      addrOnce = sqlite3CodeOnce(pParse); VdbeCoverage(v);
         1235  +      addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
  1236   1236       }
  1237   1237       sqlite3VdbeAddOp3(v, OP_OpenPseudo, iSortTab, regSortOut, nKey+1+nSortData);
  1238   1238       if( addrOnce ) sqlite3VdbeJumpHere(v, addrOnce);
  1239   1239       addr = 1 + sqlite3VdbeAddOp2(v, OP_SorterSort, iTab, addrBreak);
  1240   1240       VdbeCoverage(v);
  1241   1241       codeOffset(v, p->iOffset, addrContinue);
  1242   1242       sqlite3VdbeAddOp3(v, OP_SorterData, iTab, regSortOut, iSortTab);
................................................................................
  5023   5023         pItem->regReturn = ++pParse->nMem;
  5024   5024         topAddr = sqlite3VdbeAddOp2(v, OP_Integer, 0, pItem->regReturn);
  5025   5025         pItem->addrFillSub = topAddr+1;
  5026   5026         if( pItem->fg.isCorrelated==0 ){
  5027   5027           /* If the subquery is not correlated and if we are not inside of
  5028   5028           ** a trigger, then we only need to compute the value of the subquery
  5029   5029           ** once. */
  5030         -        onceAddr = sqlite3CodeOnce(pParse); VdbeCoverage(v);
         5030  +        onceAddr = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
  5031   5031           VdbeComment((v, "materialize \"%s\"", pItem->pTab->zName));
  5032   5032         }else{
  5033   5033           VdbeNoopComment((v, "materialize \"%s\"", pItem->pTab->zName));
  5034   5034         }
  5035   5035         sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor);
  5036   5036         explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId);
  5037   5037         sqlite3Select(pParse, pSub, &dest);

Changes to src/sqliteInt.h.

  3579   3579   void sqlite3AddCheckConstraint(Parse*, Expr*);
  3580   3580   void sqlite3AddDefaultValue(Parse*,ExprSpan*);
  3581   3581   void sqlite3AddCollateType(Parse*, Token*);
  3582   3582   void sqlite3EndTable(Parse*,Token*,Token*,u8,Select*);
  3583   3583   int sqlite3ParseUri(const char*,const char*,unsigned int*,
  3584   3584                       sqlite3_vfs**,char**,char **);
  3585   3585   Btree *sqlite3DbNameToBtree(sqlite3*,const char*);
  3586         -int sqlite3CodeOnce(Parse *);
  3587   3586   
  3588   3587   #ifdef SQLITE_OMIT_BUILTIN_TEST
  3589   3588   # define sqlite3FaultSim(X) SQLITE_OK
  3590   3589   #else
  3591   3590     int sqlite3FaultSim(int);
  3592   3591   #endif
  3593   3592   

Changes to src/where.c.

   647    647     int addrCounter = 0;        /* Address where integer counter is initialized */
   648    648     int regBase;                /* Array of registers where record is assembled */
   649    649   
   650    650     /* Generate code to skip over the creation and initialization of the
   651    651     ** transient index on 2nd and subsequent iterations of the loop. */
   652    652     v = pParse->pVdbe;
   653    653     assert( v!=0 );
   654         -  addrInit = sqlite3CodeOnce(pParse); VdbeCoverage(v);
          654  +  addrInit = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
   655    655   
   656    656     /* Count the number of columns that will be added to the index
   657    657     ** and used to match WHERE clause constraints */
   658    658     nKeyCol = 0;
   659    659     pTable = pSrc->pTab;
   660    660     pWCEnd = &pWC->a[pWC->nTerm];
   661    661     pLoop = pLevel->pWLoop;