From: drh Date: Tue, 25 Aug 2015 00:27:06 +0000 (+0000) Subject: Changes toward being abld to process indexes on expressions. Not there yet - X-Git-Tag: version-3.9.0~150^2~20 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a514b8eb0cc9c6773171381a1dfe5b456d963a97;p=thirdparty%2Fsqlite.git Changes toward being abld to process indexes on expressions. Not there yet - this check-in is just movement in that direction. Some tests are failing. FossilOrigin-Name: 0ad0f8d77d8f95ca2ffb7745d18219f5e87dc89c --- diff --git a/manifest b/manifest index 9efff535b2..34496b20c1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\ssome\sredundant\scode:\s\sCall\ssqlite3ResolveExprListNames()\srather\sthan\ncalling\ssqlite3ResolveExprNames()\sin\sa\sloop\s-\sin\stwo\splaces. -D 2015-08-24T20:54:06.120 +C Changes\stoward\sbeing\sabld\sto\sprocess\sindexes\son\sexpressions.\s\sNot\sthere\syet\s-\s\nthis\scheck-in\sis\sjust\smovement\sin\sthat\sdirection.\s\sSome\stests\sare\sfailing. +D 2015-08-25T00:27:06.624 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e2218eb228374422969de7b1680eda6864affcef F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -282,7 +282,7 @@ F src/btmutex.c 45a968cc85afed9b5e6cf55bf1f42f8d18107f79 F src/btree.c f48b3ef91676c06a90a8832987ecef6b94c931ee F src/btree.h 969adc948e89e449220ff0ff724c94bb2a52e9f1 F src/btreeInt.h 8177c9ab90d772d6d2c6c517e05bed774b7c92c0 -F src/build.c 789e75f3478ac63c0f398a131c49a0802c356c2b +F src/build.c d9d53c7318117e04cfb79bc498b45f4982092f0c F src/callback.c 7b44ce59674338ad48b0e84e7b72f935ea4f68b0 F src/complete.c addcd8160b081131005d5bc2d34adf20c1c5c92f F src/ctime.c 5a0b735dc95604766f5dac73973658eef782ee8b @@ -335,14 +335,14 @@ F src/pragma.h 631a91c8b0e6ca8f051a1d8a4a0da4150e04620a F src/prepare.c 82e5db1013846a819f198336fed72c44c974e7b1 F src/printf.c 2bc439ff20a4aad0e0ad50a37a67b5eae7d20edc F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 -F src/resolve.c 66b2740075fdb8baf90155180d33d9850cbcc976 +F src/resolve.c ad9404cfa6f698aa530cca1c86570fa92cb65a12 F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e F src/select.c da6d1e7a4f1c8d713ed5415b5ed21d82ef465c0f F src/shell.c b1f91e60918df3a68efad1e3a11696b9a7e23d23 F src/sqlite.h.in 378bebc8fe6a88bade25e5f23b7e6123fdc64b00 F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad F src/sqlite3ext.h f700e6a9dd1fdcccc9951ab022b366fb66b9e413 -F src/sqliteInt.h edbcd0c0787541a636a25ab1d1eaf847dbd043f1 +F src/sqliteInt.h 5e2ce12324eb03b75d5b8a37084550eb66dbef78 F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46 F src/status.c f266ad8a2892d659b74f0f50cb6a88b6e7c12179 F src/table.c 51b46b2a62d1b3a959633d593b89bab5e2c9155e @@ -1379,7 +1379,10 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P bed42116addabcf3dfdc2e2d51ae183965704988 -R 455d327d4502b1aadc3594ff31ef63f2 +P bdaf66465b6b1bdad10c08d9527b98e7000a41e4 +R 3888db9ab5ffaaee9ce833f48e49ed84 +T *branch * index-expr +T *sym-index-expr * +T -sym-trunk * U drh -Z 983b791d1ba8013f2148572b484fe05d +Z 80441a5a4abd6f0065befff78e2e1eff diff --git a/manifest.uuid b/manifest.uuid index 96012b923f..712ea9a3fd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bdaf66465b6b1bdad10c08d9527b98e7000a41e4 \ No newline at end of file +0ad0f8d77d8f95ca2ffb7745d18219f5e87dc89c \ No newline at end of file diff --git a/src/build.c b/src/build.c index 8a7dda89c1..64bfe1b061 100644 --- a/src/build.c +++ b/src/build.c @@ -640,9 +640,7 @@ void sqlite3DeleteTable(sqlite3 *db, Table *pTable){ sqlite3DbFree(db, pTable->zName); sqlite3DbFree(db, pTable->zColAff); sqlite3SelectDelete(db, pTable->pSelect); -#ifndef SQLITE_OMIT_CHECK sqlite3ExprListDelete(db, pTable->pCheck); -#endif #ifndef SQLITE_OMIT_VIRTUALTABLE sqlite3VtabClear(db, pTable); #endif @@ -2891,7 +2889,6 @@ Index *sqlite3CreateIndex( int iDb; /* Index of the database that is being written */ Token *pName = 0; /* Unqualified name of the index to create */ struct ExprList_item *pListItem; /* For looping over pList */ - const Column *pTabCol; /* A column in the table */ int nExtra = 0; /* Space allocated for zExtra[] */ int nExtraCol; /* Number of extra columns needed */ char *zExtra = 0; /* Extra space after the Index object */ @@ -3115,28 +3112,22 @@ Index *sqlite3CreateIndex( ** break backwards compatibility - it needs to be a warning. */ for(i=0, pListItem=pList->a; inExpr; i++, pListItem++){ - const char *zColName; Expr *pCExpr; int requestedSortOrder; char *zColl; /* Collation sequence name */ + sqlite3ResolveSelfReference(pParse, pTab, NC_IdxExpr, pListItem->pExpr, 0); + if( pParse->nErr ) goto exit_create_index; pCExpr = sqlite3ExprSkipCollate(pListItem->pExpr); - if( pCExpr->op!=TK_ID ){ + if( pCExpr->op!=TK_COLUMN ){ sqlite3ErrorMsg(pParse, "indexes on expressions not yet supported"); continue; } - zColName = pCExpr->u.zToken; - for(j=0, pTabCol=pTab->aCol; jnCol; j++, pTabCol++){ - if( sqlite3StrICmp(zColName, pTabCol->zName)==0 ) break; - } - if( j>=pTab->nCol ){ - sqlite3ErrorMsg(pParse, "table %s has no column named %s", - pTab->zName, zColName); - pParse->checkSchema = 1; - goto exit_create_index; - } + j = pCExpr->iColumn; assert( j<=0x7fff ); + if( j<0 ) j = pTab->iPKey; pIndex->aiColumn[i] = (i16)j; + zColl = 0; if( pListItem->pExpr->op==TK_COLLATE ){ int nColl; zColl = pListItem->pExpr->u.zToken; @@ -3146,10 +3137,10 @@ Index *sqlite3CreateIndex( zColl = zExtra; zExtra += nColl; nExtra -= nColl; - }else{ + }else if( j>=0 ){ zColl = pTab->aCol[j].zColl; - if( !zColl ) zColl = "BINARY"; } + if( !zColl ) zColl = "BINARY"; if( !db->init.busy && !sqlite3LocateCollSeq(pParse, zColl) ){ goto exit_create_index; } diff --git a/src/resolve.c b/src/resolve.c index 4ef8fe051b..979596941d 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -547,36 +547,28 @@ Expr *sqlite3CreateColumnExpr(sqlite3 *db, SrcList *pSrc, int iSrc, int iCol){ } /* -** Report an error that an expression is not valid for a partial index WHERE -** clause. +** Report an error that an expression is not valid for some set of +** pNC->ncFlags values determined by validMask. If */ -static void notValidPartIdxWhere( +static void notValid( Parse *pParse, /* Leave error message here */ NameContext *pNC, /* The name context */ - const char *zMsg /* Type of error */ + const char *zMsg, /* Type of error */ + int validMask, /* Set of contexts for which prohibited */ + int okForInit /* No error if pParse->db->init.busy is true */ ){ - if( (pNC->ncFlags & NC_PartIdx)!=0 ){ - sqlite3ErrorMsg(pParse, "%s prohibited in partial index WHERE clauses", - zMsg); - } -} - + assert( (validMask&~(NC_IsCheck|NC_PartIdx|NC_IdxExpr))==0 ); + if( (pNC->ncFlags & validMask)!=0 + && (pParse->db->init.busy==0 || !okForInit) + ){ + const char *zIn = "partial index WHERE clauses"; + if( pNC->ncFlags & NC_IdxExpr ) zIn = "index expressions"; #ifndef SQLITE_OMIT_CHECK -/* -** Report an error that an expression is not valid for a CHECK constraint. -*/ -static void notValidCheckConstraint( - Parse *pParse, /* Leave error message here */ - NameContext *pNC, /* The name context */ - const char *zMsg /* Type of error */ -){ - if( (pNC->ncFlags & NC_IsCheck)!=0 ){ - sqlite3ErrorMsg(pParse,"%s prohibited in CHECK constraints", zMsg); + else if( pNC->ncFlags & NC_IsCheck ) zIn = "CHECK constraints"; +#endif + sqlite3ErrorMsg(pParse, "%s prohibited in %s", zMsg, zIn); } } -#else -# define notValidCheckConstraint(P,N,M) -#endif /* ** Expression p should encode a floating point value between 1.0 and 0.0. @@ -661,6 +653,8 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ Expr *pRight; /* if( pSrcList==0 ) break; */ + notValid(pParse, pNC, "the \".\" operator", NC_IdxExpr, 0); + notValid(pParse, pNC, "the \".\" operator", NC_PartIdx|NC_IsCheck, 1); pRight = pExpr->pRight; if( pRight->op==TK_ID ){ zDb = 0; @@ -690,7 +684,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ u8 enc = ENC(pParse->db); /* The database encoding */ assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); - notValidPartIdxWhere(pParse, pNC, "functions"); + notValid(pParse, pNC, "functions", NC_PartIdx, 0); zId = pExpr->u.zToken; nId = sqlite3Strlen30(zId); pDef = sqlite3FindFunction(pParse->db, zId, nId, n, enc, 0); @@ -740,6 +734,8 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ #endif if( pDef->funcFlags & SQLITE_FUNC_CONSTANT ){ ExprSetProperty(pExpr,EP_ConstFunc); + }else{ + notValid(pParse, pNC, "non-deterministic functions", NC_IdxExpr, 0); } } if( is_agg && (pNC->ncFlags & NC_AllowAgg)==0 ){ @@ -786,8 +782,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ testcase( pExpr->op==TK_IN ); if( ExprHasProperty(pExpr, EP_xIsSelect) ){ int nRef = pNC->nRef; - notValidCheckConstraint(pParse, pNC, "subqueries"); - notValidPartIdxWhere(pParse, pNC, "subqueries"); + notValid(pParse, pNC, "subqueries", NC_IsCheck|NC_PartIdx|NC_IdxExpr,0); sqlite3WalkSelect(pWalker, pExpr->x.pSelect); assert( pNC->nRef>=nRef ); if( nRef!=pNC->nRef ){ @@ -797,8 +792,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ break; } case TK_VARIABLE: { - notValidCheckConstraint(pParse, pNC, "parameters"); - notValidPartIdxWhere(pParse, pNC, "parameters"); + notValid(pParse, pNC, "parameters", NC_IsCheck|NC_PartIdx|NC_IdxExpr, 0); break; } } @@ -1501,14 +1495,14 @@ void sqlite3ResolveSelectNames( void sqlite3ResolveSelfReference( Parse *pParse, /* Parsing context */ Table *pTab, /* The table being referenced */ - int type, /* NC_IsCheck or NC_PartIdx */ + int type, /* NC_IsCheck or NC_PartIdx or NC_IdxExpr */ Expr *pExpr, /* Expression to resolve. May be NULL. */ ExprList *pList /* Expression list to resolve. May be NUL. */ ){ SrcList sSrc; /* Fake SrcList for pParse->pNewTable */ NameContext sNC; /* Name context for pParse->pNewTable */ - assert( type==NC_IsCheck || type==NC_PartIdx ); + assert( type==NC_IsCheck || type==NC_PartIdx || type==NC_IdxExpr ); memset(&sNC, 0, sizeof(sNC)); memset(&sSrc, 0, sizeof(sSrc)); sSrc.nSrc = 1; diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 4c17904ff8..2358795148 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2391,6 +2391,7 @@ struct NameContext { #define NC_IsCheck 0x0004 /* True if resolving names in a CHECK constraint */ #define NC_InAggFunc 0x0008 /* True if analyzing arguments to an agg func */ #define NC_PartIdx 0x0010 /* True if resolving a partial index WHERE */ +#define NC_IdxExpr 0x0020 /* True if resolving columns of CREATE INDEX */ #define NC_MinMaxAgg 0x1000 /* min/max aggregates seen. See note above */ /*