3 # The author disclaims copyright to this source code. In place of
4 # a legal notice, here is a blessing:
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.
10 #***********************************************************************
12 # Test cases for generalized UPSERT
14 set testdir [file dirname $argv0]
15 source $testdir/tester.tcl
16 set testprefix upsert5
19 1 { CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c UNIQUE, d UNIQUE, e UNIQUE) }
20 2 { CREATE TABLE t1(a INT PRIMARY KEY, b, c UNIQUE, d UNIQUE, e UNIQUE) }
21 3 { CREATE TABLE t1(a INT PRIMARY KEY, b, c UNIQUE, d UNIQUE, e UNIQUE) WITHOUT ROWID}
22 4 { CREATE TABLE t1(e UNIQUE, d UNIQUE, c UNIQUE, a INTEGER PRIMARY KEY, b) }
23 5 { CREATE TABLE t1(e UNIQUE, d UNIQUE, c UNIQUE, a INT PRIMARY KEY, b) }
24 6 { CREATE TABLE t1(e UNIQUE, d UNIQUE, c UNIQUE, a INT PRIMARY KEY, b) WITHOUT ROWID}
29 do_execsql_test 1.$tn.100 {
31 INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
32 INSERT INTO t1(a,b,c,d,e) VALUES(1,NULL,3,4,5)
33 ON CONFLICT(a) DO UPDATE SET b='a'
34 ON CONFLICT(c) DO UPDATE SET b='c'
35 ON CONFLICT(d) DO UPDATE SET b='d'
36 ON CONFLICT(e) DO UPDATE SET b='e';
37 SELECT a,b,c,d,e FROM t1;
39 do_execsql_test 1.$tn.101 {
41 INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
42 INSERT INTO t1(a,b,c,d,e) VALUES(91,NULL,3,4,5)
43 ON CONFLICT(a) DO UPDATE SET b='a'
44 ON CONFLICT(c) DO UPDATE SET b='c'
45 ON CONFLICT(d) DO UPDATE SET b='d'
46 ON CONFLICT(e) DO UPDATE SET b='e';
47 SELECT a,b,c,d,e FROM t1;
49 do_execsql_test 1.$tn.102 {
51 INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
52 INSERT INTO t1(a,b,c,d,e) VALUES(91,NULL,93,4,5)
53 ON CONFLICT(a) DO UPDATE SET b='a'
54 ON CONFLICT(c) DO UPDATE SET b='c'
55 ON CONFLICT(d) DO UPDATE SET b='d'
56 ON CONFLICT(e) DO UPDATE SET b='e';
57 SELECT a,b,c,d,e FROM t1;
59 do_execsql_test 1.$tn.103 {
61 INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
62 INSERT INTO t1(a,b,c,d,e) VALUES(91,NULL,93,94,5)
63 ON CONFLICT(a) DO UPDATE SET b='a'
64 ON CONFLICT(c) DO UPDATE SET b='c'
65 ON CONFLICT(d) DO UPDATE SET b='d'
66 ON CONFLICT(e) DO UPDATE SET b='e';
67 SELECT a,b,c,d,e FROM t1;
69 do_execsql_test 1.$tn.200 {
71 INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
72 INSERT INTO t1(a,b,c,d,e) VALUES(1,NULL,93,94,95)
73 ON CONFLICT(c) DO UPDATE SET b='c'
74 ON CONFLICT(a) DO UPDATE SET b='a'
75 ON CONFLICT(d) DO UPDATE SET b='d'
76 ON CONFLICT(e) DO UPDATE SET b='e';
77 SELECT a,b,c,d,e FROM t1;
79 do_execsql_test 1.$tn.201 {
81 INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
82 INSERT INTO t1(a,b,c,d,e) VALUES(1,NULL,3,94,95)
83 ON CONFLICT(c) DO UPDATE SET b='c'
84 ON CONFLICT(a) DO UPDATE SET b='a'
85 ON CONFLICT(d) DO UPDATE SET b='d'
86 ON CONFLICT(e) DO UPDATE SET b='e';
87 SELECT a,b,c,d,e FROM t1;
89 do_execsql_test 1.$tn.202 {
91 INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
92 INSERT INTO t1(a,b,c,d,e) VALUES(1,NULL,3,4,5)
93 ON CONFLICT(c) DO UPDATE SET b='c'
94 ON CONFLICT(a) DO UPDATE SET b='a'
95 ON CONFLICT(d) DO UPDATE SET b='d'
96 ON CONFLICT(e) DO UPDATE SET b='e';
97 SELECT a,b,c,d,e FROM t1;
99 do_execsql_test 1.$tn.203 {
101 INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
102 INSERT INTO t1(a,b,c,d,e) VALUES(1,NULL,93,94,5)
103 ON CONFLICT(c) DO UPDATE SET b='c'
104 ON CONFLICT(a) DO UPDATE SET b='a'
105 ON CONFLICT(d) DO UPDATE SET b='d'
106 ON CONFLICT(e) DO UPDATE SET b='e';
107 SELECT a,b,c,d,e FROM t1;
109 do_execsql_test 1.$tn.204 {
111 INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
112 INSERT INTO t1(a,b,c,d,e) VALUES(1,NULL,93,4,95)
113 ON CONFLICT(c) DO UPDATE SET b='c'
114 ON CONFLICT(a) DO UPDATE SET b='a'
115 ON CONFLICT(d) DO UPDATE SET b='d'
116 ON CONFLICT(e) DO UPDATE SET b='e';
117 SELECT a,b,c,d,e FROM t1;
119 do_execsql_test 1.$tn.210 {
121 INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
122 INSERT INTO t1(a,b,c,d,e) VALUES(1,NULL,93,94,95)
123 ON CONFLICT(c) DO UPDATE SET b='c'
124 ON CONFLICT(d) DO UPDATE SET b='d'
125 ON CONFLICT(a) DO UPDATE SET b='a'
126 ON CONFLICT(e) DO UPDATE SET b='e';
127 SELECT a,b,c,d,e FROM t1;
129 do_execsql_test 1.$tn.211 {
131 INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
132 INSERT INTO t1(a,b,c,d,e) VALUES(1,NULL,93,4,95)
133 ON CONFLICT(c) DO UPDATE SET b='c'
134 ON CONFLICT(d) DO UPDATE SET b='d'
135 ON CONFLICT(a) DO UPDATE SET b='a'
136 ON CONFLICT(e) DO UPDATE SET b='e';
137 SELECT a,b,c,d,e FROM t1;
139 do_execsql_test 1.$tn.212 {
141 INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
142 INSERT INTO t1(a,b,c,d,e) VALUES(1,NULL,93,94,5)
143 ON CONFLICT(c) DO UPDATE SET b='c'
144 ON CONFLICT(d) DO UPDATE SET b='d'
145 ON CONFLICT(a) DO UPDATE SET b='a'
146 ON CONFLICT(e) DO UPDATE SET b='e';
147 SELECT a,b,c,d,e FROM t1;
149 do_execsql_test 1.$tn.213 {
151 INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
152 INSERT INTO t1(a,b,c,d,e) VALUES(91,NULL,93,94,5)
153 ON CONFLICT(c) DO UPDATE SET b='c'
154 ON CONFLICT(d) DO UPDATE SET b='d'
155 ON CONFLICT(a) DO UPDATE SET b='a'
156 ON CONFLICT(e) DO UPDATE SET b='e';
157 SELECT a,b,c,d,e FROM t1;
159 do_execsql_test 1.$tn.214 {
161 INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
162 INSERT INTO t1(a,b,c,d,e) VALUES(91,NULL,93,94,5)
163 ON CONFLICT(c) DO UPDATE SET b='c'
164 ON CONFLICT(d) DO UPDATE SET b='d'
165 ON CONFLICT(e) DO UPDATE SET b='e'
166 ON CONFLICT(a) DO UPDATE SET b='a';
167 SELECT a,b,c,d,e FROM t1;
169 do_execsql_test 1.$tn.215 {
171 INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
172 INSERT INTO t1(a,b,c,d,e) VALUES(1,NULL,93,94,5)
173 ON CONFLICT(c) DO UPDATE SET b='c'
174 ON CONFLICT(d) DO UPDATE SET b='d'
175 ON CONFLICT(e) DO UPDATE SET b='e'
176 ON CONFLICT(a) DO UPDATE SET b='a';
177 SELECT a,b,c,d,e FROM t1;
179 do_execsql_test 1.$tn.216 {
181 INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
182 INSERT INTO t1(a,b,c,d,e) VALUES(1,NULL,93,94,95)
183 ON CONFLICT(c) DO UPDATE SET b='c'
184 ON CONFLICT(d) DO UPDATE SET b='d'
185 ON CONFLICT(e) DO UPDATE SET b='e'
186 ON CONFLICT(a) DO UPDATE SET b='a';
187 SELECT a,b,c,d,e FROM t1;
190 do_execsql_test 1.$tn.300 {
192 INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
193 INSERT INTO t1(a,b,c,d,e) VALUES(1,NULL,93,94,95)
194 ON CONFLICT(c) DO UPDATE SET b='c'
195 ON CONFLICT(d) DO UPDATE SET b='d'
196 ON CONFLICT(a) DO UPDATE SET b='a1'
197 ON CONFLICT(a) DO UPDATE SET b='a2'
198 ON CONFLICT(a) DO UPDATE SET b='a3'
199 ON CONFLICT(a) DO UPDATE SET b='a4'
200 ON CONFLICT(a) DO UPDATE SET b='a5'
201 ON CONFLICT(e) DO UPDATE SET b='e';
202 SELECT a,b,c,d,e FROM t1;
204 do_execsql_test 1.$tn.301 {
206 INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
207 INSERT INTO t1(a,b,c,d,e) VALUES(91,NULL,93,94,5)
208 ON CONFLICT(c) DO UPDATE SET b='c'
209 ON CONFLICT(d) DO UPDATE SET b='d'
210 ON CONFLICT(a) DO UPDATE SET b='a1'
211 ON CONFLICT(a) DO UPDATE SET b='a2'
212 ON CONFLICT(a) DO UPDATE SET b='a3'
213 ON CONFLICT(a) DO UPDATE SET b='a4'
214 ON CONFLICT(a) DO UPDATE SET b='a5'
215 ON CONFLICT(e) DO UPDATE SET b='e';
216 SELECT a,b,c,d,e FROM t1;
219 do_execsql_test 1.$tn.400 {
221 INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
222 INSERT INTO t1(a,b,c,d,e) VALUES(1,NULL,93,94,95)
223 ON CONFLICT(c) DO UPDATE SET b='c'
224 ON CONFLICT(d) DO UPDATE SET b='d'
225 ON CONFLICT DO UPDATE set b='x';
226 SELECT a,b,c,d,e FROM t1;
228 do_execsql_test 1.$tn.401 {
230 INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
231 INSERT INTO t1(a,b,c,d,e) VALUES(91,NULL,93,94,5)
232 ON CONFLICT(c) DO UPDATE SET b='c'
233 ON CONFLICT(d) DO UPDATE SET b='d'
234 ON CONFLICT DO UPDATE set b='x';
235 SELECT a,b,c,d,e FROM t1;
237 do_execsql_test 1.$tn.402 {
239 INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
240 INSERT INTO t1(a,b,c,d,e) VALUES(1,NULL,93,94,95)
241 ON CONFLICT(c) DO UPDATE SET b='c'
242 ON CONFLICT(d) DO UPDATE SET b='d'
243 ON CONFLICT DO UPDATE set b='x';
244 SELECT a,b,c,d,e FROM t1;
246 do_execsql_test 1.$tn.403 {
248 INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
249 INSERT INTO t1(a,b,c,d,e) VALUES(91,NULL,3,94,95)
250 ON CONFLICT(c) DO UPDATE SET b='c'
251 ON CONFLICT(d) DO UPDATE SET b='d'
252 ON CONFLICT DO UPDATE set b='x';
253 SELECT a,b,c,d,e FROM t1;
255 do_execsql_test 1.$tn.404 {
257 INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
258 INSERT INTO t1(a,b,c,d,e) VALUES(91,NULL,3,4,95)
259 ON CONFLICT(c) DO UPDATE SET b='c'
260 ON CONFLICT(d) DO UPDATE SET b='d'
261 ON CONFLICT DO UPDATE set b='x';
262 SELECT a,b,c,d,e FROM t1;
264 do_execsql_test 1.$tn.405 {
266 INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
267 INSERT INTO t1(a,b,c,d,e) VALUES(1,NULL,93,4,5)
268 ON CONFLICT(c) DO UPDATE SET b='c'
269 ON CONFLICT(d) DO UPDATE SET b='d'
270 ON CONFLICT DO UPDATE set b='x';
271 SELECT a,b,c,d,e FROM t1;
274 do_execsql_test 1.$tn.410 {
276 INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
277 INSERT INTO t1(a,b,c,d,e) VALUES(1,NULL,93,94,95)
278 ON CONFLICT DO UPDATE set b='x';
279 SELECT a,b,c,d,e FROM t1;
281 do_execsql_test 1.$tn.411 {
283 INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
284 INSERT INTO t1(a,b,c,d,e) VALUES(91,NULL,93,94,5)
285 ON CONFLICT DO UPDATE set b='x';
286 SELECT a,b,c,d,e FROM t1;
288 do_execsql_test 1.$tn.412 {
290 INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
291 INSERT INTO t1(a,b,c,d,e) VALUES(91,NULL,93,4,95)
292 ON CONFLICT DO UPDATE set b='x';
293 SELECT a,b,c,d,e FROM t1;
295 do_execsql_test 1.$tn.413 {
297 INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
298 INSERT INTO t1(a,b,c,d,e) VALUES(91,NULL,3,94,95)
299 ON CONFLICT DO UPDATE set b='x';
300 SELECT a,b,c,d,e FROM t1;
303 do_execsql_test 1.$tn.420 {
305 INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
306 INSERT INTO t1(a,b,c,d,e) VALUES(1,NULL,93,94,95)
307 ON CONFLICT(c) DO NOTHING
308 ON CONFLICT(d) DO NOTHING
309 ON CONFLICT DO UPDATE set b='x';
310 SELECT a,b,c,d,e FROM t1;
312 do_execsql_test 1.$tn.421 {
314 INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
315 INSERT INTO t1(a,b,c,d,e) VALUES(91,NULL,93,94,5)
316 ON CONFLICT(c) DO NOTHING
317 ON CONFLICT(d) DO NOTHING
318 ON CONFLICT DO UPDATE set b='x';
319 SELECT a,b,c,d,e FROM t1;
321 do_execsql_test 1.$tn.422 {
323 INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
324 INSERT INTO t1(a,b,c,d,e) VALUES(91,NULL,93,4,95)
325 ON CONFLICT(c) DO NOTHING
326 ON CONFLICT(d) DO NOTHING
327 ON CONFLICT DO UPDATE set b='x';
328 SELECT a,b,c,d,e FROM t1;
330 do_execsql_test 1.$tn.423 {
332 INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
333 INSERT INTO t1(a,b,c,d,e) VALUES(91,NULL,3,94,95)
334 ON CONFLICT(c) DO NOTHING
335 ON CONFLICT(d) DO NOTHING
336 ON CONFLICT DO UPDATE set b='x';
337 SELECT a,b,c,d,e FROM t1;
340 do_execsql_test 1.$tn.500 {
342 INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
343 INSERT INTO t1(a,b,c,d,e) VALUES(1,NULL,93,94,95)
344 ON CONFLICT(c) DO UPDATE SET b='c'
345 ON CONFLICT(d) DO UPDATE SET b='d'
346 ON CONFLICT DO NOTHING;
347 SELECT a,b,c,d,e FROM t1;
349 do_execsql_test 1.$tn.501 {
351 INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
352 INSERT INTO t1(a,b,c,d,e) VALUES(91,NULL,93,94,5)
353 ON CONFLICT(c) DO UPDATE SET b='c'
354 ON CONFLICT(d) DO UPDATE SET b='d'
355 ON CONFLICT DO NOTHING;
356 SELECT a,b,c,d,e FROM t1;
358 do_execsql_test 1.$tn.502 {
360 INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
361 INSERT INTO t1(a,b,c,d,e) VALUES(1,NULL,93,94,95)
362 ON CONFLICT(c) DO UPDATE SET b='c'
363 ON CONFLICT(d) DO UPDATE SET b='d'
364 ON CONFLICT DO NOTHING;
365 SELECT a,b,c,d,e FROM t1;
367 do_execsql_test 1.$tn.503 {
369 INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
370 INSERT INTO t1(a,b,c,d,e) VALUES(91,NULL,3,94,95)
371 ON CONFLICT(c) DO UPDATE SET b='c'
372 ON CONFLICT(d) DO UPDATE SET b='d'
373 ON CONFLICT DO NOTHING;
374 SELECT a,b,c,d,e FROM t1;
376 do_execsql_test 1.$tn.504 {
378 INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
379 INSERT INTO t1(a,b,c,d,e) VALUES(91,NULL,3,4,95)
380 ON CONFLICT(c) DO UPDATE SET b='c'
381 ON CONFLICT(d) DO UPDATE SET b='d'
382 ON CONFLICT DO NOTHING;
383 SELECT a,b,c,d,e FROM t1;
385 do_execsql_test 1.$tn.505 {
387 INSERT INTO t1(a,b,c,d,e) VALUES(1,2,3,4,5);
388 INSERT INTO t1(a,b,c,d,e) VALUES(1,NULL,93,4,5)
389 ON CONFLICT(c) DO UPDATE SET b='c'
390 ON CONFLICT(d) DO UPDATE SET b='d'
391 ON CONFLICT DO NOTHING;
392 SELECT a,b,c,d,e FROM t1;
397 #--------------------------------------------------------------------------
399 do_execsql_test 2.0 {
400 CREATE TABLE t2(a, b, c REAL, d, e, PRIMARY KEY(a,b)) WITHOUT ROWID;
401 CREATE UNIQUE INDEX t2c ON t2(c);
404 do_catchsql_test 2.1 {
405 INSERT INTO t2(a,b,c,e,d) VALUES(1,2,3,4,5)
406 ON CONFLICT(c) DO UPDATE SET b=''
407 ON CONFLICT((SELECT t2 FROM nosuchtable)) DO NOTHING;
409 } {1 {no such table: nosuchtable}}
411 # 2024-03-08 https://sqlite.org/forum/forumpost/919c6579c8
412 # A redundant ON CONFLICT clause in an upsert can lead to
416 do_execsql_test 3.0 {
417 CREATE TABLE t1(aa INTEGER PRIMARY KEY, bb INT);
418 INSERT INTO t1 VALUES(11,22);
419 CREATE UNIQUE INDEX t1bb ON t1(bb);
420 REPLACE INTO t1 VALUES(11,33)
421 ON CONFLICT(bb) DO UPDATE SET aa = 44
422 ON CONFLICT(bb) DO UPDATE SET aa = 44;
423 PRAGMA integrity_check;
425 do_execsql_test 3.1 {
426 SELECT * FROM t1 NOT INDEXED;
428 do_execsql_test 3.2 {
429 SELECT * FROM t1 INDEXED BY t1bb;
431 do_execsql_test 3.3 {
433 CREATE TABLE t1(aa INTEGER PRIMARY KEY, bb INT, cc INT);
434 INSERT INTO t1 VALUES(10,21,32),(11,22,33),(12,23,34);
435 CREATE UNIQUE INDEX t1bb ON t1(bb);
436 CREATE UNIQUE INDEX t1cc ON t1(cc);
437 REPLACE INTO t1 VALUES(11,44,55)
438 ON CONFLICT(bb) DO UPDATE SET aa = 99
439 ON CONFLICT(cc) DO UPDATE SET aa = 99
440 ON CONFLICT(bb) DO UPDATE SET aa = 99;
441 PRAGMA integrity_check;
443 do_execsql_test 3.4 {
444 SELECT * FROM t1 NOT INDEXED ORDER BY +aa;
445 } {10 21 32 11 44 55 12 23 34}
446 do_execsql_test 3.5 {
447 SELECT * FROM t1 INDEXED BY t1bb ORDER BY +aa;
448 } {10 21 32 11 44 55 12 23 34}
449 do_execsql_test 3.6 {
450 SELECT * FROM t1 INDEXED BY t1cc ORDER BY +aa;
451 } {10 21 32 11 44 55 12 23 34}