]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Moving UPDATE towards the iDataCur/iIdxCur representation. Still not working
authordrh <drh@noemail.net>
Thu, 31 Oct 2013 12:13:37 +0000 (12:13 +0000)
committerdrh <drh@noemail.net>
Thu, 31 Oct 2013 12:13:37 +0000 (12:13 +0000)
for WITHOUT ROWID, though.

FossilOrigin-Name: deacbd21b50cc8c63a1572d14a4bbc7af4052d37

manifest
manifest.uuid
src/insert.c
src/sqliteInt.h
src/update.c

index 5e03b35ba4db237dc72284793688049d49a2ce65..0c22692110ae414b910ffb428ddddead2c020c80 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Refactor\sthe\sINSERT,\sDELETE,\sand\sUPDATE\scode\sgenerators\sto\sdistinguish\sbetween\nthe\s"data\scursor"\sand\sthe\s"first\sindex\scursor",\swhich\sare\sno\slonger\sconsecutive\nin\sthe\scase\sof\sa\sWITHOUT\sROWID\stable.
-D 2013-10-31T11:15:09.631
+C Moving\sUPDATE\stowards\sthe\siDataCur/iIdxCur\srepresentation.\s\sStill\snot\sworking\nfor\sWITHOUT\sROWID,\sthough.
+D 2013-10-31T12:13:37.732
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in 0522b53cdc1fcfc18f3a98e0246add129136c654
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -182,7 +182,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 076f600e99cd49ce4509bcff3e0620df0fdcf46d
+F src/insert.c e8f0691953194cf1df85b463fed8b75b0dedf7d9
 F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d
 F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12
 F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b
@@ -223,7 +223,7 @@ F src/shell.c d5eebdc6034014103de2b9d58e1d3f6f7de0fb50
 F src/sqlite.h.in 547a44dd4ff4d975e92a645ea2d609e543a83d0f
 F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e
 F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc
-F src/sqliteInt.h c41205f31edb0c803a7b1bad92fe91d552a9eec7
+F src/sqliteInt.h 41c5b67e6c946ae1e95a4b32f9a077c36774e0bb
 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
 F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158
 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
@@ -275,7 +275,7 @@ F src/test_vfstrace.c 34b544e80ba7fb77be15395a609c669df2e660a2
 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
 F src/tokenize.c 70061085a51f2f4fc15ece94f32c03bcb78e63b2
 F src/trigger.c 53d6b5d50b3b23d4fcd0a36504feb5cff9aed716
-F src/update.c 3be9af558558062d335e35acb13f7507f053ff76
+F src/update.c 3cabfcbd3e40e9c025fe772cf172ce24b6d53c45
 F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269
 F src/util.c 2fa6c821d28bbdbeec1b2a7b091a281c9ef8f918
 F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179
@@ -1128,7 +1128,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381
 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01
 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff
-P 0d4fea7462c0f61cd1c736cbcd7bea5ec2034d54
-R 5cee3ee2f21ff3dcfee1d1450366398f
+P 1adfca6019847d37dee4a297669f29d5ca184066
+R 925135441c339dd20ca1becb38d6fbf2
 U drh
-Z 8325d71a27ada5d7265b86dd95f46d5a
+Z 72a84fe0a8232f3d99ba9db66435b958
index cf92754a40583078f16c5e1ae097899814562a05..00f527cef5f3e6da58066757dc110b606d74b09f 100644 (file)
@@ -1 +1 @@
-1adfca6019847d37dee4a297669f29d5ca184066
\ No newline at end of file
+deacbd21b50cc8c63a1572d14a4bbc7af4052d37
\ No newline at end of file
index 66f3f568705a6b5b8c89887303bba11d18b1bf54..d58a9baea9955b759055276101032259de9e398a 100644 (file)
@@ -1122,41 +1122,6 @@ insert_cleanup:
  #undef tmask
 #endif
 
