]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Changes toward being abld to process indexes on expressions. Not there yet -
authordrh <drh@noemail.net>
Tue, 25 Aug 2015 00:27:06 +0000 (00:27 +0000)
committerdrh <drh@noemail.net>
Tue, 25 Aug 2015 00:27:06 +0000 (00:27 +0000)
this check-in is just movement in that direction.  Some tests are failing.

FossilOrigin-Name: 0ad0f8d77d8f95ca2ffb7745d18219f5e87dc89c

manifest
manifest.uuid
src/build.c
src/resolve.c
src/sqliteInt.h

index 9efff535b2cb17c54cc7ccd708c85910371fde76..34496b20c11041e0a244f7fd73bfe20d9bd4d221 100644 (file)
--- 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
index 96012b923f46b3bdd614525f45e87f9376984b70..712ea9a3fd9b25e2a8c4420b6dc76e263e5274a0 100644 (file)
@@ -1 +1 @@
-bdaf66465b6b1bdad10c08d9527b98e7000a41e4
\ No newline at end of file
+0ad0f8d77d8f95ca2ffb7745d18219f5e87dc89c
\ No newline at end of file
index 8a7dda89c176d40347460ab1c2c41bdb5c48c1f8..64bfe1b061d6a0c7671085a545d12511fe56241f 100644 (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;
     }
index 4ef8fe051b5c765c4a0fb470dd2473addec33f05..979596941d876421a7c1e7ad467a17acbdd161af 100644 (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;
index 4c17904ff85fa32a578967d56148924671fcd326..235879514837c6a40d53eaefde471a1dc6240981 100644 (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 */
 
 /*