SQLite

Check-in [e63d01c69c]
Login

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
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: e63d01c69c3e50f49ee3022a519c4f3e91f00520
User & Date: drh 2015-06-11 13:58:35.248
Context
2015-06-11
14:19
Remove stray outputs from the test suite. (check-in: afc6db9b10 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: e63d01c69c user: drh tags: trunk)
2015-06-10
22:03
Fix minor typo in the quicktest MSVC makefile target. (check-in: 75b65f9d49 user: mistachkin tags: trunk)
Changes
Side-by-Side Diff Ignore Whitespace Patch
Changes to src/delete.c.
794
795
796
797
798
799
800
801
802


803
804
805
806
807
808
809
794
795
796
797
798
799
800


801
802
803
804
805
806
807
808
809







-
-
+
+







  int nCol;

  if( piPartIdxLabel ){
    if( pIdx->pPartIdxWhere ){
      *piPartIdxLabel = sqlite3VdbeMakeLabel(v);
      pParse->iPartIdxTab = iDataCur;
      sqlite3ExprCachePush(pParse);
      sqlite3ExprIfFalse(pParse, pIdx->pPartIdxWhere, *piPartIdxLabel, 
                         SQLITE_JUMPIFNULL);
      sqlite3ExprIfFalseDup(pParse, pIdx->pPartIdxWhere, *piPartIdxLabel, 
                            SQLITE_JUMPIFNULL);
    }else{
      *piPartIdxLabel = 0;
    }
  }
  nCol = (prefixOnly && pIdx->uniqNotNull) ? pIdx->nKeyCol : pIdx->nColumn;
  regBase = sqlite3GetTempRange(pParse, nCol);
  if( pPrior && (regBase!=regPrior || pPrior->pPartIdxWhere) ) pPrior = 0;
Changes to src/expr.c.
3697
3698
3699
3700
3701
3702
3703















3704
3705
3706
3707
3708
3709
3710
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







      }
      break;
    }
  }
  sqlite3ReleaseTempReg(pParse, regFree1);
  sqlite3ReleaseTempReg(pParse, regFree2);
}

/*
** Like sqlite3ExprIfFalse() except that a copy is made of pExpr before
** code generation, and that copy is deleted after code generation. This
** ensures that the original pExpr is unchanged.
*/
void sqlite3ExprIfFalseDup(Parse *pParse, Expr *pExpr, int dest,int jumpIfNull){
  sqlite3 *db = pParse->db;
  Expr *pCopy = sqlite3ExprDup(db, pExpr, 0);
  if( db->mallocFailed==0 ){
    sqlite3ExprIfFalse(pParse, pCopy, dest, jumpIfNull);
  }
  sqlite3ExprDelete(db, pCopy);
}


/*
** Do a deep comparison of two expression trees.  Return 0 if the two
** expressions are completely identical.  Return 1 if they differ only
** by a COLLATE operator at the top level.  Return 2 if there are differences
** other than the top-level COLLATE operator.
**
Changes to src/insert.c.
1377
1378
1379
1380
1381
1382
1383
1384
1385


1386
1387
1388
1389
1390
1391
1392
1377
1378
1379
1380
1381
1382
1383


1384
1385
1386
1387
1388
1389
1390
1391
1392







-
-
+
+







    iThisCur = iIdxCur+ix;
    addrUniqueOk = sqlite3VdbeMakeLabel(v);

    /* Skip partial indices for which the WHERE clause is not true */
    if( pIdx->pPartIdxWhere ){
      sqlite3VdbeAddOp2(v, OP_Null, 0, aRegIdx[ix]);
      pParse->ckBase = regNewData+1;
      sqlite3ExprIfFalse(pParse, pIdx->pPartIdxWhere, addrUniqueOk,
                         SQLITE_JUMPIFNULL);
      sqlite3ExprIfFalseDup(pParse, pIdx->pPartIdxWhere, addrUniqueOk,
                            SQLITE_JUMPIFNULL);
      pParse->ckBase = 0;
    }

    /* Create a record for this index entry as it should appear after
    ** the insert or update.  Store that record in the aRegIdx[ix] register
    */
    regIdx = sqlite3GetTempRange(pParse, pIdx->nColumn);
Changes to src/sqliteInt.h.
3322
3323
3324
3325
3326
3327
3328

3329
3330
3331
3332
3333
3334
3335
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336







+







int sqlite3ExprCodeTarget(Parse*, Expr*, int);
void sqlite3ExprCodeAndCache(Parse*, Expr*, int);
int sqlite3ExprCodeExprList(Parse*, ExprList*, int, u8);
#define SQLITE_ECEL_DUP      0x01  /* Deep, not shallow copies */
#define SQLITE_ECEL_FACTOR   0x02  /* Factor out constant terms */
void sqlite3ExprIfTrue(Parse*, Expr*, int, int);
void sqlite3ExprIfFalse(Parse*, Expr*, int, int);
void sqlite3ExprIfFalseDup(Parse*, Expr*, int, int);
Table *sqlite3FindTable(sqlite3*,const char*, const char*);
Table *sqlite3LocateTable(Parse*,int isView,const char*, const char*);
Table *sqlite3LocateTableItem(Parse*,int isView,struct SrcList_item *);
Index *sqlite3FindIndex(sqlite3*,const char*, const char*);
void sqlite3UnlinkAndDeleteTable(sqlite3*,int,const char*);
void sqlite3UnlinkAndDeleteIndex(sqlite3*,int,const char*);
void sqlite3Vacuum(Parse*);
Changes to test/index6.test.
322
323
324
325
326
327
328



















329
330
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+


do_execsql_test index6-8.2 {
  SELECT * FROM t8a LEFT JOIN t8b ON (x = 'value' AND y = a)
} {
  1 one value 1 
  2 two {} {} 
  3 three value 3
}

# 2015-06-11.  Assertion fault found by AFL
#
do_execsql_test index6-9.1 {
  CREATE TABLE t9(a int, b int, c int);
  CREATE INDEX t9ca ON t9(c,a) WHERE a in (10,12,20);
  INSERT INTO t9 VALUES(1,1,9),(10,2,35),(11,15,82),(20,19,5),(NULL,7,3);
  UPDATE t9 SET b=c WHERE a in (10,12,20);
  SELECT a,b,c,'|' FROM t9 ORDER BY a;
} {{} 7 3 | 1 1 9 | 10 35 35 | 11 15 82 | 20 5 5 |}
do_execsql_test index6-9.2 {
  DROP TABLE t9;
  CREATE TABLE t9(a int, b int, c int, PRIMARY KEY(a)) WITHOUT ROWID;
  CREATE INDEX t9ca ON t9(c,a) WHERE a in (10,12,20);
  INSERT INTO t9 VALUES(1,1,9),(10,2,35),(11,15,82),(20,19,5);
  UPDATE t9 SET b=c WHERE a in (10,12,20);
  SELECT a,b,c,'|' FROM t9 ORDER BY a;
} {1 1 9 | 10 35 35 | 11 15 82 | 20 5 5 |}


finish_test