-/*
-** Locate the "principle btree" for a table.  This is the table itself for
-** ordinary tables, but for WITHOUT ROWID tables, the principle btree is the
-** PRIMARY KEY index.
-**
-** Inputs are pTab and baseCur.  The *ppPk is written with a pointer to the
-** PRIMARY KEY index for WITHOUT ROWID tables or with NULL for ordinary
-** tables.  The *piPkCur is written with the cursor to use, assuming that the
-** table cursor is baseCur and that index cursors are consecutively numbered
-** thereafter.
-*/
-void sqlite3PrincipleBtree(
-  Table *pTab,        /* The main Table object */
-  int baseCur,        /* VDBE cursor for main table. */
-  Index **ppPk,       /* Write PRIMARY KEY index of WITHOUT ROWID tables here */
-  int *piPkCur        /* Either baseCur or the cursor for *ppPk */
-){
-  int pkCur;
-  Index *pPk;
-  if( !HasRowid(pTab) ){
-    pkCur = baseCur+1;
-    pPk = pTab->pIndex;
-    while( ALWAYS(pPk) && pPk->autoIndex!=2 ){
-      pPk=pPk->pNext;
-      pkCur++;
-    }
-  }else{
-    pkCur = baseCur;
-    pPk = 0;
-  }
-  *ppPk = pPk;
-  *piPkCur = pkCur;
-}
-
-
 /*
 ** Generate code to do constraint checks prior to an INSERT or an UPDATE.
 **
index e4c68a0de9119fae8f1ad5c0841911ec62181119..8dd9b15fccca3566b7db6fcd7565f40b568d7322 100644 (file)
@@ -2922,7 +2922,6 @@ int sqlite3IsRowid(const char*);
 void sqlite3GenerateRowDelete(Parse*,Table*,Trigger*,int,int,int,i16,u8,u8);
 void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int, int*);
 int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int, int*);
-void sqlite3PrincipleBtree(Table*,int,Index**,int*);
 void sqlite3GenerateConstraintChecks(Parse*,Table*,int,int,int,
                                      int*,int,int,int,int,int*);
 void sqlite3CompleteInsertion(Parse*,Table*,int,int,int,int*,int,int,int);
index db300bd2af7ecbbb14667271efdc57ab5787467a..5c92f6fd69d99d6bfc7ee2bf36c7b028e0e5934e 100644 (file)
@@ -101,14 +101,15 @@ void sqlite3Update(
   Index *pIdx;           /* For looping over indices */
   Index *pPk;            /* The PRIMARY KEY index for WITHOUT ROWID tables */
   int nIdx;              /* Number of indices that need updating */
-  int iCur;              /* VDBE Cursor number of pTab */
-  int pkCur;             /* VDBE Cursor for the pPk index */
+  int iTabCur;           /* VDBE Cursor number of pTab */
+  int iDataCur;          /* Cursor for the canonical data btree */
+  int iIdxCur;           /* Cursor for the first index */
   sqlite3 *db;           /* The database structure */
   int *aRegIdx = 0;      /* One register assigned to each index to be updated */
   int *aXRef = 0;        /* aXRef[i] is the index in pChanges->a[] of the
                          ** an expression for the i-th column of the table.
                          ** aXRef[i]==-1 if the i-th column is not changed. */
-  int chngRowid;         /* True if the record number is being changed */
+  int chngPk;            /* True if the rowid or PRIMARY KEY is changed */
   Expr *pRowidExpr = 0;  /* Expression defining the new record number */
   int openAll = 0;       /* True if all indices need to be opened */
   AuthContext sContext;  /* The authorization context */
@@ -181,15 +182,14 @@ void sqlite3Update(
   ** need to occur right after the database cursor.  So go ahead and
   ** allocate enough space, just in case.
   */
-  pTabList->a[0].iCursor = iCur = pParse->nTab++;
-  for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
+  pTabList->a[0].iCursor = iTabCur = iDataCur = pParse->nTab++;
+  iIdxCur = iTabCur+1;
+  pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab);
+  for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){
+    if( pIdx->autoIndex==2 && pPk!=0 ) iDataCur = pParse->nTab;
     pParse->nTab++;
   }
 
