eqp.test 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602
  1. # 2010 November 6
  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. #
  12. set testdir [file dirname $argv0]
  13. source $testdir/tester.tcl
  14. ifcapable !compound {
  15. finish_test
  16. return
  17. }
  18. set testprefix eqp
  19. #-------------------------------------------------------------------------
  20. #
  21. # eqp-1.*: Assorted tests.
  22. # eqp-2.*: Tests for single select statements.
  23. # eqp-3.*: Select statements that execute sub-selects.
  24. # eqp-4.*: Compound select statements.
  25. # ...
  26. # eqp-7.*: "SELECT count(*) FROM tbl" statements (VDBE code OP_Count).
  27. #
  28. proc det {args} { uplevel do_eqp_test $args }
  29. do_execsql_test 1.1 {
  30. CREATE TABLE t1(a INT, b INT, ex TEXT);
  31. CREATE INDEX i1 ON t1(a);
  32. CREATE INDEX i2 ON t1(b);
  33. CREATE TABLE t2(a INT, b INT, ex TEXT);
  34. CREATE TABLE t3(a INT, b INT, ex TEXT);
  35. }
  36. do_eqp_test 1.2 {
  37. SELECT * FROM t2, t1 WHERE t1.a=1 OR t1.b=2;
  38. } {
  39. 0 0 1 {SEARCH TABLE t1 USING INDEX i1 (a=?)}
  40. 0 0 1 {SEARCH TABLE t1 USING INDEX i2 (b=?)}
  41. 0 1 0 {SCAN TABLE t2}
  42. }
  43. do_eqp_test 1.3 {
  44. SELECT * FROM t2 CROSS JOIN t1 WHERE t1.a=1 OR t1.b=2;
  45. } {
  46. 0 0 0 {SCAN TABLE t2}
  47. 0 1 1 {SEARCH TABLE t1 USING INDEX i1 (a=?)}
  48. 0 1 1 {SEARCH TABLE t1 USING INDEX i2 (b=?)}
  49. }
  50. do_eqp_test 1.3 {
  51. SELECT a FROM t1 ORDER BY a
  52. } {
  53. 0 0 0 {SCAN TABLE t1 USING COVERING INDEX i1}
  54. }
  55. do_eqp_test 1.4 {
  56. SELECT a FROM t1 ORDER BY +a
  57. } {
  58. 0 0 0 {SCAN TABLE t1 USING COVERING INDEX i1}
  59. 0 0 0 {USE TEMP B-TREE FOR ORDER BY}
  60. }
  61. do_eqp_test 1.5 {
  62. SELECT a FROM t1 WHERE a=4
  63. } {
  64. 0 0 0 {SEARCH TABLE t1 USING COVERING INDEX i1 (a=?)}
  65. }
  66. do_eqp_test 1.6 {
  67. SELECT DISTINCT count(*) FROM t3 GROUP BY a;
  68. } {
  69. 0 0 0 {SCAN TABLE t3}
  70. 0 0 0 {USE TEMP B-TREE FOR GROUP BY}
  71. 0 0 0 {USE TEMP B-TREE FOR DISTINCT}
  72. }
  73. do_eqp_test 1.7 {
  74. SELECT * FROM t3 JOIN (SELECT 1)
  75. } {
  76. 0 0 1 {SCAN SUBQUERY 1}
  77. 0 1 0 {SCAN TABLE t3}
  78. }
  79. do_eqp_test 1.8 {
  80. SELECT * FROM t3 JOIN (SELECT 1 UNION SELECT 2)
  81. } {
  82. 1 0 0 {COMPOUND SUBQUERIES 2 AND 3 USING TEMP B-TREE (UNION)}
  83. 0 0 1 {SCAN SUBQUERY 1}
  84. 0 1 0 {SCAN TABLE t3}
  85. }
  86. do_eqp_test 1.9 {
  87. SELECT * FROM t3 JOIN (SELECT 1 EXCEPT SELECT a FROM t3 LIMIT 17)
  88. } {
  89. 3 0 0 {SCAN TABLE t3}
  90. 1 0 0 {COMPOUND SUBQUERIES 2 AND 3 USING TEMP B-TREE (EXCEPT)}
  91. 0 0 1 {SCAN SUBQUERY 1}
  92. 0 1 0 {SCAN TABLE t3}
  93. }
  94. do_eqp_test 1.10 {
  95. SELECT * FROM t3 JOIN (SELECT 1 INTERSECT SELECT a FROM t3 LIMIT 17)
  96. } {
  97. 3 0 0 {SCAN TABLE t3}
  98. 1 0 0 {COMPOUND SUBQUERIES 2 AND 3 USING TEMP B-TREE (INTERSECT)}
  99. 0 0 1 {SCAN SUBQUERY 1}
  100. 0 1 0 {SCAN TABLE t3}
  101. }
  102. do_eqp_test 1.11 {
  103. SELECT * FROM t3 JOIN (SELECT 1 UNION ALL SELECT a FROM t3 LIMIT 17)
  104. } {
  105. 3 0 0 {SCAN TABLE t3}
  106. 1 0 0 {COMPOUND SUBQUERIES 2 AND 3 (UNION ALL)}
  107. 0 0 1 {SCAN SUBQUERY 1}
  108. 0 1 0 {SCAN TABLE t3}
  109. }
  110. #-------------------------------------------------------------------------
  111. # Test cases eqp-2.* - tests for single select statements.
  112. #
  113. drop_all_tables
  114. do_execsql_test 2.1 {
  115. CREATE TABLE t1(x INT, y INT, ex TEXT);
  116. CREATE TABLE t2(x INT, y INT, ex TEXT);
  117. CREATE INDEX t2i1 ON t2(x);
  118. }
  119. det 2.2.1 "SELECT DISTINCT min(x), max(x) FROM t1 GROUP BY x ORDER BY 1" {
  120. 0 0 0 {SCAN TABLE t1}
  121. 0 0 0 {USE TEMP B-TREE FOR GROUP BY}
  122. 0 0 0 {USE TEMP B-TREE FOR DISTINCT}
  123. 0 0 0 {USE TEMP B-TREE FOR ORDER BY}
  124. }
  125. det 2.2.2 "SELECT DISTINCT min(x), max(x) FROM t2 GROUP BY x ORDER BY 1" {
  126. 0 0 0 {SCAN TABLE t2 USING COVERING INDEX t2i1}
  127. 0 0 0 {USE TEMP B-TREE FOR DISTINCT}
  128. 0 0 0 {USE TEMP B-TREE FOR ORDER BY}
  129. }
  130. det 2.2.3 "SELECT DISTINCT * FROM t1" {
  131. 0 0 0 {SCAN TABLE t1}
  132. 0 0 0 {USE TEMP B-TREE FOR DISTINCT}
  133. }
  134. det 2.2.4 "SELECT DISTINCT * FROM t1, t2" {
  135. 0 0 0 {SCAN TABLE t1}
  136. 0 1 1 {SCAN TABLE t2}
  137. 0 0 0 {USE TEMP B-TREE FOR DISTINCT}
  138. }
  139. det 2.2.5 "SELECT DISTINCT * FROM t1, t2 ORDER BY t1.x" {
  140. 0 0 0 {SCAN TABLE t1}
  141. 0 1 1 {SCAN TABLE t2}
  142. 0 0 0 {USE TEMP B-TREE FOR DISTINCT}
  143. 0 0 0 {USE TEMP B-TREE FOR ORDER BY}
  144. }
  145. det 2.2.6 "SELECT DISTINCT t2.x FROM t1, t2 ORDER BY t2.x" {
  146. 0 0 1 {SCAN TABLE t2 USING COVERING INDEX t2i1}
  147. 0 1 0 {SCAN TABLE t1}
  148. }
  149. det 2.3.1 "SELECT max(x) FROM t2" {
  150. 0 0 0 {SEARCH TABLE t2 USING COVERING INDEX t2i1}
  151. }
  152. det 2.3.2 "SELECT min(x) FROM t2" {
  153. 0 0 0 {SEARCH TABLE t2 USING COVERING INDEX t2i1}
  154. }
  155. det 2.3.3 "SELECT min(x), max(x) FROM t2" {
  156. 0 0 0 {SCAN TABLE t2 USING COVERING INDEX t2i1}
  157. }
  158. det 2.4.1 "SELECT * FROM t1 WHERE rowid=?" {
  159. 0 0 0 {SEARCH TABLE t1 USING INTEGER PRIMARY KEY (rowid=?)}
  160. }
  161. #-------------------------------------------------------------------------
  162. # Test cases eqp-3.* - tests for select statements that use sub-selects.
  163. #
  164. do_eqp_test 3.1.1 {
  165. SELECT (SELECT x FROM t1 AS sub) FROM t1;
  166. } {
  167. 0 0 0 {SCAN TABLE t1}
  168. 0 0 0 {EXECUTE SCALAR SUBQUERY 1}
  169. 1 0 0 {SCAN TABLE t1 AS sub}
  170. }
  171. do_eqp_test 3.1.2 {
  172. SELECT * FROM t1 WHERE (SELECT x FROM t1 AS sub);
  173. } {
  174. 0 0 0 {SCAN TABLE t1}
  175. 0 0 0 {EXECUTE SCALAR SUBQUERY 1}
  176. 1 0 0 {SCAN TABLE t1 AS sub}
  177. }
  178. do_eqp_test 3.1.3 {
  179. SELECT * FROM t1 WHERE (SELECT x FROM t1 AS sub ORDER BY y);
  180. } {
  181. 0 0 0 {SCAN TABLE t1}
  182. 0 0 0 {EXECUTE SCALAR SUBQUERY 1}
  183. 1 0 0 {SCAN TABLE t1 AS sub}
  184. 1 0 0 {USE TEMP B-TREE FOR ORDER BY}
  185. }
  186. do_eqp_test 3.1.4 {
  187. SELECT * FROM t1 WHERE (SELECT x FROM t2 ORDER BY x);
  188. } {
  189. 0 0 0 {SCAN TABLE t1}
  190. 0 0 0 {EXECUTE SCALAR SUBQUERY 1}
  191. 1 0 0 {SCAN TABLE t2 USING COVERING INDEX t2i1}
  192. }
  193. det 3.2.1 {
  194. SELECT * FROM (SELECT * FROM t1 ORDER BY x LIMIT 10) ORDER BY y LIMIT 5
  195. } {
  196. 1 0 0 {SCAN TABLE t1}
  197. 1 0 0 {USE TEMP B-TREE FOR ORDER BY}
  198. 0 0 0 {SCAN SUBQUERY 1}
  199. 0 0 0 {USE TEMP B-TREE FOR ORDER BY}
  200. }
  201. det 3.2.2 {
  202. SELECT * FROM
  203. (SELECT * FROM t1 ORDER BY x LIMIT 10) AS x1,
  204. (SELECT * FROM t2 ORDER BY x LIMIT 10) AS x2
  205. ORDER BY x2.y LIMIT 5
  206. } {
  207. 1 0 0 {SCAN TABLE t1}
  208. 1 0 0 {USE TEMP B-TREE FOR ORDER BY}
  209. 2 0 0 {SCAN TABLE t2 USING INDEX t2i1}
  210. 0 0 0 {SCAN SUBQUERY 1 AS x1}
  211. 0 1 1 {SCAN SUBQUERY 2 AS x2}
  212. 0 0 0 {USE TEMP B-TREE FOR ORDER BY}
  213. }
  214. det 3.3.1 {
  215. SELECT * FROM t1 WHERE y IN (SELECT y FROM t2)
  216. } {
  217. 0 0 0 {SCAN TABLE t1}
  218. 0 0 0 {EXECUTE LIST SUBQUERY 1}
  219. 1 0 0 {SCAN TABLE t2}
  220. }
  221. det 3.3.2 {
  222. SELECT * FROM t1 WHERE y IN (SELECT y FROM t2 WHERE t1.x!=t2.x)
  223. } {
  224. 0 0 0 {SCAN TABLE t1}
  225. 0 0 0 {EXECUTE CORRELATED LIST SUBQUERY 1}
  226. 1 0 0 {SCAN TABLE t2}
  227. }
  228. det 3.3.3 {
  229. SELECT * FROM t1 WHERE EXISTS (SELECT y FROM t2 WHERE t1.x!=t2.x)
  230. } {
  231. 0 0 0 {SCAN TABLE t1}
  232. 0 0 0 {EXECUTE CORRELATED SCALAR SUBQUERY 1}
  233. 1 0 0 {SCAN TABLE t2}
  234. }
  235. #-------------------------------------------------------------------------
  236. # Test cases eqp-4.* - tests for composite select statements.
  237. #
  238. do_eqp_test 4.1.1 {
  239. SELECT * FROM t1 UNION ALL SELECT * FROM t2
  240. } {
  241. 1 0 0 {SCAN TABLE t1}
  242. 2 0 0 {SCAN TABLE t2}
  243. 0 0 0 {COMPOUND SUBQUERIES 1 AND 2 (UNION ALL)}
  244. }
  245. do_eqp_test 4.1.2 {
  246. SELECT * FROM t1 UNION ALL SELECT * FROM t2 ORDER BY 2
  247. } {
  248. 1 0 0 {SCAN TABLE t1}
  249. 1 0 0 {USE TEMP B-TREE FOR ORDER BY}
  250. 2 0 0 {SCAN TABLE t2}
  251. 2 0 0 {USE TEMP B-TREE FOR ORDER BY}
  252. 0 0 0 {COMPOUND SUBQUERIES 1 AND 2 (UNION ALL)}
  253. }
  254. do_eqp_test 4.1.3 {
  255. SELECT * FROM t1 UNION SELECT * FROM t2 ORDER BY 2
  256. } {
  257. 1 0 0 {SCAN TABLE t1}
  258. 1 0 0 {USE TEMP B-TREE FOR ORDER BY}
  259. 2 0 0 {SCAN TABLE t2}
  260. 2 0 0 {USE TEMP B-TREE FOR ORDER BY}
  261. 0 0 0 {COMPOUND SUBQUERIES 1 AND 2 (UNION)}
  262. }
  263. do_eqp_test 4.1.4 {
  264. SELECT * FROM t1 INTERSECT SELECT * FROM t2 ORDER BY 2
  265. } {
  266. 1 0 0 {SCAN TABLE t1}
  267. 1 0 0 {USE TEMP B-TREE FOR ORDER BY}
  268. 2 0 0 {SCAN TABLE t2}
  269. 2 0 0 {USE TEMP B-TREE FOR ORDER BY}
  270. 0 0 0 {COMPOUND SUBQUERIES 1 AND 2 (INTERSECT)}
  271. }
  272. do_eqp_test 4.1.5 {
  273. SELECT * FROM t1 EXCEPT SELECT * FROM t2 ORDER BY 2
  274. } {
  275. 1 0 0 {SCAN TABLE t1}
  276. 1 0 0 {USE TEMP B-TREE FOR ORDER BY}
  277. 2 0 0 {SCAN TABLE t2}
  278. 2 0 0 {USE TEMP B-TREE FOR ORDER BY}
  279. 0 0 0 {COMPOUND SUBQUERIES 1 AND 2 (EXCEPT)}
  280. }
  281. do_eqp_test 4.2.2 {
  282. SELECT * FROM t1 UNION ALL SELECT * FROM t2 ORDER BY 1
  283. } {
  284. 1 0 0 {SCAN TABLE t1}
  285. 1 0 0 {USE TEMP B-TREE FOR ORDER BY}
  286. 2 0 0 {SCAN TABLE t2 USING INDEX t2i1}
  287. 0 0 0 {COMPOUND SUBQUERIES 1 AND 2 (UNION ALL)}
  288. }
  289. do_eqp_test 4.2.3 {
  290. SELECT * FROM t1 UNION SELECT * FROM t2 ORDER BY 1
  291. } {
  292. 1 0 0 {SCAN TABLE t1}
  293. 1 0 0 {USE TEMP B-TREE FOR ORDER BY}
  294. 2 0 0 {SCAN TABLE t2}
  295. 2 0 0 {USE TEMP B-TREE FOR ORDER BY}
  296. 0 0 0 {COMPOUND SUBQUERIES 1 AND 2 (UNION)}
  297. }
  298. do_eqp_test 4.2.4 {
  299. SELECT * FROM t1 INTERSECT SELECT * FROM t2 ORDER BY 1
  300. } {
  301. 1 0 0 {SCAN TABLE t1}
  302. 1 0 0 {USE TEMP B-TREE FOR ORDER BY}
  303. 2 0 0 {SCAN TABLE t2}
  304. 2 0 0 {USE TEMP B-TREE FOR ORDER BY}
  305. 0 0 0 {COMPOUND SUBQUERIES 1 AND 2 (INTERSECT)}
  306. }
  307. do_eqp_test 4.2.5 {
  308. SELECT * FROM t1 EXCEPT SELECT * FROM t2 ORDER BY 1
  309. } {
  310. 1 0 0 {SCAN TABLE t1}
  311. 1 0 0 {USE TEMP B-TREE FOR ORDER BY}
  312. 2 0 0 {SCAN TABLE t2}
  313. 2 0 0 {USE TEMP B-TREE FOR ORDER BY}
  314. 0 0 0 {COMPOUND SUBQUERIES 1 AND 2 (EXCEPT)}
  315. }
  316. do_eqp_test 4.3.1 {
  317. SELECT x FROM t1 UNION SELECT x FROM t2
  318. } {
  319. 1 0 0 {SCAN TABLE t1}
  320. 2 0 0 {SCAN TABLE t2 USING COVERING INDEX t2i1}
  321. 0 0 0 {COMPOUND SUBQUERIES 1 AND 2 USING TEMP B-TREE (UNION)}
  322. }
  323. do_eqp_test 4.3.2 {
  324. SELECT x FROM t1 UNION SELECT x FROM t2 UNION SELECT x FROM t1
  325. } {
  326. 2 0 0 {SCAN TABLE t1}
  327. 3 0 0 {SCAN TABLE t2 USING COVERING INDEX t2i1}
  328. 1 0 0 {COMPOUND SUBQUERIES 2 AND 3 USING TEMP B-TREE (UNION)}
  329. 4 0 0 {SCAN TABLE t1}
  330. 0 0 0 {COMPOUND SUBQUERIES 1 AND 4 USING TEMP B-TREE (UNION)}
  331. }
  332. do_eqp_test 4.3.3 {
  333. SELECT x FROM t1 UNION SELECT x FROM t2 UNION SELECT x FROM t1 ORDER BY 1
  334. } {
  335. 2 0 0 {SCAN TABLE t1}
  336. 2 0 0 {USE TEMP B-TREE FOR ORDER BY}
  337. 3 0 0 {SCAN TABLE t2 USING COVERING INDEX t2i1}
  338. 1 0 0 {COMPOUND SUBQUERIES 2 AND 3 (UNION)}
  339. 4 0 0 {SCAN TABLE t1}
  340. 4 0 0 {USE TEMP B-TREE FOR ORDER BY}
  341. 0 0 0 {COMPOUND SUBQUERIES 1 AND 4 (UNION)}
  342. }
  343. #-------------------------------------------------------------------------
  344. # This next block of tests verifies that the examples on the
  345. # lang_explain.html page are correct.
  346. #
  347. drop_all_tables
  348. # EVIDENCE-OF: R-47779-47605 sqlite> EXPLAIN QUERY PLAN SELECT a, b
  349. # FROM t1 WHERE a=1;
  350. # 0|0|0|SCAN TABLE t1
  351. #
  352. do_execsql_test 5.1.0 { CREATE TABLE t1(a INT, b INT, ex TEXT) }
  353. det 5.1.1 "SELECT a, b FROM t1 WHERE a=1" {
  354. 0 0 0 {SCAN TABLE t1}
  355. }
  356. # EVIDENCE-OF: R-55852-17599 sqlite> CREATE INDEX i1 ON t1(a);
  357. # sqlite> EXPLAIN QUERY PLAN SELECT a, b FROM t1 WHERE a=1;
  358. # 0|0|0|SEARCH TABLE t1 USING INDEX i1
  359. #
  360. do_execsql_test 5.2.0 { CREATE INDEX i1 ON t1(a) }
  361. det 5.2.1 "SELECT a, b FROM t1 WHERE a=1" {
  362. 0 0 0 {SEARCH TABLE t1 USING INDEX i1 (a=?)}
  363. }
  364. # EVIDENCE-OF: R-21179-11011 sqlite> CREATE INDEX i2 ON t1(a, b);
  365. # sqlite> EXPLAIN QUERY PLAN SELECT a, b FROM t1 WHERE a=1;
  366. # 0|0|0|SEARCH TABLE t1 USING COVERING INDEX i2 (a=?)
  367. #
  368. do_execsql_test 5.3.0 { CREATE INDEX i2 ON t1(a, b) }
  369. det 5.3.1 "SELECT a, b FROM t1 WHERE a=1" {
  370. 0 0 0 {SEARCH TABLE t1 USING COVERING INDEX i2 (a=?)}
  371. }
  372. # EVIDENCE-OF: R-09991-48941 sqlite> EXPLAIN QUERY PLAN
  373. # SELECT t1.*, t2.* FROM t1, t2 WHERE t1.a=1 AND t1.b>2;
  374. # 0|0|0|SEARCH TABLE t1 USING COVERING INDEX i2 (a=? AND b>?)
  375. # 0|1|1|SCAN TABLE t2
  376. #
  377. do_execsql_test 5.4.0 {CREATE TABLE t2(c INT, d INT, ex TEXT)}
  378. det 5.4.1 "SELECT t1.a, t2.c FROM t1, t2 WHERE t1.a=1 AND t1.b>2" {
  379. 0 0 0 {SEARCH TABLE t1 USING COVERING INDEX i2 (a=? AND b>?)}
  380. 0 1 1 {SCAN TABLE t2}
  381. }
  382. # EVIDENCE-OF: R-33626-61085 sqlite> EXPLAIN QUERY PLAN
  383. # SELECT t1.*, t2.* FROM t2, t1 WHERE t1.a=1 AND t1.b>2;
  384. # 0|0|1|SEARCH TABLE t1 USING COVERING INDEX i2 (a=? AND b>?)
  385. # 0|1|0|SCAN TABLE t2
  386. #
  387. det 5.5 "SELECT t1.a, t2.c FROM t2, t1 WHERE t1.a=1 AND t1.b>2" {
  388. 0 0 1 {SEARCH TABLE t1 USING COVERING INDEX i2 (a=? AND b>?)}
  389. 0 1 0 {SCAN TABLE t2}
  390. }
  391. # EVIDENCE-OF: R-04002-25654 sqlite> CREATE INDEX i3 ON t1(b);
  392. # sqlite> EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE a=1 OR b=2;
  393. # 0|0|0|SEARCH TABLE t1 USING COVERING INDEX i2 (a=?)
  394. # 0|0|0|SEARCH TABLE t1 USING INDEX i3 (b=?)
  395. #
  396. do_execsql_test 5.5.0 {CREATE INDEX i3 ON t1(b)}
  397. det 5.6.1 "SELECT a, b FROM t1 WHERE a=1 OR b=2" {
  398. 0 0 0 {SEARCH TABLE t1 USING COVERING INDEX i2 (a=?)}
  399. 0 0 0 {SEARCH TABLE t1 USING INDEX i3 (b=?)}
  400. }
  401. # EVIDENCE-OF: R-24577-38891 sqlite> EXPLAIN QUERY PLAN
  402. # SELECT c, d FROM t2 ORDER BY c;
  403. # 0|0|0|SCAN TABLE t2
  404. # 0|0|0|USE TEMP B-TREE FOR ORDER BY
  405. #
  406. det 5.7 "SELECT c, d FROM t2 ORDER BY c" {
  407. 0 0 0 {SCAN TABLE t2}
  408. 0 0 0 {USE TEMP B-TREE FOR ORDER BY}
  409. }
  410. # EVIDENCE-OF: R-58157-12355 sqlite> CREATE INDEX i4 ON t2(c);
  411. # sqlite> EXPLAIN QUERY PLAN SELECT c, d FROM t2 ORDER BY c;
  412. # 0|0|0|SCAN TABLE t2 USING INDEX i4
  413. #
  414. do_execsql_test 5.8.0 {CREATE INDEX i4 ON t2(c)}
  415. det 5.8.1 "SELECT c, d FROM t2 ORDER BY c" {
  416. 0 0 0 {SCAN TABLE t2 USING INDEX i4}
  417. }
  418. # EVIDENCE-OF: R-13931-10421 sqlite> EXPLAIN QUERY PLAN SELECT
  419. # (SELECT b FROM t1 WHERE a=0), (SELECT a FROM t1 WHERE b=t2.c) FROM t2;
  420. # 0|0|0|SCAN TABLE t2
  421. # 0|0|0|EXECUTE SCALAR SUBQUERY 1
  422. # 1|0|0|SEARCH TABLE t1 USING COVERING INDEX i2 (a=?)
  423. # 0|0|0|EXECUTE CORRELATED SCALAR SUBQUERY 2
  424. # 2|0|0|SEARCH TABLE t1 USING INDEX i3 (b=?)
  425. #
  426. det 5.9 {
  427. SELECT (SELECT b FROM t1 WHERE a=0), (SELECT a FROM t1 WHERE b=t2.c) FROM t2
  428. } {
  429. 0 0 0 {SCAN TABLE t2 USING COVERING INDEX i4}
  430. 0 0 0 {EXECUTE SCALAR SUBQUERY 1}
  431. 1 0 0 {SEARCH TABLE t1 USING COVERING INDEX i2 (a=?)}
  432. 0 0 0 {EXECUTE CORRELATED SCALAR SUBQUERY 2}
  433. 2 0 0 {SEARCH TABLE t1 USING INDEX i3 (b=?)}
  434. }
  435. # EVIDENCE-OF: R-50892-45943 sqlite> EXPLAIN QUERY PLAN
  436. # SELECT count(*) FROM (SELECT max(b) AS x FROM t1 GROUP BY a) GROUP BY x;
  437. # 1|0|0|SCAN TABLE t1 USING COVERING INDEX i2
  438. # 0|0|0|SCAN SUBQUERY 1
  439. # 0|0|0|USE TEMP B-TREE FOR GROUP BY
  440. #
  441. det 5.10 {
  442. SELECT count(*) FROM (SELECT max(b) AS x FROM t1 GROUP BY a) GROUP BY x
  443. } {
  444. 1 0 0 {SCAN TABLE t1 USING COVERING INDEX i2}
  445. 0 0 0 {SCAN SUBQUERY 1}
  446. 0 0 0 {USE TEMP B-TREE FOR GROUP BY}
  447. }
  448. # EVIDENCE-OF: R-46219-33846 sqlite> EXPLAIN QUERY PLAN
  449. # SELECT * FROM (SELECT * FROM t2 WHERE c=1), t1;
  450. # 0|0|0|SEARCH TABLE t2 USING INDEX i4 (c=?)
  451. # 0|1|1|SCAN TABLE t1
  452. #
  453. det 5.11 "SELECT a, b FROM (SELECT * FROM t2 WHERE c=1), t1" {
  454. 0 0 0 {SEARCH TABLE t2 USING INDEX i4 (c=?)}
  455. 0 1 1 {SCAN TABLE t1 USING COVERING INDEX i2}
  456. }
  457. # EVIDENCE-OF: R-37879-39987 sqlite> EXPLAIN QUERY PLAN
  458. # SELECT a FROM t1 UNION SELECT c FROM t2;
  459. # 1|0|0|SCAN TABLE t1
  460. # 2|0|0|SCAN TABLE t2
  461. # 0|0|0|COMPOUND SUBQUERIES 1 AND 2 USING TEMP B-TREE (UNION)
  462. #
  463. det 5.12 "SELECT a,b FROM t1 UNION SELECT c, 99 FROM t2" {
  464. 1 0 0 {SCAN TABLE t1 USING COVERING INDEX i2}
  465. 2 0 0 {SCAN TABLE t2 USING COVERING INDEX i4}
  466. 0 0 0 {COMPOUND SUBQUERIES 1 AND 2 USING TEMP B-TREE (UNION)}
  467. }
  468. # EVIDENCE-OF: R-44864-63011 sqlite> EXPLAIN QUERY PLAN
  469. # SELECT a FROM t1 EXCEPT SELECT d FROM t2 ORDER BY 1;
  470. # 1|0|0|SCAN TABLE t1 USING COVERING INDEX i2
  471. # 2|0|0|SCAN TABLE t2 2|0|0|USE TEMP B-TREE FOR ORDER BY
  472. # 0|0|0|COMPOUND SUBQUERIES 1 AND 2 (EXCEPT)
  473. #
  474. det 5.13 "SELECT a FROM t1 EXCEPT SELECT d FROM t2 ORDER BY 1" {
  475. 1 0 0 {SCAN TABLE t1 USING COVERING INDEX i1}
  476. 2 0 0 {SCAN TABLE t2}
  477. 2 0 0 {USE TEMP B-TREE FOR ORDER BY}
  478. 0 0 0 {COMPOUND SUBQUERIES 1 AND 2 (EXCEPT)}
  479. }
  480. #-------------------------------------------------------------------------
  481. # The following tests - eqp-6.* - test that the example C code on
  482. # documentation page eqp.html works. The C code is duplicated in test1.c
  483. # and wrapped in Tcl command [print_explain_query_plan]
  484. #
  485. set boilerplate {
  486. proc explain_query_plan {db sql} {
  487. set stmt [sqlite3_prepare_v2 db $sql -1 DUMMY]
  488. print_explain_query_plan $stmt
  489. sqlite3_finalize $stmt
  490. }
  491. sqlite3 db test.db
  492. explain_query_plan db {%SQL%}
  493. db close
  494. exit
  495. }
  496. # Do a "Print Explain Query Plan" test.
  497. proc do_peqp_test {tn sql res} {
  498. set fd [open script.tcl w]
  499. puts $fd [string map [list %SQL% $sql] $::boilerplate]
  500. close $fd
  501. uplevel do_test $tn [list {
  502. set fd [open "|[info nameofexec] script.tcl"]
  503. set data [read $fd]
  504. close $fd
  505. set data
  506. }] [list $res]
  507. }
  508. do_peqp_test 6.1 {
  509. SELECT a, b FROM t1 EXCEPT SELECT d, 99 FROM t2 ORDER BY 1
  510. } [string trimleft {
  511. 1 0 0 SCAN TABLE t1 USING COVERING INDEX i2
  512. 2 0 0 SCAN TABLE t2
  513. 2 0 0 USE TEMP B-TREE FOR ORDER BY
  514. 0 0 0 COMPOUND SUBQUERIES 1 AND 2 (EXCEPT)
  515. }]
  516. #-------------------------------------------------------------------------
  517. # The following tests - eqp-7.* - test that queries that use the OP_Count
  518. # optimization return something sensible with EQP.
  519. #
  520. drop_all_tables
  521. do_execsql_test 7.0 {
  522. CREATE TABLE t1(a INT, b INT, ex CHAR(100));
  523. CREATE TABLE t2(a INT, b INT, ex CHAR(100));
  524. CREATE INDEX i1 ON t2(a);
  525. }
  526. det 7.1 "SELECT count(*) FROM t1" {
  527. 0 0 0 {SCAN TABLE t1}
  528. }
  529. det 7.2 "SELECT count(*) FROM t2" {
  530. 0 0 0 {SCAN TABLE t2 USING COVERING INDEX i1}
  531. }
  532. do_execsql_test 7.3 {
  533. INSERT INTO t1(a,b) VALUES(1, 2);
  534. INSERT INTO t1(a,b) VALUES(3, 4);
  535. INSERT INTO t2(a,b) VALUES(1, 2);
  536. INSERT INTO t2(a,b) VALUES(3, 4);
  537. INSERT INTO t2(a,b) VALUES(5, 6);
  538. ANALYZE;
  539. }
  540. db close
  541. sqlite3 db test.db
  542. det 7.4 "SELECT count(*) FROM t1" {
  543. 0 0 0 {SCAN TABLE t1}
  544. }
  545. det 7.5 "SELECT count(*) FROM t2" {
  546. 0 0 0 {SCAN TABLE t2 USING COVERING INDEX i1}
  547. }
  548. finish_test