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