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 #***********************************************************************
11 # This file implements regression tests for SQLite library. The
12 # focus of this file is testing the INSERT transfer optimization.
14 # $Id: insert4.test,v 1.10 2008/01/21 16:22:46 drh Exp $
16 set testdir [file dirname $argv0]
17 source $testdir/tester.tcl
19 ifcapable !view||!subquery {
24 # The sqlite3_xferopt_count variable is incremented whenever the
25 # insert transfer optimization applies.
27 # This procedure runs a test to see if the sqlite3_xferopt_count is
30 proc xferopt_test {testname N} {
31 do_test $testname {set ::sqlite3_xferopt_count} $N
34 # Create tables used for testing.
37 PRAGMA legacy_file_format = 0;
38 CREATE TABLE t1(a int, b int, check(b>a));
39 CREATE TABLE t2(x int, y int);
40 CREATE VIEW v2 AS SELECT y, x FROM t2;
41 CREATE TABLE t3(a int, b int);
44 # Ticket #2252. Make sure the an INSERT from identical tables
45 # does not violate constraints.
48 set sqlite3_xferopt_count 0
52 INSERT INTO t2 VALUES(9,1);
55 INSERT INTO t1 SELECT * FROM t2;
57 } {1 {CHECK constraint failed: t1}}
58 xferopt_test insert4-1.2 0
65 # Tests to make sure that the transfer optimization is not occurring
66 # when it is not a valid optimization.
68 # The SELECT must be against a real table.
69 do_test insert4-2.1.1 {
72 INSERT INTO t1 SELECT 4, 8;
76 xferopt_test insert4-2.1.2 0
77 do_test insert4-2.2.1 {
80 INSERT INTO t1 SELECT * FROM v2;
84 xferopt_test insert4-2.2.2 0
86 # Do not run the transfer optimization if there is a LIMIT clause
88 do_test insert4-2.3.1 {
91 INSERT INTO t2 VALUES(9,1);
92 INSERT INTO t2 SELECT y, x FROM t2;
93 INSERT INTO t3 SELECT * FROM t2 LIMIT 1;
97 xferopt_test insert4-2.3.2 0
98 do_test insert4-2.3.3 {
101 INSERT INTO t1 SELECT * FROM t2 LIMIT 1;
104 } {1 {CHECK constraint failed: t1}}
105 xferopt_test insert4-2.3.4 0
107 # Do not run the transfer optimization if there is a DISTINCT
109 do_test insert4-2.4.1 {
112 INSERT INTO t3 SELECT DISTINCT * FROM t2;
116 xferopt_test insert4-2.4.2 0
117 do_test insert4-2.4.3 {
120 INSERT INTO t1 SELECT DISTINCT * FROM t2;
122 } {1 {CHECK constraint failed: t1}}
123 xferopt_test insert4-2.4.4 0
125 # The following procedure constructs two tables then tries to transfer
126 # data from one table to the other. Checks are made to make sure the
127 # transfer is successful and that the transfer optimization was used or
128 # not, as appropriate.
130 # xfer_check TESTID XFER-USED INIT-DATA DEST-SCHEMA SRC-SCHEMA
132 # The TESTID argument is the symbolic name for this test. The XFER-USED
133 # argument is true if the transfer optimization should be employed and
134 # false if not. INIT-DATA is a single row of data that is to be
135 # transfered. DEST-SCHEMA and SRC-SCHEMA are table declarations for
136 # the destination and source tables.
138 proc xfer_check {testid xferused initdata destschema srcschema} {
139 execsql "CREATE TABLE dest($destschema)"
140 execsql "CREATE TABLE src($srcschema)"
141 execsql "INSERT INTO src VALUES([join $initdata ,])"
142 set ::sqlite3_xferopt_count 0
145 INSERT INTO dest SELECT * FROM src;
150 set ::sqlite3_xferopt_count
159 # Do run the transfer optimization if tables have identical
162 xfer_check insert4-3.1 1 {1 9} \
163 {a int, b int CHECK(b>a)} \
164 {x int, y int CHECK(y>x)}
165 xfer_check insert4-3.2 1 {1 9} \
166 {a int, b int CHECK(b>a)} \
167 {x int CHECK(y>x), y int}
169 # Do run the transfer optimization if the destination table lacks
170 # any CHECK constraints regardless of whether or not there are CHECK
171 # constraints on the source table.
173 xfer_check insert4-3.3 1 {1 9} \
175 {x int, y int CHECK(y>x)}
177 # Do run the transfer optimization if the destination table omits
178 # NOT NULL constraints that the source table has.
180 xfer_check insert4-3.4 0 {1 9} \
181 {a int, b int CHECK(b>a)} \
184 # Do not run the optimization if the destination has NOT NULL
185 # constraints that the source table lacks.
187 xfer_check insert4-3.5 0 {1 9} \
188 {a int, b int NOT NULL} \
190 xfer_check insert4-3.6 0 {1 9} \
191 {a int, b int NOT NULL} \
192 {x int NOT NULL, y int}
193 xfer_check insert4-3.7 0 {1 9} \
194 {a int NOT NULL, b int NOT NULL} \
195 {x int NOT NULL, y int}
196 xfer_check insert4-3.8 0 {1 9} \
197 {a int NOT NULL, b int} \
201 # Do run the transfer optimization if the destination table and
202 # source table have the same NOT NULL constraints or if the
203 # source table has extra NOT NULL constraints.
205 xfer_check insert4-3.9 1 {1 9} \
207 {x int NOT NULL, y int}
208 xfer_check insert4-3.10 1 {1 9} \
210 {x int NOT NULL, y int NOT NULL}
211 xfer_check insert4-3.11 1 {1 9} \
212 {a int NOT NULL, b int} \
213 {x int NOT NULL, y int NOT NULL}
214 xfer_check insert4-3.12 1 {1 9} \
215 {a int, b int NOT NULL} \
216 {x int NOT NULL, y int NOT NULL}
218 # Do not run the optimization if any corresponding table
219 # columns have different affinities.
221 xfer_check insert4-3.20 0 {1 9} \
224 xfer_check insert4-3.21 0 {1 9} \
228 # "int" and "integer" are equivalent so the optimization should
231 xfer_check insert4-3.22 1 {1 9} \
238 do_test insert4-4.1a {
239 execsql {CREATE TABLE t4(a, b, UNIQUE(a,b))}
242 do_test insert4-4.1b {
244 INSERT INTO t4 VALUES(NULL,0);
245 INSERT INTO t4 VALUES(NULL,1);
246 INSERT INTO t4 VALUES(NULL,1);
252 # Check some error conditions:
254 do_test insert4-5.1 {
255 # Table does not exist.
256 catchsql { INSERT INTO t2 SELECT a, b FROM nosuchtable }
257 } {1 {no such table: nosuchtable}}
258 do_test insert4-5.2 {
259 # Number of columns does not match.
261 CREATE TABLE t5(a, b, c);
262 INSERT INTO t4 SELECT * FROM t5;
264 } {1 {table t4 has 2 columns but 3 values were supplied}}
266 do_test insert4-6.1 {
267 set ::sqlite3_xferopt_count 0
269 CREATE INDEX t2_i2 ON t2(x, y COLLATE nocase);
270 CREATE INDEX t2_i1 ON t2(x ASC, y DESC);
271 CREATE INDEX t3_i1 ON t3(a, b);
272 INSERT INTO t2 SELECT * FROM t3;
274 set ::sqlite3_xferopt_count
276 do_test insert4-6.2 {
277 set ::sqlite3_xferopt_count 0
280 INSERT INTO t2 SELECT * FROM t3;
282 set ::sqlite3_xferopt_count
284 do_test insert4-6.3 {
285 set ::sqlite3_xferopt_count 0
288 CREATE INDEX t2_i1 ON t2(x ASC, y ASC);
289 INSERT INTO t2 SELECT * FROM t3;
291 set ::sqlite3_xferopt_count
293 do_test insert4-6.4 {
294 set ::sqlite3_xferopt_count 0
297 CREATE INDEX t2_i1 ON t2(x ASC, y COLLATE RTRIM);
298 INSERT INTO t2 SELECT * FROM t3;
300 set ::sqlite3_xferopt_count
304 do_test insert4-6.5 {
306 CREATE TABLE t6a(x CHECK( x<>'abc' ));
307 INSERT INTO t6a VALUES('ABC');
311 do_test insert4-6.6 {
313 CREATE TABLE t6b(x CHECK( x<>'abc' COLLATE nocase ));
316 INSERT INTO t6b SELECT * FROM t6a;
318 } {1 {CHECK constraint failed: t6b}}
319 do_test insert4-6.7 {
322 CREATE TABLE t6b(x CHECK( x COLLATE nocase <>'abc' ));
325 INSERT INTO t6b SELECT * FROM t6a;
327 } {1 {CHECK constraint failed: t6b}}
329 # Ticket [6284df89debdfa61db8073e062908af0c9b6118e]
330 # Disable the xfer optimization if the destination table contains
331 # a foreign key constraint
333 ifcapable foreignkey {
334 do_test insert4-7.1 {
335 set ::sqlite3_xferopt_count 0
337 CREATE TABLE t7a(x INTEGER PRIMARY KEY); INSERT INTO t7a VALUES(123);
338 CREATE TABLE t7b(y INTEGER REFERENCES t7a);
339 CREATE TABLE t7c(z INT); INSERT INTO t7c VALUES(234);
340 INSERT INTO t7b SELECT * FROM t7c;
344 do_test insert4-7.2 {
345 set ::sqlite3_xferopt_count
347 do_test insert4-7.3 {
348 set ::sqlite3_xferopt_count 0
351 PRAGMA foreign_keys=ON;
354 INSERT INTO t7b SELECT * FROM t7c;
356 } {1 {FOREIGN KEY constraint failed}}
357 do_test insert4-7.4 {
358 execsql {SELECT * FROM t7b}
360 do_test insert4-7.5 {
361 set ::sqlite3_xferopt_count
363 do_test insert4-7.6 {
364 set ::sqlite3_xferopt_count 0
366 DELETE FROM t7b; DELETE FROM t7c;
367 INSERT INTO t7c VALUES(123);
368 INSERT INTO t7b SELECT * FROM t7c;
372 do_test insert4-7.7 {
373 set ::sqlite3_xferopt_count
375 do_test insert4-7.7 {
376 set ::sqlite3_xferopt_count 0
378 PRAGMA foreign_keys=OFF;
380 INSERT INTO t7b SELECT * FROM t7c;
384 do_test insert4-7.8 {
385 set ::sqlite3_xferopt_count
389 # Ticket [676bc02b87176125635cb174d110b431581912bb]
390 # Make sure INTEGER PRIMARY KEY ON CONFLICT ... works with the xfer
393 do_test insert4-8.1 {
395 DROP TABLE IF EXISTS t1;
396 DROP TABLE IF EXISTS t2;
397 CREATE TABLE t1(a INTEGER PRIMARY KEY ON CONFLICT REPLACE, b);
398 CREATE TABLE t2(x INTEGER PRIMARY KEY ON CONFLICT REPLACE, y);
399 INSERT INTO t1 VALUES(1,2);
400 INSERT INTO t2 VALUES(1,3);
401 INSERT INTO t1 SELECT * FROM t2;
405 do_test insert4-8.2 {
407 DROP TABLE IF EXISTS t1;
408 DROP TABLE IF EXISTS t2;
409 CREATE TABLE t1(a INTEGER PRIMARY KEY ON CONFLICT REPLACE, b);
410 CREATE TABLE t2(x, y);
411 INSERT INTO t1 VALUES(1,2);
412 INSERT INTO t2 VALUES(1,3);
413 INSERT INTO t1 SELECT * FROM t2;
417 do_test insert4-8.3 {
419 DROP TABLE IF EXISTS t1;
420 DROP TABLE IF EXISTS t2;
421 CREATE TABLE t1(a INTEGER PRIMARY KEY ON CONFLICT IGNORE, b);
422 CREATE TABLE t2(x INTEGER PRIMARY KEY ON CONFLICT IGNORE, y);
423 INSERT INTO t1 VALUES(1,2);
424 INSERT INTO t2 VALUES(1,3);
425 INSERT INTO t1 SELECT * FROM t2;
429 do_test insert4-8.4 {
431 DROP TABLE IF EXISTS t1;
432 DROP TABLE IF EXISTS t2;
433 CREATE TABLE t1(a INTEGER PRIMARY KEY ON CONFLICT IGNORE, b);
434 CREATE TABLE t2(x, y);
435 INSERT INTO t1 VALUES(1,2);
436 INSERT INTO t2 VALUES(1,3);
437 INSERT INTO t1 SELECT * FROM t2;
441 do_test insert4-8.5 {
443 DROP TABLE IF EXISTS t1;
444 DROP TABLE IF EXISTS t2;
445 CREATE TABLE t1(a INTEGER PRIMARY KEY ON CONFLICT FAIL, b);
446 CREATE TABLE t2(x INTEGER PRIMARY KEY ON CONFLICT FAIL, y);
447 INSERT INTO t1 VALUES(1,2);
448 INSERT INTO t2 VALUES(-99,100);
449 INSERT INTO t2 VALUES(1,3);
453 INSERT INTO t1 SELECT * FROM t2;
455 } {1 {UNIQUE constraint failed: t1.a}}
456 do_test insert4-8.6 {
461 do_test insert4-8.7 {
463 DROP TABLE IF EXISTS t1;
464 DROP TABLE IF EXISTS t2;
465 CREATE TABLE t1(a INTEGER PRIMARY KEY ON CONFLICT ABORT, b);
466 CREATE TABLE t2(x INTEGER PRIMARY KEY ON CONFLICT ABORT, y);
467 INSERT INTO t1 VALUES(1,2);
468 INSERT INTO t2 VALUES(-99,100);
469 INSERT INTO t2 VALUES(1,3);
473 INSERT INTO t1 SELECT * FROM t2;
475 } {1 {UNIQUE constraint failed: t1.a}}
476 do_test insert4-8.8 {
481 do_test insert4-8.9 {
483 DROP TABLE IF EXISTS t1;
484 DROP TABLE IF EXISTS t2;
485 CREATE TABLE t1(a INTEGER PRIMARY KEY ON CONFLICT ROLLBACK, b);
486 CREATE TABLE t2(x INTEGER PRIMARY KEY ON CONFLICT ROLLBACK, y);
487 INSERT INTO t1 VALUES(1,2);
488 INSERT INTO t2 VALUES(-99,100);
489 INSERT INTO t2 VALUES(1,3);
494 INSERT INTO t1 VALUES(2,3);
495 INSERT INTO t1 SELECT * FROM t2;
497 } {1 {UNIQUE constraint failed: t1.a}}
498 do_test insert4-8.10 {
500 } {1 {cannot commit - no transaction is active}}
501 do_test insert4-8.11 {
507 do_test insert4-8.21 {
509 DROP TABLE IF EXISTS t1;
510 DROP TABLE IF EXISTS t2;
511 CREATE TABLE t1(a INTEGER PRIMARY KEY ON CONFLICT REPLACE, b);
512 CREATE TABLE t2(x INTEGER PRIMARY KEY ON CONFLICT REPLACE, y);
513 INSERT INTO t2 VALUES(1,3);
514 INSERT INTO t1 SELECT * FROM t2;
518 do_test insert4-8.22 {
520 DROP TABLE IF EXISTS t1;
521 DROP TABLE IF EXISTS t2;
522 CREATE TABLE t1(a INTEGER PRIMARY KEY ON CONFLICT IGNORE, b);
523 CREATE TABLE t2(x INTEGER PRIMARY KEY ON CONFLICT IGNORE, y);
524 INSERT INTO t2 VALUES(1,3);
525 INSERT INTO t1 SELECT * FROM t2;
529 do_test insert4-8.23 {
531 DROP TABLE IF EXISTS t1;
532 DROP TABLE IF EXISTS t2;
533 CREATE TABLE t1(a INTEGER PRIMARY KEY ON CONFLICT ABORT, b);
534 CREATE TABLE t2(x INTEGER PRIMARY KEY ON CONFLICT ABORT, y);
535 INSERT INTO t2 VALUES(1,3);
536 INSERT INTO t1 SELECT * FROM t2;
540 do_test insert4-8.24 {
542 DROP TABLE IF EXISTS t1;
543 DROP TABLE IF EXISTS t2;
544 CREATE TABLE t1(a INTEGER PRIMARY KEY ON CONFLICT FAIL, b);
545 CREATE TABLE t2(x INTEGER PRIMARY KEY ON CONFLICT FAIL, y);
546 INSERT INTO t2 VALUES(1,3);
547 INSERT INTO t1 SELECT * FROM t2;
551 do_test insert4-8.25 {
553 DROP TABLE IF EXISTS t1;
554 DROP TABLE IF EXISTS t2;
555 CREATE TABLE t1(a INTEGER PRIMARY KEY ON CONFLICT ROLLBACK, b);
556 CREATE TABLE t2(x INTEGER PRIMARY KEY ON CONFLICT ROLLBACK, y);
557 INSERT INTO t2 VALUES(1,3);
558 INSERT INTO t1 SELECT * FROM t2;