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:
@@ -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
@@ -1 +1 @@
|
||||
bdaf66465b6b1bdad10c08d9527b98e7000a41e4
|
||||
0ad0f8d77d8f95ca2ffb7745d18219f5e87dc89c
|
||||
+8
-17
@@ -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
@@ -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;
|
||||
|
||||
@@ -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 */
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user