-  /* For WITHOUT ROWID tables, we'll need to know the Index and the cursor
-  ** number for the PRIMARY KEY index */
-  sqlite3PrincipleBtree(pTab, iCur, &pPk, &pkCur);
-
   /* Initialize the name-context */
   memset(&sNC, 0, sizeof(sNC));
   sNC.pParse = pParse;
@@ -201,7 +201,7 @@ void sqlite3Update(
   ** column to be updated, make sure we have authorization to change
   ** that column.
   */
-  chngRowid = 0;
+  chngPk = 0;
   for(i=0; i<pChanges->nExpr; i++){
     if( sqlite3ResolveExprNames(&sNC, pChanges->a[i].pExpr) ){
       goto update_cleanup;
@@ -209,8 +209,10 @@ void sqlite3Update(
     for(j=0; j<pTab->nCol; j++){
       if( sqlite3StrICmp(pTab->aCol[j].zName, pChanges->a[i].zName)==0 ){
         if( j==pTab->iPKey ){
-          chngRowid = 1;
+          chngPk = 1;
           pRowidExpr = pChanges->a[i].pExpr;
+        }else if( pPk && (pTab->aCol[j].colFlags & COLFLAG_PRIMKEY)!=0 ){
+          chngPk = 1;
         }
         aXRef[j] = i;
         break;
@@ -219,7 +221,7 @@ void sqlite3Update(
     if( j>=pTab->nCol ){
       if( pPk==0 && sqlite3IsRowid(pChanges->a[i].zName) ){
         j = -1;
-        chngRowid = 1;
+        chngPk = 1;
         pRowidExpr = pChanges->a[i].pExpr;
       }else{
         sqlite3ErrorMsg(pParse, "no such column: %s", pChanges->a[i].zName);
@@ -242,21 +244,20 @@ void sqlite3Update(
 #endif
   }
 
-  hasFK = sqlite3FkRequired(pParse, pTab, aXRef, chngRowid);
+  hasFK = sqlite3FkRequired(pParse, pTab, aXRef, chngPk);
 
   /* Allocate memory for the array aRegIdx[].  There is one entry in the
   ** array for each index associated with table being updated.  Fill in
   ** the value with a register number for indices that are to be used
   ** and with zero for unused indices.
   */
-  for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){}
   if( nIdx>0 ){
     aRegIdx = sqlite3DbMallocRaw(db, sizeof(Index*) * nIdx );
     if( aRegIdx==0 ) goto update_cleanup;
   }
   for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
     int reg;
-    if( hasFK || chngRowid || pIdx->pPartIdxWhere ){
+    if( hasFK || chngPk || pIdx->pPartIdxWhere ){
       reg = ++pParse->nMem;
     }else{
       reg = 0;
@@ -294,7 +295,7 @@ void sqlite3Update(
     regOld = pParse->nMem + 1;
     pParse->nMem += pTab->nCol;
   }
-  if( chngRowid || pTrigger || hasFK ){
+  if( chngPk || pTrigger || hasFK ){
     regNewRowid = ++pParse->nMem;
   }
   regNew = pParse->nMem + 1;
@@ -310,7 +311,7 @@ void sqlite3Update(
   */
 #if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER)
   if( isView ){
-    sqlite3MaterializeView(pParse, pTab, pWhere, iCur);
+    sqlite3MaterializeView(pParse, pTab, pWhere, iTabCur);
   }
 #endif
 
@@ -333,7 +334,7 @@ void sqlite3Update(
   
     /* Remember the rowid of every item to be updated.
     */
-    sqlite3VdbeAddOp2(v, OP_Rowid, iCur, regOldRowid);
+    sqlite3VdbeAddOp2(v, OP_Rowid, iTabCur, regOldRowid);
     if( !okOnePass ){
       sqlite3VdbeAddOp2(v, OP_RowSetAdd, regRowSet, regOldRowid);
     }
@@ -357,7 +358,8 @@ void sqlite3Update(
     pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0, 0, 0);
     if( pWInfo==0 ) goto update_cleanup;
     for(i=0; i<nPk; i++){
-      sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, pPk->aiColumn[i], iPk+i);
+      sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, pPk->aiColumn[i],
+                                      iPk+i);
     }
     sqlite3VdbeAddOp4(v, OP_MakeRecord, iPk, nPk, regKey,
                       sqlite3IndexAffinityStr(v, pPk), P4_TRANSIENT);
@@ -381,7 +383,7 @@ void sqlite3Update(
     ** to be deleting some records.
     */
     if( !okOnePass && HasRowid(pTab) ){
-      sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenWrite); 
+      sqlite3OpenTable(pParse, iTabCur, iDb, pTab, OP_OpenWrite); 
     }
     if( onError==OE_Replace ){
       openAll = 1;
@@ -398,9 +400,9 @@ void sqlite3Update(
       assert( aRegIdx );
       if( openAll || aRegIdx[i]>0 ){
         KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx);
-        sqlite3VdbeAddOp4(v, OP_OpenWrite, iCur+i+1, pIdx->tnum, iDb,
+        sqlite3VdbeAddOp4(v, OP_OpenWrite, iIdxCur+i, pIdx->tnum, iDb,
                        (char*)pKey, P4_KEYINFO_HANDOFF);
-        assert( pParse->nTab>iCur+i+1 );
+        assert( pParse->nTab>iIdxCur+i );
       }
     }
   }
@@ -419,15 +421,15 @@ void sqlite3Update(
   }else{
     addr = sqlite3VdbeAddOp3(v, OP_RowSetRead, regRowSet, labelBreak,
                              regOldRowid);
-    sqlite3VdbeAddOp3(v, OP_NotExists, iCur, addr, regOldRowid);
+    sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, addr, regOldRowid);
   }
 
   /* If the record number will change, set register regNewRowid to
   ** contain the new value. If the record number is not being modified,
   ** then regNewRowid is the same register as regOldRowid, which is
   ** already populated.  */
-  assert( chngRowid || pTrigger || hasFK || regOldRowid==regNewRowid );
-  if( chngRowid ){
+  assert( chngPk || pTrigger || hasFK || regOldRowid==regNewRowid );
+  if( chngPk ){
     sqlite3ExprCode(pParse, pRowidExpr, regNewRowid);
     sqlite3VdbeAddOp1(v, OP_MustBeInt, regNewRowid);
   }
@@ -441,12 +443,12 @@ void sqlite3Update(
     );
     for(i=0; i<pTab->nCol; i++){
       if( aXRef[i]<0 || oldmask==0xffffffff || (i<32 && (oldmask & (1<<i))) ){
-        sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, i, regOld+i);
+        sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, i, regOld+i);
       }else{
         sqlite3VdbeAddOp2(v, OP_Null, 0, regOld+i);
       }
     }
-    if( chngRowid==0 ){
+    if( chngPk==0 ){
       sqlite3VdbeAddOp2(v, OP_Copy, regOldRowid, regNewRowid);
     }
   }
@@ -483,7 +485,7 @@ void sqlite3Update(
         */
         testcase( i==31 );
         testcase( i==32 );
-        sqlite3VdbeAddOp3(v, OP_Column, iCur, i, regNew+i);
+        sqlite3VdbeAddOp3(v, OP_Column, iDataCur, i, regNew+i);
         sqlite3ColumnDefault(v, pTab, i, regNew+i);
       }
     }
@@ -504,7 +506,7 @@ void sqlite3Update(
     ** is deleted or renamed by a BEFORE trigger - is left undefined in the
     ** documentation.
     */
-    sqlite3VdbeAddOp3(v, OP_NotExists, iCur, addr, regOldRowid);
+    sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, addr, regOldRowid);
 
     /* If it did not delete it, the row-trigger may still have modified 
     ** some of the columns of the row being updated. Load the values for 
@@ -513,7 +515,7 @@ void sqlite3Update(
     */
     for(i=0; i<pTab->nCol; i++){
       if( aXRef[i]<0 && i!=pTab->iPKey ){
-        sqlite3VdbeAddOp3(v, OP_Column, iCur, i, regNew+i);
+        sqlite3VdbeAddOp3(v, OP_Column, iDataCur, i, regNew+i);
         sqlite3ColumnDefault(v, pTab, i, regNew+i);
       }
     }
@@ -523,41 +525,41 @@ void sqlite3Update(
     int j1;                       /* Address of jump instruction */
 
     /* Do constraint checks. */
-    sqlite3GenerateConstraintChecks(pParse, pTab, iCur, iCur+1, regNewRowid,
-        aRegIdx, (chngRowid?regOldRowid:0), 1, onError, addr, 0);
+    sqlite3GenerateConstraintChecks(pParse, pTab, iDataCur, iIdxCur,
+        regNewRowid, aRegIdx, (chngPk?regOldRowid:0), 1, onError, addr, 0);
 
     /* Do FK constraint checks. */
     if( hasFK ){
-      sqlite3FkCheck(pParse, pTab, regOldRowid, 0, aXRef, chngRowid);
+      sqlite3FkCheck(pParse, pTab, regOldRowid, 0, aXRef, chngPk);
     }
 
     /* Delete the index entries associated with the current record.  */
     if( pPk ){
-      j1 = sqlite3VdbeAddOp4Int(v, OP_NotFound, pkCur, 0, regOldRowid, 1);
+      j1 = sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, 0, regOldRowid, 1);
     }else{
-      j1 = sqlite3VdbeAddOp3(v, OP_NotExists, iCur, 0, regOldRowid);
-      sqlite3GenerateRowIndexDelete(pParse, pTab, pkCur, iCur+1, aRegIdx);
+      j1 = sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, 0, regOldRowid);
+      sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur, aRegIdx);
     }
   
     /* If changing the record number, delete the old record.  */
-    if( hasFK || chngRowid ){
-      sqlite3VdbeAddOp2(v, OP_Delete, iCur, 0);
+    if( hasFK || chngPk ){
+      sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, 0);
     }
     sqlite3VdbeJumpHere(v, j1);
 
     if( hasFK ){
-      sqlite3FkCheck(pParse, pTab, 0, regNewRowid, aXRef, chngRowid);
+      sqlite3FkCheck(pParse, pTab, 0, regNewRowid, aXRef, chngPk);
     }
   
     /* Insert the new index entries and the new record. */
-    sqlite3CompleteInsertion(pParse, pTab, iCur, iCur+1,
+    sqlite3CompleteInsertion(pParse, pTab, iDataCur, iIdxCur,
                              regNewRowid, aRegIdx, 1, 0, 0);
 
     /* Do any ON CASCADE, SET NULL or SET DEFAULT operations required to
     ** handle rows (possibly in other tables) that refer via a foreign key
     ** to the row just updated. */ 
     if( hasFK ){
-      sqlite3FkActions(pParse, pTab, pChanges, regOldRowid, aXRef, chngRowid);
+      sqlite3FkActions(pParse, pTab, pChanges, regOldRowid, aXRef, chngPk);
     }
   }
 
@@ -585,10 +587,10 @@ void sqlite3Update(
   for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
     assert( aRegIdx );
     if( openAll || aRegIdx[i]>0 ){
-      sqlite3VdbeAddOp2(v, OP_Close, iCur+i+1, 0);
+      sqlite3VdbeAddOp2(v, OP_Close, iIdxCur, 0);
     }
   }
-  sqlite3VdbeAddOp2(v, OP_Close, iCur, 0);
+  if( iDataCur<iIdxCur ) sqlite3VdbeAddOp2(v, OP_Close, iDataCur, 0);
 
   /* Update the sqlite_sequence table by storing the content of the
   ** maximum rowid counter values recorded while inserting into