]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Resolve names in CREATE INDEX WHERE clauses and detect errors. Disallow
authordrh <drh@noemail.net>
Wed, 31 Jul 2013 19:05:22 +0000 (19:05 +0000)
committerdrh <drh@noemail.net>
Wed, 31 Jul 2013 19:05:22 +0000 (19:05 +0000)
expressions that contain variables, subqueries, or functions.
The expression is still not used for anything, however.
still unused.

FossilOrigin-Name: f2aa7842c8b9df24294f09e2bde27b3f08c455c7

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

index 0a7fe0faeebb4fc40553ddda106cbd008d1a9a7e..ac70fd7d00d8d2bea2d9da466a41a7b1b8bbe24a 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Here\sbegins\san\sexperimental\sbranch\sfor\sexploring\sthe\sidea\sof\sa\spartial\sindex.\nThis\scheck-in\sis\sable\sto\sparse\sa\sWHERE\sclause\son\sa\sCREATE\sINDEX\sstatement,\sbut\ndoes\snot\sactually\sdo\sanythingn\swith\sthat\sWHERE\sclause\syet.
-D 2013-07-31T18:12:26.006
+C Resolve\snames\sin\sCREATE\sINDEX\sWHERE\sclauses\sand\sdetect\serrors.\s\sDisallow\nexpressions\sthat\scontain\svariables,\ssubqueries,\sor\sfunctions.\nThe\sexpression\sis\sstill\snot\sused\sfor\sanything,\showever.\nstill\sunused.
+D 2013-07-31T19:05:22.844
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -166,7 +166,7 @@ F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7
 F src/btree.c 3f7bbfd72efb1cbf6a49515c376a031767ec930a
 F src/btree.h 6fa8a3ff2483d0bb64a9f0105a8cedeac9e00cca
 F src/btreeInt.h eecc84f02375b2bb7a44abbcbbe3747dde73edb2
-F src/build.c c2903be4a825d6be0a518f87b60e0dcf878782d3
+F src/build.c f1ef982f38df47b11e10edaf03fbcc77b80e4d35
 F src/callback.c d7e46f40c3cf53c43550b7da7a1d0479910b62cc
 F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
 F src/ctime.c 4262c227bc91cecc61ae37ed3a40f08069cfa267
@@ -214,14 +214,14 @@ F src/pragma.c 2790c5175bc3f95d2a0cf39283d144b9b012fec7
 F src/prepare.c fa6988589f39af8504a61731614cd4f6ae71554f
 F src/printf.c 41c49dac366a3a411190001a8ab495fa8887974e
 F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50
-F src/resolve.c 89f9003e8316ee3a172795459efc2a0274e1d5a8
+F src/resolve.c ada80e8df5d4ab0a21cf65ec5be8ba3b826e2b6f
 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0
 F src/select.c 91b62654caf8dfe292fb8882715e575d34ad3874
 F src/shell.c 52f975eae87c8338c4dfbf4c2842d2a0971f01fd
 F src/sqlite.h.in d6a7523d6795317aac574fccc67d9df25253771c
 F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0
 F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc
-F src/sqliteInt.h c99f22c5bda01f07e2f9a9a8cb2c0b9adeea696c
+F src/sqliteInt.h ffe632c1de338b459af86e6df712f4583c05b8af
 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
 F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158
 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
@@ -589,7 +589,7 @@ F test/index2.test ee83c6b5e3173a3d7137140d945d9a5d4fdfb9d6
 F test/index3.test 423a25c789fc8cc51aaf2a4370bbdde2d9e9eed7
 F test/index4.test 2983216eb8c86ee62d9ed7cb206b5cc3331c0026
 F test/index5.test fc07c14193c0430814e7a08b5da46888ee795c33
-F test/index6.test cbd74aa8604e29982438a7defae9fadaf9605336
+F test/index6.test 11171203a09b543d6181af59c298d2429ba762e2
 F test/indexedby.test 0e959308707c808515c3a51363f7a9835027108c
 F test/indexfault.test 31d4ab9a7d2f6e9616933eb079722362a883eb1d
 F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7
@@ -1104,10 +1104,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
 F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae
 F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac
-P eb6d4278b8516e0571269049d1eaa55066f51b1a
-R d0aa2f7065f4153ebb66a1af4210e515
-T *branch * partial-indices
-T *sym-partial-indices *
-T -sym-trunk *
+P 6794b2dcb48b3507caccfc7867fc185818cf8291
+R 1d2a041bdd5863b9d0e35692b3da5ea5
 U drh
