/ Check-in [6ae4ad6e]
Login

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

Overview
Comment:Remove references to deleted function sqlite3ExprRegister(). Changes to the expr.c source module to promote better testing. (CVS 6686)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 6ae4ad6ebee4db88c411df97bb1de574708dd53c
User & Date: drh 2009-05-28 21:04:38
Context
2009-05-29
00:30
Modify the hasHotJournal() routine to return a false-positive if it is unable to open the journal file to check its header due to a race condition. Processing downstream of hasHotJournal() already knows how to deal with false-positives. Ticket #3883. (CVS 6687) check-in: d6b5d8e1 user: drh tags: trunk
2009-05-28
21:04
Remove references to deleted function sqlite3ExprRegister(). Changes to the expr.c source module to promote better testing. (CVS 6686) check-in: 6ae4ad6e user: drh tags: trunk
14:34
Fix a NULL pointer dereference following an OOM error in the column name resolver. (CVS 6685) check-in: 3b461425 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/build.c.

    18     18   **     CREATE INDEX
    19     19   **     DROP INDEX
    20     20   **     creating ID lists
    21     21   **     BEGIN TRANSACTION
    22     22   **     COMMIT
    23     23   **     ROLLBACK
    24     24   **
    25         -** $Id: build.c,v 1.546 2009/05/28 01:00:55 drh Exp $
           25  +** $Id: build.c,v 1.547 2009/05/28 21:04:38 drh Exp $
    26     26   */
    27     27   #include "sqliteInt.h"
    28     28   
    29     29   /*
    30     30   ** This routine is called when a new SQL statement is beginning to
    31     31   ** be parsed.  Initialize the pParse structure as needed.
    32     32   */
................................................................................
  1876   1876   #ifndef SQLITE_OMIT_AUTOVACUUM
  1877   1877     /* OP_Destroy stores an in integer r1. If this integer
  1878   1878     ** is non-zero, then it is the root page number of a table moved to
  1879   1879     ** location iTable. The following code modifies the sqlite_master table to
  1880   1880     ** reflect this.
  1881   1881     **
  1882   1882     ** The "#NNN" in the SQL is a special constant that means whatever value
  1883         -  ** is in register NNN.  See sqlite3RegisterExpr().
         1883  +  ** is in register NNN.  See grammar rules associated with the TK_REGISTER
         1884  +  ** token for additional information.
  1884   1885     */
  1885   1886     sqlite3NestedParse(pParse, 
  1886   1887        "UPDATE %Q.%s SET rootpage=%d WHERE #%d AND rootpage=#%d",
  1887   1888        pParse->db->aDb[iDb].zName, SCHEMA_TABLE(iDb), iTable, r1, r1);
  1888   1889   #endif
  1889   1890     sqlite3ReleaseTempReg(pParse, r1);
  1890   1891   }

