Index: src/insert.c ================================================================== --- src/insert.c +++ src/insert.c @@ -1637,11 +1637,12 @@ if( pDest->tabFlags & TF_Virtual ){ return 0; /* tab1 must not be a virtual table */ } #endif if( onError==OE_Default ){ - onError = OE_Abort; + if( pDest->iPKey>=0 ) onError = pDest->keyConf; + if( onError==OE_Default ) onError = OE_Abort; } if( onError!=OE_Abort && onError!=OE_Rollback ){ return 0; /* Cannot do OR REPLACE or OR IGNORE or OR FAIL */ } assert(pSelect->pSrc); /* allocated even if there is no FROM clause */ Index: test/insert4.test ================================================================== --- test/insert4.test +++ test/insert4.test @@ -383,7 +383,126 @@ } {123} do_test insert4-7.8 { set ::sqlite3_xferopt_count } {1} } + +# Ticket [676bc02b87176125635cb174d110b431581912bb] +# Make sure INTEGER PRIMARY KEY ON CONFLICT ... works with the xfer +# optimization. +# +do_test insert4-8.1 { + execsql { + DROP TABLE IF EXISTS t1; + DROP TABLE IF EXISTS t2; + CREATE TABLE t1(a INTEGER PRIMARY KEY ON CONFLICT REPLACE, b); + CREATE TABLE t2(x INTEGER PRIMARY KEY ON CONFLICT REPLACE, y); + INSERT INTO t1 VALUES(1,2); + INSERT INTO t2 VALUES(1,3); + INSERT INTO t1 SELECT * FROM t2; + SELECT * FROM t1; + } +} {1 3} +do_test insert4-8.2 { + execsql { + DROP TABLE IF EXISTS t1; + DROP TABLE IF EXISTS t2; + CREATE TABLE t1(a INTEGER PRIMARY KEY ON CONFLICT REPLACE, b); + CREATE TABLE t2(x, y); + INSERT INTO t1 VALUES(1,2); + INSERT INTO t2 VALUES(1,3); + INSERT INTO t1 SELECT * FROM t2; + SELECT * FROM t1; + } +} {1 3} +do_test insert4-8.3 { + execsql { + DROP TABLE IF EXISTS t1; + DROP TABLE IF EXISTS t2; + CREATE TABLE t1(a INTEGER PRIMARY KEY ON CONFLICT IGNORE, b); + CREATE TABLE t2(x INTEGER PRIMARY KEY ON CONFLICT IGNORE, y); + INSERT INTO t1 VALUES(1,2); + INSERT INTO t2 VALUES(1,3); + INSERT INTO t1 SELECT * FROM t2; + SELECT * FROM t1; + } +} {1 2} +do_test insert4-8.4 { + execsql { + DROP TABLE IF EXISTS t1; + DROP TABLE IF EXISTS t2; + CREATE TABLE t1(a INTEGER PRIMARY KEY ON CONFLICT IGNORE, b); + CREATE TABLE t2(x, y); + INSERT INTO t1 VALUES(1,2); + INSERT INTO t2 VALUES(1,3); + INSERT INTO t1 SELECT * FROM t2; + SELECT * FROM t1; + } +} {1 2} +do_test insert4-8.5 { + execsql { + DROP TABLE IF EXISTS t1; + DROP TABLE IF EXISTS t2; + CREATE TABLE t1(a INTEGER PRIMARY KEY ON CONFLICT FAIL, b); + CREATE TABLE t2(x INTEGER PRIMARY KEY ON CONFLICT FAIL, y); + INSERT INTO t1 VALUES(1,2); + INSERT INTO t2 VALUES(-99,100); + INSERT INTO t2 VALUES(1,3); + SELECT * FROM t1; + } + catchsql { + INSERT INTO t1 SELECT * FROM t2; + } +} {1 {PRIMARY KEY must be unique}} +do_test insert4-8.6 { + execsql { + SELECT * FROM t1; + } +} {-99 100 1 2} +do_test insert4-8.7 { + execsql { + DROP TABLE IF EXISTS t1; + DROP TABLE IF EXISTS t2; + CREATE TABLE t1(a INTEGER PRIMARY KEY ON CONFLICT ABORT, b); + CREATE TABLE t2(x INTEGER PRIMARY KEY ON CONFLICT ABORT, y); + INSERT INTO t1 VALUES(1,2); + INSERT INTO t2 VALUES(-99,100); + INSERT INTO t2 VALUES(1,3); + SELECT * FROM t1; + } + catchsql { + INSERT INTO t1 SELECT * FROM t2; + } +} {1 {PRIMARY KEY must be unique}} +do_test insert4-8.8 { + execsql { + SELECT * FROM t1; + } +} {1 2} +do_test insert4-8.9 { + execsql { + DROP TABLE IF EXISTS t1; + DROP TABLE IF EXISTS t2; + CREATE TABLE t1(a INTEGER PRIMARY KEY ON CONFLICT ROLLBACK, b); + CREATE TABLE t2(x INTEGER PRIMARY KEY ON CONFLICT ROLLBACK, y); + INSERT INTO t1 VALUES(1,2); + INSERT INTO t2 VALUES(-99,100); + INSERT INTO t2 VALUES(1,3); + SELECT * FROM t1; + } + catchsql { + BEGIN; + INSERT INTO t1 VALUES(2,3); + INSERT INTO t1 SELECT * FROM t2; + } +} {1 {PRIMARY KEY must be unique}} +do_test insert4-8.10 { + catchsql {COMMIT} +} {1 {cannot commit - no transaction is active}} +do_test insert4-8.11 { + execsql { + SELECT * FROM t1; + } +} {1 2} + finish_test