]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Add the logic to keep partial indices up to date through DML statements and
authordrh <drh@noemail.net>
Thu, 1 Aug 2013 01:14:43 +0000 (01:14 +0000)
committerdrh <drh@noemail.net>
Thu, 1 Aug 2013 01:14:43 +0000 (01:14 +0000)
when new partial indices are created.  This new logic is untested except to
verify that it does not interfere with full indices.

FossilOrigin-Name: fb9044d15ad4fd6ae4a38858c0c0e6fe9d4faa25

manifest
manifest.uuid
src/build.c
src/delete.c
src/expr.c
src/insert.c
src/pragma.c
src/sqliteInt.h
src/update.c
src/vdbeaux.c
src/where.c

index 71bc8d11ba1caf5eee3d8dc98dcad6c2ef98b88d..1e76bc8d3c2e48fcb9540b563b365e9663ec6bcc 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Add\slogic\sto\sthe\squery\splanner\sto\sonly\suse\spartial\sindices\sif\sthe\sWHERE\sclause\nconstrains\sthe\ssearch\sto\srows\scovered\sby\sthe\spartial\sindex.\s\sThis\sis\sjust\ninfrastructure.\s\sThe\skey\sroutine,\ssqlite3ExprImpliesExpr(),\sis\scurrently\sa\nno-op\sso\sthat\spartial\sindices\swill\snever\sbe\sused.
-D 2013-07-31T23:22:39.876
+C Add\sthe\slogic\sto\skeep\spartial\sindices\sup\sto\sdate\sthrough\sDML\sstatements\sand\nwhen\snew\spartial\sindices\sare\screated.\s\sThis\snew\slogic\sis\suntested\sexcept\sto\nverify\sthat\sit\sdoes\snot\sinterfere\swith\sfull\sindices.
+D 2013-08-01T01:14:43.210
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -166,13 +166,13 @@ F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7
 F src/btree.c 3f7bbfd72efb1cbf6a49515c376a031767ec930a
 F src/btree.h 6fa8a3ff2483d0bb64a9f0105a8cedeac9e00cca
 F src/btreeInt.h eecc84f02375b2bb7a44abbcbbe3747dde73edb2
-F src/build.c f1ef982f38df47b11e10edaf03fbcc77b80e4d35
+F src/build.c 9422ab5fe5f3ea21575b50c182ebf2081253bed0
 F src/callback.c d7e46f40c3cf53c43550b7da7a1d0479910b62cc
 F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
 F src/ctime.c 4262c227bc91cecc61ae37ed3a40f08069cfa267
 F src/date.c 067a81c9942c497aafd2c260e13add8a7d0c7dd4
-F src/delete.c aeabdabeeeaa0584127f291baa9617153d334778
-F src/expr.c 8a5e78f47c4919bd53c2ef3c652088d71d5c4d79
+F src/delete.c 2317c814866d9aa71fea16b3faf4fdd4d6a49b94
+F src/expr.c 299f1de324676599b818e587b77e683978514461
 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
 F src/fkey.c 914a6bbd987d857c41ac9d244efa6641f36faadb
 F src/func.c 5c50c1ea31fd864b0fe921fe1a8d4c55acd609ef
@@ -180,7 +180,7 @@ F src/global.c 5caf4deab621abb45b4c607aad1bd21c20aac759
 F src/hash.c ac3470bbf1ca4ae4e306a8ecb0fdf1731810ffe4
 F src/hash.h 8890a25af81fb85a9ad7790d32eedab4b994da22
 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08
-F src/insert.c f7cb141e8ce257cb6b15c497f09e4e23d6055599
+F src/insert.c 1e2eb1d4150c57f41dda8719f1b5ccb28abdacc2
 F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d
 F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12
 F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b
@@ -210,7 +210,7 @@ F src/parse.y a950b48d4363f44dd98fef8a89fbd48970ebd9ce
 F src/pcache.c f8043b433a57aba85384a531e3937a804432a346
 F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222
 F src/pcache1.c d23d07716de96c7c0c2503ec5051a4384c3fb938
-F src/pragma.c 2790c5175bc3f95d2a0cf39283d144b9b012fec7
+F src/pragma.c f8936b23ce3eeddff4ab868c726d1546a6674418
 F src/prepare.c fa6988589f39af8504a61731614cd4f6ae71554f
 F src/printf.c 41c49dac366a3a411190001a8ab495fa8887974e
 F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50
