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
18 set testprefix insert4
20 ifcapable !view||!subquery {
25 # The sqlite3_xferopt_count variable is incremented whenever the
26 # insert transfer optimization applies.
28 # This procedure runs a test to see if the sqlite3_xferopt_count is
31 proc xferopt_test {testname N} {
32 do_test $testname {set ::sqlite3_xferopt_count} $N
35 # Create tables used for testing.
38 PRAGMA legacy_file_format = 0;
39 CREATE TABLE t1(a int, b int, check(b>a));
40 CREATE TABLE t2(x int, y int);
41 CREATE VIEW v2 AS SELECT y, x FROM t2;
42 CREATE TABLE t3(a int, b int);
45 # Ticket #2252. Make sure the an INSERT from identical tables
46 # does not violate constraints.
49 set sqlite3_xferopt_count 0
53 INSERT INTO t2 VALUES(9,1);
56 INSERT INTO t1 SELECT * FROM t2;
58 } {1 {CHECK constraint failed: t1}}
59 xferopt_test insert4-1.2 0
66 # Tests to make sure that the transfer optimization is not occurring
67 # when it is not a valid optimization.
69 # The SELECT must be against a real table.
70 do_test insert4-2.1.1 {
73 INSERT INTO t1 SELECT 4, 8;
77 xferopt_test insert4-2.1.2 0
78 do_test insert4-2.2.1 {
81 INSERT INTO t1 SELECT * FROM v2;
85 xferopt_test insert4-2.2.2 0
87 # Do not run the transfer optimization if there is a LIMIT clause
89 do_test insert4-2.3.1 {
92 INSERT INTO t2 VALUES(9,1);
93 INSERT INTO t2 SELECT y, x FROM t2;
94 INSERT INTO t3 SELECT * FROM t2 LIMIT 1;
98 xferopt_test insert4-2.3.2 0
99 do_test insert4-2.3.3 {
102 INSERT INTO t1 SELECT * FROM t2 LIMIT 1;
105 } {1 {CHECK constraint failed: t1}}
106 xferopt_test insert4-2.3.4 0
108 # Do not run the transfer optimization if there is a DISTINCT
110 do_test insert4-2.4.1 {
113 INSERT INTO t3 SELECT DISTINCT * FROM t2;
117 xferopt_test insert4-2.4.2 0
118 do_test insert4-2.4.3 {
121 INSERT INTO t1 SELECT DISTINCT * FROM t2;
123 } {1 {CHECK constraint failed: t1}}
124 xferopt_test insert4-2.4.4 0
126 # The following procedure constructs two tables then tries to transfer
127 # data from one table to the other. Checks are made to make sure the
128 # transfer is successful and that the transfer optimization was used or
129 # not, as appropriate.
131 # xfer_check TESTID XFER-USED INIT-DATA DEST-SCHEMA SRC-SCHEMA
133 # The TESTID argument is the symbolic name for this test. The XFER-USED
134 # argument is true if the transfer optimization should be employed and
135 # false if not. INIT-DATA is a single row of data that is to be
136 # transfered. DEST-SCHEMA and SRC-SCHEMA are table declarations for
137 # the destination and source tables.
139 proc xfer_check {testid xferused initdata destschema srcschema} {
140 execsql "CREATE TABLE dest($destschema)"
141 execsql "CREATE TABLE src($srcschema)"
142 execsql "INSERT INTO src VALUES([join $initdata ,])"
143 set ::sqlite3_xferopt_count 0
146 INSERT INTO dest SELECT * FROM src;
151 set ::sqlite3_xferopt_count
160 # Do run the transfer optimization if tables have identical
163 xfer_check insert4-3.1 1 {1 9} \
164 {a int, b int CHECK(b>a)} \
165 {x int, y int CHECK(y>x)}
166 xfer_check insert4-3.2 1 {1 9} \
167 {a int, b int CHECK(b>a)} \
168 {x int CHECK(y>x), y int}
170 # Do run the transfer optimization if the destination table lacks
171 # any CHECK constraints regardless of whether or not there are CHECK
172 # constraints on the source table.
174 xfer_check insert4-3.3 1 {1 9} \
176 {x int, y int CHECK(y>x)}
178 # Do run the transfer optimization if the destination table omits
179 # NOT NULL constraints that the source table has.
181 xfer_check insert4-3.4 0 {1 9} \
182 {a int, b int CHECK(b>a)} \
185 # Do not run the optimization if the destination has NOT NULL
186 # constraints that the source table lacks.
188 xfer_check insert4-3.5 0 {1 9} \
189 {a int, b int NOT NULL} \
191 xfer_check insert4-3.6 0 {1 9} \
192 {a int, b int NOT NULL} \
193 {x int NOT NULL, y int}
194 xfer_check insert4-3.7 0 {1 9} \
195 {a int NOT NULL, b int NOT NULL} \
196 {x int NOT NULL, y int}
197 xfer_check insert4-3.8 0 {1 9} \
198 {a int NOT NULL, b int} \
202 # Do run the transfer optimization if the destination table and
203 # source table have the same NOT NULL constraints or if the
204 # source table has extra NOT NULL constraints.
206 xfer_check insert4-3.9 1 {1 9} \
208 {x int NOT NULL, y int}
209 xfer_check insert4-3.10 1 {1 9} \
211 {x int NOT NULL, y int NOT NULL}
212 xfer_check insert4-3.11 1 {1 9} \
213 {a int NOT NULL, b int} \
214 {x int NOT NULL, y int NOT NULL}
215 xfer_check insert4-3.12 1 {1 9} \
216 {a int, b int NOT NULL} \
217 {x int NOT NULL, y int NOT NULL}
219 # Do not run the optimization if any corresponding table
220 # columns have different affinities.
222 xfer_check insert4-3.20 0 {1 9} \
225 xfer_check insert4-3.21 0 {1 9} \
229 # "int" and "integer" are equivalent so the optimization should
232 xfer_check insert4-3.22 1 {1 9} \
239 do_test insert4-4.1a {
240 execsql {CREATE TABLE t4(a, b, UNIQUE(a,b))}
243 do_test insert4-4.1b {
245 INSERT INTO t4 VALUES(NULL,0);
246 INSERT INTO t4 VALUES(NULL,1);
247 INSERT INTO t4 VALUES(NULL,1);
253 # Check some error conditions:
255 do_test insert4-5.1 {
256 # Table does not exist.
257 catchsql { INSERT INTO t2 SELECT a, b FROM nosuchtable }
258 } {1 {no such table: nosuchtable}}
259 do_test insert4-5.2 {
260 # Number of columns does not match.
262 CREATE TABLE t5(a, b, c);
263 INSERT INTO t4 SELECT * FROM t5;
265 } {1 {table t4 has 2 columns but 3 values were supplied}}
267 do_test insert4-6.1 {
268 set ::sqlite3_xferopt_count 0
270 CREATE INDEX t2_i2 ON t2(x, y COLLATE nocase);
271 CREATE INDEX t2_i1 ON t2(x ASC, y DESC);
272 CREATE INDEX t3_i1 ON t3(a, b);
273 INSERT INTO t2 SELECT * FROM t3;
275 set ::sqlite3_xferopt_count
277 do_test insert4-6.2 {
278 set ::sqlite3_xferopt_count 0
281 INSERT INTO t2 SELECT * FROM t3;
283 set ::sqlite3_xferopt_count
285 do_test insert4-6.3 {
286 set ::sqlite3_xferopt_count 0
289 CREATE INDEX t2_i1 ON t2(x ASC, y ASC);
290 INSERT INTO t2 SELECT * FROM t3;
292 set ::sqlite3_xferopt_count
294 do_test insert4-6.4 {
295 set ::sqlite3_xferopt_count 0
298 CREATE INDEX t2_i1 ON t2(x ASC, y COLLATE RTRIM);
299 INSERT INTO t2 SELECT * FROM t3;
301 set ::sqlite3_xferopt_count
305 do_test insert4-6.5 {
307 CREATE TABLE t6a(x CHECK( x<>'abc' ));
308 INSERT INTO t6a VALUES('ABC');
312 do_test insert4-6.6 {
314 CREATE TABLE t6b(x CHECK( x<>'abc' COLLATE nocase ));
317 INSERT INTO t6b SELECT * FROM t6a;
319 } {1 {CHECK constraint failed: t6b}}
320 do_test insert4-6.7 {
323 CREATE TABLE t6b(x CHECK( x COLLATE nocase <>'abc' ));
326 INSERT INTO t6b SELECT * FROM t6a;
328 } {1 {CHECK constraint failed: t6b}}
330 # Ticket [6284df89debdfa61db8073e062908af0c9b6118e]
331 # Disable the xfer optimization if the destination table contains
332 # a foreign key constraint
334 ifcapable foreignkey {
335 do_test insert4-7.1 {
336 set ::sqlite3_xferopt_count 0
338 CREATE TABLE t7a(x INTEGER PRIMARY KEY); INSERT INTO t7a VALUES(123);
339 CREATE TABLE t7b(y INTEGER REFERENCES t7a);
340 CREATE TABLE t7c(z INT); INSERT INTO t7c VALUES(234);
341 INSERT INTO t7b SELECT * FROM t7c;
345 do_test insert4-7.2 {
346 set ::sqlite3_xferopt_count
348 do_test insert4-7.3 {
349 set ::sqlite3_xferopt_count 0
352 PRAGMA foreign_keys=ON;
355 INSERT INTO t7b SELECT * FROM t7c;
357 } {1 {FOREIGN KEY constraint failed}}
358 do_test insert4-7.4 {
359 execsql {SELECT * FROM t7b}
361 do_test insert4-7.5 {
362 set ::sqlite3_xferopt_count
364 do_test insert4-7.6 {
365 set ::sqlite3_xferopt_count 0
367 DELETE FROM t7b; DELETE FROM t7c;
368 INSERT INTO t7c VALUES(123);
369 INSERT INTO t7b SELECT * FROM t7c;
373 do_test insert4-7.7 {
374 set ::sqlite3_xferopt_count
376 do_test insert4-7.7 {
377 set ::sqlite3_xferopt_count 0
379 PRAGMA foreign_keys=OFF;
381 INSERT INTO t7b SELECT * FROM t7c;
385 do_test insert4-7.8 {
386 set ::sqlite3_xferopt_count
390 # Ticket [676bc02b87176125635cb174d110b431581912bb]
391 # Make sure INTEGER PRIMARY KEY ON CONFLICT ... works with the xfer
394 do_test insert4-8.1 {
396 DROP TABLE IF EXISTS t1;
397 DROP TABLE IF EXISTS t2;
398 CREATE TABLE t1(a INTEGER PRIMARY KEY ON CONFLICT REPLACE, b);
399 CREATE TABLE t2(x INTEGER PRIMARY KEY ON CONFLICT REPLACE, y);
400 INSERT INTO t1 VALUES(1,2);
401 INSERT INTO t2 VALUES(1,3);
402 INSERT INTO t1 SELECT * FROM t2;
406 do_test insert4-8.2 {
408 DROP TABLE IF EXISTS t1;
409 DROP TABLE IF EXISTS t2;
410 CREATE TABLE t1(a INTEGER PRIMARY KEY ON CONFLICT REPLACE, b);
411 CREATE TABLE t2(x, y);
412 INSERT INTO t1 VALUES(1,2);
413 INSERT INTO t2 VALUES(1,3);
414 INSERT INTO t1 SELECT * FROM t2;
418 do_test insert4-8.3 {
420 DROP TABLE IF EXISTS t1;
421 DROP TABLE IF EXISTS t2;
422 CREATE TABLE t1(a INTEGER PRIMARY KEY ON CONFLICT IGNORE, b);
423 CREATE TABLE t2(x INTEGER PRIMARY KEY ON CONFLICT IGNORE, y);
424 INSERT INTO t1 VALUES(1,2);
425 INSERT INTO t2 VALUES(1,3);
426 INSERT INTO t1 SELECT * FROM t2;
430 do_test insert4-8.4 {
432 DROP TABLE IF EXISTS t1;
433 DROP TABLE IF EXISTS t2;
434 CREATE TABLE t1(a INTEGER PRIMARY KEY ON CONFLICT IGNORE, b);
435 CREATE TABLE t2(x, y);
436 INSERT INTO t1 VALUES(1,2);
437 INSERT INTO t2 VALUES(1,3);
438 INSERT INTO t1 SELECT * FROM t2;
442 do_test insert4-8.5 {
444 DROP TABLE IF EXISTS t1;
445 DROP TABLE IF EXISTS t2;
446 CREATE TABLE t1(a INTEGER PRIMARY KEY ON CONFLICT FAIL, b);
447 CREATE TABLE t2(x INTEGER PRIMARY KEY ON CONFLICT FAIL, y);
448 INSERT INTO t1 VALUES(1,2);
449 INSERT INTO t2 VALUES(-99,100);
450 INSERT INTO t2 VALUES(1,3);
454 INSERT INTO t1 SELECT * FROM t2;
456 } {1 {UNIQUE constraint failed: t1.a}}
457 do_test insert4-8.6 {
462 do_test insert4-8.7 {
464 DROP TABLE IF EXISTS t1;
465 DROP TABLE IF EXISTS t2;
466 CREATE TABLE t1(a INTEGER PRIMARY KEY ON CONFLICT ABORT, b);
467 CREATE TABLE t2(x INTEGER PRIMARY KEY ON CONFLICT ABORT, y);
468 INSERT INTO t1 VALUES(1,2);
469 INSERT INTO t2 VALUES(-99,100);
470 INSERT INTO t2 VALUES(1,3);
474 INSERT INTO t1 SELECT * FROM t2;
476 } {1 {UNIQUE constraint failed: t1.a}}
477 do_test insert4-8.8 {
482 do_test insert4-8.9 {
484 DROP TABLE IF EXISTS t1;
485 DROP TABLE IF EXISTS t2;
486 CREATE TABLE t1(a INTEGER PRIMARY KEY ON CONFLICT ROLLBACK, b);
487 CREATE TABLE t2(x INTEGER PRIMARY KEY ON CONFLICT ROLLBACK, y);
488 INSERT INTO t1 VALUES(1,2);
489 INSERT INTO t2 VALUES(-99,100);
490 INSERT INTO t2 VALUES(1,3);
495 INSERT INTO t1 VALUES(2,3);
496 INSERT INTO t1 SELECT * FROM t2;
498 } {1 {UNIQUE constraint failed: t1.a}}
499 do_test insert4-8.10 {
501 } {1 {cannot commit - no transaction is active}}
502 do_test insert4-8.11 {
508 do_test insert4-8.21 {
510 DROP TABLE IF EXISTS t1;
511 DROP TABLE IF EXISTS t2;
512 CREATE TABLE t1(a INTEGER PRIMARY KEY ON CONFLICT REPLACE, b);
513 CREATE TABLE t2(x INTEGER PRIMARY KEY ON CONFLICT REPLACE, y);
514 INSERT INTO t2 VALUES(1,3);
515 INSERT INTO t1 SELECT * FROM t2;
519 do_test insert4-8.22 {
521 DROP TABLE IF EXISTS t1;
522 DROP TABLE IF EXISTS t2;
523 CREATE TABLE t1(a INTEGER PRIMARY KEY ON CONFLICT IGNORE, b);
524 CREATE TABLE t2(x INTEGER PRIMARY KEY ON CONFLICT IGNORE, y);
525 INSERT INTO t2 VALUES(1,3);
526 INSERT INTO t1 SELECT * FROM t2;
530 do_test insert4-8.23 {
532 DROP TABLE IF EXISTS t1;
533 DROP TABLE IF EXISTS t2;
534 CREATE TABLE t1(a INTEGER PRIMARY KEY ON CONFLICT ABORT, b);
535 CREATE TABLE t2(x INTEGER PRIMARY KEY ON CONFLICT ABORT, y);
536 INSERT INTO t2 VALUES(1,3);
537 INSERT INTO t1 SELECT * FROM t2;
541 do_test insert4-8.24 {
543 DROP TABLE IF EXISTS t1;
544 DROP TABLE IF EXISTS t2;
545 CREATE TABLE t1(a INTEGER PRIMARY KEY ON CONFLICT FAIL, b);
546 CREATE TABLE t2(x INTEGER PRIMARY KEY ON CONFLICT FAIL, y);
547 INSERT INTO t2 VALUES(1,3);
548 INSERT INTO t1 SELECT * FROM t2;
552 do_test insert4-8.25 {
554 DROP TABLE IF EXISTS t1;
555 DROP TABLE IF EXISTS t2;
556 CREATE TABLE t1(a INTEGER PRIMARY KEY ON CONFLICT ROLLBACK, b);
557 CREATE TABLE t2(x INTEGER PRIMARY KEY ON CONFLICT ROLLBACK, y);
558 INSERT INTO t2 VALUES(1,3);
559 INSERT INTO t1 SELECT * FROM t2;
564 do_catchsql_test insert4-9.1 {
565 DROP TABLE IF EXISTS t1;
567 INSERT INTO t1(x) VALUES(5 COLLATE xyzzy) UNION SELECT 0;
568 } {1 {no such collation sequence: xyzzy}}
570 #-------------------------------------------------------------------------
571 # Check that running an integrity-check does not disable the xfer
572 # optimization for tables with CHECK constraints.
574 do_execsql_test 10.1 {
579 px INTEGER DEFAULT(0) CHECK(px IN(0, 1))
585 px INTEGER DEFAULT(0) CHECK(px IN(0, 1))
589 set sqlite3_xferopt_count 0
590 execsql { INSERT INTO x SELECT * FROM t8 }
591 set sqlite3_xferopt_count
595 execsql { PRAGMA integrity_check }
596 set sqlite3_xferopt_count 0
597 execsql { INSERT INTO x SELECT * FROM t8 }
598 set sqlite3_xferopt_count