]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Add tests for ORDER BY, LIMIT and OFFSET clauses to e_select.test.
authordan <dan@noemail.net>
Thu, 16 Sep 2010 18:51:09 +0000 (18:51 +0000)
committerdan <dan@noemail.net>
Thu, 16 Sep 2010 18:51:09 +0000 (18:51 +0000)
FossilOrigin-Name: 7c989db55cbe87dfb8659dcf534f72cdc2df3bc5

manifest
manifest.uuid
test/e_select.test

index 9ba9cc5d246c5a04bc9943bc2899e5c6d94a3c32..cde6a7581107bd109931f5513a054f5ac4bc3cc7 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Further\stweaks\srelated\sto\sdeleting\sfiles\sfrom\smalloc_common.tcl.
-D 2010-09-16T16:16:07
+C Add\stests\sfor\sORDER\sBY,\sLIMIT\sand\sOFFSET\sclauses\sto\se_select.test.
+D 2010-09-16T18:51:09
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in c599a15d268b1db2aeadea19df2adc3bf2eb6bee
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -350,7 +350,7 @@ F test/distinctagg.test 1a6ef9c87a58669438fc771450d7a72577417376
 F test/e_expr.test 164e87c1d7b40ceb47c57c3bffa384c81d009aa7
 F test/e_fkey.test 6721a741c6499b3ab7e5385923233343c8f1ad05
 F test/e_fts3.test 75bb0aee26384ef586165e21018a17f7cd843469
-F test/e_select.test 8eea9e86a36c61c9d75ac5830a069916e70ab05d
+F test/e_select.test 08868f620e244579913ca11b758eed82f2027dde
 F test/enc.test e54531cd6bf941ee6760be041dff19a104c7acea
 F test/enc2.test 6d91a5286f59add0cfcbb2d0da913b76f2242398
 F test/enc3.test 5c550d59ff31dccdba5d1a02ae11c7047d77c041
@@ -857,7 +857,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
 F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
-P e07a33ea0fd50d56f2d00965c754e652c48f32fb
-R 4597070adb412a9d1599a6d66968aaba
+P 3e649f80e2a1b2e098f6ca32994ba40157271e69
+R 62bec971cfb429e388867311d3233a9a
 U dan
-Z a4c88f0ce920360a36140ed000ccaa9e
+Z 8ab963ff6625685ba34c3c915673797e
index 057f4387e8612d695a5d4f842e5e970bfdf08af3..f53744ae8d30a091a28fcbf662f634b277fb8f3c 100644 (file)
@@ -1 +1 @@
-3e649f80e2a1b2e098f6ca32994ba40157271e69
\ No newline at end of file
+7c989db55cbe87dfb8659dcf534f72cdc2df3bc5
\ No newline at end of file
index b6c5c81bbf4c07e3b9df361a1c094e3ef2a9a479..9bac6e9d409dd662c068e28051c229fa181b97a6 100644 (file)
@@ -2298,4 +2298,291 @@ do_execsql_test e_select-8.12.1 {
   SELECT x FROM d4 ORDER BY x||''
 } {DEF JKL abc ghi}
 