@@ -221,7 +221,7 @@ 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 911e2fe9bbd45c394e6396a1c00a8539285f82e6
+F src/sqliteInt.h b69d7bac8a7fea89f11558f0659324f0551b0868
 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
 F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158
 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
@@ -273,7 +273,7 @@ F src/test_vfstrace.c 34b544e80ba7fb77be15395a609c669df2e660a2
 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
 F src/tokenize.c e0e8fd3cb90a88451f6b6425726c84747b6b20d7
 F src/trigger.c 5c0ea9b8755e7c5e1a700f3e27ac4f8d92dd221e
-F src/update.c 8e76c3d03e4b7b21cb250bd2df0c05e12993e577
+F src/update.c 7f3fe64d8f3b44c44a1eac293f0f85f87c355b7a
 F src/utf.c 8d819e2e5104a430fc2005f018db14347c95a38f
 F src/util.c f566b5138099a2df8533b190d0dcc74b7dfbe0c9
 F src/vacuum.c d9c5759f4c5a438bb43c2086f72c5d2edabc36c8
@@ -281,7 +281,7 @@ F src/vdbe.c d6048a720c197db2f0e7d618e918bd2e2eff0322
 F src/vdbe.h f380af2a7fab32ba8a8b05bf042497636afec66d
 F src/vdbeInt.h e9b7c6b165a31a4715c5aa97223d20d265515231
 F src/vdbeapi.c 4d13580bd058b39623e8fcfc233b7df4b8191e8b
-F src/vdbeaux.c c01594ecf5a78ef41a721f3465152bb91883a942
+F src/vdbeaux.c 75206d58c2e1ea7ed2758106d591ff7a082ea909
 F src/vdbeblob.c 5dc79627775bd9a9b494dd956e26297946417d69
 F src/vdbemem.c 833005f1cbbf447289f1973dba2a0c2228c7b8ab
 F src/vdbesort.c 3937e06b2a0e354500e17dc206ef4c35770a5017
@@ -290,7 +290,7 @@ F src/vtab.c 2e8b489db47e20ae36cd247932dc671c9ded0624
 F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4
 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
 F src/walker.c 4fa43583d0a84b48f93b1e88f11adf2065be4e73
-F src/where.c afa338426730378f3d0aa9b24218462b6cca31f3
+F src/where.c 14d48fe735a7d5f4d610d8b9396a9e7752539199
 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
 F test/aggnested.test 45c0201e28045ad38a530b5a144b73cd4aa2cfd6
@@ -1104,7 +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 f2aa7842c8b9df24294f09e2bde27b3f08c455c7
-R 7502b7f00f8eb060c8cfe6d979c2a415
+P 8ca3eac111e06a1854f878a74bffe8f20eb47f1b
+R 9dc930e0b891070c4f237bde08c1f247
 U drh
-Z 8c5239fd3bb5391973b43192e175e4ae
+Z dd655b435ca4957c549da40144eccbfa
index d8663d417555d437508cc2b7ead80ba0bb396c1e..53ef0430bf10d520afa0b696eb453b630d4241e4 100644 (file)
@@ -1 +1 @@
-8ca3eac111e06a1854f878a74bffe8f20eb47f1b
\ No newline at end of file
+fb9044d15ad4fd6ae4a38858c0c0e6fe9d4faa25
\ No newline at end of file
index 61a1ae9e3caa9df16191d27eabecca8701ed4f5f..941bcb269f928135191e88805f951da420240189 100644 (file)
@@ -2374,6 +2374,7 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
   int addr1;                     /* Address of top of loop */
   int addr2;                     /* Address to jump to for next iteration */
   int tnum;                      /* Root page of index */
+  int iPartIdxLabel;             /* Jump to this label to skip a row */
   Vdbe *v;                       /* Generate code into this virtual machine */
   KeyInfo *pKey;                 /* KeyInfo for index */
   int regRecord;                 /* Register holding assemblied index record */
@@ -2413,8 +2414,9 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
   addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0);
   regRecord = sqlite3GetTempReg(pParse);
 
-  sqlite3GenerateIndexKey(pParse, pIndex, iTab, regRecord, 1);
+  sqlite3GenerateIndexKey(pParse, pIndex, iTab, regRecord, 1, &iPartIdxLabel);
   sqlite3VdbeAddOp2(v, OP_SorterInsert, iSorter, regRecord);
