orderby1.test 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457
  1. # 2012 Sept 27
  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. # This file implements regression tests for SQLite library. The
  12. # focus of this file is testing that the optimizations that disable
  13. # ORDER BY clauses when the natural order of a query is correct.
  14. #
  15. set testdir [file dirname $argv0]
  16. source $testdir/tester.tcl
  17. set ::testprefix orderby1
  18. # Generate test data for a join. Verify that the join gets the
  19. # correct answer.
  20. #
  21. do_test 1.0 {
  22. db eval {
  23. BEGIN;
  24. CREATE TABLE album(
  25. aid INTEGER PRIMARY KEY,
  26. title TEXT UNIQUE NOT NULL
  27. );
  28. CREATE TABLE track(
  29. tid INTEGER PRIMARY KEY,
  30. aid INTEGER NOT NULL REFERENCES album,
  31. tn INTEGER NOT NULL,
  32. name TEXT,
  33. UNIQUE(aid, tn)
  34. );
  35. INSERT INTO album VALUES(1, '1-one'), (2, '2-two'), (3, '3-three');
  36. INSERT INTO track VALUES
  37. (NULL, 1, 1, 'one-a'),
  38. (NULL, 2, 2, 'two-b'),
  39. (NULL, 3, 3, 'three-c'),
  40. (NULL, 1, 3, 'one-c'),
  41. (NULL, 2, 1, 'two-a'),
  42. (NULL, 3, 1, 'three-a');
  43. COMMIT;
  44. }
  45. } {}
  46. do_test 1.1a {
  47. db eval {
  48. SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn
  49. }
  50. } {one-a one-c two-a two-b three-a three-c}
  51. # Verify that the ORDER BY clause is optimized out
  52. #
  53. do_test 1.1b {
  54. db eval {
  55. EXPLAIN QUERY PLAN
  56. SELECT name FROM album CROSS JOIN track USING (aid) ORDER BY title, tn
  57. }
  58. } {~/ORDER BY/} ;# ORDER BY optimized out
  59. # The same query with ORDER BY clause optimization disabled via + operators
  60. # should give exactly the same answer.
  61. #
  62. do_test 1.2a {
  63. db eval {
  64. SELECT name FROM album JOIN track USING (aid) ORDER BY +title, +tn
  65. }
  66. } {one-a one-c two-a two-b three-a three-c}
  67. # The output is sorted manually in this case.
  68. #
  69. do_test 1.2b {
  70. db eval {
  71. EXPLAIN QUERY PLAN
  72. SELECT name FROM album JOIN track USING (aid) ORDER BY +title, +tn
  73. }
  74. } {/ORDER BY/} ;# separate sorting pass due to "+" on ORDER BY terms
  75. # The same query with ORDER BY optimizations turned off via built-in test.
  76. #
  77. do_test 1.3a {
  78. optimization_control db order-by-idx-join 0
  79. db cache flush
  80. db eval {
  81. SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn
  82. }
  83. } {one-a one-c two-a two-b three-a three-c}
  84. do_test 1.3b {
  85. db eval {
  86. EXPLAIN QUERY PLAN
  87. SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn
  88. }
  89. } {/ORDER BY/} ;# separate sorting pass due to disabled optimization
  90. optimization_control db all 1
  91. db cache flush
  92. # Reverse order sorts
  93. #
  94. do_test 1.4a {
  95. db eval {
  96. SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn
  97. }
  98. } {three-a three-c two-a two-b one-a one-c}
  99. do_test 1.4b {
  100. db eval {
  101. SELECT name FROM album JOIN track USING (aid) ORDER BY +title DESC, +tn
  102. }
  103. } {three-a three-c two-a two-b one-a one-c} ;# verify same order after sorting
  104. do_test 1.4c {
  105. db eval {
  106. EXPLAIN QUERY PLAN
  107. SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn
  108. }
  109. } {~/ORDER BY/} ;# ORDER BY suppressed due to uniqueness constraints
  110. do_test 1.5a {
  111. db eval {
  112. SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn DESC
  113. }
  114. } {one-c one-a two-b two-a three-c three-a}
  115. do_test 1.5b {
  116. db eval {
  117. SELECT name FROM album JOIN track USING (aid) ORDER BY +title, +tn DESC
  118. }
  119. } {one-c one-a two-b two-a three-c three-a} ;# verify same order after sorting
  120. do_test 1.5c {
  121. db eval {
  122. EXPLAIN QUERY PLAN
  123. SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn DESC
  124. }
  125. } {~/ORDER BY/} ;# ORDER BY suppressed due to uniqueness constraints
  126. do_test 1.6a {
  127. db eval {
  128. SELECT name FROM album CROSS JOIN track USING (aid)
  129. ORDER BY title DESC, tn DESC
  130. }
  131. } {three-c three-a two-b two-a one-c one-a}
  132. do_test 1.6b {
  133. db eval {
  134. SELECT name FROM album CROSS JOIN track USING (aid)
  135. ORDER BY +title DESC, +tn DESC
  136. }
  137. } {three-c three-a two-b two-a one-c one-a} ;# verify same order after sorting
  138. do_test 1.6c {
  139. db eval {
  140. EXPLAIN QUERY PLAN
  141. SELECT name FROM album CROSS JOIN track USING (aid)
  142. ORDER BY title DESC, tn DESC
  143. }
  144. } {~/ORDER BY/} ;# ORDER BY
  145. # Reconstruct the test data to use indices rather than integer primary keys.
  146. #
  147. do_test 2.0 {
  148. db eval {
  149. BEGIN;
  150. DROP TABLE album;
  151. DROP TABLE track;
  152. CREATE TABLE album(
  153. aid INT PRIMARY KEY,
  154. title TEXT NOT NULL
  155. );
  156. CREATE INDEX album_i1 ON album(title, aid);
  157. CREATE TABLE track(
  158. aid INTEGER NOT NULL REFERENCES album,
  159. tn INTEGER NOT NULL,
  160. name TEXT,
  161. UNIQUE(aid, tn)
  162. );
  163. INSERT INTO album VALUES(1, '1-one'), (20, '2-two'), (3, '3-three');
  164. INSERT INTO track VALUES
  165. (1, 1, 'one-a'),
  166. (20, 2, 'two-b'),
  167. (3, 3, 'three-c'),
  168. (1, 3, 'one-c'),
  169. (20, 1, 'two-a'),
  170. (3, 1, 'three-a');
  171. COMMIT;
  172. }
  173. } {}
  174. do_test 2.1a {
  175. db eval {
  176. SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn
  177. }
  178. } {one-a one-c two-a two-b three-a three-c}
  179. # Verify that the ORDER BY clause is optimized out
  180. #
  181. do_test 2.1b {
  182. db eval {
  183. EXPLAIN QUERY PLAN
  184. SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn
  185. }
  186. } {/ORDER BY/} ;# ORDER BY required because of missing aid term in ORDER BY
  187. do_test 2.1c {
  188. db eval {
  189. SELECT name FROM album JOIN track USING (aid) ORDER BY title, aid, tn
  190. }
  191. } {one-a one-c two-a two-b three-a three-c}
  192. do_test 2.1d {
  193. db eval {
  194. EXPLAIN QUERY PLAN
  195. SELECT name FROM album JOIN track USING (aid) ORDER BY title, aid, tn
  196. }
  197. } {/ORDER BY/} ;# ORDER BY required in this case
  198. # The same query with ORDER BY clause optimization disabled via + operators
  199. # should give exactly the same answer.
  200. #
  201. do_test 2.2a {
  202. db eval {
  203. SELECT name FROM album JOIN track USING (aid) ORDER BY +title, +tn
  204. }
  205. } {one-a one-c two-a two-b three-a three-c}
  206. # The output is sorted manually in this case.
  207. #
  208. do_test 2.2b {
  209. db eval {
  210. EXPLAIN QUERY PLAN
  211. SELECT name FROM album JOIN track USING (aid) ORDER BY +title, +tn
  212. }
  213. } {/ORDER BY/} ;# separate sorting pass due to "+" on ORDER BY terms
  214. # The same query with ORDER BY optimizations turned off via built-in test.
  215. #
  216. do_test 2.3a {
  217. optimization_control db order-by-idx-join 0
  218. db cache flush
  219. db eval {
  220. SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn
  221. }
  222. } {one-a one-c two-a two-b three-a three-c}
  223. do_test 2.3b {
  224. db eval {
  225. EXPLAIN QUERY PLAN
  226. SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn
  227. }
  228. } {/ORDER BY/} ;# separate sorting pass due to disabled optimization
  229. optimization_control db all 1
  230. db cache flush
  231. # Reverse order sorts
  232. #
  233. do_test 2.4a {
  234. db eval {
  235. SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn
  236. }
  237. } {three-a three-c two-a two-b one-a one-c}
  238. do_test 2.4b {
  239. db eval {
  240. SELECT name FROM album JOIN track USING (aid) ORDER BY +title DESC, +tn
  241. }
  242. } {three-a three-c two-a two-b one-a one-c} ;# verify same order after sorting
  243. do_test 2.4c {
  244. db eval {
  245. EXPLAIN QUERY PLAN
  246. SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn
  247. }
  248. } {/ORDER BY/} ;# separate sorting pass due to mixed DESC/ASC
  249. do_test 2.5a {
  250. db eval {
  251. SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn DESC
  252. }
  253. } {one-c one-a two-b two-a three-c three-a}
  254. do_test 2.5b {
  255. db eval {
  256. SELECT name FROM album JOIN track USING (aid) ORDER BY +title, +tn DESC
  257. }
  258. } {one-c one-a two-b two-a three-c three-a} ;# verify same order after sorting
  259. do_test 2.5c {
  260. db eval {
  261. EXPLAIN QUERY PLAN
  262. SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn DESC
  263. }
  264. } {/ORDER BY/} ;# separate sorting pass due to mixed ASC/DESC
  265. do_test 2.6a {
  266. db eval {
  267. SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn DESC
  268. }
  269. } {three-c three-a two-b two-a one-c one-a}
  270. do_test 2.6b {
  271. db eval {
  272. SELECT name FROM album JOIN track USING (aid) ORDER BY +title DESC, +tn DESC
  273. }
  274. } {three-c three-a two-b two-a one-c one-a} ;# verify same order after sorting
  275. do_test 2.6c {
  276. db eval {
  277. EXPLAIN QUERY PLAN
  278. SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn DESC
  279. }
  280. } {/ORDER BY/} ;# ORDER BY required
  281. # Generate another test dataset, but this time using mixed ASC/DESC indices.
  282. #
  283. do_test 3.0 {
  284. db eval {
  285. BEGIN;
  286. DROP TABLE album;
  287. DROP TABLE track;
  288. CREATE TABLE album(
  289. aid INTEGER PRIMARY KEY,
  290. title TEXT UNIQUE NOT NULL
  291. );
  292. CREATE TABLE track(
  293. tid INTEGER PRIMARY KEY,
  294. aid INTEGER NOT NULL REFERENCES album,
  295. tn INTEGER NOT NULL,
  296. name TEXT,
  297. UNIQUE(aid ASC, tn DESC)
  298. );
  299. INSERT INTO album VALUES(1, '1-one'), (2, '2-two'), (3, '3-three');
  300. INSERT INTO track VALUES
  301. (NULL, 1, 1, 'one-a'),
  302. (NULL, 2, 2, 'two-b'),
  303. (NULL, 3, 3, 'three-c'),
  304. (NULL, 1, 3, 'one-c'),
  305. (NULL, 2, 1, 'two-a'),
  306. (NULL, 3, 1, 'three-a');
  307. COMMIT;
  308. }
  309. } {}
  310. do_test 3.1a {
  311. db eval {
  312. SELECT name FROM album CROSS JOIN track USING (aid) ORDER BY title, tn DESC
  313. }
  314. } {one-c one-a two-b two-a three-c three-a}
  315. # Verify that the ORDER BY clause is optimized out
  316. #
  317. do_test 3.1b {
  318. db eval {
  319. EXPLAIN QUERY PLAN
  320. SELECT name FROM album CROSS JOIN track USING (aid) ORDER BY title, tn DESC
  321. }
  322. } {~/ORDER BY/} ;# ORDER BY optimized out
  323. # The same query with ORDER BY clause optimization disabled via + operators
  324. # should give exactly the same answer.
  325. #
  326. do_test 3.2a {
  327. db eval {
  328. SELECT name FROM album JOIN track USING (aid) ORDER BY +title, +tn DESC
  329. }
  330. } {one-c one-a two-b two-a three-c three-a}
  331. # The output is sorted manually in this case.
  332. #
  333. do_test 3.2b {
  334. db eval {
  335. EXPLAIN QUERY PLAN
  336. SELECT name FROM album JOIN track USING (aid) ORDER BY +title, +tn DESC
  337. }
  338. } {/ORDER BY/} ;# separate sorting pass due to "+" on ORDER BY terms
  339. # The same query with ORDER BY optimizations turned off via built-in test.
  340. #
  341. do_test 3.3a {
  342. optimization_control db order-by-idx-join 0
  343. db cache flush
  344. db eval {
  345. SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn DESC
  346. }
  347. } {one-c one-a two-b two-a three-c three-a}
  348. do_test 3.3b {
  349. db eval {
  350. EXPLAIN QUERY PLAN
  351. SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn DESC
  352. }
  353. } {/ORDER BY/} ;# separate sorting pass due to disabled optimization
  354. optimization_control db all 1
  355. db cache flush
  356. # Without the mixed ASC/DESC on ORDER BY
  357. #
  358. do_test 3.4a {
  359. db eval {
  360. SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn
  361. }
  362. } {one-a one-c two-a two-b three-a three-c}
  363. do_test 3.4b {
  364. db eval {
  365. SELECT name FROM album JOIN track USING (aid) ORDER BY +title, +tn
  366. }
  367. } {one-a one-c two-a two-b three-a three-c} ;# verify same order after sorting
  368. do_test 3.4c {
  369. db eval {
  370. EXPLAIN QUERY PLAN
  371. SELECT name FROM album JOIN track USING (aid) ORDER BY title, tn
  372. }
  373. } {~/ORDER BY/} ;# ORDER BY suppressed by uniqueness constraints
  374. do_test 3.5a {
  375. db eval {
  376. SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn DESC
  377. }
  378. } {three-c three-a two-b two-a one-c one-a}
  379. do_test 3.5b {
  380. db eval {
  381. SELECT name FROM album JOIN track USING (aid) ORDER BY +title DESC, +tn DESC
  382. }
  383. } {three-c three-a two-b two-a one-c one-a} ;# verify same order after sorting
  384. do_test 3.5c {
  385. db eval {
  386. EXPLAIN QUERY PLAN
  387. SELECT name FROM album JOIN track USING (aid) ORDER BY title DESC, tn DESC
  388. }
  389. } {~/ORDER BY/} ;# ORDER BY suppressed by uniqueness constraints
  390. do_test 3.6a {
  391. db eval {
  392. SELECT name FROM album CROSS JOIN track USING (aid) ORDER BY title DESC, tn
  393. }
  394. } {three-a three-c two-a two-b one-a one-c}
  395. do_test 3.6b {
  396. db eval {
  397. SELECT name FROM album CROSS JOIN track USING (aid)
  398. ORDER BY +title DESC, +tn
  399. }
  400. } {three-a three-c two-a two-b one-a one-c} ;# verify same order after sorting
  401. do_test 3.6c {
  402. db eval {
  403. EXPLAIN QUERY PLAN
  404. SELECT name FROM album CROSS JOIN track USING (aid) ORDER BY title DESC, tn
  405. }
  406. } {~/ORDER BY/} ;# inverted ASC/DESC is optimized out
  407. # Ticket 5ed1772895bf3deeab78c5e3519b1da9165c541b (2013-06-04)
  408. # Incorrect ORDER BY on an indexed JOIN
  409. #
  410. do_test 4.0 {
  411. db eval {
  412. CREATE TABLE t41(a INT UNIQUE NOT NULL, b INT NOT NULL);
  413. CREATE INDEX t41ba ON t41(b,a);
  414. CREATE TABLE t42(x INT NOT NULL REFERENCES t41(a), y INT NOT NULL);
  415. CREATE UNIQUE INDEX t42xy ON t42(x,y);
  416. INSERT INTO t41 VALUES(1,1),(3,1);
  417. INSERT INTO t42 VALUES(1,13),(1,15),(3,14),(3,16);
  418. SELECT b, y FROM t41 CROSS JOIN t42 ON x=a ORDER BY b, y;
  419. }
  420. } {1 13 1 14 1 15 1 16}
  421. finish_test