Changes to src/expr.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 routines used for analyzing expressions and
    13     13   ** for generating VDBE code that evaluates expressions in SQLite.
    14     14   **
    15         -** $Id: expr.c,v 1.438 2009/05/28 01:00:55 drh Exp $
           15  +** $Id: expr.c,v 1.439 2009/05/28 21:04:38 drh Exp $
    16     16   */
    17     17   #include "sqliteInt.h"
    18     18   
    19     19   /*
    20     20   ** Return the 'affinity' of the expression pExpr if any.
    21     21   **
    22     22   ** If pExpr is a column, a reference to a column via an 'AS' alias,
................................................................................
  1152   1152       case TK_FUNCTION:
  1153   1153         if( pWalker->u.i==2 ) return 0;
  1154   1154         /* Fall through */
  1155   1155       case TK_ID:
  1156   1156       case TK_COLUMN:
  1157   1157       case TK_AGG_FUNCTION:
  1158   1158       case TK_AGG_COLUMN:
  1159         -#ifndef SQLITE_OMIT_SUBQUERY
  1160         -    case TK_SELECT:
  1161         -    case TK_EXISTS:
  1162         -      testcase( pExpr->op==TK_SELECT );
  1163         -      testcase( pExpr->op==TK_EXISTS );
  1164         -#endif
  1165   1159         testcase( pExpr->op==TK_ID );
  1166   1160         testcase( pExpr->op==TK_COLUMN );
  1167   1161         testcase( pExpr->op==TK_AGG_FUNCTION );
  1168   1162         testcase( pExpr->op==TK_AGG_COLUMN );
  1169   1163         pWalker->u.i = 0;
  1170   1164         return WRC_Abort;
  1171   1165       default:
         1166  +      testcase( pExpr->op==TK_SELECT ); /* selectNodeIsConstant will disallow */
         1167  +      testcase( pExpr->op==TK_EXISTS ); /* selectNodeIsConstant will disallow */
  1172   1168         return WRC_Continue;
  1173   1169     }
  1174   1170   }
  1175   1171   static int selectNodeIsConstant(Walker *pWalker, Select *NotUsed){
  1176   1172     UNUSED_PARAMETER(NotUsed);
  1177   1173     pWalker->u.i = 0;
  1178   1174     return WRC_Abort;
................................................................................
  1270   1266     if( sqlite3StrICmp(z, "_ROWID_")==0 ) return 1;
  1271   1267     if( sqlite3StrICmp(z, "ROWID")==0 ) return 1;
  1272   1268     if( sqlite3StrICmp(z, "OID")==0 ) return 1;
  1273   1269     return 0;
  1274   1270   }
  1275   1271   
  1276   1272   /*
  1277         -** Return true if the IN operator optimization is enabled and
  1278         -** the SELECT statement p exists and is of the
  1279         -** simple form:
         1273  +** Return true if we are able to the IN operator optimization on a
         1274  +** query of the form
  1280   1275   **
  1281         -**     SELECT <column> FROM <table>
         1276  +**       x IN (SELECT ...)
  1282   1277   **
  1283         -** If this is the case, it may be possible to use an existing table
  1284         -** or index instead of generating an epheremal table.
         1278  +** Where the SELECT... clause is as specified by the parameter to this
         1279  +** routine.
         1280  +**
         1281  +** The Select object passed in has already been preprocessed and no
         1282  +** errors have been found.
  1285   1283   */
  1286   1284   #ifndef SQLITE_OMIT_SUBQUERY
  1287   1285   static int isCandidateForInOpt(Select *p){
  1288   1286     SrcList *pSrc;
  1289   1287     ExprList *pEList;
  1290   1288     Table *pTab;
  1291   1289     if( p==0 ) return 0;                   /* right-hand side of IN is SELECT */
  1292   1290     if( p->pPrior ) return 0;              /* Not a compound SELECT */
  1293   1291     if( p->selFlags & (SF_Distinct|SF_Aggregate) ){
  1294         -      return 0; /* No DISTINCT keyword and no aggregate functions */
         1292  +    testcase( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct );
         1293  +    testcase( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Aggregate );
         1294  +    return 0; /* No DISTINCT keyword and no aggregate functions */
  1295   1295     }
  1296         -  if( p->pGroupBy ) return 0;            /* Has no GROUP BY clause */
         1296  +  assert( p->pGroupBy==0 );              /* Has no GROUP BY clause */
  1297   1297     if( p->pLimit ) return 0;              /* Has no LIMIT clause */
  1298         -  if( p->pOffset ) return 0;
         1298  +  assert( p->pOffset==0 );               /* No LIMIT means no OFFSET */
  1299   1299     if( p->pWhere ) return 0;              /* Has no WHERE clause */
  1300   1300     pSrc = p->pSrc;
  1301   1301     assert( pSrc!=0 );
  1302   1302     if( pSrc->nSrc!=1 ) return 0;          /* Single term in FROM clause */
  1303         -  if( pSrc->a[0].pSelect ) return 0;     /* FROM clause is not a subquery */
         1303  +  if( pSrc->a[0].pSelect ) return 0;     /* FROM is not a subquery or view */
  1304   1304     pTab = pSrc->a[0].pTab;
  1305         -  if( pTab==0 ) return 0;
  1306         -  if( pTab->pSelect ) return 0;          /* FROM clause is not a view */
         1305  +  if( NEVER(pTab==0) ) return 0;
         1306  +  assert( pTab->pSelect==0 );            /* FROM clause is not a view */
  1307   1307     if( IsVirtual(pTab) ) return 0;        /* FROM clause not a virtual table */
  1308   1308     pEList = p->pEList;
  1309   1309     if( pEList->nExpr!=1 ) return 0;       /* One column in the result set */
  1310   1310     if( pEList->a[0].pExpr->op!=TK_COLUMN ) return 0; /* Result is a column */
  1311   1311     return 1;
  1312   1312   }
  1313   1313   #endif /* SQLITE_OMIT_SUBQUERY */
