xref: /sqlite-3.40.0/test/wherelimit.test (revision 1408bf17)
18a7389f2Sshane# 2008 October 6
28a7389f2Sshane#
38a7389f2Sshane# The author disclaims copyright to this source code.  In place of
48a7389f2Sshane# a legal notice, here is a blessing:
58a7389f2Sshane#
68a7389f2Sshane#    May you do good and not evil.
78a7389f2Sshane#    May you find forgiveness for yourself and forgive others.
88a7389f2Sshane#    May you share freely, never taking more than you give.
98a7389f2Sshane#
108a7389f2Sshane#***********************************************************************
118a7389f2Sshane# This file implements regression tests for SQLite library.  The
128a7389f2Sshane# focus of this file is testing the LIMIT ... OFFSET ... clause
138a7389f2Sshane#  of UPDATE and DELETE statements.
148a7389f2Sshane#
1549ffdbf4Sshane# $Id: wherelimit.test,v 1.2 2008/10/10 18:25:46 shane Exp $
168a7389f2Sshane
178a7389f2Sshaneset testdir [file dirname $argv0]
188a7389f2Sshanesource $testdir/tester.tcl
198a7389f2Sshane
208a7389f2Sshaneproc create_test_data {size} {
218a7389f2Sshane  # Build some test data
228a7389f2Sshane  #
238a7389f2Sshane  execsql {
248a7389f2Sshane    DROP TABLE IF EXISTS t1;
258a7389f2Sshane    CREATE TABLE t1(x int, y int);
268a7389f2Sshane    BEGIN;
278a7389f2Sshane  }
288a7389f2Sshane  for {set i 1} {$i<=$size} {incr i} {
298a7389f2Sshane    for {set j 1} {$j<=$size} {incr j} {
308a7389f2Sshane      execsql "INSERT INTO t1 VALUES([expr {$i}],[expr {$j}])"
318a7389f2Sshane    }
328a7389f2Sshane  }
338a7389f2Sshane  execsql {
348a7389f2Sshane    COMMIT;
358a7389f2Sshane  }
368a7389f2Sshane  return {}
378a7389f2Sshane}
388a7389f2Sshane
398a7389f2Sshaneifcapable {update_delete_limit} {
408a7389f2Sshane
41b3c16b89Sdan  execsql { CREATE TABLE t1(x, y) }
42b3c16b89Sdan
438a7389f2Sshane  # check syntax error support
448a7389f2Sshane  do_test wherelimit-0.1 {
458a7389f2Sshane    catchsql {DELETE FROM t1 ORDER BY x}
468a7389f2Sshane  } {1 {ORDER BY without LIMIT on DELETE}}
478a7389f2Sshane  do_test wherelimit-0.2 {
488a7389f2Sshane    catchsql {DELETE FROM t1 WHERE x=1 ORDER BY x}
498a7389f2Sshane  } {1 {ORDER BY without LIMIT on DELETE}}
508a7389f2Sshane  do_test wherelimit-0.3 {
518a7389f2Sshane    catchsql {UPDATE t1 SET y=1 WHERE x=1 ORDER BY x}
528a7389f2Sshane  } {1 {ORDER BY without LIMIT on UPDATE}}
538a7389f2Sshane
548a7389f2Sshane  # no AS on table sources
55a44005afSdan  #
56a44005afSdan  # UPDATE: As of version 3.24, AS clauses are allowed as part of
57a44005afSdan  # UPDATE or DELETE statements.
588a7389f2Sshane  do_test wherelimit-0.4 {
59a44005afSdan    catchsql {DELETE FROM t1 AS a WHERE a.x=1}
60a44005afSdan  } {0 {}}
61a44005afSdan  do_test wherelimit-0.5.1 {
628a7389f2Sshane    catchsql {UPDATE t1 AS a SET y=1 WHERE x=1}
63a44005afSdan  } {0 {}}
64a44005afSdan  do_test wherelimit-0.5.2 {
65a44005afSdan    catchsql {UPDATE t1 AS a SET y=1 WHERE t1.x=1}
66a44005afSdan  } {1 {no such column: t1.x}}
678a7389f2Sshane
6849ffdbf4Sshane  # OFFSET w/o LIMIT
6949ffdbf4Sshane  do_test wherelimit-0.6 {
7049ffdbf4Sshane    catchsql {DELETE FROM t1 WHERE x=1 OFFSET 2}
7149ffdbf4Sshane  } {1 {near "OFFSET": syntax error}}
7249ffdbf4Sshane  do_test wherelimit-0.7 {
7349ffdbf4Sshane    catchsql {UPDATE t1 SET y=1 WHERE x=1 OFFSET 2}
7449ffdbf4Sshane  } {1 {near "OFFSET": syntax error}}
7549ffdbf4Sshane
76a44005afSdan  execsql { DROP TABLE t1 }
7749ffdbf4Sshane
788a7389f2Sshane  # check deletes w/o where clauses but with limit/offsets
798a7389f2Sshane  create_test_data 5
808a7389f2Sshane  do_test wherelimit-1.0 {
818a7389f2Sshane    execsql {SELECT count(*) FROM t1}
828a7389f2Sshane  } {25}
838a7389f2Sshane  do_test wherelimit-1.1 {
848a7389f2Sshane    execsql {DELETE FROM t1}
858a7389f2Sshane    execsql {SELECT count(*) FROM t1}
868a7389f2Sshane  } {0}
878a7389f2Sshane  create_test_data 5
888a7389f2Sshane  do_test wherelimit-1.2 {
898a7389f2Sshane    execsql {DELETE FROM t1 LIMIT 5}
908a7389f2Sshane    execsql {SELECT count(*) FROM t1}
918a7389f2Sshane  } {20}
928a7389f2Sshane  do_test wherelimit-1.3 {
938a7389f2Sshane    # limit 5
948a7389f2Sshane    execsql {DELETE FROM t1 ORDER BY x LIMIT 5}
958a7389f2Sshane    execsql {SELECT count(*) FROM t1}
968a7389f2Sshane  } {15}
97d33d3a2bSdrh  create_test_data 4
98d33d3a2bSdrh  do_test wherelimit-1.3b {
99d33d3a2bSdrh    # limit 5
100d33d3a2bSdrh    execsql {DELETE FROM t1 RETURNING x, y, '|' ORDER BY x, y LIMIT 5}
101d33d3a2bSdrh  } {1 1 | 1 2 | 1 3 | 1 4 | 2 1 |}
102d33d3a2bSdrh  do_test wherelimit-1.3c {
103d33d3a2bSdrh    execsql {SELECT count(*) FROM t1}
104d33d3a2bSdrh  } {11}
1058a7389f2Sshane  do_test wherelimit-1.4 {
1068a7389f2Sshane    # limit 5, offset 2
107d33d3a2bSdrh    execsql {DELETE FROM t1 RETURNING x, y, '|' ORDER BY x  LIMIT 5 OFFSET 2}
108d33d3a2bSdrh  } {2 4 | 3 1 | 3 2 | 3 3 | 3 4 |}
109d33d3a2bSdrh  do_test wherelimit-1.4cnt {
1108a7389f2Sshane    execsql {SELECT count(*) FROM t1}
111d33d3a2bSdrh  } {6}
1128a7389f2Sshane  do_test wherelimit-1.5 {
1138a7389f2Sshane    # limit 5, offset -2
1148a7389f2Sshane    execsql {DELETE FROM t1 ORDER BY x LIMIT 5 OFFSET -2}
1158a7389f2Sshane    execsql {SELECT count(*) FROM t1}
116d33d3a2bSdrh  } {1}
1178a7389f2Sshane  do_test wherelimit-1.6 {
1188a7389f2Sshane    # limit -5 (no limit), offset 2
1198a7389f2Sshane    execsql {DELETE FROM t1 ORDER BY x LIMIT 2, -5}
1208a7389f2Sshane    execsql {SELECT count(*) FROM t1}
121d33d3a2bSdrh  } {1}
1228a7389f2Sshane  do_test wherelimit-1.7 {
1238a7389f2Sshane    # limit 5, offset -2 (no offset)
1248a7389f2Sshane    execsql {DELETE FROM t1 ORDER BY x LIMIT -2, 5}
1258a7389f2Sshane    execsql {SELECT count(*) FROM t1}
1268a7389f2Sshane  } {0}
1278a7389f2Sshane  create_test_data 5
1288a7389f2Sshane  do_test wherelimit-1.8 {
1298a7389f2Sshane    # limit -5 (no limit), offset -2 (no offset)
1308a7389f2Sshane    execsql {DELETE FROM t1 ORDER BY x LIMIT -2, -5}
1318a7389f2Sshane    execsql {SELECT count(*) FROM t1}
1328a7389f2Sshane  } {0}
1338a7389f2Sshane  create_test_data 3
1348a7389f2Sshane  do_test wherelimit-1.9 {
1358a7389f2Sshane    # limit 5, offset 2
1368a7389f2Sshane    execsql {DELETE FROM t1 ORDER BY x LIMIT 2, 5}
1378a7389f2Sshane    execsql {SELECT count(*) FROM t1}
1388a7389f2Sshane  } {4}
1398a7389f2Sshane  do_test wherelimit-1.10 {
1408a7389f2Sshane    # limit 5, offset 5
1418a7389f2Sshane    execsql {DELETE FROM t1 ORDER BY x LIMIT 5 OFFSET 5}
1428a7389f2Sshane    execsql {SELECT count(*) FROM t1}
1438a7389f2Sshane  } {4}
1448a7389f2Sshane  do_test wherelimit-1.11 {
1458a7389f2Sshane    # limit 50, offset 30
1468a7389f2Sshane    execsql {DELETE FROM t1 ORDER BY x LIMIT 50 OFFSET 30}
1478a7389f2Sshane    execsql {SELECT count(*) FROM t1}
1488a7389f2Sshane  } {4}
1498a7389f2Sshane  do_test wherelimit-1.12 {
1508a7389f2Sshane    # limit 50, offset 30
1518a7389f2Sshane    execsql {DELETE FROM t1 ORDER BY x LIMIT 30, 50}
1528a7389f2Sshane    execsql {SELECT count(*) FROM t1}
1538a7389f2Sshane  } {4}
1548a7389f2Sshane  do_test wherelimit-1.13 {
1558a7389f2Sshane    execsql {DELETE FROM t1 ORDER BY x LIMIT 50 OFFSET 50}
1568a7389f2Sshane    execsql {SELECT count(*) FROM t1}
1578a7389f2Sshane  } {4}
1588a7389f2Sshane
1598a7389f2Sshane
1608a7389f2Sshane  create_test_data 6
1618a7389f2Sshane  do_test wherelimit-2.0 {
1628a7389f2Sshane    execsql {SELECT count(*) FROM t1}
1638a7389f2Sshane  } {36}
1648a7389f2Sshane  do_test wherelimit-2.1 {
1658a7389f2Sshane    execsql {DELETE FROM t1 WHERE x=1}
1668a7389f2Sshane    execsql {SELECT count(*) FROM t1}
1678a7389f2Sshane  } {30}
1688a7389f2Sshane  create_test_data 6
1698a7389f2Sshane  do_test wherelimit-2.2 {
1708a7389f2Sshane    execsql {DELETE FROM t1 WHERE x=1 LIMIT 5}
1718a7389f2Sshane    execsql {SELECT count(*) FROM t1}
1728a7389f2Sshane  } {31}
1738a7389f2Sshane  do_test wherelimit-2.3 {
1748a7389f2Sshane    # limit 5
1758a7389f2Sshane    execsql {DELETE FROM t1 WHERE x=1 ORDER BY x LIMIT 5}
1768a7389f2Sshane    execsql {SELECT count(*) FROM t1}
1778a7389f2Sshane  } {30}
1788a7389f2Sshane  do_test wherelimit-2.4 {
1798a7389f2Sshane    # limit 5, offset 2
1808a7389f2Sshane    execsql {DELETE FROM t1 WHERE x=2 ORDER BY x LIMIT 5 OFFSET 2}
1818a7389f2Sshane    execsql {SELECT count(*) FROM t1}
1828a7389f2Sshane  } {26}
1838a7389f2Sshane  do_test wherelimit-2.5 {
1848a7389f2Sshane    # limit 5, offset -2
1858a7389f2Sshane    execsql {DELETE FROM t1 WHERE x=2 ORDER BY x LIMIT 5 OFFSET -2}
1868a7389f2Sshane    execsql {SELECT count(*) FROM t1}
1878a7389f2Sshane  } {24}
1888a7389f2Sshane  do_test wherelimit-2.6 {
1898a7389f2Sshane    # limit -5 (no limit), offset 2
1908a7389f2Sshane    execsql {DELETE FROM t1 WHERE x=3 ORDER BY x LIMIT 2, -5}
1918a7389f2Sshane    execsql {SELECT count(*) FROM t1}
1928a7389f2Sshane  } {20}
1938a7389f2Sshane  do_test wherelimit-2.7 {
1948a7389f2Sshane    # limit 5, offset -2 (no offset)
1958a7389f2Sshane    execsql {DELETE FROM t1 WHERE x=3 ORDER BY x LIMIT -2, 5}
1968a7389f2Sshane    execsql {SELECT count(*) FROM t1}
1978a7389f2Sshane  } {18}
1988a7389f2Sshane  do_test wherelimit-2.8 {
1998a7389f2Sshane    # limit -5 (no limit), offset -2 (no offset)
2008a7389f2Sshane    execsql {DELETE FROM t1 WHERE x=4 ORDER BY x LIMIT -2, -5}
2018a7389f2Sshane    execsql {SELECT count(*) FROM t1}
2028a7389f2Sshane  } {12}
2038a7389f2Sshane  create_test_data 6
2048a7389f2Sshane  do_test wherelimit-2.9 {
2058a7389f2Sshane    # limit 5, offset 2
2068a7389f2Sshane    execsql {DELETE FROM t1 WHERE x=5 ORDER BY x LIMIT 2, 5}
2078a7389f2Sshane    execsql {SELECT count(*) FROM t1}
2088a7389f2Sshane  } {32}
2098a7389f2Sshane  do_test wherelimit-2.10 {
2108a7389f2Sshane    # limit 5, offset 5
2118a7389f2Sshane    execsql {DELETE FROM t1 WHERE x=6 ORDER BY x LIMIT 5 OFFSET 5}
2128a7389f2Sshane    execsql {SELECT count(*) FROM t1}
2138a7389f2Sshane  } {31}
2148a7389f2Sshane  do_test wherelimit-2.11 {
2158a7389f2Sshane    # limit 50, offset 30
2168a7389f2Sshane    execsql {DELETE FROM t1 WHERE x=1 ORDER BY x LIMIT 50 OFFSET 30}
2178a7389f2Sshane    execsql {SELECT count(*) FROM t1}
2188a7389f2Sshane  } {31}
2198a7389f2Sshane  do_test wherelimit-2.12 {
2208a7389f2Sshane    # limit 50, offset 30
2218a7389f2Sshane    execsql {DELETE FROM t1 WHERE x=2 ORDER BY x LIMIT 30, 50}
2228a7389f2Sshane    execsql {SELECT count(*) FROM t1}
2238a7389f2Sshane  } {31}
2248a7389f2Sshane  do_test wherelimit-2.13 {
2258a7389f2Sshane    execsql {DELETE FROM t1 WHERE x=3 ORDER BY x LIMIT 50 OFFSET 50}
2268a7389f2Sshane    execsql {SELECT count(*) FROM t1}
2278a7389f2Sshane  } {31}
2288a7389f2Sshane
2298a7389f2Sshane
2308a7389f2Sshane  create_test_data 6
2318a7389f2Sshane  do_test wherelimit-3.0 {
2328a7389f2Sshane    execsql {SELECT count(*) FROM t1}
2338a7389f2Sshane  } {36}
2348a7389f2Sshane  do_test wherelimit-3.1 {
2358a7389f2Sshane    execsql {UPDATE t1 SET y=1 WHERE x=1}
2368a7389f2Sshane    execsql {SELECT count(*) FROM t1 WHERE y=1}
2378a7389f2Sshane  } {11}
2388a7389f2Sshane  create_test_data 6
2398a7389f2Sshane  do_test wherelimit-3.2 {
240*1408bf17Sdan    execsql {UPDATE t1 SET y=1 WHERE x=1 RETURNING x, y, '|' LIMIT 5}
241*1408bf17Sdan  } {1 1 | 1 1 | 1 1 | 1 1 | 1 1 |}
242d33d3a2bSdrh  do_test wherelimit-3.2cnt {
2438a7389f2Sshane    execsql {SELECT count(*) FROM t1 WHERE y=1}
2448a7389f2Sshane  } {10}
2458a7389f2Sshane  do_test wherelimit-3.3 {
2468a7389f2Sshane    # limit 5
2478a7389f2Sshane    execsql {UPDATE t1 SET y=2 WHERE x=2 ORDER BY x LIMIT 5}
2488a7389f2Sshane    execsql {SELECT count(*) FROM t1 WHERE y=2}
2498a7389f2Sshane  } {9}
2508a7389f2Sshane  create_test_data 6
2518a7389f2Sshane  do_test wherelimit-3.4 {
2528a7389f2Sshane    # limit 5, offset 2
2538a7389f2Sshane    execsql {UPDATE t1 SET y=2 WHERE x=2 ORDER BY x LIMIT 5 OFFSET 2}
2548a7389f2Sshane    execsql {SELECT count(*) FROM t1 WHERE y=1}
2558a7389f2Sshane  } {6}
2568a7389f2Sshane  do_test wherelimit-3.5 {
2578a7389f2Sshane    # limit 5, offset -2
2588a7389f2Sshane    execsql {UPDATE t1 SET y=2 WHERE x=2 ORDER BY x LIMIT 5 OFFSET -2}
2598a7389f2Sshane    execsql {SELECT count(*) FROM t1 WHERE y=1}
2608a7389f2Sshane  } {5}
2618a7389f2Sshane  do_test wherelimit-3.6 {
2628a7389f2Sshane    # limit -5 (no limit), offset 2
2638a7389f2Sshane    execsql {UPDATE t1 SET y=3 WHERE x=3 ORDER BY x LIMIT 2, -5}
2648a7389f2Sshane    execsql {SELECT count(*) FROM t1 WHERE y=3}
2658a7389f2Sshane  } {8}
2668a7389f2Sshane  do_test wherelimit-3.7 {
2678a7389f2Sshane    # limit 5, offset -2 (no offset)
2688a7389f2Sshane    execsql {UPDATE t1 SET y=3 WHERE x=3 ORDER BY x LIMIT -2, 5}
2698a7389f2Sshane    execsql {SELECT count(*) FROM t1 WHERE y=3}
2708a7389f2Sshane  } {10}
2718a7389f2Sshane
2728a7389f2Sshane  do_test wherelimit-3.8 {
2738a7389f2Sshane    # limit -5 (no limit), offset -2 (no offset)
2748a7389f2Sshane    execsql {UPDATE t1 SET y=4 WHERE x=4 ORDER BY x LIMIT -2, -5}
2758a7389f2Sshane    execsql {SELECT count(*) FROM t1 WHERE y=4}
2768a7389f2Sshane  } {9}
2778a7389f2Sshane  create_test_data 6
2788a7389f2Sshane  do_test wherelimit-3.9 {
2798a7389f2Sshane    # limit 5, offset 2
2808a7389f2Sshane    execsql {UPDATE t1 SET y=4 WHERE x=5 ORDER BY x LIMIT 2, 5}
2818a7389f2Sshane    execsql {SELECT count(*) FROM t1 WHERE y=4}
2828a7389f2Sshane  } {9}
2838a7389f2Sshane  do_test wherelimit-3.10 {
2848a7389f2Sshane    # limit 5, offset 5
2858a7389f2Sshane    execsql {UPDATE t1 SET y=4 WHERE x=6 ORDER BY x LIMIT 5 OFFSET 5}
2868a7389f2Sshane    execsql {SELECT count(*) FROM t1 WHERE y=1}
2878a7389f2Sshane  } {6}
2888a7389f2Sshane  do_test wherelimit-3.11 {
2898a7389f2Sshane    # limit 50, offset 30
2908a7389f2Sshane    execsql {UPDATE t1 SET y=1 WHERE x=1 ORDER BY x LIMIT 50 OFFSET 30}
2918a7389f2Sshane    execsql {SELECT count(*) FROM t1 WHERE y=1}
2928a7389f2Sshane  } {6}
2938a7389f2Sshane  do_test wherelimit-3.12 {
2948a7389f2Sshane    # limit 50, offset 30
2958a7389f2Sshane    execsql {UPDATE t1 SET y=1 WHERE x=2 ORDER BY x LIMIT 30, 50}
2968a7389f2Sshane    execsql {SELECT count(*) FROM t1 WHERE y=1}
2978a7389f2Sshane  } {6}
2988a7389f2Sshane  do_test wherelimit-3.13 {
2998a7389f2Sshane    execsql {UPDATE t1 SET y=1 WHERE x=3 ORDER BY x LIMIT 50 OFFSET 50}
3008a7389f2Sshane    execsql {SELECT count(*) FROM t1 WHERE y=1}
3018a7389f2Sshane  } {6}
3028a7389f2Sshane
3032fba394cSdrh  # Cannot use a LIMIT for UPDATE or DELETE against a WITHOUT ROWID table
3042fba394cSdrh  # or a VIEW.  (We should fix this someday).
3052fba394cSdrh  #
3062fba394cSdrh  db close
3072fba394cSdrh  sqlite3 db :memory:
3082fba394cSdrh  do_execsql_test wherelimit-4.1 {
3092fba394cSdrh    CREATE TABLE t1(a int);
3102fba394cSdrh    INSERT INTO t1 VALUES(1);
3112fba394cSdrh    INSERT INTO t1 VALUES(2);
3122fba394cSdrh    INSERT INTO t1 VALUES(3);
3132fba394cSdrh    CREATE TABLE t2(a int);
3142fba394cSdrh    INSERT INTO t2 SELECT a+100 FROM t1;
3152fba394cSdrh    CREATE VIEW tv(r,a) AS
3162fba394cSdrh       SELECT rowid, a FROM t2 UNION ALL SELECT rowid, a FROM t1;
3172fba394cSdrh    CREATE TRIGGER tv_del INSTEAD OF DELETE ON tv
3182fba394cSdrh    BEGIN
3192fba394cSdrh      DELETE FROM t1 WHERE rowid=old.r;
3202fba394cSdrh      DELETE FROM t2 WHERE rowid=old.r;
3212fba394cSdrh    END;
3222fba394cSdrh  } {}
3232fba394cSdrh  do_catchsql_test wherelimit-4.2 {
3242fba394cSdrh    DELETE FROM tv WHERE 1 LIMIT 2;
325b3c16b89Sdan  } {0 {}}
3262fba394cSdrh  do_catchsql_test wherelimit-4.3 {
3272fba394cSdrh    DELETE FROM tv WHERE 1 ORDER BY a LIMIT 2;
328b3c16b89Sdan  } {0 {}}
3292fba394cSdrh  do_execsql_test wherelimit-4.10 {
3302fba394cSdrh    CREATE TABLE t3(a,b,c,d TEXT, PRIMARY KEY(a,b)) WITHOUT ROWID;
3312fba394cSdrh    INSERT INTO t3(a,b,c,d) VALUES(1,2,3,4),(5,6,7,8),(9,10,11,12);
3322fba394cSdrh  } {}
3332fba394cSdrh  do_catchsql_test wherelimit-4.11 {
3342fba394cSdrh    DELETE FROM t3 WHERE a=5 LIMIT 2;
335b3c16b89Sdan  } {0 {}}
3362fba394cSdrh  do_execsql_test wherelimit-4.12 {
3372fba394cSdrh    SELECT a,b,c,d FROM t3 ORDER BY 1;
338b3c16b89Sdan  } {1 2 3 4 9 10 11 12}
3392fba394cSdrh
3408a7389f2Sshane}
3418a7389f2Sshane
3428a7389f2Sshanefinish_test
343