]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
The idea of coding IN operator with a short list on the RHS as an OR expression
authordrh <drh@noemail.net>
Fri, 1 Aug 2014 15:34:36 +0000 (15:34 +0000)
committerdrh <drh@noemail.net>
Fri, 1 Aug 2014 15:34:36 +0000 (15:34 +0000)
turns out to be helpful.  If the list is of length 1 or 2, the OR expression
is very slightly faster, but the ephemeral table approach is clearly better for
all list lengths greater than 2.  Better to keep the code simple.

FossilOrigin-Name: e13175d3579e1045165bab091b3b28951d691704

manifest
manifest.uuid
src/expr.c
src/sqliteInt.h

index 3fae6c98bdc8e946d072f5fd050282a3f43db128..76ab0745e9fd1b987b663d09b36e1f07dd9d8755 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Begin\smaking\schanges\sto\sthe\sIN\soperator\sin\san\sattempt\sto\smake\sit\srun\sfaster\nand\sto\smake\sthe\scode\seasier\sto\sunderstand.
-D 2014-08-01T14:46:57.155
+C The\sidea\sof\scoding\sIN\soperator\swith\sa\sshort\slist\son\sthe\sRHS\sas\san\sOR\sexpression\nturns\sout\sto\sbe\shelpful.\s\sIf\sthe\slist\sis\sof\slength\s1\sor\s2,\sthe\sOR\sexpression\nis\svery\sslightly\sfaster,\sbut\sthe\sephemeral\stable\sapproach\sis\sclearly\sbetter\sfor\nall\slist\slengths\sgreater\sthan\s2.\s\sBetter\sto\skeep\sthe\scode\ssimple.
+D 2014-08-01T15:34:36.551
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in 5eb79e334a5de69c87740edd56af6527dd219308
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -176,7 +176,7 @@ F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
 F src/ctime.c 0231df905e2c4abba4483ee18ffc05adc321df2a
 F src/date.c 593c744b2623971e45affd0bde347631bdfa4625
 F src/delete.c bcf8f72126cea80fc3d5bc5494cf19b3f8935aaf
-F src/expr.c 7c52ea8b322992a91a241c0092a5bf97b141d353
+F src/expr.c 1f7fa7ddbdffd89898a3ce5ff1e57d137ec87aa5
 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
 F src/fkey.c 8545f3b36da47473e10800ea4fb0810fd4062514
 F src/func.c 3bc223ea36cd29a91c481485343d0ee4257ab8dc
@@ -227,7 +227,7 @@ F src/shell.c 191129c3f7a9cf241aea90ff6a6be3e74d3767f0
 F src/sqlite.h.in 9bbc5815c73b0e77e68b5275481a5e3e7814a804
 F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e
 F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc
-F src/sqliteInt.h 17ece600d3c9d36cc0ee2b74a30507507f3e0937
+F src/sqliteInt.h 5cee19f34f6efe6e6f7733d55a5c59e3a35a378a
 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
 F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158
 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
@@ -1185,10 +1185,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P 9abcf2698c09f4f6a44a68e74f9f6b538f3253d6
-R 1cc42777f2b661f6d0caf162eadc6d85
-T *branch * IN-operator-improvements
-T *sym-IN-operator-improvements *
-T -sym-trunk *
+P ee0fd6aaf94cda1dce3fe752bfe3b0f83e0043f1
+R b49330a02feffafe84f051ae1dbb9076
 U drh
