15c193464Sdan# 2020-02-23 25c193464Sdan# 35c193464Sdan# The author disclaims copyright to this source code. In place of 45c193464Sdan# a legal notice, here is a blessing: 55c193464Sdan# 65c193464Sdan# May you do good and not evil. 75c193464Sdan# May you find forgiveness for yourself and forgive others. 85c193464Sdan# May you share freely, never taking more than you give. 95c193464Sdan# 105c193464Sdan#*********************************************************************** 115c193464Sdan# Tests for functionality related to ANALYZE. 125c193464Sdan# 135c193464Sdan 145c193464Sdanset testdir [file dirname $argv0] 155c193464Sdansource $testdir/tester.tcl 165c193464Sdan 1735d3cb80Sdrhifcapable !stat4 { 1835d3cb80Sdrh finish_test 1935d3cb80Sdrh return 2035d3cb80Sdrh} 215c193464Sdanset testprefix analyzeG 225c193464Sdan 235c193464Sdan#------------------------------------------------------------------------- 245c193464Sdan# Test cases 1.* seek to verify that even if an index is not used, its 255c193464Sdan# stat4 data may be used by the planner to estimate the number of 265c193464Sdan# rows that match an unindexed constraint on the same column. 275c193464Sdan# 285c193464Sdando_execsql_test 1.0 { 295c193464Sdan PRAGMA automatic_index = 0; 305c193464Sdan CREATE TABLE t1(a, x); 315c193464Sdan CREATE TABLE t2(b, y); 325c193464Sdan WITH s(i) AS ( 335c193464Sdan SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<100 345c193464Sdan ) 355c193464Sdan INSERT INTO t1 SELECT (i%50), NULL FROM s; 365c193464Sdan WITH s(i) AS ( 375c193464Sdan SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<100 385c193464Sdan ) 395c193464Sdan INSERT INTO t2 SELECT (CASE WHEN i<95 THEN 44 ELSE i END), NULL FROM s; 405c193464Sdan} 415c193464Sdan 425c193464Sdan# Join tables t1 and t2. Both contain 100 rows. (a=44) matches 2 rows 435c193464Sdan# in "t1", (b=44) matches 95 rows in table "t2". But the planner doesn't 445c193464Sdan# know this, so it has no preference as to which order the tables are 455c193464Sdan# scanned in. In practice this means that tables are scanned in the order 465c193464Sdan# they are specified in in the FROM clause. 47*06c7cc76Sdrhdo_eqp_test 1.1.1 { 485c193464Sdan SELECT * FROM t1, t2 WHERE a=44 AND b=44; 495c193464Sdan} { 50*06c7cc76Sdrh 515c193464Sdan} 52*06c7cc76Sdrhdo_eqp_test 1.1.2 { 535c193464Sdan SELECT * FROM t2, t1 WHERE a=44 AND b=44 545c193464Sdan} { 55*06c7cc76Sdrh QUERY PLAN 56*06c7cc76Sdrh |--SCAN t2 57*06c7cc76Sdrh `--SCAN t1 585c193464Sdan} 595c193464Sdan 605c193464Sdando_execsql_test 1.2 { 615c193464Sdan CREATE INDEX t2b ON t2(b); 625c193464Sdan ANALYZE; 635c193464Sdan} 645c193464Sdan 655c193464Sdan# Now, with the ANALYZE data, the planner knows that (b=44) matches a 665c193464Sdan# large number of rows. So it elects to scan table "t1" first, regardless 675c193464Sdan# of the order in which the tables are specified in the FROM clause. 68*06c7cc76Sdrhdo_eqp_test 1.3.1 { 695c193464Sdan SELECT * FROM t1, t2 WHERE a=44 AND b=44; 705c193464Sdan} { 71*06c7cc76Sdrh QUERY PLAN 72*06c7cc76Sdrh |--SCAN t1 73*06c7cc76Sdrh `--SCAN t2 745c193464Sdan} 75*06c7cc76Sdrhdo_eqp_test 1.3.2 { 765c193464Sdan SELECT * FROM t2, t1 WHERE a=44 AND b=44 775c193464Sdan} { 78*06c7cc76Sdrh QUERY PLAN 79*06c7cc76Sdrh |--SCAN t1 80*06c7cc76Sdrh `--SCAN t2 815c193464Sdan} 825c193464Sdan 835c193464Sdan 845c193464Sdanfinish_test 85