/ Check-in [e63d01c6]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:When generating code for partial indexes, be sure not to modify the index condition expression in the schema.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: e63d01c69c3e50f49ee3022a519c4f3e91f00520
User & Date: drh 2015-06-11 13:58:35
Context
2015-06-11
14:19
Remove stray outputs from the test suite. check-in: afc6db9b user: drh tags: trunk
13:58
When generating code for partial indexes, be sure not to modify the index condition expression in the schema. check-in: e63d01c6 user: drh tags: trunk
2015-06-10
22:03
Fix minor typo in the quicktest MSVC makefile target. check-in: 75b65f9d user: mistachkin tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/delete.c.

   794    794     int nCol;
   795    795   
   796    796     if( piPartIdxLabel ){
   797    797       if( pIdx->pPartIdxWhere ){
   798    798         *piPartIdxLabel = sqlite3VdbeMakeLabel(v);
   799    799         pParse->iPartIdxTab = iDataCur;
   800    800         sqlite3ExprCachePush(pParse);
   801         -      sqlite3ExprIfFalse(pParse, pIdx->pPartIdxWhere, *piPartIdxLabel, 
   802         -                         SQLITE_JUMPIFNULL);
          801  +      sqlite3ExprIfFalseDup(pParse, pIdx->pPartIdxWhere, *piPartIdxLabel, 
          802  +                            SQLITE_JUMPIFNULL);
   803    803       }else{
   804    804         *piPartIdxLabel = 0;
   805    805       }
   806    806     }
   807    807     nCol = (prefixOnly && pIdx->uniqNotNull) ? pIdx->nKeyCol : pIdx->nColumn;
   808    808     regBase = sqlite3GetTempRange(pParse, nCol);
   809    809     if( pPrior && (regBase!=regPrior || pPrior->pPartIdxWhere) ) pPrior = 0;

Changes to src/expr.c.

  3697   3697         }
  3698   3698         break;
  3699   3699       }
  3700   3700     }
  3701   3701     sqlite3ReleaseTempReg(pParse, regFree1);
  3702   3702     sqlite3ReleaseTempReg(pParse, regFree2);
  3703   3703   }
         3704  +
         3705  +/*
         3706  +** Like sqlite3ExprIfFalse() except that a copy is made of pExpr before
         3707  +** code generation, and that copy is deleted after code generation. This
         3708  +** ensures that the original pExpr is unchanged.
         3709  +*/
         3710  +void sqlite3ExprIfFalseDup(Parse *pParse, Expr *pExpr, int dest,int jumpIfNull){
         3711  +  sqlite3 *db = pParse->db;
         3712  +  Expr *pCopy = sqlite3ExprDup(db, pExpr, 0);
         3713  +  if( db->mallocFailed==0 ){
         3714  +    sqlite3ExprIfFalse(pParse, pCopy, dest, jumpIfNull);
         3715  +  }
         3716  +  sqlite3ExprDelete(db, pCopy);
         3717  +}
         3718  +
  3704   3719   
  3705   3720   /*
  3706   3721   ** Do a deep comparison of two expression trees.  Return 0 if the two
  3707   3722   ** expressions are completely identical.  Return 1 if they differ only
  3708   3723   ** by a COLLATE operator at the top level.  Return 2 if there are differences
  3709   3724   ** other than the top-level COLLATE operator.
  3710   3725   **

Changes to src/insert.c.

  1377   1377       iThisCur = iIdxCur+ix;
  1378   1378       addrUniqueOk = sqlite3VdbeMakeLabel(v);
  1379   1379   
  1380   1380       /* Skip partial indices for which the WHERE clause is not true */
  1381   1381       if( pIdx->pPartIdxWhere ){
  1382   1382         sqlite3VdbeAddOp2(v, OP_Null, 0, aRegIdx[ix]);
  1383   1383         pParse->ckBase = regNewData+1;
  1384         -      sqlite3ExprIfFalse(pParse, pIdx->pPartIdxWhere, addrUniqueOk,
  1385         -                         SQLITE_JUMPIFNULL);
         1384  +      sqlite3ExprIfFalseDup(pParse, pIdx->pPartIdxWhere, addrUniqueOk,
         1385  +                            SQLITE_JUMPIFNULL);
  1386   1386         pParse->ckBase = 0;
  1387   1387       }
  1388   1388   
  1389   1389       /* Create a record for this index entry as it should appear after
  1390   1390       ** the insert or update.  Store that record in the aRegIdx[ix] register
  1391   1391       */
  1392   1392       regIdx = sqlite3GetTempRange(pParse, pIdx->nColumn);

