github.com/jdgcs/sqlite3@v1.12.1-0.20210908114423-bc5f96e4dd51/testdata/tcl/cursorhint2.test (about)

     1  # 2016 June 17
     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 is on testing that cursor-hints are correct for queries
    13  # involving LEFT JOIN.
    14  #
    15  
    16  
    17  set testdir [file dirname $argv0]
    18  source $testdir/tester.tcl
    19  set ::testprefix cursorhint2
    20  
    21  ifcapable !cursorhints {
    22    finish_test
    23    return
    24  }
    25  
    26  proc extract_hints {sql} {
    27  
    28    db eval "SELECT tbl_name, rootpage FROM sqlite_master where rootpage" {
    29      set lookup($rootpage) $tbl_name
    30    }
    31  
    32    set ret [list]
    33    db eval "EXPLAIN $sql" a {
    34      switch -- $a(opcode) {
    35        OpenRead {
    36          set csr($a(p1)) $lookup($a(p2))
    37        }
    38        CursorHint { 
    39          lappend ret $csr($a(p1)) $a(p4) 
    40        }
    41      }
    42    }
    43  
    44    set ret
    45  }
    46  
    47  proc do_extract_hints_test {tn sql ret} {
    48    uplevel [list do_test $tn [list extract_hints $sql] [list {*}$ret]]
    49  }
    50  
    51  do_execsql_test 1.0 {
    52    PRAGMA automatic_index = 0;
    53    CREATE TABLE t1(a, b);
    54    CREATE TABLE t2(c, d);
    55    CREATE TABLE t3(e, f);
    56  }
    57  
    58  do_extract_hints_test 1.1 {
    59    SELECT * FROM t1 WHERE a=1;
    60  } {
    61    t1 EQ(c0,1)
    62  }
    63  
    64  do_extract_hints_test 1.2 {
    65    SELECT * FROM t1 CROSS JOIN t2 ON (a=c) WHERE d IS NULL;
    66  } {
    67    t2 {AND(ISNULL(c1),EQ(r[1],c0))}
    68  }
    69  
    70  do_extract_hints_test 1.3 {
    71    SELECT * FROM t1 LEFT JOIN t2 ON (a=c) WHERE d IS NULL;
    72  } {
    73    t2 {EQ(r[2],c0)}
    74  }
    75  
    76  do_extract_hints_test 1.4 {
    77    SELECT * FROM t1 LEFT JOIN t2 ON (a=c AND a=10) WHERE d IS NULL;
    78  } {
    79    t2 {AND(EQ(r[2],c0),EQ(r[3],10))}
    80  }
    81  
    82  do_extract_hints_test 1.5 {
    83    SELECT * FROM t1 CROSS JOIN t2 ON (a=c AND a=10) WHERE d IS NULL;
    84  } {
    85    t1 EQ(c0,10) t2 {AND(ISNULL(c1),EQ(r[3],c0))}
    86  }
    87  
    88  do_extract_hints_test 1.6 {
    89    SELECT * FROM t1 LEFT JOIN t2 ON (a=c) LEFT JOIN t3 ON (d=f);
    90  } {
    91    t2 {EQ(r[2],c0)} t3 {EQ(r[6],c1)}
    92  }
    93  
    94  if 0 {
    95    do_extract_hints_test 1.7 {
    96      SELECT * FROM t1 LEFT JOIN t2 ON (a=c AND d=e) LEFT JOIN t3 ON (d=f);
    97    } {
    98      t2 {EQ(r[2],c0)} t3 {AND(EQ(r[6],c0),EQ(r[7],c1))}
    99    }
   100  }
   101  
   102  #-------------------------------------------------------------------------
   103  #
   104  do_execsql_test 2.0 {
   105    CREATE TABLE x1(x, y);
   106    CREATE TABLE x2(a, b);
   107  }
   108  
   109  do_extract_hints_test 2.1 {
   110    SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE b IS NULL;
   111  } {
   112    x2 {EQ(c0,r[2])}
   113  }
   114  
   115  do_extract_hints_test 2.2 {
   116    SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE b IS +NULL;
   117  } {
   118    x2 {EQ(c0,r[2])}
   119  }
   120  
   121  do_extract_hints_test 2.3 {
   122    SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE 1 = (b IS NULL)
   123  } {
   124    x2 {EQ(c0,r[2])}
   125  }
   126  
   127  do_extract_hints_test 2.4 {
   128    SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE 1 = coalesce(b, 1)
   129  } {
   130    x2 {EQ(c0,r[2])}
   131  }
   132  
   133  do_extract_hints_test 2.5 {
   134    SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE 1 = coalesce(b, 1)
   135  } {
   136    x2 {EQ(c0,r[2])}
   137  }
   138  
   139  if {0} {
   140    # These tests no longer work due to the LEFT-JOIN strength reduction
   141    # optimization
   142    do_extract_hints_test 2.6 {
   143      SELECT * FROM x1 CROSS JOIN x2 ON (a=x) WHERE 0 = (b IS NOT NULL)
   144    } {
   145      x2 {EQ(c0,r[2])}
   146    }
   147    
   148    do_extract_hints_test 2.7 {
   149      SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE 0 = (b IS NOT +NULL)
   150    } {
   151      x2 {EQ(c0,r[2])}
   152    }
   153    
   154    do_extract_hints_test 2.8 {
   155      SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE b IS NOT +NULL
   156    } {
   157      x2 {EQ(c0,r[2])}
   158    }
   159    
   160    do_extract_hints_test 2.9 {
   161      SELECT * FROM x1 LEFT JOIN x2 ON (a=x)
   162        WHERE CASE b WHEN 0 THEN 0 ELSE 1 END;
   163    } {
   164      x2 {EQ(c0,r[2])}
   165    }
   166    
   167    do_extract_hints_test 2.10 {
   168      SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE x2.b = 32+32
   169    } {
   170      x2 {AND(EQ(c1,ADD(32,32)),EQ(c0,r[2]))}
   171    }
   172    
   173    ifcapable !icu {
   174      # This test only works using the built-in LIKE, not the ICU LIKE extension.
   175      do_extract_hints_test 2.11 {
   176        SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE x2.b LIKE 'abc%'
   177      } {
   178        x2 {AND(expr,EQ(c0,r[2]))}
   179      }
   180    }
   181  }
   182    
   183  do_extract_hints_test 2.12 {
   184    SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE coalesce(x2.b, 1)
   185  } {
   186    x2 {EQ(c0,r[2])}
   187  }
   188  
   189  reset_db
   190  do_execsql_test 3.0 {
   191    CREATE TABLE t1 (i1 TEXT);    
   192    CREATE TABLE t2 (i2 TEXT UNIQUE);    
   193    INSERT INTO t1 VALUES('0');
   194    INSERT INTO t2 VALUES('0');
   195  }
   196  
   197  do_extract_hints_test 3.1 {
   198    SELECT * FROM t1 CROSS JOIN t2 WHERE (t1.i1 = t2.i2) AND t2.i2 = 1;
   199  } {
   200    t1 {EQ(c0,r[1])} t2 EQ(c0,1)
   201  }
   202  
   203  
   204  finish_test