From: drh Date: Thu, 28 May 2009 21:04:37 +0000 (+0000) Subject: Remove references to deleted function sqlite3ExprRegister(). Changes to X-Git-Tag: version-3.6.15~74 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=b74b101766e3766f7485a1b85451b914349e2f1f;p=thirdparty%2Fsqlite.git Remove references to deleted function sqlite3ExprRegister(). Changes to the expr.c source module to promote better testing. (CVS 6686) FossilOrigin-Name: 6ae4ad6ebee4db88c411df97bb1de574708dd53c --- diff --git a/manifest b/manifest index 40c453eaf3..0dcb6dcb19 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sNULL\spointer\sdereference\sfollowing\san\sOOM\serror\sin\sthe\scolumn\sname\nresolver.\s(CVS\s6685) -D 2009-05-28T14:34:50 +C Remove\sreferences\sto\sdeleted\sfunction\ssqlite3ExprRegister().\s\sChanges\sto\nthe\sexpr.c\ssource\smodule\sto\spromote\sbetter\stesting.\s(CVS\s6686) +D 2009-05-28T21:04:38 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.in 583e87706abc3026960ed759aff6371faf84c211 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -109,12 +109,12 @@ F src/btmutex.c 9b899c0d8df3bd68f527b0afe03088321b696d3c F src/btree.c 41bee6e4699e61f9d33beabfcf13caba4467c20a F src/btree.h 3748683b382bc3022f23840c0a35d3231b24fc6e F src/btreeInt.h df64030d632f8c8ac217ed52e8b6b3eacacb33a5 -F src/build.c 567574f5756e9e462cf50c5da1895dc43672bafe +F src/build.c dedb5bcbd8261c182e831b4784a596c000c72958 F src/callback.c 57359fa93de47c341b6b8ee504a88ff276397686 F src/complete.c 5ad5c6cd4548211867c204c41a126d73a9fbcea0 F src/date.c ab5f7137656652a48434d64f96bdcdc823bb23b3 F src/delete.c cb791855c7948cecc96def9d97989879ca26f257 -F src/expr.c 2f8b6e5c3c867fa421189ad5692b1ff60ecc59c4 +F src/expr.c 9d25d7229719334dc87909f8094b10d033b994f1 F src/fault.c dc88c821842157460750d2d61a8a8b4197d047ff F src/func.c 9d7b47729c337c5e4b78d795922ed34eec4aef67 F src/global.c 448419c44ce0701104c2121b0e06919b44514c0c @@ -162,7 +162,7 @@ F src/select.c fd1737a667bab296f50049a841b3aba5ec89418e F src/shell.c 7eacd0bdaa887931f5ff205c9defc3e8df95a2dd F src/sqlite.h.in 79210c4d8905cfb4b038486dde5f36fabb796a86 F src/sqlite3ext.h 1db7d63ab5de4b3e6b83dd03d1a4e64fef6d2a17 -F src/sqliteInt.h 97f9125229c14cd3afa6c4fed4b419a1899be476 +F src/sqliteInt.h 39fb1a85a71f9a86817ccc55b308335b4b43012a F src/sqliteLimit.h ffe93f5a0c4e7bd13e70cd7bf84cfb5c3465f45d F src/status.c 237b193efae0cf6ac3f0817a208de6c6c6ef6d76 F src/table.c cc86ad3d6ad54df7c63a3e807b5783c90411a08d @@ -731,7 +731,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81 F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e -P 376ecf0d87e4a2329f5861401f83ed9ceb35d528 -R bbce5972206d6f118dd6353677bfd682 +P 3b46142532934d17aa136c2e56e58e7828df0f54 +R 6a3a4185326252490b36e399fe92cbcc U drh -Z f90523b52af270223148e00c0be5042d +Z 2830ef720e4e0990284e68ba861f067a diff --git a/manifest.uuid b/manifest.uuid index 173ad89e90..5b6459477d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3b46142532934d17aa136c2e56e58e7828df0f54 \ No newline at end of file +6ae4ad6ebee4db88c411df97bb1de574708dd53c \ No newline at end of file diff --git a/src/build.c b/src/build.c index ce83859928..93548aff6f 100644 --- a/src/build.c +++ b/src/build.c @@ -22,7 +22,7 @@ ** COMMIT ** ROLLBACK ** -** $Id: build.c,v 1.546 2009/05/28 01:00:55 drh Exp $ +** $Id: build.c,v 1.547 2009/05/28 21:04:38 drh Exp $ */ #include "sqliteInt.h" @@ -1880,7 +1880,8 @@ static void destroyRootPage(Parse *pParse, int iTable, int iDb){ ** reflect this. ** ** The "#NNN" in the SQL is a special constant that means whatever value - ** is in register NNN. See sqlite3RegisterExpr(). + ** is in register NNN. See grammar rules associated with the TK_REGISTER + ** token for additional information. */ sqlite3NestedParse(pParse, "UPDATE %Q.%s SET rootpage=%d WHERE #%d AND rootpage=#%d", diff --git a/src/expr.c b/src/expr.c index a94b825eb3..e69cc2d696 100644 --- a/src/expr.c +++ b/src/expr.c @@ -12,7 +12,7 @@ ** This file contains routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions in SQLite. ** -** $Id: expr.c,v 1.438 2009/05/28 01:00:55 drh Exp $ +** $Id: expr.c,v 1.439 2009/05/28 21:04:38 drh Exp $ */ #include "sqliteInt.h" @@ -1156,12 +1156,6 @@ static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){ case TK_COLUMN: case TK_AGG_FUNCTION: case TK_AGG_COLUMN: -#ifndef SQLITE_OMIT_SUBQUERY - case TK_SELECT: - case TK_EXISTS: - testcase( pExpr->op==TK_SELECT ); - testcase( pExpr->op==TK_EXISTS ); -#endif testcase( pExpr->op==TK_ID ); testcase( pExpr->op==TK_COLUMN ); testcase( pExpr->op==TK_AGG_FUNCTION ); @@ -1169,6 +1163,8 @@ static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){ pWalker->u.i = 0; return WRC_Abort; default: + testcase( pExpr->op==TK_SELECT ); /* selectNodeIsConstant will disallow */ + testcase( pExpr->op==TK_EXISTS ); /* selectNodeIsConstant will disallow */ return WRC_Continue; } } @@ -1274,14 +1270,16 @@ int sqlite3IsRowid(const char *z){ } /* -** Return true if the IN operator optimization is enabled and -** the SELECT statement p exists and is of the -** simple form: +** Return true if we are able to the IN operator optimization on a +** query of the form ** -** SELECT FROM +** x IN (SELECT ...) +** +** Where the SELECT... clause is as specified by the parameter to this +** routine. ** -** If this is the case, it may be possible to use an existing table -** or index instead of generating an epheremal table. +** The Select object passed in has already been preprocessed and no +** errors have been found. */ #ifndef SQLITE_OMIT_SUBQUERY static int isCandidateForInOpt(Select *p){ @@ -1291,19 +1289,21 @@ static int isCandidateForInOpt(Select *p){ if( p==0 ) return 0; /* right-hand side of IN is SELECT */ if( p->pPrior ) return 0; /* Not a compound SELECT */ if( p->selFlags & (SF_Distinct|SF_Aggregate) ){ - return 0; /* No DISTINCT keyword and no aggregate functions */ + testcase( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct ); + testcase( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Aggregate ); + return 0; /* No DISTINCT keyword and no aggregate functions */ } - if( p->pGroupBy ) return 0; /* Has no GROUP BY clause */ + assert( p->pGroupBy==0 ); /* Has no GROUP BY clause */ if( p->pLimit ) return 0; /* Has no LIMIT clause */ - if( p->pOffset ) return 0; + assert( p->pOffset==0 ); /* No LIMIT means no OFFSET */ if( p->pWhere ) return 0; /* Has no WHERE clause */ pSrc = p->pSrc; assert( pSrc!=0 ); if( pSrc->nSrc!=1 ) return 0; /* Single term in FROM clause */ - if( pSrc->a[0].pSelect ) return 0; /* FROM clause is not a subquery */ + if( pSrc->a[0].pSelect ) return 0; /* FROM is not a subquery or view */ pTab = pSrc->a[0].pTab; - if( pTab==0 ) return 0; - if( pTab->pSelect ) return 0; /* FROM clause is not a view */ + if( NEVER(pTab==0) ) return 0; + assert( pTab->pSelect==0 ); /* FROM clause is not a view */ if( IsVirtual(pTab) ) return 0; /* FROM clause not a virtual table */ pEList = p->pEList; if( pEList->nExpr!=1 ) return 0; /* One column in the result set */ @@ -1318,45 +1318,45 @@ static int isCandidateForInOpt(Select *p){ ** either to test for membership of the (...) set or to iterate through ** its members, skipping duplicates. ** -** The cursor opened on the structure (database table, database index +** The index of the cursor opened on the b-tree (database table, database index ** or ephermal table) is stored in pX->iTable before this function returns. -** The returned value indicates the structure type, as follows: +** The returned value of this function indicates the b-tree type, as follows: ** ** IN_INDEX_ROWID - The cursor was opened on a database table. ** IN_INDEX_INDEX - The cursor was opened on a database index. ** IN_INDEX_EPH - The cursor was opened on a specially created and ** populated epheremal table. ** -** An existing structure may only be used if the SELECT is of the simple +** An existing b-tree may only be used if the SELECT is of the simple ** form: ** ** SELECT FROM
** -** If prNotFound parameter is 0, then the structure will be used to iterate +** If the prNotFound parameter is 0, then the b-tree will be used to iterate ** through the set members, skipping any duplicates. In this case an ** epheremal table must be used unless the selected is guaranteed ** to be unique - either because it is an INTEGER PRIMARY KEY or it -** is unique by virtue of a constraint or implicit index. +** has a UNIQUE constraint or UNIQUE index. ** -** If the prNotFound parameter is not 0, then the structure will be used +** If the prNotFound parameter is not 0, then the b-tree will be used ** for fast set membership tests. In this case an epheremal table must ** be used unless is an INTEGER PRIMARY KEY or an index can ** be found with as its left-most column. ** -** When the structure is being used for set membership tests, the user +** When the b-tree is being used for membership tests, the calling function ** needs to know whether or not the structure contains an SQL NULL ** value in order to correctly evaluate expressions like "X IN (Y, Z)". -** If there is a chance that the structure may contain a NULL value at +** If there is a chance that the b-tree might contain a NULL value at ** runtime, then a register is allocated and the register number written -** to *prNotFound. If there is no chance that the structure contains a +** to *prNotFound. If there is no chance that the b-tree contains a ** NULL value, then *prNotFound is left unchanged. ** ** If a register is allocated and its location stored in *prNotFound, then -** its initial value is NULL. If the structure does not remain constant -** for the duration of the query (i.e. the set is a correlated sub-select), -** the value of the allocated register is reset to NULL each time the -** structure is repopulated. This allows the caller to use vdbe code -** equivalent to the following: +** its initial value is NULL. If the b-tree does not remain constant +** for the duration of the query (i.e. the SELECT that generates the b-tree +** is a correlated subquery) then the value of the allocated register is +** reset to NULL each time the b-tree is repopulated. This allows the +** caller to use vdbe code equivalent to the following: ** ** if( register==NULL ){ ** has_null = @@ -1368,21 +1368,17 @@ static int isCandidateForInOpt(Select *p){ */ #ifndef SQLITE_OMIT_SUBQUERY int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){ - Select *p; - int eType = 0; - int iTab = pParse->nTab++; - int mustBeUnique = !prNotFound; - - /* The follwing if(...) expression is true if the SELECT is of the - ** simple form: - ** - ** SELECT FROM
- ** - ** If this is the case, it may be possible to use an existing table - ** or index instead of generating an epheremal table. + Select *p; /* SELECT to the right of IN operator */ + int eType = 0; /* Type of RHS table. IN_INDEX_* */ + int iTab = pParse->nTab++; /* Cursor of the RHS table */ + int mustBeUnique = (prNotFound==0); /* True if RHS must be unique */ + + /* Check to see if an existing table or index can be used to + ** satisfy the query. This is preferable to generating a new + ** ephemeral table. */ p = (ExprHasProperty(pX, EP_xIsSelect) ? pX->x.pSelect : 0); - if( isCandidateForInOpt(p) ){ + if( pParse->nErr==0 && isCandidateForInOpt(p) ){ sqlite3 *db = pParse->db; /* Database connection */ Expr *pExpr = p->pEList->a[0].pExpr; /* Expression */ int iCol = pExpr->iColumn; /* Index of column */ @@ -1415,7 +1411,7 @@ int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){ }else{ Index *pIdx; /* Iterator variable */ - /* The collation sequence used by the comparison. If an index is to + /* The collation sequence used by the comparison. If an index is to ** be used in place of a temp-table, it must be ordered according ** to this collation sequence. */ CollSeq *pReq = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pExpr); @@ -1429,7 +1425,7 @@ int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){ for(pIdx=pTab->pIndex; pIdx && eType==0 && affinity_ok; pIdx=pIdx->pNext){ if( (pIdx->aiColumn[0]==iCol) - && (pReq==sqlite3FindCollSeq(db, ENC(db), pIdx->azColl[0], 0)) + && sqlite3FindCollSeq(db, ENC(db), pIdx->azColl[0], 0)==pReq && (!mustBeUnique || (pIdx->nColumn==1 && pIdx->onError!=OE_None)) ){ int iMem = ++pParse->nMem; @@ -1458,6 +1454,9 @@ int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){ } if( eType==0 ){ + /* Could not found an existing able or index to use as the RHS b-tree. + ** We will have to generate an ephemeral table to do the job. + */ int rMayHaveNull = 0; eType = IN_INDEX_EPH; if( prNotFound ){ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 97de27667b..fadde5047d 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -11,7 +11,7 @@ ************************************************************************* ** Internal interface definitions for SQLite. ** -** @(#) $Id: sqliteInt.h,v 1.877 2009/05/28 01:00:55 drh Exp $ +** @(#) $Id: sqliteInt.h,v 1.878 2009/05/28 21:04:39 drh Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ @@ -2403,7 +2403,6 @@ Expr *sqlite3ExprAlloc(sqlite3*,int,const Token*,int); Expr *sqlite3Expr(sqlite3*,int,const char*); void sqlite3ExprAttachSubtrees(sqlite3*,Expr*,Expr*,Expr*); Expr *sqlite3PExpr(Parse*, int, Expr*, Expr*, const Token*); -Expr *sqlite3RegisterExpr(Parse*,Token*); Expr *sqlite3ExprAnd(sqlite3*,Expr*, Expr*); Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*); void sqlite3ExprAssignVarNumber(Parse*, Expr*);