+# EVIDENCE-OF: R-44130-32593 If an ORDER BY expression is not an integer
+# alias, then SQLite searches the left-most SELECT in the compound for a
+# result column that matches either the second or third rules above. If
+# a match is found, the search stops and the expression is handled as an
+# alias for the result column that it has been matched against.
+# Otherwise, the next SELECT to the right is tried, and so on.
+#
+do_execsql_test e_select-8.13.0 {
+  CREATE TABLE d5(a, b);
+  CREATE TABLE d6(c, d);
+  CREATE TABLE d7(e, f);
+  INSERT INTO d5 VALUES(1, 'f');
+  INSERT INTO d6 VALUES(2, 'e');
+  INSERT INTO d7 VALUES(3, 'd');
+  INSERT INTO d5 VALUES(4, 'c');
+  INSERT INTO d6 VALUES(5, 'b');
+  INSERT INTO d7 VALUES(6, 'a');
+
+  CREATE TABLE d8(x COLLATE nocase);
+  CREATE TABLE d9(y COLLATE nocase);
+
+  INSERT INTO d8 VALUES('a');
+  INSERT INTO d9 VALUES('B');
+  INSERT INTO d8 VALUES('c');
+  INSERT INTO d9 VALUES('D');
+} {}
+foreach {tn select res} {
+  1   { SELECT a FROM d5 UNION ALL SELECT c FROM d6 UNION ALL SELECT e FROM d7
+         ORDER BY a
+      } {1 2 3 4 5 6}
+  2   { SELECT a FROM d5 UNION ALL SELECT c FROM d6 UNION ALL SELECT e FROM d7
+         ORDER BY c
+      } {1 2 3 4 5 6}
+  3   { SELECT a FROM d5 UNION ALL SELECT c FROM d6 UNION ALL SELECT e FROM d7
+         ORDER BY e
+      } {1 2 3 4 5 6}
+  4   { SELECT a FROM d5 UNION ALL SELECT c FROM d6 UNION ALL SELECT e FROM d7
+         ORDER BY 1
+      } {1 2 3 4 5 6}
+
+  5   { SELECT a, b FROM d5 UNION ALL SELECT b, a FROM d5 ORDER BY b } 
+      {f 1   c 4   4 c   1 f}
+  6   { SELECT a, b FROM d5 UNION ALL SELECT b, a FROM d5 ORDER BY 2 } 
+      {f 1   c 4   4 c   1 f}
+
+  7   { SELECT a, b FROM d5 UNION ALL SELECT b, a FROM d5 ORDER BY a } 
+      {1 f   4 c   c 4   f 1}
+  8   { SELECT a, b FROM d5 UNION ALL SELECT b, a FROM d5 ORDER BY 1 } 
+      {1 f   4 c   c 4   f 1}
+
+  9   { SELECT a, b FROM d5 UNION ALL SELECT b, a+1 FROM d5 ORDER BY a+1 } 
+      {f 2   c 5   4 c   1 f}
+  10  { SELECT a, b FROM d5 UNION ALL SELECT b, a+1 FROM d5 ORDER BY 2 } 
+      {f 2   c 5   4 c   1 f}
+
+  11  { SELECT a+1, b FROM d5 UNION ALL SELECT b, a+1 FROM d5 ORDER BY a+1 } 
+      {2 f   5 c   c 5   f 2}
+  12  { SELECT a+1, b FROM d5 UNION ALL SELECT b, a+1 FROM d5 ORDER BY 1 } 
+      {2 f   5 c   c 5   f 2}
+
+} {
+  do_execsql_test e_select-8.13.$tn $select [list {*}$res]
+}
+
+# EVIDENCE-OF: R-39265-04070 If no matching expression can be found in
+# the result columns of any constituent SELECT, it is an error.
+#
+foreach {tn select idx} {
+  1   { SELECT a FROM d5 UNION SELECT c FROM d6 ORDER BY a+1 }          1st
+  2   { SELECT a FROM d5 UNION SELECT c FROM d6 ORDER BY a, a+1 }       2nd
+  3   { SELECT * FROM d5 INTERSECT SELECT * FROM d6 ORDER BY 'hello' }  1st
+  4   { SELECT * FROM d5 INTERSECT SELECT * FROM d6 ORDER BY blah    }  1st
+  5   { SELECT * FROM d5 INTERSECT SELECT * FROM d6 ORDER BY c,d,c+d }  3rd
+  6   { SELECT * FROM d5 EXCEPT SELECT * FROM d7 ORDER BY 1,2,b,a/b  }  4th
+} {
+  set err "$idx ORDER BY term does not match any column in the result set"
+  do_catchsql_test e_select-8.14.$tn $select [list 1 $err]
+}
+
+# EVIDENCE-OF: R-03407-11483 Each term of the ORDER BY clause is
+# processed separately and may be matched against result columns from
+# different SELECT statements in the compound.
+# 
+foreach {tn select res} {
+  1  { SELECT a, b FROM d5 UNION ALL SELECT c-1, d FROM d6 ORDER BY a, d }
+     {1 e   1 f   4 b   4 c}
+  2  { SELECT a, b FROM d5 UNION ALL SELECT c-1, d FROM d6 ORDER BY c-1, b }
+     {1 e   1 f   4 b   4 c}
+  3  { SELECT a, b FROM d5 UNION ALL SELECT c-1, d FROM d6 ORDER BY 1, 2 }
+     {1 e   1 f   4 b   4 c}
+} {
+  do_execsql_test e_select-8.15.$tn $select [list {*}$res]
+}
+
+
+#-------------------------------------------------------------------------
+# Tests related to statements made about the LIMIT/OFFSET clause.
+#
+do_execsql_test e_select-9.0 {
+  CREATE TABLE f1(a, b);
+  INSERT INTO f1 VALUES(26, 'z');
+  INSERT INTO f1 VALUES(25, 'y');
+  INSERT INTO f1 VALUES(24, 'x');
+  INSERT INTO f1 VALUES(23, 'w');
+  INSERT INTO f1 VALUES(22, 'v');
+  INSERT INTO f1 VALUES(21, 'u');
+  INSERT INTO f1 VALUES(20, 't');
+  INSERT INTO f1 VALUES(19, 's');
+  INSERT INTO f1 VALUES(18, 'r');
+  INSERT INTO f1 VALUES(17, 'q');
+  INSERT INTO f1 VALUES(16, 'p');
+  INSERT INTO f1 VALUES(15, 'o');
+  INSERT INTO f1 VALUES(14, 'n');
+  INSERT INTO f1 VALUES(13, 'm');
+  INSERT INTO f1 VALUES(12, 'l');
+  INSERT INTO f1 VALUES(11, 'k');
+  INSERT INTO f1 VALUES(10, 'j');
+  INSERT INTO f1 VALUES(9, 'i');
+  INSERT INTO f1 VALUES(8, 'h');
+  INSERT INTO f1 VALUES(7, 'g');
+  INSERT INTO f1 VALUES(6, 'f');
+  INSERT INTO f1 VALUES(5, 'e');
+  INSERT INTO f1 VALUES(4, 'd');
+  INSERT INTO f1 VALUES(3, 'c');
+  INSERT INTO f1 VALUES(2, 'b');
+  INSERT INTO f1 VALUES(1, 'a');
+} {}
+
+# EVIDENCE-OF: R-30481-56627 Any scalar expression may be used in the
+# LIMIT clause, so long as it evaluates to an integer or a value that
+# can be losslessly converted to an integer.
+#
+foreach {tn select res} {
+  1  { SELECT b FROM f1 ORDER BY a LIMIT 5 } {a b c d e}
+  2  { SELECT b FROM f1 ORDER BY a LIMIT 2+3 } {a b c d e}
+  3  { SELECT b FROM f1 ORDER BY a LIMIT (SELECT a FROM f1 WHERE b = 'e') } 
+     {a b c d e}
+  4  { SELECT b FROM f1 ORDER BY a LIMIT 5.0 } {a b c d e}
+  5  { SELECT b FROM f1 ORDER BY a LIMIT '5' } {a b c d e}
+} {
+  do_execsql_test e_select-9.1.$tn $select [list {*}$res]
+}
+
+# EVIDENCE-OF: R-46155-47219 If the expression evaluates to a NULL value
+# or any other value that cannot be losslessly converted to an integer,
+# an error is returned.
+#
+foreach {tn select} {
+  1  { SELECT b FROM f1 ORDER BY a LIMIT 'hello' } 
+  2  { SELECT b FROM f1 ORDER BY a LIMIT NULL } 
+  3  { SELECT b FROM f1 ORDER BY a LIMIT X'ABCD' } 
+  4  { SELECT b FROM f1 ORDER BY a LIMIT 5.1 } 
+  5  { SELECT b FROM f1 ORDER BY a LIMIT (SELECT group_concat(b) FROM f1) } 
+} {
+  do_catchsql_test e_select-9.2.$tn $select {1 {datatype mismatch}}
+}
+
+# EVIDENCE-OF: R-03014-26414 If the LIMIT expression evaluates to a
+# negative value, then there is no upper bound on the number of rows
+# returned.
+#
+foreach {tn select res} {
+  1  { SELECT b FROM f1 ORDER BY a LIMIT -1 } 
+     {a b c d e f g h i j k l m n o p q r s t u v w x y z}
+  2  { SELECT b FROM f1 ORDER BY a LIMIT length('abc')-100 } 
+     {a b c d e f g h i j k l m n o p q r s t u v w x y z}
+  3  { SELECT b FROM f1 ORDER BY a LIMIT (SELECT count(*) FROM f1)/2 - 14 }
+     {a b c d e f g h i j k l m n o p q r s t u v w x y z}
+} {
+  do_execsql_test e_select-9.4.$tn $select [list {*}$res]
+}
+
+# EVIDENCE-OF: R-33750-29536 Otherwise, the SELECT returns the first N
+# rows of its result set only, where N is the value that the LIMIT
+# expression evaluates to.
+#
+foreach {tn select res} {
+  1  { SELECT b FROM f1 ORDER BY a LIMIT 0 } {}
+  2  { SELECT b FROM f1 ORDER BY a DESC LIMIT 4 } {z y x w}
+  3  { SELECT b FROM f1 ORDER BY a DESC LIMIT 8 } {z y x w v u t s}
+  4  { SELECT b FROM f1 ORDER BY a DESC LIMIT '12.0' } {z y x w v u t s r q p o}
+} {
+  do_execsql_test e_select-9.5.$tn $select [list {*}$res]
+}
+
+# EVIDENCE-OF: R-54935-19057 Or, if the SELECT statement would return
+# less than N rows without a LIMIT clause, then the entire result set is
+# returned.
+#
+foreach {tn select res} {
+  1  { SELECT b FROM f1 WHERE a>21 ORDER BY a LIMIT 10 } {v w x y z}
+  2  { SELECT count(*) FROM f1 GROUP BY a/5 ORDER BY 1 LIMIT 10 } {2 4 5 5 5 5}
+} {
+  do_execsql_test e_select-9.6.$tn $select [list {*}$res]
+}
+
+
+# EVIDENCE-OF: R-24188-24349 The expression attached to the optional
+# OFFSET clause that may follow a LIMIT clause must also evaluate to an
+# integer, or a value that can be losslessly converted to an integer.
+#
+foreach {tn select} {
+  1  { SELECT b FROM f1 ORDER BY a LIMIT 2 OFFSET 'hello' } 
+  2  { SELECT b FROM f1 ORDER BY a LIMIT 2 OFFSET NULL } 
+  3  { SELECT b FROM f1 ORDER BY a LIMIT 2 OFFSET X'ABCD' } 
+  4  { SELECT b FROM f1 ORDER BY a LIMIT 2 OFFSET 5.1 } 
+  5  { SELECT b FROM f1 ORDER BY a 
+       LIMIT 2 OFFSET (SELECT group_concat(b) FROM f1) 
+  } 
+} {
+  do_catchsql_test e_select-9.7.$tn $select {1 {datatype mismatch}}
+}
+
+# EVIDENCE-OF: R-20467-43422 If an expression has an OFFSET clause, then
+# the first M rows are omitted from the result set returned by the
+# SELECT statement and the next N rows are returned, where M and N are
+# the values that the OFFSET and LIMIT clauses evaluate to,
+# respectively.
+#
+foreach {tn select res} {
+  1  { SELECT b FROM f1 ORDER BY a LIMIT 10 OFFSET 5} {f g h i j k l m n o}
+  2  { SELECT b FROM f1 ORDER BY a LIMIT 2+3 OFFSET 10} {k l m n o}
+  3  { SELECT b FROM f1 ORDER BY a 
+       LIMIT  (SELECT a FROM f1 WHERE b='j') 
+       OFFSET (SELECT a FROM f1 WHERE b='b') 
+     } {c d e f g h i j k l}
+  4  { SELECT b FROM f1 ORDER BY a LIMIT '5' OFFSET 3.0 } {d e f g h}
+  5  { SELECT b FROM f1 ORDER BY a LIMIT '5' OFFSET 0 } {a b c d e}
+  6  { SELECT b FROM f1 ORDER BY a LIMIT 0 OFFSET 10 } {}
+  7  { SELECT b FROM f1 ORDER BY a LIMIT 3 OFFSET '1'||'5' } {p q r}
+} {
+  do_execsql_test e_select-9.8.$tn $select [list {*}$res]
+}
+
+# EVIDENCE-OF: R-34648-44875 Or, if the SELECT would return less than
+# M+N rows if it did not have a LIMIT clause, then the first M rows are
+# skipped and the remaining rows (if any) are returned.
+#
+foreach {tn select res} {
+  1  { SELECT b FROM f1 ORDER BY a LIMIT 10 OFFSET 20} {u v w x y z}
+  2  { SELECT a FROM f1 ORDER BY a DESC LIMIT 100 OFFSET 18+4} {4 3 2 1}
+} {
+  do_execsql_test e_select-9.9.$tn $select [list {*}$res]
+}
+
+
+# EVIDENCE-OF: R-23293-62447 If the OFFSET clause evaluates to a
+# negative value, the results are the same as if it had evaluated to
+# zero.
+#
+foreach {tn select res} {
+  1  { SELECT b FROM f1 ORDER BY a LIMIT 5 OFFSET -1 } {a b c d e}
+  2  { SELECT b FROM f1 ORDER BY a LIMIT 5 OFFSET -500 } {a b c d e}
+  3  { SELECT b FROM f1 ORDER BY a LIMIT 5 OFFSET 0  } {a b c d e}
+} {
+  do_execsql_test e_select-9.10.$tn $select [list {*}$res]
+}
+
+# EVIDENCE-OF: R-19509-40356 Instead of a separate OFFSET clause, the
+# LIMIT clause may specify two scalar expressions separated by a comma.
+#
+# EVIDENCE-OF: R-33788-46243 In this case, the first expression is used
+# as the OFFSET expression and the second as the LIMIT expression.
+#
+foreach {tn select res} {
+  1  { SELECT b FROM f1 ORDER BY a LIMIT 5, 10 } {f g h i j k l m n o}
+  2  { SELECT b FROM f1 ORDER BY a LIMIT 10, 2+3 } {k l m n o}
+  3  { SELECT b FROM f1 ORDER BY a 
+       LIMIT (SELECT a FROM f1 WHERE b='b'), (SELECT a FROM f1 WHERE b='j') 
+     } {c d e f g h i j k l}
+  4  { SELECT b FROM f1 ORDER BY a LIMIT 3.0, '5' } {d e f g h}
+  5  { SELECT b FROM f1 ORDER BY a LIMIT 0, '5' } {a b c d e}
+  6  { SELECT b FROM f1 ORDER BY a LIMIT 10, 0 } {}
+  7  { SELECT b FROM f1 ORDER BY a LIMIT '1'||'5', 3 } {p q r}
+
+  8  { SELECT b FROM f1 ORDER BY a LIMIT 20, 10 } {u v w x y z}
+  9  { SELECT a FROM f1 ORDER BY a DESC LIMIT 18+4, 100 } {4 3 2 1}
+
+  10 { SELECT b FROM f1 ORDER BY a LIMIT -1, 5 } {a b c d e}
+  11 { SELECT b FROM f1 ORDER BY a LIMIT -500, 5 } {a b c d e}
+  12 { SELECT b FROM f1 ORDER BY a LIMIT 0, 5 } {a b c d e}
+} {
+  do_execsql_test e_select-9.11.$tn $select [list {*}$res]
+}
+
+
 finish_test