000001 # 2010 September 20 000002 # 000003 # The author disclaims copyright to this source code. In place of 000004 # a legal notice, here is a blessing: 000005 # 000006 # May you do good and not evil. 000007 # May you find forgiveness for yourself and forgive others. 000008 # May you share freely, never taking more than you give. 000009 # 000010 #*********************************************************************** 000011 # 000012 # This file implements tests to verify that the "testable statements" in 000013 # the lang_update.html document are correct. 000014 # 000015 set testdir [file dirname $argv0] 000016 source $testdir/tester.tcl 000017 000018 #-------------------- 000019 # Test organization: 000020 # 000021 # e_update-1.*: Test statements describing the workings of UPDATE statements. 000022 # 000023 # e_update-2.*: Test the restrictions on the UPDATE statement syntax that 000024 # can be used within triggers. 000025 # 000026 # e_update-3.*: Test the special LIMIT/OFFSET and ORDER BY clauses that can 000027 # be used with UPDATE when SQLite is compiled with 000028 # SQLITE_ENABLE_UPDATE_DELETE_LIMIT. 000029 # 000030 000031 forcedelete test.db2 000032 000033 do_execsql_test e_update-0.0 { 000034 ATTACH 'test.db2' AS aux; 000035 CREATE TABLE t1(a, b); 000036 CREATE TABLE t2(a, b, c); 000037 CREATE TABLE t3(a, b UNIQUE); 000038 CREATE TABLE t6(x, y); 000039 CREATE INDEX i1 ON t1(a); 000040 000041 CREATE TEMP TABLE t4(x, y); 000042 CREATE TEMP TABLE t6(x, y); 000043 000044 CREATE TABLE aux.t1(a, b); 000045 CREATE TABLE aux.t5(a, b); 000046 } {} 000047 000048 proc do_update_tests {args} { 000049 uplevel do_select_tests $args 000050 } 000051 000052 # -- syntax diagram update-stmt 000053 # 000054 do_update_tests e_update-0 { 000055 1 "UPDATE t1 SET a=10" {} 000056 2 "UPDATE t1 SET a=10, b=5" {} 000057 3 "UPDATE t1 SET a=10 WHERE b=5" {} 000058 4 "UPDATE t1 SET b=5,a=10 WHERE 1" {} 000059 5 "UPDATE main.t1 SET a=10" {} 000060 6 "UPDATE main.t1 SET a=10, b=5" {} 000061 7 "UPDATE main.t1 SET a=10 WHERE b=5" {} 000062 9 "UPDATE OR ROLLBACK t1 SET a=10" {} 000063 10 "UPDATE OR ROLLBACK t1 SET a=10, b=5" {} 000064 11 "UPDATE OR ROLLBACK t1 SET a=10 WHERE b=5" {} 000065 12 "UPDATE OR ROLLBACK t1 SET b=5,a=10 WHERE 1" {} 000066 13 "UPDATE OR ROLLBACK main.t1 SET a=10" {} 000067 14 "UPDATE OR ROLLBACK main.t1 SET a=10, b=5" {} 000068 15 "UPDATE OR ROLLBACK main.t1 SET a=10 WHERE b=5" {} 000069 16 "UPDATE OR ROLLBACK main.t1 SET b=5,a=10 WHERE 1" {} 000070 17 "UPDATE OR ABORT t1 SET a=10" {} 000071 18 "UPDATE OR ABORT t1 SET a=10, b=5" {} 000072 19 "UPDATE OR ABORT t1 SET a=10 WHERE b=5" {} 000073 20 "UPDATE OR ABORT t1 SET b=5,a=10 WHERE 1" {} 000074 21 "UPDATE OR ABORT main.t1 SET a=10" {} 000075 22 "UPDATE OR ABORT main.t1 SET a=10, b=5" {} 000076 23 "UPDATE OR ABORT main.t1 SET a=10 WHERE b=5" {} 000077 24 "UPDATE OR ABORT main.t1 SET b=5,a=10 WHERE 1" {} 000078 25 "UPDATE OR REPLACE t1 SET a=10" {} 000079 26 "UPDATE OR REPLACE t1 SET a=10, b=5" {} 000080 27 "UPDATE OR REPLACE t1 SET a=10 WHERE b=5" {} 000081 28 "UPDATE OR REPLACE t1 SET b=5,a=10 WHERE 1" {} 000082 29 "UPDATE OR REPLACE main.t1 SET a=10" {} 000083 30 "UPDATE OR REPLACE main.t1 SET a=10, b=5" {} 000084 31 "UPDATE OR REPLACE main.t1 SET a=10 WHERE b=5" {} 000085 32 "UPDATE OR REPLACE main.t1 SET b=5,a=10 WHERE 1" {} 000086 33 "UPDATE OR FAIL t1 SET a=10" {} 000087 34 "UPDATE OR FAIL t1 SET a=10, b=5" {} 000088 35 "UPDATE OR FAIL t1 SET a=10 WHERE b=5" {} 000089 36 "UPDATE OR FAIL t1 SET b=5,a=10 WHERE 1" {} 000090 37 "UPDATE OR FAIL main.t1 SET a=10" {} 000091 38 "UPDATE OR FAIL main.t1 SET a=10, b=5" {} 000092 39 "UPDATE OR FAIL main.t1 SET a=10 WHERE b=5" {} 000093 40 "UPDATE OR FAIL main.t1 SET b=5,a=10 WHERE 1" {} 000094 41 "UPDATE OR IGNORE t1 SET a=10" {} 000095 42 "UPDATE OR IGNORE t1 SET a=10, b=5" {} 000096 43 "UPDATE OR IGNORE t1 SET a=10 WHERE b=5" {} 000097 44 "UPDATE OR IGNORE t1 SET b=5,a=10 WHERE 1" {} 000098 45 "UPDATE OR IGNORE main.t1 SET a=10" {} 000099 46 "UPDATE OR IGNORE main.t1 SET a=10, b=5" {} 000100 47 "UPDATE OR IGNORE main.t1 SET a=10 WHERE b=5" {} 000101 48 "UPDATE OR IGNORE main.t1 SET b=5,a=10 WHERE 1" {} 000102 } 000103 000104 # EVIDENCE-OF: R-38515-45264 An UPDATE statement is used to modify a 000105 # subset of the values stored in zero or more rows of the database table 000106 # identified by the qualified-table-name specified as part of the UPDATE 000107 # statement. 000108 # 000109 # Test cases e_update-1.1.1.* test the "identified by the 000110 # qualified-table-name" part of the statement above. Tests 000111 # e_update-1.1.2.* show that the "zero or more rows" part is 000112 # accurate. 000113 # 000114 do_execsql_test e_update-1.1.0 { 000115 INSERT INTO main.t1 VALUES(1, 'i'); 000116 INSERT INTO main.t1 VALUES(2, 'ii'); 000117 INSERT INTO main.t1 VALUES(3, 'iii'); 000118 000119 INSERT INTO aux.t1 VALUES(1, 'I'); 000120 INSERT INTO aux.t1 VALUES(2, 'II'); 000121 INSERT INTO aux.t1 VALUES(3, 'III'); 000122 } {} 000123 do_update_tests e_update-1.1 { 000124 1.1 "UPDATE t1 SET a = a+1; SELECT * FROM t1" {2 i 3 ii 4 iii} 000125 1.2 "UPDATE main.t1 SET a = a+1; SELECT * FROM main.t1" {3 i 4 ii 5 iii} 000126 1.3 "UPDATE aux.t1 SET a = a+1; SELECT * FROM aux.t1" {2 I 3 II 4 III} 000127 000128 2.1 "UPDATE t1 SET a = a+1 WHERE a = 1; SELECT * FROM t1" {3 i 4 ii 5 iii} 000129 2.2 "UPDATE t1 SET a = a+1 WHERE a = 4; SELECT * FROM t1" {3 i 5 ii 5 iii} 000130 } 000131 000132 # EVIDENCE-OF: R-55869-30521 If the UPDATE statement does not have a 000133 # WHERE clause, all rows in the table are modified by the UPDATE. 000134 # 000135 do_execsql_test e_update-1.2.0 { 000136 DELETE FROM main.t1; 000137 INSERT INTO main.t1 VALUES(1, 'i'); 000138 INSERT INTO main.t1 VALUES(2, 'ii'); 000139 INSERT INTO main.t1 VALUES(3, 'iii'); 000140 } {} 000141 do_update_tests e_update-1.2 { 000142 1 "UPDATE t1 SET b = 'roman' ; SELECT * FROM t1" 000143 {1 roman 2 roman 3 roman} 000144 000145 2 "UPDATE t1 SET a = 'greek' ; SELECT * FROM t1" 000146 {greek roman greek roman greek roman} 000147 } 000148 000149 # EVIDENCE-OF: R-58095-46013 Otherwise, the UPDATE affects only those 000150 # rows for which the WHERE clause boolean expression is true. 000151 # 000152 do_execsql_test e_update-1.3.0 { 000153 DELETE FROM main.t1; 000154 INSERT INTO main.t1 VALUES(NULL, ''); 000155 INSERT INTO main.t1 VALUES(1, 'i'); 000156 INSERT INTO main.t1 VALUES(2, 'ii'); 000157 INSERT INTO main.t1 VALUES(3, 'iii'); 000158 } {} 000159 do_update_tests e_update-1.3 { 000160 1 "UPDATE t1 SET b = 'roman' WHERE a<2 ; SELECT * FROM t1" 000161 {{} {} 1 roman 2 ii 3 iii} 000162 000163 2 "UPDATE t1 SET b = 'egyptian' WHERE (a-3)/10.0 ; SELECT * FROM t1" 000164 {{} {} 1 egyptian 2 egyptian 3 iii} 000165 000166 3 "UPDATE t1 SET b = 'macedonian' WHERE a; SELECT * FROM t1" 000167 {{} {} 1 macedonian 2 macedonian 3 macedonian} 000168 000169 4 "UPDATE t1 SET b = 'lithuanian' WHERE a IS NULL; SELECT * FROM t1" 000170 {{} lithuanian 1 macedonian 2 macedonian 3 macedonian} 000171 } 000172 000173 # EVIDENCE-OF: R-58129-20729 It is not an error if the WHERE clause does 000174 # not evaluate to true for any row in the table - this just means that 000175 # the UPDATE statement affects zero rows. 000176 # 000177 do_execsql_test e_update-1.4.0 { 000178 DELETE FROM main.t1; 000179 INSERT INTO main.t1 VALUES(NULL, ''); 000180 INSERT INTO main.t1 VALUES(1, 'i'); 000181 INSERT INTO main.t1 VALUES(2, 'ii'); 000182 INSERT INTO main.t1 VALUES(3, 'iii'); 000183 } {} 000184 do_update_tests e_update-1.4 -query { 000185 SELECT * FROM t1 000186 } { 000187 1 "UPDATE t1 SET b = 'burmese' WHERE a=5" {{} {} 1 i 2 ii 3 iii} 000188 000189 2 "UPDATE t1 SET b = 'burmese' WHERE length(b)<1 AND a IS NOT NULL" 000190 {{} {} 1 i 2 ii 3 iii} 000191 000192 3 "UPDATE t1 SET b = 'burmese' WHERE 0" {{} {} 1 i 2 ii 3 iii} 000193 000194 4 "UPDATE t1 SET b = 'burmese' WHERE (SELECT a FROM t1 WHERE rowid=1)" 000195 {{} {} 1 i 2 ii 3 iii} 000196 } 000197 000198 # EVIDENCE-OF: R-40598-36595 For each affected row, the named columns 000199 # are set to the values found by evaluating the corresponding scalar 000200 # expressions. 000201 # 000202 # EVIDENCE-OF: R-40472-60438 Columns that do not appear in the list of 000203 # assignments are left unmodified. 000204 # 000205 do_execsql_test e_update-1.5.0 { 000206 INSERT INTO t2(rowid, a, b, c) VALUES(1, 3, 1, 4); 000207 INSERT INTO t2(rowid, a, b, c) VALUES(2, 1, 5, 9); 000208 INSERT INTO t2(rowid, a, b, c) VALUES(3, 2, 6, 5); 000209 } {} 000210 do_update_tests e_update-1.5 -query { 000211 SELECT * FROM t2 000212 } { 000213 1 "UPDATE t2 SET c = 1+1 WHERE a=2" 000214 {3 1 4 1 5 9 2 6 2} 000215 000216 2 "UPDATE t2 SET b = 4/2, c=CAST((0.4*5) AS INTEGER) WHERE a<3" 000217 {3 1 4 1 2 2 2 2 2} 000218 000219 3 "UPDATE t2 SET a = 1" 000220 {1 1 4 1 2 2 1 2 2} 000221 000222 4 "UPDATE t2 SET b = (SELECT count(*)+2 FROM t2), c = 24/3+1 WHERE rowid=2" 000223 {1 1 4 1 5 9 1 2 2} 000224 000225 5 "UPDATE t2 SET a = 3 WHERE c = 4" 000226 {3 1 4 1 5 9 1 2 2} 000227 000228 6 "UPDATE t2 SET a = b WHERE rowid>2" 000229 {3 1 4 1 5 9 2 2 2} 000230 000231 6 "UPDATE t2 SET b=6, c=5 WHERE a=b AND b=c" 000232 {3 1 4 1 5 9 2 6 5} 000233 } 000234 000235 # EVIDENCE-OF: R-34751-18293 If a single column-name appears more than 000236 # once in the list of assignment expressions, all but the rightmost 000237 # occurrence is ignored. 000238 # 000239 do_update_tests e_update-1.6 -query { 000240 SELECT * FROM t2 000241 } { 000242 1 "UPDATE t2 SET c=5, c=6, c=7 WHERE rowid=1" {3 1 7 1 5 9 2 6 5} 000243 2 "UPDATE t2 SET c=7, c=6, c=5 WHERE rowid=1" {3 1 5 1 5 9 2 6 5} 000244 3 "UPDATE t2 SET c=5, b=6, c=7 WHERE rowid=1" {3 6 7 1 5 9 2 6 5} 000245 } 000246 000247 # EVIDENCE-OF: R-36239-04077 The scalar expressions may refer to columns 000248 # of the row being updated. 000249 # 000250 # EVIDENCE-OF: R-04558-24451 In this case all scalar expressions are 000251 # evaluated before any assignments are made. 000252 # 000253 do_execsql_test e_update-1.7.0 { 000254 DELETE FROM t2; 000255 INSERT INTO t2(rowid, a, b, c) VALUES(1, 3, 1, 4); 000256 INSERT INTO t2(rowid, a, b, c) VALUES(2, 1, 5, 9); 000257 INSERT INTO t2(rowid, a, b, c) VALUES(3, 2, 6, 5); 000258 } {} 000259 do_update_tests e_update-1.7 -query { 000260 SELECT * FROM t2 000261 } { 000262 1 "UPDATE t2 SET a=b+c" {5 1 4 14 5 9 11 6 5} 000263 2 "UPDATE t2 SET a=b, b=a" {1 5 4 5 14 9 6 11 5} 000264 3 "UPDATE t2 SET a=c||c, c=NULL" {44 5 {} 99 14 {} 55 11 {}} 000265 } 000266 000267 # EVIDENCE-OF: R-28518-13457 The optional "OR action" conflict clause 000268 # that follows the UPDATE keyword allows the user to nominate a specific 000269 # constraint conflict resolution algorithm to use during this one UPDATE 000270 # command. 000271 # 000272 do_execsql_test e_update-1.8.0 { 000273 DELETE FROM t3; 000274 INSERT INTO t3 VALUES(1, 'one'); 000275 INSERT INTO t3 VALUES(2, 'two'); 000276 INSERT INTO t3 VALUES(3, 'three'); 000277 INSERT INTO t3 VALUES(4, 'four'); 000278 } {} 000279 foreach {tn sql error ac data } { 000280 1 "UPDATE t3 SET b='one' WHERE a=3" 000281 {UNIQUE constraint failed: t3.b} 1 {1 one 2 two 3 three 4 four} 000282 000283 2 "UPDATE OR REPLACE t3 SET b='one' WHERE a=3" 000284 {} 1 {2 two 3 one 4 four} 000285 000286 3 "UPDATE OR FAIL t3 SET b='three'" 000287 {UNIQUE constraint failed: t3.b} 1 {2 three 3 one 4 four} 000288 000289 4 "UPDATE OR IGNORE t3 SET b='three' WHERE a=3" 000290 {} 1 {2 three 3 one 4 four} 000291 000292 5 "UPDATE OR ABORT t3 SET b='three' WHERE a=3" 000293 {UNIQUE constraint failed: t3.b} 1 {2 three 3 one 4 four} 000294 000295 6 "BEGIN" {} 0 {2 three 3 one 4 four} 000296 000297 7 "UPDATE t3 SET b='three' WHERE a=3" 000298 {UNIQUE constraint failed: t3.b} 0 {2 three 3 one 4 four} 000299 000300 8 "UPDATE OR ABORT t3 SET b='three' WHERE a=3" 000301 {UNIQUE constraint failed: t3.b} 0 {2 three 3 one 4 four} 000302 000303 9 "UPDATE OR FAIL t3 SET b='two'" 000304 {UNIQUE constraint failed: t3.b} 0 {2 two 3 one 4 four} 000305 000306 10 "UPDATE OR IGNORE t3 SET b='four' WHERE a=3" 000307 {} 0 {2 two 3 one 4 four} 000308 000309 11 "UPDATE OR REPLACE t3 SET b='four' WHERE a=3" 000310 {} 0 {2 two 3 four} 000311 000312 12 "UPDATE OR ROLLBACK t3 SET b='four'" 000313 {UNIQUE constraint failed: t3.b} 1 {2 three 3 one 4 four} 000314 } { 000315 do_catchsql_test e_update-1.8.$tn.1 $sql [list [expr {$error!=""}] $error] 000316 do_execsql_test e_update-1.8.$tn.2 {SELECT * FROM t3} [list {*}$data] 000317 do_test e_update-1.8.$tn.3 {sqlite3_get_autocommit db} $ac 000318 } 000319 000320 000321 000322 # EVIDENCE-OF: R-12123-54095 The table-name specified as part of an 000323 # UPDATE statement within a trigger body must be unqualified. 000324 # 000325 # EVIDENCE-OF: R-43190-62442 In other words, the schema-name. prefix on 000326 # the table name of the UPDATE is not allowed within triggers. 000327 # 000328 do_update_tests e_update-2.1 -error { 000329 qualified table names are not allowed on INSERT, UPDATE, and DELETE statements within triggers 000330 } { 000331 1 { 000332 CREATE TRIGGER tr1 AFTER INSERT ON t1 BEGIN 000333 UPDATE main.t2 SET a=1, b=2, c=3; 000334 END; 000335 } {} 000336 000337 2 { 000338 CREATE TRIGGER tr1 BEFORE UPDATE ON t2 BEGIN 000339 UPDATE aux.t1 SET a=1, b=2; 000340 END; 000341 } {} 000342 000343 3 { 000344 CREATE TRIGGER tr1 AFTER DELETE ON t4 BEGIN 000345 UPDATE main.t1 SET a=1, b=2; 000346 END; 000347 } {} 000348 } 000349 000350 # EVIDENCE-OF: R-06085-13761 Unless the table to which the trigger is 000351 # attached is in the TEMP database, the table being updated by the 000352 # trigger program must reside in the same database as it. 000353 # 000354 do_update_tests e_update-2.2 -error { 000355 no such table: %s 000356 } { 000357 1 { 000358 CREATE TRIGGER tr1 AFTER INSERT ON t1 BEGIN 000359 UPDATE t4 SET x=x+1; 000360 END; 000361 INSERT INTO t1 VALUES(1, 2); 000362 } "main.t4" 000363 000364 2 { 000365 CREATE TRIGGER aux.tr1 AFTER INSERT ON t5 BEGIN 000366 UPDATE t4 SET x=x+1; 000367 END; 000368 INSERT INTO t5 VALUES(1, 2); 000369 } "aux.t4" 000370 } 000371 do_execsql_test e_update-2.2.X { 000372 DROP TRIGGER tr1; 000373 DROP TRIGGER aux.tr1; 000374 } {} 000375 000376 # EVIDENCE-OF: R-29512-54644 If the table to which the trigger is 000377 # attached is in the TEMP database, then the unqualified name of the 000378 # table being updated is resolved in the same way as it is for a 000379 # top-level statement (by searching first the TEMP database, then the 000380 # main database, then any other databases in the order they were 000381 # attached). 000382 # 000383 do_execsql_test e_update-2.3.0 { 000384 SELECT 'main', tbl_name FROM main.sqlite_master WHERE type = 'table'; 000385 SELECT 'temp', tbl_name FROM sqlite_temp_master WHERE type = 'table'; 000386 SELECT 'aux', tbl_name FROM aux.sqlite_master WHERE type = 'table'; 000387 } [list {*}{ 000388 main t1 000389 main t2 000390 main t3 000391 main t6 000392 temp t4 000393 temp t6 000394 aux t1 000395 aux t5 000396 }] 000397 do_execsql_test e_update-2.3.1 { 000398 DELETE FROM main.t6; 000399 DELETE FROM temp.t6; 000400 INSERT INTO main.t6 VALUES(1, 2); 000401 INSERT INTO temp.t6 VALUES(1, 2); 000402 000403 CREATE TRIGGER temp.tr1 AFTER INSERT ON t4 BEGIN 000404 UPDATE t6 SET x=x+1; 000405 END; 000406 000407 INSERT INTO t4 VALUES(1, 2); 000408 SELECT * FROM main.t6; 000409 SELECT * FROM temp.t6; 000410 } {1 2 2 2} 000411 do_execsql_test e_update-2.3.2 { 000412 DELETE FROM main.t1; 000413 DELETE FROM aux.t1; 000414 INSERT INTO main.t1 VALUES(1, 2); 000415 INSERT INTO aux.t1 VALUES(1, 2); 000416 000417 CREATE TRIGGER temp.tr2 AFTER DELETE ON t4 BEGIN 000418 UPDATE t1 SET a=a+1; 000419 END; 000420 000421 DELETE FROM t4; 000422 SELECT * FROM main.t1; 000423 SELECT * FROM aux.t1; 000424 } {2 2 1 2} 000425 do_execsql_test e_update-2.3.3 { 000426 DELETE FROM aux.t5; 000427 INSERT INTO aux.t5 VALUES(1, 2); 000428 000429 INSERT INTO t4 VALUES('x', 'y'); 000430 CREATE TRIGGER temp.tr3 AFTER UPDATE ON t4 BEGIN 000431 UPDATE t5 SET a=a+1; 000432 END; 000433 000434 UPDATE t4 SET x=10; 000435 SELECT * FROM aux.t5; 000436 } {2 2} 000437 000438 # EVIDENCE-OF: R-19619-42762 The INDEXED BY and NOT INDEXED clauses are 000439 # not allowed on UPDATE statements within triggers. 000440 # 000441 do_update_tests e_update-2.4 -error { 000442 the %s %s clause is not allowed on UPDATE or DELETE statements within triggers 000443 } { 000444 1 { 000445 CREATE TRIGGER tr1 AFTER INSERT ON t2 BEGIN 000446 UPDATE t1 INDEXED BY i1 SET a=a+1; 000447 END; 000448 } {INDEXED BY} 000449 000450 2 { 000451 CREATE TRIGGER tr1 AFTER INSERT ON t2 BEGIN 000452 UPDATE t1 NOT INDEXED SET a=a+1; 000453 END; 000454 } {NOT INDEXED} 000455 } 000456 000457 ifcapable update_delete_limit { 000458 000459 # EVIDENCE-OF: R-57359-59558 The LIMIT and ORDER BY clauses for UPDATE 000460 # are unsupported within triggers, regardless of the compilation options 000461 # used to build SQLite. 000462 # 000463 do_update_tests e_update-2.5 -error { 000464 near "%s": syntax error 000465 } { 000466 1 { 000467 CREATE TRIGGER tr1 AFTER INSERT ON t2 BEGIN 000468 UPDATE t1 SET a=a+1 LIMIT 10; 000469 END; 000470 } {LIMIT} 000471 000472 2 { 000473 CREATE TRIGGER tr1 AFTER INSERT ON t2 BEGIN 000474 UPDATE t1 SET a=a+1 ORDER BY a LIMIT 10; 000475 END; 000476 } {ORDER} 000477 000478 3 { 000479 CREATE TRIGGER tr1 AFTER INSERT ON t2 BEGIN 000480 UPDATE t1 SET a=a+1 ORDER BY a LIMIT 10 OFFSET 2; 000481 END; 000482 } {ORDER} 000483 000484 4 { 000485 CREATE TRIGGER tr1 AFTER INSERT ON t2 BEGIN 000486 UPDATE t1 SET a=a+1 LIMIT 10 OFFSET 2; 000487 END; 000488 } {LIMIT} 000489 } 000490 000491 # EVIDENCE-OF: R-59581-44104 If SQLite is built with the 000492 # SQLITE_ENABLE_UPDATE_DELETE_LIMIT compile-time option then the syntax 000493 # of the UPDATE statement is extended with optional ORDER BY and LIMIT 000494 # clauses 000495 # 000496 # -- syntax diagram update-stmt-limited 000497 # 000498 do_update_tests e_update-3.0 { 000499 1 "UPDATE t1 SET a=b LIMIT 5" {} 000500 2 "UPDATE t1 SET a=b LIMIT 5-1 OFFSET 2+2" {} 000501 3 "UPDATE t1 SET a=b LIMIT 2+2, 16/4" {} 000502 4 "UPDATE t1 SET a=b ORDER BY a LIMIT 5" {} 000503 5 "UPDATE t1 SET a=b ORDER BY a LIMIT 5-1 OFFSET 2+2" {} 000504 6 "UPDATE t1 SET a=b ORDER BY a LIMIT 2+2, 16/4" {} 000505 7 "UPDATE t1 SET a=b WHERE a>2 LIMIT 5" {} 000506 8 "UPDATE t1 SET a=b WHERE a>2 LIMIT 5-1 OFFSET 2+2" {} 000507 9 "UPDATE t1 SET a=b WHERE a>2 LIMIT 2+2, 16/4" {} 000508 10 "UPDATE t1 SET a=b WHERE a>2 ORDER BY a LIMIT 5" {} 000509 11 "UPDATE t1 SET a=b WHERE a>2 ORDER BY a LIMIT 5-1 OFFSET 2+2" {} 000510 12 "UPDATE t1 SET a=b WHERE a>2 ORDER BY a LIMIT 2+2, 16/4" {} 000511 } 000512 000513 do_execsql_test e_update-3.1.0 { 000514 CREATE TABLE t7(q, r, s); 000515 INSERT INTO t7 VALUES(1, 'one', 'X'); 000516 INSERT INTO t7 VALUES(2, 'two', 'X'); 000517 INSERT INTO t7 VALUES(3, 'three', 'X'); 000518 INSERT INTO t7 VALUES(4, 'four', 'X'); 000519 INSERT INTO t7 VALUES(5, 'five', 'X'); 000520 INSERT INTO t7 VALUES(6, 'six', 'X'); 000521 INSERT INTO t7 VALUES(7, 'seven', 'X'); 000522 INSERT INTO t7 VALUES(8, 'eight', 'X'); 000523 INSERT INTO t7 VALUES(9, 'nine', 'X'); 000524 INSERT INTO t7 VALUES(10, 'ten', 'X'); 000525 } {} 000526 000527 # EVIDENCE-OF: R-58862-44169 If an UPDATE statement has a LIMIT clause, 000528 # the maximum number of rows that will be updated is found by evaluating 000529 # the accompanying expression and casting it to an integer value. 000530 # 000531 do_update_tests e_update-3.1 -query { SELECT s FROM t7 } { 000532 1 "UPDATE t7 SET s = q LIMIT 5" {1 2 3 4 5 X X X X X} 000533 2 "UPDATE t7 SET s = r WHERE q>2 LIMIT 4" {1 2 three four five six X X X X} 000534 3 "UPDATE t7 SET s = q LIMIT 0" {1 2 three four five six X X X X} 000535 } 000536 000537 # EVIDENCE-OF: R-63582-45120 A negative value is interpreted as "no limit". 000538 # 000539 do_update_tests e_update-3.2 -query { SELECT s FROM t7 } { 000540 1 "UPDATE t7 SET s = q LIMIT -1" {1 2 3 4 5 6 7 8 9 10} 000541 2 "UPDATE t7 SET s = r WHERE q>4 LIMIT -1" 000542 {1 2 3 4 five six seven eight nine ten} 000543 3 "UPDATE t7 SET s = 'X' LIMIT -1" {X X X X X X X X X X} 000544 } 000545 000546 # EVIDENCE-OF: R-18628-11938 If the LIMIT expression evaluates to 000547 # non-negative value N and the UPDATE statement has an ORDER BY clause, 000548 # then all rows that would be updated in the absence of the LIMIT clause 000549 # are sorted according to the ORDER BY and the first N updated. 000550 # 000551 do_update_tests e_update-3.3 -query { SELECT s FROM t7 } { 000552 1 "UPDATE t7 SET s = q ORDER BY r LIMIT 3" {X X X 4 5 X X 8 X X} 000553 2 "UPDATE t7 SET s = r ORDER BY r DESC LIMIT 2" {X two three 4 5 X X 8 X X} 000554 3 "UPDATE t7 SET s = q ORDER BY q DESC LIMIT 5" {X two three 4 5 6 7 8 9 10} 000555 000556 X "UPDATE t7 SET s = 'X'" {X X X X X X X X X X} 000557 } 000558 000559 # EVIDENCE-OF: R-30955-38324 If the UPDATE statement also has an OFFSET 000560 # clause, then it is similarly evaluated and cast to an integer value. 000561 # If the OFFSET expression evaluates to a non-negative value M, then the 000562 # first M rows are skipped and the following N rows updated instead. 000563 # 000564 do_update_tests e_update-3.3 -query { SELECT s FROM t7 } { 000565 1 "UPDATE t7 SET s = q ORDER BY q LIMIT 3 OFFSET 2" {X X 3 4 5 X X X X X} 000566 2 "UPDATE t7 SET s = q ORDER BY q DESC LIMIT 2, 3 " {X X 3 4 5 6 7 8 X X} 000567 000568 X "UPDATE t7 SET s = 'X'" {X X X X X X X X X X} 000569 } 000570 000571 # EVIDENCE-OF: R-19486-35828 If the UPDATE statement has no ORDER BY 000572 # clause, then all rows that would be updated in the absence of the 000573 # LIMIT clause are assembled in an arbitrary order before applying the 000574 # LIMIT and OFFSET clauses to determine which are actually updated. 000575 # 000576 # In practice, "arbitrary order" is rowid order. This is also tested 000577 # by e_update-3.2.* above. 000578 # 000579 do_update_tests e_update-3.4 -query { SELECT s FROM t7 } { 000580 1 "UPDATE t7 SET s = q LIMIT 4, 2" {X X X X 5 6 X X X X} 000581 2 "UPDATE t7 SET s = q LIMIT 2 OFFSET 7" {X X X X 5 6 X 8 9 X} 000582 } 000583 000584 # EVIDENCE-OF: R-10927-26133 The ORDER BY clause on an UPDATE statement 000585 # is used only to determine which rows fall within the LIMIT. The order 000586 # in which rows are modified is arbitrary and is not influenced by the 000587 # ORDER BY clause. 000588 # 000589 do_execsql_test e_update-3.5.0 { 000590 CREATE TABLE t8(x); 000591 CREATE TRIGGER tr7 BEFORE UPDATE ON t7 BEGIN 000592 INSERT INTO t8 VALUES(old.q); 000593 END; 000594 } {} 000595 do_update_tests e_update-3.5 -query { SELECT x FROM t8 ; DELETE FROM t8 } { 000596 1 "UPDATE t7 SET s = q ORDER BY r LIMIT -1" {1 2 3 4 5 6 7 8 9 10} 000597 2 "UPDATE t7 SET s = q ORDER BY r ASC LIMIT -1" {1 2 3 4 5 6 7 8 9 10} 000598 3 "UPDATE t7 SET s = q ORDER BY r DESC LIMIT -1" {1 2 3 4 5 6 7 8 9 10} 000599 4 "UPDATE t7 SET s = q ORDER BY q DESC LIMIT 5" {6 7 8 9 10} 000600 } 000601 000602 000603 } ;# ifcapable update_delete_limit 000604 000605 finish_test