gitlab.com/CoiaPrant/sqlite3@v1.19.1/testdata/tcl/where3.test (about)

     1  # 2006 January 31
     2  #
     3  # The author disclaims copyright to this source code.  In place of
     4  # a legal notice, here is a blessing:
     5  #
     6  #    May you do good and not evil.
     7  #    May you find forgiveness for yourself and forgive others.
     8  #    May you share freely, never taking more than you give.
     9  #
    10  #***********************************************************************
    11  # This file implements regression tests for SQLite library.  The
    12  # focus of this file is testing the join reordering optimization
    13  # in cases that include a LEFT JOIN.
    14  #
    15  # $Id: where3.test,v 1.4 2008/04/17 19:14:02 drh Exp $
    16  
    17  set testdir [file dirname $argv0]
    18  source $testdir/tester.tcl
    19  
    20  # The following is from ticket #1652.
    21  #
    22  # A comma join then a left outer join:  A,B left join C.
    23  # Arrange indices so that the B table is chosen to go first.
    24  # Also put an index on C, but make sure that A is chosen before C.
    25  #
    26  do_test where3-1.1 {
    27    execsql {
    28      CREATE TABLE t1(a, b);
    29      CREATE TABLE t2(p, q);
    30      CREATE TABLE t3(x, y);
    31      
    32      INSERT INTO t1 VALUES(111,'one');
    33      INSERT INTO t1 VALUES(222,'two');
    34      INSERT INTO t1 VALUES(333,'three');
    35      
    36      INSERT INTO t2 VALUES(1,111);
    37      INSERT INTO t2 VALUES(2,222);
    38      INSERT INTO t2 VALUES(4,444);
    39      CREATE INDEX t2i1 ON t2(p);
    40      
    41      INSERT INTO t3 VALUES(999,'nine');
    42      CREATE INDEX t3i1 ON t3(x);
    43      
    44      SELECT * FROM t1, t2 LEFT JOIN t3 ON q=x WHERE p=2 AND a=q;
    45    }
    46  } {222 two 2 222 {} {}}
    47  
    48  ifcapable explain&&!cursorhints {
    49    do_test where3-1.1.1 {
    50       explain_no_trace {SELECT * FROM t1, t2 LEFT JOIN t3 ON q=x
    51                          WHERE p=2 AND a=q}
    52    } [explain_no_trace {SELECT * FROM t1, t2 LEFT JOIN t3 ON x=q
    53                          WHERE p=2 AND a=q}]
    54  }
    55  
    56  # Ticket #1830
    57  #
    58  # This is similar to the above but with the LEFT JOIN on the
    59  # other side.
    60  #
    61  do_test where3-1.2 {
    62    execsql {
    63      CREATE TABLE parent1(parent1key, child1key, Child2key, child3key);
    64      CREATE TABLE child1 ( child1key NVARCHAR, value NVARCHAR );
    65      CREATE UNIQUE INDEX PKIDXChild1 ON child1 ( child1key );
    66      CREATE TABLE child2 ( child2key NVARCHAR, value NVARCHAR );
    67  
    68      INSERT INTO parent1(parent1key,child1key,child2key)
    69         VALUES ( 1, 'C1.1', 'C2.1' );
    70      INSERT INTO child1 ( child1key, value ) VALUES ( 'C1.1', 'Value for C1.1' );
    71      INSERT INTO child2 ( child2key, value ) VALUES ( 'C2.1', 'Value for C2.1' );
    72  
    73      INSERT INTO parent1 ( parent1key, child1key, child2key )
    74         VALUES ( 2, 'C1.2', 'C2.2' );
    75      INSERT INTO child2 ( child2key, value ) VALUES ( 'C2.2', 'Value for C2.2' );
    76  
    77      INSERT INTO parent1 ( parent1key, child1key, child2key )
    78         VALUES ( 3, 'C1.3', 'C2.3' );
    79      INSERT INTO child1 ( child1key, value ) VALUES ( 'C1.3', 'Value for C1.3' );
    80      INSERT INTO child2 ( child2key, value ) VALUES ( 'C2.3', 'Value for C2.3' );
    81  
    82      SELECT parent1.parent1key, child1.value, child2.value
    83      FROM parent1
    84      LEFT OUTER JOIN child1 ON child1.child1key = parent1.child1key
    85      INNER JOIN child2 ON child2.child2key = parent1.child2key;
    86    }
    87  } {1 {Value for C1.1} {Value for C2.1} 2 {} {Value for C2.2} 3 {Value for C1.3} {Value for C2.3}}
    88  
    89  ifcapable explain&&!cursorhints {
    90    do_test where3-1.2.1 {
    91       explain_no_trace {
    92         SELECT parent1.parent1key, child1.value, child2.value
    93         FROM parent1
    94         LEFT OUTER JOIN child1 ON child1.child1key = parent1.child1key
    95         INNER JOIN child2 ON child2.child2key = parent1.child2key;
    96       }
    97    } [explain_no_trace {
    98         SELECT parent1.parent1key, child1.value, child2.value
    99         FROM parent1
   100         LEFT OUTER JOIN child1 ON parent1.child1key = child1.child1key 
   101         INNER JOIN child2 ON child2.child2key = parent1.child2key;
   102       }]
   103  }
   104  
   105  # This procedure executes the SQL.  Then it appends 
   106  # the names of the table and index used
   107  #
   108  proc queryplan {sql} {
   109    set ::sqlite_sort_count 0
   110    set data [execsql $sql]
   111    set eqp [execsql "EXPLAIN QUERY PLAN $sql"]
   112    # puts eqp=$eqp
   113    foreach {a b c x} $eqp {
   114      if {[regexp {SCAN CONSTANT} $x]} {
   115        # noop
   116      } elseif {[regexp {(SCAN|SEARCH) (\w+ AS )?(\w+) USING.* INDEX (\w+)\y} \
   117          $x all ss as tab idx]} {
   118        lappend data $tab $idx
   119      } elseif {[regexp {(SCAN|SEARCH) (\w+ AS )?(\w+)\y} $x all ss as tab]} {
   120        lappend data $tab *
   121      }
   122    }
   123    return $data   
   124  }
   125  
   126  
   127  # If you have a from clause of the form:   A B C left join D
   128  # then make sure the query optimizer is able to reorder the 
   129  # A B C part anyway it wants. 
   130  #
   131  # Following the fix to ticket #1652, there was a time when
   132  # the C table would not reorder.  So the following reorderings
   133  # were possible:
   134  #
   135  #            A B C left join D
   136  #            B A C left join D
   137  #
   138  # But these reorders were not allowed
   139  #
   140  #            C A B left join D
   141  #            A C B left join D
   142  #            C B A left join D
   143  #            B C A left join D
   144  #
   145  # The following tests are here to verify that the latter four
   146  # reorderings are allowed again.
   147  #
   148  do_test where3-2.1 {
   149    execsql {
   150      CREATE TABLE tA(apk integer primary key, ax);
   151      CREATE TABLE tB(bpk integer primary key, bx);
   152      CREATE TABLE tC(cpk integer primary key, cx);
   153      CREATE TABLE tD(dpk integer primary key, dx);
   154    }
   155    queryplan {
   156      SELECT * FROM tA, tB, tC LEFT JOIN tD ON dpk=cx
   157       WHERE cpk=bx AND bpk=ax
   158    }
   159  } {tA * tB * tC * tD *}
   160  do_test where3-2.1.1 {
   161    queryplan {
   162      SELECT * FROM tA, tB, tC LEFT JOIN tD ON cx=dpk
   163       WHERE cpk=bx AND bpk=ax
   164    }
   165  } {tA * tB * tC * tD *}
   166  do_test where3-2.1.2 {
   167    queryplan {
   168      SELECT * FROM tA, tB, tC LEFT JOIN tD ON cx=dpk
   169       WHERE bx=cpk AND bpk=ax
   170    }
   171  } {tA * tB * tC * tD *}
   172  do_test where3-2.1.3 {
   173    queryplan {
   174      SELECT * FROM tA, tB, tC LEFT JOIN tD ON cx=dpk
   175       WHERE bx=cpk AND ax=bpk
   176    }
   177  } {tA * tB * tC * tD *}
   178  do_test where3-2.1.4 {
   179    queryplan {
   180      SELECT * FROM tA, tB, tC LEFT JOIN tD ON dpk=cx
   181       WHERE bx=cpk AND ax=bpk
   182    }
   183  } {tA * tB * tC * tD *}
   184  do_test where3-2.1.5 {
   185    queryplan {
   186      SELECT * FROM tA, tB, tC LEFT JOIN tD ON dpk=cx
   187       WHERE cpk=bx AND ax=bpk
   188    }
   189  } {tA * tB * tC * tD *}
   190  do_test where3-2.2 {
   191    queryplan {
   192      SELECT * FROM tA, tB, tC LEFT JOIN tD ON dpk=cx
   193       WHERE cpk=bx AND apk=bx
   194    }
   195  } {tB * tA * tC * tD *}
   196  do_test where3-2.3 {
   197    queryplan {
   198      SELECT * FROM tA, tB, tC LEFT JOIN tD ON dpk=cx
   199       WHERE cpk=bx AND apk=bx
   200    }
   201  } {tB * tA * tC * tD *}
   202  do_test where3-2.4 {
   203    queryplan {
   204      SELECT * FROM tA, tB, tC LEFT JOIN tD ON dpk=cx
   205       WHERE apk=cx AND bpk=ax
   206    }
   207  } {tC * tA * tB * tD *}
   208  do_test where3-2.5 {
   209    queryplan {
   210      SELECT * FROM tA, tB, tC LEFT JOIN tD ON dpk=cx
   211       WHERE cpk=ax AND bpk=cx
   212    }
   213  } {tA * tC * tB * tD *}
   214  do_test where3-2.6 {
   215    queryplan {
   216      SELECT * FROM tA, tB, tC LEFT JOIN tD ON dpk=cx
   217       WHERE bpk=cx AND apk=bx
   218    }
   219  } {tC * tB * tA * tD *}
   220  do_test where3-2.7 {
   221    queryplan {
   222      SELECT * FROM tA, tB, tC LEFT JOIN tD ON dpk=cx
   223       WHERE cpk=bx AND apk=cx
   224    }
   225  } {tB * tC * tA * tD *}
   226  
   227  # Ticket [13f033c865f878953]
   228  # If the outer loop must be a full table scan, do not let ANALYZE trick
   229  # the planner into use a table for the outer loop that might be indexable
   230  # if held until an inner loop.
   231  # 
   232  do_execsql_test where3-3.0 {
   233    CREATE TABLE t301(a INTEGER PRIMARY KEY,b,c);
   234    CREATE INDEX t301c ON t301(c);
   235    INSERT INTO t301 VALUES(1,2,3);
   236    INSERT INTO t301 VALUES(2,2,3);
   237    CREATE TABLE t302(x, y);
   238    INSERT INTO t302 VALUES(4,5);
   239    ANALYZE;
   240  }
   241  do_eqp_test where3-3.0a {
   242    SELECT * FROM t302, t301 WHERE t302.x=5 AND t301.a=t302.y;
   243  } {
   244    QUERY PLAN
   245    |--SCAN t302
   246    `--SEARCH t301 USING INTEGER PRIMARY KEY (rowid=?)
   247  }
   248  do_eqp_test where3-3.1 {
   249    SELECT * FROM t301, t302 WHERE t302.x=5 AND t301.a=t302.y;
   250  } {
   251    QUERY PLAN
   252    |--SCAN t302
   253    `--SEARCH t301 USING INTEGER PRIMARY KEY (rowid=?)
   254  }
   255  do_execsql_test where3-3.2 {
   256    SELECT * FROM t301 WHERE c=3 AND a IS NULL;
   257  } {}
   258  do_execsql_test where3-3.3 {
   259    SELECT * FROM t301 WHERE c=3 AND a IS NOT NULL;
   260  } {1 2 3 2 2 3}
   261  
   262  if 0 {  # Query planner no longer does this
   263  # Verify that when there are multiple tables in a join which must be
   264  # full table scans that the query planner attempts put the table with
   265  # the fewest number of output rows as the outer loop.
   266  #
   267  do_execsql_test where3-4.0 {
   268    CREATE TABLE t400(a INTEGER PRIMARY KEY, b, c);
   269    CREATE TABLE t401(p INTEGER PRIMARY KEY, q, r);
   270    CREATE TABLE t402(x INTEGER PRIMARY KEY, y, z);
   271    EXPLAIN QUERY PLAN
   272    SELECT * FROM t400, t401, t402 WHERE t402.z GLOB 'abc*';
   273  } {
   274    0 0 2 {SCAN t402} 
   275    0 1 0 {SCAN t400} 
   276    0 2 1 {SCAN t401}
   277  }
   278  do_execsql_test where3-4.1 {
   279    EXPLAIN QUERY PLAN
   280    SELECT * FROM t400, t401, t402 WHERE t401.r GLOB 'abc*';
   281  } {
   282    0 0 1 {SCAN t401} 
   283    0 1 0 {SCAN t400} 
   284    0 2 2 {SCAN t402}
   285  }
   286  do_execsql_test where3-4.2 {
   287    EXPLAIN QUERY PLAN
   288    SELECT * FROM t400, t401, t402 WHERE t400.c GLOB 'abc*';
   289  } {
   290    0 0 0 {SCAN t400} 
   291    0 1 1 {SCAN t401} 
   292    0 2 2 {SCAN t402}
   293  }
   294  } ;# endif
   295  
   296  # Verify that a performance regression encountered by firefox
   297  # has been fixed.
   298  #
   299  do_execsql_test where3-5.0 {
   300    CREATE TABLE aaa (id INTEGER PRIMARY KEY, type INTEGER,
   301                      fk INTEGER DEFAULT NULL, parent INTEGER,
   302                      position INTEGER, title LONGVARCHAR,
   303                      keyword_id INTEGER, folder_type TEXT,
   304                      dateAdded INTEGER, lastModified INTEGER);
   305    CREATE INDEX aaa_111 ON aaa (fk, type);
   306    CREATE INDEX aaa_222 ON aaa (parent, position);
   307    CREATE INDEX aaa_333 ON aaa (fk, lastModified);
   308    CREATE TABLE bbb (id INTEGER PRIMARY KEY, type INTEGER,
   309                      fk INTEGER DEFAULT NULL, parent INTEGER,
   310                      position INTEGER, title LONGVARCHAR,
   311                      keyword_id INTEGER, folder_type TEXT,
   312                      dateAdded INTEGER, lastModified INTEGER);
   313    CREATE INDEX bbb_111 ON bbb (fk, type);
   314    CREATE INDEX bbb_222 ON bbb (parent, position);
   315    CREATE INDEX bbb_333 ON bbb (fk, lastModified);
   316  }
   317  do_eqp_test where3-5.0a {
   318     SELECT bbb.title AS tag_title 
   319       FROM aaa JOIN bbb ON bbb.id = aaa.parent  
   320      WHERE aaa.fk = 'constant'
   321        AND LENGTH(bbb.title) > 0
   322        AND bbb.parent = 4
   323      ORDER BY bbb.title COLLATE NOCASE ASC;
   324  } {
   325    QUERY PLAN
   326    |--SEARCH aaa USING INDEX aaa_333 (fk=?)
   327    |--SEARCH bbb USING INTEGER PRIMARY KEY (rowid=?)
   328    `--USE TEMP B-TREE FOR ORDER BY
   329  }
   330  do_eqp_test where3-5.1 {
   331     SELECT bbb.title AS tag_title 
   332       FROM aaa JOIN aaa AS bbb ON bbb.id = aaa.parent  
   333      WHERE aaa.fk = 'constant'
   334        AND LENGTH(bbb.title) > 0
   335        AND bbb.parent = 4
   336      ORDER BY bbb.title COLLATE NOCASE ASC;
   337  } {
   338    QUERY PLAN
   339    |--SEARCH aaa USING INDEX aaa_333 (fk=?)
   340    |--SEARCH bbb USING INTEGER PRIMARY KEY (rowid=?)
   341    `--USE TEMP B-TREE FOR ORDER BY
   342  }
   343  do_eqp_test where3-5.2 {
   344     SELECT bbb.title AS tag_title 
   345       FROM bbb JOIN aaa ON bbb.id = aaa.parent  
   346      WHERE aaa.fk = 'constant'
   347        AND LENGTH(bbb.title) > 0
   348        AND bbb.parent = 4
   349      ORDER BY bbb.title COLLATE NOCASE ASC;
   350  } {
   351    QUERY PLAN
   352    |--SEARCH aaa USING INDEX aaa_333 (fk=?)
   353    |--SEARCH bbb USING INTEGER PRIMARY KEY (rowid=?)
   354    `--USE TEMP B-TREE FOR ORDER BY
   355  }
   356  do_eqp_test where3-5.3 {
   357     SELECT bbb.title AS tag_title 
   358       FROM aaa AS bbb JOIN aaa ON bbb.id = aaa.parent  
   359      WHERE aaa.fk = 'constant'
   360        AND LENGTH(bbb.title) > 0
   361        AND bbb.parent = 4
   362      ORDER BY bbb.title COLLATE NOCASE ASC;
   363  } {
   364    QUERY PLAN
   365    |--SEARCH aaa USING INDEX aaa_333 (fk=?)
   366    |--SEARCH bbb USING INTEGER PRIMARY KEY (rowid=?)
   367    `--USE TEMP B-TREE FOR ORDER BY
   368  }
   369  
   370  # Name resolution with NATURAL JOIN and USING
   371  #
   372  do_test where3-6.setup {
   373    db eval {
   374      CREATE TABLE t6w(a, w);
   375      INSERT INTO t6w VALUES(1, 'w-one');
   376      INSERT INTO t6w VALUES(2, 'w-two');
   377      INSERT INTO t6w VALUES(9, 'w-nine');
   378      CREATE TABLE t6x(a, x);
   379      INSERT INTO t6x VALUES(1, 'x-one');
   380      INSERT INTO t6x VALUES(3, 'x-three');
   381      INSERT INTO t6x VALUES(9, 'x-nine');
   382      CREATE TABLE t6y(a, y);
   383      INSERT INTO t6y VALUES(1, 'y-one');
   384      INSERT INTO t6y VALUES(4, 'y-four');
   385      INSERT INTO t6y VALUES(9, 'y-nine');
   386      CREATE TABLE t6z(a, z);
   387      INSERT INTO t6z VALUES(1, 'z-one');
   388      INSERT INTO t6z VALUES(5, 'z-five');
   389      INSERT INTO t6z VALUES(9, 'z-nine');
   390    }
   391  } {}
   392  set cnt 0
   393  foreach predicate {
   394     {}
   395     {ORDER BY a}
   396     {ORDER BY t6w.a}
   397     {WHERE a>0}
   398     {WHERE t6y.a>0}
   399     {WHERE a>0 ORDER BY a}
   400  } {
   401    incr cnt
   402    do_test where3-6.$cnt.1 {
   403      set sql "SELECT * FROM t6w NATURAL JOIN t6x NATURAL JOIN t6y"
   404      append sql " NATURAL JOIN t6z "
   405      append sql $::predicate
   406      db eval $sql
   407    } {1 w-one x-one y-one z-one 9 w-nine x-nine y-nine z-nine}
   408    do_test where3-6.$cnt.2 {
   409      set sql "SELECT * FROM t6w JOIN t6x USING(a) JOIN t6y USING(a)"
   410      append sql " JOIN t6z USING(a) "
   411      append sql $::predicate
   412      db eval $sql
   413    } {1 w-one x-one y-one z-one 9 w-nine x-nine y-nine z-nine}
   414    do_test where3-6.$cnt.3 {
   415      set sql "SELECT * FROM t6w NATURAL JOIN t6x JOIN t6y USING(a)"
   416      append sql " JOIN t6z USING(a) "
   417      append sql $::predicate
   418      db eval $sql
   419    } {1 w-one x-one y-one z-one 9 w-nine x-nine y-nine z-nine}
   420    do_test where3-6.$cnt.4 {
   421      set sql "SELECT * FROM t6w JOIN t6x USING(a) NATURAL JOIN t6y"
   422      append sql " JOIN t6z USING(a) "
   423      append sql $::predicate
   424      db eval $sql
   425    } {1 w-one x-one y-one z-one 9 w-nine x-nine y-nine z-nine}
   426    do_test where3-6.$cnt.5 {
   427      set sql "SELECT * FROM t6w JOIN t6x USING(a) JOIN t6y USING(a)"
   428      append sql " NATURAL JOIN t6z "
   429      append sql $::predicate
   430      db eval $sql
   431    } {1 w-one x-one y-one z-one 9 w-nine x-nine y-nine z-nine}
   432    do_test where3-6.$cnt.6 {
   433      set sql "SELECT * FROM t6w JOIN t6x USING(a) NATURAL JOIN t6y"
   434      append sql " NATURAL JOIN t6z "
   435      append sql $::predicate
   436      db eval $sql
   437    } {1 w-one x-one y-one z-one 9 w-nine x-nine y-nine z-nine}
   438    do_test where3-6.$cnt.7 {
   439      set sql "SELECT * FROM t6w NATURAL JOIN t6x JOIN t6y USING(a)"
   440      append sql " NATURAL JOIN t6z "
   441      append sql $::predicate
   442      db eval $sql
   443    } {1 w-one x-one y-one z-one 9 w-nine x-nine y-nine z-nine}
   444    do_test where3-6.$cnt.8 {
   445      set sql "SELECT * FROM t6w NATURAL JOIN t6x NATURAL JOIN t6y"
   446      append sql " JOIN t6z USING(a) "
   447      append sql $::predicate
   448      db eval $sql
   449    } {1 w-one x-one y-one z-one 9 w-nine x-nine y-nine z-nine}
   450  }
   451  
   452  do_execsql_test where3-7-setup {
   453    CREATE TABLE t71(x1 INTEGER PRIMARY KEY, y1);
   454    CREATE TABLE t72(x2 INTEGER PRIMARY KEY, y2);
   455    CREATE TABLE t73(x3, y3);
   456    CREATE TABLE t74(x4, y4);
   457    INSERT INTO t71 VALUES(123,234);
   458    INSERT INTO t72 VALUES(234,345);
   459    INSERT INTO t73 VALUES(123,234);
   460    INSERT INTO t74 VALUES(234,345);
   461    INSERT INTO t74 VALUES(234,678);
   462  } {}
   463  foreach disabled_opt {none omit-noop-join all} {
   464    optimization_control db all 1
   465    optimization_control db $disabled_opt 0
   466    do_execsql_test where3-7.$disabled_opt.1 {
   467      SELECT x1 FROM t71 LEFT JOIN t72 ON x2=y1;
   468    } {123}
   469    do_execsql_test where3-7.$disabled_opt.2 {
   470      SELECT x1 FROM t71 LEFT JOIN t72 ON x2=y1 WHERE y2 IS NULL;
   471    } {}
   472    do_execsql_test where3-7.$disabled_opt.3 {
   473      SELECT x1 FROM t71 LEFT JOIN t72 ON x2=y1 WHERE y2 IS NOT NULL;
   474    } {123}
   475    do_execsql_test where3-7.$disabled_opt.4 {
   476      SELECT x1 FROM t71 LEFT JOIN t72 ON x2=y1 AND y2 IS NULL;
   477    } {123}
   478    do_execsql_test where3-7.$disabled_opt.5 {
   479      SELECT x1 FROM t71 LEFT JOIN t72 ON x2=y1 AND y2 IS NOT NULL;
   480    } {123}
   481    do_execsql_test where3-7.$disabled_opt.6 {
   482      SELECT x3 FROM t73 LEFT JOIN t72 ON x2=y3;
   483    } {123}
   484    do_execsql_test where3-7.$disabled_opt.7 {
   485      SELECT DISTINCT x3 FROM t73 LEFT JOIN t72 ON x2=y3;
   486    } {123}
   487    do_execsql_test where3-7.$disabled_opt.8 {
   488      SELECT x3 FROM t73 LEFT JOIN t74 ON x4=y3;
   489    } {123 123}
   490    do_execsql_test where3-7.$disabled_opt.9 {
   491      SELECT DISTINCT x3 FROM t73 LEFT JOIN t74 ON x4=y3;
   492    } {123}
   493  }
   494  
   495  
   496  finish_test