From e7224a011bd2ee28ceab126b6d867ba7963260e7 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 4 Nov 2011 00:23:53 +0000 Subject: [PATCH] Make sure the INSERT INTO ... SELECT statement works correctly even when the destination table contains an INTEGER PRIMARY KEY ON CONFLICT... column. Ticket [676bc02b87176125]. FossilOrigin-Name: 6f9898db7ff0730cc03f561f9c32ef3dee7e5d81 --- manifest | 15 +++--- manifest.uuid | 2 +- src/insert.c | 3 +- test/insert4.test | 119 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 129 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 307b0c39c8..178b6147a5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Version\s3.7.9 -D 2011-11-01T00:52:41.132 +C Make\ssure\sthe\sINSERT\sINTO\s...\sSELECT\sstatement\sworks\scorrectly\seven\swhen\nthe\sdestination\stable\scontains\san\sINTEGER\sPRIMARY\sKEY\sON\sCONFLICT...\scolumn.\nTicket\s[676bc02b87176125]. +D 2011-11-04T00:23:53.875 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in a162fe39e249b8ed4a65ee947c30152786cfe897 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -142,7 +142,7 @@ F src/global.c e230227de13601714b29f9363028514aada5ae2f F src/hash.c 458488dcc159c301b8e7686280ab209f1fb915af F src/hash.h 2894c932d84d9f892d4b4023a75e501f83050970 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 -F src/insert.c ca18783512323f74aaf4ee74b46ffd75ec80d031 +F src/insert.c bfe25a1d333658bd6f79fded6581d8a6962ce272 F src/journal.c 552839e54d1bf76fb8f7abe51868b66acacf6a0e F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f F src/lempar.c 0ee69fca0be54cd93939df98d2aca4ca46f44416 @@ -525,7 +525,7 @@ F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7 F test/insert.test aef273dd1cee84cc92407469e6bd1b3cdcb76908 F test/insert2.test 4f3a04d168c728ed5ec2c88842e772606c7ce435 F test/insert3.test 1b7db95a03ad9c5013fdf7d6722b6cd66ee55e30 -F test/insert4.test 63ea672b0fc6d3a9a0ccee774a771510b1e684c4 +F test/insert4.test 03f1644c4f2393e26e6b12d105ce375811178ace F test/insert5.test 394f96728d1258f406fe5f5aeb0aaf29487c39a6 F test/intarray.test 066b7d7ac38d25bf96f87f1b017bfc687551cdd4 F test/interrupt.test 42e7cf98646fd9cb4a3b131a93ed3c50b9e149f1 @@ -974,8 +974,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 6635cd9a7714b681dd8aa96e90be462a40d10178 -R b059ff356abfc5b4524a9b548916f43e -T +sym-version-3.7.9 * +P c7c6050ef060877ebe77b41d959e9df13f8c9b5e +R 86847a1d583226c862e98772b444bf54 U drh -Z a9ecbb5c487c786a176874d979505217 +Z a5a032e1b2e9278ae9ce6bac983d1037 diff --git a/manifest.uuid b/manifest.uuid index ce12ac8420..27b9032fb9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c7c6050ef060877ebe77b41d959e9df13f8c9b5e \ No newline at end of file +6f9898db7ff0730cc03f561f9c32ef3dee7e5d81 \ No newline at end of file diff --git a/src/insert.c b/src/insert.c index 277a852cc7..72fba06efd 100644 --- a/src/insert.c +++ b/src/insert.c @@ -1639,7 +1639,8 @@ static int xferOptimization( } #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 */ diff --git a/test/insert4.test b/test/insert4.test index cb02b9dccb..8e316448c1 100644 --- a/test/insert4.test +++ b/test/insert4.test @@ -386,4 +386,123 @@ ifcapable foreignkey { } {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