]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Replace the OP_IsUnique opcode with OP_NoConflict. This code simplification
authordrh <drh@noemail.net>
Sat, 26 Oct 2013 13:36:51 +0000 (13:36 +0000)
committerdrh <drh@noemail.net>
Sat, 26 Oct 2013 13:36:51 +0000 (13:36 +0000)
might be useful to move onto trunk even if this branch is never merged.

FossilOrigin-Name: e6650e16dd11327afd25961b2feb29ec8778c2ca

manifest
manifest.uuid
src/insert.c
src/sqliteInt.h
src/vdbe.c
src/vdbeaux.c

index b264809eda85b4735a55cd90929eee6b1f6d7d5f..c8331f4e7f29073402e2c3bd1b1d9f455a352126 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Minor\srefactoring\sof\svariable\snames\sand\sfixes\sto\scomments\sin\sinsert.c.
-D 2013-10-26T00:58:34.188
+C Replace\sthe\sOP_IsUnique\sopcode\swith\sOP_NoConflict.\s\sThis\scode\ssimplification\nmight\sbe\suseful\sto\smove\sonto\strunk\seven\sif\sthis\sbranch\sis\snever\smerged.
+D 2013-10-26T13:36:51.811
 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 684154a70880e8a8b6f390227440db336ae6172c
+F src/insert.c e87728415d32d6f572f5578c2107e382d1dd8203
 F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d
 F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12
 F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b
@@ -223,7 +223,7 @@ F src/shell.c 6f11f0e9ded63d48e306f2c6858c521e568a47bb
 F src/sqlite.h.in 547a44dd4ff4d975e92a645ea2d609e543a83d0f
 F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e
 F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc
-F src/sqliteInt.h 674cee6761771e7c1d6446671fcf7daf27b4c0f7
+F src/sqliteInt.h 2653257af49bf87af81d7c35899297043f10879a
 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
 F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158
 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
@@ -279,11 +279,11 @@ F src/update.c e39378bc5ed0c42e80624229703e59b5c7a4d50a
 F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269
 F src/util.c 2fa6c821d28bbdbeec1b2a7b091a281c9ef8f918
 F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179
-F src/vdbe.c f7a2fb5d707db64f59ebb2d054485790350f84db
+F src/vdbe.c 115f2c06e4d943d289599a46634514bf94479db4
 F src/vdbe.h 4f554b5627f26710c4c36d919110a3fc611ca5c4
 F src/vdbeInt.h ff57f67aee1ba26a3a47e786533dab155ab6dad6
 F src/vdbeapi.c 93a22a9ba2abe292d5c2cf304d7eb2e894dde0ed
-F src/vdbeaux.c 6d59c132174a7e9152f0ca2db8f0f3ec97ef199b
+F src/vdbeaux.c 4ccdfd27f97fec98385f53fc8c880f1873137d95
 F src/vdbeblob.c ef973d8d9f8170015343dd8824f795da675caa87
 F src/vdbemem.c 6087553f2c61c06c8e1ab3959a60e174d6240c98
 F src/vdbesort.c 3937e06b2a0e354500e17dc206ef4c35770a5017
@@ -1127,7 +1127,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 e557b7d80f1ede63427a31b16757bf5d8dbfb66d
-R 8ecb8965e88397a72e81a0bfa7fd01e8
+P ae61a34378d3ed2f454ba8768029d6f5fef849e4
+R 4e2e179014c5b2ce47e50b4ad5c73b59
 U drh
-Z ed26d40c375e5bd903fb1bf3e632fe62
+Z bf09176aa6b2dce2a1f786b527e72d8e
index e864bbe7b0821a71c7e2ba4126826af84405e002..6723151d82d7e22b19ca6133ea7fc4c40ca61f94 100644 (file)
@@ -1 +1 @@
-ae61a34378d3ed2f454ba8768029d6f5fef849e4
\ No newline at end of file
+e6650e16dd11327afd25961b2feb29ec8778c2ca
\ No newline at end of file
index 28fa1d357b9dc231d07b0dc93e4f12742b4e6b13..c6d3900ceb5fadd4f845fea04fb7cdb4ac7f99d5 100644 (file)
@@ -1392,13 +1392,12 @@ void sqlite3GenerateConstraintChecks(
   for(iCur=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, iCur++){
     int regIdx;
     int regR;
-    int addrSkipRow = 0;
+    int addrSkipRow = sqlite3VdbeMakeLabel(v);
 
     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);
@@ -1438,8 +1437,10 @@ void sqlite3GenerateConstraintChecks(
     
     /* Check to see if the new index entry will be unique */
     regR = sqlite3GetTempReg(pParse);
-    sqlite3VdbeAddOp2(v, OP_SCopy, regOldRowid, regR);
-    j3 = sqlite3VdbeAddOp4Int(v, OP_IsUnique, baseCur+iCur+1, 0, regR, regIdx);
+    sqlite3VdbeAddOp4Int(v, OP_NoConflict, baseCur+iCur+1, addrSkipRow,
+                         regIdx, pIdx->nKeyCol);
+    sqlite3VdbeAddOp2(v, OP_IdxRowid, baseCur+iCur+1, regR);
+    sqlite3VdbeAddOp3(v, OP_Eq, regR, addrSkipRow, regOldRowid);
     sqlite3ReleaseTempRange(pParse, regIdx, pIdx->nKeyCol+1);
 
     /* Generate code that executes if the new index entry is not unique */
@@ -1490,7 +1491,6 @@ void sqlite3GenerateConstraintChecks(
         break;
       }
     }
-    sqlite3VdbeJumpHere(v, j3);
     sqlite3VdbeResolveLabel(v, addrSkipRow);
     sqlite3ReleaseTempReg(pParse, regR);
   }