Changes to src/sqliteInt.h.

  3322   3322   int sqlite3ExprCodeTarget(Parse*, Expr*, int);
  3323   3323   void sqlite3ExprCodeAndCache(Parse*, Expr*, int);
  3324   3324   int sqlite3ExprCodeExprList(Parse*, ExprList*, int, u8);
  3325   3325   #define SQLITE_ECEL_DUP      0x01  /* Deep, not shallow copies */
  3326   3326   #define SQLITE_ECEL_FACTOR   0x02  /* Factor out constant terms */
  3327   3327   void sqlite3ExprIfTrue(Parse*, Expr*, int, int);
  3328   3328   void sqlite3ExprIfFalse(Parse*, Expr*, int, int);
         3329  +void sqlite3ExprIfFalseDup(Parse*, Expr*, int, int);
  3329   3330   Table *sqlite3FindTable(sqlite3*,const char*, const char*);
  3330   3331   Table *sqlite3LocateTable(Parse*,int isView,const char*, const char*);
  3331   3332   Table *sqlite3LocateTableItem(Parse*,int isView,struct SrcList_item *);
  3332   3333   Index *sqlite3FindIndex(sqlite3*,const char*, const char*);
  3333   3334   void sqlite3UnlinkAndDeleteTable(sqlite3*,int,const char*);
  3334   3335   void sqlite3UnlinkAndDeleteIndex(sqlite3*,int,const char*);
  3335   3336   void sqlite3Vacuum(Parse*);

Changes to test/index6.test.

   322    322   do_execsql_test index6-8.2 {
   323    323     SELECT * FROM t8a LEFT JOIN t8b ON (x = 'value' AND y = a)
   324    324   } {
   325    325     1 one value 1 
   326    326     2 two {} {} 
   327    327     3 three value 3
   328    328   }
          329  +
          330  +# 2015-06-11.  Assertion fault found by AFL
          331  +#
          332  +do_execsql_test index6-9.1 {
          333  +  CREATE TABLE t9(a int, b int, c int);
          334  +  CREATE INDEX t9ca ON t9(c,a) WHERE a in (10,12,20);
          335  +  INSERT INTO t9 VALUES(1,1,9),(10,2,35),(11,15,82),(20,19,5),(NULL,7,3);
          336  +  UPDATE t9 SET b=c WHERE a in (10,12,20);
          337  +  SELECT a,b,c,'|' FROM t9 ORDER BY a;
          338  +} {{} 7 3 | 1 1 9 | 10 35 35 | 11 15 82 | 20 5 5 |}
          339  +do_execsql_test index6-9.2 {
          340  +  DROP TABLE t9;
          341  +  CREATE TABLE t9(a int, b int, c int, PRIMARY KEY(a)) WITHOUT ROWID;
          342  +  CREATE INDEX t9ca ON t9(c,a) WHERE a in (10,12,20);
          343  +  INSERT INTO t9 VALUES(1,1,9),(10,2,35),(11,15,82),(20,19,5);
          344  +  UPDATE t9 SET b=c WHERE a in (10,12,20);
          345  +  SELECT a,b,c,'|' FROM t9 ORDER BY a;
          346  +} {1 1 9 | 10 35 35 | 11 15 82 | 20 5 5 |}
          347  +
   329    348   
   330    349   finish_test