mirror of
				https://github.com/sqlite/sqlite.git
				synced 2025-11-03 16:53:36 +03:00 
			
		
		
		
	Avoid an unnecessary key comparison when doing an indexed lookup against an
equality constraint. FossilOrigin-Name: d741e1ccdce96e6142e294fbdd20a0282296dcea
This commit is contained in:
		
							
								
								
									
										28
									
								
								manifest
									
									
									
									
									
								
							
							
						
						
									
										28
									
								
								manifest
									
									
									
									
									
								
							@@ -1,5 +1,5 @@
 | 
			
		||||
C Work\saround\sa\ssign-extension\sbug\sin\sthe\soptimizer\son\sthe\sHP\sC\scompiler\sthat\ncomes\swith\sHP/UX.
 | 
			
		||||
D 2015-11-06T20:13:48.903
 | 
			
		||||
C Avoid\san\sunnecessary\skey\scomparison\swhen\sdoing\san\sindexed\slookup\sagainst\san\nequality\sconstraint.
 | 
			
		||||
D 2015-11-06T20:22:25.475
 | 
			
		||||
F Makefile.in 3a705bb4bd12e194212ddbdbf068310d17153cdb
 | 
			
		||||
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
 | 
			
		||||
F Makefile.msc 702d3e98f3afc6587a78481257f3c4c900efc3a4
 | 
			
		||||
@@ -282,8 +282,8 @@ F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240
 | 
			
		||||
F src/backup.c 2869a76c03eb393ee795416e2387005553df72bc
 | 
			
		||||
F src/bitvec.c d1f21d7d91690747881f03940584f4cc548c9d3d
 | 
			
		||||
F src/btmutex.c 45a968cc85afed9b5e6cf55bf1f42f8d18107f79
 | 
			
		||||
F src/btree.c 233c1536927b12d820cb0a19c657c59837f9334f
 | 
			
		||||
F src/btree.h b512723e4f27d7ba16b4b985cdecdb82c0f6d0c0
 | 
			
		||||
F src/btree.c 9e5d713bf54be8bfcae9b60210173dd53570f56d
 | 
			
		||||
F src/btree.h 1b8bf2818b5e256c25a5e09126720113b1d783da
 | 
			
		||||
F src/btreeInt.h 3ab435ed27adea54d040584b0bcc488ee7db1e38
 | 
			
		||||
F src/build.c ca574d33ffb1763cfd2979383f4d507095bfbe19
 | 
			
		||||
F src/callback.c 7b44ce59674338ad48b0e84e7b72f935ea4f68b0
 | 
			
		||||
@@ -345,7 +345,7 @@ F src/shell.c d25df04168d6ba5a4fa05bdbf859df667f9eb621
 | 
			
		||||
F src/sqlite.h.in 3cfc86c55e57c63d86b9e1e92869e2bfb162ca8e
 | 
			
		||||
F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
 | 
			
		||||
F src/sqlite3ext.h 4b66e3e3435da4b4c8c83696d0349f0c503b3924
 | 
			
		||||
F src/sqliteInt.h b1e72ffe282c91ae30a2bf403319126dbaebd556
 | 
			
		||||
F src/sqliteInt.h 12ff325b433c4ded39995b74b01b78aacc19805a
 | 
			
		||||
F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46
 | 
			
		||||
F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba
 | 
			
		||||
F src/table.c 51b46b2a62d1b3a959633d593b89bab5e2c9155e
 | 
			
		||||
@@ -403,11 +403,11 @@ F src/update.c 40e51cd0883cb5bfd6abb7d8a7cd8aa47fab2945
 | 
			
		||||
F src/utf.c fc6b889ba0779b7722634cdeaa25f1930d93820c
 | 
			
		||||
F src/util.c fc612367108b74573c5fd13a85d0a23027f438bd
 | 
			
		||||
F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701
 | 
			
		||||
F src/vdbe.c dfbaae2570172c523bce14299021d352b8508f7f
 | 
			
		||||
F src/vdbe.c a9b0ec9f8df86a805d593b625d1f21a8e71dcda5
 | 
			
		||||
F src/vdbe.h efb7a8c1459e31f3ea4377824c6a7e4cb5068637
 | 
			
		||||
F src/vdbeInt.h 33403622c6a8feaaac5f0f3f17f5d1bf6df42286
 | 
			
		||||