index c99cdb2070b71aed9f6173736ce73f6a57e60d44..0d5a68d5043531779fc21eca2a4bb7c48c017738 100644 (file)
@@ -1542,7 +1542,6 @@ struct UnpackedRecord {
   KeyInfo *pKeyInfo;  /* Collation and sort-order information */
   u16 nField;         /* Number of entries in apMem[] */
   u8 flags;           /* Boolean settings.  UNPACKED_... below */
-  i64 rowid;          /* Used by UNPACKED_PREFIX_SEARCH */
   Mem *aMem;          /* Values */
 };
 
@@ -1551,7 +1550,6 @@ struct UnpackedRecord {
 */
 #define UNPACKED_INCRKEY       0x01  /* Make this key an epsilon larger */
 #define UNPACKED_PREFIX_MATCH  0x02  /* A prefix match is considered OK */
-#define UNPACKED_PREFIX_SEARCH 0x04  /* Ignore final (rowid) field */
 
 /*
 ** Each SQL index is represented in memory by an
index d9f01837ee559e14ea0ef8f5108798527882de8d..0747e26fb6dfd603bf9a5c4ac16e5d292ac13b66 100644 (file)
@@ -3616,6 +3616,8 @@ case OP_Seek: {    /* in2 */
 ** Cursor P1 is on an index btree.  If the record identified by P3 and P4
 ** is a prefix of any entry in P1 then a jump is made to P2 and
 ** P1 is left pointing at the matching entry.
+**
+** See also: NotFound, NoConflict, NotExists. SeekGe
 */
 /* Opcode: NotFound P1 P2 P3 P4 *
 **
@@ -3629,11 +3631,31 @@ case OP_Seek: {    /* in2 */
 ** falls through to the next instruction and P1 is left pointing at the
 ** matching entry.
 **
-** See also: Found, NotExists, IsUnique
+** See also: Found, NotExists, NoConflict
+*/
+/* Opcode: NoConflict P1 P2 P3 P4 *
+**
+** If P4==0 then register P3 holds a blob constructed by MakeRecord.  If
+** P4>0 then register P3 is the first of P4 registers that form an unpacked
+** record.
+** 
+** Cursor P1 is on an index btree.  If the record identified by P3 and P4
+** contains any NULL value, jump immediately to P2.  If all terms of the
+** record are not-NULL then a check is done to determine if any row in the
+** P1 index btree has a matching key prefix.  If there are no matches, jump
+** immediately to P2.  If there is a match, fall through and leave the P1
+** cursor pointing to the matching row.
+**
+** This opcode is similar to OP_NotFound with the exceptions that the
+** branch is always taken if any part of the search key input is NULL.
+**
+** See also: NotFound, Found, NotExists
 */
+case OP_NoConflict:     /* jump, in3 */
 case OP_NotFound:       /* jump, in3 */
 case OP_Found: {        /* jump, in3 */
   int alreadyExists;
+  int ii;
   VdbeCursor *pC;
   int res;
   char *pFree;
@@ -3642,7 +3664,7 @@ case OP_Found: {        /* jump, in3 */
   char aTempRec[ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*3 + 7];
 
 #ifdef SQLITE_TEST
-  sqlite3_found_count++;
+  if( pOp->opcode!=OP_NoConflict ) sqlite3_found_count++;
 #endif
 
   alreadyExists = 0;
@@ -3673,6 +3695,17 @@ case OP_Found: {        /* jump, in3 */
       sqlite3VdbeRecordUnpack(pC->pKeyInfo, pIn3->n, pIn3->z, pIdxKey);
       pIdxKey->flags |= UNPACKED_PREFIX_MATCH;
     }
+    if( pOp->opcode==OP_NoConflict ){
+      /* For the OP_NoConflict opcode, take the jump if any of the
+      ** input fields are NULL, since any key with a NULL will not
+      ** conflict */
+      for(ii=0; ii<r.nField; ii++){
+        if( r.aMem[ii].flags & MEM_Null ){
+          pc = pOp->p2 - 1;
+          break;
+        }
+      }
+    }
     rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, pIdxKey, 0, 0, &res);
     if( pOp->p4.i==0 ){
       sqlite3DbFree(db, pFree);
@@ -3693,93 +3726,6 @@ case OP_Found: {        /* jump, in3 */
   break;
 }
 
-/* Opcode: IsUnique P1 P2 P3 P4 *
-**
-** Cursor P1 is open on an index b-tree - that is to say, a btree which
-** no data and where the key are records generated by OP_MakeRecord with
-** the list field being the integer ROWID of the entry that the index
-** entry refers to.
-**
-** The P3 register contains an integer record number. Call this record 
-** number R. Register P4 is the first in a set of N contiguous registers
-** that make up an unpacked index key that can be used with cursor P1.
-** The value of N can be inferred from the cursor. N includes the rowid
-** value appended to the end of the index record. This rowid value may
-** or may not be the same as R.
-**
-** If any of the N registers beginning with register P4 contains a NULL
-** value, jump immediately to P2.
-**
-** Otherwise, this instruction checks if cursor P1 contains an entry
-** where the first (N-1) fields match but the rowid value at the end
-** of the index entry is not R. If there is no such entry, control jumps
-** to instruction P2. Otherwise, the rowid of the conflicting index
-** entry is copied to register P3 and control falls through to the next
-** instruction.
-**
-** See also: NotFound, NotExists, Found
-*/
-case OP_IsUnique: {        /* jump, in3 */
-  u16 ii;
-  VdbeCursor *pCx;
-  BtCursor *pCrsr;
-  u16 nField;
-  Mem *aMx;
-  UnpackedRecord r;                  /* B-Tree index search key */
-  i64 R;                             /* Rowid stored in register P3 */
-
-  pIn3 = &aMem[pOp->p3];
-  aMx = &aMem[pOp->p4.i];
-  /* Assert that the values of parameters P1 and P4 are in range. */
-  assert( pOp->p4type==P4_INT32 );
-  assert( pOp->p4.i>0 && pOp->p4.i<=(p->nMem-p->nCursor) );
-  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
-
-  /* Find the index cursor. */
-  pCx = p->apCsr[pOp->p1];
-  assert( pCx->deferredMoveto==0 );
-  pCx->seekResult = 0;
-  pCx->cacheStatus = CACHE_STALE;
-  pCrsr = pCx->pCursor;
-
-  /* If any of the values are NULL, take the jump. */
-  nField = pCx->pKeyInfo->nField;
-  for(ii=0; ii<nField; ii++){
-    if( aMx[ii].flags & MEM_Null ){
-      pc = pOp->p2 - 1;
-      pCrsr = 0;
-      break;
-    }
-  }
-  assert( (aMx[nField].flags & MEM_Null)==0 );
-
-  if( pCrsr!=0 ){
-    /* Populate the index search key. */
-    r.pKeyInfo = pCx->pKeyInfo;
-    r.nField = nField + 1;
-    r.flags = UNPACKED_PREFIX_SEARCH;
-    r.aMem = aMx;
-#ifdef SQLITE_DEBUG
-    { int i; for(i=0; i<r.nField; i++) assert( memIsValid(&r.aMem[i]) ); }
-#endif
-
-    /* Extract the value of R from register P3. */
-    sqlite3VdbeMemIntegerify(pIn3);
-    R = pIn3->u.i;
-
-    /* Search the B-Tree index. If no conflicting record is found, jump
-    ** to P2. Otherwise, copy the rowid of the conflicting record to
-    ** register P3 and fall through to the next instruction.  */
-    rc = sqlite3BtreeMovetoUnpacked(pCrsr, &r, 0, 0, &pCx->seekResult);
-    if( (r.flags & UNPACKED_PREFIX_SEARCH) || r.rowid==R ){
-      pc = pOp->p2 - 1;
-    }else{
-      pIn3->u.i = r.rowid;
-    }
-  }
-  break;
-}
-
 /* Opcode: NotExists P1 P2 P3 * *
 **
 ** P1 is the index of a cursor open on an SQL table btree (with integer
index 68a9fbd51e3100320eb24e596968e2b26e500ded..ee573926903f65e3d3760ccbea7680daa81dd2ae 100644 (file)
@@ -3060,24 +3060,9 @@ int sqlite3VdbeRecordCompare(
     rc = sqlite3MemCompare(&mem1, &pPKey2->aMem[i], pKeyInfo->aColl[i]);
     if( rc!=0 ){
       assert( mem1.zMalloc==0 );  /* See comment below */
-
-      /* Invert the result if we are using DESC sort order. */
       if( pKeyInfo->aSortOrder[i] ){
-        rc = -rc;
-      }
-    
-      /* If the PREFIX_SEARCH flag is set and all fields except the final
-      ** rowid field were equal, then clear the PREFIX_SEARCH flag and set 
-      ** pPKey2->rowid to the value of the rowid field in (pKey1, nKey1).
-      ** This is used by the OP_IsUnique opcode.
-      */
-      if( (pPKey2->flags & UNPACKED_PREFIX_SEARCH) && i==(pPKey2->nField-1) ){
-        assert( idx1==szHdr1 && rc );
-        assert( mem1.flags & MEM_Int );
-        pPKey2->flags &= ~UNPACKED_PREFIX_SEARCH;
-        pPKey2->rowid = mem1.u.i;
+        rc = -rc;  /* Invert the result for DESC sort order. */
       }
-    
       return rc;
     }
     i++;