................................................................................
  1314   1314   
  1315   1315   /*
  1316   1316   ** This function is used by the implementation of the IN (...) operator.
  1317   1317   ** It's job is to find or create a b-tree structure that may be used
  1318   1318   ** either to test for membership of the (...) set or to iterate through
  1319   1319   ** its members, skipping duplicates.
  1320   1320   **
  1321         -** The cursor opened on the structure (database table, database index 
         1321  +** The index of the cursor opened on the b-tree (database table, database index 
  1322   1322   ** or ephermal table) is stored in pX->iTable before this function returns.
  1323         -** The returned value indicates the structure type, as follows:
         1323  +** The returned value of this function indicates the b-tree type, as follows:
  1324   1324   **
  1325   1325   **   IN_INDEX_ROWID - The cursor was opened on a database table.
  1326   1326   **   IN_INDEX_INDEX - The cursor was opened on a database index.
  1327   1327   **   IN_INDEX_EPH -   The cursor was opened on a specially created and
  1328   1328   **                    populated epheremal table.
  1329   1329   **
  1330         -** An existing structure may only be used if the SELECT is of the simple
         1330  +** An existing b-tree may only be used if the SELECT is of the simple
  1331   1331   ** form:
  1332   1332   **
  1333   1333   **     SELECT <column> FROM <table>
  1334   1334   **
  1335         -** If prNotFound parameter is 0, then the structure will be used to iterate
         1335  +** If the prNotFound parameter is 0, then the b-tree will be used to iterate
  1336   1336   ** through the set members, skipping any duplicates. In this case an
  1337   1337   ** epheremal table must be used unless the selected <column> is guaranteed
  1338   1338   ** to be unique - either because it is an INTEGER PRIMARY KEY or it
  1339         -** is unique by virtue of a constraint or implicit index.
         1339  +** has a UNIQUE constraint or UNIQUE index.
  1340   1340   **
  1341         -** If the prNotFound parameter is not 0, then the structure will be used 
         1341  +** If the prNotFound parameter is not 0, then the b-tree will be used 
  1342   1342   ** for fast set membership tests. In this case an epheremal table must 
  1343   1343   ** be used unless <column> is an INTEGER PRIMARY KEY or an index can 
  1344   1344   ** be found with <column> as its left-most column.
  1345   1345   **
  1346         -** When the structure is being used for set membership tests, the user
         1346  +** When the b-tree is being used for membership tests, the calling function
  1347   1347   ** needs to know whether or not the structure contains an SQL NULL 
  1348   1348   ** value in order to correctly evaluate expressions like "X IN (Y, Z)".
  1349         -** If there is a chance that the structure may contain a NULL value at
         1349  +** If there is a chance that the b-tree might contain a NULL value at
  1350   1350   ** runtime, then a register is allocated and the register number written
  1351         -** to *prNotFound. If there is no chance that the structure contains a
         1351  +** to *prNotFound. If there is no chance that the b-tree contains a
  1352   1352   ** NULL value, then *prNotFound is left unchanged.
  1353   1353   **
  1354   1354   ** If a register is allocated and its location stored in *prNotFound, then
  1355         -** its initial value is NULL. If the structure does not remain constant
  1356         -** for the duration of the query (i.e. the set is a correlated sub-select), 
  1357         -** the value of the allocated register is reset to NULL each time the 
  1358         -** structure is repopulated. This allows the caller to use vdbe code 
  1359         -** equivalent to the following:
         1355  +** its initial value is NULL. If the b-tree does not remain constant
         1356  +** for the duration of the query (i.e. the SELECT that generates the b-tree
         1357  +** is a correlated subquery) then the value of the allocated register is
         1358  +** reset to NULL each time the b-tree is repopulated. This allows the
         1359  +** caller to use vdbe code equivalent to the following:
  1360   1360   **
  1361   1361   **   if( register==NULL ){
  1362   1362   **     has_null = <test if data structure contains null>
  1363   1363   **     register = 1
  1364   1364   **   }
  1365   1365   **
  1366   1366   ** in order to avoid running the <test if data structure contains null>
  1367   1367   ** test more often than is necessary.
  1368   1368   */
  1369   1369   #ifndef SQLITE_OMIT_SUBQUERY
  1370   1370   int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){
  1371         -  Select *p;
  1372         -  int eType = 0;
  1373         -  int iTab = pParse->nTab++;
  1374         -  int mustBeUnique = !prNotFound;
         1371  +  Select *p;                            /* SELECT to the right of IN operator */
         1372  +  int eType = 0;                        /* Type of RHS table. IN_INDEX_* */
         1373  +  int iTab = pParse->nTab++;            /* Cursor of the RHS table */
         1374  +  int mustBeUnique = (prNotFound==0);   /* True if RHS must be unique */
  1375   1375   
  1376         -  /* The follwing if(...) expression is true if the SELECT is of the 
  1377         -  ** simple form:
  1378         -  **
  1379         -  **     SELECT <column> FROM <table>
  1380         -  **
  1381         -  ** If this is the case, it may be possible to use an existing table
  1382         -  ** or index instead of generating an epheremal table.
         1376  +  /* Check to see if an existing table or index can be used to
         1377  +  ** satisfy the query.  This is preferable to generating a new 
         1378  +  ** ephemeral table.
  1383   1379     */
  1384   1380     p = (ExprHasProperty(pX, EP_xIsSelect) ? pX->x.pSelect : 0);
  1385         -  if( isCandidateForInOpt(p) ){
         1381  +  if( pParse->nErr==0 && isCandidateForInOpt(p) ){
  1386   1382       sqlite3 *db = pParse->db;              /* Database connection */
  1387   1383       Expr *pExpr = p->pEList->a[0].pExpr;   /* Expression <column> */
  1388   1384       int iCol = pExpr->iColumn;             /* Index of column <column> */
  1389   1385       Vdbe *v = sqlite3GetVdbe(pParse);      /* Virtual machine being coded */
  1390   1386       Table *pTab = p->pSrc->a[0].pTab;      /* Table <table>. */
  1391   1387       int iDb;                               /* Database idx for pTab */
  1392   1388      
................................................................................
  1411   1407         sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead);
  1412   1408         eType = IN_INDEX_ROWID;
  1413   1409   
  1414   1410         sqlite3VdbeJumpHere(v, iAddr);
  1415   1411       }else{
  1416   1412         Index *pIdx;                         /* Iterator variable */
  1417   1413   
  1418         -      /* The collation sequence used by the comparison. If an index is to 
         1414  +      /* The collation sequence used by the comparison. If an index is to
  1419   1415         ** be used in place of a temp-table, it must be ordered according
  1420   1416         ** to this collation sequence.  */
  1421   1417         CollSeq *pReq = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pExpr);
  1422   1418   
  1423   1419         /* Check that the affinity that will be used to perform the 
  1424   1420         ** comparison is the same as the affinity of the column. If
  1425   1421         ** it is not, it is not possible to use any index.
  1426   1422         */
  1427   1423         char aff = comparisonAffinity(pX);
  1428   1424         int affinity_ok = (pTab->aCol[iCol].affinity==aff||aff==SQLITE_AFF_NONE);
  1429   1425   
  1430   1426         for(pIdx=pTab->pIndex; pIdx && eType==0 && affinity_ok; pIdx=pIdx->pNext){
  1431   1427           if( (pIdx->aiColumn[0]==iCol)
  1432         -         && (pReq==sqlite3FindCollSeq(db, ENC(db), pIdx->azColl[0], 0))
         1428  +         && sqlite3FindCollSeq(db, ENC(db), pIdx->azColl[0], 0)==pReq
  1433   1429            && (!mustBeUnique || (pIdx->nColumn==1 && pIdx->onError!=OE_None))
  1434   1430           ){
  1435   1431             int iMem = ++pParse->nMem;
  1436   1432             int iAddr;
  1437   1433             char *pKey;
  1438   1434     
  1439   1435             pKey = (char *)sqlite3IndexKeyinfo(pParse, pIdx);
................................................................................
  1454   1450             }
  1455   1451           }
  1456   1452         }
  1457   1453       }
  1458   1454     }
  1459   1455   
  1460   1456     if( eType==0 ){
         1457  +    /* Could not found an existing able or index to use as the RHS b-tree.
         1458  +    ** We will have to generate an ephemeral table to do the job.
         1459  +    */
  1461   1460       int rMayHaveNull = 0;
  1462   1461       eType = IN_INDEX_EPH;
  1463   1462       if( prNotFound ){
  1464   1463         *prNotFound = rMayHaveNull = ++pParse->nMem;
  1465   1464       }else if( pX->pLeft->iColumn<0 && !ExprHasAnyProperty(pX, EP_xIsSelect) ){
  1466   1465         eType = IN_INDEX_ROWID;
  1467   1466       }

Changes to src/sqliteInt.h.

     7      7   **    May you do good and not evil.
     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   ** Internal interface definitions for SQLite.
    13     13   **
    14         -** @(#) $Id: sqliteInt.h,v 1.877 2009/05/28 01:00:55 drh Exp $
           14  +** @(#) $Id: sqliteInt.h,v 1.878 2009/05/28 21:04:39 drh Exp $
    15     15   */
    16     16   #ifndef _SQLITEINT_H_
    17     17   #define _SQLITEINT_H_
    18     18   
    19     19   /*
    20     20   ** Include the configuration header output by 'configure' if we're using the
    21     21   ** autoconf-based build
................................................................................
  2399   2399   void sqlite3ReleaseTempReg(Parse*,int);
  2400   2400   int sqlite3GetTempRange(Parse*,int);
  2401   2401   void sqlite3ReleaseTempRange(Parse*,int,int);
  2402   2402   Expr *sqlite3ExprAlloc(sqlite3*,int,const Token*,int);
  2403   2403   Expr *sqlite3Expr(sqlite3*,int,const char*);
  2404   2404   void sqlite3ExprAttachSubtrees(sqlite3*,Expr*,Expr*,Expr*);
  2405   2405   Expr *sqlite3PExpr(Parse*, int, Expr*, Expr*, const Token*);
  2406         -Expr *sqlite3RegisterExpr(Parse*,Token*);
  2407   2406   Expr *sqlite3ExprAnd(sqlite3*,Expr*, Expr*);
  2408   2407   Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*);
  2409   2408   void sqlite3ExprAssignVarNumber(Parse*, Expr*);
  2410   2409   void sqlite3ExprClear(sqlite3*, Expr*);
  2411   2410   void sqlite3ExprDelete(sqlite3*, Expr*);
  2412   2411   ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*);
  2413   2412   void sqlite3ExprListSetName(Parse*,ExprList*,Token*,int);