Annotation of embedaddon/sqlite3/test/limit.test, revision 1.1
1.1 ! misho 1: # 2001 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: # This file implements regression tests for SQLite library. The
! 12: # focus of this file is testing the LIMIT ... OFFSET ... clause
! 13: # of SELECT statements.
! 14: #
! 15: # $Id: limit.test,v 1.32 2008/08/02 03:50:39 drh Exp $
! 16:
! 17: set testdir [file dirname $argv0]
! 18: source $testdir/tester.tcl
! 19:
! 20: # Build some test data
! 21: #
! 22: execsql {
! 23: CREATE TABLE t1(x int, y int);
! 24: BEGIN;
! 25: }
! 26: for {set i 1} {$i<=32} {incr i} {
! 27: for {set j 0} {(1<<$j)<$i} {incr j} {}
! 28: execsql "INSERT INTO t1 VALUES([expr {32-$i}],[expr {10-$j}])"
! 29: }
! 30: execsql {
! 31: COMMIT;
! 32: }
! 33:
! 34: do_test limit-1.0 {
! 35: execsql {SELECT count(*) FROM t1}
! 36: } {32}
! 37: do_test limit-1.1 {
! 38: execsql {SELECT count(*) FROM t1 LIMIT 5}
! 39: } {32}
! 40: do_test limit-1.2.1 {
! 41: execsql {SELECT x FROM t1 ORDER BY x LIMIT 5}
! 42: } {0 1 2 3 4}
! 43: do_test limit-1.2.2 {
! 44: execsql {SELECT x FROM t1 ORDER BY x LIMIT 5 OFFSET 2}
! 45: } {2 3 4 5 6}
! 46: do_test limit-1.2.3 {
! 47: execsql {SELECT x FROM t1 ORDER BY x+1 LIMIT 5 OFFSET -2}
! 48: } {0 1 2 3 4}
! 49: do_test limit-1.2.4 {
! 50: execsql {SELECT x FROM t1 ORDER BY x+1 LIMIT 2, -5}
! 51: } {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}
! 52: do_test limit-1.2.5 {
! 53: execsql {SELECT x FROM t1 ORDER BY x+1 LIMIT -2, 5}
! 54: } {0 1 2 3 4}
! 55: do_test limit-1.2.6 {
! 56: execsql {SELECT x FROM t1 ORDER BY x+1 LIMIT -2, -5}
! 57: } {0 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}
! 58: do_test limit-1.2.7 {
! 59: execsql {SELECT x FROM t1 ORDER BY x LIMIT 2, 5}
! 60: } {2 3 4 5 6}
! 61: do_test limit-1.3 {
! 62: execsql {SELECT x FROM t1 ORDER BY x LIMIT 5 OFFSET 5}
! 63: } {5 6 7 8 9}
! 64: do_test limit-1.4.1 {
! 65: execsql {SELECT x FROM t1 ORDER BY x LIMIT 50 OFFSET 30}
! 66: } {30 31}
! 67: do_test limit-1.4.2 {
! 68: execsql {SELECT x FROM t1 ORDER BY x LIMIT 30, 50}
! 69: } {30 31}
! 70: do_test limit-1.5 {
! 71: execsql {SELECT x FROM t1 ORDER BY x LIMIT 50 OFFSET 50}
! 72: } {}
! 73: do_test limit-1.6 {
! 74: execsql {SELECT * FROM t1 AS a, t1 AS b ORDER BY a.x, b.x LIMIT 5}
! 75: } {0 5 0 5 0 5 1 5 0 5 2 5 0 5 3 5 0 5 4 5}
! 76: do_test limit-1.7 {
! 77: execsql {SELECT * FROM t1 AS a, t1 AS b ORDER BY a.x, b.x LIMIT 5 OFFSET 32}
! 78: } {1 5 0 5 1 5 1 5 1 5 2 5 1 5 3 5 1 5 4 5}
! 79:
! 80: ifcapable {view && subquery} {
! 81: do_test limit-2.1 {
! 82: execsql {
! 83: CREATE VIEW v1 AS SELECT * FROM t1 LIMIT 2;
! 84: SELECT count(*) FROM (SELECT * FROM v1);
! 85: }
! 86: } 2
! 87: } ;# ifcapable view
! 88: do_test limit-2.2 {
! 89: execsql {
! 90: CREATE TABLE t2 AS SELECT * FROM t1 LIMIT 2;
! 91: SELECT count(*) FROM t2;
! 92: }
! 93: } 2
! 94: ifcapable subquery {
! 95: do_test limit-2.3 {
! 96: execsql {
! 97: SELECT count(*) FROM t1 WHERE rowid IN (SELECT rowid FROM t1 LIMIT 2);
! 98: }
! 99: } 2
! 100: }
! 101:
! 102: ifcapable subquery {
! 103: do_test limit-3.1 {
! 104: execsql {
! 105: SELECT z FROM (SELECT y*10+x AS z FROM t1 ORDER BY x LIMIT 10)
! 106: ORDER BY z LIMIT 5;
! 107: }
! 108: } {50 51 52 53 54}
! 109: }
! 110:
! 111: do_test limit-4.1 {
! 112: ifcapable subquery {
! 113: execsql {
! 114: BEGIN;
! 115: CREATE TABLE t3(x);
! 116: INSERT INTO t3 SELECT x FROM t1 ORDER BY x LIMIT 10 OFFSET 1;
! 117: INSERT INTO t3 SELECT x+(SELECT max(x) FROM t3) FROM t3;
! 118: INSERT INTO t3 SELECT x+(SELECT max(x) FROM t3) FROM t3;
! 119: INSERT INTO t3 SELECT x+(SELECT max(x) FROM t3) FROM t3;
! 120: INSERT INTO t3 SELECT x+(SELECT max(x) FROM t3) FROM t3;
! 121: INSERT INTO t3 SELECT x+(SELECT max(x) FROM t3) FROM t3;
! 122: INSERT INTO t3 SELECT x+(SELECT max(x) FROM t3) FROM t3;
! 123: INSERT INTO t3 SELECT x+(SELECT max(x) FROM t3) FROM t3;
! 124: INSERT INTO t3 SELECT x+(SELECT max(x) FROM t3) FROM t3;
! 125: INSERT INTO t3 SELECT x+(SELECT max(x) FROM t3) FROM t3;
! 126: INSERT INTO t3 SELECT x+(SELECT max(x) FROM t3) FROM t3;
! 127: END;
! 128: SELECT count(*) FROM t3;
! 129: }
! 130: } else {
! 131: execsql {
! 132: BEGIN;
! 133: CREATE TABLE t3(x);
! 134: INSERT INTO t3 SELECT x FROM t1 ORDER BY x LIMIT 10 OFFSET 1;
! 135: }
! 136: for {set i 0} {$i<10} {incr i} {
! 137: set max_x_t3 [execsql {SELECT max(x) FROM t3}]
! 138: execsql "INSERT INTO t3 SELECT x+$max_x_t3 FROM t3;"
! 139: }
! 140: execsql {
! 141: END;
! 142: SELECT count(*) FROM t3;
! 143: }
! 144: }
! 145: } {10240}
! 146: do_test limit-4.2 {
! 147: execsql {
! 148: SELECT x FROM t3 LIMIT 2 OFFSET 10000
! 149: }
! 150: } {10001 10002}
! 151: do_test limit-4.3 {
! 152: execsql {
! 153: CREATE TABLE t4 AS SELECT x,
! 154: 'abcdefghijklmnopqrstuvwyxz ABCDEFGHIJKLMNOPQRSTUVWYXZ' || x ||
! 155: 'abcdefghijklmnopqrstuvwyxz ABCDEFGHIJKLMNOPQRSTUVWYXZ' || x ||
! 156: 'abcdefghijklmnopqrstuvwyxz ABCDEFGHIJKLMNOPQRSTUVWYXZ' || x ||
! 157: 'abcdefghijklmnopqrstuvwyxz ABCDEFGHIJKLMNOPQRSTUVWYXZ' || x ||
! 158: 'abcdefghijklmnopqrstuvwyxz ABCDEFGHIJKLMNOPQRSTUVWYXZ' || x AS y
! 159: FROM t3 LIMIT 1000;
! 160: SELECT x FROM t4 ORDER BY y DESC LIMIT 1 OFFSET 999;
! 161: }
! 162: } {1000}
! 163:
! 164: do_test limit-5.1 {
! 165: execsql {
! 166: CREATE TABLE t5(x,y);
! 167: INSERT INTO t5 SELECT x-y, x+y FROM t1 WHERE x BETWEEN 10 AND 15
! 168: ORDER BY x LIMIT 2;
! 169: SELECT * FROM t5 ORDER BY x;
! 170: }
! 171: } {5 15 6 16}
! 172: do_test limit-5.2 {
! 173: execsql {
! 174: DELETE FROM t5;
! 175: INSERT INTO t5 SELECT x-y, x+y FROM t1 WHERE x BETWEEN 10 AND 15
! 176: ORDER BY x DESC LIMIT 2;
! 177: SELECT * FROM t5 ORDER BY x;
! 178: }
! 179: } {9 19 10 20}
! 180: do_test limit-5.3 {
! 181: execsql {
! 182: DELETE FROM t5;
! 183: INSERT INTO t5 SELECT x-y, x+y FROM t1 WHERE x ORDER BY x DESC LIMIT 31;
! 184: SELECT * FROM t5 ORDER BY x LIMIT 2;
! 185: }
! 186: } {-4 6 -3 7}
! 187: do_test limit-5.4 {
! 188: execsql {
! 189: SELECT * FROM t5 ORDER BY x DESC, y DESC LIMIT 2;
! 190: }
! 191: } {21 41 21 39}
! 192: do_test limit-5.5 {
! 193: execsql {
! 194: DELETE FROM t5;
! 195: INSERT INTO t5 SELECT a.x*100+b.x, a.y*100+b.y FROM t1 AS a, t1 AS b
! 196: ORDER BY 1, 2 LIMIT 1000;
! 197: SELECT count(*), sum(x), sum(y), min(x), max(x), min(y), max(y) FROM t5;
! 198: }
! 199: } {1000 1528204 593161 0 3107 505 1005}
! 200:
! 201: # There is some contraversy about whether LIMIT 0 should be the same as
! 202: # no limit at all or if LIMIT 0 should result in zero output rows.
! 203: #
! 204: do_test limit-6.1 {
! 205: execsql {
! 206: BEGIN;
! 207: CREATE TABLE t6(a);
! 208: INSERT INTO t6 VALUES(1);
! 209: INSERT INTO t6 VALUES(2);
! 210: INSERT INTO t6 SELECT a+2 FROM t6;
! 211: COMMIT;
! 212: SELECT * FROM t6;
! 213: }
! 214: } {1 2 3 4}
! 215: do_test limit-6.2 {
! 216: execsql {
! 217: SELECT * FROM t6 LIMIT -1 OFFSET -1;
! 218: }
! 219: } {1 2 3 4}
! 220: do_test limit-6.3 {
! 221: execsql {
! 222: SELECT * FROM t6 LIMIT 2 OFFSET -123;
! 223: }
! 224: } {1 2}
! 225: do_test limit-6.4 {
! 226: execsql {
! 227: SELECT * FROM t6 LIMIT -432 OFFSET 2;
! 228: }
! 229: } {3 4}
! 230: do_test limit-6.5 {
! 231: execsql {
! 232: SELECT * FROM t6 LIMIT -1
! 233: }
! 234: } {1 2 3 4}
! 235: do_test limit-6.6 {
! 236: execsql {
! 237: SELECT * FROM t6 LIMIT -1 OFFSET 1
! 238: }
! 239: } {2 3 4}
! 240: do_test limit-6.7 {
! 241: execsql {
! 242: SELECT * FROM t6 LIMIT 0
! 243: }
! 244: } {}
! 245: do_test limit-6.8 {
! 246: execsql {
! 247: SELECT * FROM t6 LIMIT 0 OFFSET 1
! 248: }
! 249: } {}
! 250:
! 251: # Make sure LIMIT works well with compound SELECT statements.
! 252: # Ticket #393
! 253: #
! 254: ifcapable compound {
! 255: do_test limit-7.1.1 {
! 256: catchsql {
! 257: SELECT x FROM t2 LIMIT 5 UNION ALL SELECT a FROM t6;
! 258: }
! 259: } {1 {LIMIT clause should come after UNION ALL not before}}
! 260: do_test limit-7.1.2 {
! 261: catchsql {
! 262: SELECT x FROM t2 LIMIT 5 UNION SELECT a FROM t6;
! 263: }
! 264: } {1 {LIMIT clause should come after UNION not before}}
! 265: do_test limit-7.1.3 {
! 266: catchsql {
! 267: SELECT x FROM t2 LIMIT 5 EXCEPT SELECT a FROM t6 LIMIT 3;
! 268: }
! 269: } {1 {LIMIT clause should come after EXCEPT not before}}
! 270: do_test limit-7.1.4 {
! 271: catchsql {
! 272: SELECT x FROM t2 LIMIT 0,5 INTERSECT SELECT a FROM t6;
! 273: }
! 274: } {1 {LIMIT clause should come after INTERSECT not before}}
! 275: do_test limit-7.2 {
! 276: execsql {
! 277: SELECT x FROM t2 UNION ALL SELECT a FROM t6 LIMIT 5;
! 278: }
! 279: } {31 30 1 2 3}
! 280: do_test limit-7.3 {
! 281: execsql {
! 282: SELECT x FROM t2 UNION ALL SELECT a FROM t6 LIMIT 3 OFFSET 1;
! 283: }
! 284: } {30 1 2}
! 285: do_test limit-7.4 {
! 286: execsql {
! 287: SELECT x FROM t2 UNION ALL SELECT a FROM t6 ORDER BY 1 LIMIT 3 OFFSET 1;
! 288: }
! 289: } {2 3 4}
! 290: do_test limit-7.5 {
! 291: execsql {
! 292: SELECT x FROM t2 UNION SELECT x+2 FROM t2 LIMIT 2 OFFSET 1;
! 293: }
! 294: } {31 32}
! 295: do_test limit-7.6 {
! 296: execsql {
! 297: SELECT x FROM t2 UNION SELECT x+2 FROM t2 ORDER BY 1 DESC LIMIT 2 OFFSET 1;
! 298: }
! 299: } {32 31}
! 300: do_test limit-7.7 {
! 301: execsql {
! 302: SELECT a+9 FROM t6 EXCEPT SELECT y FROM t2 LIMIT 2;
! 303: }
! 304: } {11 12}
! 305: do_test limit-7.8 {
! 306: execsql {
! 307: SELECT a+9 FROM t6 EXCEPT SELECT y FROM t2 ORDER BY 1 DESC LIMIT 2;
! 308: }
! 309: } {13 12}
! 310: do_test limit-7.9 {
! 311: execsql {
! 312: SELECT a+26 FROM t6 INTERSECT SELECT x FROM t2 LIMIT 1;
! 313: }
! 314: } {30}
! 315: do_test limit-7.10 {
! 316: execsql {
! 317: SELECT a+27 FROM t6 INTERSECT SELECT x FROM t2 LIMIT 1;
! 318: }
! 319: } {30}
! 320: do_test limit-7.11 {
! 321: execsql {
! 322: SELECT a+27 FROM t6 INTERSECT SELECT x FROM t2 LIMIT 1 OFFSET 1;
! 323: }
! 324: } {31}
! 325: do_test limit-7.12 {
! 326: execsql {
! 327: SELECT a+27 FROM t6 INTERSECT SELECT x FROM t2
! 328: ORDER BY 1 DESC LIMIT 1 OFFSET 1;
! 329: }
! 330: } {30}
! 331: } ;# ifcapable compound
! 332:
! 333: # Tests for limit in conjunction with distinct. The distinct should
! 334: # occur before both the limit and the offset. Ticket #749.
! 335: #
! 336: do_test limit-8.1 {
! 337: execsql {
! 338: SELECT DISTINCT cast(round(x/100) as integer) FROM t3 LIMIT 5;
! 339: }
! 340: } {0 1 2 3 4}
! 341: do_test limit-8.2 {
! 342: execsql {
! 343: SELECT DISTINCT cast(round(x/100) as integer) FROM t3 LIMIT 5 OFFSET 5;
! 344: }
! 345: } {5 6 7 8 9}
! 346: do_test limit-8.3 {
! 347: execsql {
! 348: SELECT DISTINCT cast(round(x/100) as integer) FROM t3 LIMIT 5 OFFSET 25;
! 349: }
! 350: } {25 26 27 28 29}
! 351:
! 352: # Make sure limits on multiple subqueries work correctly.
! 353: # Ticket #1035
! 354: #
! 355: ifcapable subquery {
! 356: do_test limit-9.1 {
! 357: execsql {
! 358: SELECT * FROM (SELECT * FROM t6 LIMIT 3);
! 359: }
! 360: } {1 2 3}
! 361: }
! 362: do_test limit-9.2.1 {
! 363: execsql {
! 364: CREATE TABLE t7 AS SELECT * FROM t6;
! 365: }
! 366: } {}
! 367: ifcapable subquery {
! 368: do_test limit-9.2.2 {
! 369: execsql {
! 370: SELECT * FROM (SELECT * FROM t7 LIMIT 3);
! 371: }
! 372: } {1 2 3}
! 373: }
! 374: ifcapable compound {
! 375: ifcapable subquery {
! 376: do_test limit-9.3 {
! 377: execsql {
! 378: SELECT * FROM (SELECT * FROM t6 LIMIT 3)
! 379: UNION
! 380: SELECT * FROM (SELECT * FROM t7 LIMIT 3)
! 381: ORDER BY 1
! 382: }
! 383: } {1 2 3}
! 384: do_test limit-9.4 {
! 385: execsql {
! 386: SELECT * FROM (SELECT * FROM t6 LIMIT 3)
! 387: UNION
! 388: SELECT * FROM (SELECT * FROM t7 LIMIT 3)
! 389: ORDER BY 1
! 390: LIMIT 2
! 391: }
! 392: } {1 2}
! 393: }
! 394: do_test limit-9.5 {
! 395: catchsql {
! 396: SELECT * FROM t6 LIMIT 3
! 397: UNION
! 398: SELECT * FROM t7 LIMIT 3
! 399: }
! 400: } {1 {LIMIT clause should come after UNION not before}}
! 401: }
! 402:
! 403: # Test LIMIT and OFFSET using SQL variables.
! 404: do_test limit-10.1 {
! 405: set limit 10
! 406: db eval {
! 407: SELECT x FROM t1 LIMIT :limit;
! 408: }
! 409: } {31 30 29 28 27 26 25 24 23 22}
! 410: do_test limit-10.2 {
! 411: set limit 5
! 412: set offset 5
! 413: db eval {
! 414: SELECT x FROM t1 LIMIT :limit OFFSET :offset;
! 415: }
! 416: } {26 25 24 23 22}
! 417: do_test limit-10.3 {
! 418: set limit -1
! 419: db eval {
! 420: SELECT x FROM t1 WHERE x<10 LIMIT :limit;
! 421: }
! 422: } {9 8 7 6 5 4 3 2 1 0}
! 423: do_test limit-10.4 {
! 424: set limit 1.5
! 425: set rc [catch {
! 426: db eval {
! 427: SELECT x FROM t1 WHERE x<10 LIMIT :limit;
! 428: } } msg]
! 429: list $rc $msg
! 430: } {1 {datatype mismatch}}
! 431: do_test limit-10.5 {
! 432: set limit "hello world"
! 433: set rc [catch {
! 434: db eval {
! 435: SELECT x FROM t1 WHERE x<10 LIMIT :limit;
! 436: } } msg]
! 437: list $rc $msg
! 438: } {1 {datatype mismatch}}
! 439:
! 440: ifcapable subquery {
! 441: do_test limit-11.1 {
! 442: db eval {
! 443: SELECT x FROM (SELECT x FROM t1 ORDER BY x LIMIT 0) ORDER BY x
! 444: }
! 445: } {}
! 446: } ;# ifcapable subquery
! 447:
! 448: # Test error processing.
! 449: #
! 450: do_test limit-12.1 {
! 451: catchsql {
! 452: SELECT * FROM t1 LIMIT replace(1)
! 453: }
! 454: } {1 {wrong number of arguments to function replace()}}
! 455: do_test limit-12.2 {
! 456: catchsql {
! 457: SELECT * FROM t1 LIMIT 5 OFFSET replace(1)
! 458: }
! 459: } {1 {wrong number of arguments to function replace()}}
! 460: do_test limit-12.3 {
! 461: catchsql {
! 462: SELECT * FROM t1 LIMIT x
! 463: }
! 464: } {1 {no such column: x}}
! 465: do_test limit-12.4 {
! 466: catchsql {
! 467: SELECT * FROM t1 LIMIT 1 OFFSET x
! 468: }
! 469: } {1 {no such column: x}}
! 470:
! 471:
! 472: finish_test
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>