| # 2016 June 17 | |
| # | |
| # The author disclaims copyright to this source code. In place of | |
| # a legal notice, here is a blessing: | |
| # | |
| # May you do good and not evil. | |
| # May you find forgiveness for yourself and forgive others. | |
| # May you share freely, never taking more than you give. | |
| # | |
| #*********************************************************************** | |
| # This file implements regression tests for SQLite library. The | |
| # focus of this file is testing the SELECT statement. | |
| # | |
| set testdir [file dirname $argv0] | |
| source $testdir/tester.tcl | |
| set ::testprefix rowvalue2 | |
| do_execsql_test 1.0 { | |
| CREATE TABLE t1(a, b, c); | |
| INSERT INTO t1 VALUES(0, 0, 0); | |
| INSERT INTO t1 VALUES(0, 1, 1); | |
| INSERT INTO t1 VALUES(1, 0, 2); | |
| INSERT INTO t1 VALUES(1, 1, 3); | |
| CREATE INDEX i1 ON t1(a, b); | |
| } | |
| do_execsql_test 1.1.1 { SELECT c FROM t1 WHERE (a, b) >= (1, 0) } {2 3} | |
| do_execsql_test 1.1.2 { SELECT c FROM t1 WHERE (a, b) > (1, 0) } {3} | |
| #------------------------------------------------------------------------- | |
| do_execsql_test 2.0.1 { | |
| CREATE TABLE t2(a INTEGER, b INTEGER, c INTEGER, d INTEGER); | |
| CREATE INDEX i2 ON t2(a, b, c); | |
| } | |
| do_test 2.0.2 { | |
| foreach a {0 1 2 3} { | |
| foreach b {0 1 2 3} { | |
| foreach c {0 1 2 3} { | |
| execsql { INSERT INTO t2 VALUES($a, $b, $c, $c + $b*4 + $a*16); } | |
| }}} | |
| } {} | |
| do_execsql_test 2.1 { | |
| SELECT d FROM t2 WHERE (a, b) > (2, 2); | |
| } [db eval { SELECT d FROM t2 WHERE a>2 OR (a=2 AND b>2) }] | |
| do_execsql_test 2.2 { | |
| SELECT d FROM t2 WHERE (a, b) >= (2, 2); | |
| } [db eval { SELECT d FROM t2 WHERE a>2 OR (a=2 AND b>=2) }] | |
| do_execsql_test 2.3 { | |
| SELECT d FROM t2 WHERE a=1 AND (b, c) >= (1, 2); | |
| } [db eval { SELECT d FROM t2 WHERE +a=1 AND (b>1 OR (b==1 AND c>=2)) }] | |
| do_execsql_test 2.4 { | |
| SELECT d FROM t2 WHERE a=1 AND (b, c) > (1, 2); | |
| } [db eval { SELECT d FROM t2 WHERE +a=1 AND (b>1 OR (b==1 AND c>2)) }] | |
| #------------------------------------------------------------------------- | |
| set words { | |
| airfare airfield airfields airflow airfoil | |
| airfoils airframe airframes airily airing | |
| airings airless airlift airlifts airline | |
| airliner airlines airlock airlocks airmail | |
| airmails airman airmen airplane airplanes | |
| arraignment arraignments arraigns arrange arranged | |
| arrangement arrangements arranger arrangers arranges | |
| arranging arrant array arrayed arrays | |
| arrears arrest arrested arrester arresters | |
| arresting arrestingly arrestor arrestors arrests | |
| edifices edit edited editing edition | |
| editions editor editorial editorially editorials | |
| editors edits educable educate educated | |
| educates educating education educational educationally | |
| educations educator educators eel eelgrass | |
| } | |
| do_test 3.0 { | |
| execsql { CREATE TABLE t3(a, b, c, w); } | |
| foreach w $words { | |
| set a [string range $w 0 2] | |
| set b [string range $w 3 5] | |
| set c [string range $w 6 end] | |
| execsql { INSERT INTO t3 VALUES($a, $b, $c, $w) } | |
| } | |
| } {} | |
| foreach {tn idx} { | |
| IDX1 {} | |
| IDX2 { CREATE INDEX i3 ON t3(a, b, c); } | |
| IDX3 { CREATE INDEX i3 ON t3(a, b); } | |
| IDX4 { CREATE INDEX i3 ON t3(a); } | |
| } { | |
| execsql { DROP INDEX IF EXISTS i3 } | |
| execsql $idx | |
| foreach w $words { | |
| set a [string range $w 0 2] | |
| set b [string range $w 3 5] | |
| set c [string range $w 6 end] | |
| foreach op [list > >= < <= == IS] { | |
| do_execsql_test 3.1.$tn.$w.$op [subst -novar { | |
| SELECT rowid FROM t3 WHERE (a, b, c) [set op] ($a, $b, $c) | |
| ORDER BY +rowid | |
| }] [db eval [subst -novar { | |
| SELECT rowid FROM t3 WHERE w [set op] $w ORDER BY +rowid | |
| }]] | |
| do_execsql_test 3.1.$tn.$w.$op.subselect [subst -novar { | |
| SELECT rowid FROM t3 WHERE (a, b, c) [set op] ( | |
| SELECT a, b, c FROM t3 WHERE w = $w | |
| ) | |
| ORDER BY +rowid | |
| }] [db eval [subst -novar { | |
| SELECT rowid FROM t3 WHERE w [set op] $w ORDER BY +rowid | |
| }]] | |
| } | |
| } | |
| } | |
| #------------------------------------------------------------------------- | |
| # | |
| do_execsql_test 4.0 { | |
| CREATE TABLE t4(a, b, c); | |
| INSERT INTO t4 VALUES(NULL, NULL, NULL); | |
| INSERT INTO t4 VALUES(NULL, NULL, 0); | |
| INSERT INTO t4 VALUES(NULL, NULL, 1); | |
| INSERT INTO t4 VALUES(NULL, 0, NULL); | |
| INSERT INTO t4 VALUES(NULL, 0, 0); | |
| INSERT INTO t4 VALUES(NULL, 0, 1); | |
| INSERT INTO t4 VALUES(NULL, 1, NULL); | |
| INSERT INTO t4 VALUES(NULL, 1, 0); | |
| INSERT INTO t4 VALUES(NULL, 1, 1); | |
| INSERT INTO t4 VALUES( 0, NULL, NULL); | |
| INSERT INTO t4 VALUES( 0, NULL, 0); | |
| INSERT INTO t4 VALUES( 0, NULL, 1); | |
| INSERT INTO t4 VALUES( 0, 0, NULL); | |
| INSERT INTO t4 VALUES( 0, 0, 0); | |
| INSERT INTO t4 VALUES( 0, 0, 1); | |
| INSERT INTO t4 VALUES( 0, 1, NULL); | |
| INSERT INTO t4 VALUES( 0, 1, 0); | |
| INSERT INTO t4 VALUES( 0, 1, 1); | |
| INSERT INTO t4 VALUES( 1, NULL, NULL); | |
| INSERT INTO t4 VALUES( 1, NULL, 0); | |
| INSERT INTO t4 VALUES( 1, NULL, 1); | |
| INSERT INTO t4 VALUES( 1, 0, NULL); | |
| INSERT INTO t4 VALUES( 1, 0, 0); | |
| INSERT INTO t4 VALUES( 1, 0, 1); | |
| INSERT INTO t4 VALUES( 1, 1, NULL); | |
| INSERT INTO t4 VALUES( 1, 1, 0); | |
| INSERT INTO t4 VALUES( 1, 1, 1); | |
| } | |
| proc make_expr1 {cList vList op} { | |
| return "([join $cList ,]) $op ([join $vList ,])" | |
| } | |
| proc make_expr3 {cList vList op} { | |
| set n [llength $cList] | |
| set aList [list] | |
| foreach c [lrange $cList 0 end-1] v [lrange $vList 0 end-1] { | |
| lappend aList "$c == $v" | |
| } | |
| lappend aList "[lindex $cList end] $op [lindex $vList end]" | |
| return "([join $aList { AND }])" | |
| } | |
| proc make_expr2 {cList vList op} { | |
| set ret "" | |
| switch -- $op { | |
| == - IS { | |
| set aList [list] | |
| foreach c $cList v $vList { lappend aList "($c $op $v)" } | |
| set ret [join $aList " AND "] | |
| } | |
| < - > { | |
| set oList [list] | |
| for {set i 0} {$i < [llength $cList]} {incr i} { | |
| lappend oList [make_expr3 [lrange $cList 0 $i] [lrange $vList 0 $i] $op] | |
| } | |
| set ret [join $oList " OR "] | |
| } | |
| <= - >= { | |
| set o2 [string range $op 0 0] | |
| set oList [list] | |
| for {set i 0} {$i < [llength $cList]-1} {incr i} { | |
| lappend oList [make_expr3 [lrange $cList 0 $i] [lrange $vList 0 $i] $o2] | |
| } | |
| lappend oList [make_expr3 $cList $vList $op] | |
| set ret [join $oList " OR "] | |
| } | |
| default { | |
| error "Unknown op: $op" | |
| } | |
| } | |
| set ret | |
| } | |
| foreach {tn idx} { | |
| IDX1 {} | |
| IDX2 { CREATE INDEX i4 ON t4(a, b, c); } | |
| IDX3 { CREATE INDEX i4 ON t4(a, b); } | |
| IDX4 { CREATE INDEX i4 ON t4(a); } | |
| } { | |
| execsql { DROP INDEX IF EXISTS i4 } | |
| execsql $idx | |
| foreach {tn2 vector} { | |
| 1 {0 0 0} | |
| 2 {1 1 1} | |
| 3 {0 0 NULL} | |
| 4 {0 NULL 0} | |
| 5 {NULL 0 0} | |
| 6 {1 1 NULL} | |
| 7 {1 NULL 1} | |
| 8 {NULL 1 1} | |
| } { | |
| foreach op { IS == < <= > >= } { | |
| set e1 [make_expr1 {a b c} $vector $op] | |
| set e2 [make_expr2 {a b c} $vector $op] | |
| do_execsql_test 4.$tn.$tn2.$op \ | |
| "SELECT rowid FROM t4 WHERE $e2 ORDER BY +rowid" [ | |
| db eval "SELECT rowid FROM t4 WHERE $e1 ORDER BY +rowid" | |
| ] | |
| } | |
| } | |
| } | |
| do_execsql_test 5.0 { | |
| CREATE TABLE r1(a TEXT, iB TEXT); | |
| CREATE TABLE r2(x TEXT, zY INTEGER); | |
| CREATE INDEX r1ab ON r1(a, iB); | |
| INSERT INTO r1 VALUES(35, 35); | |
| INSERT INTO r2 VALUES(35, 36); | |
| INSERT INTO r2 VALUES(35, 4); | |
| INSERT INTO r2 VALUES(35, 35); | |
| } {} | |
| foreach {tn lhs rhs} { | |
| 1 {x +zY} {a iB} | |
| 2 {x zY} {a iB} | |
| 3 {x zY} {a +iB} | |
| 4 {+x zY} {a iB} | |
| 5 {x zY} {+a iB} | |
| } { | |
| foreach op { IS == < <= > >= } { | |
| set e1 [make_expr1 $lhs $rhs $op] | |
| set e2 [make_expr2 $lhs $rhs $op] | |
| do_execsql_test 5.$tn.$op \ | |
| "SELECT * FROM r1, r2 WHERE $e2 ORDER BY iB" [db eval \ | |
| "SELECT * FROM r1, r2 WHERE $e1 ORDER BY iB" | |
| ] | |
| } | |
| } | |
| finish_test |