F src/vdbeapi.c 020681b943e77766b32ae1cddf86d7831b7374ca
 | 
			
		||||
F src/vdbeaux.c 232c242a0ccb3d67a66d55c71135a00123a5d88f
 | 
			
		||||
F src/vdbeaux.c 6d55530b05b69bc663c87d2d258318dcdf042644
 | 
			
		||||
F src/vdbeblob.c 565fabd302f5fca3bdf3d56cac330483616a39b6
 | 
			
		||||
F src/vdbemem.c fdd1578e47bea61390d472de53c565781d81e045
 | 
			
		||||
F src/vdbesort.c 8b23930a1289526f6d2a3a9f2e965bcc963e4a68
 | 
			
		||||
@@ -519,7 +519,7 @@ F test/coalesce.test cee0dccb9fbd2d494b77234bccf9dc6c6786eb91
 | 
			
		||||
F test/collate1.test 08c18e7512a5a32c97938854263fa15362eeb846
 | 
			
		||||
F test/collate2.test 9aaa410a00734e48bcb27f3872617d6f69b2a621
 | 
			
		||||
F test/collate3.test 89defc49983ddfbf0a0555aca8c0521a676f56a5
 | 
			
		||||
F test/collate4.test f04d5168685f2eef637ecfa2d4ddf8ec0d600177
 | 
			
		||||
F test/collate4.test c953715fb498b87163e3e73dd94356bff1f317bd
 | 
			
		||||
F test/collate5.test 65d928034d30d2d263a80f6359f7549ee1598ec6
 | 
			
		||||
F test/collate6.test 8be65a182abaac8011a622131486dafb8076e907
 | 
			
		||||
F test/collate7.test 8ec29d98f3ee4ccebce6e16ce3863fb6b8c7b868
 | 
			
		||||
@@ -1303,10 +1303,10 @@ F test/walro.test 34422d1d95aaff0388f0791ec20edb34e2a3ed57
 | 
			
		||||
F test/walshared.test 0befc811dcf0b287efae21612304d15576e35417
 | 
			
		||||
F test/walslow.test e7be6d9888f83aa5d3d3c7c08aa9b5c28b93609a
 | 
			
		||||
F test/walthread.test de8dbaf6d9e41481c460ba31ca61e163d7348f8e
 | 
			
		||||
F test/where.test 66d4c107e82dfe86c01a96277b77e7a8809aff0b
 | 
			
		||||
F test/where.test 9902a3d84e9bc80357a2c54ed0e76c0d6d04a867
 | 
			
		||||
F test/where2.test af78c55589cbc82d793449493adba0dc3d659f23
 | 
			
		||||
F test/where3.test 1ad55ba900bd7747f98b6082e65bd3e442c5004e
 | 
			
		||||
F test/where4.test 44f506bf1737cf0fa4fc795e340208250f1fcd89
 | 
			
		||||
F test/where4.test 4a371bfcc607f41d233701bdec33ac2972908ba8
 | 
			
		||||
F test/where5.test fdf66f96d29a064b63eb543e28da4dfdccd81ad2
 | 
			
		||||
F test/where6.test 5da5a98cec820d488e82708301b96cb8c18a258b
 | 
			
		||||
F test/where7.test 5a4b0abc207d71da4deecd734ad8579e8dd40aa8
 | 
			
		||||
@@ -1400,8 +1400,8 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f
 | 
			
		||||
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 | 
			
		||||
F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b
 | 
			
		||||
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
 | 
			
		||||
P d421efbf9a5688f5a20b6dfe3aa216299c7b9c86 8a171548e4f665f03d00af6dcb46669a4a78fad5
 | 
			
		||||
R 0bb8acd557038f7fa4d6dfd57e3d94da
 | 
			
		||||
T +closed 8a171548e4f665f03d00af6dcb46669a4a78fad5
 | 
			
		||||
P 46c36b1543d7a8156eaa866c67080526153fb10d 997ce6c90b454c03cc2ef6934752ee8dd2e520e3
 | 
			
		||||
R d671b922284dee0f3690ad077e9da684
 | 
			
		||||
T +closed 997ce6c90b454c03cc2ef6934752ee8dd2e520e3
 | 
			
		||||
U drh
 | 
			
		||||
Z 27befb1035577d32c475d270bda1aa44
 | 
			
		||||
Z 296d234d0e2e95f43350e42db47ce3df
 | 
			
		||||
 
 | 
			
		||||
