1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199
|
#!/usr/bin/env tarantool
test = require("sqltester")
test:plan(13)
--!./tcltestrunner.lua
-- 2011 March 3
--
-- 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 tests for sql library. The focus of the tests
-- in this file a corner-case query planner optimization involving the
-- join order of two tables of different sizes.
--
-- ["set","testdir",[["file","dirname",["argv0"]]]]
-- ["source",[["testdir"],"\/tester.tcl"]]
testprefix = "analyze6"
test:do_test(
"analyze6-1.0",
function()
return test:execsql([[
CREATE TABLE cat(id INTEGER PRIMARY KEY AUTOINCREMENT, x INT, yz TEXT);
CREATE UNIQUE INDEX catx ON cat(x);
/* Give cat 16 unique integers */
INSERT INTO cat(x) VALUES(1);
INSERT INTO cat(x) VALUES(2);
INSERT INTO cat(x) SELECT x+2 FROM cat;
INSERT INTO cat(x) SELECT x+4 FROM cat;
INSERT INTO cat(x) SELECT x+8 FROM cat;
CREATE TABLE ev(id INTEGER PRIMARY KEY AUTOINCREMENT, y INT);
CREATE INDEX evy ON ev(y);
/* ev will hold 32 copies of 16 integers found in cat */
INSERT INTO ev(y) SELECT x FROM cat;
INSERT INTO ev(y) SELECT x FROM cat;
INSERT INTO ev(y) SELECT y FROM ev;
INSERT INTO ev(y) SELECT y FROM ev;
INSERT INTO ev(y) SELECT y FROM ev;
INSERT INTO ev(y) SELECT y FROM ev;
ANALYZE;
SELECT count(*) FROM cat;
]])
end, {
-- <analyze6-1.0>
16
-- </analyze6-1.0>
})
test:do_test(
"analyze6-1.0.1",
function()
return test:execsql([[
SELECT count(*) FROM ev;
]])
end, {
-- <analyze6-1.0>
512
-- </analyze6-1.0>
})
-- The lowest cost plan is to scan CAT and for each integer there, do a single
-- lookup of the first corresponding entry in EV then read off the equal values
-- in EV. (Prior to the 2011-03-04 enhancement to where.c, this query would
-- have used EV for the outer loop instead of CAT - which was about 3x slower.)
--
test:do_eqp_test(
"analyze6-1.1",
[[SELECT count(*) FROM ev, cat WHERE x=y;]],
{
-- <analyze6-1.1>
{0, 0, 1, "SCAN TABLE CAT"}, {0, 1, 0, "SEARCH TABLE EV USING COVERING INDEX EVY (Y=?)"}
-- </analyze6-1.1>
})
-- The same plan is chosen regardless of the order of the tables in the
-- FROM clause.
--
test:do_eqp_test(
"analyze6-1.2",
[[SELECT count(*) FROM cat, ev WHERE x=y]],
{
-- <analyze6-1.2>
{0, 0, 0, "SCAN TABLE CAT"}, {0, 1, 1, "SEARCH TABLE EV USING COVERING INDEX EVY (Y=?)"}
-- </analyze6-1.2>
})
-- Ticket [83ea97620bd3101645138b7b0e71c12c5498fe3d] 2011-03-30
-- If ANALYZE is run on an empty table, make sure indices are used
-- on the table.
--
test:do_test(
"analyze6-2.1",
function()
test:execsql([[
CREATE TABLE t201(x INTEGER PRIMARY KEY, y INT UNIQUE, z INT );
CREATE INDEX t201z ON t201(z);
ANALYZE;
]])
return test:execsql("EXPLAIN QUERY PLAN ".."SELECT * FROM t201 WHERE z=5")
end, {
-- <analyze6-2.1>
0, 0, 0, "SEARCH TABLE T201 USING COVERING INDEX T201Z (Z=?)"
-- </analyze6-2.1>
})
test:do_eqp_test(
"analyze6-2.2",
[[SELECT * FROM t201 WHERE y=5]],
{
-- <analyze6-2.2>
{0, 0, 0, "SEARCH TABLE T201 USING COVERING INDEX unique_unnamed_T201_2 (Y=?)"}
-- </analyze6-2.2>
})
test:do_eqp_test(
"analyze6-2.3",
[[SELECT * FROM t201 WHERE x=5]],
{
-- <analyze6-2.3>
{0, 0, 0, "SEARCH TABLE T201 USING PRIMARY KEY (X=?)"}
-- </analyze6-2.3>
})
test:do_test(
"analyze6-2.4",
function()
test:execsql([[
INSERT INTO t201 VALUES(1,2,3),(2,3,4),(3,4,5);
ANALYZE t201;
]])
return test:execsql("EXPLAIN QUERY PLAN ".."SELECT * FROM t201 WHERE z=5")
end, {
-- <analyze6-2.4>
0, 0, 0, "SEARCH TABLE T201 USING COVERING INDEX T201Z (Z=?)"
-- </analyze6-2.4>
})
test:do_eqp_test(
"analyze6-2.5",
[[SELECT * FROM t201 WHERE y=5]],
{
-- <analyze6-2.5>
{0, 0, 0, "SEARCH TABLE T201 USING COVERING INDEX unique_unnamed_T201_2 (Y=?)"}
-- </analyze6-2.5>
})
test:do_eqp_test(
"analyze6-2.6",
[[SELECT * FROM t201 WHERE x=5]],
{
-- <analyze6-2.6>
{0, 0, 0, "SEARCH TABLE T201 USING PRIMARY KEY (X=?)"}
-- </analyze6-2.6>
})
test:do_test(
"analyze6-2.7",
function()
test:execsql([[
INSERT INTO t201 VALUES(4,5,7);
INSERT INTO t201 SELECT x+100, y+100, z+100 FROM t201;
INSERT INTO t201 SELECT x+200, y+200, z+200 FROM t201;
INSERT INTO t201 SELECT x+400, y+400, z+400 FROM t201;
ANALYZE t201;
]])
return test:execsql("EXPLAIN QUERY PLAN ".."SELECT * FROM t201 WHERE z=5")
end, {
-- <analyze6-2.7>
0, 0, 0, "SEARCH TABLE T201 USING COVERING INDEX T201Z (Z=?)"
-- </analyze6-2.7>
})
test:do_eqp_test(
"analyze6-2.8",
[[SELECT * FROM t201 WHERE y=5]],
{
-- <analyze6-2.8>
{0, 0, 0, "SEARCH TABLE T201 USING COVERING INDEX unique_unnamed_T201_2 (Y=?)"}
-- </analyze6-2.8>
})
test:do_eqp_test(
"analyze6-2.9",
[[SELECT * FROM t201 WHERE x=5]],
{
-- <analyze6-2.9>
{0, 0, 0, "SEARCH TABLE T201 USING PRIMARY KEY (X=?)"}
-- </analyze6-2.9>
})
test:finish_test()
|