DROP SCHEMA test_insert_update_010 CASCADE;
ERROR: schema "test_insert_update_010" does not exist
CREATE SCHEMA test_insert_update_010;
SET CURRENT_SCHEMA TO test_insert_update_010;
-- SET enable_upsert_to_merge=ON to test the upsert implemented by merge,
-- real upsert will be tested in specialized case.
SET enable_upsert_to_merge TO ON;
-- test t4 with one primary key with three columns
CREATE TABLE t4 (
col1 INT,
col2 INT DEFAULT 0,
col3 INT DEFAULT 1,
col4 TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
col5 BIGSERIAL,
PRIMARY KEY (col2, col3, col5)
) ;
NOTICE: CREATE TABLE will create implicit sequence "t4_col5_seq" for serial column "t4.col5"
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "t4_pkey" for table "t4"
--- should insert
INSERT INTO t4 VALUES (1) ON DUPLICATE KEY UPDATE col1 = 10;
INSERT INTO t4 VALUES (1) ON DUPLICATE KEY UPDATE col1 = 10;
INSERT INTO t4 VALUES (2, 2, 2) ON DUPLICATE KEY UPDATE col1 = 200;
INSERT INTO t4 VALUES (100, 100, 100, CURRENT_TIMESTAMP, 100) ON DUPLICATE KEY UPDATE col1 = 1000;
SELECT col1, col2, col3, col5 FROM t4 ORDER BY col5;
col1 | col2 | col3 | col5
------+------+------+------
1 | 0 | 1 | 1
1 | 0 | 1 | 2
2 | 2 | 2 | 3
100 | 100 | 100 | 100
(4 rows)
--- should update
INSERT INTO t4 VALUES (2, 2, 2, CURRENT_TIMESTAMP, 3) ON DUPLICATE KEY UPDATE col1 = 200;
INSERT INTO t4 VALUES (100, 100, 100, CURRENT_TIMESTAMP, 100) ON DUPLICATE KEY UPDATE col1 = 1000;
SELECT col1, col2, col3, col5 FROM t4 ORDER BY col5;
col1 | col2 | col3 | col5
------+------+------+------
1 | 0 | 1 | 1
1 | 0 | 1 | 2
200 | 2 | 2 | 3
1000 | 100 | 100 | 100
(4 rows)
--- error: duplicate key update on (x, x, 20)
--- this is because current version is not inplace update but merge,
--- so when the subquery contains multiple same values, it will cause duplicate insert failure.
SELECT col3, sum(col3) * 10 FROM t4 GROUP BY col3 ORDER BY 1, 2;
col3 | ?column?
------+----------
1 | 20
2 | 20
100 | 1000
(3 rows)
INSERT INTO t4 (col1, col5)
(SELECT col3, sum(col3) * 10 FROM t4 GROUP BY col3)
ON DUPLICATE KEY UPDATE col1 = 3;
ERROR: duplicate key value violates unique constraint "t4_pkey"
DETAIL: Key (col2, col3, col5)=(0, 1, 20) already exists.
-- test t5 with sequence or default column with volatile function in constaint index
CREATE TABLE t5 (
col1 INT,
col2 INT DEFAULT 1,
col3 BIGSERIAL,
-- col4 TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
col5 INTEGER(10, 5) DEFAULT RANDOM() + 1
) ;
NOTICE: CREATE TABLE will create implicit sequence "t5_col3_seq" for serial column "t5.col3"
-- test t5 with sequence column in constaint index
CREATE UNIQUE INDEX u_t5_index1 ON t5(col1, col3);
--- should insert
INSERT INTO t5 VALUES (1), (1), (1) ON DUPLICATE KEY UPDATE col2 = col3;
INSERT INTO t5 DEFAULT VALUES ON DUPLICATE KEY UPDATE col2 = col3;
SELECT * FROM t5 ORDER BY col3;
col1 | col2 | col3 | col5
------+------+------+---------
--? 1 | 1 | 1 | 1.58182
--? 1 | 1 | 2 | 1.00814
--? 1 | 1 | 3 | 1.50194
--? | 1 | 4 | 1.12955
(4 rows)
--- should update
INSERT INTO t5 (col1, col3) VALUES (1, 1), (1, 2), (1, 3) ON DUPLICATE KEY UPDATE col5 = col2, col2 = col3 * 10;
SELECT * FROM t5 WHERE col1 = 1 ORDER BY col3;
col1 | col2 | col3 | col5
------+------+------+---------
1 | 10 | 1 | 1.00000
1 | 20 | 2 | 1.00000
1 | 30 | 3 | 1.00000
(3 rows)
--- should some insert some update
INSERT INTO t5 (col1, col3) VALUES (2, 5), (2, 6);
SELECT col1, col2, col3 FROM t5 ORDER BY col3;
col1 | col2 | col3
------+------+------
1 | 10 | 1
1 | 20 | 2
1 | 30 | 3
| 1 | 4
2 | 1 | 5
2 | 1 | 6
(6 rows)
INSERT INTO t5 (col1) VALUES (2), (2), (2) ON DUPLICATE KEY UPDATE col2 = col3;
SELECT col1, col2, col3 FROM t5 ORDER BY col3;
col1 | col2 | col3
------+------+------
1 | 10 | 1
1 | 20 | 2
1 | 30 | 3
| 1 | 4
2 | 5 | 5
2 | 6 | 6
2 | 1 | 7
(7 rows)
--- should INSERT and sequence starting from 7
INSERT INTO t5 VALUES (2), (2);
SELECT col1, col2, col3 FROM t5 ORDER BY col3;
col1 | col2 | col3
------+------+------
1 | 10 | 1
1 | 20 | 2
1 | 30 | 3
| 1 | 4
2 | 5 | 5
2 | 6 | 6
2 | 1 | 7
2 | 1 | 8
2 | 1 | 9
(9 rows)
-- test with volatile function as default column in constraint index
TRUNCATE t5;
DROP INDEX u_t5_index1;
CREATE UNIQUE INDEX u_t5_index2 ON t5(col1, col5) WHERE col1 > 2;
--- should insert
INSERT INTO t5 VALUES (3), (3), (3) ON DUPLICATE KEY UPDATE col2 = col3;
INSERT INTO t5 (col1) VALUES (4), (4), (4) ON DUPLICATE KEY UPDATE col2 = col3;
SELECT * FROM t5 ORDER BY col3;
col1 | col2 | col3 | col5
------+------+------+---------
--? 3 | 1 | 10 | 1.24521
--? 3 | 1 | 11 | 1.80598
--? 3 | 1 | 12 | 1.86845
--? 4 | 1 | 13 | 1.65797
--? 4 | 1 | 14 | 1.07881
--? 4 | 1 | 15 | 1.69493
(6 rows)
--- should update
INSERT INTO t5 (col1, col5) SELECT col1, col5 FROM t5 where col1 = 3 ON DUPLICATE KEY UPDATE col2 = col5 * 100;
SELECT * FROM t5 ORDER BY col3;
col1 | col2 | col3 | col5
------+------+------+---------
--? 3 | 125 | 10 | 1.24521
--? 3 | 181 | 11 | 1.80598
--? 3 | 187 | 12 | 1.86845
--? 4 | 1 | 13 | 1.65797
--? 4 | 1 | 14 | 1.07881
--? 4 | 1 | 15 | 1.69493
(6 rows)
--- test subquery
---- should insert
INSERT INTO t5 (col1, col2) SELECT col1, col2 FROM t5 ON DUPLICATE KEY UPDATE col2 = col5 * 100;
SELECT * FROM t5 ORDER BY col3;
col1 | col2 | col3 | col5
------+------+------+---------
--? 3 | 167 | 10 | 1.67400
--? 3 | 132 | 11 | 1.31552
--? 3 | 129 | 12 | 1.29423
--? 4 | 1 | 13 | 1.44100
--? 4 | 1 | 14 | 1.37620
--? 4 | 1 | 15 | 1.51296
--? 4 | 1 | 16 | 1.37516
--? 4 | 1 | 17 | 1.21710
--? 4 | 1 | 18 | 1.50422
--? 3 | 132 | 19 | 1.30560
--? 3 | 167 | 20 | 1.62282
--? 3 | 129 | 21 | 1.76699
(12 rows)
---- should update
INSERT INTO t5 SELECT * FROM t5 ON DUPLICATE KEY UPDATE col2 = col5 * 1000;
SELECT * FROM t5 ORDER BY col3;
col1 | col2 | col3 | col5
------+------+------+---------
--? 3 | 1674 | 10 | 1.67400
--? 3 | 1316 | 11 | 1.31552
--? 3 | 1294 | 12 | 1.29423
--? 4 | 1441 | 13 | 1.44100
--? 4 | 1376 | 14 | 1.37620
--? 4 | 1513 | 15 | 1.51296
--? 4 | 1375 | 16 | 1.37516
--? 4 | 1217 | 17 | 1.21710
--? 4 | 1504 | 18 | 1.50422
--? 3 | 1306 | 19 | 1.30560
--? 3 | 1623 | 20 | 1.62282
--? 3 | 1767 | 21 | 1.76699
(12 rows)
-- test t6 with one more index
CREATE TABLE t6 (
col1 INT,
col2 INT DEFAULT 1,
col3 BIGSERIAL,
-- col4 TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
col5 INTEGER(10, 5) DEFAULT RANDOM(),
col6 INT,
col7 TEXT
) ;
NOTICE: CREATE TABLE will create implicit sequence "t6_col3_seq" for serial column "t6.col3"
ALTER TABLE t6 ADD PRIMARY KEY (col1, col3);
NOTICE: ALTER TABLE / ADD PRIMARY KEY will create implicit index "t6_pkey" for table "t6"
CREATE UNIQUE INDEX u_t6_index1 ON t6(col1, col5, col6);
INSERT INTO t6 (col1) VALUES (1), (2), (3), (4), (5);
SELECT col1, col2, col3, col6, col7 FROM t6 ORDER BY col3;
col1 | col2 | col3 | col6 | col7
------+------+------+------+------
1 | 1 | 1 | |
2 | 1 | 2 | |
3 | 1 | 3 | |
4 | 1 | 4 | |
5 | 1 | 5 | |
(5 rows)
--- should insert
INSERT INTO t6 (col1) VALUES (1), (2), (3), (4), (5) ON DUPLICATE KEY UPDATE col6 = power(col1, col2);
SELECT col1, col2, col3, col6, col7 FROM t6 ORDER BY col3;
col1 | col2 | col3 | col6 | col7
------+------+------+------+------
1 | 1 | 1 | |
2 | 1 | 2 | |
3 | 1 | 3 | |
4 | 1 | 4 | |
5 | 1 | 5 | |
1 | 1 | 6 | |
2 | 1 | 7 | |
3 | 1 | 8 | |
4 | 1 | 9 | |
5 | 1 | 10 | |
(10 rows)
--- should update because primary key matches
INSERT INTO t6 (col1, col3) VALUES (6, 11), (6, 12);
SELECT col1, col2, col3, col6, col7 FROM t6 WHERE col1 = 6 ORDER BY col3;
col1 | col2 | col3 | col6 | col7
------+------+------+------+------
6 | 1 | 11 | |
6 | 1 | 12 | |
(2 rows)
INSERT INTO t6 (col1) VALUES (6), (6), (6) ON DUPLICATE KEY UPDATE col2 = col1 + col3, col6 = col2 * 10;
SELECT col1, col2, col3, col6, col7 FROM t6 WHERE col1 = 6 ORDER BY col3;
col1 | col2 | col3 | col6 | col7
------+------+------+------+------
6 | 17 | 11 | 10 |
6 | 18 | 12 | 10 |
6 | 1 | 13 | |
(3 rows)
--- should update for those col6 is not null bacause they will match the unique index,
--- and insert for those col6 is null because the unique index containing null never matches,
--- also primary key will not match
--- be ware the sequence column of the inserted row will jump n step, where n is the count of the not null rows,
--- because those sequence have to be generated during the unique index join stage.
INSERT INTO t6 (col1, col5, col6)
(SELECT col1, col5, col6 FROM t6 WHERE col1 = 6)
ON DUPLICATE KEY UPDATE
col7 = col2 + 1;
SELECT col1, col2, col3, col6, col7 FROM t6 WHERE col1 = 6 ORDER BY col1, col3, col6, col7;
col1 | col2 | col3 | col6 | col7
------+------+------+------+------
6 | 17 | 11 | 10 | 18
6 | 18 | 12 | 10 | 19
6 | 1 | 13 | |
6 | 1 | 16 | |
(4 rows)
--- should update because unique index and primary key both match
INSERT INTO t6 (col1, col3, col5, col6)
(SELECT col1, col3, col5, col6 FROM t6 WHERE col1 = 6 AND col6 IS NOT NULL)
ON DUPLICATE KEY UPDATE
col7 = col7 * 10;
SELECT col1, col2, col3, col6, col7 FROM t6 WHERE col1 = 6 ORDER BY col1, col3, col6, col7;
col1 | col2 | col3 | col6 | col7
------+------+------+------+------
6 | 17 | 11 | 10 | 180
6 | 18 | 12 | 10 | 190
6 | 1 | 13 | |
6 | 1 | 16 | |
(4 rows)
--- insert when col3 = 17 because constaints does not match,
--- but update when col3 = 18 because 18 has been inserted and will cause a match
INSERT INTO t6 (col1, col3, col5, col6) VALUES (7, 18, 100, 100);
SELECT * FROM t6 WHERE col3 > 16 ORDER BY col1, col3, col6, col7;
col1 | col2 | col3 | col5 | col6 | col7
------+------+------+-----------+------+------
7 | 1 | 18 | 100.00000 | 100 |
(1 row)
INSERT INTO t6 (col1, col5, col6) VALUES (7, 10, 10), (7, 100, 100) ON DUPLICATE KEY UPDATE
col7 = col3 * 100;
SELECT * FROM t6 WHERE col1 = 7 ORDER BY col1, col3, col6, col7;
col1 | col2 | col3 | col5 | col6 | col7
------+------+------+-----------+------+------
7 | 1 | 17 | 10.00000 | 10 |
7 | 1 | 18 | 100.00000 | 100 | 1800
(2 rows)
DROP SCHEMA test_insert_update_010 CASCADE;
NOTICE: drop cascades to 3 other objects
DETAIL: drop cascades to table t4
drop cascades to table t5
drop cascades to table t6