diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/scanstatus.test | 14 | ||||
-rw-r--r-- | test/scanstatus2.test | 159 |
2 files changed, 167 insertions, 6 deletions
diff --git a/test/scanstatus.test b/test/scanstatus.test index 46249f665..caad70c5b 100644 --- a/test/scanstatus.test +++ b/test/scanstatus.test @@ -36,7 +36,9 @@ proc do_scanstatus_test {tn res} { while {1} { set r [sqlite3_stmt_scanstatus $stmt $idx] if {[llength $r]==0} break - lappend ret {*}$r + foreach v {nLoop nVisit nEst zName zExplain} { + lappend ret $v [dict get $r $v] + } incr idx } @@ -312,8 +314,8 @@ do_execsql_test 5.1.1 { SELECT count(*) FROM t1 WHERE a IN (SELECT b FROM t1 AS ii) } {2} do_scanstatus_test 5.1.2 { - nLoop 1 nVisit 10 nEst 10.0 zName t1bc - zExplain {SCAN ii USING COVERING INDEX t1bc} + nLoop 1 nVisit 10 nEst 10.0 zName t1 + zExplain {SCAN ii} nLoop 1 nVisit 2 nEst 8.0 zName sqlite_autoindex_t1_1 zExplain {SEARCH t1 USING COVERING INDEX sqlite_autoindex_t1_1 (a=?)} } @@ -341,15 +343,15 @@ do_eqp_test 5.4.1 { SELECT count(*) FROM t1, t2 WHERE y = c; } { QUERY PLAN - |--SCAN t1 USING COVERING INDEX t1bc + |--SCAN t1 `--SEARCH t2 USING COVERING INDEX t2xy (ANY(x) AND y=?) } do_execsql_test 5.4.2 { SELECT count(*) FROM t1, t2 WHERE y = c; } {200} do_scanstatus_test 5.4.3 { - nLoop 1 nVisit 10 nEst 10.0 zName t1bc - zExplain {SCAN t1 USING COVERING INDEX t1bc} + nLoop 1 nVisit 10 nEst 10.0 zName t1 + zExplain {SCAN t1} nLoop 10 nVisit 200 nEst 56.0 zName t2xy zExplain {SEARCH t2 USING COVERING INDEX t2xy (ANY(x) AND y=?)} } diff --git a/test/scanstatus2.test b/test/scanstatus2.test new file mode 100644 index 000000000..3c5b4b16a --- /dev/null +++ b/test/scanstatus2.test @@ -0,0 +1,159 @@ +# 2022 December 5 +# +# 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. +# +#*********************************************************************** +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix scanstatus2 + +ifcapable !scanstatus { + finish_test + return +} + +do_execsql_test 1.0 { + CREATE TABLE t1(a, b); + CREATE TABLE t2(x, y); + INSERT INTO t1 VALUES(1, 2); + INSERT INTO t1 VALUES(3, 4); + INSERT INTO t2 VALUES('a', 'b'); + INSERT INTO t2 VALUES('c', 'd'); + INSERT INTO t2 VALUES('e', 'f'); +} + +proc do_zexplain_test {v2 tn sql res} { + db eval $sql + set stmt [db version -last-stmt-ptr] + set idx 0 + set ret [list] + + set cmd sqlite3_stmt_scanstatus + set f [list] + if {$v2} { lappend f complex } + + while {1} { + set r [sqlite3_stmt_scanstatus -flags $f $stmt $idx] + if {[llength $r]==0} break + lappend ret [dict get $r zExplain] + incr idx + } + uplevel [list do_test $tn [list set {} $ret] [list {*}$res]] +} + +proc get_cycles {stmt} { + set r [sqlite3_stmt_scanstatus $stmt -1] + dict get $r nCycle +} + +proc foreach_scan {varname stmt body} { + upvar $varname var + + for {set ii 0} {1} {incr ii} { + set r [sqlite3_stmt_scanstatus -flags complex $stmt $ii] + if {[llength $r]==0} break + array set var $r + uplevel $body + } +} + +proc get_eqp_graph {stmt iPar nIndent} { + set res "" + foreach_scan A $stmt { + if {$A(iParentId)==$iPar} { + set txt $A(zExplain) + if {$A(nCycle)>=0} { + append txt " (nCycle=$A(nCycle))" + } + append res "[string repeat - $nIndent]$txt\n" + append res [get_eqp_graph $stmt $A(iSelectId) [expr $nIndent+2]] + } + } + set res +} + +proc get_graph {stmt} { + set nCycle [get_cycles $stmt] + set res "QUERY (nCycle=$nCycle)\n" + append res [get_eqp_graph $stmt 0 2] +} + +proc do_graph_test {tn sql res} { + db eval $sql + set stmt [db version -last-stmt-ptr] + + set graph [string trim [get_graph $stmt]] + set graph [regsub -all {nCycle=[0-9]+} $graph nCycle=nnn] + uplevel [list do_test $tn [list set {} $graph] [string trim $res]] +} + +proc puts_graph {sql} { + db eval $sql + set stmt [db version -last-stmt-ptr] + puts [string trim [get_graph $stmt]] +} + + +do_zexplain_test 0 1.1 { + SELECT (SELECT a FROM t1 WHERE b=x) FROM t2 WHERE y=2 +} { + {SCAN t2} + {SCAN t1} +} +do_zexplain_test 1 1.2 { + SELECT (SELECT a FROM t1 WHERE b=x) FROM t2 WHERE y=2 +} { + {SCAN t2} + {CORRELATED SCALAR SUBQUERY 1} + {SCAN t1} +} + +do_graph_test 1.3 { + SELECT (SELECT a FROM t1 WHERE b=x) FROM t2 WHERE y=2 +} { +QUERY (nCycle=nnn) +--SCAN t2 +--CORRELATED SCALAR SUBQUERY 1 (nCycle=nnn) +----SCAN t1 +} + +do_graph_test 1.4 { + WITH v2(x,y) AS MATERIALIZED ( + SELECT x,y FROM t2 + ) + SELECT * FROM t1, v2 ORDER BY y; +} { +QUERY (nCycle=nnn) +--MATERIALIZE v2 (nCycle=nnn) +----SCAN t2 +--SCAN v2 +--SCAN t1 +--USE TEMP B-TREE FOR ORDER BY (nCycle=nnn) +} + +#------------------------------------------------------------------------- +reset_db +do_execsql_test 2.0 { + CREATE VIRTUAL TABLE ft USING fts5(a); + INSERT INTO ft VALUES('abc'); + INSERT INTO ft VALUES('def'); + INSERT INTO ft VALUES('ghi'); +} + +do_graph_test 2.1 { + SELECT * FROM ft('def') +} { +QUERY (nCycle=nnn) +--SCAN ft VIRTUAL TABLE INDEX 0:M1 (nCycle=nnn) +} + +finish_test + + |