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
This commit is contained in:
drh
2015-08-25 00:27:06 +00:00
parent fea870be38
commit a514b8eb0c
5 changed files with 45 additions and 56 deletions
+11 -8
View File
@@ -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
+1 -1
View File
@@ -1 +1 @@
bdaf66465b6b1bdad10c08d9527b98e7000a41e4
0ad0f8d77d8f95ca2ffb7745d18219f5e87dc89c
+8 -17
View File
@@ -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; i<pList->nExpr; 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; j<pTab->nCol; 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;
}
+24 -30
View File
@@ -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;
+1
View File
@@ -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 */
/*