+  sqlite3VdbeResolveLabel(v, iPartIdxLabel);
   sqlite3VdbeAddOp2(v, OP_Next, iTab, addr1+1);
   sqlite3VdbeJumpHere(v, addr1);
   addr1 = sqlite3VdbeAddOp2(v, OP_SorterSort, iSorter, 0);
@@ -2843,7 +2845,7 @@ Index *sqlite3CreateIndex(
   ** has just been created, it contains no data and the index initialization
   ** step can be skipped.
   */
-  else{ /* if( db->init.busy==0 ) */
+  else if( pParse->nErr==0 ){
     Vdbe *v;
     char *zStmt;
     int iMem = ++pParse->nMem;
index 634e115563ae12ba6558ccc512aed631c066bad8..af64afc65cc082bf899e8e6ed8890d3ac3a1287d 100644 (file)
@@ -591,11 +591,14 @@ void sqlite3GenerateRowIndexDelete(
   int i;
   Index *pIdx;
   int r1;
+  int iPartIdxLabel;
+  Vdbe *v = pParse->pVdbe;
 
   for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
     if( aRegIdx!=0 && aRegIdx[i-1]==0 ) continue;
-    r1 = sqlite3GenerateIndexKey(pParse, pIdx, iCur, 0, 0);
-    sqlite3VdbeAddOp3(pParse->pVdbe, OP_IdxDelete, iCur+i, r1,pIdx->nColumn+1);
+    r1 = sqlite3GenerateIndexKey(pParse, pIdx, iCur, 0, 0, &iPartIdxLabel);
+    sqlite3VdbeAddOp3(v, OP_IdxDelete, iCur+i, r1, pIdx->nColumn+1);
+    sqlite3VdbeResolveLabel(v, iPartIdxLabel);
   }
 }
 
@@ -609,13 +612,21 @@ void sqlite3GenerateRowIndexDelete(
 ** registers that holds the elements of the index key.  The
 ** block of registers has already been deallocated by the time
 ** this routine returns.
+**
+** If *piPartIdxLabel is not NULL, fill it in with a label and jump
+** to that label if pIdx is a partial index that should be skipped.
+** A partial index should be skipped if its WHERE clause evaluates
+** to false or null.  If pIdx is not a partial index, *piPartIdxLabel
+** will be set to zero which is an empty label that is ignored by
+** sqlite3VdbeResolveLabel().
 */
 int sqlite3GenerateIndexKey(
-  Parse *pParse,     /* Parsing context */
-  Index *pIdx,       /* The index for which to generate a key */
-  int iCur,          /* Cursor number for the pIdx->pTable table */
-  int regOut,        /* Write the new index key to this register */
-  int doMakeRec      /* Run the OP_MakeRecord instruction if true */
+  Parse *pParse,       /* Parsing context */
+  Index *pIdx,         /* The index for which to generate a key */
+  int iCur,            /* Cursor number for the pIdx->pTable table */
+  int regOut,          /* Write the new index key to this register */
+  int doMakeRec,       /* Run the OP_MakeRecord instruction if true */
+  int *piPartIdxLabel  /* OUT: Jump to this label to skip partial index */
 ){
   Vdbe *v = pParse->pVdbe;
   int j;
@@ -623,6 +634,16 @@ int sqlite3GenerateIndexKey(
   int regBase;
   int nCol;
 
+  if( piPartIdxLabel ){
+    if( pIdx->pPartIdxWhere ){
+      *piPartIdxLabel = sqlite3VdbeMakeLabel(v);
+      pParse->iPartIdxTab = iCur;
+      sqlite3ExprIfFalse(pParse, pIdx->pPartIdxWhere, *piPartIdxLabel, 
+                         SQLITE_JUMPIFNULL);
+    }else{
+      *piPartIdxLabel = 0;
+    }
+  }
   nCol = pIdx->nColumn;
   regBase = sqlite3GetTempRange(pParse, nCol+1);
   sqlite3VdbeAddOp2(v, OP_Rowid, iCur, regBase+nCol);
index 03258c32c90753a50c83142c275317bd911536a8..96c05dc3ae3e68ab1d7c613a452d31dc7e32cf66 100644 (file)
@@ -2362,15 +2362,20 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
       /* Otherwise, fall thru into the TK_COLUMN case */
     }
     case TK_COLUMN: {
-      if( pExpr->iTable<0 ){
-        /* This only happens when coding check constraints */
-        assert( pParse->ckBase>0 );
-        inReg = pExpr->iColumn + pParse->ckBase;
-      }else{
-        inReg = sqlite3ExprCodeGetColumn(pParse, pExpr->pTab,
-                                 pExpr->iColumn, pExpr->iTable, target,
-                                 pExpr->op2);
+      int iTab = pExpr->iTable;
+      if( iTab<0 ){
+        if( pParse->ckBase>0 ){
+          /* Generating CHECK constraints or inserting into partial index */
+          inReg = pExpr->iColumn + pParse->ckBase;
+          break;
+        }else{
+          /* Deleting from a partial index */
+          iTab = pParse->iPartIdxTab;
+        }
       }
+      inReg = sqlite3ExprCodeGetColumn(pParse, pExpr->pTab,
+                               pExpr->iColumn, iTab, target,
+                               pExpr->op2);
       break;
     }
     case TK_INTEGER: {
index 9a5661f59a72952be6c167a0c2db159b91b71fae..099c07f8b8661e0ce7317b38bea6ff3553990ec3 100644 (file)
@@ -1379,9 +1379,19 @@ void sqlite3GenerateConstraintChecks(
   for(iCur=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, iCur++){
     int regIdx;
     int regR;
+    int addrSkipRow = 0;
 
     if( aRegIdx[iCur]==0 ) continue;  /* Skip unused indices */
 
+    if( pIdx->pPartIdxWhere ){
+      sqlite3VdbeAddOp2(v, OP_Null, 0, aRegIdx[iCur]);
+      addrSkipRow = sqlite3VdbeMakeLabel(v);
+      pParse->ckBase = regData;
+      sqlite3ExprIfFalse(pParse, pIdx->pPartIdxWhere, addrSkipRow,
+                         SQLITE_JUMPIFNULL);
+      pParse->ckBase = 0;
+    }
+
     /* Create a key for accessing the index entry */
     regIdx = sqlite3GetTempRange(pParse, pIdx->nColumn+1);
     for(i=0; i<pIdx->nColumn; i++){
@@ -1470,6 +1480,7 @@ void sqlite3GenerateConstraintChecks(
       }
     }
     sqlite3VdbeJumpHere(v, j3);
+    sqlite3VdbeResolveLabel(v, addrSkipRow);
     sqlite3ReleaseTempReg(pParse, regR);
   }
   
@@ -1499,7 +1510,6 @@ void sqlite3CompleteInsertion(
 ){
   int i;
   Vdbe *v;
-  int nIdx;
   Index *pIdx;
   u8 pik_flags;
   int regData;
@@ -1508,9 +1518,11 @@ void sqlite3CompleteInsertion(
   v = sqlite3GetVdbe(pParse);
   assert( v!=0 );
   assert( pTab->pSelect==0 );  /* This table is not a VIEW */
-  for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){}
-  for(i=nIdx-1; i>=0; i--){
+  for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
     if( aRegIdx[i]==0 ) continue;
+    if( pIdx->pPartIdxWhere ){
+      sqlite3VdbeAddOp2(v, OP_IsNull, aRegIdx[i], sqlite3VdbeCurrentAddr(v)+2);
+    }
     sqlite3VdbeAddOp2(v, OP_IdxInsert, baseCur+i+1, aRegIdx[i]);
     if( useSeekResult ){
       sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
@@ -1612,6 +1624,7 @@ static int xferCompatibleCollation(const char *z1, const char *z2){
 **    *   The same DESC and ASC markings occurs on all columns
 **    *   The same onError processing (OE_Abort, OE_Ignore, etc)
 **    *   The same collating sequence on each column
+**    *   The index has the exact same WHERE clause
 */
 static int xferCompatibleIndex(Index *pDest, Index *pSrc){
   int i;
@@ -1634,6 +1647,9 @@ static int xferCompatibleIndex(Index *pDest, Index *pSrc){
       return 0;   /* Different collating sequences */
     }
   }
+  if( sqlite3ExprCompare(pSrc->pPartIdxWhere, pDest->pPartIdxWhere) ){
+    return 0;     /* Different WHERE clauses */
+  }
 
   /* If no test above fails then the indices must be compatible */
   return 1;
index 9bbbfa8aa1e296bbad51982ebb313373befbce8e..fcbd614fb358e89ba9db1130c20a0273154b296b 100644 (file)
@@ -1432,7 +1432,7 @@ void sqlite3Pragma(
         loopTop = sqlite3VdbeAddOp2(v, OP_Rewind, 1, 0);
         sqlite3VdbeAddOp2(v, OP_AddImm, 2, 1);   /* increment entry count */
         for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
-          int jmp2;
+          int jmp2, jmp3;
           int r1;
           static const VdbeOpList idxErr[] = {
             { OP_AddImm,      1, -1,  0},
@@ -1447,7 +1447,7 @@ void sqlite3Pragma(
             { OP_IfPos,       1,  0,  0},    /* 9 */
             { OP_Halt,        0,  0,  0},
           };
-          r1 = sqlite3GenerateIndexKey(pParse, pIdx, 1, 3, 0);
+          r1 = sqlite3GenerateIndexKey(pParse, pIdx, 1, 3, 0, &jmp3);
           jmp2 = sqlite3VdbeAddOp4Int(v, OP_Found, j+2, 0, r1, pIdx->nColumn+1);
           addr = sqlite3VdbeAddOpList(v, ArraySize(idxErr), idxErr);
           sqlite3VdbeChangeP4(v, addr+1, "rowid ", P4_STATIC);
@@ -1455,6 +1455,7 @@ void sqlite3Pragma(
           sqlite3VdbeChangeP4(v, addr+4, pIdx->zName, P4_TRANSIENT);
           sqlite3VdbeJumpHere(v, addr+9);
           sqlite3VdbeJumpHere(v, jmp2);
+          sqlite3VdbeResolveLabel(v, jmp3);
         }
         sqlite3VdbeAddOp2(v, OP_Next, 1, loopTop+1);
         sqlite3VdbeJumpHere(v, loopTop);
index 9d5580f9281446340db79b2575a7c383bb0e4e41..206c8a0300873ce1670c4cceceec2e6f1b664305 100644 (file)
@@ -2204,6 +2204,7 @@ struct Parse {
   int nSet;            /* Number of sets used so far */
   int nOnce;           /* Number of OP_Once instructions so far */
   int ckBase;          /* Base register of data during check constraints */
+  int iPartIdxTab;     /* Table corresponding to a partial index */
   int iCacheLevel;     /* ColCache valid when aColCache[].iLevel<=iCacheLevel */
   int iCacheCnt;       /* Counter used to generate aColCache[].lru values */
   struct yColCache {
@@ -2862,7 +2863,7 @@ int sqlite3ExprNeedsNoAffinityChange(const Expr*, char);
 int sqlite3IsRowid(const char*);
 void sqlite3GenerateRowDelete(Parse*, Table*, int, int, int, Trigger *, int);
 void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int*);
-int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int);
+int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int, int*);
 void sqlite3GenerateConstraintChecks(Parse*,Table*,int,int,
                                      int*,int,int,int,int,int*);
 void sqlite3CompleteInsertion(Parse*, Table*, int, int, int*, int, int, int);
index 5b18ebd6bf35d79e6e79eae3e7460593d902f2f0..4fbefc3b5956fcba914e73b274ca9590769803f7 100644 (file)
@@ -246,7 +246,7 @@ void sqlite3Update(
   }
   for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
     int reg;
-    if( hasFK || chngRowid ){
+    if( hasFK || chngRowid || pIdx->pPartIdxWhere ){
       reg = ++pParse->nMem;
     }else{
       reg = 0;
index f54685cb71e120607f6e794d5d8db7e4df7fcafc..e970d5ff6daebfcbd87e33df2413c4abc81f20dc 100644 (file)
@@ -250,8 +250,8 @@ int sqlite3VdbeMakeLabel(Vdbe *p){
 void sqlite3VdbeResolveLabel(Vdbe *p, int x){
   int j = -1-x;
   assert( p->magic==VDBE_MAGIC_INIT );
-  assert( j>=0 && j<p->nLabel );
-  if( p->aLabel ){
+  assert( j<p->nLabel );
+  if( j>=0 && p->aLabel ){
     p->aLabel[j] = p->nOp;
   }
 }
index 315c4035cb4830d96df349b4d9effeae68d90215..fd7efd64780d036861c6092b037095a46ce4fd74 100644 (file)
@@ -2235,7 +2235,7 @@ static void constructAutomaticIndex(
   /* Fill the automatic index with content */
   addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, pLevel->iTabCur);
   regRecord = sqlite3GetTempReg(pParse);
-  sqlite3GenerateIndexKey(pParse, pIdx, pLevel->iTabCur, regRecord, 1);
+  sqlite3GenerateIndexKey(pParse, pIdx, pLevel->iTabCur, regRecord, 1, 0);
   sqlite3VdbeAddOp2(v, OP_IdxInsert, pLevel->iIdxCur, regRecord);
   sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
   sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1);