-Z 08adfdc6013d75458685b1e962a583ca
+Z f695386e744e4159654587b52ac0d789
index 1b3e9a1eeb1338809d28fdada4116ddc7819c6dc..9b33d2f23a4eef889f7004c333274b95b4cdde57 100644 (file)
@@ -1 +1 @@
-ee0fd6aaf94cda1dce3fe752bfe3b0f83e0043f1
\ No newline at end of file
+e13175d3579e1045165bab091b3b28951d691704
\ No newline at end of file
index dd7b7c3de12512c14736dc98d3e5dc24e58e9684..d8188271075da8c3fa4c3b4075885c367600d0d3 100644 (file)
@@ -1494,8 +1494,6 @@ int sqlite3CodeOnce(Parse *pParse){
 **   IN_INDEX_INDEX_DESC - The cursor was opened on a descending index.
 **   IN_INDEX_EPH        - The cursor was opened on a specially created and
 **                         populated epheremal table.
-**   IN_INDEX_NOOP       - No cursor was allocated.  The in operator must be
-**                         implemented as a sequence of comparisons.
 **
 ** An existing b-tree might be used if the RHS expression pX is a simple
 ** subquery such as:
@@ -1525,13 +1523,6 @@ int sqlite3CodeOnce(Parse *pParse){
 ** be used unless <column> is an INTEGER PRIMARY KEY or an index can 
 ** be found with <column> as its left-most column.
 **
-** If the IN_INDEX_NOOP_OK and IN_INDEX_MEMBERSHIP are both set and
-** if the RHS of the IN operator is a list (not a subquery) then this
-** routine might decide that creating an ephemeral b-tree for membership
-** testing is too expensive and return IN_INDEX_NOOP.  IN that case, the
-** calling routine should implement the IN operator using a sequence
-** of Eq or Ne comparison operations.
-**
 ** When the b-tree is being used for membership tests, the calling function
 ** might need to know whether or not the RHS side of the IN operator
 ** contains a NULL.  If prNotFound is not NULL and 
@@ -1939,7 +1930,7 @@ static void sqlite3ExprCodeIN(
   v = pParse->pVdbe;
   assert( v!=0 );       /* OOM detected prior to this routine */
   VdbeNoopComment((v, "begin IN expr"));
-  eType = sqlite3FindInIndex(pParse, pExpr, 0,
+  eType = sqlite3FindInIndex(pParse, pExpr, IN_INDEX_MEMBERSHIP,
                              destIfFalse==destIfNull ? 0 : &rRhsHasNull);
 
   /* Figure out the affinity to use to create a key from the results
@@ -1986,7 +1977,8 @@ static void sqlite3ExprCodeIN(
     ** contains one or more NULL values, then the result of the
     ** expression is also NULL.
     */
-    if( rRhsHasNull==0 || destIfFalse==destIfNull ){
+    assert( destIfFalse!=destIfNull || rRhsHasNull==0 );
+    if( rRhsHasNull==0 ){
       /* This branch runs if it is known at compile time that the RHS
       ** cannot contain NULL values. This happens as the result
       ** of a "NOT NULL" constraint in the database schema.
index 784fd0fd939fd6fd2aeefcbefdd16007d328ac11..97fb2d46e465fec5f353b2c70090fbca33278566 100644 (file)
@@ -3598,13 +3598,11 @@ const char *sqlite3JournalModename(int);
 #define IN_INDEX_EPH          2   /* Search an ephemeral b-tree */
 #define IN_INDEX_INDEX_ASC    3   /* Existing index ASCENDING */
 #define IN_INDEX_INDEX_DESC   4   /* Existing index DESCENDING */
-#define IN_INDEX_NOOP         5   /* No table available. Use comparisons */
 /*
 ** Allowed flags for the 3rd parameter to sqlite3FindInIndex().
 */
-#define IN_INDEX_NOOP_OK     0x0001  /* OK to return IN_INDEX_NOOP */
-#define IN_INDEX_MEMBERSHIP  0x0002  /* IN operator used for membership test */
-#define IN_INDEX_LOOP        0x0004  /* IN operator used as a loop */
+#define IN_INDEX_MEMBERSHIP  0x0001  /* IN operator used for membership test */
+#define IN_INDEX_LOOP        0x0002  /* IN operator used as a loop */
 int sqlite3FindInIndex(Parse *, Expr *, u32, int*);
 
 #ifdef SQLITE_ENABLE_ATOMIC_WRITE