-Z cfed8379e8335c37848dda6e7de0acdf
+Z 96979d6477d3e0c5f80978a86c33129b
index 4d7035783c5a292ab3a483da819ab0556eb64e1a..9efb9eb1f1167f9c1b86329c769ff31d372eaa02 100644 (file)
@@ -1 +1 @@
-6794b2dcb48b3507caccfc7867fc185818cf8291
\ No newline at end of file
+f2aa7842c8b9df24294f09e2bde27b3f08c455c7
\ No newline at end of file
index 7ca2ef00cc38819f6bbe4377141dc3a60a5a4b5a..61a1ae9e3caa9df16191d27eabecca8701ed4f5f 100644 (file)
@@ -1522,26 +1522,7 @@ void sqlite3EndTable(
   /* Resolve names in all CHECK constraint expressions.
   */
   if( p->pCheck ){
-    SrcList sSrc;                   /* Fake SrcList for pParse->pNewTable */
-    NameContext sNC;                /* Name context for pParse->pNewTable */
-    ExprList *pList;                /* List of all CHECK constraints */
-    int i;                          /* Loop counter */
-
-    memset(&sNC, 0, sizeof(sNC));
-    memset(&sSrc, 0, sizeof(sSrc));
-    sSrc.nSrc = 1;
-    sSrc.a[0].zName = p->zName;
-    sSrc.a[0].pTab = p;
-    sSrc.a[0].iCursor = -1;
-    sNC.pParse = pParse;
-    sNC.pSrcList = &sSrc;
-    sNC.ncFlags = NC_IsCheck;
-    pList = p->pCheck;
-    for(i=0; i<pList->nExpr; i++){
-      if( sqlite3ResolveExprNames(&sNC, pList->a[i].pExpr) ){
-        return;
-      }
-    }
+    sqlite3ResolveSelfReference(pParse, p, NC_IsCheck, 0, p->pCheck);
   }
 #endif /* !defined(SQLITE_OMIT_CHECK) */
 
@@ -2702,8 +2683,11 @@ Index *sqlite3CreateIndex(
   pIndex->uniqNotNull = onError==OE_Abort;
   pIndex->autoIndex = (u8)(pName==0);
   pIndex->pSchema = db->aDb[iDb].pSchema;
-  pIndex->pPartIdxWhere = pPIWhere;
-  pPIWhere = 0;
+  if( pPIWhere ){
+    sqlite3ResolveSelfReference(pParse, pTab, NC_PartIdx, pPIWhere, 0);
+    pIndex->pPartIdxWhere = pPIWhere;
+    pPIWhere = 0;
+  }
   assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
 
   /* Check to see if we should honor DESC requests on index columns
index 91efcaa1a16bfc98fb35d85cad156b93533e4e06..239e0eb2a05e0d846e37a646e097f9915adfc87f 100644 (file)
@@ -522,6 +522,39 @@ Expr *sqlite3CreateColumnExpr(sqlite3 *db, SrcList *pSrc, int iSrc, int iCol){
   return p;
 }
 
+/*
+** Report an error that an expression is not valid for a partial index WHERE
+** clause.
+*/
+static void notValidPartIdxWhere(
+  Parse *pParse,       /* Leave error message here */
+  NameContext *pNC,    /* The name context */
+  const char *zMsg     /* Type of error */
+){
+  if( (pNC->ncFlags & NC_PartIdx)!=0 ){
+    sqlite3ErrorMsg(pParse, "%s prohibited in partial index WHERE clauses",
+                    zMsg);
+  }
+}
+
+#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
+# define notValidCheckConstraint(P,N,M)
+#endif
+
+
 /*
 ** This routine is callback for sqlite3WalkExpr().
 **
@@ -621,6 +654,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
 
       testcase( pExpr->op==TK_CONST_FUNC );
       assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
+      notValidPartIdxWhere(pParse, pNC, "functions");
       zId = pExpr->u.zToken;
       nId = sqlite3Strlen30(zId);
       pDef = sqlite3FindFunction(pParse->db, zId, nId, n, enc, 0);
@@ -686,11 +720,8 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
       testcase( pExpr->op==TK_IN );
       if( ExprHasProperty(pExpr, EP_xIsSelect) ){
         int nRef = pNC->nRef;
-#ifndef SQLITE_OMIT_CHECK
-        if( (pNC->ncFlags & NC_IsCheck)!=0 ){
-          sqlite3ErrorMsg(pParse,"subqueries prohibited in CHECK constraints");
-        }
-#endif
+        notValidCheckConstraint(pParse, pNC, "subqueries");
+        notValidPartIdxWhere(pParse, pNC, "subqueries");
         sqlite3WalkSelect(pWalker, pExpr->x.pSelect);
         assert( pNC->nRef>=nRef );
         if( nRef!=pNC->nRef ){
@@ -699,14 +730,11 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
       }
       break;
     }
-#ifndef SQLITE_OMIT_CHECK
     case TK_VARIABLE: {
-      if( (pNC->ncFlags & NC_IsCheck)!=0 ){
-        sqlite3ErrorMsg(pParse,"parameters prohibited in CHECK constraints");
-      }
+      notValidCheckConstraint(pParse, pNC, "parameters");
+      notValidPartIdxWhere(pParse, pNC, "parameters");
       break;
     }
-#endif
   }
   return (pParse->nErr || pParse->db->mallocFailed) ? WRC_Abort : WRC_Continue;
 }
@@ -1331,3 +1359,45 @@ void sqlite3ResolveSelectNames(
   w.u.pNC = pOuterNC;
   sqlite3WalkSelect(&w, p);
 }
+
+/*
+** Resolve names in expressions that can only reference a single table:
+**
+**    *   CHECK constraints
+**    *   WHERE clauses on partial indices
+**
+** The Expr.iTable value for Expr.op==TK_COLUMN nodes of the expression
+** is set to -1 and the Expr.iColumn value is set to the column number.
+**
+** Any errors cause an error message to be set in pParse.
+*/
+void sqlite3ResolveSelfReference(
+  Parse *pParse,      /* Parsing context */
+  Table *pTab,        /* The table being referenced */
+  int type,           /* NC_IsCheck or NC_PartIdx */
+  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 */
+  int i;                          /* Loop counter */
+
+  assert( type==NC_IsCheck || type==NC_PartIdx );
+  memset(&sNC, 0, sizeof(sNC));
+  memset(&sSrc, 0, sizeof(sSrc));
+  sSrc.nSrc = 1;
+  sSrc.a[0].zName = pTab->zName;
+  sSrc.a[0].pTab = pTab;
+  sSrc.a[0].iCursor = -1;
+  sNC.pParse = pParse;
+  sNC.pSrcList = &sSrc;
+  sNC.ncFlags = type;
+  if( sqlite3ResolveExprNames(&sNC, pExpr) ) return;
+  if( pList ){
+    for(i=0; i<pList->nExpr; i++){
+      if( sqlite3ResolveExprNames(&sNC, pList->a[i].pExpr) ){
+        return;
+      }
+    }
+  }
+}
index dba1e55b83dd359a340fe107eb9a8bdca38261ea..3d4a57f3a4239d47527efee5db93203428e21929 100644 (file)
@@ -2019,6 +2019,7 @@ struct NameContext {
 #define NC_InAggFunc 0x08    /* True if analyzing arguments to an agg func */
 #define NC_AsMaybe   0x10    /* Resolve to AS terms of the result set only
                              ** if no other resolution is available */
+#define NC_PartIdx   0x20    /* True if resolving a partial index WHERE */
 
 /*
 ** An instance of the following structure contains all information
@@ -3063,6 +3064,7 @@ void sqlite3SelectPrep(Parse*, Select*, NameContext*);
 int sqlite3MatchSpanName(const char*, const char*, const char*, const char*);
 int sqlite3ResolveExprNames(NameContext*, Expr*);
 void sqlite3ResolveSelectNames(Parse*, Select*, NameContext*);
+void sqlite3ResolveSelfReference(Parse*,Table*,int,Expr*,ExprList*);
 int sqlite3ResolveOrderGroupBy(Parse*, Select*, ExprList*, const char*);
 void sqlite3ColumnDefault(Vdbe *, Table *, int, int);
 void sqlite3AlterFinishAddColumn(Parse *, Token *);
index 7bd83769f3515600041fd55254c3da53772adfd8..89b9c4876197b6c8cf63adb6cc34a4715d938e23 100644 (file)
@@ -30,4 +30,31 @@ do_test index6-1.1 {
   }
 } {14 20}
 
+do_test index6-1.2 {
+  catchsql {
+    CREATE INDEX bad1 ON t1(a,b) WHERE c IS NOT NULL;
+  }
+} {1 {no such column: c}}
+do_test index6-1.3 {
+  catchsql {
+    CREATE INDEX bad1 ON t1(a,b) WHERE EXISTS(SELECT * FROM t1);
+  }
+} {1 {subqueries prohibited in partial index WHERE clauses}}
+do_test index6-1.4 {
+  catchsql {
+    CREATE INDEX bad1 ON t1(a,b) WHERE a!=?1;
+  }
+} {1 {parameters prohibited in partial index WHERE clauses}}
+do_test index6-1.5 {
+  catchsql {
+    CREATE INDEX bad1 ON t1(a,b) WHERE a!=random();
+  }
+} {1 {functions prohibited in partial index WHERE clauses}}
+do_test index6-1.6 {
+  catchsql {
+    CREATE INDEX bad1 ON t1(a,b) WHERE a NOT LIKE 'abc%';
+  }
+} {1 {functions prohibited in partial index WHERE clauses}}
+
+
 finish_test