@@ -1 +1 @@
 | 
			
		||||
46c36b1543d7a8156eaa866c67080526153fb10d
 | 
			
		||||
d741e1ccdce96e6142e294fbdd20a0282296dcea
 | 
			
		||||
@@ -5041,6 +5041,8 @@ int sqlite3BtreeLast(BtCursor *pCur, int *pRes){
 | 
			
		||||
**     *pRes>0      The cursor is left pointing at an entry that
 | 
			
		||||
**                  is larger than intKey/pIdxKey.
 | 
			
		||||
**
 | 
			
		||||
** For index tables, the pIdxKey->eqSeen field is set to 1 if there
 | 
			
		||||
** exists an entry in the table that exactly matches pIdxKey.  
 | 
			
		||||
*/
 | 
			
		||||
int sqlite3BtreeMovetoUnpacked(
 | 
			
		||||
  BtCursor *pCur,          /* The cursor to be moved */
 | 
			
		||||
@@ -9644,7 +9646,6 @@ int sqlite3BtreeSetVersion(Btree *pBtree, int iVersion){
 | 
			
		||||
  return rc;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef SQLITE_DEBUG
 | 
			
		||||
/*
 | 
			
		||||
** Return true if the cursor has a hint specified.  This routine is
 | 
			
		||||
** only used from within assert() statements
 | 
			
		||||
@@ -9652,7 +9653,6 @@ int sqlite3BtreeSetVersion(Btree *pBtree, int iVersion){
 | 
			
		||||
int sqlite3BtreeCursorHasHint(BtCursor *pCsr, unsigned int mask){
 | 
			
		||||
  return (pCsr->hints & mask)!=0;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
** Return true if the given Btree is read-only.
 | 
			
		||||
 
 | 
			
		||||
@@ -257,9 +257,7 @@ int sqlite3BtreePutData(BtCursor*, u32 offset, u32 amt, void*);
 | 
			
		||||
void sqlite3BtreeIncrblobCursor(BtCursor *);
 | 
			
		||||
void sqlite3BtreeClearCursor(BtCursor *);
 | 
			
		||||
int sqlite3BtreeSetVersion(Btree *pBt, int iVersion);
 | 
			
		||||
#ifdef SQLITE_DEBUG
 | 
			
		||||
int sqlite3BtreeCursorHasHint(BtCursor*, unsigned int mask);
 | 
			
		||||
#endif
 | 
			
		||||
int sqlite3BtreeIsReadonly(Btree *pBt);
 | 
			
		||||
int sqlite3HeaderSizeBtree(void);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1812,9 +1812,8 @@ struct KeyInfo {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
** An instance of the following structure holds information about a
 | 
			
		||||
** single index record that has already been parsed out into individual
 | 
			
		||||
** values.
 | 
			
		||||
** This object holds a record which has been parsed out into individual
 | 
			
		||||
** fields, for the purposes of doing a comparison.
 | 
			
		||||
**
 | 
			
		||||
** A record is an object that contains one or more fields of data.
 | 
			
		||||
** Records are used to store the content of a table row and to store
 | 
			
		||||
@@ -1822,20 +1821,40 @@ struct KeyInfo {
 | 
			
		||||
** the OP_MakeRecord opcode of the VDBE and is disassembled by the
 | 
			
		||||
** OP_Column opcode.
 | 
			
		||||
**
 | 
			
		||||
** This structure holds a record that has already been disassembled
 | 
			
		||||
** into its constituent fields.
 | 
			
		||||
** An instance of this object serves as a "key" for doing a search on
 | 
			
		||||
** an index b+tree. The goal of the search is to find the entry that
 | 
			
		||||
** is closed to the key described by this object.  This object might hold
 | 
			
		||||
** just a prefix of the key.  The number of fields is given by
 | 
			
		||||
** pKeyInfo->nField.
 | 
			
		||||
**
 | 
			
		||||
** The r1 and r2 member variables are only used by the optimized comparison
 | 
			
		||||
** functions vdbeRecordCompareInt() and vdbeRecordCompareString().
 | 
			
		||||
** The r1 and r2 fields are the values to return if this key is less than
 | 
			
		||||
** or greater than a key in the btree, respectively.  These are normally
 | 
			
		||||
** -1 and +1 respectively, but might be inverted to +1 and -1 if the b-tree
 | 
			
		||||
** is in DESC order.
 | 
			
		||||
**
 | 
			
		||||
** The key comparison functions actually return default_rc when they find
 | 
			
		||||
** an equals comparison.  default_rc can be -1, 0, or +1.  If there are
 | 
			
		||||
** multiple entries in the b-tree with the same key (when only looking
 | 
			
		||||
** at the first pKeyInfo->nFields,) then default_rc can be set to -1 to 
 | 
			
		||||
** cause the search to find the last match, or +1 to cause the search to
 | 
			
		||||
** find the first match.
 | 
			
		||||
**
 | 
			
		||||
** The key comparison functions will set eqSeen to true if they ever
 | 
			
		||||
** get and equal results when comparing this structure to a b-tree record.
 | 
			
		||||
** When default_rc!=0, the search might end up on the record immediately
 | 
			
		||||
** before the first match or immediately after the last match.  The
 | 
			
		||||
** eqSeen field will indicate whether or not an exact match exists in the
 | 
			
		||||
** b-tree.
 | 
			
		||||
*/
 | 
			
		||||
struct UnpackedRecord {
 | 
			
		||||
  KeyInfo *pKeyInfo;  /* Collation and sort-order information */
 | 
			
		||||
  Mem *aMem;          /* Values */
 | 
			
		||||
  u16 nField;         /* Number of entries in apMem[] */
 | 
			
		||||
  i8 default_rc;      /* Comparison result if keys are equal */
 | 
			
		||||
  u8 errCode;         /* Error detected by xRecordCompare (CORRUPT or NOMEM) */
 | 
			
		||||
  Mem *aMem;          /* Values */
 | 
			
		||||
  int r1;             /* Value to return if (lhs > rhs) */
 | 
			
		||||
  int r2;             /* Value to return if (rhs < lhs) */
 | 
			
		||||
  i8 r1;              /* Value to return if (lhs > rhs) */
 | 
			
		||||
  i8 r2;              /* Value to return if (rhs < lhs) */
 | 
			
		||||
  u8 eqSeen;          /* True if an equality comparison has been seen */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										38
									
								
								src/vdbe.c
									
									
									
									
									
								
							
							
						
						
									
										38
									
								
								src/vdbe.c
									
									
									
									
									
								
							@@ -3597,6 +3597,13 @@ case OP_ColumnsUsed: {
 | 
			
		||||
** is greater than or equal to the key value. If there are no records 
 | 
			
		||||
** greater than or equal to the key and P2 is not zero, then jump to P2.
 | 
			
		||||
**
 | 
			
		||||
** If the cursor P1 was opened using the OPFLAG_SEEKEQ flag, then this
 | 
			
		||||
** opcode will always land on a record that equally equals the key, or
 | 
			
		||||
** else jump immediately to P2.  When the cursor is OPFLAG_SEEKEQ, this
 | 
			
		||||
** opcode must be followed by an IdxLE opcode with the same arguments.
 | 
			
		||||
** The IdxLE opcode will be skipped if this opcode succeeds, but the
 | 
			
		||||
** IdxLE opcode will be used on subsequent loop iterations.
 | 
			
		||||
**
 | 
			
		||||
** This opcode leaves the cursor configured to move in forward order,
 | 
			
		||||
** from the beginning toward the end.  In other words, the cursor is
 | 
			
		||||
** configured to use Next, not Prev.
 | 
			
		||||
@@ -3655,18 +3662,26 @@ case OP_ColumnsUsed: {
 | 
			
		||||
** from the end toward the beginning.  In other words, the cursor is
 | 
			
		||||
** configured to use Prev, not Next.
 | 
			
		||||
**
 | 
			
		||||
** If the cursor P1 was opened using the OPFLAG_SEEKEQ flag, then this
 | 
			
		||||
** opcode will always land on a record that equally equals the key, or
 | 
			
		||||
** else jump immediately to P2.  When the cursor is OPFLAG_SEEKEQ, this
 | 
			
		||||
** opcode must be followed by an IdxGE opcode with the same arguments.
 | 
			
		||||
** The IdxGE opcode will be skipped if this opcode succeeds, but the
 | 
			
		||||
** IdxGE opcode will be used on subsequent loop iterations.
 | 
			
		||||
**
 | 
			
		||||
** See also: Found, NotFound, SeekGt, SeekGe, SeekLt
 | 
			
		||||
*/
 | 
			
		||||
case OP_SeekLT:         /* jump, in3 */
 | 
			
		||||
case OP_SeekLE:         /* jump, in3 */
 | 
			
		||||
case OP_SeekGE:         /* jump, in3 */
 | 
			
		||||
case OP_SeekGT: {       /* jump, in3 */
 | 
			
		||||
  int res;
 | 
			
		||||
  int oc;
 | 
			
		||||
  VdbeCursor *pC;
 | 
			
		||||
  UnpackedRecord r;
 | 
			
		||||
  int nField;
 | 
			
		||||
  int res;           /* Comparison result */
 | 
			
		||||
  int oc;            /* Opcode */
 | 
			
		||||
  VdbeCursor *pC;    /* The cursor to seek */
 | 
			
		||||
  UnpackedRecord r;  /* The key to seek for */
 | 
			
		||||
  int nField;        /* Number of columns or fields in the key */
 | 
			
		||||
  i64 iKey;          /* The rowid we are to seek to */
 | 
			
		||||
  int eqOnly = 0;    /* Only interested in == results */
 | 
			
		||||
 | 
			
		||||
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
 | 
			
		||||
  assert( pOp->p2!=0 );
 | 
			
		||||
@@ -3688,8 +3703,8 @@ case OP_SeekGT: {       /* jump, in3 */
 | 
			
		||||
  ** OP_SeekLE opcodes are allowed, and these must be immediately followed
 | 
			
		||||
  ** by an OP_IdxGT or OP_IdxLT opcode, respectively, with the same key.
 | 
			
		||||
  */
 | 
			
		||||
#ifdef SQLITE_DEBUG
 | 
			
		||||
  if( sqlite3BtreeCursorHasHint(pC->pCursor, BTREE_SEEK_EQ) ){
 | 
			
		||||
    eqOnly = 1;
 | 
			
		||||
    assert( pOp->opcode==OP_SeekGE || pOp->opcode==OP_SeekLE );
 | 
			
		||||
    assert( pOp[1].opcode==OP_IdxLT || pOp[1].opcode==OP_IdxGT );
 | 
			
		||||
    assert( pOp[1].p1==pOp[0].p1 );
 | 
			
		||||
@@ -3697,7 +3712,6 @@ case OP_SeekGT: {       /* jump, in3 */
 | 
			
		||||
    assert( pOp[1].p3==pOp[0].p3 );
 | 
			
		||||
    assert( pOp[1].p4.i==pOp[0].p4.i );
 | 
			
		||||
  }
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
  if( pC->isTable ){
 | 
			
		||||
    /* The input value in P3 might be of any type: integer, real, string,
 | 
			
		||||
@@ -3747,6 +3761,7 @@ case OP_SeekGT: {       /* jump, in3 */
 | 
			
		||||
    if( rc!=SQLITE_OK ){
 | 
			
		||||
      goto abort_due_to_error;
 | 
			
		||||
    }
 | 
			
		||||
    if( eqOnly && res ) goto seek_not_found;
 | 
			
		||||
  }else{
 | 
			
		||||
    nField = pOp->p4.i;
 | 
			
		||||
    assert( pOp->p4type==P4_INT32 );
 | 
			
		||||
@@ -3772,10 +3787,15 @@ case OP_SeekGT: {       /* jump, in3 */
 | 
			
		||||
    { int i; for(i=0; i<r.nField; i++) assert( memIsValid(&r.aMem[i]) ); }
 | 
			
		||||
#endif
 | 
			
		||||
    ExpandBlob(r.aMem);
 | 
			
		||||
    r.eqSeen = 0;
 | 
			
		||||
    rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, &r, 0, 0, &res);
 | 
			
		||||
    if( rc!=SQLITE_OK ){
 | 
			
		||||
      goto abort_due_to_error;
 | 
			
		||||
    }
 | 
			
		||||
    if( eqOnly && r.eqSeen==0 ){
 | 
			
		||||
      assert( res!=0 );
 | 
			
		||||
      goto seek_not_found;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  pC->deferredMoveto = 0;
 | 
			
		||||
  pC->cacheStatus = CACHE_STALE;
 | 
			
		||||
@@ -3803,10 +3823,14 @@ case OP_SeekGT: {       /* jump, in3 */
 | 
			
		||||
      res = sqlite3BtreeEof(pC->pCursor);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
seek_not_found:
 | 
			
		||||
  assert( pOp->p2>0 );
 | 
			
		||||
  VdbeBranchTaken(res!=0,2);
 | 
			
		||||
  if( res ){
 | 
			
		||||
    goto jump_to_p2;
 | 
			
		||||
  }else if( eqOnly ){
 | 
			
		||||
    assert( pOp[1].opcode==OP_IdxLT || pOp[1].opcode==OP_IdxGT );
 | 
			
		||||
    pOp++; /* Skip the OP_IdxLt or OP_IdxGT that follows */
 | 
			
		||||
  }
 | 
			
		||||
  break;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -3993,6 +3993,7 @@ int sqlite3VdbeRecordCompareWithSkip(
 | 
			
		||||
       || vdbeRecordCompareDebug(nKey1, pKey1, pPKey2, pPKey2->default_rc) 
 | 
			
		||||
       || pKeyInfo->db->mallocFailed
 | 
			
		||||
  );
 | 
			
		||||
  pPKey2->eqSeen = 1;
 | 
			
		||||
  return pPKey2->default_rc;
 | 
			
		||||
}
 | 
			
		||||
int sqlite3VdbeRecordCompare(
 | 
			
		||||
@@ -4092,6 +4093,7 @@ static int vdbeRecordCompareInt(
 | 
			
		||||
    /* The first fields of the two keys are equal and there are no trailing
 | 
			
		||||
    ** fields. Return pPKey2->default_rc in this case. */
 | 
			
		||||
    res = pPKey2->default_rc;
 | 
			
		||||
    pPKey2->eqSeen = 1;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  assert( vdbeRecordCompareDebug(nKey1, pKey1, pPKey2, res) );
 | 
			
		||||
@@ -4139,6 +4141,7 @@ static int vdbeRecordCompareString(
 | 
			
		||||
          res = sqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 1);
 | 
			
		||||
        }else{
 | 
			
		||||
          res = pPKey2->default_rc;
 | 
			
		||||
          pPKey2->eqSeen = 1;
 | 
			
		||||
        }
 | 
			
		||||
      }else if( res>0 ){
 | 
			
		||||
        res = pPKey2->r2;
 | 
			
		||||
 
 | 
			
		||||
@@ -352,7 +352,7 @@ do_test collate4-2.1.2 {
 | 
			
		||||
  count {
 | 
			
		||||
    SELECT * FROM collate4t2, collate4t1 WHERE a = b;
 | 
			
		||||
  }
 | 
			
		||||
} {A a A A 5}
 | 
			
		||||
} {A a A A 4}
 | 
			
		||||
do_test collate4-2.1.3 {
 | 
			
		||||
  count {
 | 
			
		||||
    SELECT * FROM collate4t2, collate4t1 WHERE b = a;
 | 
			
		||||
@@ -372,7 +372,7 @@ do_test collate4-2.1.5 {
 | 
			
		||||
  count {
 | 
			
		||||
    SELECT * FROM collate4t2, collate4t1 WHERE b = a;
 | 
			
		||||
  }
 | 
			
		||||
} {A A 4}
 | 
			
		||||
} {A A 3}
 | 
			
		||||
ifcapable subquery {
 | 
			
		||||
  do_test collate4-2.1.6 {
 | 
			
		||||
    count {
 | 
			
		||||
@@ -389,12 +389,12 @@ ifcapable subquery {
 | 
			
		||||
      SELECT a FROM collate4t1 WHERE a IN (SELECT * FROM collate4t2)
 | 
			
		||||
       ORDER BY rowid
 | 
			
		||||
    }
 | 
			
		||||
  } {a A 6}
 | 
			
		||||
  } {a A 5}
 | 
			
		||||
  do_test collate4-2.1.8 {
 | 
			
		||||
    count {
 | 
			
		||||
      SELECT a FROM collate4t1 WHERE a IN ('z', 'a');
 | 
			
		||||
    }
 | 
			
		||||
  } {a A 5}
 | 
			
		||||
  } {a A 4}
 | 
			
		||||
  do_test collate4-2.1.9 {
 | 
			
		||||
    execsql {
 | 
			
		||||
      DROP INDEX collate4i1;
 | 
			
		||||
 
 | 
			
		||||
@@ -412,22 +412,22 @@ ifcapable subquery {
 | 
			
		||||
    count {
 | 
			
		||||
      SELECT * FROM t1 WHERE w IN (-1,1,2,3) order by 1;
 | 
			
		||||
    }
 | 
			
		||||
  } {1 0 4 2 1 9 3 1 16 13}
 | 
			
		||||
  } {1 0 4 2 1 9 3 1 16 12}
 | 
			
		||||
  do_test where-5.3b {
 | 
			
		||||
    count {
 | 
			
		||||
      SELECT * FROM t1 WHERE w IN (3,-1,1,2) order by 1;
 | 
			
		||||
    }
 | 
			
		||||
  } {1 0 4 2 1 9 3 1 16 13}
 | 
			
		||||
  } {1 0 4 2 1 9 3 1 16 12}
 | 
			
		||||
  do_test where-5.3c {
 | 
			
		||||
    count {
 | 
			
		||||
      SELECT * FROM t1 WHERE w IN (3,2,-1,1,2) order by 1;
 | 
			
		||||
    }
 | 
			
		||||
  } {1 0 4 2 1 9 3 1 16 13}
 | 
			
		||||
  } {1 0 4 2 1 9 3 1 16 12}
 | 
			
		||||
  do_test where-5.3d {
 | 
			
		||||
    count {
 | 
			
		||||
      SELECT * FROM t1 WHERE w IN (-1,1,2,3) order by 1 DESC;
 | 
			
		||||
    }
 | 
			
		||||
  } {3 1 16 2 1 9 1 0 4 12}
 | 
			
		||||
  } {3 1 16 2 1 9 1 0 4 11}
 | 
			
		||||
  do_test where-5.4 {
 | 
			
		||||
    count {
 | 
			
		||||
      SELECT * FROM t1 WHERE w+0 IN (-1,1,2,3) order by 1;
 | 
			
		||||
@@ -465,7 +465,7 @@ ifcapable subquery {
 | 
			
		||||
    count {
 | 
			
		||||
      SELECT * FROM t1 WHERE x IN (1,7) ORDER BY 1;
 | 
			
		||||
    }
 | 
			
		||||
  } {2 1 9 3 1 16 7}
 | 
			
		||||
  } {2 1 9 3 1 16 6}
 | 
			
		||||
  do_test where-5.10 {
 | 
			
		||||
    count {
 | 
			
		||||
      SELECT * FROM t1 WHERE x+0 IN (1,7) ORDER BY 1;
 | 
			
		||||
@@ -485,17 +485,17 @@ ifcapable subquery {
 | 
			
		||||
    count {
 | 
			
		||||
      SELECT * FROM t1 WHERE x IN (1,7) AND y NOT IN (6400,8100) ORDER BY 1;
 | 
			
		||||
    }
 | 
			
		||||
  } {2 1 9 3 1 16 7}
 | 
			
		||||
  } {2 1 9 3 1 16 6}
 | 
			
		||||
  do_test where-5.14 {
 | 
			
		||||
    count {
 | 
			
		||||
      SELECT * FROM t1 WHERE x IN (1,7) AND y IN (9,10) ORDER BY 1;
 | 
			
		||||
    }
 | 
			
		||||
  } {2 1 9 8}
 | 
			
		||||
  } {2 1 9 5}
 | 
			
		||||
  do_test where-5.15 {
 | 
			
		||||
    count {
 | 
			
		||||
      SELECT * FROM t1 WHERE x IN (1,7) AND y IN (9,16) ORDER BY 1;
 | 
			
		||||
    }
 | 
			
		||||
  } {2 1 9 3 1 16 11}
 | 
			
		||||
  } {2 1 9 3 1 16 9}
 | 
			
		||||
  do_test where-5.100 {
 | 
			
		||||
    db eval {
 | 
			
		||||
      SELECT w, x, y FROM t1 WHERE x IN (1,5) AND y IN (9,8,3025,1000,3969)
 | 
			
		||||
 
 | 
			
		||||
@@ -91,7 +91,7 @@ do_test where4-1.10 {
 | 
			
		||||
} {6 2}
 | 
			
		||||
do_test where4-1.11 {
 | 
			
		||||
  count {SELECT rowid FROM t1 WHERE w=x'78' AND x IS NULL AND y=123}
 | 
			
		||||
} {1}
 | 
			
		||||
} {0}
 | 
			
		||||
do_test where4-1.12 {
 | 
			
		||||
  count {SELECT rowid FROM t1 WHERE w=x'78' AND x IS NULL AND y=x'7A'}
 | 
			
		||||
} {6 2}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user