forked from huawei/openGauss-server
UPSERT test case
This commit is contained in:
parent
ec6bdc4f11
commit
ca5f135273
|
|
@ -2,6 +2,9 @@ DROP SCHEMA test_insert_update_001 CASCADE;
|
|||
ERROR: schema "test_insert_update_001" does not exist
|
||||
CREATE SCHEMA test_insert_update_001;
|
||||
SET CURRENT_SCHEMA TO test_insert_update_001;
|
||||
-- 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 description
|
||||
\h INSERT
|
||||
Command: INSERT
|
||||
|
|
|
|||
|
|
@ -2,6 +2,9 @@ DROP SCHEMA test_insert_update_002 CASCADE;
|
|||
ERROR: schema "test_insert_update_002" does not exist
|
||||
CREATE SCHEMA test_insert_update_002;
|
||||
SET CURRENT_SCHEMA TO test_insert_update_002;
|
||||
-- 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 t1 with no index
|
||||
CREATE TABLE t1 (
|
||||
col1 INT,
|
||||
|
|
|
|||
|
|
@ -2,6 +2,9 @@ DROP SCHEMA test_insert_update_003 CASCADE;
|
|||
ERROR: schema "test_insert_update_003" does not exist
|
||||
CREATE SCHEMA test_insert_update_003;
|
||||
SET CURRENT_SCHEMA TO test_insert_update_003;
|
||||
-- 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,
|
||||
|
|
|
|||
|
|
@ -4,6 +4,9 @@
|
|||
-- initial
|
||||
CREATE SCHEMA test_insert_update_008;
|
||||
SET current_schema = test_insert_update_008;
|
||||
-- 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;
|
||||
CREATE TABLE products_base
|
||||
(
|
||||
product_id INTEGER DEFAULT 0,
|
||||
|
|
@ -58,9 +61,9 @@ EXPLAIN (VERBOSE on, COSTS off)
|
|||
INSERT INTO products_row
|
||||
SELECT product_id, product_name, category, total FROM newproducts_row
|
||||
ON DUPLICATE KEY UPDATE
|
||||
product_name = __unnamed_subquery_source__.product_name,
|
||||
category = __unnamed_subquery_source__.category,
|
||||
total = __unnamed_subquery_source__.total;
|
||||
product_name = excluded.product_name,
|
||||
category = excluded.category,
|
||||
total = excluded.total;
|
||||
QUERY PLAN
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
Merge on test_insert_update_008.products_row
|
||||
|
|
@ -84,9 +87,9 @@ INSERT INTO products_row
|
|||
FROM newproducts_row, products_row
|
||||
WHERE products_row.total + newproducts_row.total < 1000
|
||||
ON DUPLICATE KEY UPDATE
|
||||
product_name = __unnamed_subquery_source__.product_name,
|
||||
category = __unnamed_subquery_source__.category,
|
||||
total = __unnamed_subquery_source__.total;
|
||||
product_name = excluded.product_name,
|
||||
category = excluded.category,
|
||||
total = excluded.total;
|
||||
QUERY PLAN
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
Merge on test_insert_update_008.products_row
|
||||
|
|
@ -113,9 +116,9 @@ INSERT INTO products_row
|
|||
SELECT product_id, product_name, category, total
|
||||
FROM newproducts_row WHERE product_id IS NOT NULL AND product_name IS NOT NULL
|
||||
ON DUPLICATE KEY UPDATE
|
||||
product_name = __unnamed_subquery_source__.product_name,
|
||||
category = __unnamed_subquery_source__.category,
|
||||
total = __unnamed_subquery_source__.total;
|
||||
product_name = excluded.product_name,
|
||||
category = excluded.category,
|
||||
total = excluded.total;
|
||||
QUERY PLAN
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
Merge on test_insert_update_008.products_row
|
||||
|
|
@ -137,9 +140,9 @@ EXPLAIN (ANALYZE on, COSTS off, TIMING off)
|
|||
INSERT INTO products_row
|
||||
SELECT product_id, product_name, category, total FROM newproducts_row
|
||||
ON DUPLICATE KEY UPDATE
|
||||
product_name = __unnamed_subquery_source__.product_name,
|
||||
category = __unnamed_subquery_source__.category,
|
||||
total = __unnamed_subquery_source__.total;
|
||||
product_name = excluded.product_name,
|
||||
category = excluded.category,
|
||||
total = excluded.total;
|
||||
QUERY PLAN
|
||||
---------------------------------------------------------------------------
|
||||
Merge on products_row (actual rows=4 loops=1)
|
||||
|
|
@ -162,9 +165,9 @@ EXPLAIN PERFORMANCE
|
|||
INSERT INTO products_row
|
||||
SELECT product_id, product_name, category, total FROM newproducts_row
|
||||
ON DUPLICATE KEY UPDATE
|
||||
product_name = __unnamed_subquery_source__.product_name,
|
||||
category = __unnamed_subquery_source__.category,
|
||||
total = __unnamed_subquery_source__.total;
|
||||
product_name = excluded.product_name,
|
||||
category = excluded.category,
|
||||
total = excluded.total;
|
||||
ROLLBACK;
|
||||
\o
|
||||
-- explain analyze
|
||||
|
|
@ -173,9 +176,9 @@ EXPLAIN (ANALYZE on, COSTS off, TIMING off)
|
|||
INSERT INTO products_row
|
||||
SELECT product_id, product_name, category, total FROM newproducts_row
|
||||
ON DUPLICATE KEY UPDATE
|
||||
product_name = __unnamed_subquery_source__.product_name,
|
||||
category = __unnamed_subquery_source__.category,
|
||||
total = __unnamed_subquery_source__.total;
|
||||
product_name = excluded.product_name,
|
||||
category = excluded.category,
|
||||
total = excluded.total;
|
||||
QUERY PLAN
|
||||
---------------------------------------------------------------------------
|
||||
Merge on products_row (actual rows=4 loops=1)
|
||||
|
|
@ -198,9 +201,9 @@ EXPLAIN (VERBOSE on, COSTS off)
|
|||
INSERT INTO products_row
|
||||
SELECT product_id, product_name, category, total FROM newproducts_row
|
||||
ON DUPLICATE KEY UPDATE
|
||||
product_name = __unnamed_subquery_source__.product_name,
|
||||
category = __unnamed_subquery_source__.category,
|
||||
total = __unnamed_subquery_source__.total;
|
||||
product_name = excluded.product_name,
|
||||
category = excluded.category,
|
||||
total = excluded.total;
|
||||
QUERY PLAN
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
Merge on test_insert_update_008.products_row
|
||||
|
|
@ -221,9 +224,9 @@ EXPLAIN (ANALYZE on, COSTS off, TIMING off)
|
|||
INSERT INTO products_row
|
||||
SELECT product_id, product_name, category, total FROM newproducts_row
|
||||
ON DUPLICATE KEY UPDATE
|
||||
product_name = __unnamed_subquery_source__.product_name,
|
||||
category = __unnamed_subquery_source__.category,
|
||||
total = __unnamed_subquery_source__.total;
|
||||
product_name = excluded.product_name,
|
||||
category = excluded.category,
|
||||
total = excluded.total;
|
||||
QUERY PLAN
|
||||
---------------------------------------------------------------------------
|
||||
Merge on products_row (actual rows=4 loops=1)
|
||||
|
|
@ -245,9 +248,9 @@ EXPLAIN (ANALYZE on, COSTS off, TIMING off)
|
|||
INSERT INTO products_row
|
||||
SELECT product_id, product_name, category, total FROM newproducts_row
|
||||
ON DUPLICATE KEY UPDATE
|
||||
product_name = __unnamed_subquery_source__.product_name,
|
||||
category = __unnamed_subquery_source__.category,
|
||||
total = __unnamed_subquery_source__.total;
|
||||
product_name = excluded.product_name,
|
||||
category = excluded.category,
|
||||
total = excluded.total;
|
||||
QUERY PLAN
|
||||
---------------------------------------------------------------------------
|
||||
Merge on products_row (actual rows=4 loops=1)
|
||||
|
|
@ -270,9 +273,9 @@ EXPLAIN PERFORMANCE
|
|||
INSERT INTO products_row
|
||||
SELECT product_id, product_name, category, total FROM newproducts_row
|
||||
ON DUPLICATE KEY UPDATE
|
||||
product_name = __unnamed_subquery_source__.product_name,
|
||||
category = __unnamed_subquery_source__.category,
|
||||
total = __unnamed_subquery_source__.total;
|
||||
product_name = excluded.product_name,
|
||||
category = excluded.category,
|
||||
total = excluded.total;
|
||||
ROLLBACK;
|
||||
SET explain_perf_mode = run;
|
||||
BEGIN;
|
||||
|
|
@ -280,9 +283,9 @@ EXPLAIN PERFORMANCE
|
|||
INSERT INTO products_row
|
||||
SELECT product_id, product_name, category, total FROM newproducts_row
|
||||
ON DUPLICATE KEY UPDATE
|
||||
product_name = __unnamed_subquery_source__.product_name,
|
||||
category = __unnamed_subquery_source__.category,
|
||||
total = __unnamed_subquery_source__.total;
|
||||
product_name = excluded.product_name,
|
||||
category = excluded.category,
|
||||
total = excluded.total;
|
||||
ROLLBACK;
|
||||
SET explain_perf_mode = summary;
|
||||
BEGIN;
|
||||
|
|
@ -290,9 +293,9 @@ EXPLAIN PERFORMANCE
|
|||
INSERT INTO products_row
|
||||
SELECT product_id, product_name, category, total FROM newproducts_row
|
||||
ON DUPLICATE KEY UPDATE
|
||||
product_name = __unnamed_subquery_source__.product_name,
|
||||
category = __unnamed_subquery_source__.category,
|
||||
total = __unnamed_subquery_source__.total;
|
||||
product_name = excluded.product_name,
|
||||
category = excluded.category,
|
||||
total = excluded.total;
|
||||
ROLLBACK;
|
||||
\o
|
||||
CREATE TABLE item
|
||||
|
|
|
|||
|
|
@ -3,6 +3,9 @@ ERROR: schema "test_insert_update_009" does not exist
|
|||
CREATE SCHEMA test_insert_update_009;
|
||||
SET CURRENT_SCHEMA TO test_insert_update_009;
|
||||
SET enable_light_proxy=off;
|
||||
-- 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 t1 with no index
|
||||
CREATE TABLE t1 (
|
||||
col1 INT,
|
||||
|
|
|
|||
|
|
@ -2,6 +2,9 @@ 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,
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
-- 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;
|
||||
SELECT name, setting FROM pg_settings WHERE name LIKE 'enable%' ORDER BY name;
|
||||
name | setting
|
||||
-----------------------------------+---------
|
||||
|
|
@ -74,12 +77,13 @@ SELECT name, setting FROM pg_settings WHERE name LIKE 'enable%' ORDER BY name;
|
|||
enable_thread_pool | off
|
||||
enable_tidscan | on
|
||||
enable_upgrade_merge_lock_mode | off
|
||||
enable_upsert_to_merge | on
|
||||
enable_user_metric_persistent | on
|
||||
enable_valuepartition_pruning | on
|
||||
enable_vector_engine | on
|
||||
enable_wdr_snapshot | off
|
||||
enable_xlog_prune | on
|
||||
(78 rows)
|
||||
(79 rows)
|
||||
|
||||
CREATE TABLE foo2(fooid int, f2 int);
|
||||
INSERT INTO foo2 VALUES(1, 11);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,515 @@
|
|||
DROP SCHEMA test_upsert_001 CASCADE;
|
||||
ERROR: schema "test_upsert_001" does not exist
|
||||
CREATE SCHEMA test_upsert_001;
|
||||
SET CURRENT_SCHEMA TO test_upsert_001;
|
||||
-- enable_upsert_to_merge must is off, or upsert will be translated to merge.
|
||||
SET enable_upsert_to_merge TO OFF;
|
||||
-- test description
|
||||
\h INSERT
|
||||
Command: INSERT
|
||||
Description: create new rows in a table
|
||||
Syntax:
|
||||
[ WITH [ RECURSIVE ] with_query [, ...] ]
|
||||
INSERT INTO table_name [ ( column_name [, ...] ) ]
|
||||
{ DEFAULT VALUES | VALUES {( { expression | DEFAULT } [, ...] ) }[, ...] | query }
|
||||
[ ON DUPLICATE KEY UPDATE { column_name = { expression | DEFAULT } } [, ...] ]
|
||||
[ RETURNING {* | {output_expression [ [ AS ] output_name ] }[, ...]} ];
|
||||
|
||||
-- test permission
|
||||
--- test with no sequence column
|
||||
CREATE TABLE t00 (col1 INT DEFAULT 1 PRIMARY KEY, col2 INT);
|
||||
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "t00_pkey" for table "t00"
|
||||
CREATE USER upsert_tester PASSWORD '123456@cc';
|
||||
GRANT ALL PRIVILEGES ON SCHEMA test_upsert_001 TO upsert_tester;
|
||||
SET SESSION SESSION AUTHORIZATION upsert_tester PASSWORD '123456@cc';
|
||||
INSERT INTO test_upsert_001.t00 VALUES(1) ON DUPLICATE KEY UPDATE col2 = 5;
|
||||
ERROR: permission denied for relation t00
|
||||
RESET SESSION AUTHORIZATION;
|
||||
---- error: only have INSERT permission
|
||||
GRANT INSERT ON test_upsert_001.t00 TO upsert_tester;
|
||||
SET SESSION SESSION AUTHORIZATION upsert_tester PASSWORD '123456@cc';
|
||||
INSERT INTO test_upsert_001.t00 VALUES(1) ON DUPLICATE KEY UPDATE col2 = 5;
|
||||
ERROR: permission denied for relation t00
|
||||
RESET SESSION AUTHORIZATION;
|
||||
---- success: have INSERT UPDATE permission
|
||||
GRANT INSERT, UPDATE ON test_upsert_001.t00 TO upsert_tester;
|
||||
SET SESSION SESSION AUTHORIZATION upsert_tester PASSWORD '123456@cc';
|
||||
INSERT INTO test_upsert_001.t00 VALUES(1) ON DUPLICATE KEY UPDATE col2 = 5;
|
||||
RESET SESSION AUTHORIZATION;
|
||||
--- have SELECT INSERT UPDATE permission
|
||||
GRANT SELECT, INSERT, UPDATE ON test_upsert_001.t00 TO upsert_tester;
|
||||
SET SESSION SESSION AUTHORIZATION upsert_tester PASSWORD '123456@cc';
|
||||
INSERT INTO test_upsert_001.t00 VALUES(1) ON DUPLICATE KEY UPDATE col2 = 5;
|
||||
INSERT INTO test_upsert_001.t00 VALUES(1) ON DUPLICATE KEY UPDATE col3 = 5;
|
||||
ERROR: column "col3" of relation "t00" does not exist
|
||||
LINE 1: ...t_upsert_001.t00 VALUES(1) ON DUPLICATE KEY UPDATE col3 = 5;
|
||||
^
|
||||
RESET SESSION AUTHORIZATION;
|
||||
--- test with sequnce column
|
||||
CREATE TABLE t01 (col1 INT , col2 BIGSERIAL PRIMARY KEY, col3 INT) ;
|
||||
NOTICE: CREATE TABLE will create implicit sequence "t01_col2_seq" for serial column "t01.col2"
|
||||
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "t01_pkey" for table "t01"
|
||||
---- error: don't have UPDATE permission on sequence table.
|
||||
GRANT SELECT, INSERT, UPDATE ON test_upsert_001.t01 TO upsert_tester;
|
||||
SET SESSION SESSION AUTHORIZATION upsert_tester PASSWORD '123456@cc';
|
||||
INSERT INTO test_upsert_001.t01 VALUES(1) ON DUPLICATE KEY UPDATE col3 = 5;
|
||||
ERROR: permission denied for sequence t01_col2_seq
|
||||
CONTEXT: referenced column: col2
|
||||
RESET SESSION AUTHORIZATION;
|
||||
---- have SELECT INSERT UPDATE permission on target relation, and UPDATE permission on sequence table.
|
||||
GRANT UPDATE ON test_upsert_001.t01_col2_seq TO upsert_tester;
|
||||
SET SESSION SESSION AUTHORIZATION upsert_tester PASSWORD '123456@cc';
|
||||
INSERT INTO test_upsert_001.t01 VALUES(1) ON DUPLICATE KEY UPDATE col3 = 5;
|
||||
INSERT INTO test_upsert_001.t01 VALUES(1) ON DUPLICATE KEY UPDATE col3 = 5;
|
||||
RESET SESSION AUTHORIZATION;
|
||||
-- test ommit INSERT target column
|
||||
CREATE TABLE t02 (col1 INT DEFAULT 1 PRIMARY KEY, col2 INT, col3 INT);
|
||||
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "t02_pkey" for table "t02"
|
||||
INSERT INTO t02 VALUES(1, 2, 3) ON DUPLICATE KEY UPDATE col2 = 20;
|
||||
SELECT * FROM t02 ORDER BY 1, 2;
|
||||
col1 | col2 | col3
|
||||
------+------+------
|
||||
1 | 2 | 3
|
||||
(1 row)
|
||||
|
||||
INSERT INTO t02 VALUES(1, 2, 3) ON DUPLICATE KEY UPDATE col2 = 20;
|
||||
SELECT * FROM t02 ORDER BY 1, 2;
|
||||
col1 | col2 | col3
|
||||
------+------+------
|
||||
1 | 20 | 3
|
||||
(1 row)
|
||||
|
||||
ALTER TABLE t02 DROP COLUMN col2;
|
||||
ALTER TABLE t02 ADD COLUMN col4 INT;
|
||||
INSERT INTO t02 VALUES(1, 2, 3) ON DUPLICATE KEY UPDATE col4 = 40;
|
||||
SELECT * FROM t02 ORDER BY 1, 2;
|
||||
col1 | col3 | col4
|
||||
------+------+------
|
||||
1 | 3 | 40
|
||||
(1 row)
|
||||
|
||||
INSERT INTO t02 VALUES(2, 3, 4) ON DUPLICATE KEY UPDATE col4 = 40;
|
||||
SELECT * FROM t02 ORDER BY 1, 2;
|
||||
col1 | col3 | col4
|
||||
------+------+------
|
||||
1 | 3 | 40
|
||||
2 | 3 | 4
|
||||
(2 rows)
|
||||
|
||||
INSERT INTO t02 VALUES(2, 3, 4) ON DUPLICATE KEY UPDATE col4 = 40;
|
||||
SELECT * FROM t02 ORDER BY 1, 2;
|
||||
col1 | col3 | col4
|
||||
------+------+------
|
||||
1 | 3 | 40
|
||||
2 | 3 | 40
|
||||
(2 rows)
|
||||
|
||||
-- test restriction
|
||||
--- test replication table
|
||||
CREATE TABLE t03 (col1 int PRIMARY KEY, col2 INT, col3 smallserial) ;
|
||||
NOTICE: CREATE TABLE will create implicit sequence "t03_col3_seq" for serial column "t03.col3"
|
||||
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "t03_pkey" for table "t03"
|
||||
--- error: not allowed volatile function as default value
|
||||
INSERT INTO t03(col2) VALUES(1) ON DUPLICATE KEY UPDATE col2 = 100;
|
||||
ERROR: null value in column "col1" violates not-null constraint
|
||||
DETAIL: Failing row contains (null, 1, 1).
|
||||
ALTER TABLE t03 DROP COLUMN col3;
|
||||
--- error: primary key are not allowed to update
|
||||
INSERT INTO t03 VALUES(1) ON DUPLICATE KEY UPDATE col1 = 1;
|
||||
ERROR: INSERT ON DUPLICATE KEY UPDATE don't allow update on primary key or unique key.
|
||||
--- error: clause other than VALUSES are not allowed to use
|
||||
INSERT INTO t03 SELECT * FROM t03 ON DUPLICATE KEY UPDATE col2 = 1;
|
||||
--- success: expression index are supported
|
||||
CREATE UNIQUE INDEX u_expr_index ON t03 USING btree (abs(col1));
|
||||
INSERT INTO t03 VALUES(-10, 10) ON DUPLICATE KEY UPDATE col2 = 20;
|
||||
DROP INDEX u_expr_index;
|
||||
-- test with stream operator on
|
||||
INSERT INTO t03 VALUES(1) ON DUPLICATE KEY UPDATE col2 = 100;
|
||||
SELECT * FROM t03;
|
||||
col1 | col2
|
||||
------+------
|
||||
-10 | 10
|
||||
1 |
|
||||
(2 rows)
|
||||
|
||||
INSERT INTO t03 VALUES(1) ON DUPLICATE KEY UPDATE col2 = 100;
|
||||
SELECT * FROM t03;
|
||||
col1 | col2
|
||||
------+------
|
||||
-10 | 10
|
||||
1 | 100
|
||||
(2 rows)
|
||||
|
||||
SELECT * FROM t03;
|
||||
col1 | col2
|
||||
------+------
|
||||
-10 | 10
|
||||
1 | 100
|
||||
(2 rows)
|
||||
|
||||
--- test PBE
|
||||
PREPARE p1 AS INSERT INTO t03 VALUES($1, $2) ON DUPLICATE KEY UPDATE col2 = $1*100;
|
||||
EXECUTE p1(5, 50);
|
||||
SELECT * FROM t03 WHERE col1 = 5;
|
||||
col1 | col2
|
||||
------+------
|
||||
5 | 50
|
||||
(1 row)
|
||||
|
||||
EXECUTE p1(5, 50);
|
||||
SELECT * FROM t03 WHERE col1 = 5;
|
||||
col1 | col2
|
||||
------+------
|
||||
5 | 500
|
||||
(1 row)
|
||||
|
||||
DELETE t03 WHERE col1 = 5;
|
||||
---- test with primary key
|
||||
INSERT INTO t03 VALUES(2) ON DUPLICATE KEY UPDATE col2 = 200;
|
||||
SELECT * FROM t03;
|
||||
col1 | col2
|
||||
------+------
|
||||
-10 | 10
|
||||
1 | 100
|
||||
2 |
|
||||
(3 rows)
|
||||
|
||||
INSERT INTO t03 VALUES(2) ON DUPLICATE KEY UPDATE col2 = 200;
|
||||
SELECT * FROM t03;
|
||||
col1 | col2
|
||||
------+------
|
||||
-10 | 10
|
||||
1 | 100
|
||||
2 | 200
|
||||
(3 rows)
|
||||
|
||||
SELECT * FROM t03;
|
||||
col1 | col2
|
||||
------+------
|
||||
-10 | 10
|
||||
1 | 100
|
||||
2 | 200
|
||||
(3 rows)
|
||||
|
||||
---- test with unique key without NOT NULL constraint
|
||||
ALTER TABLE t03 DROP CONSTRAINT t03_pkey;
|
||||
ALTER TABLE t03 ADD COLUMN col3 INT;
|
||||
CREATE UNIQUE INDEX ON t03 (col1, col3);
|
||||
---- unique constraints might contain NULL, depends on the plan
|
||||
----- for cn light and fqs, it can be done
|
||||
INSERT INTO t03 VALUES(3) ON DUPLICATE KEY UPDATE col2 = 300;
|
||||
----- for stream or pgxc it can not be done
|
||||
INSERT INTO t03 VALUES(3) ON DUPLICATE KEY UPDATE col2 = 300;
|
||||
---- test with unique key with NOT NULL constraint, should success
|
||||
CREATE UNIQUE INDEX ON t03 (col1);
|
||||
ERROR: could not create unique index "t03_col1_idx"
|
||||
DETAIL: Key (col1)=(3) is duplicated.
|
||||
INSERT INTO t03 VALUES(3) ON DUPLICATE KEY UPDATE col2 = 300;
|
||||
SELECT * FROM t03;
|
||||
col1 | col2 | col3
|
||||
------+------+------
|
||||
-10 | 10 |
|
||||
1 | 100 |
|
||||
2 | 200 |
|
||||
3 | |
|
||||
3 | |
|
||||
3 | |
|
||||
(6 rows)
|
||||
|
||||
INSERT INTO t03 VALUES(3) ON DUPLICATE KEY UPDATE col2 = 300;
|
||||
SELECT * FROM t03;
|
||||
col1 | col2 | col3
|
||||
------+------+------
|
||||
-10 | 10 |
|
||||
1 | 100 |
|
||||
2 | 200 |
|
||||
3 | |
|
||||
3 | |
|
||||
3 | |
|
||||
3 | |
|
||||
(7 rows)
|
||||
|
||||
SELECT * FROM t03;
|
||||
col1 | col2 | col3
|
||||
------+------+------
|
||||
-10 | 10 |
|
||||
1 | 100 |
|
||||
2 | 200 |
|
||||
3 | |
|
||||
3 | |
|
||||
3 | |
|
||||
3 | |
|
||||
(7 rows)
|
||||
|
||||
---- test PBE
|
||||
PREPARE p2 AS INSERT INTO t03 VALUES($1, $2) ON DUPLICATE KEY UPDATE col2 = $1*100;
|
||||
EXECUTE p2(5, 50);
|
||||
SELECT * FROM t03 WHERE col1 = 5;
|
||||
col1 | col2 | col3
|
||||
------+------+------
|
||||
5 | 50 |
|
||||
(1 row)
|
||||
|
||||
EXECUTE p2(5, 50);
|
||||
SELECT * FROM t03 WHERE col1 = 5;
|
||||
col1 | col2 | col3
|
||||
------+------+------
|
||||
5 | 50 |
|
||||
5 | 50 |
|
||||
(2 rows)
|
||||
|
||||
--- error: test with clause
|
||||
WITH tmp(col1, col2) AS (SELECT * FROM t01)
|
||||
INSERT INTO t01 SELECT * FROM tmp ON DUPLICATE KEY UPDATE col1 = 1;
|
||||
ERROR: WITH clause is not yet supported whithin INSERT ON DUPLICATE KEY UPDATE statement.
|
||||
WITH RECURSIVE rq AS
|
||||
(
|
||||
SELECT col1, col2 FROM t00 WHERE col1 = 1
|
||||
UNION ALL
|
||||
SELECT origin.col1, rq.col2
|
||||
FROM rq JOIN t00 AS origin ON origin.col1 = rq.col1
|
||||
)
|
||||
INSERT INTO t03 SELECT * FROM rq ON DUPLICATE KEY UPDATE col1 = rq.col1;
|
||||
ERROR: WITH clause is not yet supported whithin INSERT ON DUPLICATE KEY UPDATE statement.
|
||||
--- error: test returning clause
|
||||
INSERT INTO t01 VALUES (1) ON DUPLICATE KEY UPDATE col1 = 1 RETURNING NOT(1::bool);
|
||||
ERROR: RETURNING clause is not yet supported whithin INSERT ON DUPLICATE KEY UPDATE statement.
|
||||
--- error: distribute key are not allowed to UPDATE
|
||||
CREATE TABLE t04 (col1 INT, col2 INT) ;
|
||||
INSERT INTO t04 VALUES (1) ON DUPLICATE KEY UPDATE col1 = 5;
|
||||
--- error: unique index referenced column are not allowed to UPDATE
|
||||
CREATE UNIQUE INDEX t04_u_index ON t04(col1, col2);
|
||||
INSERT INTO t04 VALUES (1) ON DUPLICATE KEY UPDATE col2 = 5;
|
||||
ERROR: INSERT ON DUPLICATE KEY UPDATE don't allow update on primary key or unique key.
|
||||
DROP INDEX t04_u_index;
|
||||
--- error: primary key referenced column are not allowed to UPDATE
|
||||
ALTER TABLE t04 ADD PRIMARY KEY (col1, col2);
|
||||
ERROR: column "col2" contains null values
|
||||
INSERT INTO t04 VALUES (1) ON DUPLICATE KEY UPDATE col2 = 5;
|
||||
--- error: invalid column
|
||||
INSERT INTO t04 (col2, col3) VALUES (2, 3) ON DUPLICATE KEY UPDATE col2 = 5;
|
||||
ERROR: column "col3" of relation "t04" does not exist
|
||||
LINE 1: INSERT INTO t04 (col2, col3) VALUES (2, 3) ON DUPLICATE KEY ...
|
||||
^
|
||||
--- error: duplicate column
|
||||
INSERT INTO t04 (col2, col2) VALUES (2, 3) ON DUPLICATE KEY UPDATE col2 = 5;
|
||||
ERROR: column "col2" specified more than once
|
||||
LINE 1: INSERT INTO t04 (col2, col2) VALUES (2, 3) ON DUPLICATE KEY ...
|
||||
^
|
||||
-- error: target column more than insert target
|
||||
INSERT INTO t04 (col1, col2) VALUES (2, 3, 4) ON DUPLICATE KEY UPDATE col2 = 5;
|
||||
ERROR: INSERT has more expressions than target columns
|
||||
LINE 1: INSERT INTO t04 (col1, col2) VALUES (2, 3, 4) ON DUPLICATE K...
|
||||
^
|
||||
INSERT INTO t04 (col1, col2) VALUES (1) ON DUPLICATE KEY UPDATE col2 = 5;
|
||||
ERROR: INSERT has more target columns than expressions
|
||||
LINE 1: INSERT INTO t04 (col1, col2) VALUES (1) ON DUPLICATE KEY UPD...
|
||||
^
|
||||
INSERT INTO t04 (col1, col2) SELECT col1 FROM t04 ON DUPLICATE KEY UPDATE col2 = 5;
|
||||
ERROR: INSERT has more target columns than expressions
|
||||
LINE 1: INSERT INTO t04 (col1, col2) SELECT col1 FROM t04 ON DUPLICA...
|
||||
^
|
||||
INSERT INTO t04 (col1, col2) SELECT *, col1 FROM t04 ON DUPLICATE KEY UPDATE col2 = 5;
|
||||
ERROR: INSERT has more expressions than target columns
|
||||
LINE 1: INSERT INTO t04 (col1, col2) SELECT *, col1 FROM t04 ON DUPL...
|
||||
^
|
||||
INSERT INTO t04 VALUES (2, 3, 4) ON DUPLICATE KEY UPDATE col2 = 5;
|
||||
ERROR: INSERT has more expressions than target columns
|
||||
LINE 1: INSERT INTO t04 VALUES (2, 3, 4) ON DUPLICATE KEY UPDATE col...
|
||||
^
|
||||
INSERT INTO t04 VALUES (1) ON DUPLICATE KEY UPDATE col2 = 5;
|
||||
INSERT INTO t04 SELECT col1 FROM t04 ON DUPLICATE KEY UPDATE col2 = 5;
|
||||
INSERT INTO t04 SELECT *, col1 FROM t04 ON DUPLICATE KEY UPDATE col2 = 5;
|
||||
ERROR: INSERT has more expressions than target columns
|
||||
LINE 1: INSERT INTO t04 SELECT *, col1 FROM t04 ON DUPLICATE KEY UPD...
|
||||
^
|
||||
-- test DEFAULT VALUES
|
||||
TRUNCATE t00;
|
||||
TRUNCATE t01;
|
||||
--- without sequence
|
||||
----should insert
|
||||
INSERT INTO t00 DEFAULT VALUES ON DUPLICATE KEY UPDATE col2 = col1;
|
||||
SELECT * FROM t00 ORDER BY 1, 2;
|
||||
col1 | col2
|
||||
------+------
|
||||
1 |
|
||||
(1 row)
|
||||
|
||||
---- should update
|
||||
INSERT INTO t00 DEFAULT VALUES ON DUPLICATE KEY UPDATE col2 = col1;
|
||||
SELECT * FROM t00 ORDER BY 1, 2;
|
||||
col1 | col2
|
||||
------+------
|
||||
1 | 1
|
||||
(1 row)
|
||||
|
||||
--- test drop column
|
||||
TRUNCATE t00;
|
||||
ALTER TABLE t00 DROP COLUMN col2;
|
||||
ALTER TABLE t00 ADD COLUMN col3 INT DEFAULT 100;
|
||||
----should insert
|
||||
INSERT INTO t00 DEFAULT VALUES ON DUPLICATE KEY UPDATE col3 = col1;
|
||||
SELECT * FROM t00 ORDER BY 1, 2;
|
||||
col1 | col3
|
||||
------+------
|
||||
1 | 100
|
||||
(1 row)
|
||||
|
||||
---- should update
|
||||
INSERT INTO t00 DEFAULT VALUES ON DUPLICATE KEY UPDATE col3 = col1;
|
||||
SELECT * FROM t00 ORDER BY 1, 2;
|
||||
col1 | col3
|
||||
------+------
|
||||
1 | 1
|
||||
(1 row)
|
||||
|
||||
--- with sequence
|
||||
----should insert
|
||||
INSERT INTO t01 DEFAULT VALUES ON DUPLICATE KEY UPDATE col1 = col2;
|
||||
INSERT INTO t01 (col2) SELECT col2 + 1 FROM t01 LIMIT 1;
|
||||
SELECT * FROM t01 ORDER BY 1, 2, 3;
|
||||
col1 | col2 | col3
|
||||
------+------+------
|
||||
| 3 |
|
||||
| 4 |
|
||||
(2 rows)
|
||||
|
||||
---- should update
|
||||
INSERT INTO t01 DEFAULT VALUES ON DUPLICATE KEY UPDATE col1 = col2;
|
||||
SELECT * FROM t01 ORDER BY 1, 2, 3;
|
||||
col1 | col2 | col3
|
||||
------+------+------
|
||||
4 | 4 |
|
||||
| 3 |
|
||||
(2 rows)
|
||||
|
||||
-- test VALUES(DEFAULT)
|
||||
CREATE TABLE t05 (col1 INT , col2 INT DEFAULT 1 PRIMARY KEY, col3 INT DEFAULT 100) ;
|
||||
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "t05_pkey" for table "t05"
|
||||
--- should insert
|
||||
INSERT INTO t05 VALUES(DEFAULT) ON DUPLICATE KEY UPDATE col3 = 1000;
|
||||
SELECT * FROM t05 ORDER BY 1, 2, 3;
|
||||
col1 | col2 | col3
|
||||
------+------+------
|
||||
| 1 | 100
|
||||
(1 row)
|
||||
|
||||
--- should update
|
||||
INSERT INTO t05 VALUES(DEFAULT) ON DUPLICATE KEY UPDATE col3 = 1000;
|
||||
SELECT * FROM t05 ORDER BY 1, 2, 3;
|
||||
col1 | col2 | col3
|
||||
------+------+------
|
||||
| 1 | 1000
|
||||
(1 row)
|
||||
|
||||
-- test UPDATE DEFAULT
|
||||
INSERT INTO t05 (col1, col2, col3) VALUES (2, 2, 2) ON DUPLICATE KEY UPDATE col3 = DEFAULT;
|
||||
SELECT * FROM t05 ORDER BY 1, 2, 3;
|
||||
col1 | col2 | col3
|
||||
------+------+------
|
||||
2 | 2 | 2
|
||||
| 1 | 1000
|
||||
(2 rows)
|
||||
|
||||
INSERT INTO t05 (col1, col2, col3) VALUES (2, 2, 2) ON DUPLICATE KEY UPDATE col3 = DEFAULT;
|
||||
SELECT * FROM t05 ORDER BY 1, 2, 3;
|
||||
col1 | col2 | col3
|
||||
------+------+------
|
||||
2 | 2 | 100
|
||||
| 1 | 1000
|
||||
(2 rows)
|
||||
|
||||
-- test VALUES (DEFAULT, ...)
|
||||
TRUNCATE t05;
|
||||
--- should insert
|
||||
INSERT INTO t05 VALUES(DEFAULT, DEFAULT, 200), (DEFAULT, 200, DEFAULT)
|
||||
ON DUPLICATE KEY UPDATE col3 = DEFAULT, col1 = col3;
|
||||
SELECT * FROM t05 ORDER BY 1, 2, 3;
|
||||
col1 | col2 | col3
|
||||
------+------+------
|
||||
| 1 | 200
|
||||
| 200 | 100
|
||||
(2 rows)
|
||||
|
||||
--- should update
|
||||
INSERT INTO t05 VALUES(DEFAULT, DEFAULT, 200), (DEFAULT, 200, DEFAULT)
|
||||
ON DUPLICATE KEY UPDATE col3 = DEFAULT, col1 = col3;
|
||||
SELECT * FROM t05 ORDER BY 1, 2, 3;
|
||||
col1 | col2 | col3
|
||||
------+------+------
|
||||
100 | 200 | 100
|
||||
200 | 1 | 100
|
||||
(2 rows)
|
||||
|
||||
--- test drop coulmn
|
||||
BEGIN;
|
||||
ALTER TABLE t05 ADD COLUMN col4 INT;
|
||||
ALTER TABLE t05 ADD COLUMN col5 INT DEFAULT 500;
|
||||
ALTER TABLE t05 DROP COLUMN col3;
|
||||
TRUNCATE t05;
|
||||
INSERT INTO t05 VALUES(DEFAULT, DEFAULT, DEFAULT, 600) ON DUPLICATE KEY UPDATE col5 = DEFAULT;
|
||||
SELECT * FROM t05 ORDER BY 1, 2, 3;
|
||||
col1 | col2 | col4 | col5
|
||||
------+------+------+------
|
||||
| 1 | | 600
|
||||
(1 row)
|
||||
|
||||
INSERT INTO t05 VALUES(DEFAULT, DEFAULT, DEFAULT, 600) ON DUPLICATE KEY UPDATE col5 = DEFAULT;
|
||||
SELECT * FROM t05 ORDER BY 1, 2, 3;
|
||||
col1 | col2 | col4 | col5
|
||||
------+------+------+------
|
||||
| 1 | | 500
|
||||
(1 row)
|
||||
|
||||
ROLLBACK;
|
||||
-- test schema
|
||||
SET current_schema = public;
|
||||
TRUNCATE test_upsert_001.t05;
|
||||
--- should insert
|
||||
INSERT INTO test_upsert_001.t05 VALUES(DEFAULT, DEFAULT, 200), (DEFAULT, 200, DEFAULT)
|
||||
ON DUPLICATE KEY UPDATE col3 = DEFAULT, col1 = col3;
|
||||
SELECT * FROM test_upsert_001.t05 ORDER BY 1, 2, 3;
|
||||
col1 | col2 | col3
|
||||
------+------+------
|
||||
| 1 | 200
|
||||
| 200 | 100
|
||||
(2 rows)
|
||||
|
||||
--- should update
|
||||
INSERT INTO test_upsert_001.t05 VALUES(DEFAULT, DEFAULT, 200), (DEFAULT, 200, DEFAULT)
|
||||
ON DUPLICATE KEY UPDATE col3 = DEFAULT, col1 = col3;
|
||||
SELECT * FROM test_upsert_001.t05 ORDER BY 1, 2, 3;
|
||||
col1 | col2 | col3
|
||||
------+------+------
|
||||
100 | 200 | 100
|
||||
200 | 1 | 100
|
||||
(2 rows)
|
||||
|
||||
--- test using schema on update
|
||||
INSERT INTO test_upsert_001.t05 VALUES(DEFAULT, DEFAULT, 200), (DEFAULT, 200, DEFAULT)
|
||||
ON DUPLICATE KEY UPDATE t05.col3 = DEFAULT, t05.col1 = t05.col3 + 1;
|
||||
SELECT * FROM test_upsert_001.t05 ORDER BY 1, 2, 3;
|
||||
col1 | col2 | col3
|
||||
------+------+------
|
||||
101 | 1 | 100
|
||||
101 | 200 | 100
|
||||
(2 rows)
|
||||
|
||||
--- error: should not append schema
|
||||
INSERT INTO test_upsert_001.t05 VALUES(DEFAULT, DEFAULT, 200), (DEFAULT, 200, DEFAULT)
|
||||
ON DUPLICATE KEY UPDATE test_upsert_001.t05.col3 = DEFAULT, t05.col1 = t05.col3 + 1;
|
||||
ERROR: column "test_upsert_001.t05" of relation "t05" does not exist
|
||||
LINE 2: ON DUPLICATE KEY UPDATE test_upsert_001.t05.col3 = DEFAULT, ...
|
||||
^
|
||||
INSERT INTO test_upsert_001.t05 VALUES(DEFAULT, DEFAULT, 200), (DEFAULT, 200, DEFAULT)
|
||||
ON DUPLICATE KEY UPDATE t05.col3 = DEFAULT, t05.col1 = test_upsert_001.t05.col3 + 1;
|
||||
SET CURRENT_SCHEMA TO test_upsert_001;
|
||||
DROP USER upsert_tester CASCADE;
|
||||
DROP SCHEMA test_upsert_001 CASCADE;
|
||||
NOTICE: drop cascades to 6 other objects
|
||||
DETAIL: drop cascades to table t00
|
||||
drop cascades to table t01
|
||||
drop cascades to table t02
|
||||
drop cascades to table t03
|
||||
drop cascades to table t04
|
||||
drop cascades to table t05
|
||||
|
|
@ -0,0 +1,545 @@
|
|||
DROP SCHEMA test_upsert_002 CASCADE;
|
||||
ERROR: schema "test_upsert_002" does not exist
|
||||
CREATE SCHEMA test_upsert_002;
|
||||
SET CURRENT_SCHEMA TO test_upsert_002;
|
||||
-- enable_upsert_to_merge must is off, or upsert will be translated to merge.
|
||||
SET enable_upsert_to_merge TO OFF;
|
||||
-- test t1 with no index
|
||||
CREATE TABLE t1 (
|
||||
col1 INT,
|
||||
col2 INT,
|
||||
col3 INT DEFAULT 1,
|
||||
-- col4 TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
col5 BIGSERIAL
|
||||
) ;
|
||||
NOTICE: CREATE TABLE will create implicit sequence "t1_col5_seq" for serial column "t1.col5"
|
||||
INSERT INTO t1 VALUES (1, 2) ON DUPLICATE KEY UPDATE col1 = 3;
|
||||
--- should always insert
|
||||
INSERT INTO t1 VALUES (1, 2) ON DUPLICATE KEY UPDATE col2 = 3;
|
||||
INSERT INTO t1 VALUES (1, 2) ON DUPLICATE KEY UPDATE t1.col2 = 4;
|
||||
--- appoint column list in insert clause, should always insert
|
||||
INSERT INTO t1(col1, col3) VALUES (1, 3) ON DUPLICATE KEY UPDATE col2 = 5;
|
||||
INSERT INTO t1(col1, col3) VALUES (1, 3) ON DUPLICATE KEY UPDATE t1.col2 = 6;
|
||||
--- multiple rows, should always insert
|
||||
INSERT INTO t1 VALUES (2, 1), (2, 1) ON DUPLICATE KEY UPDATE col2 = 7, col3 = 7;
|
||||
SELECT * FROM t1 ORDER BY col5;
|
||||
col1 | col2 | col3 | col5
|
||||
------+------+------+------
|
||||
1 | 2 | 1 | 1
|
||||
1 | 2 | 1 | 2
|
||||
1 | 2 | 1 | 3
|
||||
1 | | 3 | 4
|
||||
1 | | 3 | 5
|
||||
2 | 1 | 1 | 6
|
||||
2 | 1 | 1 | 7
|
||||
(7 rows)
|
||||
|
||||
--- test union, should insert
|
||||
INSERT INTO t1 (col1, col2)
|
||||
SELECT * FROM
|
||||
(SELECT col1, col2 FROM t1
|
||||
UNION
|
||||
SELECT col1, col3 FROM t1) AS union_table
|
||||
ON DUPLICATE KEY UPDATE col3 = (col1 + col2 + col3) * 10;
|
||||
SELECT col1, col2, col3 FROM t1 WHERE col5 > 6 ORDER BY col1, col2;
|
||||
col1 | col2 | col3
|
||||
------+------+------
|
||||
1 | 1 | 1
|
||||
1 | 2 | 1
|
||||
1 | 3 | 1
|
||||
1 | | 1
|
||||
2 | 1 | 1
|
||||
2 | 1 | 1
|
||||
(6 rows)
|
||||
|
||||
--- test subquery, should insert
|
||||
INSERT INTO t1
|
||||
(SELECT col1 || col2 || '00' FROM t1 ORDER BY col5)
|
||||
ON DUPLICATE KEY UPDATE col3 = col1 * 100;
|
||||
SELECT col1, col2, col3 FROM t1 WHERE col1 >= 100 ORDER BY col1;
|
||||
col1 | col2 | col3
|
||||
------+------+------
|
||||
100 | | 1
|
||||
100 | | 1
|
||||
100 | | 1
|
||||
1100 | | 1
|
||||
1200 | | 1
|
||||
1200 | | 1
|
||||
1200 | | 1
|
||||
1200 | | 1
|
||||
1300 | | 1
|
||||
2100 | | 1
|
||||
2100 | | 1
|
||||
2100 | | 1
|
||||
(12 rows)
|
||||
|
||||
-- test t2 with one primary key
|
||||
CREATE TABLE t2 (
|
||||
col1 INT,
|
||||
col2 INT PRIMARY KEY,
|
||||
col3 INT DEFAULT 1,
|
||||
col4 TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
col5 BIGSERIAL
|
||||
) ;
|
||||
NOTICE: CREATE TABLE will create implicit sequence "t2_col5_seq" for serial column "t2.col5"
|
||||
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "t2_pkey" for table "t2"
|
||||
--- primary key or unique key are not allowed to update
|
||||
INSERT INTO t2 VALUES (1, 1) ON DUPLICATE KEY UPDATE col2 = 3;
|
||||
ERROR: INSERT ON DUPLICATE KEY UPDATE don't allow update on primary key or unique key.
|
||||
INSERT INTO t2 VALUES (1, 1) ON DUPLICATE KEY UPDATE t2.col2 = 3;
|
||||
ERROR: INSERT ON DUPLICATE KEY UPDATE don't allow update on primary key or unique key.
|
||||
INSERT INTO t2 (col2, col3, col4, col5)
|
||||
VALUES (10, 10, CURRENT_TIMESTAMP(0), 10),
|
||||
(20, 20, CURRENT_TIMESTAMP(1), 20),
|
||||
(30, 30, CURRENT_TIMESTAMP(2), 30)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
col1 = 100,
|
||||
col2 = 100,
|
||||
col3 = 100,
|
||||
col4 = '2019-08-09'::TIMESTAMP,
|
||||
col5 = 100;
|
||||
ERROR: INSERT ON DUPLICATE KEY UPDATE don't allow update on primary key or unique key.
|
||||
--- should insert
|
||||
INSERT INTO t2 VALUES (1, 1) ON DUPLICATE KEY UPDATE col1 = 30;
|
||||
INSERT INTO t2 VALUES (2, 2) ON DUPLICATE KEY UPDATE t2.col1 = 40;
|
||||
INSERT INTO t2 VALUES (3, 3) ON DUPLICATE KEY UPDATE col1 = col1 * 2;
|
||||
INSERT INTO t2 VALUES (4, 4) ON DUPLICATE KEY UPDATE t2.col1 = t2.col1 * 2 ;
|
||||
INSERT INTO t2 VALUES (5, 5) ON DUPLICATE KEY UPDATE col1 = col2 + 1;
|
||||
INSERT INTO t2 VALUES (6, 6) ON DUPLICATE KEY UPDATE t2.col1 = t2.col2 + 1;
|
||||
INSERT INTO t2 VALUES (7, 7) ON DUPLICATE KEY UPDATE col1 = extract(dow from col4) + 10;
|
||||
INSERT INTO t2 VALUES (8, 8) ON DUPLICATE KEY UPDATE t2.col1 = extract(century from col4) * 100 + extract(isodow from col4);
|
||||
SELECT col1, col2, col3, col5 FROM t2 ORDER BY col5;
|
||||
col1 | col2 | col3 | col5
|
||||
------+------+------+------
|
||||
1 | 1 | 1 | 1
|
||||
2 | 2 | 1 | 2
|
||||
3 | 3 | 1 | 3
|
||||
4 | 4 | 1 | 4
|
||||
5 | 5 | 1 | 5
|
||||
6 | 6 | 1 | 6
|
||||
7 | 7 | 1 | 7
|
||||
8 | 8 | 1 | 8
|
||||
(8 rows)
|
||||
|
||||
--- should update
|
||||
INSERT INTO t2 VALUES (3, 1) ON DUPLICATE KEY UPDATE col1 = 30, col3 = col5 + 1;
|
||||
INSERT INTO t2 VALUES (4, 2) ON DUPLICATE KEY UPDATE t2.col1 = 40, t2.col3 = t2.col5;
|
||||
INSERT INTO t2 VALUES (3, 3), (4, 4) ON DUPLICATE KEY UPDATE col3 = t2.col5 + 1;
|
||||
INSERT INTO t2 VALUES (5, 5) ON DUPLICATE KEY UPDATE col1 = extract(dow from col4) + 10;
|
||||
INSERT INTO t2 VALUES (6, 6) ON DUPLICATE KEY UPDATE t2.col1 = extract(century from col4) * 100 + extract(isodow from col4);
|
||||
SELECT col1, col2, col3, col5 FROM t2 ORDER BY col5;
|
||||
col1 | col2 | col3 | col5
|
||||
------+------+------+------
|
||||
30 | 1 | 2 | 1
|
||||
40 | 2 | 2 | 2
|
||||
3 | 3 | 4 | 3
|
||||
4 | 4 | 5 | 4
|
||||
--?.*| 5 | 1 | 5
|
||||
--?.*| 6 | 1 | 6
|
||||
7 | 7 | 1 | 7
|
||||
8 | 8 | 1 | 8
|
||||
(8 rows)
|
||||
|
||||
-- primary key are not allowed to be null
|
||||
INSERT INTO t2 (col1) VALUES (10) ON DUPLICATE KEY UPDATE col1 = 10;
|
||||
ERROR: null value in column "col2" violates not-null constraint
|
||||
--?
|
||||
--- appoint column list in insert clause
|
||||
---- should insert
|
||||
INSERT INTO t2 (col2, col3) VALUES (9, 9) ON DUPLICATE KEY UPDATE col1 = 90;
|
||||
INSERT INTO t2 (col2, col3, col4, col5)
|
||||
VALUES (10, 10, CURRENT_TIMESTAMP(0), 10),
|
||||
(20, 20, CURRENT_TIMESTAMP(1), 20),
|
||||
(30, 30, CURRENT_TIMESTAMP(2), 30)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
col1 = 100,
|
||||
col3 = 100,
|
||||
col4 = '2019-08-20'::TIMESTAMP,
|
||||
col5 = 100;
|
||||
SELECT * FROM t2 ORDER BY col5;
|
||||
col1 | col2 | col3 | col4 | col5
|
||||
------+------+------+---------------------------------+------
|
||||
--? 30 | 1 | 2 | .* | 1
|
||||
--? 40 | 2 | 2 | .* | 2
|
||||
--? 3 | 3 | 4 | .* | 3
|
||||
--? 4 | 4 | 5 | .* | 4
|
||||
--? .* | 5 | 1 | .* | 5
|
||||
--? .* | 6 | 1 | .* | 6
|
||||
--? 7 | 7 | 1 | .* | 7
|
||||
--? 8 | 8 | 1 | .* | 8
|
||||
--? | 10 | 10 | .* | 10
|
||||
--? | 9 | 9 | .* | 16
|
||||
--? | 20 | 20 | .* | 20
|
||||
--? | 30 | 30 | .* | 30
|
||||
(12 rows)
|
||||
|
||||
---- should update
|
||||
INSERT INTO t2 (col2, col3) VALUES (9, 9) ON DUPLICATE KEY UPDATE col1 = 90;
|
||||
INSERT INTO t2 (col2, col3, col4, col5)
|
||||
VALUES (10, 10, CURRENT_TIMESTAMP(0), 10),
|
||||
(20, 20, CURRENT_TIMESTAMP(1), 20),
|
||||
(30, 30, CURRENT_TIMESTAMP(2), 30)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
col1 = 100,
|
||||
col3 = 100,
|
||||
col4 = '2019-08-20'::TIMESTAMP,
|
||||
col5 = 100;
|
||||
SELECT * FROM t2 ORDER BY col5, col2;
|
||||
col1 | col2 | col3 | col4 | col5
|
||||
------+------+------+---------------------------------+------
|
||||
--? 30 | 1 | 2 | .* | 1
|
||||
--? 40 | 2 | 2 | .* | 2
|
||||
--? 3 | 3 | 4 | .* | 3
|
||||
--? 4 | 4 | 5 | .* | 4
|
||||
--? .* | 5 | 1 | .* | 5
|
||||
--? .* | 6 | 1 | .* | 6
|
||||
--? 7 | 7 | 1 | .* | 7
|
||||
--? 8 | 8 | 1 | .* | 8
|
||||
--? 90 | 9 | 9 | .* | 16
|
||||
100 | 10 | 100 | Tue Aug 20 00:00:00 2019 | 100
|
||||
100 | 20 | 100 | Tue Aug 20 00:00:00 2019 | 100
|
||||
100 | 30 | 100 | Tue Aug 20 00:00:00 2019 | 100
|
||||
(12 rows)
|
||||
|
||||
--- test subquery
|
||||
---- should insert
|
||||
INSERT INTO t2
|
||||
(SELECT col1 * 1000, col2 * 1000 + 1 FROM t2 ORDER BY col5 LIMIT 2)
|
||||
ON DUPLICATE KEY UPDATE col3 = col2 + 1;
|
||||
INSERT INTO t2 (col2, col3)
|
||||
(SELECT col1 * 1000 + 2, col2 * 1000 FROM t2 ORDER BY col5 LIMIT 2 OFFSET 1)
|
||||
ON DUPLICATE KEY UPDATE col3 = col2 + 1;
|
||||
SELECT col1, col2, col3, col5 FROM t2 ORDER BY col5, col2;
|
||||
col1 | col2 | col3 | col5
|
||||
-------+-------+------+------
|
||||
30 | 1 | 2 | 1
|
||||
40 | 2 | 2 | 2
|
||||
3 | 3 | 4 | 3
|
||||
4 | 4 | 5 | 4
|
||||
--? .* | 5 | 1 | 5
|
||||
--? .* | 6 | 1 | 6
|
||||
7 | 7 | 1 | 7
|
||||
8 | 8 | 1 | 8
|
||||
90 | 9 | 9 | 16
|
||||
--? 30000 | 1001 | 1 | 11
|
||||
--? 40000 | 2001 | 1 | 12
|
||||
--? | 40002 | 2000 | 13
|
||||
--? | 3002 | 3000 | 14
|
||||
100 | 10 | 100 | 100
|
||||
100 | 20 | 100 | 100
|
||||
100 | 30 | 100 | 100
|
||||
(16 rows)
|
||||
|
||||
---- should update
|
||||
INSERT INTO t2
|
||||
(SELECT col1 * 1000, col2 * 1000 + 1 FROM t2 ORDER BY col5 LIMIT 2)
|
||||
ON DUPLICATE KEY UPDATE col3 = col2 + 1;
|
||||
INSERT INTO t2 (col2, col3)
|
||||
(SELECT col1 * 1000 + 2, col2 * 1000 FROM t2 ORDER BY col5 LIMIT 2 OFFSET 1)
|
||||
ON DUPLICATE KEY UPDATE col3 = col2 + 1;
|
||||
SELECT col1, col2, col3, col5 FROM t2 ORDER BY col5, col2;
|
||||
col1 | col2 | col3 | col5
|
||||
-------+-------+-------+------
|
||||
30 | 1 | 2 | 1
|
||||
40 | 2 | 2 | 2
|
||||
3 | 3 | 4 | 3
|
||||
4 | 4 | 5 | 4
|
||||
--? .* | 5 | 1 | 5
|
||||
--? .* | 6 | 1 | 6
|
||||
7 | 7 | 1 | 7
|
||||
8 | 8 | 1 | 8
|
||||
90 | 9 | 9 | 16
|
||||
--? 30000 | 1001 | 1002 | 11
|
||||
--? 40000 | 2001 | 2002 | 12
|
||||
--? | 40002 | 40003 | 13
|
||||
--? | 3002 | 3003 | 14
|
||||
100 | 10 | 100 | 100
|
||||
100 | 20 | 100 | 100
|
||||
100 | 30 | 100 | 100
|
||||
(16 rows)
|
||||
|
||||
--- test union, some insert some update
|
||||
SELECT col1, col2 FROM t1 WHERE col2 IS NOT NULL
|
||||
UNION
|
||||
SELECT col1, col3 FROM t1 ORDER BY 1, 2;
|
||||
col1 | col2
|
||||
------+------
|
||||
1 | 1
|
||||
1 | 2
|
||||
1 | 3
|
||||
2 | 1
|
||||
100 | 1
|
||||
1100 | 1
|
||||
1200 | 1
|
||||
1300 | 1
|
||||
2100 | 1
|
||||
(9 rows)
|
||||
|
||||
INSERT INTO t2 (col1, col2)
|
||||
SELECT * FROM
|
||||
(SELECT col1, col2 FROM t1 WHERE col2 IS NOT NULL
|
||||
UNION
|
||||
SELECT col1, col3 FROM t1) AS union_table
|
||||
ON DUPLICATE KEY UPDATE col3 = (col1 + col2 + col3);
|
||||
SELECT col1, col2, col3, col5 FROM t2 ORDER BY col5, col2;
|
||||
col1 | col2 | col3 | col5
|
||||
-------+-------+-------+------
|
||||
30 | 1 | 219 | 1
|
||||
40 | 2 | 44 | 2
|
||||
3 | 3 | 10 | 3
|
||||
4 | 4 | 5 | 4
|
||||
--? .* | 5 | 1 | 5
|
||||
--? .* | 6 | 1 | 6
|
||||
7 | 7 | 1 | 7
|
||||
8 | 8 | 1 | 8
|
||||
90 | 9 | 9 | 16
|
||||
--? 30000 | 1001 | 1002 | 11
|
||||
--? 40000 | 2001 | 2002 | 12
|
||||
--? | 40002 | 40003 | 13
|
||||
--? | 3002 | 3003 | 14
|
||||
100 | 10 | 100 | 100
|
||||
100 | 20 | 100 | 100
|
||||
100 | 30 | 100 | 100
|
||||
(16 rows)
|
||||
|
||||
INSERT INTO t2 (col1, col2)
|
||||
SELECT col1, col2 FROM t1 WHERE col2 IS NOT NULL
|
||||
UNION
|
||||
SELECT col1, col3 FROM t1
|
||||
ON DUPLICATE KEY UPDATE col3 = col3 + 1;
|
||||
SELECT col1, col2, col3, col5 FROM t2 ORDER BY col5, col2;
|
||||
col1 | col2 | col3 | col5
|
||||
-------+-------+-------+------
|
||||
30 | 1 | 226 | 1
|
||||
40 | 2 | 45 | 2
|
||||
3 | 3 | 11 | 3
|
||||
4 | 4 | 5 | 4
|
||||
--? 15 | 5 | 1 | 5
|
||||
--? 2105 | 6 | 1 | 6
|
||||
7 | 7 | 1 | 7
|
||||
8 | 8 | 1 | 8
|
||||
90 | 9 | 9 | 16
|
||||
--? 30000 | 1001 | 1002 | 11
|
||||
--? 40000 | 2001 | 2002 | 12
|
||||
--? | 40002 | 40003 | 13
|
||||
--? | 3002 | 3003 | 14
|
||||
100 | 10 | 100 | 100
|
||||
100 | 20 | 100 | 100
|
||||
100 | 30 | 100 | 100
|
||||
(16 rows)
|
||||
|
||||
reset behavior_compat_options;
|
||||
-- test INTERSECT, should update
|
||||
(SELECT col1, col1 + col2 FROM t1 WHERE col2 IS NOT NULL
|
||||
UNION
|
||||
SELECT 1, 2)
|
||||
INTERSECT
|
||||
SELECT col1, col3 FROM t1;
|
||||
col1 | ?column?
|
||||
------+----------
|
||||
1 | 3
|
||||
(1 row)
|
||||
|
||||
INSERT INTO t2 (col1, col2)
|
||||
(SELECT col1, col1 + col2 FROM t1 WHERE col2 IS NOT NULL
|
||||
UNION
|
||||
SELECT 1, 2)
|
||||
INTERSECT
|
||||
SELECT col1, col3 FROM t1
|
||||
ON DUPLICATE KEY UPDATE col3 = col3 + 1;
|
||||
SELECT col1, col2, col3, col5 FROM t2 WHERE col2 = 3 ORDER BY col5, col2;
|
||||
col1 | col2 | col3 | col5
|
||||
------+------+------+------
|
||||
3 | 3 | 12 | 3
|
||||
(1 row)
|
||||
|
||||
-- test EXCEPT, should update
|
||||
SELECT col1, col2 FROM t1 WHERE col2 IS NOT NULL
|
||||
EXCEPT
|
||||
(SELECT col1, col3 FROM t1
|
||||
UNION
|
||||
SELECT NULL, NULL);
|
||||
col1 | col2
|
||||
------+------
|
||||
1 | 2
|
||||
(1 row)
|
||||
|
||||
INSERT INTO t2 (col1, col2)
|
||||
SELECT col1, col2 FROM t1 WHERE col2 IS NOT NULL
|
||||
EXCEPT
|
||||
(SELECT col1, col3 FROM t1
|
||||
UNION
|
||||
SELECT NULL, NULL)
|
||||
ON DUPLICATE KEY UPDATE col3 = col3 + 1;
|
||||
SELECT col1, col2, col3, col5 FROM t2 WHERE col2 = 2 ORDER BY col5, col2;
|
||||
col1 | col2 | col3 | col5
|
||||
------+------+------+------
|
||||
40 | 2 | 46 | 2
|
||||
(1 row)
|
||||
|
||||
-- test unique index with not default value
|
||||
ALTER TABLE t2 DROP CONSTRAINT t2_pkey;
|
||||
CREATE UNIQUE INDEX t2_u_index ON t2(col2, col5);
|
||||
SELECT col1, col2 FROM t1 WHERE col2 IS NOT NULL
|
||||
EXCEPT
|
||||
(SELECT col1, col3 FROM t1
|
||||
UNION
|
||||
SELECT NULL, NULL);
|
||||
col1 | col2
|
||||
------+------
|
||||
1 | 2
|
||||
(1 row)
|
||||
|
||||
INSERT INTO t2
|
||||
SELECT col1, col2 FROM t1 WHERE col2 IS NOT NULL
|
||||
EXCEPT
|
||||
(SELECT col1, col3 FROM t1
|
||||
UNION
|
||||
SELECT NULL, NULL)
|
||||
ON DUPLICATE KEY UPDATE col3 = col3 + 1;
|
||||
SELECT col1, col2, col3, col5 FROM t2 WHERE col2 = 2 ORDER BY col5, col2;
|
||||
col1 | col2 | col3 | col5
|
||||
------+------+------+------
|
||||
40 | 2 | 46 | 2
|
||||
1 | 2 | 1 | 46
|
||||
(2 rows)
|
||||
|
||||
-- test t3 with one primary index with two columns
|
||||
CREATE TABLE t3 (
|
||||
col1 INT,
|
||||
col2 INT,
|
||||
col3 INT DEFAULT 1,
|
||||
-- col4 TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
col5 BIGSERIAL,
|
||||
PRIMARY KEY (col2, col3)
|
||||
) ;
|
||||
NOTICE: CREATE TABLE will create implicit sequence "t3_col5_seq" for serial column "t3.col5"
|
||||
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "t3_pkey" for table "t3"
|
||||
--- column referenced by primary key are not allowed to update
|
||||
INSERT INTO t3 VALUES (1, 1) ON DUPLICATE KEY UPDATE col3 = 3;
|
||||
ERROR: INSERT ON DUPLICATE KEY UPDATE don't allow update on primary key or unique key.
|
||||
--- should insert when not contains primary key and not all primary key referred columns have default value.
|
||||
--- but will fail cause primary key should not be null
|
||||
INSERT INTO t3 (col1) VALUES (1) ON DUPLICATE KEY UPDATE col1 = 2;
|
||||
ERROR: null value in column "col2" violates not-null constraint
|
||||
--?.*
|
||||
--- should insert
|
||||
--- (SEQUENCE BUG: the serial column will starts from 2 since the above statement has applied for a sequence)
|
||||
INSERT INTO t3 VALUES (1, 1) ON DUPLICATE KEY UPDATE col1 = 10;
|
||||
INSERT INTO t3 VALUES (2, 2, 2) ON DUPLICATE KEY UPDATE col5 = 20;
|
||||
SELECT * FROM t3 order by col5;
|
||||
col1 | col2 | col3 | col5
|
||||
------+------+------+------
|
||||
1 | 1 | 1 | 2
|
||||
2 | 2 | 2 | 3
|
||||
(2 rows)
|
||||
|
||||
--- should update
|
||||
INSERT INTO t3 VALUES (1, 1) ON DUPLICATE KEY UPDATE col1 = 10;
|
||||
INSERT INTO t3 VALUES (2, 2, 2) ON DUPLICATE KEY UPDATE col5 = 20;
|
||||
SELECT * FROM t3 order by col5;
|
||||
col1 | col2 | col3 | col5
|
||||
------+------+------+------
|
||||
10 | 1 | 1 | 2
|
||||
2 | 2 | 2 | 20
|
||||
(2 rows)
|
||||
|
||||
--- test subquery
|
||||
---- should insert
|
||||
INSERT INTO t3 (col2, col3) (SELECT max(col2) + 1, max(col3) + 1 FROM t3) ON DUPLICATE KEY UPDATE col1 = col2 + col3;
|
||||
SELECT * FROM t3 order by col5;
|
||||
col1 | col2 | col3 | col5
|
||||
------+------+------+------
|
||||
10 | 1 | 1 | 2
|
||||
| 3 | 3 | 6
|
||||
2 | 2 | 2 | 20
|
||||
(3 rows)
|
||||
|
||||
---- should update
|
||||
INSERT INTO t3 (col2, col3) (SELECT max(col2), max(col3) FROM t3) ON DUPLICATE KEY UPDATE col1 = col2 + col3;
|
||||
SELECT * FROM t3 order by col5;
|
||||
col1 | col2 | col3 | col5
|
||||
------+------+------+------
|
||||
10 | 1 | 1 | 2
|
||||
6 | 3 | 3 | 6
|
||||
2 | 2 | 2 | 20
|
||||
(3 rows)
|
||||
|
||||
-- test t3 with one unique index with two columns
|
||||
TRUNCATE t3;
|
||||
ALTER TABLE t3 DROP CONSTRAINT t3_pkey;
|
||||
ALTER TABLE t3 ALTER COLUMN col2 DROP NOT NULL;
|
||||
CREATE UNIQUE INDEX t3_ukey ON t3 (col2, col3);
|
||||
--- column referenced by unique key are not allowed to update
|
||||
INSERT INTO t3 VALUES (1, 1) ON DUPLICATE KEY UPDATE col3 = 3;
|
||||
ERROR: INSERT ON DUPLICATE KEY UPDATE don't allow update on primary key or unique key.
|
||||
--- should insert cause not contains unique key and not all unique key referred columns have default value.
|
||||
INSERT INTO t3 (col1) VALUES (1) ON DUPLICATE KEY UPDATE col1 = 2;
|
||||
INSERT INTO t3 (col1) VALUES (1) ON DUPLICATE KEY UPDATE col1 = 2;
|
||||
SELECT * FROM t3 order by col5;
|
||||
col1 | col2 | col3 | col5
|
||||
------+------+------+------
|
||||
1 | | 1 | 8
|
||||
1 | | 1 | 9
|
||||
(2 rows)
|
||||
|
||||
--- should insert
|
||||
INSERT INTO t3 VALUES (1, 1) ON DUPLICATE KEY UPDATE col1 = 10;
|
||||
INSERT INTO t3 VALUES (2, 2, 2) ON DUPLICATE KEY UPDATE t3.col5 = 20;
|
||||
SELECT * FROM t3 ORDER BY col5;
|
||||
col1 | col2 | col3 | col5
|
||||
------+------+------+------
|
||||
1 | | 1 | 8
|
||||
1 | | 1 | 9
|
||||
1 | 1 | 1 | 10
|
||||
2 | 2 | 2 | 11
|
||||
(4 rows)
|
||||
|
||||
--- should update
|
||||
INSERT INTO t3 VALUES (1, 1) ON DUPLICATE KEY UPDATE t3.col1 = 10;
|
||||
INSERT INTO t3 VALUES (2, 2, 2) ON DUPLICATE KEY UPDATE col5 = 20;
|
||||
SELECT * FROM t3 ORDER BY col5;
|
||||
col1 | col2 | col3 | col5
|
||||
------+------+------+------
|
||||
1 | | 1 | 8
|
||||
1 | | 1 | 9
|
||||
10 | 1 | 1 | 10
|
||||
2 | 2 | 2 | 20
|
||||
(4 rows)
|
||||
|
||||
--- test subquery
|
||||
---- should insert
|
||||
INSERT INTO t3 (SELECT 100, NULL, max(col3) FROM t3) ON DUPLICATE KEY UPDATE col1 = col2 + col3;
|
||||
INSERT INTO t3 (SELECT 100, NULL, max(col3) FROM t3) ON DUPLICATE KEY UPDATE col1 = col2 + col3;
|
||||
INSERT INTO t3 (col2, col3) (SELECT max(col2) + 1, max(col3) + 1 FROM t3) ON DUPLICATE KEY UPDATE col1 = col2 + col3;
|
||||
SELECT * FROM t3 ORDER BY col5;
|
||||
col1 | col2 | col3 | col5
|
||||
------+------+------+------
|
||||
1 | | 1 | 8
|
||||
1 | | 1 | 9
|
||||
10 | 1 | 1 | 10
|
||||
100 | | 2 | 14
|
||||
100 | | 2 | 15
|
||||
| 3 | 3 | 16
|
||||
2 | 2 | 2 | 20
|
||||
(7 rows)
|
||||
|
||||
---- should update
|
||||
INSERT INTO t3 (col2, col3) (SELECT max(col2), max(col3) FROM t3) ON DUPLICATE KEY UPDATE col1 = col2 + col3;
|
||||
SELECT * FROM t3 ORDER BY col5;
|
||||
col1 | col2 | col3 | col5
|
||||
------+------+------+------
|
||||
1 | | 1 | 8
|
||||
1 | | 1 | 9
|
||||
10 | 1 | 1 | 10
|
||||
100 | | 2 | 14
|
||||
100 | | 2 | 15
|
||||
6 | 3 | 3 | 16
|
||||
2 | 2 | 2 | 20
|
||||
(7 rows)
|
||||
|
||||
DROP SCHEMA test_upsert_002 CASCADE;
|
||||
NOTICE: drop cascades to 3 other objects
|
||||
DETAIL: drop cascades to table t1
|
||||
drop cascades to table t2
|
||||
drop cascades to table t3
|
||||
|
|
@ -0,0 +1,313 @@
|
|||
DROP SCHEMA test_insert_update_003 CASCADE;
|
||||
ERROR: schema "test_insert_update_003" does not exist
|
||||
CREATE SCHEMA test_insert_update_003;
|
||||
SET CURRENT_SCHEMA TO test_insert_update_003;
|
||||
-- enable_upsert_to_merge must is off, or upsert will be translated to merge.
|
||||
SET enable_upsert_to_merge TO OFF;
|
||||
-- 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;
|
||||
-- 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 not insert
|
||||
INSERT INTO t6 (col1) VALUES (1), (2), (3), (4), (5) ON DUPLICATE KEY UPDATE col6 = power(col1, col2);
|
||||
ERROR: INSERT ON DUPLICATE KEY UPDATE don't allow update on primary key or unique key.
|
||||
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 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;
|
||||
ERROR: INSERT ON DUPLICATE KEY UPDATE don't allow update on primary key or unique key.
|
||||
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)
|
||||
|
||||
--- 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 | 1 | 6 | |
|
||||
6 | 1 | 7 | |
|
||||
6 | 1 | 11 | |
|
||||
6 | 1 | 12 | |
|
||||
(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 | 1 | 6 | |
|
||||
6 | 1 | 7 | |
|
||||
6 | 1 | 11 | |
|
||||
6 | 1 | 12 | |
|
||||
(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 | 8 | 10.00000 | 10 |
|
||||
7 | 1 | 18 | 100.00000 | 100 | 1800
|
||||
(2 rows)
|
||||
|
||||
DROP SCHEMA test_insert_update_003 CASCADE;
|
||||
NOTICE: drop cascades to 3 other objects
|
||||
DETAIL: drop cascades to table t4
|
||||
drop cascades to table t5
|
||||
drop cascades to table t6
|
||||
|
|
@ -0,0 +1,466 @@
|
|||
--
|
||||
-- INSERT UPDATE, test explain command, comes from merge_explain and merge_explain_pretty
|
||||
--
|
||||
-- initial
|
||||
CREATE SCHEMA test_insert_update_008;
|
||||
SET current_schema = test_insert_update_008;
|
||||
-- enable_upsert_to_merge must is off, or upsert will be translated to merge.
|
||||
SET enable_upsert_to_merge TO OFF;
|
||||
CREATE TABLE products_base
|
||||
(
|
||||
product_id INTEGER DEFAULT 0,
|
||||
product_name VARCHAR(60) DEFAULT 'null',
|
||||
category VARCHAR(60) DEFAULT 'unknown',
|
||||
total INTEGER DEFAULT '0'
|
||||
);
|
||||
INSERT INTO products_base VALUES (1501, 'vivitar 35mm', 'electrncs', 100);
|
||||
INSERT INTO products_base VALUES (1502, 'olympus is50', 'electrncs', 100);
|
||||
INSERT INTO products_base VALUES (1600, 'play gym', 'toys', 100);
|
||||
INSERT INTO products_base VALUES (1601, 'lamaze', 'toys', 100);
|
||||
INSERT INTO products_base VALUES (1666, 'harry potter', 'dvd', 100);
|
||||
CREATE TABLE newproducts_base
|
||||
(
|
||||
product_id INTEGER DEFAULT 0,
|
||||
product_name VARCHAR(60) DEFAULT 'null',
|
||||
category VARCHAR(60) DEFAULT 'unknown',
|
||||
total INTEGER DEFAULT '0'
|
||||
);
|
||||
INSERT INTO newproducts_base VALUES (1502, 'olympus camera', 'electrncs', 200);
|
||||
INSERT INTO newproducts_base VALUES (1601, 'lamaze', 'toys', 200);
|
||||
INSERT INTO newproducts_base VALUES (1666, 'harry potter', 'toys', 200);
|
||||
INSERT INTO newproducts_base VALUES (1700, 'wait interface', 'books', 200);
|
||||
ANALYZE products_base;
|
||||
ANALYZE newproducts_base;
|
||||
--
|
||||
-- row table
|
||||
--
|
||||
CREATE TABLE products_row
|
||||
(
|
||||
product_id INTEGER DEFAULT 0 PRIMARY KEY,
|
||||
product_name VARCHAR(60) DEFAULT 'null',
|
||||
category VARCHAR(60) DEFAULT 'unknown',
|
||||
total INTEGER DEFAULT '0'
|
||||
);
|
||||
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "products_row_pkey" for table "products_row"
|
||||
CREATE TABLE newproducts_row
|
||||
(
|
||||
product_id INTEGER DEFAULT 0 PRIMARY KEY,
|
||||
product_name VARCHAR(60) DEFAULT 'null',
|
||||
category VARCHAR(60) DEFAULT 'unknown',
|
||||
total INTEGER DEFAULT '0'
|
||||
);
|
||||
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "newproducts_row_pkey" for table "newproducts_row"
|
||||
INSERT INTO products_row SELECT * FROM products_base;
|
||||
INSERT INTO newproducts_row SELECT * FROM newproducts_base;
|
||||
ANALYZE products_row;
|
||||
ANALYZE newproducts_row;
|
||||
SET explain_perf_mode = normal;
|
||||
-- explain verbose
|
||||
EXPLAIN (VERBOSE on, COSTS off)
|
||||
INSERT INTO products_row
|
||||
SELECT product_id, product_name, category, total FROM newproducts_row
|
||||
ON DUPLICATE KEY UPDATE
|
||||
product_name = excluded.product_name,
|
||||
category = excluded.category,
|
||||
total = excluded.total;
|
||||
QUERY PLAN
|
||||
---------------------------------------------------------------------------------------------------------------------------
|
||||
Insert on test_insert_update_008.products_row
|
||||
Conflict Resolution: UPDATE
|
||||
Conflict Arbiter Indexes: products_row_pkey
|
||||
-> Seq Scan on test_insert_update_008.newproducts_row
|
||||
Output: newproducts_row.product_id, newproducts_row.product_name, newproducts_row.category, newproducts_row.total
|
||||
(5 rows)
|
||||
|
||||
EXPLAIN (VERBOSE on, COSTS off)
|
||||
INSERT INTO products_row
|
||||
SELECT newproducts_row.product_id,
|
||||
newproducts_row.product_name,
|
||||
newproducts_row.category,
|
||||
newproducts_row.total
|
||||
FROM newproducts_row, products_row
|
||||
WHERE products_row.total + newproducts_row.total < 1000
|
||||
ON DUPLICATE KEY UPDATE
|
||||
product_name = excluded.product_name,
|
||||
category = excluded.category,
|
||||
total = excluded.total;
|
||||
QUERY PLAN
|
||||
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
Insert on test_insert_update_008.products_row
|
||||
Conflict Resolution: UPDATE
|
||||
Conflict Arbiter Indexes: products_row_pkey
|
||||
-> Nested Loop
|
||||
Output: newproducts_row.product_id, newproducts_row.product_name, newproducts_row.category, newproducts_row.total
|
||||
Join Filter: ((test_insert_update_008.products_row.total + newproducts_row.total) < 1000)
|
||||
-> Seq Scan on test_insert_update_008.products_row
|
||||
Output: test_insert_update_008.products_row.product_id, test_insert_update_008.products_row.product_name, test_insert_update_008.products_row.category, test_insert_update_008.products_row.total
|
||||
-> Materialize
|
||||
Output: newproducts_row.product_id, newproducts_row.product_name, newproducts_row.category, newproducts_row.total
|
||||
-> Seq Scan on test_insert_update_008.newproducts_row
|
||||
Output: newproducts_row.product_id, newproducts_row.product_name, newproducts_row.category, newproducts_row.total
|
||||
(12 rows)
|
||||
|
||||
EXPLAIN (VERBOSE on, COSTS off)
|
||||
INSERT INTO products_row
|
||||
SELECT product_id, product_name, category, total
|
||||
FROM newproducts_row WHERE product_id IS NOT NULL AND product_name IS NOT NULL
|
||||
ON DUPLICATE KEY UPDATE
|
||||
product_name = excluded.product_name,
|
||||
category = excluded.category,
|
||||
total = excluded.total;
|
||||
QUERY PLAN
|
||||
---------------------------------------------------------------------------------------------------------------------------
|
||||
Insert on test_insert_update_008.products_row
|
||||
Conflict Resolution: UPDATE
|
||||
Conflict Arbiter Indexes: products_row_pkey
|
||||
-> Seq Scan on test_insert_update_008.newproducts_row
|
||||
Output: newproducts_row.product_id, newproducts_row.product_name, newproducts_row.category, newproducts_row.total
|
||||
Filter: ((newproducts_row.product_id IS NOT NULL) AND (newproducts_row.product_name IS NOT NULL))
|
||||
(6 rows)
|
||||
|
||||
-- explain analyze
|
||||
BEGIN;
|
||||
EXPLAIN (ANALYZE on, COSTS off, TIMING off)
|
||||
INSERT INTO products_row
|
||||
SELECT product_id, product_name, category, total FROM newproducts_row
|
||||
ON DUPLICATE KEY UPDATE
|
||||
product_name = excluded.product_name,
|
||||
category = excluded.category,
|
||||
total = excluded.total;
|
||||
QUERY PLAN
|
||||
-----------------------------------------------------------
|
||||
Insert on products_row (actual rows=4 loops=1)
|
||||
Conflict Resolution: UPDATE
|
||||
Conflict Arbiter Indexes: products_row_pkey
|
||||
-> Seq Scan on newproducts_row (actual rows=4 loops=1)
|
||||
--? Total runtime: .* ms
|
||||
(5 rows)
|
||||
|
||||
ROLLBACK;
|
||||
-- explain performance
|
||||
\o insert_update_explain.txt
|
||||
BEGIN;
|
||||
EXPLAIN PERFORMANCE
|
||||
INSERT INTO products_row
|
||||
SELECT product_id, product_name, category, total FROM newproducts_row
|
||||
ON DUPLICATE KEY UPDATE
|
||||
product_name = excluded.product_name,
|
||||
category = excluded.category,
|
||||
total = excluded.total;
|
||||
ROLLBACK;
|
||||
\o
|
||||
-- explain analyze
|
||||
BEGIN;
|
||||
EXPLAIN (ANALYZE on, COSTS off, TIMING off)
|
||||
INSERT INTO products_row
|
||||
SELECT product_id, product_name, category, total FROM newproducts_row
|
||||
ON DUPLICATE KEY UPDATE
|
||||
product_name = excluded.product_name,
|
||||
category = excluded.category,
|
||||
total = excluded.total;
|
||||
QUERY PLAN
|
||||
-----------------------------------------------------------
|
||||
Insert on products_row (actual rows=4 loops=1)
|
||||
Conflict Resolution: UPDATE
|
||||
Conflict Arbiter Indexes: products_row_pkey
|
||||
-> Seq Scan on newproducts_row (actual rows=4 loops=1)
|
||||
--? Total runtime: .* ms
|
||||
(5 rows)
|
||||
|
||||
ROLLBACK;
|
||||
-- pretty mode performance
|
||||
SET explain_perf_mode = pretty;
|
||||
-- explain verbose
|
||||
EXPLAIN (VERBOSE on, COSTS off)
|
||||
INSERT INTO products_row
|
||||
SELECT product_id, product_name, category, total FROM newproducts_row
|
||||
ON DUPLICATE KEY UPDATE
|
||||
product_name = excluded.product_name,
|
||||
category = excluded.category,
|
||||
total = excluded.total;
|
||||
QUERY PLAN
|
||||
---------------------------------------------------------------------------------------------------------------------------
|
||||
Insert on test_insert_update_008.products_row
|
||||
Conflict Resolution: UPDATE
|
||||
Conflict Arbiter Indexes: products_row_pkey
|
||||
-> Seq Scan on test_insert_update_008.newproducts_row
|
||||
Output: newproducts_row.product_id, newproducts_row.product_name, newproducts_row.category, newproducts_row.total
|
||||
(5 rows)
|
||||
|
||||
-- explain analyze
|
||||
BEGIN;
|
||||
EXPLAIN (ANALYZE on, COSTS off, TIMING off)
|
||||
INSERT INTO products_row
|
||||
SELECT product_id, product_name, category, total FROM newproducts_row
|
||||
ON DUPLICATE KEY UPDATE
|
||||
product_name = excluded.product_name,
|
||||
category = excluded.category,
|
||||
total = excluded.total;
|
||||
QUERY PLAN
|
||||
-----------------------------------------------------------
|
||||
Insert on products_row (actual rows=4 loops=1)
|
||||
Conflict Resolution: UPDATE
|
||||
Conflict Arbiter Indexes: products_row_pkey
|
||||
-> Seq Scan on newproducts_row (actual rows=4 loops=1)
|
||||
--? Total runtime: .* ms
|
||||
(5 rows)
|
||||
|
||||
ROLLBACK;
|
||||
-- explain analyze
|
||||
BEGIN;
|
||||
EXPLAIN (ANALYZE on, COSTS off, TIMING off)
|
||||
INSERT INTO products_row
|
||||
SELECT product_id, product_name, category, total FROM newproducts_row
|
||||
ON DUPLICATE KEY UPDATE
|
||||
product_name = excluded.product_name,
|
||||
category = excluded.category,
|
||||
total = excluded.total;
|
||||
QUERY PLAN
|
||||
-----------------------------------------------------------
|
||||
Insert on products_row (actual rows=4 loops=1)
|
||||
Conflict Resolution: UPDATE
|
||||
Conflict Arbiter Indexes: products_row_pkey
|
||||
-> Seq Scan on newproducts_row (actual rows=4 loops=1)
|
||||
--? Total runtime: .* ms
|
||||
(5 rows)
|
||||
|
||||
ROLLBACK;
|
||||
-- explain performance
|
||||
\o insert_update_explain_pretty.txt
|
||||
BEGIN;
|
||||
EXPLAIN PERFORMANCE
|
||||
INSERT INTO products_row
|
||||
SELECT product_id, product_name, category, total FROM newproducts_row
|
||||
ON DUPLICATE KEY UPDATE
|
||||
product_name = excluded.product_name,
|
||||
category = excluded.category,
|
||||
total = excluded.total;
|
||||
ROLLBACK;
|
||||
SET explain_perf_mode = run;
|
||||
BEGIN;
|
||||
EXPLAIN PERFORMANCE
|
||||
INSERT INTO products_row
|
||||
SELECT product_id, product_name, category, total FROM newproducts_row
|
||||
ON DUPLICATE KEY UPDATE
|
||||
product_name = excluded.product_name,
|
||||
category = excluded.category,
|
||||
total = excluded.total;
|
||||
ROLLBACK;
|
||||
SET explain_perf_mode = summary;
|
||||
BEGIN;
|
||||
EXPLAIN PERFORMANCE
|
||||
INSERT INTO products_row
|
||||
SELECT product_id, product_name, category, total FROM newproducts_row
|
||||
ON DUPLICATE KEY UPDATE
|
||||
product_name = excluded.product_name,
|
||||
category = excluded.category,
|
||||
total = excluded.total;
|
||||
ROLLBACK;
|
||||
\o
|
||||
CREATE TABLE item
|
||||
(
|
||||
a INT DEFAULT 3,
|
||||
item_id NUMERIC(18,10),
|
||||
item_name VARCHAR(100),
|
||||
item_level NUMERIC(39,0),
|
||||
item_desc VARCHAR(250),
|
||||
item_subclass_cd VARCHAR(50),
|
||||
item_type_cd VARCHAR(50),
|
||||
inventory_ind CHAR(300),
|
||||
vendor_party_id SMALLINT,
|
||||
commodity_cd VARCHAR(50),
|
||||
brand_cd VARCHAR(50),
|
||||
item_available CHAR(100),
|
||||
CONSTRAINT u_item_index UNIQUE (item_subclass_cd, vendor_party_id)
|
||||
)
|
||||
PARTITION BY RANGE (vendor_party_id)
|
||||
(
|
||||
PARTITION item_1 VALUES LESS THAN (0),
|
||||
PARTITION item_2 VALUES LESS THAN (1),
|
||||
PARTITION item_3 VALUES LESS THAN (2),
|
||||
PARTITION item_4 VALUES LESS THAN (3),
|
||||
PARTITION item_5 VALUES LESS THAN (6),
|
||||
PARTITION item_6 VALUES LESS THAN (8),
|
||||
PARTITION item_7 VALUES LESS THAN (10),
|
||||
PARTITION item_8 VALUES LESS THAN (15),
|
||||
PARTITION item_9 VALUES LESS THAN (MAXVALUE)
|
||||
) ENABLE ROW MOVEMENT;
|
||||
NOTICE: CREATE TABLE / UNIQUE will create implicit index "u_item_index" for table "item"
|
||||
CREATE TABLE region
|
||||
(
|
||||
a INT DEFAULT 8,
|
||||
region_cd VARCHAR(50),
|
||||
region_name VARCHAR(100),
|
||||
division_cd VARCHAR(50),
|
||||
region_mgr_associate_id number(18,9)
|
||||
);
|
||||
CREATE TABLE associate_benefit_expense
|
||||
(
|
||||
a INT DEFAULT 44,
|
||||
period_end_dt DATE,
|
||||
associate_expns_type_cd VARCHAR(50),
|
||||
associate_party_id INTEGER,
|
||||
benefit_hours_qty decimal(38,11),
|
||||
benefit_cost_amt number(38,4)
|
||||
)
|
||||
PARTITION BY RANGE (associate_expns_type_cd)
|
||||
(
|
||||
PARTITION associate_benefit_expense_1 VALUES LESS THAN ('B'),
|
||||
PARTITION associate_benefit_expense_2 VALUES LESS THAN ('E'),
|
||||
PARTITION associate_benefit_expense_3 VALUES LESS THAN ('G'),
|
||||
PARTITION associate_benefit_expense_4 VALUES LESS THAN ('I'),
|
||||
PARTITION associate_benefit_expense_5 VALUES LESS THAN ('L'),
|
||||
PARTITION associate_benefit_expense_6 VALUES LESS THAN ('N'),
|
||||
PARTITION associate_benefit_expense_7 VALUES LESS THAN ('P'),
|
||||
PARTITION associate_benefit_expense_8 VALUES LESS THAN ('Q'),
|
||||
PARTITION associate_benefit_expense_9 VALUES LESS THAN ('R'),
|
||||
PARTITION associate_benefit_expense_10 VALUES LESS THAN ('T'),
|
||||
PARTITION associate_benefit_expense_11 VALUES LESS THAN ('U'),
|
||||
PARTITION associate_benefit_expense_12 VALUES LESS THAN ('V'),
|
||||
PARTITION associate_benefit_expense_13 VALUES LESS THAN (MAXVALUE)
|
||||
) ENABLE ROW MOVEMENT;
|
||||
INSERT INTO item (ITEM_ID, ITEM_NAME, ITEM_DESC, ITEM_SUBCLASS_CD, ITEM_TYPE_CD, INVENTORY_IND, VENDOR_PARTY_ID, COMMODITY_CD, BRAND_CD,ITEM_AVAILABLE) VALUES (0.12, ' ' , 'A' , NULL, 'TGK' , 'A' , 2, 'A' , 'A' , 'Y');
|
||||
INSERT INTO item (ITEM_ID, ITEM_NAME, ITEM_DESC, ITEM_SUBCLASS_CD, ITEM_TYPE_CD, INVENTORY_IND, VENDOR_PARTY_ID, COMMODITY_CD, BRAND_CD,ITEM_AVAILABLE) VALUES (1.3, 'B' , NULL, 'B' , 'B' , NULL, 1, 'B' , NULL , 'N');
|
||||
INSERT INTO item (ITEM_ID, ITEM_NAME, ITEM_DESC, ITEM_SUBCLASS_CD, ITEM_TYPE_CD, INVENTORY_IND, VENDOR_PARTY_ID, COMMODITY_CD, BRAND_CD,ITEM_AVAILABLE) VALUES (2.23, 'C' , 'C' , NULL, 'C' , 'C' , 2, 'C' , 'C' , 'N');
|
||||
INSERT INTO item (ITEM_ID, ITEM_NAME, ITEM_DESC, ITEM_SUBCLASS_CD, ITEM_TYPE_CD, INVENTORY_IND, VENDOR_PARTY_ID, COMMODITY_CD, BRAND_CD,ITEM_AVAILABLE) VALUES (3.33, 'D' , 'D' , 'PT' , NULL, 'D' , 3, 'D' , 'D' , 'N');
|
||||
INSERT INTO item (ITEM_ID, ITEM_NAME, ITEM_DESC, ITEM_SUBCLASS_CD, ITEM_TYPE_CD, INVENTORY_IND, VENDOR_PARTY_ID, COMMODITY_CD, BRAND_CD,ITEM_AVAILABLE) VALUES (4.98, ' ' , NULL, 'E' , 'E' , 'E' , 4, 'E' , 'E' , 'Y');
|
||||
INSERT INTO item (ITEM_ID, ITEM_NAME, ITEM_DESC, ITEM_SUBCLASS_CD, ITEM_TYPE_CD, INVENTORY_IND, VENDOR_PARTY_ID, COMMODITY_CD, BRAND_CD,ITEM_AVAILABLE) VALUES (5.01, NULL, 'F' , ' ' , 'F' , 'F' , 5, 'F' , 'F' , 'N');
|
||||
INSERT INTO item (ITEM_ID, ITEM_NAME, ITEM_DESC, ITEM_SUBCLASS_CD, ITEM_TYPE_CD, INVENTORY_IND, VENDOR_PARTY_ID, COMMODITY_CD, BRAND_CD,ITEM_AVAILABLE) VALUES (6, 'G' , 'G' , 'G' , '_D' , 'G' , 6, 'G' , NULL ,'N');
|
||||
INSERT INTO item (ITEM_ID, ITEM_NAME, ITEM_DESC, ITEM_SUBCLASS_CD, ITEM_TYPE_CD, INVENTORY_IND, VENDOR_PARTY_ID, COMMODITY_CD, BRAND_CD,ITEM_AVAILABLE) VALUES (0.7, NULL, NULL, NULL, 'H' , 'H' , 7, NULL, 'G' , 'Y');
|
||||
INSERT INTO item (ITEM_ID, ITEM_NAME, ITEM_DESC, ITEM_SUBCLASS_CD, ITEM_TYPE_CD, INVENTORY_IND, VENDOR_PARTY_ID, COMMODITY_CD, BRAND_CD,ITEM_AVAILABLE) VALUES (0.08, 'I' , ' ' , ' T ' , NULL, 'I' , 8, 'I' , '' , 'N');
|
||||
INSERT INTO item (ITEM_ID, ITEM_NAME, ITEM_DESC, ITEM_SUBCLASS_CD, ITEM_TYPE_CD, INVENTORY_IND, VENDOR_PARTY_ID, COMMODITY_CD, BRAND_CD,ITEM_AVAILABLE) VALUES (9.12, ' ' , 'J' , ' PP' , 'J' , 'J' , 9, 'J' , NULL , 'Y');
|
||||
INSERT INTO item (ITEM_ID, ITEM_NAME, ITEM_DESC, ITEM_SUBCLASS_CD, ITEM_TYPE_CD, INVENTORY_IND, VENDOR_PARTY_ID, COMMODITY_CD, BRAND_CD,ITEM_AVAILABLE) VALUES (10.10, NULL, ' ' , 'A' , 'A' , 'A' , 2, NULL, 'A','Y');
|
||||
--INSERT INTO item (ITEM_ID, ITEM_NAME, ITEM_DESC, ITEM_SUBCLASS_CD, ITEM_TYPE_CD, INVENTORY_IND, VENDOR_PARTY_ID, COMMODITY_CD, BRAND_CD,ITEM_AVAILABLE) VALUES (11.11, 'B' , 'B' , 'B' , 'BCDAA' , NULL, 1, 'B' , 'B','N');
|
||||
INSERT INTO item (ITEM_ID, ITEM_NAME, ITEM_DESC, ITEM_SUBCLASS_CD, ITEM_TYPE_CD, INVENTORY_IND, VENDOR_PARTY_ID, COMMODITY_CD, BRAND_CD,ITEM_AVAILABLE) VALUES (12.02, 'D' , NULL, NULL, 'C' , 'C' , 2, 'C' , 'C','N');
|
||||
INSERT INTO item (ITEM_ID, ITEM_NAME, ITEM_DESC, ITEM_SUBCLASS_CD, ITEM_TYPE_CD, INVENTORY_IND, VENDOR_PARTY_ID, COMMODITY_CD, BRAND_CD,ITEM_AVAILABLE) VALUES (13.99, NULL, ' ' , 'D' , 'D' , 'D' , 3, 'D' , 'D','Y');
|
||||
--INSERT INTO item (ITEM_ID, ITEM_NAME, ITEM_DESC, ITEM_SUBCLASS_CD, ITEM_TYPE_CD, INVENTORY_IND, VENDOR_PARTY_ID, COMMODITY_CD, BRAND_CD,ITEM_AVAILABLE) VALUES (14, 'G' , 'E' , 'E' , NULL, 'E' , 4, 'E' , 'E','N');
|
||||
INSERT INTO item (ITEM_ID, ITEM_NAME, ITEM_DESC, ITEM_SUBCLASS_CD, ITEM_TYPE_CD, INVENTORY_IND, VENDOR_PARTY_ID, COMMODITY_CD, BRAND_CD,ITEM_AVAILABLE) VALUES (15, 'F' , ' ' , 'C' , 'CLEANING' , 'F' , 5, 'F' , 'F','Y');
|
||||
INSERT INTO item (ITEM_ID, ITEM_NAME, ITEM_DESC, ITEM_SUBCLASS_CD, ITEM_TYPE_CD, INVENTORY_IND, VENDOR_PARTY_ID, COMMODITY_CD, BRAND_CD,ITEM_AVAILABLE) VALUES (16, '' , 'Z' , NULL, 'G' , 'G' , 6, 'G' , NULL,'N');
|
||||
INSERT INTO item (ITEM_ID, ITEM_NAME, ITEM_DESC, ITEM_SUBCLASS_CD, ITEM_TYPE_CD, INVENTORY_IND, VENDOR_PARTY_ID, COMMODITY_CD, BRAND_CD,ITEM_AVAILABLE) VALUES (17, NULL, '' , ' PAPER' , 'H' , '' , 7, NULL, NULL,'Y');
|
||||
INSERT INTO item (ITEM_ID, ITEM_NAME, ITEM_DESC, ITEM_SUBCLASS_CD, ITEM_TYPE_CD, INVENTORY_IND, VENDOR_PARTY_ID, COMMODITY_CD, BRAND_CD,ITEM_AVAILABLE) VALUES (19, ' ' , 'B' , '' , '' , 'I' , 8, 'I' , NULL,'N');
|
||||
INSERT INTO item (ITEM_ID, ITEM_NAME, ITEM_DESC, ITEM_SUBCLASS_CD, ITEM_TYPE_CD, INVENTORY_IND, VENDOR_PARTY_ID, COMMODITY_CD, BRAND_CD,ITEM_AVAILABLE) VALUES (20 , 'A' , 'J' , 'J' , 'J' , NULL, 9, 'J' , 'G','Y');
|
||||
/*--REGION--*/
|
||||
INSERT INTO REGION (REGION_CD, REGION_NAME, DIVISION_CD, REGION_MGR_ASSOCIATE_ID) VALUES ('A', 'A ', 'A', 0.123433);
|
||||
INSERT INTO REGION (REGION_CD, REGION_NAME, DIVISION_CD, REGION_MGR_ASSOCIATE_ID) VALUES ('B', 'B', 'B', NULL);
|
||||
INSERT INTO REGION (REGION_CD, REGION_NAME, DIVISION_CD, REGION_MGR_ASSOCIATE_ID) VALUES ('C', 'C', 'C', 2.232008908);
|
||||
INSERT INTO REGION (REGION_CD, REGION_NAME, DIVISION_CD, REGION_MGR_ASSOCIATE_ID) VALUES ('D', ' DD', 'D', 3.878789);
|
||||
INSERT INTO REGION (REGION_CD, REGION_NAME, DIVISION_CD, REGION_MGR_ASSOCIATE_ID) VALUES ('E', 'A', 'E', 4.89060603);
|
||||
INSERT INTO REGION (REGION_CD, REGION_NAME, DIVISION_CD, REGION_MGR_ASSOCIATE_ID) VALUES ('F', 'F', 'F', 5.82703827);
|
||||
INSERT INTO REGION (REGION_CD, REGION_NAME, DIVISION_CD, REGION_MGR_ASSOCIATE_ID) VALUES ('G', 'G', 'TTT', NULL);
|
||||
INSERT INTO REGION (REGION_CD, REGION_NAME, DIVISION_CD, REGION_MGR_ASSOCIATE_ID) VALUES ('H', 'H', 'G', 7.3829083);
|
||||
INSERT INTO REGION (REGION_CD, REGION_NAME, DIVISION_CD, REGION_MGR_ASSOCIATE_ID) VALUES ('I', 'C', 'M', 8.983989);
|
||||
INSERT INTO REGION (REGION_CD, REGION_NAME, DIVISION_CD, REGION_MGR_ASSOCIATE_ID) VALUES ('J', 'J', 'G', NULL);
|
||||
INSERT INTO REGION (REGION_CD, REGION_NAME, DIVISION_CD, REGION_MGR_ASSOCIATE_ID) VALUES ('K', ' ', 'C', 2.232008908);
|
||||
INSERT INTO REGION (REGION_CD, REGION_NAME, DIVISION_CD, REGION_MGR_ASSOCIATE_ID) VALUES ('L', 'D', 'X', 3.878789);
|
||||
INSERT INTO REGION (REGION_CD, REGION_NAME, DIVISION_CD, REGION_MGR_ASSOCIATE_ID) VALUES ('M', 'TTTTTT ', 'D' , 4.89060603);
|
||||
INSERT INTO REGION (REGION_CD, REGION_NAME, DIVISION_CD, REGION_MGR_ASSOCIATE_ID) VALUES ('N', 'G' , 'B' , NULL);
|
||||
INSERT INTO REGION (REGION_CD, REGION_NAME, DIVISION_CD, REGION_MGR_ASSOCIATE_ID) VALUES ('O' , 'G', 'F', 6.6703972);
|
||||
INSERT INTO ASSOCIATE_BENEFIT_EXPENSE (PERIOD_END_DT, ASSOCIATE_EXPNS_TYPE_CD, ASSOCIATE_PARTY_ID, BENEFIT_HOURS_QTY, BENEFIT_COST_AMT) VALUES (DATE '1970-01-01', 'A', 5, 0.5 , 0.5);
|
||||
INSERT INTO ASSOCIATE_BENEFIT_EXPENSE (PERIOD_END_DT, ASSOCIATE_EXPNS_TYPE_CD, ASSOCIATE_PARTY_ID, BENEFIT_HOURS_QTY, BENEFIT_COST_AMT) VALUES (DATE '1973-01-01', 'B', 1, NULL, 1.0);
|
||||
INSERT INTO ASSOCIATE_BENEFIT_EXPENSE (PERIOD_END_DT, ASSOCIATE_EXPNS_TYPE_CD, ASSOCIATE_PARTY_ID, BENEFIT_HOURS_QTY, BENEFIT_COST_AMT) VALUES (DATE '1976-01-01', 'C', 2, 2.0 , NULL);
|
||||
INSERT INTO ASSOCIATE_BENEFIT_EXPENSE (PERIOD_END_DT, ASSOCIATE_EXPNS_TYPE_CD, ASSOCIATE_PARTY_ID, BENEFIT_HOURS_QTY, BENEFIT_COST_AMT) VALUES (DATE '1979-01-01', 'D', 3, 3.0 , 3.0);
|
||||
INSERT INTO ASSOCIATE_BENEFIT_EXPENSE (PERIOD_END_DT, ASSOCIATE_EXPNS_TYPE_CD, ASSOCIATE_PARTY_ID, BENEFIT_HOURS_QTY, BENEFIT_COST_AMT) VALUES (DATE '1982-01-01', 'E', 4, 4.0 , 4.0);
|
||||
INSERT INTO ASSOCIATE_BENEFIT_EXPENSE (PERIOD_END_DT, ASSOCIATE_EXPNS_TYPE_CD, ASSOCIATE_PARTY_ID, BENEFIT_HOURS_QTY, BENEFIT_COST_AMT) VALUES (DATE '1985-01-01', 'F', 5, 5.0 , 5.0);
|
||||
INSERT INTO ASSOCIATE_BENEFIT_EXPENSE (PERIOD_END_DT, ASSOCIATE_EXPNS_TYPE_CD, ASSOCIATE_PARTY_ID, BENEFIT_HOURS_QTY, BENEFIT_COST_AMT) VALUES (DATE '1988-01-01', 'F', 6, NULL, 6.0);
|
||||
INSERT INTO ASSOCIATE_BENEFIT_EXPENSE (PERIOD_END_DT, ASSOCIATE_EXPNS_TYPE_CD, ASSOCIATE_PARTY_ID, BENEFIT_HOURS_QTY, BENEFIT_COST_AMT) VALUES (DATE '1991-01-01', 'G', 6, NULL, NULL);
|
||||
INSERT INTO ASSOCIATE_BENEFIT_EXPENSE (PERIOD_END_DT, ASSOCIATE_EXPNS_TYPE_CD, ASSOCIATE_PARTY_ID, BENEFIT_HOURS_QTY, BENEFIT_COST_AMT) VALUES (DATE '1994-01-01', 'G', 15, 8.0 , 8.0);
|
||||
INSERT INTO ASSOCIATE_BENEFIT_EXPENSE (PERIOD_END_DT, ASSOCIATE_EXPNS_TYPE_CD, ASSOCIATE_PARTY_ID, BENEFIT_HOURS_QTY, BENEFIT_COST_AMT) VALUES (DATE '1997-01-01', 'G', 16, 9.0 , 9.0);
|
||||
INSERT INTO ASSOCIATE_BENEFIT_EXPENSE (PERIOD_END_DT, ASSOCIATE_EXPNS_TYPE_CD, ASSOCIATE_PARTY_ID, BENEFIT_HOURS_QTY, BENEFIT_COST_AMT) VALUES (DATE '1983-01-03', 'I', 14, 4.0 , 4.0);
|
||||
INSERT INTO ASSOCIATE_BENEFIT_EXPENSE (PERIOD_END_DT, ASSOCIATE_EXPNS_TYPE_CD, ASSOCIATE_PARTY_ID, BENEFIT_HOURS_QTY, BENEFIT_COST_AMT) VALUES (DATE '1984-01-01', 'GO', 15, 5.0 , NULL);
|
||||
INSERT INTO ASSOCIATE_BENEFIT_EXPENSE (PERIOD_END_DT, ASSOCIATE_EXPNS_TYPE_CD, ASSOCIATE_PARTY_ID, BENEFIT_HOURS_QTY, BENEFIT_COST_AMT) VALUES (DATE '1985-05-01', 'I', 16, 6.0 , 6.0);
|
||||
INSERT INTO ASSOCIATE_BENEFIT_EXPENSE (PERIOD_END_DT, ASSOCIATE_EXPNS_TYPE_CD, ASSOCIATE_PARTY_ID, BENEFIT_HOURS_QTY, BENEFIT_COST_AMT) VALUES (DATE '1990-01-01', 'TTT', 16, NULL, 7.0);
|
||||
INSERT INTO ASSOCIATE_BENEFIT_EXPENSE (PERIOD_END_DT, ASSOCIATE_EXPNS_TYPE_CD, ASSOCIATE_PARTY_ID, BENEFIT_HOURS_QTY, BENEFIT_COST_AMT) VALUES (DATE '1992-02-01', 'A', 15, 8.0 , 8.0);
|
||||
INSERT INTO ASSOCIATE_BENEFIT_EXPENSE (PERIOD_END_DT, ASSOCIATE_EXPNS_TYPE_CD, ASSOCIATE_PARTY_ID, BENEFIT_HOURS_QTY, BENEFIT_COST_AMT) VALUES (DATE '1997-02-01', 'G', 17, 9.0 , NULL);
|
||||
INSERT INTO ASSOCIATE_BENEFIT_EXPENSE (PERIOD_END_DT, ASSOCIATE_EXPNS_TYPE_CD, ASSOCIATE_PARTY_ID, BENEFIT_HOURS_QTY, BENEFIT_COST_AMT) VALUES (DATE '1997-05-01', 'G' , 17, 9.0 , NULL);
|
||||
ANALYZE item;
|
||||
ANALYZE region;
|
||||
ANALYZE associate_benefit_expense;
|
||||
EXPLAIN (VERBOSE ON, COSTS OFF)
|
||||
INSERT INTO item (item_level, item_subclass_cd, item_desc, vendor_party_id)
|
||||
SELECT Table_001.REGION_MGR_ASSOCIATE_ID Column_003,
|
||||
Table_002.associate_expns_type_cd Column_004,
|
||||
CAST(Table_001.region_name AS VARCHAR) Column_005,
|
||||
10 Column_006
|
||||
-- 'o' Column_007,
|
||||
-- 'F' Column_008,
|
||||
-- pg_client_encoding() Column_009
|
||||
FROM region Table_001, associate_benefit_expense Table_002
|
||||
ON DUPLICATE KEY UPDATE item_level = -1000;
|
||||
QUERY PLAN
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
Insert on test_insert_update_008.item
|
||||
Conflict Resolution: UPDATE
|
||||
Conflict Arbiter Indexes: u_item_index
|
||||
-> Nested Loop
|
||||
Output: 3, NULL::numeric, NULL::character varying, table_001.region_mgr_associate_id, (table_001.region_name)::character varying(250), table_002.associate_expns_type_cd, NULL::character varying, NULL::bpchar, 10::smallint, NULL::character varying, NULL::character varying, NULL::bpchar
|
||||
-> Partition Iterator
|
||||
Output: table_002.a, table_002.period_end_dt, table_002.associate_expns_type_cd, table_002.associate_party_id, table_002.benefit_hours_qty, table_002.benefit_cost_amt
|
||||
Iterations: 13
|
||||
-> Partitioned Seq Scan on test_insert_update_008.associate_benefit_expense table_002
|
||||
Output: table_002.a, table_002.period_end_dt, table_002.associate_expns_type_cd, table_002.associate_party_id, table_002.benefit_hours_qty, table_002.benefit_cost_amt
|
||||
Selected Partitions: 1..13
|
||||
-> Materialize
|
||||
Output: table_001.region_mgr_associate_id, table_001.region_name
|
||||
-> Seq Scan on test_insert_update_008.region table_001
|
||||
Output: table_001.region_mgr_associate_id, table_001.region_name
|
||||
(15 rows)
|
||||
|
||||
EXPLAIN (VERBOSE ON, COSTS OFF)
|
||||
INSERT INTO products_row VALUES(100)
|
||||
ON DUPLICATE KEY UPDATE total=100;
|
||||
QUERY PLAN
|
||||
-----------------------------------------------------------------------------------------
|
||||
Insert on test_insert_update_008.products_row
|
||||
Conflict Resolution: UPDATE
|
||||
Conflict Arbiter Indexes: products_row_pkey
|
||||
-> Result
|
||||
Output: 100, 'null'::character varying(60), 'unknown'::character varying(60), 0
|
||||
(5 rows)
|
||||
|
||||
SET enable_light_proxy=off;
|
||||
EXPLAIN (VERBOSE ON, COSTS OFF)
|
||||
INSERT INTO products_row VALUES(100)
|
||||
ON DUPLICATE KEY UPDATE total=100;
|
||||
QUERY PLAN
|
||||
-----------------------------------------------------------------------------------------
|
||||
Insert on test_insert_update_008.products_row
|
||||
Conflict Resolution: UPDATE
|
||||
Conflict Arbiter Indexes: products_row_pkey
|
||||
-> Result
|
||||
Output: 100, 'null'::character varying(60), 'unknown'::character varying(60), 0
|
||||
(5 rows)
|
||||
|
||||
EXPLAIN (VERBOSE ON, COSTS OFF)
|
||||
INSERT INTO products_row VALUES(100)
|
||||
ON DUPLICATE KEY UPDATE total=100;
|
||||
QUERY PLAN
|
||||
-----------------------------------------------------------------------------------------
|
||||
Insert on test_insert_update_008.products_row
|
||||
Conflict Resolution: UPDATE
|
||||
Conflict Arbiter Indexes: products_row_pkey
|
||||
-> Result
|
||||
Output: 100, 'null'::character varying(60), 'unknown'::character varying(60), 0
|
||||
(5 rows)
|
||||
|
||||
EXPLAIN (VERBOSE ON, COSTS OFF)
|
||||
INSERT INTO products_row VALUES(100)
|
||||
ON DUPLICATE KEY UPDATE total=100;
|
||||
QUERY PLAN
|
||||
-----------------------------------------------------------------------------------------
|
||||
Insert on test_insert_update_008.products_row
|
||||
Conflict Resolution: UPDATE
|
||||
Conflict Arbiter Indexes: products_row_pkey
|
||||
-> Result
|
||||
Output: 100, 'null'::character varying(60), 'unknown'::character varying(60), 0
|
||||
(5 rows)
|
||||
|
||||
RESET enable_light_proxy;
|
||||
DROP SCHEMA test_insert_update_008 CASCADE;
|
||||
NOTICE: drop cascades to 7 other objects
|
||||
DETAIL: drop cascades to table products_base
|
||||
drop cascades to table newproducts_base
|
||||
drop cascades to table products_row
|
||||
drop cascades to table newproducts_row
|
||||
drop cascades to table item
|
||||
drop cascades to table region
|
||||
drop cascades to table associate_benefit_expense
|
||||
|
|
@ -0,0 +1,548 @@
|
|||
DROP SCHEMA test_insert_update_009 CASCADE;
|
||||
ERROR: schema "test_insert_update_009" does not exist
|
||||
CREATE SCHEMA test_insert_update_009;
|
||||
SET CURRENT_SCHEMA TO test_insert_update_009;
|
||||
SET enable_light_proxy=off;
|
||||
-- enable_upsert_to_merge must is off, or upsert will be translated to merge.
|
||||
SET enable_upsert_to_merge TO OFF;
|
||||
-- test t1 with no index
|
||||
CREATE TABLE t1 (
|
||||
col1 INT,
|
||||
col2 INT,
|
||||
col3 INT DEFAULT 1,
|
||||
-- col4 TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
col5 BIGSERIAL
|
||||
) ;
|
||||
NOTICE: CREATE TABLE will create implicit sequence "t1_col5_seq" for serial column "t1.col5"
|
||||
--- distribute key are not allowed to update
|
||||
INSERT INTO t1 VALUES (1, 2) ON DUPLICATE KEY UPDATE col1 = 3;
|
||||
--- should always insert
|
||||
INSERT INTO t1 VALUES (1, 2) ON DUPLICATE KEY UPDATE col2 = 3;
|
||||
INSERT INTO t1 VALUES (1, 2) ON DUPLICATE KEY UPDATE t1.col2 = 4;
|
||||
--- appoint column list in insert clause, should always insert
|
||||
INSERT INTO t1(col1, col3) VALUES (1, 3) ON DUPLICATE KEY UPDATE col2 = 5;
|
||||
INSERT INTO t1(col1, col3) VALUES (1, 3) ON DUPLICATE KEY UPDATE t1.col2 = 6;
|
||||
--- multiple rows, should always insert
|
||||
INSERT INTO t1 VALUES (2, 1), (2, 1) ON DUPLICATE KEY UPDATE col2 = 7, col3 = 7;
|
||||
SELECT * FROM t1 ORDER BY col5;
|
||||
col1 | col2 | col3 | col5
|
||||
------+------+------+------
|
||||
1 | 2 | 1 | 1
|
||||
1 | 2 | 1 | 2
|
||||
1 | 2 | 1 | 3
|
||||
1 | | 3 | 4
|
||||
1 | | 3 | 5
|
||||
2 | 1 | 1 | 6
|
||||
2 | 1 | 1 | 7
|
||||
(7 rows)
|
||||
|
||||
--- test union, should insert
|
||||
INSERT INTO t1 (col1, col2)
|
||||
SELECT * FROM
|
||||
(SELECT col1, col2 FROM t1
|
||||
UNION
|
||||
SELECT col1, col3 FROM t1) AS union_table
|
||||
ON DUPLICATE KEY UPDATE col3 = (col1 + col2 + col3);
|
||||
SELECT col1, col2, col3 FROM t1 WHERE col5 > 6 ORDER BY col1, col2;
|
||||
col1 | col2 | col3
|
||||
------+------+------
|
||||
1 | 1 | 1
|
||||
1 | 2 | 1
|
||||
1 | 3 | 1
|
||||
1 | | 1
|
||||
2 | 1 | 1
|
||||
2 | 1 | 1
|
||||
(6 rows)
|
||||
|
||||
--- test subquery, should insert
|
||||
INSERT INTO t1
|
||||
(SELECT col1 || col2 || '00' FROM t1 ORDER BY col5)
|
||||
ON DUPLICATE KEY UPDATE col3 = col1 * 100;
|
||||
SELECT col1, col2, col3 FROM t1 WHERE col1 >= 100 ORDER BY col1;
|
||||
col1 | col2 | col3
|
||||
------+------+------
|
||||
100 | | 1
|
||||
100 | | 1
|
||||
100 | | 1
|
||||
1100 | | 1
|
||||
1200 | | 1
|
||||
1200 | | 1
|
||||
1200 | | 1
|
||||
1200 | | 1
|
||||
1300 | | 1
|
||||
2100 | | 1
|
||||
2100 | | 1
|
||||
2100 | | 1
|
||||
(12 rows)
|
||||
|
||||
-- test t2 with one primary key
|
||||
CREATE TABLE t2 (
|
||||
col1 INT,
|
||||
col2 INT PRIMARY KEY,
|
||||
col3 INT DEFAULT 1,
|
||||
col4 TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
col5 BIGSERIAL
|
||||
) ;
|
||||
NOTICE: CREATE TABLE will create implicit sequence "t2_col5_seq" for serial column "t2.col5"
|
||||
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "t2_pkey" for table "t2"
|
||||
--- distribute key are not allowed to update
|
||||
INSERT INTO t2 VALUES (1, 1) ON DUPLICATE KEY UPDATE col2 = 3;
|
||||
ERROR: INSERT ON DUPLICATE KEY UPDATE don't allow update on primary key or unique key.
|
||||
INSERT INTO t2 VALUES (1, 1) ON DUPLICATE KEY UPDATE t2.col2 = 3;
|
||||
ERROR: INSERT ON DUPLICATE KEY UPDATE don't allow update on primary key or unique key.
|
||||
INSERT INTO t2 (col2, col3, col4, col5)
|
||||
VALUES (10, 10, CURRENT_TIMESTAMP(0), 10),
|
||||
(20, 20, CURRENT_TIMESTAMP(1), 20),
|
||||
(30, 30, CURRENT_TIMESTAMP(2), 30)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
col1 = 100,
|
||||
col2 = 100,
|
||||
col3 = 100,
|
||||
col4 = '2019-08-09'::TIMESTAMP,
|
||||
col5 = 100;
|
||||
ERROR: INSERT ON DUPLICATE KEY UPDATE don't allow update on primary key or unique key.
|
||||
--- should insert
|
||||
INSERT INTO t2 VALUES (1, 1) ON DUPLICATE KEY UPDATE col1 = 30;
|
||||
INSERT INTO t2 VALUES (2, 2) ON DUPLICATE KEY UPDATE t2.col1 = 40;
|
||||
INSERT INTO t2 VALUES (3, 3) ON DUPLICATE KEY UPDATE col1 = col1 * 2;
|
||||
INSERT INTO t2 VALUES (4, 4) ON DUPLICATE KEY UPDATE t2.col1 = t2.col1 * 2 ;
|
||||
INSERT INTO t2 VALUES (5, 5) ON DUPLICATE KEY UPDATE col1 = col2 + 1;
|
||||
INSERT INTO t2 VALUES (6, 6) ON DUPLICATE KEY UPDATE t2.col1 = t2.col2 + 1;
|
||||
INSERT INTO t2 VALUES (7, 7) ON DUPLICATE KEY UPDATE col1 = extract(dow from col4) + 10;
|
||||
INSERT INTO t2 VALUES (8, 8) ON DUPLICATE KEY UPDATE t2.col1 = extract(century from col4) * 100 + extract(isodow from col4);
|
||||
SELECT col1, col2, col3, col5 FROM t2 ORDER BY col5;
|
||||
col1 | col2 | col3 | col5
|
||||
------+------+------+------
|
||||
1 | 1 | 1 | 1
|
||||
2 | 2 | 1 | 2
|
||||
3 | 3 | 1 | 3
|
||||
4 | 4 | 1 | 4
|
||||
5 | 5 | 1 | 5
|
||||
6 | 6 | 1 | 6
|
||||
7 | 7 | 1 | 7
|
||||
8 | 8 | 1 | 8
|
||||
(8 rows)
|
||||
|
||||
--- should update
|
||||
INSERT INTO t2 VALUES (3, 1) ON DUPLICATE KEY UPDATE col1 = 30, col3 = col5 + 1;
|
||||
INSERT INTO t2 VALUES (4, 2) ON DUPLICATE KEY UPDATE t2.col1 = 40, t2.col3 = t2.col5;
|
||||
INSERT INTO t2 VALUES (3, 3), (4, 4) ON DUPLICATE KEY UPDATE col3 = t2.col5 + 1;
|
||||
INSERT INTO t2 VALUES (5, 5) ON DUPLICATE KEY UPDATE col1 = extract(dow from col4) + 10;
|
||||
INSERT INTO t2 VALUES (6, 6) ON DUPLICATE KEY UPDATE t2.col1 = extract(century from col4) * 100 + extract(isodow from col4);
|
||||
SELECT col1, col2, col3, col5 FROM t2 ORDER BY col5;
|
||||
col1 | col2 | col3 | col5
|
||||
------+------+------+------
|
||||
30 | 1 | 2 | 1
|
||||
40 | 2 | 2 | 2
|
||||
3 | 3 | 4 | 3
|
||||
4 | 4 | 5 | 4
|
||||
--?.*| 5 | 1 | 5
|
||||
--?.*| 6 | 1 | 6
|
||||
7 | 7 | 1 | 7
|
||||
8 | 8 | 1 | 8
|
||||
(8 rows)
|
||||
|
||||
-- primary key are not allowed to be null
|
||||
INSERT INTO t2 (col1) VALUES (10) ON DUPLICATE KEY UPDATE col1 = 10;
|
||||
ERROR: null value in column "col2" violates not-null constraint
|
||||
--?
|
||||
--- appoint column list in insert clause
|
||||
---- should insert
|
||||
INSERT INTO t2 (col2, col3) VALUES (9, 9) ON DUPLICATE KEY UPDATE col1 = 90;
|
||||
INSERT INTO t2 (col2, col3, col4, col5)
|
||||
VALUES (10, 10, CURRENT_TIMESTAMP(0), 10),
|
||||
(20, 20, CURRENT_TIMESTAMP(1), 20),
|
||||
(30, 30, CURRENT_TIMESTAMP(2), 30)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
col1 = 100,
|
||||
col3 = 100,
|
||||
col4 = '2019-08-20'::TIMESTAMP,
|
||||
col5 = 100;
|
||||
SELECT * FROM t2 ORDER BY col5;
|
||||
col1 | col2 | col3 | col4 | col5
|
||||
------+------+------+---------------------------------+------
|
||||
--? 30 | 1 | 2 | .* | 1
|
||||
--? 40 | 2 | 2 | .* | 2
|
||||
--? 3 | 3 | 4 | .* | 3
|
||||
--? 4 | 4 | 5 | .* | 4
|
||||
--? .* | 5 | 1 | .* | 5
|
||||
--? .* | 6 | 1 | .* | 6
|
||||
--? 7 | 7 | 1 | .* | 7
|
||||
--? 8 | 8 | 1 | .* | 8
|
||||
--? | 9 | 9 | .* | 10
|
||||
--? | 10 | 10 | .* | 10
|
||||
--? | 20 | 20 | .* | 20
|
||||
--? | 30 | 30 | .* | 30
|
||||
(12 rows)
|
||||
|
||||
---- should update
|
||||
INSERT INTO t2 (col2, col3) VALUES (9, 9) ON DUPLICATE KEY UPDATE col1 = 90;
|
||||
INSERT INTO t2 (col2, col3, col4, col5)
|
||||
VALUES (10, 10, CURRENT_TIMESTAMP(0), 10),
|
||||
(20, 20, CURRENT_TIMESTAMP(1), 20),
|
||||
(30, 30, CURRENT_TIMESTAMP(2), 30)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
col1 = 100,
|
||||
col3 = 100,
|
||||
col4 = '2019-08-20'::TIMESTAMP,
|
||||
col5 = 100;
|
||||
SELECT * FROM t2 ORDER BY col5, col2;
|
||||
col1 | col2 | col3 | col4 | col5
|
||||
------+------+------+---------------------------------+------
|
||||
--? 30 | 1 | 2 | .* | 1
|
||||
--? 40 | 2 | 2 | .* | 2
|
||||
--? 3 | 3 | 4 | .* | 3
|
||||
--? 4 | 4 | 5 | .* | 4
|
||||
--? .* | 5 | 1 | .* | 5
|
||||
--? .* | 6 | 1 | .* | 6
|
||||
--? 7 | 7 | 1 | .* | 7
|
||||
--? 8 | 8 | 1 | .* | 8
|
||||
--? 90 | 9 | 9 | .* | 10
|
||||
100 | 10 | 100 | Tue Aug 20 00:00:00 2019 | 100
|
||||
100 | 20 | 100 | Tue Aug 20 00:00:00 2019 | 100
|
||||
100 | 30 | 100 | Tue Aug 20 00:00:00 2019 | 100
|
||||
(12 rows)
|
||||
|
||||
--- test subquery
|
||||
---- should insert
|
||||
INSERT INTO t2
|
||||
(SELECT col1 * 1000, col2 * 1000 + 1 FROM t2 ORDER BY col5 LIMIT 2)
|
||||
ON DUPLICATE KEY UPDATE col3 = col2 + 1;
|
||||
INSERT INTO t2 (col2, col3)
|
||||
(SELECT col1 * 1000 + 2, col2 * 1000 FROM t2 ORDER BY col5 LIMIT 2 OFFSET 1)
|
||||
ON DUPLICATE KEY UPDATE col3 = col2 + 1;
|
||||
SELECT col1, col2, col3, col5 FROM t2 ORDER BY col5, col2;
|
||||
col1 | col2 | col3 | col5
|
||||
-------+-------+------+------
|
||||
30 | 1 | 2 | 1
|
||||
40 | 2 | 2 | 2
|
||||
3 | 3 | 4 | 3
|
||||
4 | 4 | 5 | 4
|
||||
--? .* | 5 | 1 | 5
|
||||
--? .* | 6 | 1 | 6
|
||||
7 | 7 | 1 | 7
|
||||
8 | 8 | 1 | 8
|
||||
90 | 9 | 9 | 16
|
||||
--? 30000 | 1001 | 1 | 11
|
||||
--? 40000 | 2001 | 1 | 12
|
||||
--? | 40002 | 2000 | 13
|
||||
--? | 3002 | 3000 | 14
|
||||
100 | 10 | 100 | 100
|
||||
100 | 20 | 100 | 100
|
||||
100 | 30 | 100 | 100
|
||||
(16 rows)
|
||||
|
||||
---- should update
|
||||
INSERT INTO t2
|
||||
(SELECT col1 * 1000, col2 * 1000 + 1 FROM t2 ORDER BY col5 LIMIT 2)
|
||||
ON DUPLICATE KEY UPDATE col3 = col2 + 1;
|
||||
INSERT INTO t2 (col2, col3)
|
||||
(SELECT col1 * 1000 + 2, col2 * 1000 FROM t2 ORDER BY col5 LIMIT 2 OFFSET 1)
|
||||
ON DUPLICATE KEY UPDATE col3 = col2 + 1;
|
||||
SELECT col1, col2, col3, col5 FROM t2 ORDER BY col5, col2;
|
||||
col1 | col2 | col3 | col5
|
||||
-------+-------+-------+------
|
||||
30 | 1 | 2 | 1
|
||||
40 | 2 | 2 | 2
|
||||
3 | 3 | 4 | 3
|
||||
4 | 4 | 5 | 4
|
||||
--? 2 | 5 | 1 | 5
|
||||
--? 2101 | 6 | 1 | 6
|
||||
7 | 7 | 1 | 7
|
||||
8 | 8 | 1 | 8
|
||||
90 | 9 | 9 | 16
|
||||
--? 30000 | 1001 | 1002 | 11
|
||||
--? 40000 | 2001 | 2002 | 12
|
||||
--? | 40002 | 40003 | 13
|
||||
--? | 3002 | 3003 | 14
|
||||
100 | 10 | 100 | 100
|
||||
100 | 20 | 100 | 100
|
||||
100 | 30 | 100 | 100
|
||||
(16 rows)
|
||||
|
||||
--- test union, some insert some update
|
||||
SELECT col1, col2 FROM t1 WHERE col2 IS NOT NULL
|
||||
UNION
|
||||
SELECT col1, col3 FROM t1 ORDER BY 1, 2;
|
||||
col1 | col2
|
||||
------+------
|
||||
1 | 1
|
||||
1 | 2
|
||||
1 | 3
|
||||
2 | 1
|
||||
100 | 1
|
||||
1100 | 1
|
||||
1200 | 1
|
||||
1300 | 1
|
||||
2100 | 1
|
||||
(9 rows)
|
||||
|
||||
INSERT INTO t2 (col1, col2)
|
||||
SELECT * FROM
|
||||
(SELECT col1, col2 FROM t1 WHERE col2 IS NOT NULL
|
||||
UNION
|
||||
SELECT col1, col3 FROM t1) AS union_table
|
||||
ON DUPLICATE KEY UPDATE col3 = (col1 + col2 + col3);
|
||||
SELECT col1, col2, col3, col5 FROM t2 ORDER BY col5, col2;
|
||||
col1 | col2 | col3 | col5
|
||||
-------+-------+-------+------
|
||||
30 | 1 | 219 | 1
|
||||
40 | 2 | 44 | 2
|
||||
3 | 3 | 10 | 3
|
||||
4 | 4 | 5 | 4
|
||||
--? .* | 5 | 1 | 5
|
||||
--? .* | 6 | 1 | 6
|
||||
7 | 7 | 1 | 7
|
||||
8 | 8 | 1 | 8
|
||||
90 | 9 | 9 | 16
|
||||
--? 30000 | 1001 | 1002 | 11
|
||||
--? 40000 | 2001 | 2002 | 12
|
||||
--? | 40002 | 40003 | 13
|
||||
--? | 3002 | 3003 | 14
|
||||
100 | 10 | 100 | 100
|
||||
100 | 20 | 100 | 100
|
||||
100 | 30 | 100 | 100
|
||||
(16 rows)
|
||||
|
||||
INSERT INTO t2 (col1, col2)
|
||||
SELECT col1, col2 FROM t1 WHERE col2 IS NOT NULL
|
||||
UNION
|
||||
SELECT col1, col3 FROM t1
|
||||
ON DUPLICATE KEY UPDATE col3 = (col1 + col2 + col3);
|
||||
SELECT col1, col2, col3, col5 FROM t2 ORDER BY col5, col2;
|
||||
col1 | col2 | col3 | col5
|
||||
-------+-------+-------+------
|
||||
30 | 1 | 436 | 1
|
||||
40 | 2 | 86 | 2
|
||||
3 | 3 | 16 | 3
|
||||
4 | 4 | 5 | 4
|
||||
--? 15 | 5 | 1 | 5
|
||||
--? 2105 | 6 | 1 | 6
|
||||
7 | 7 | 1 | 7
|
||||
8 | 8 | 1 | 8
|
||||
90 | 9 | 9 | 16
|
||||
--? 30000 | 1001 | 1002 | 11
|
||||
--? 40000 | 2001 | 2002 | 12
|
||||
--? | 40002 | 40003 | 13
|
||||
--? | 3002 | 3003 | 14
|
||||
100 | 10 | 100 | 100
|
||||
100 | 20 | 100 | 100
|
||||
100 | 30 | 100 | 100
|
||||
(16 rows)
|
||||
|
||||
reset behavior_compat_options;
|
||||
-- test INTERSECT, should update
|
||||
(SELECT col1, col1 + col2 FROM t1 WHERE col2 IS NOT NULL
|
||||
UNION
|
||||
SELECT 1, 2)
|
||||
INTERSECT
|
||||
SELECT col1, col3 FROM t1;
|
||||
col1 | ?column?
|
||||
------+----------
|
||||
1 | 3
|
||||
(1 row)
|
||||
|
||||
INSERT INTO t2 (col1, col2)
|
||||
(SELECT col1, col1 + col2 FROM t1 WHERE col2 IS NOT NULL
|
||||
UNION
|
||||
SELECT 1, 2)
|
||||
INTERSECT
|
||||
SELECT col1, col3 FROM t1
|
||||
ON DUPLICATE KEY UPDATE col3 = (col1 + col2 + col3);
|
||||
SELECT col1, col2, col3, col5 FROM t2 WHERE col2 = 3 ORDER BY col5, col2;
|
||||
col1 | col2 | col3 | col5
|
||||
------+------+------+------
|
||||
3 | 3 | 22 | 3
|
||||
(1 row)
|
||||
|
||||
-- test EXCEPT, should update
|
||||
SELECT col1, col2 FROM t1 WHERE col2 IS NOT NULL
|
||||
EXCEPT
|
||||
(SELECT col1, col3 FROM t1
|
||||
UNION
|
||||
SELECT NULL, NULL);
|
||||
col1 | col2
|
||||
------+------
|
||||
1 | 2
|
||||
(1 row)
|
||||
|
||||
INSERT INTO t2 (col1, col2)
|
||||
SELECT col1, col2 FROM t1 WHERE col2 IS NOT NULL
|
||||
EXCEPT
|
||||
(SELECT col1, col3 FROM t1
|
||||
UNION
|
||||
SELECT NULL, NULL)
|
||||
ON DUPLICATE KEY UPDATE col3 = (col1 + col2 + col3);
|
||||
SELECT col1, col2, col3, col5 FROM t2 WHERE col2 = 2 ORDER BY col5, col2;
|
||||
col1 | col2 | col3 | col5
|
||||
------+------+------+------
|
||||
40 | 2 | 128 | 2
|
||||
(1 row)
|
||||
|
||||
-- test unique index with not default value
|
||||
ALTER TABLE t2 DROP CONSTRAINT t2_pkey;
|
||||
CREATE UNIQUE INDEX t2_u_index ON t2(col2, col5);
|
||||
SELECT col1, col2 FROM t1 WHERE col2 IS NOT NULL
|
||||
EXCEPT
|
||||
(SELECT col1, col3 FROM t1
|
||||
UNION
|
||||
SELECT NULL, NULL);
|
||||
col1 | col2
|
||||
------+------
|
||||
1 | 2
|
||||
(1 row)
|
||||
|
||||
INSERT INTO t2
|
||||
SELECT col1, col2 FROM t1 WHERE col2 IS NOT NULL
|
||||
EXCEPT
|
||||
(SELECT col1, col3 FROM t1
|
||||
UNION
|
||||
SELECT NULL, NULL)
|
||||
ON DUPLICATE KEY UPDATE col3 = (col1 + col2 + col3);
|
||||
SELECT col1, col2, col3, col5 FROM t2 WHERE col2 = 2 ORDER BY col5, col2;
|
||||
col1 | col2 | col3 | col5
|
||||
------+------+------+------
|
||||
40 | 2 | 128 | 2
|
||||
1 | 2 | 1 | 46
|
||||
(2 rows)
|
||||
|
||||
-- test t3 with one primary index with two columns
|
||||
CREATE TABLE t3 (
|
||||
col1 INT,
|
||||
col2 INT,
|
||||
col3 INT DEFAULT 1,
|
||||
-- col4 TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
col5 BIGSERIAL,
|
||||
PRIMARY KEY (col2, col3)
|
||||
) ;
|
||||
NOTICE: CREATE TABLE will create implicit sequence "t3_col5_seq" for serial column "t3.col5"
|
||||
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "t3_pkey" for table "t3"
|
||||
--- column referenced by primary key are not allowed to update
|
||||
INSERT INTO t3 VALUES (1, 1) ON DUPLICATE KEY UPDATE col3 = 3;
|
||||
ERROR: INSERT ON DUPLICATE KEY UPDATE don't allow update on primary key or unique key.
|
||||
--- should insert when not contains primary key and not all primary key referred columns have default value.
|
||||
--- but will fail cause primary key should not be null
|
||||
INSERT INTO t3 (col1) VALUES (1) ON DUPLICATE KEY UPDATE col1 = 2;
|
||||
ERROR: null value in column "col2" violates not-null constraint
|
||||
--?.*
|
||||
--- should insert
|
||||
--- (SEQUENCE BUG: the serial column will starts from 2 since the above statement has applied for a sequence)
|
||||
INSERT INTO t3 VALUES (1, 1) ON DUPLICATE KEY UPDATE col1 = 10;
|
||||
INSERT INTO t3 VALUES (2, 2, 2) ON DUPLICATE KEY UPDATE col5 = 20;
|
||||
SELECT * FROM t3 order by col5;
|
||||
col1 | col2 | col3 | col5
|
||||
------+------+------+------
|
||||
1 | 1 | 1 | 2
|
||||
2 | 2 | 2 | 3
|
||||
(2 rows)
|
||||
|
||||
--- should update
|
||||
INSERT INTO t3 VALUES (1, 1) ON DUPLICATE KEY UPDATE col1 = 10;
|
||||
INSERT INTO t3 VALUES (2, 2, 2) ON DUPLICATE KEY UPDATE col5 = 20;
|
||||
SELECT * FROM t3 order by col5;
|
||||
col1 | col2 | col3 | col5
|
||||
------+------+------+------
|
||||
10 | 1 | 1 | 2
|
||||
2 | 2 | 2 | 20
|
||||
(2 rows)
|
||||
|
||||
--- test subquery
|
||||
---- should insert
|
||||
INSERT INTO t3 (col2, col3) (SELECT max(col2) + 1, max(col3) + 1 FROM t3) ON DUPLICATE KEY UPDATE col1 = col2 + col3;
|
||||
SELECT * FROM t3 order by col5;
|
||||
col1 | col2 | col3 | col5
|
||||
------+------+------+------
|
||||
10 | 1 | 1 | 2
|
||||
| 3 | 3 | 6
|
||||
2 | 2 | 2 | 20
|
||||
(3 rows)
|
||||
|
||||
---- should update
|
||||
INSERT INTO t3 (col2, col3) (SELECT max(col2), max(col3) FROM t3) ON DUPLICATE KEY UPDATE col1 = col2 + col3;
|
||||
SELECT * FROM t3 order by col5;
|
||||
col1 | col2 | col3 | col5
|
||||
------+------+------+------
|
||||
10 | 1 | 1 | 2
|
||||
6 | 3 | 3 | 6
|
||||
2 | 2 | 2 | 20
|
||||
(3 rows)
|
||||
|
||||
-- test t3 with one unique index with two columns
|
||||
TRUNCATE t3;
|
||||
ALTER TABLE t3 DROP CONSTRAINT t3_pkey;
|
||||
ALTER TABLE t3 ALTER COLUMN col2 DROP NOT NULL;
|
||||
CREATE UNIQUE INDEX t3_ukey ON t3 (col2, col3);
|
||||
--- column referenced by unique key are not allowed to update
|
||||
INSERT INTO t3 VALUES (1, 1) ON DUPLICATE KEY UPDATE col3 = 3;
|
||||
ERROR: INSERT ON DUPLICATE KEY UPDATE don't allow update on primary key or unique key.
|
||||
--- should insert cause not contains unique key and not all unique key referred columns have default value.
|
||||
INSERT INTO t3 (col1) VALUES (1) ON DUPLICATE KEY UPDATE col1 = 2;
|
||||
INSERT INTO t3 (col1) VALUES (1) ON DUPLICATE KEY UPDATE col1 = 2;
|
||||
SELECT * FROM t3 order by col5;
|
||||
col1 | col2 | col3 | col5
|
||||
------+------+------+------
|
||||
1 | | 1 | 8
|
||||
1 | | 1 | 9
|
||||
(2 rows)
|
||||
|
||||
--- should insert
|
||||
INSERT INTO t3 VALUES (1, 1) ON DUPLICATE KEY UPDATE col1 = 10;
|
||||
INSERT INTO t3 VALUES (2, 2, 2) ON DUPLICATE KEY UPDATE t3.col5 = 20;
|
||||
SELECT * FROM t3 ORDER BY col5;
|
||||
col1 | col2 | col3 | col5
|
||||
------+------+------+------
|
||||
1 | | 1 | 8
|
||||
1 | | 1 | 9
|
||||
1 | 1 | 1 | 10
|
||||
2 | 2 | 2 | 11
|
||||
(4 rows)
|
||||
|
||||
--- should update
|
||||
INSERT INTO t3 VALUES (1, 1) ON DUPLICATE KEY UPDATE t3.col1 = 10;
|
||||
INSERT INTO t3 VALUES (2, 2, 2) ON DUPLICATE KEY UPDATE col5 = 20;
|
||||
SELECT * FROM t3 ORDER BY col5;
|
||||
col1 | col2 | col3 | col5
|
||||
------+------+------+------
|
||||
1 | | 1 | 8
|
||||
1 | | 1 | 9
|
||||
10 | 1 | 1 | 10
|
||||
2 | 2 | 2 | 20
|
||||
(4 rows)
|
||||
|
||||
--- test subquery
|
||||
---- should insert
|
||||
INSERT INTO t3 (SELECT 100, NULL, max(col3) FROM t3) ON DUPLICATE KEY UPDATE col1 = col2 + col3;
|
||||
INSERT INTO t3 (SELECT 100, NULL, max(col3) FROM t3) ON DUPLICATE KEY UPDATE col1 = col2 + col3;
|
||||
INSERT INTO t3 (col2, col3) (SELECT max(col2) + 1, max(col3) + 1 FROM t3) ON DUPLICATE KEY UPDATE col1 = col2 + col3;
|
||||
SELECT * FROM t3 ORDER BY col5;
|
||||
col1 | col2 | col3 | col5
|
||||
------+------+------+------
|
||||
1 | | 1 | 8
|
||||
1 | | 1 | 9
|
||||
10 | 1 | 1 | 10
|
||||
100 | | 2 | 14
|
||||
100 | | 2 | 15
|
||||
| 3 | 3 | 16
|
||||
2 | 2 | 2 | 20
|
||||
(7 rows)
|
||||
|
||||
---- should update
|
||||
INSERT INTO t3 (col2, col3) (SELECT max(col2), max(col3) FROM t3) ON DUPLICATE KEY UPDATE col1 = col2 + col3;
|
||||
SELECT * FROM t3 ORDER BY col5;
|
||||
col1 | col2 | col3 | col5
|
||||
------+------+------+------
|
||||
1 | | 1 | 8
|
||||
1 | | 1 | 9
|
||||
10 | 1 | 1 | 10
|
||||
100 | | 2 | 14
|
||||
100 | | 2 | 15
|
||||
6 | 3 | 3 | 16
|
||||
2 | 2 | 2 | 20
|
||||
(7 rows)
|
||||
|
||||
RESET enable_light_proxy;
|
||||
DROP SCHEMA test_insert_update_009 CASCADE;
|
||||
NOTICE: drop cascades to 3 other objects
|
||||
DETAIL: drop cascades to table t1
|
||||
drop cascades to table t2
|
||||
drop cascades to table t3
|
||||
|
|
@ -0,0 +1,313 @@
|
|||
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;
|
||||
-- enable_upsert_to_merge must is off, or upsert will be translated to merge.
|
||||
SET enable_upsert_to_merge TO OFF;
|
||||
-- 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;
|
||||
-- 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);
|
||||
ERROR: INSERT ON DUPLICATE KEY UPDATE don't allow update on primary key or unique key.
|
||||
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 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;
|
||||
ERROR: INSERT ON DUPLICATE KEY UPDATE don't allow update on primary key or unique key.
|
||||
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)
|
||||
|
||||
--- 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 | 1 | 6 | |
|
||||
6 | 1 | 7 | |
|
||||
6 | 1 | 11 | |
|
||||
6 | 1 | 12 | |
|
||||
(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 | 1 | 6 | |
|
||||
6 | 1 | 7 | |
|
||||
6 | 1 | 11 | |
|
||||
6 | 1 | 12 | |
|
||||
(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 | 8 | 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
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
\c upsert
|
||||
DROP SCHEMA upsert_test CASCADE;
|
||||
NOTICE: drop cascades to 8 other objects
|
||||
DETAIL: drop cascades to type upsert_test.atype
|
||||
drop cascades to type upsert_test.btype
|
||||
drop cascades to table upsert_test.t_grammer
|
||||
drop cascades to table upsert_test.t_default
|
||||
drop cascades to table upsert_test.t_data
|
||||
drop cascades to table upsert_test.t_trigger
|
||||
drop cascades to function upsert_test.upsert_before_func()
|
||||
drop cascades to function upsert_test.upsert_after_func()
|
||||
DROP SCHEMA upsert_test_unlog CASCADE;
|
||||
NOTICE: drop cascades to 6 other objects
|
||||
DETAIL: drop cascades to type upsert_test_unlog.atype
|
||||
drop cascades to type upsert_test_unlog.btype
|
||||
drop cascades to table upsert_test_unlog.t_hash_unlog_0
|
||||
drop cascades to table upsert_test_unlog.t_hash_unlog_1
|
||||
drop cascades to table upsert_test_unlog.t_rep_unlog_0
|
||||
drop cascades to table upsert_test_unlog.t_rep_unlog_1
|
||||
|
|
@ -0,0 +1 @@
|
|||
drop database upsert_etc;
|
||||
|
|
@ -0,0 +1,404 @@
|
|||
--------------------------------------------------------------------------------------------
|
||||
/*
|
||||
* procedure
|
||||
*/
|
||||
--------------------------------------------------------------------------------------------
|
||||
\c upsert;
|
||||
SET CURRENT_SCHEMA TO upsert_test_procedure;
|
||||
-- enable_upsert_to_merge must be off, or upsert will be translated to merge.
|
||||
SET enable_upsert_to_merge TO OFF;
|
||||
SHOW enable_upsert_to_merge;
|
||||
enable_upsert_to_merge
|
||||
------------------------
|
||||
off
|
||||
(1 row)
|
||||
|
||||
drop table IF EXISTS t_proc;
|
||||
NOTICE: table "t_proc" does not exist, skipping
|
||||
create table t_proc(c1 int, c2 int, c3 int unique);
|
||||
NOTICE: CREATE TABLE / UNIQUE will create implicit index "t_proc_c3_key" for table "t_proc"
|
||||
insert into t_proc select a,a,a from generate_series(1,20) as a;
|
||||
select *from t_proc order by c3;
|
||||
c1 | c2 | c3
|
||||
----+----+----
|
||||
1 | 1 | 1
|
||||
2 | 2 | 2
|
||||
3 | 3 | 3
|
||||
4 | 4 | 4
|
||||
5 | 5 | 5
|
||||
6 | 6 | 6
|
||||
7 | 7 | 7
|
||||
8 | 8 | 8
|
||||
9 | 9 | 9
|
||||
10 | 10 | 10
|
||||
11 | 11 | 11
|
||||
12 | 12 | 12
|
||||
13 | 13 | 13
|
||||
14 | 14 | 14
|
||||
15 | 15 | 15
|
||||
16 | 16 | 16
|
||||
17 | 17 | 17
|
||||
18 | 18 | 18
|
||||
19 | 19 | 19
|
||||
20 | 20 | 20
|
||||
(20 rows)
|
||||
|
||||
create or replace procedure mul_ups( c in INTEGER)
|
||||
as
|
||||
declare
|
||||
val int;
|
||||
begin
|
||||
for val in select c3 from t_proc loop
|
||||
insert into t_proc values(c,c, val) on duplicate key update c1 = c, c2 =c;
|
||||
end loop;
|
||||
end;
|
||||
/
|
||||
call mul_ups(100);
|
||||
mul_ups
|
||||
---------
|
||||
|
||||
(1 row)
|
||||
|
||||
select *from t_proc order by c3;
|
||||
c1 | c2 | c3
|
||||
-----+-----+----
|
||||
100 | 100 | 1
|
||||
100 | 100 | 2
|
||||
100 | 100 | 3
|
||||
100 | 100 | 4
|
||||
100 | 100 | 5
|
||||
100 | 100 | 6
|
||||
100 | 100 | 7
|
||||
100 | 100 | 8
|
||||
100 | 100 | 9
|
||||
100 | 100 | 10
|
||||
100 | 100 | 11
|
||||
100 | 100 | 12
|
||||
100 | 100 | 13
|
||||
100 | 100 | 14
|
||||
100 | 100 | 15
|
||||
100 | 100 | 16
|
||||
100 | 100 | 17
|
||||
100 | 100 | 18
|
||||
100 | 100 | 19
|
||||
100 | 100 | 20
|
||||
(20 rows)
|
||||
|
||||
create or replace procedure mul_ups( c in INTEGER)
|
||||
as
|
||||
declare
|
||||
val int;
|
||||
begin
|
||||
for val in select c3 from t_proc loop
|
||||
insert into t_proc values(c,c, val) on duplicate key update c1 = $1, c2 =$1;
|
||||
end loop;
|
||||
end;
|
||||
/
|
||||
call mul_ups(200);
|
||||
mul_ups
|
||||
---------
|
||||
|
||||
(1 row)
|
||||
|
||||
select *from t_proc order by c3;
|
||||
c1 | c2 | c3
|
||||
-----+-----+----
|
||||
200 | 200 | 1
|
||||
200 | 200 | 2
|
||||
200 | 200 | 3
|
||||
200 | 200 | 4
|
||||
200 | 200 | 5
|
||||
200 | 200 | 6
|
||||
200 | 200 | 7
|
||||
200 | 200 | 8
|
||||
200 | 200 | 9
|
||||
200 | 200 | 10
|
||||
200 | 200 | 11
|
||||
200 | 200 | 12
|
||||
200 | 200 | 13
|
||||
200 | 200 | 14
|
||||
200 | 200 | 15
|
||||
200 | 200 | 16
|
||||
200 | 200 | 17
|
||||
200 | 200 | 18
|
||||
200 | 200 | 19
|
||||
200 | 200 | 20
|
||||
(20 rows)
|
||||
|
||||
create or replace procedure mul_ups_00()
|
||||
as
|
||||
declare
|
||||
val int;
|
||||
begin
|
||||
for val in select c3 from t_proc loop
|
||||
insert into t_proc values(val,val,val) on duplicate key update c1 = 300, c2 =300;
|
||||
end loop;
|
||||
end;
|
||||
/
|
||||
call mul_ups_00();
|
||||
mul_ups_00
|
||||
------------
|
||||
|
||||
(1 row)
|
||||
|
||||
select *from t_proc order by c3;
|
||||
c1 | c2 | c3
|
||||
-----+-----+----
|
||||
300 | 300 | 1
|
||||
300 | 300 | 2
|
||||
300 | 300 | 3
|
||||
300 | 300 | 4
|
||||
300 | 300 | 5
|
||||
300 | 300 | 6
|
||||
300 | 300 | 7
|
||||
300 | 300 | 8
|
||||
300 | 300 | 9
|
||||
300 | 300 | 10
|
||||
300 | 300 | 11
|
||||
300 | 300 | 12
|
||||
300 | 300 | 13
|
||||
300 | 300 | 14
|
||||
300 | 300 | 15
|
||||
300 | 300 | 16
|
||||
300 | 300 | 17
|
||||
300 | 300 | 18
|
||||
300 | 300 | 19
|
||||
300 | 300 | 20
|
||||
(20 rows)
|
||||
|
||||
declare
|
||||
val int;
|
||||
c int :=400;
|
||||
begin
|
||||
for val in select c3 from t_proc loop
|
||||
insert into t_proc values(c,c, val) on duplicate key update c1 = c, c2 =c;
|
||||
end loop;
|
||||
end;
|
||||
/
|
||||
select *from t_proc order by c3;
|
||||
c1 | c2 | c3
|
||||
-----+-----+----
|
||||
400 | 400 | 1
|
||||
400 | 400 | 2
|
||||
400 | 400 | 3
|
||||
400 | 400 | 4
|
||||
400 | 400 | 5
|
||||
400 | 400 | 6
|
||||
400 | 400 | 7
|
||||
400 | 400 | 8
|
||||
400 | 400 | 9
|
||||
400 | 400 | 10
|
||||
400 | 400 | 11
|
||||
400 | 400 | 12
|
||||
400 | 400 | 13
|
||||
400 | 400 | 14
|
||||
400 | 400 | 15
|
||||
400 | 400 | 16
|
||||
400 | 400 | 17
|
||||
400 | 400 | 18
|
||||
400 | 400 | 19
|
||||
400 | 400 | 20
|
||||
(20 rows)
|
||||
|
||||
create or replace procedure mul_ups( c in INTEGER)
|
||||
as
|
||||
declare
|
||||
val int;
|
||||
begin
|
||||
for val in select c3 from t_proc loop
|
||||
insert into t_proc values(c,c, val+100) on duplicate key update c1 = $1, c2 =$1;
|
||||
end loop;
|
||||
end;
|
||||
/
|
||||
call mul_ups(500);
|
||||
mul_ups
|
||||
---------
|
||||
|
||||
(1 row)
|
||||
|
||||
select *from t_proc order by c3;
|
||||
c1 | c2 | c3
|
||||
-----+-----+-----
|
||||
400 | 400 | 1
|
||||
400 | 400 | 2
|
||||
400 | 400 | 3
|
||||
400 | 400 | 4
|
||||
400 | 400 | 5
|
||||
400 | 400 | 6
|
||||
400 | 400 | 7
|
||||
400 | 400 | 8
|
||||
400 | 400 | 9
|
||||
400 | 400 | 10
|
||||
400 | 400 | 11
|
||||
400 | 400 | 12
|
||||
400 | 400 | 13
|
||||
400 | 400 | 14
|
||||
400 | 400 | 15
|
||||
400 | 400 | 16
|
||||
400 | 400 | 17
|
||||
400 | 400 | 18
|
||||
400 | 400 | 19
|
||||
400 | 400 | 20
|
||||
500 | 500 | 101
|
||||
500 | 500 | 102
|
||||
500 | 500 | 103
|
||||
500 | 500 | 104
|
||||
500 | 500 | 105
|
||||
500 | 500 | 106
|
||||
500 | 500 | 107
|
||||
500 | 500 | 108
|
||||
500 | 500 | 109
|
||||
500 | 500 | 110
|
||||
500 | 500 | 111
|
||||
500 | 500 | 112
|
||||
500 | 500 | 113
|
||||
500 | 500 | 114
|
||||
500 | 500 | 115
|
||||
500 | 500 | 116
|
||||
500 | 500 | 117
|
||||
500 | 500 | 118
|
||||
500 | 500 | 119
|
||||
500 | 500 | 120
|
||||
(40 rows)
|
||||
|
||||
/*
|
||||
* insert
|
||||
*/
|
||||
drop table if exists t_default;
|
||||
NOTICE: table "t_default" does not exist, skipping
|
||||
CREATE TABLE t_default (c1 INT PRIMARY KEY DEFAULT 10, c2 FLOAT DEFAULT 3.0, c3 TIMESTAMP DEFAULT '20200508');
|
||||
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "t_default_pkey" for table "t_default"
|
||||
create view v_default as select *from t_default order by c1;
|
||||
-- insert src
|
||||
---- insert values
|
||||
truncate t_default;
|
||||
insert into t_default values(DEFAULT, DEFAULT, DEFAULT);
|
||||
insert into t_default values(1, 2, '20200630');
|
||||
select *from t_default order by c1;
|
||||
c1 | c2 | c3
|
||||
----+----+--------------------------
|
||||
1 | 2 | Tue Jun 30 00:00:00 2020
|
||||
10 | 3 | Fri May 08 00:00:00 2020
|
||||
(2 rows)
|
||||
|
||||
insert into t_default values(DEFAULT, DEFAULT, DEFAULT) on duplicate key update c2 = 1;
|
||||
select *from t_default order by c1;
|
||||
c1 | c2 | c3
|
||||
----+----+--------------------------
|
||||
1 | 2 | Tue Jun 30 00:00:00 2020
|
||||
10 | 1 | Fri May 08 00:00:00 2020
|
||||
(2 rows)
|
||||
|
||||
insert into t_default values(1, 2, '20200630') on duplicate key update c2 = 2;
|
||||
select *from t_default order by c1;
|
||||
c1 | c2 | c3
|
||||
----+----+--------------------------
|
||||
1 | 2 | Tue Jun 30 00:00:00 2020
|
||||
10 | 1 | Fri May 08 00:00:00 2020
|
||||
(2 rows)
|
||||
|
||||
insert into t_default values(DEFAULT, DEFAULT, DEFAULT),(1, 2, '20200630') on duplicate key update c2 = 3;
|
||||
select *from t_default order by c1;
|
||||
c1 | c2 | c3
|
||||
----+----+--------------------------
|
||||
1 | 3 | Tue Jun 30 00:00:00 2020
|
||||
10 | 3 | Fri May 08 00:00:00 2020
|
||||
(2 rows)
|
||||
|
||||
---- insert subquery
|
||||
insert into t_default select *from t_default order by c1 on duplicate key update c2 = 4;
|
||||
select *from t_default order by c1;
|
||||
c1 | c2 | c3
|
||||
----+----+--------------------------
|
||||
1 | 4 | Tue Jun 30 00:00:00 2020
|
||||
10 | 4 | Fri May 08 00:00:00 2020
|
||||
(2 rows)
|
||||
|
||||
insert into t_default select *from t_default order by c1 limit 1 on duplicate key update c2 = 5;
|
||||
select *from t_default order by c1;
|
||||
c1 | c2 | c3
|
||||
----+----+--------------------------
|
||||
1 | 5 | Tue Jun 30 00:00:00 2020
|
||||
10 | 4 | Fri May 08 00:00:00 2020
|
||||
(2 rows)
|
||||
|
||||
insert into t_default select *from t_default where c1=10 on duplicate key update c2 = 6;
|
||||
select *from t_default order by c1;
|
||||
c1 | c2 | c3
|
||||
----+----+--------------------------
|
||||
1 | 5 | Tue Jun 30 00:00:00 2020
|
||||
10 | 6 | Fri May 08 00:00:00 2020
|
||||
(2 rows)
|
||||
|
||||
insert into t_default select *from t_default order by c1 on duplicate key update c2 = 7;
|
||||
select *from t_default order by c1;
|
||||
c1 | c2 | c3
|
||||
----+----+--------------------------
|
||||
1 | 7 | Tue Jun 30 00:00:00 2020
|
||||
10 | 7 | Fri May 08 00:00:00 2020
|
||||
(2 rows)
|
||||
|
||||
insert into t_default select *from v_default order by c1 on duplicate key update c2 = 8;
|
||||
select *from t_default order by c1;
|
||||
c1 | c2 | c3
|
||||
----+----+--------------------------
|
||||
1 | 8 | Tue Jun 30 00:00:00 2020
|
||||
10 | 8 | Fri May 08 00:00:00 2020
|
||||
(2 rows)
|
||||
|
||||
insert into t_default select *from t_default union select c1+1,c2+1,c3+1 from t_default order by c1 on duplicate key update c2 = 9;
|
||||
select *from t_default order by c1;
|
||||
c1 | c2 | c3
|
||||
----+----+--------------------------
|
||||
1 | 9 | Tue Jun 30 00:00:00 2020
|
||||
2 | 9 | Wed Jul 01 00:00:00 2020
|
||||
10 | 9 | Fri May 08 00:00:00 2020
|
||||
11 | 9 | Sat May 09 00:00:00 2020
|
||||
(4 rows)
|
||||
|
||||
insert into t_default(c1,c2) select max(c1),c2 from t_default group by c2 on duplicate key update c2 = 10;
|
||||
-- index
|
||||
---- mul index
|
||||
truncate t_default;
|
||||
create unique index t_default_mul on t_default(c1,c3);
|
||||
insert into t_default values(DEFAULT, DEFAULT, DEFAULT);
|
||||
insert into t_default values(1, 2, '20200630');
|
||||
select *from t_default order by c1;
|
||||
c1 | c2 | c3
|
||||
----+----+--------------------------
|
||||
1 | 2 | Tue Jun 30 00:00:00 2020
|
||||
10 | 3 | Fri May 08 00:00:00 2020
|
||||
(2 rows)
|
||||
|
||||
insert into t_default values(DEFAULT, DEFAULT, DEFAULT) on duplicate key update c2 = 1;
|
||||
select *from t_default order by c1;
|
||||
c1 | c2 | c3
|
||||
----+----+--------------------------
|
||||
1 | 2 | Tue Jun 30 00:00:00 2020
|
||||
10 | 1 | Fri May 08 00:00:00 2020
|
||||
(2 rows)
|
||||
|
||||
insert into t_default values(1, 2, '20200630') on duplicate key update c2 = 2;
|
||||
select *from t_default order by c1;
|
||||
c1 | c2 | c3
|
||||
----+----+--------------------------
|
||||
1 | 2 | Tue Jun 30 00:00:00 2020
|
||||
10 | 1 | Fri May 08 00:00:00 2020
|
||||
(2 rows)
|
||||
|
||||
insert into t_default values(DEFAULT, DEFAULT, DEFAULT),(1, 2, '20200630') on duplicate key update c2 = 3;
|
||||
select *from t_default order by c1;
|
||||
c1 | c2 | c3
|
||||
----+----+--------------------------
|
||||
1 | 3 | Tue Jun 30 00:00:00 2020
|
||||
10 | 3 | Fri May 08 00:00:00 2020
|
||||
(2 rows)
|
||||
|
||||
insert into t_default select *from t_default on duplicate key update c2 = 4;
|
||||
select *from t_default order by c1;
|
||||
c1 | c2 | c3
|
||||
----+----+--------------------------
|
||||
1 | 4 | Tue Jun 30 00:00:00 2020
|
||||
10 | 4 | Fri May 08 00:00:00 2020
|
||||
(2 rows)
|
||||
|
||||
|
|
@ -0,0 +1,297 @@
|
|||
--------------------------------------------------------------------------------------------
|
||||
/*
|
||||
* explain upsert
|
||||
*/
|
||||
--------------------------------------------------------------------------------------------
|
||||
\c upsert;
|
||||
SET CURRENT_SCHEMA TO upsert_test_explain;
|
||||
-- enable_upsert_to_merge must be off, or upsert will be translated to merge.
|
||||
SET enable_upsert_to_merge TO OFF;
|
||||
SHOW enable_upsert_to_merge;
|
||||
enable_upsert_to_merge
|
||||
------------------------
|
||||
off
|
||||
(1 row)
|
||||
|
||||
create temp table up_expl_temp(c1 int, c2 int, c3 int unique) ;
|
||||
NOTICE: CREATE TABLE / UNIQUE will create implicit index "up_expl_temp_c3_key" for table "up_expl_temp"
|
||||
insert into up_expl_hash select a,a,a from generate_series(1,20) as a;
|
||||
insert into up_expl_repl select a,a,a from generate_series(1,20) as a;
|
||||
insert into up_expl_part select a,a,a from generate_series(1,20) as a;
|
||||
insert into up_expl_temp select a,a,a from generate_series(1,20) as a;
|
||||
insert into up_expl_unlog select a,a,a from generate_series(1,20) as a;
|
||||
insert into up_expl_node select a,a,a from generate_series(1,20) as a;
|
||||
insert into up_expl_repl2 select a,a,a,a,a from generate_series(1,20) as a;
|
||||
EXPLAIN (VERBOSE on, COSTS off, TIMING off) insert into up_expl_hash values(1,1,1) on duplicate key update c1 = 2;
|
||||
QUERY PLAN
|
||||
-------------------------------------------------
|
||||
Insert on upsert_test_explain.up_expl_hash
|
||||
Conflict Resolution: UPDATE
|
||||
Conflict Arbiter Indexes: up_expl_hash_c3_key
|
||||
-> Result
|
||||
Output: 1, 1, 1
|
||||
(5 rows)
|
||||
|
||||
EXPLAIN (ANALYZE on, COSTS off, TIMING off) insert into up_expl_hash values(1,1,1) on duplicate key update c1 = 2;
|
||||
QUERY PLAN
|
||||
-------------------------------------------------
|
||||
Insert on up_expl_hash (actual rows=1 loops=1)
|
||||
Conflict Resolution: UPDATE
|
||||
Conflict Arbiter Indexes: up_expl_hash_c3_key
|
||||
-> Result (actual rows=1 loops=1)
|
||||
--? Total runtime: .* ms
|
||||
(5 rows)
|
||||
|
||||
EXPLAIN PERFORMANCE insert into up_expl_hash values(1,1,1) on duplicate key update c1 = 2;
|
||||
QUERY PLAN
|
||||
------------------------------------------------------------------------------------------------------------------------
|
||||
--? Insert on upsert_test_explain.up_expl_hash (cost=.* rows=1 width=0) (actual time=.* rows=1 loops=1)
|
||||
Conflict Resolution: UPDATE
|
||||
Conflict Arbiter Indexes: up_expl_hash_c3_key
|
||||
(Buffers: shared hit=4)
|
||||
--? (CPU: ex c/r=.*, ex row=1, ex cyc=.*, inc cyc=.*)
|
||||
--? -> Result (cost=.* rows=1 width=0) (actual time=.* rows=1 loops=1)
|
||||
Output: 1, 1, 1
|
||||
--? (CPU: ex c/r=.*, ex row=1, ex cyc=.*, inc cyc=.*)
|
||||
--? Total runtime: .* ms
|
||||
(9 rows)
|
||||
|
||||
EXPLAIN (VERBOSE on, COSTS off, TIMING off) insert into up_expl_hash values(1,1,1),(2,2,2)on duplicate key update c1 = 2;
|
||||
QUERY PLAN
|
||||
----------------------------------------------------------------------------
|
||||
Insert on upsert_test_explain.up_expl_hash
|
||||
Conflict Resolution: UPDATE
|
||||
Conflict Arbiter Indexes: up_expl_hash_c3_key
|
||||
-> Values Scan on "*VALUES*"
|
||||
Output: "*VALUES*".column1, "*VALUES*".column2, "*VALUES*".column3
|
||||
(5 rows)
|
||||
|
||||
EXPLAIN (ANALYZE on, COSTS off, TIMING off) insert into up_expl_hash values(1,1,1),(2,2,2)on duplicate key update c1 = 2;
|
||||
QUERY PLAN
|
||||
---------------------------------------------------------
|
||||
Insert on up_expl_hash (actual rows=2 loops=1)
|
||||
Conflict Resolution: UPDATE
|
||||
Conflict Arbiter Indexes: up_expl_hash_c3_key
|
||||
-> Values Scan on "*VALUES*" (actual rows=2 loops=1)
|
||||
--? Total runtime: .* ms
|
||||
(5 rows)
|
||||
|
||||
EXPLAIN (VERBOSE on, COSTS off, TIMING off) insert into up_expl_repl values(1,1,1) on duplicate key update c1 = 2;
|
||||
QUERY PLAN
|
||||
-------------------------------------------------
|
||||
Insert on upsert_test_explain.up_expl_repl
|
||||
Conflict Resolution: UPDATE
|
||||
Conflict Arbiter Indexes: up_expl_repl_c3_key
|
||||
-> Result
|
||||
Output: 1, 1, 1
|
||||
(5 rows)
|
||||
|
||||
EXPLAIN (ANALYZE on, COSTS off, TIMING off) insert into up_expl_repl values(1,1,1) on duplicate key update c1 = 2;
|
||||
QUERY PLAN
|
||||
-------------------------------------------------
|
||||
Insert on up_expl_repl (actual rows=1 loops=1)
|
||||
Conflict Resolution: UPDATE
|
||||
Conflict Arbiter Indexes: up_expl_repl_c3_key
|
||||
-> Result (actual rows=1 loops=1)
|
||||
--? Total runtime: .* ms
|
||||
(5 rows)
|
||||
|
||||
EXPLAIN (VERBOSE on, COSTS off, TIMING off) insert into up_expl_part values(1,1,1) on duplicate key update c1 = 2;
|
||||
QUERY PLAN
|
||||
-------------------------------------------------
|
||||
Insert on upsert_test_explain.up_expl_part
|
||||
Conflict Resolution: UPDATE
|
||||
Conflict Arbiter Indexes: up_expl_part_c3_key
|
||||
-> Result
|
||||
Output: 1, 1, 1
|
||||
(5 rows)
|
||||
|
||||
EXPLAIN (ANALYZE on, COSTS off, TIMING off) insert into up_expl_part values(1,1,1) on duplicate key update c1 = 2;
|
||||
QUERY PLAN
|
||||
-------------------------------------------------
|
||||
Insert on up_expl_part (actual rows=1 loops=1)
|
||||
Conflict Resolution: UPDATE
|
||||
Conflict Arbiter Indexes: up_expl_part_c3_key
|
||||
-> Result (actual rows=1 loops=1)
|
||||
--? Total runtime: .* ms
|
||||
(5 rows)
|
||||
|
||||
EXPLAIN (VERBOSE on, COSTS off, TIMING off) insert into up_expl_temp values(1,1,1) on duplicate key update c1 = 2;
|
||||
QUERY PLAN
|
||||
--?.*
|
||||
--? Insert on pg_temp_datanod.*.up_expl_temp
|
||||
Conflict Resolution: UPDATE
|
||||
Conflict Arbiter Indexes: up_expl_temp_c3_key
|
||||
-> Result
|
||||
Output: 1, 1, 1
|
||||
(5 rows)
|
||||
|
||||
EXPLAIN (ANALYZE on, COSTS off, TIMING off) insert into up_expl_temp values(1,1,1) on duplicate key update c1 = 2;
|
||||
QUERY PLAN
|
||||
-------------------------------------------------
|
||||
Insert on up_expl_temp (actual rows=1 loops=1)
|
||||
Conflict Resolution: UPDATE
|
||||
Conflict Arbiter Indexes: up_expl_temp_c3_key
|
||||
-> Result (actual rows=1 loops=1)
|
||||
--? Total runtime: .* ms
|
||||
(5 rows)
|
||||
|
||||
EXPLAIN (VERBOSE on, COSTS off, TIMING off) insert into up_expl_unlog values(1,1,1) on duplicate key update c1 = 2;
|
||||
QUERY PLAN
|
||||
--------------------------------------------------
|
||||
Insert on upsert_test_explain.up_expl_unlog
|
||||
Conflict Resolution: UPDATE
|
||||
Conflict Arbiter Indexes: up_expl_unlog_c3_key
|
||||
-> Result
|
||||
Output: 1, 1, 1
|
||||
(5 rows)
|
||||
|
||||
EXPLAIN (ANALYZE on, COSTS off, TIMING off) insert into up_expl_unlog values(1,1,1) on duplicate key update c1 = 2;
|
||||
QUERY PLAN
|
||||
--------------------------------------------------
|
||||
Insert on up_expl_unlog (actual rows=1 loops=1)
|
||||
Conflict Resolution: UPDATE
|
||||
Conflict Arbiter Indexes: up_expl_unlog_c3_key
|
||||
-> Result (actual rows=1 loops=1)
|
||||
--? Total runtime: .* ms
|
||||
(5 rows)
|
||||
|
||||
EXPLAIN (VERBOSE on, COSTS off, TIMING off) insert into up_expl_node values(1,1,1) on duplicate key update c1 = 2;
|
||||
QUERY PLAN
|
||||
-------------------------------------------------
|
||||
Insert on upsert_test_explain.up_expl_node
|
||||
Conflict Resolution: UPDATE
|
||||
Conflict Arbiter Indexes: up_expl_node_c3_key
|
||||
-> Result
|
||||
Output: 1, 1, 1
|
||||
(5 rows)
|
||||
|
||||
EXPLAIN (ANALYZE on, COSTS off, TIMING off) insert into up_expl_node values(1,1,1) on duplicate key update c1 = 2;
|
||||
QUERY PLAN
|
||||
-------------------------------------------------
|
||||
Insert on up_expl_node (actual rows=1 loops=1)
|
||||
Conflict Resolution: UPDATE
|
||||
Conflict Arbiter Indexes: up_expl_node_c3_key
|
||||
-> Result (actual rows=1 loops=1)
|
||||
--? Total runtime: .* ms
|
||||
(5 rows)
|
||||
|
||||
EXPLAIN (VERBOSE on, COSTS off, TIMING off) insert into up_expl_hash values(1,1,1),(2,2,2)on duplicate key update nothing;
|
||||
QUERY PLAN
|
||||
----------------------------------------------------------------------------
|
||||
Insert on upsert_test_explain.up_expl_hash
|
||||
Conflict Resolution: NOTHING
|
||||
Conflict Arbiter Indexes: up_expl_hash_c3_key
|
||||
-> Values Scan on "*VALUES*"
|
||||
Output: "*VALUES*".column1, "*VALUES*".column2, "*VALUES*".column3
|
||||
(5 rows)
|
||||
|
||||
EXPLAIN (ANALYZE on, COSTS off, TIMING off) insert into up_expl_hash values(1,1,1),(2,2,2)on duplicate key update nothing;
|
||||
QUERY PLAN
|
||||
---------------------------------------------------------
|
||||
Insert on up_expl_hash (actual rows=0 loops=1)
|
||||
Conflict Resolution: NOTHING
|
||||
Conflict Arbiter Indexes: up_expl_hash_c3_key
|
||||
-> Values Scan on "*VALUES*" (actual rows=2 loops=1)
|
||||
--? Total runtime: .* ms
|
||||
(5 rows)
|
||||
|
||||
EXPLAIN (VERBOSE on, COSTS off, TIMING off) insert into up_expl_repl values(1,1,1) on duplicate key update nothing;
|
||||
QUERY PLAN
|
||||
-------------------------------------------------
|
||||
Insert on upsert_test_explain.up_expl_repl
|
||||
Conflict Resolution: NOTHING
|
||||
Conflict Arbiter Indexes: up_expl_repl_c3_key
|
||||
-> Result
|
||||
Output: 1, 1, 1
|
||||
(5 rows)
|
||||
|
||||
EXPLAIN (ANALYZE on, COSTS off, TIMING off) insert into up_expl_repl values(1,1,1) on duplicate key update nothing;
|
||||
QUERY PLAN
|
||||
-------------------------------------------------
|
||||
Insert on up_expl_repl (actual rows=0 loops=1)
|
||||
Conflict Resolution: NOTHING
|
||||
Conflict Arbiter Indexes: up_expl_repl_c3_key
|
||||
-> Result (actual rows=1 loops=1)
|
||||
--? Total runtime: .* ms
|
||||
(5 rows)
|
||||
|
||||
EXPLAIN (VERBOSE on, COSTS off, TIMING off) insert into up_expl_part values(1,1,1) on duplicate key update nothing;
|
||||
QUERY PLAN
|
||||
-------------------------------------------------
|
||||
Insert on upsert_test_explain.up_expl_part
|
||||
Conflict Resolution: NOTHING
|
||||
Conflict Arbiter Indexes: up_expl_part_c3_key
|
||||
-> Result
|
||||
Output: 1, 1, 1
|
||||
(5 rows)
|
||||
|
||||
EXPLAIN (ANALYZE on, COSTS off, TIMING off) insert into up_expl_part values(1,1,1) on duplicate key update nothing;
|
||||
QUERY PLAN
|
||||
-------------------------------------------------
|
||||
Insert on up_expl_part (actual rows=0 loops=1)
|
||||
Conflict Resolution: NOTHING
|
||||
Conflict Arbiter Indexes: up_expl_part_c3_key
|
||||
-> Result (actual rows=1 loops=1)
|
||||
--? Total runtime: .* ms
|
||||
(5 rows)
|
||||
|
||||
EXPLAIN (VERBOSE on, COSTS off, TIMING off) insert into up_expl_temp values(1,1,1) on duplicate key update nothing;
|
||||
QUERY PLAN
|
||||
--?.*
|
||||
--? Insert on pg_temp_datanod.*.up_expl_temp
|
||||
Conflict Resolution: NOTHING
|
||||
Conflict Arbiter Indexes: up_expl_temp_c3_key
|
||||
-> Result
|
||||
Output: 1, 1, 1
|
||||
(5 rows)
|
||||
|
||||
EXPLAIN (ANALYZE on, COSTS off, TIMING off) insert into up_expl_temp values(1,1,1) on duplicate key update nothing;
|
||||
QUERY PLAN
|
||||
-------------------------------------------------
|
||||
Insert on up_expl_temp (actual rows=0 loops=1)
|
||||
Conflict Resolution: NOTHING
|
||||
Conflict Arbiter Indexes: up_expl_temp_c3_key
|
||||
-> Result (actual rows=1 loops=1)
|
||||
--? Total runtime: .* ms
|
||||
(5 rows)
|
||||
|
||||
EXPLAIN (VERBOSE on, COSTS off, TIMING off) insert into up_expl_unlog values(1,1,1) on duplicate key update nothing;
|
||||
QUERY PLAN
|
||||
--------------------------------------------------
|
||||
Insert on upsert_test_explain.up_expl_unlog
|
||||
Conflict Resolution: NOTHING
|
||||
Conflict Arbiter Indexes: up_expl_unlog_c3_key
|
||||
-> Result
|
||||
Output: 1, 1, 1
|
||||
(5 rows)
|
||||
|
||||
EXPLAIN (ANALYZE on, COSTS off, TIMING off) insert into up_expl_unlog values(1,1,1) on duplicate key update nothing;
|
||||
QUERY PLAN
|
||||
--------------------------------------------------
|
||||
Insert on up_expl_unlog (actual rows=0 loops=1)
|
||||
Conflict Resolution: NOTHING
|
||||
Conflict Arbiter Indexes: up_expl_unlog_c3_key
|
||||
-> Result (actual rows=1 loops=1)
|
||||
--? Total runtime: .* ms
|
||||
(5 rows)
|
||||
|
||||
EXPLAIN (VERBOSE on, COSTS off, TIMING off) insert into up_expl_node values(1,1,1) on duplicate key update nothing;
|
||||
QUERY PLAN
|
||||
-------------------------------------------------
|
||||
Insert on upsert_test_explain.up_expl_node
|
||||
Conflict Resolution: NOTHING
|
||||
Conflict Arbiter Indexes: up_expl_node_c3_key
|
||||
-> Result
|
||||
Output: 1, 1, 1
|
||||
(5 rows)
|
||||
|
||||
EXPLAIN (ANALYZE on, COSTS off, TIMING off) insert into up_expl_node values(1,1,1) on duplicate key update nothing;
|
||||
QUERY PLAN
|
||||
-------------------------------------------------
|
||||
Insert on up_expl_node (actual rows=0 loops=1)
|
||||
Conflict Resolution: NOTHING
|
||||
Conflict Arbiter Indexes: up_expl_node_c3_key
|
||||
-> Result (actual rows=1 loops=1)
|
||||
--? Total runtime: .* ms
|
||||
(5 rows)
|
||||
|
|
@ -0,0 +1,188 @@
|
|||
\c upsert
|
||||
SET CURRENT_SCHEMA TO upsert_test;
|
||||
-- enable_upsert_to_merge must be off, or upsert will be translated to merge.
|
||||
SET enable_upsert_to_merge TO OFF;
|
||||
SHOW enable_upsert_to_merge;
|
||||
enable_upsert_to_merge
|
||||
------------------------
|
||||
off
|
||||
(1 row)
|
||||
|
||||
-- support multiple set
|
||||
INSERT INTO t_grammer VALUES(11, 1) ON DUPLICATE KEY UPDATE c2 = 2, c4 = ROW(10, 20), c3 = '{10, 20, 30}';
|
||||
INSERT INTO t_grammer VALUES(12, 2) ON DUPLICATE KEY UPDATE c2 = 2, c3[1] = 3;
|
||||
-- support const value and expr
|
||||
INSERT INTO t_grammer VALUES(23) ON DUPLICATE KEY UPDATE c2 = 2;
|
||||
INSERT INTO t_grammer VALUES(24) ON DUPLICATE KEY UPDATE c2 = length('test') + 100;
|
||||
-- support without table name
|
||||
INSERT INTO t_grammer VALUES(31, 1) ON DUPLICATE KEY UPDATE c2 = c1, c4.a = VALUES(c1);
|
||||
INSERT INTO t_grammer VALUES(32, 2) ON DUPLICATE KEY UPDATE c2 = c1 + 5, c4.a = VALUES(c1);
|
||||
-- support with table name
|
||||
INSERT INTO t_grammer VALUES(41, 1) ON DUPLICATE KEY UPDATE c2 = t_grammer.c1, c4.a = VALUES(c1);
|
||||
INSERT INTO t_grammer VALUES(42, 2) ON DUPLICATE KEY UPDATE c2 = t_grammer.c1 + 5, c4.a = VALUES(c1);
|
||||
-- support EXCLUDED alone and with expr
|
||||
INSERT INTO t_grammer VALUES(51, 1) ON DUPLICATE KEY UPDATE c2 = c1 + 5, c4.a = EXCLUDED.c1;
|
||||
INSERT INTO t_grammer VALUES(52, 2) ON DUPLICATE KEY UPDATE c2 = t_grammer.c1 + 5, c4.a = EXCLUDED.c1 + 5;
|
||||
INSERT INTO t_grammer VALUES(53, 3) ON DUPLICATE KEY UPDATE c4.a = sqrt(EXCLUDED.c1 - EXCLUDED.c2 - 1) + 1, c2 = t_grammer.c1 + 5;
|
||||
INSERT INTO t_grammer VALUES(54, 4) ON DUPLICATE KEY UPDATE c4.b = EXCLUDED.c1 + t_grammer.c1;
|
||||
INSERT INTO t_grammer VALUES(55, 5) ON DUPLICATE KEY UPDATE c4.a = EXCLUDED.c2, c4.b = EXCLUDED.c1 + sqrt(c1 - 6);
|
||||
-- support ARRAY
|
||||
INSERT INTO t_grammer VALUES(61, 1) ON DUPLICATE KEY UPDATE c2 = VALUES(c3[1]);
|
||||
INSERT INTO t_grammer VALUES(62, 2) ON DUPLICATE KEY UPDATE c5 = VALUES(c3[2,3]);
|
||||
INSERT INTO t_grammer VALUES(63, 3) ON DUPLICATE KEY UPDATE c5 = VALUES(c3[2:3]);
|
||||
INSERT INTO t_grammer VALUES(64, 4, '{10, 20, 30}') ON DUPLICATE KEY UPDATE c2 = EXCLUDED.c3[1];
|
||||
INSERT INTO t_grammer VALUES(65, 5, '{10, 20, 30}') ON DUPLICATE KEY UPDATE c5 = EXCLUDED.c3[2,3];
|
||||
INSERT INTO t_grammer VALUES(66, 6, '{10, 20, 30}') ON DUPLICATE KEY UPDATE c5 = EXCLUDED.c3[1:2];
|
||||
INSERT INTO t_grammer VALUES(67, 7, '{10, 20, 30}') ON DUPLICATE KEY UPDATE c2 = c3[1];
|
||||
INSERT INTO t_grammer VALUES(68, 8, '{10, 20, 30}') ON DUPLICATE KEY UPDATE c5 = c3[2,3];
|
||||
INSERT INTO t_grammer VALUES(69, 9, '{10, 20, 30}') ON DUPLICATE KEY UPDATE c5 = c3[1:2];
|
||||
-- support user defined type
|
||||
INSERT INTO t_grammer VALUES(71, 1) ON DUPLICATE KEY UPDATE c4.a = c3[1] + c1;
|
||||
INSERT INTO t_grammer VALUES(72, 2, '{71, 72, 73}') ON DUPLICATE KEY UPDATE c4.a = c3[1] + c1;
|
||||
INSERT INTO t_grammer VALUES(73, 3, '{71, 72, 73}') ON DUPLICATE KEY UPDATE c4.a = c3[1] + c1, c4.b = c3[2];
|
||||
INSERT INTO t_grammer VALUES(74, 4, '{71, 72, 73}', ROW(74, 75)) ON DUPLICATE KEY UPDATE c4 = ROW(740, 750);
|
||||
-- appoint INSERT target column
|
||||
INSERT INTO t_grammer (c5, c1, c2) VALUES('{81,82}', 81, DEFAULT) ON DUPLICATE KEY UPDATE c2 = VALUES(c1);
|
||||
INSERT INTO t_grammer (c3[1], c3[2], c1) VALUES(881, 882, 82) ON DUPLICATE KEY UPDATE c5 = VALUES(c3), c2 = VALUES(c3[1]);
|
||||
INSERT INTO t_grammer (c1, c3, c4) VALUES(83, '{81, 82, 83}', ROW(810, 820)) ON DUPLICATE KEY UPDATE c4 = EXCLUDED.c4;
|
||||
INSERT INTO t_grammer (c1, c3, c4.a) VALUES(84, '{81, 82, 83}', 850) ON DUPLICATE KEY UPDATE c4.b = c3[3];
|
||||
-- support UPDATE NOTHING
|
||||
INSERT INTO t_grammer VALUES(91, 1, '{91, 92, 93}', ROW(94, 95)) ON DUPLICATE KEY UPDATE NOTHING;
|
||||
INSERT INTO t_grammer (c5, c1, c2, c4) VALUES('{91,92}', 92, DEFAULT, ROW(910, 920)) ON DUPLICATE KEY UPDATE NOTHING;
|
||||
-- UPDATE target: unsupport with schema but support with tablename
|
||||
INSERT INTO t_grammer VALUES(0, 0, '{0,0}', ROW(0, 0), '{107, 108}') ON DUPLICATE KEY UPDATE
|
||||
upsert_test.t_grammer.c2 = c2 * 10, upsert_test.t_grammer.c3[1:2] = c5[1:2], upsert_test.t_grammer.c4.a = c1;
|
||||
ERROR: column "upsert_test.t_grammer" of relation "t_grammer" does not exist
|
||||
LINE 2: upsert_test.t_grammer.c2 = c2 * 10, upsert_test.t_grammer.c...
|
||||
^
|
||||
INSERT INTO t_grammer VALUES(101, 1, '{102, 103, 104}', ROW(105, 106), '{107, 108}') ON DUPLICATE KEY UPDATE
|
||||
t_grammer.c2 = c2 * 10, t_grammer.c3[1:2] = c5[1:2], t_grammer.c4.a = c1;
|
||||
-- INSERT target: appoint schema
|
||||
INSERT INTO upsert_test.t_grammer VALUES(102, 2, '{102, 103, 104}', ROW(105, 106), '{107, 108}') ON DUPLICATE KEY UPDATE
|
||||
t_grammer.c2 = EXCLUDED.c2 * 10, t_grammer.c3[1:2] = c5[1:2], t_grammer.c4.a = VALUES(c1);
|
||||
CREATE SCHEMA upsert_test_tmpschema;
|
||||
SET CURRENT_SCHEMA TO upsert_test_tmpschema;
|
||||
INSERT INTO upsert_test.t_grammer VALUES(103, 3, '{102, 103, 104}', ROW(105, 106), '{107, 108}') ON DUPLICATE KEY UPDATE
|
||||
t_grammer.c2 = EXCLUDED.c2 * 10, t_grammer.c3[1:2] = c5[1:2], t_grammer.c4.a = VALUES(c1);
|
||||
SET CURRENT_SCHEMA TO upsert_test;
|
||||
DROP SCHEMA upsert_test_tmpschema;
|
||||
-- support data type
|
||||
INSERT INTO t_data VALUES(11, 11, 11, 11, 11, '11', '11', '11', '2020-04-23', '2020-04-23 11:00', '1:00') ON DUPLICATE KEY UPDATE NOTHING;
|
||||
INSERT INTO t_data VALUES(12, 12, 12, 12, 12, '12', '12', '12', '2020-04-24', '2020-04-24 11:00', '2:00')
|
||||
ON DUPLICATE KEY UPDATE
|
||||
c_tiny = 13, c_smallint = 13, c_bigint = 13, c_numeric = 13,
|
||||
c_var = '13', c_text = '13', c_bytea = '13', c_date = '2020-05-24', c_timestamp = '2020-05-24 11:00', c_time = '3:00';
|
||||
INSERT INTO t_data VALUES(13, 13, 13, 13, 13, '13', '13', '13', '2020-04-25', '2020-04-25 11:00', '4:00')
|
||||
ON DUPLICATE KEY UPDATE
|
||||
c_tiny = EXCLUDED.c_tiny + 1, c_smallint = EXCLUDED.c_smallint + 1, c_bigint = EXCLUDED.c_bigint + 1, c_numeric = EXCLUDED.c_numeric + 1,
|
||||
c_var = EXCLUDED.c_var || '3', c_text = EXCLUDED.c_text || '3', c_bytea = EXCLUDED.c_bytea || '3',
|
||||
c_date = EXCLUDED.c_date + '1 day'::interval, c_timestamp = EXCLUDED.c_timestamp + '1 day'::interval, c_time = EXCLUDED.c_time + '1 hour'::interval;
|
||||
-- support UPDATE to default
|
||||
INSERT INTO t_default DEFAULT VALUES ON DUPLICATE KEY UPDATE c2 = 100, c3 = '2020-05-17';
|
||||
INSERT INTO t_default VALUES(91, 0.91, '2020-05-17') ON DUPLICATE KEY UPDATE c2 = DEFAULT, c3 = DEFAULT;
|
||||
INSERT INTO t_default VALUES(92, DEFAULT, '2020-05-17') ON DUPLICATE KEY UPDATE c2 = 10, c3 = DEFAULT;
|
||||
-- unsupport alias
|
||||
INSERT INTO t_grammer AS alias VALUES (91) ON DUPLICATE KEY UPDATE c2 = VALUES(c1);
|
||||
ERROR: syntax error at or near "AS"
|
||||
LINE 1: INSERT INTO t_grammer AS alias VALUES (91) ON DUPLICATE KEY ...
|
||||
^
|
||||
-- unsupport VALUES with expr
|
||||
INSERT INTO t_grammer VALUES(0, 0) ON DUPLICATE KEY UPDATE c2 = sqrt(VALUES(c2));
|
||||
ERROR: syntax error at or near "("
|
||||
LINE 1: ... VALUES(0, 0) ON DUPLICATE KEY UPDATE c2 = sqrt(VALUES(c2));
|
||||
^
|
||||
INSERT INTO t_grammer VALUES(0, 0) ON DUPLICATE KEY UPDATE c2 = VALUES(c3[1]) + 1;
|
||||
ERROR: syntax error at or near "+"
|
||||
LINE 1: ...VALUES(0, 0) ON DUPLICATE KEY UPDATE c2 = VALUES(c3[1]) + 1;
|
||||
^
|
||||
INSERT INTO t_grammer VALUES(0, 0) ON DUPLICATE KEY UPDATE c2 = VALUES(c4.a) + 1;
|
||||
ERROR: only allow column name within VALUES
|
||||
LINE 1: ... VALUES(0, 0) ON DUPLICATE KEY UPDATE c2 = VALUES(c4.a) + 1;
|
||||
^
|
||||
INSERT INTO t_grammer VALUES(0, 0) ON DUPLICATE KEY UPDATE c2 = VALUES(t_grammer.c3[1]) + 1;
|
||||
ERROR: only allow column name within VALUES
|
||||
LINE 1: ... VALUES(0, 0) ON DUPLICATE KEY UPDATE c2 = VALUES(t_grammer....
|
||||
^
|
||||
-- unsupport VALUES with table name
|
||||
INSERT INTO t_grammer VALUES(0, 0) ON DUPLICATE KEY UPDATE c2 = VALUES(t_grammer.c4.a);
|
||||
ERROR: only allow column name within VALUES
|
||||
LINE 1: ... VALUES(0, 0) ON DUPLICATE KEY UPDATE c2 = VALUES(t_grammer....
|
||||
^
|
||||
INSERT INTO t_grammer VALUES(0, 0) ON DUPLICATE KEY UPDATE c2 = VALUES(t_grammer.c2);
|
||||
ERROR: only allow column name within VALUES
|
||||
LINE 1: ... VALUES(0, 0) ON DUPLICATE KEY UPDATE c2 = VALUES(t_grammer....
|
||||
^
|
||||
-- unsupport DEFAULT with expr
|
||||
INSERT INTO t_grammer VALUES(0, 0) ON DUPLICATE KEY UPDATE c2 = DEFAULT + 1;
|
||||
ERROR: syntax error at or near "+"
|
||||
LINE 1: ...ammer VALUES(0, 0) ON DUPLICATE KEY UPDATE c2 = DEFAULT + 1;
|
||||
^
|
||||
-- unsupport user defined typed column's element
|
||||
INSERT INTO t_grammer VALUES(0, 0) ON DUPLICATE KEY UPDATE c2 = VALUES(c4.a);
|
||||
ERROR: only allow column name within VALUES
|
||||
LINE 1: ...mmer VALUES(0, 0) ON DUPLICATE KEY UPDATE c2 = VALUES(c4.a);
|
||||
^
|
||||
INSERT INTO t_grammer VALUES(0, 0) ON DUPLICATE KEY UPDATE c2 = EXCLUDED.c4.a;
|
||||
ERROR: schema "excluded" does not exist
|
||||
CONTEXT: referenced column: c2
|
||||
INSERT INTO t_grammer VALUES(0, 0) ON DUPLICATE KEY UPDATE c2 = c4.a;
|
||||
ERROR: missing FROM-clause entry for table "c4"
|
||||
LINE 1: ...TO t_grammer VALUES(0, 0) ON DUPLICATE KEY UPDATE c2 = c4.a;
|
||||
^
|
||||
CONTEXT: referenced column: c2
|
||||
SELECT * FROM t_data ORDER BY 1;
|
||||
c_int | c_tiny | c_smallint | c_bigint | c_numeric | c_var | c_text | c_bytea | c_date | c_timestamp | c_time | c_intarray | c_com
|
||||
-------+--------+------------+----------+-----------+-------+--------+---------+--------------------------+--------------------------+----------+------------+-------
|
||||
11 | 11 | 11 | 11 | 11 | 11 | 11 | \x3131 | Thu Apr 23 00:00:00 2020 | Thu Apr 23 11:00:00 2020 | 01:00:00 | |
|
||||
12 | 12 | 12 | 12 | 12 | 12 | 12 | \x3132 | Fri Apr 24 00:00:00 2020 | Fri Apr 24 11:00:00 2020 | 02:00:00 | |
|
||||
13 | 13 | 13 | 13 | 13 | 13 | 13 | \x3133 | Sat Apr 25 00:00:00 2020 | Sat Apr 25 11:00:00 2020 | 04:00:00 | |
|
||||
(3 rows)
|
||||
|
||||
SELECT * FROM t_grammer ORDER BY 1;
|
||||
c1 | c2 | c3 | c4 | c5
|
||||
-----+------+---------------+-----------+-----------
|
||||
11 | 1 | | |
|
||||
12 | 2 | | |
|
||||
23 | -100 | | |
|
||||
24 | -100 | | |
|
||||
31 | 1 | | |
|
||||
32 | 2 | | |
|
||||
41 | 1 | | |
|
||||
42 | 2 | | |
|
||||
51 | 1 | | |
|
||||
52 | 2 | | |
|
||||
53 | 3 | | |
|
||||
54 | 4 | | |
|
||||
55 | 5 | | |
|
||||
61 | 1 | | |
|
||||
62 | 2 | | |
|
||||
63 | 3 | | |
|
||||
64 | 4 | {10,20,30} | |
|
||||
65 | 5 | {10,20,30} | |
|
||||
66 | 6 | {10,20,30} | |
|
||||
67 | 7 | {10,20,30} | |
|
||||
68 | 8 | {10,20,30} | |
|
||||
69 | 9 | {10,20,30} | |
|
||||
71 | 1 | | |
|
||||
72 | 2 | {71,72,73} | |
|
||||
73 | 3 | {71,72,73} | |
|
||||
74 | 4 | {71,72,73} | (74,75) |
|
||||
81 | -100 | | | {81,82}
|
||||
82 | -100 | {881,882} | |
|
||||
83 | -100 | {81,82,83} | (810,820) |
|
||||
84 | -100 | {81,82,83} | (850,) |
|
||||
91 | 1 | {91,92,93} | (94,95) |
|
||||
92 | -100 | | (910,920) | {91,92}
|
||||
101 | 1 | {102,103,104} | (105,106) | {107,108}
|
||||
102 | 2 | {102,103,104} | (105,106) | {107,108}
|
||||
103 | 3 | {102,103,104} | (105,106) | {107,108}
|
||||
(35 rows)
|
||||
|
||||
SELECT * FROM t_default ORDER BY 1;
|
||||
--? c1 | c2 | c3
|
||||
--?
|
||||
--? 10 | .396464773453772 | Wed Apr 29 10:25:23.202729 2020
|
||||
--? 91 | .91 | Sun May 17 00:00:00 2020
|
||||
--? 92 | .840485369320959 | Sun May 17 00:00:00 2020
|
||||
(3 rows)
|
||||
|
||||
|
|
@ -0,0 +1,188 @@
|
|||
\c upsert
|
||||
SET CURRENT_SCHEMA TO upsert_test;
|
||||
-- enable_upsert_to_merge must be off, or upsert will be translated to merge.
|
||||
SET enable_upsert_to_merge TO OFF;
|
||||
SHOW enable_upsert_to_merge;
|
||||
enable_upsert_to_merge
|
||||
------------------------
|
||||
off
|
||||
(1 row)
|
||||
|
||||
-- support multiple set
|
||||
INSERT INTO t_grammer VALUES(11, 1) ON DUPLICATE KEY UPDATE c2 = 2, c4 = ROW(10, 20), c3 = '{10, 20, 30}';
|
||||
INSERT INTO t_grammer VALUES(12, 2) ON DUPLICATE KEY UPDATE c2 = 2, c3[1] = 3;
|
||||
-- support const value and expr
|
||||
INSERT INTO t_grammer VALUES(23) ON DUPLICATE KEY UPDATE c2 = 2;
|
||||
INSERT INTO t_grammer VALUES(24) ON DUPLICATE KEY UPDATE c2 = length('test') + 100;
|
||||
-- support without table name
|
||||
INSERT INTO t_grammer VALUES(31, 1) ON DUPLICATE KEY UPDATE c2 = c1, c4.a = VALUES(c1);
|
||||
INSERT INTO t_grammer VALUES(32, 2) ON DUPLICATE KEY UPDATE c2 = c1 + 5, c4.a = VALUES(c1);
|
||||
-- support with table name
|
||||
INSERT INTO t_grammer VALUES(41, 1) ON DUPLICATE KEY UPDATE c2 = t_grammer.c1, c4.a = VALUES(c1);
|
||||
INSERT INTO t_grammer VALUES(42, 2) ON DUPLICATE KEY UPDATE c2 = t_grammer.c1 + 5, c4.a = VALUES(c1);
|
||||
-- support EXCLUDED alone and with expr
|
||||
INSERT INTO t_grammer VALUES(51, 1) ON DUPLICATE KEY UPDATE c2 = c1 + 5, c4.a = EXCLUDED.c1;
|
||||
INSERT INTO t_grammer VALUES(52, 2) ON DUPLICATE KEY UPDATE c2 = t_grammer.c1 + 5, c4.a = EXCLUDED.c1 + 5;
|
||||
INSERT INTO t_grammer VALUES(53, 3) ON DUPLICATE KEY UPDATE c4.a = sqrt(EXCLUDED.c1 - EXCLUDED.c2 - 1) + 1, c2 = t_grammer.c1 + 5;
|
||||
INSERT INTO t_grammer VALUES(54, 4) ON DUPLICATE KEY UPDATE c4.b = EXCLUDED.c1 + t_grammer.c1;
|
||||
INSERT INTO t_grammer VALUES(55, 5) ON DUPLICATE KEY UPDATE c4.a = EXCLUDED.c2, c4.b = EXCLUDED.c1 + sqrt(c1 - 6);
|
||||
-- support ARRAY
|
||||
INSERT INTO t_grammer VALUES(61, 1) ON DUPLICATE KEY UPDATE c2 = VALUES(c3[1]);
|
||||
INSERT INTO t_grammer VALUES(62, 2) ON DUPLICATE KEY UPDATE c5 = VALUES(c3[2,3]);
|
||||
INSERT INTO t_grammer VALUES(63, 3) ON DUPLICATE KEY UPDATE c5 = VALUES(c3[2:3]);
|
||||
INSERT INTO t_grammer VALUES(64, 4, '{10, 20, 30}') ON DUPLICATE KEY UPDATE c2 = EXCLUDED.c3[1];
|
||||
INSERT INTO t_grammer VALUES(65, 5, '{10, 20, 30}') ON DUPLICATE KEY UPDATE c5 = EXCLUDED.c3[2,3];
|
||||
INSERT INTO t_grammer VALUES(66, 6, '{10, 20, 30}') ON DUPLICATE KEY UPDATE c5 = EXCLUDED.c3[1:2];
|
||||
INSERT INTO t_grammer VALUES(67, 7, '{10, 20, 30}') ON DUPLICATE KEY UPDATE c2 = c3[1];
|
||||
INSERT INTO t_grammer VALUES(68, 8, '{10, 20, 30}') ON DUPLICATE KEY UPDATE c5 = c3[2,3];
|
||||
INSERT INTO t_grammer VALUES(69, 9, '{10, 20, 30}') ON DUPLICATE KEY UPDATE c5 = c3[1:2];
|
||||
-- support user defined type
|
||||
INSERT INTO t_grammer VALUES(71, 1) ON DUPLICATE KEY UPDATE c4.a = c3[1] + c1;
|
||||
INSERT INTO t_grammer VALUES(72, 2, '{71, 72, 73}') ON DUPLICATE KEY UPDATE c4.a = c3[1] + c1;
|
||||
INSERT INTO t_grammer VALUES(73, 3, '{71, 72, 73}') ON DUPLICATE KEY UPDATE c4.a = c3[1] + c1, c4.b = c3[2];
|
||||
INSERT INTO t_grammer VALUES(74, 4, '{71, 72, 73}', ROW(74, 75)) ON DUPLICATE KEY UPDATE c4 = ROW(740, 750);
|
||||
-- appoint INSERT target column
|
||||
INSERT INTO t_grammer (c5, c1, c2) VALUES('{81,82}', 81, DEFAULT) ON DUPLICATE KEY UPDATE c2 = VALUES(c1);
|
||||
INSERT INTO t_grammer (c3[1], c3[2], c1) VALUES(881, 882, 82) ON DUPLICATE KEY UPDATE c5 = VALUES(c3), c2 = VALUES(c3[1]);
|
||||
INSERT INTO t_grammer (c1, c3, c4) VALUES(83, '{81, 82, 83}', ROW(810, 820)) ON DUPLICATE KEY UPDATE c4 = EXCLUDED.c4;
|
||||
INSERT INTO t_grammer (c1, c3, c4.a) VALUES(84, '{81, 82, 83}', 850) ON DUPLICATE KEY UPDATE c4.b = c3[3];
|
||||
-- support UPDATE NOTHING
|
||||
INSERT INTO t_grammer VALUES(91, 1, '{91, 92, 93}', ROW(94, 95)) ON DUPLICATE KEY UPDATE NOTHING;
|
||||
INSERT INTO t_grammer (c5, c1, c2, c4) VALUES('{91,92}', 92, DEFAULT, ROW(910, 920)) ON DUPLICATE KEY UPDATE NOTHING;
|
||||
-- UPDATE target: unsupport with schema but support with tablename
|
||||
INSERT INTO t_grammer VALUES(0, 0, '{0,0}', ROW(0, 0), '{107, 108}') ON DUPLICATE KEY UPDATE
|
||||
upsert_test.t_grammer.c2 = c2 * 10, upsert_test.t_grammer.c3[1:2] = c5[1:2], upsert_test.t_grammer.c4.a = c1;
|
||||
ERROR: column "upsert_test.t_grammer" of relation "t_grammer" does not exist
|
||||
LINE 2: upsert_test.t_grammer.c2 = c2 * 10, upsert_test.t_grammer.c...
|
||||
^
|
||||
INSERT INTO t_grammer VALUES(101, 1, '{102, 103, 104}', ROW(105, 106), '{107, 108}') ON DUPLICATE KEY UPDATE
|
||||
t_grammer.c2 = c2 * 10, t_grammer.c3[1:2] = c5[1:2], t_grammer.c4.a = c1;
|
||||
-- INSERT target: appoint schema
|
||||
INSERT INTO upsert_test.t_grammer VALUES(102, 2, '{102, 103, 104}', ROW(105, 106), '{107, 108}') ON DUPLICATE KEY UPDATE
|
||||
t_grammer.c2 = EXCLUDED.c2 * 10, t_grammer.c3[1:2] = c5[1:2], t_grammer.c4.a = VALUES(c1);
|
||||
CREATE SCHEMA upsert_test_tmp;
|
||||
SET CURRENT_SCHEMA TO upsert_test_tmp;
|
||||
INSERT INTO upsert_test.t_grammer VALUES(103, 3, '{102, 103, 104}', ROW(105, 106), '{107, 108}') ON DUPLICATE KEY UPDATE
|
||||
t_grammer.c2 = EXCLUDED.c2 * 10, t_grammer.c3[1:2] = c5[1:2], t_grammer.c4.a = VALUES(c1);
|
||||
SET CURRENT_SCHEMA TO upsert_test;
|
||||
DROP SCHEMA upsert_test_tmp;
|
||||
-- support data type
|
||||
INSERT INTO t_data VALUES(11, 11, 11, 11, 11, '11', '11', '11', '2020-04-23', '2020-04-23 11:00', '1:00') ON DUPLICATE KEY UPDATE NOTHING;
|
||||
INSERT INTO t_data VALUES(12, 12, 12, 12, 12, '12', '12', '12', '2020-04-24', '2020-04-24 11:00', '2:00')
|
||||
ON DUPLICATE KEY UPDATE
|
||||
c_tiny = 13, c_smallint = 13, c_bigint = 13, c_numeric = 13,
|
||||
c_var = '13', c_text = '13', c_bytea = '13', c_date = '2020-05-24', c_timestamp = '2020-05-24 11:00', c_time = '3:00';
|
||||
INSERT INTO t_data VALUES(13, 13, 13, 13, 13, '13', '13', '13', '2020-04-25', '2020-04-25 11:00', '4:00')
|
||||
ON DUPLICATE KEY UPDATE
|
||||
c_tiny = EXCLUDED.c_tiny + 1, c_smallint = EXCLUDED.c_smallint + 1, c_bigint = EXCLUDED.c_bigint + 1, c_numeric = EXCLUDED.c_numeric + 1,
|
||||
c_var = EXCLUDED.c_var || '3', c_text = EXCLUDED.c_text || '3', c_bytea = EXCLUDED.c_bytea || '3',
|
||||
c_date = EXCLUDED.c_date + '1 day'::interval, c_timestamp = EXCLUDED.c_timestamp + '1 day'::interval, c_time = EXCLUDED.c_time + '1 hour'::interval;
|
||||
-- support UPDATE to default
|
||||
INSERT INTO t_default DEFAULT VALUES ON DUPLICATE KEY UPDATE c2 = 100, c3 = '2020-05-17';
|
||||
INSERT INTO t_default VALUES(91, 0.91, '2020-05-17') ON DUPLICATE KEY UPDATE c2 = DEFAULT, c3 = DEFAULT;
|
||||
INSERT INTO t_default VALUES(92, DEFAULT, '2020-05-17') ON DUPLICATE KEY UPDATE c2 = 10, c3 = DEFAULT;
|
||||
-- unsupport alias
|
||||
INSERT INTO t_grammer AS alias VALUES (91) ON DUPLICATE KEY UPDATE c2 = VALUES(c1);
|
||||
ERROR: syntax error at or near "AS"
|
||||
LINE 1: INSERT INTO t_grammer AS alias VALUES (91) ON DUPLICATE KEY ...
|
||||
^
|
||||
-- unsupport VALUES with expr
|
||||
INSERT INTO t_grammer VALUES(0, 0) ON DUPLICATE KEY UPDATE c2 = sqrt(VALUES(c2));
|
||||
ERROR: syntax error at or near "("
|
||||
LINE 1: ... VALUES(0, 0) ON DUPLICATE KEY UPDATE c2 = sqrt(VALUES(c2));
|
||||
^
|
||||
INSERT INTO t_grammer VALUES(0, 0) ON DUPLICATE KEY UPDATE c2 = VALUES(c3[1]) + 1;
|
||||
ERROR: syntax error at or near "+"
|
||||
LINE 1: ...VALUES(0, 0) ON DUPLICATE KEY UPDATE c2 = VALUES(c3[1]) + 1;
|
||||
^
|
||||
INSERT INTO t_grammer VALUES(0, 0) ON DUPLICATE KEY UPDATE c2 = VALUES(c4.a) + 1;
|
||||
ERROR: only allow column name within VALUES
|
||||
LINE 1: ... VALUES(0, 0) ON DUPLICATE KEY UPDATE c2 = VALUES(c4.a) + 1;
|
||||
^
|
||||
INSERT INTO t_grammer VALUES(0, 0) ON DUPLICATE KEY UPDATE c2 = VALUES(t_grammer.c3[1]) + 1;
|
||||
ERROR: only allow column name within VALUES
|
||||
LINE 1: ... VALUES(0, 0) ON DUPLICATE KEY UPDATE c2 = VALUES(t_grammer....
|
||||
^
|
||||
-- unsupport VALUES with table name
|
||||
INSERT INTO t_grammer VALUES(0, 0) ON DUPLICATE KEY UPDATE c2 = VALUES(t_grammer.c4.a);
|
||||
ERROR: only allow column name within VALUES
|
||||
LINE 1: ... VALUES(0, 0) ON DUPLICATE KEY UPDATE c2 = VALUES(t_grammer....
|
||||
^
|
||||
INSERT INTO t_grammer VALUES(0, 0) ON DUPLICATE KEY UPDATE c2 = VALUES(t_grammer.c2);
|
||||
ERROR: only allow column name within VALUES
|
||||
LINE 1: ... VALUES(0, 0) ON DUPLICATE KEY UPDATE c2 = VALUES(t_grammer....
|
||||
^
|
||||
-- unsupport DEFAULT with expr
|
||||
INSERT INTO t_grammer VALUES(0, 0) ON DUPLICATE KEY UPDATE c2 = DEFAULT + 1;
|
||||
ERROR: syntax error at or near "+"
|
||||
LINE 1: ...ammer VALUES(0, 0) ON DUPLICATE KEY UPDATE c2 = DEFAULT + 1;
|
||||
^
|
||||
-- unsupport user defined typed column's element
|
||||
INSERT INTO t_grammer VALUES(0, 0) ON DUPLICATE KEY UPDATE c2 = VALUES(c4.a);
|
||||
ERROR: only allow column name within VALUES
|
||||
LINE 1: ...mmer VALUES(0, 0) ON DUPLICATE KEY UPDATE c2 = VALUES(c4.a);
|
||||
^
|
||||
INSERT INTO t_grammer VALUES(0, 0) ON DUPLICATE KEY UPDATE c2 = EXCLUDED.c4.a;
|
||||
ERROR: schema "excluded" does not exist
|
||||
CONTEXT: referenced column: c2
|
||||
INSERT INTO t_grammer VALUES(0, 0) ON DUPLICATE KEY UPDATE c2 = c4.a;
|
||||
ERROR: missing FROM-clause entry for table "c4"
|
||||
LINE 1: ...TO t_grammer VALUES(0, 0) ON DUPLICATE KEY UPDATE c2 = c4.a;
|
||||
^
|
||||
CONTEXT: referenced column: c2
|
||||
SELECT * FROM t_data ORDER BY 1;
|
||||
c_int | c_tiny | c_smallint | c_bigint | c_numeric | c_var | c_text | c_bytea | c_date | c_timestamp | c_time | c_intarray | c_com
|
||||
-------+--------+------------+----------+-----------+-------+--------+----------+--------------------------+--------------------------+----------+------------+-------
|
||||
11 | 11 | 11 | 11 | 11 | 11 | 11 | \x3131 | Thu Apr 23 00:00:00 2020 | Thu Apr 23 11:00:00 2020 | 01:00:00 | |
|
||||
12 | 13 | 13 | 13 | 13 | 13 | 13 | \x3133 | Sun May 24 00:00:00 2020 | Sun May 24 11:00:00 2020 | 03:00:00 | |
|
||||
13 | 14 | 14 | 14 | 14 | 133 | 133 | \x313333 | Sun Apr 26 00:00:00 2020 | Sun Apr 26 11:00:00 2020 | 05:00:00 | |
|
||||
(3 rows)
|
||||
|
||||
SELECT * FROM t_grammer ORDER BY 1;
|
||||
c1 | c2 | c3 | c4 | c5
|
||||
-----+------+---------------+-----------+-----------
|
||||
11 | 2 | {10,20,30} | (10,20) |
|
||||
12 | 2 | {3} | |
|
||||
23 | 2 | | |
|
||||
24 | 104 | | |
|
||||
31 | 31 | | (31,) |
|
||||
32 | 37 | | (32,) |
|
||||
41 | 41 | | (41,) |
|
||||
42 | 47 | | (42,) |
|
||||
51 | 56 | | (51,) |
|
||||
52 | 57 | | (57,) |
|
||||
53 | 58 | | (8,) |
|
||||
54 | 4 | | (,108) |
|
||||
55 | 5 | | (5,62) |
|
||||
61 | | | |
|
||||
62 | 2 | | |
|
||||
63 | 3 | | |
|
||||
64 | 10 | {10,20,30} | |
|
||||
65 | 5 | {10,20,30} | | {20,30}
|
||||
66 | 6 | {10,20,30} | | {10,20}
|
||||
67 | 10 | {10,20,30} | |
|
||||
68 | 8 | {10,20,30} | | {20,30}
|
||||
69 | 9 | {10,20,30} | | {10,20}
|
||||
71 | 1 | | (,) |
|
||||
72 | 2 | {71,72,73} | (143,) |
|
||||
73 | 3 | {71,72,73} | (144,72) |
|
||||
74 | 4 | {71,72,73} | (740,750) |
|
||||
81 | 81 | | | {81,82}
|
||||
82 | 881 | {881,882} | | {881,882}
|
||||
83 | -100 | {81,82,83} | (810,820) |
|
||||
84 | -100 | {81,82,83} | (850,83) |
|
||||
91 | 1 | {91,92,93} | (94,95) |
|
||||
92 | -100 | | (910,920) | {91,92}
|
||||
101 | 10 | {107,108,104} | (101,106) | {107,108}
|
||||
102 | 20 | {107,108,104} | (102,106) | {107,108}
|
||||
103 | 30 | {107,108,104} | (103,106) | {107,108}
|
||||
(35 rows)
|
||||
|
||||
SELECT * FROM t_default ORDER BY 1;
|
||||
--? c1 | c2 | c3
|
||||
--?
|
||||
--? 10 | 100 | Sun May 17 00:00:00 2020
|
||||
--? 91 | .840485369320959 | Wed Apr 29 10:25:28.439693 2020
|
||||
--? 92 | 10 | Wed Apr 29 10:25:28.442916 2020
|
||||
(3 rows)
|
||||
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
-- Note: about upsert test
|
||||
-- test point:
|
||||
-- grammer
|
||||
-- table, unlogged table, temp table, matview
|
||||
-- constraint(primary key, index, foreign key, null ...)
|
||||
-- trigger
|
||||
-- sequence
|
||||
CREATE DATABASE upsert WITH TEMPLATE template0 ENCODING 'UTF8';
|
||||
\c upsert
|
||||
-- grammer test
|
||||
CREATE SCHEMA upsert_test;
|
||||
SET CURRENT_SCHEMA TO upsert_test;
|
||||
CREATE TYPE atype AS(a int, b int);
|
||||
CREATE TYPE btype AS(a int, b atype, c varchar[3]);
|
||||
CREATE TABLE t_grammer (c1 INT PRIMARY KEY, c2 INT DEFAULT -100, c3 int[3], c4 atype, c5 int[2]);
|
||||
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "t_grammer_pkey" for table "t_grammer"
|
||||
CREATE TABLE t_default (c1 INT PRIMARY KEY DEFAULT 10, c2 FLOAT DEFAULT random(), c3 TIMESTAMP DEFAULT current_timestamp);
|
||||
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "t_default_pkey" for table "t_default"
|
||||
CREATE TABLE t_data (c_int INT PRIMARY KEY, c_tiny TINYINT, c_smallint SMALLINT, c_bigint BIGINT, c_numeric NUMERIC,
|
||||
c_var VARCHAR, c_text TEXT, c_bytea BYTEA, c_date DATE, c_timestamp TIMESTAMP, c_time TIME,
|
||||
c_intarray INT[3], c_com atype);
|
||||
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "t_data_pkey" for table "t_data"
|
||||
CREATE TABLE t_trigger (key INT PRIMARY KEY, color TEXT);
|
||||
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "t_trigger_pkey" for table "t_trigger"
|
||||
-- unlogged table
|
||||
CREATE SCHEMA upsert_test_unlog;
|
||||
SET CURRENT_SCHEMA TO upsert_test_unlog;
|
||||
CREATE TYPE atype AS(a int, b int);
|
||||
CREATE TYPE btype AS(a int, b atype, c varchar[3]);
|
||||
CREATE UNLOGGED TABLE t_hash_unlog_0 (c1 INT, c2 INT, c3 VARCHAR, c4 INT[3], c5 INT[5], c6 atype, c7 btype);
|
||||
CREATE UNLOGGED TABLE t_hash_unlog_1 (c1 INT, c2 INT PRIMARY KEY, c3 VARCHAR, c4 INT[3], c5 INT[5], c6 atype, c7 btype);
|
||||
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "t_hash_unlog_1_pkey" for table "t_hash_unlog_1"
|
||||
CREATE UNLOGGED TABLE t_rep_unlog_0 (c1 INT, c2 INT, c3 VARCHAR, c4 INT[3], c5 INT[5], c6 atype, c7 btype) ;
|
||||
CREATE UNLOGGED TABLE t_rep_unlog_1 (c1 INT, c2 INT PRIMARY KEY, c3 VARCHAR, c4 INT[3], c5 INT[5], c6 atype, c7 btype);
|
||||
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "t_rep_unlog_1_pkey" for table "t_rep_unlog_1"
|
||||
-- temp table
|
||||
-- temp table can not be created here, we create it in upsert_tmp_test.
|
||||
-- restriction test
|
||||
CREATE SCHEMA upsert_test_etc;
|
||||
SET CURRENT_SCHEMA TO upsert_test_etc;
|
||||
create table up_neg_01 (c1 int, c2 int, c3 int) with (ORIENTATION = COLUMN);
|
||||
create table up_neg_02 (c1 int, c2 int, c3 int) with (ORIENTATION = COLUMN);
|
||||
create table up_neg_03 (c1 int, c2 int UNIQUE DEFERRABLE, c3 int);
|
||||
NOTICE: CREATE TABLE / UNIQUE will create implicit index "up_neg_03_c2_key" for table "up_neg_03"
|
||||
create table up_neg_04 (c1 int, c2 int UNIQUE, c3 int);
|
||||
NOTICE: CREATE TABLE / UNIQUE will create implicit index "up_neg_04_c2_key" for table "up_neg_04"
|
||||
create table up_neg_05(c1 int, c2 int, c3 int, c4 int unique, c5 int primary key, unique(c2,c3));
|
||||
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "up_neg_05_pkey" for table "up_neg_05"
|
||||
NOTICE: CREATE TABLE / UNIQUE will create implicit index "up_neg_05_c4_key" for table "up_neg_05"
|
||||
NOTICE: CREATE TABLE / UNIQUE will create implicit index "up_neg_05_c2_c3_key" for table "up_neg_05"
|
||||
create table up_neg_0(c1 int, c2 int, c3 int, c4 int unique, c5 int primary key, unique(c2,c3)) ;
|
||||
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "up_neg_0_pkey" for table "up_neg_0"
|
||||
NOTICE: CREATE TABLE / UNIQUE will create implicit index "up_neg_0_c4_key" for table "up_neg_0"
|
||||
NOTICE: CREATE TABLE / UNIQUE will create implicit index "up_neg_0_c2_c3_key" for table "up_neg_0"
|
||||
create table up_neg_06(c1 int, c2 int, c3 int unique) ;
|
||||
NOTICE: CREATE TABLE / UNIQUE will create implicit index "up_neg_06_c3_key" for table "up_neg_06"
|
||||
create table up_neg_07(c1 int, c2 int, c3 int unique) ;
|
||||
NOTICE: CREATE TABLE / UNIQUE will create implicit index "up_neg_07_c3_key" for table "up_neg_07"
|
||||
create table up_neg_08(c1 int, c2 int, c3 int unique) ;
|
||||
NOTICE: CREATE TABLE / UNIQUE will create implicit index "up_neg_08_c3_key" for table "up_neg_08"
|
||||
create table up_neg_09(c1 int, c2 int, c3 int, unique(c2,c3)) ;
|
||||
NOTICE: CREATE TABLE / UNIQUE will create implicit index "up_neg_09_c2_c3_key" for table "up_neg_09"
|
||||
create table up_neg_10(c1 int, c2 int, c3 int, unique(c2,c3)) ;
|
||||
NOTICE: CREATE TABLE / UNIQUE will create implicit index "up_neg_10_c2_c3_key" for table "up_neg_10"
|
||||
create view up_view as select *from up_neg_01;
|
||||
create materialized view mat_view as select *from up_neg_01;
|
||||
create table pkt (a int primary key, b int, c int);
|
||||
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "pkt_pkey" for table "pkt"
|
||||
create table fkt (a int primary key, b int references pkt, c int);
|
||||
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "fkt_pkey" for table "fkt"
|
||||
-- procedure test
|
||||
CREATE SCHEMA upsert_test_procedure;
|
||||
-- explain test
|
||||
CREATE SCHEMA upsert_test_explain;
|
||||
SET CURRENT_SCHEMA TO upsert_test_explain;
|
||||
create table up_expl_hash(c1 int, c2 int, c3 int unique) ;
|
||||
NOTICE: CREATE TABLE / UNIQUE will create implicit index "up_expl_hash_c3_key" for table "up_expl_hash"
|
||||
create table up_expl_repl(c1 int, c2 int, c3 int unique) ;
|
||||
NOTICE: CREATE TABLE / UNIQUE will create implicit index "up_expl_repl_c3_key" for table "up_expl_repl"
|
||||
create table up_expl_part(c1 int, c2 int, c3 int unique) ;
|
||||
NOTICE: CREATE TABLE / UNIQUE will create implicit index "up_expl_part_c3_key" for table "up_expl_part"
|
||||
create unlogged table up_expl_unlog(c1 int, c2 int, c3 int unique) ;
|
||||
NOTICE: CREATE TABLE / UNIQUE will create implicit index "up_expl_unlog_c3_key" for table "up_expl_unlog"
|
||||
create table up_expl_node(c1 int, c2 int, c3 int unique) ;
|
||||
NOTICE: CREATE TABLE / UNIQUE will create implicit index "up_expl_node_c3_key" for table "up_expl_node"
|
||||
create table up_expl_repl(c1 int, c2 int, c3 int unique) ;
|
||||
ERROR: relation "up_expl_repl" already exists
|
||||
create table up_expl_repl2(c1 int, c2 int, c3 int, c4 int unique, c5 int primary key, unique(c2,c3));
|
||||
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "up_expl_repl2_pkey" for table "up_expl_repl2"
|
||||
NOTICE: CREATE TABLE / UNIQUE will create implicit index "up_expl_repl2_c4_key" for table "up_expl_repl2"
|
||||
NOTICE: CREATE TABLE / UNIQUE will create implicit index "up_expl_repl2_c2_c3_key" for table "up_expl_repl2"
|
||||
-- create temp table up_expl_temp(c1 int, c2 int, c3 int unique);
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
CREATE DATABASE upsert_etc;
|
||||
\c upsert_etc;
|
||||
CREATE SCHEMA upsert_test_etc;
|
||||
SET CURRENT_SCHEMA TO upsert_test_etc;
|
||||
|
|
@ -0,0 +1,229 @@
|
|||
/*
|
||||
* upsert negative test cases
|
||||
*
|
||||
table cases
|
||||
col table
|
||||
ORC table
|
||||
VIEW
|
||||
MAT view
|
||||
index
|
||||
DEFERABLE index
|
||||
insert stmt
|
||||
returning
|
||||
with
|
||||
with recur
|
||||
update stmt
|
||||
VALUES with expr
|
||||
update distribute key
|
||||
update primary key
|
||||
update unique key
|
||||
update partition key
|
||||
where clause
|
||||
with clause
|
||||
sub query
|
||||
*/
|
||||
--------------------------------------------------------------------------------------------
|
||||
\c upsert
|
||||
SET CURRENT_SCHEMA TO upsert_test_etc;
|
||||
-- enable_upsert_to_merge must be off, or upsert will be translated to merge.
|
||||
SET enable_upsert_to_merge TO OFF;
|
||||
SHOW enable_upsert_to_merge;
|
||||
enable_upsert_to_merge
|
||||
------------------------
|
||||
off
|
||||
(1 row)
|
||||
|
||||
insert into up_neg_04 select a,a,a from generate_series(1,20) as a;
|
||||
insert into up_neg_05 select a,a,a,a,a from generate_series(1,20) as a;
|
||||
insert into up_neg_06 select a,a,a from generate_series(1,20) as a;
|
||||
insert into up_neg_07 select a,a,a from generate_series(1,20) as a;
|
||||
insert into up_neg_08 select a,a,a from generate_series(1,20) as a;
|
||||
insert into up_neg_09 select a,a,a from generate_series(1,20) as a;
|
||||
insert into up_neg_10 select a,a,a from generate_series(1,20) as a;
|
||||
-- table cases
|
||||
---- col table
|
||||
insert into up_neg_01 values(1,2,3) on duplicate key update c3 = 1;
|
||||
ERROR: INSERT ON DUPLICATE KEY UPDATE is not supported on column orientated table.
|
||||
---- ORC table
|
||||
insert into up_neg_02 values(1,2,3) on duplicate key update c3 = 1;
|
||||
ERROR: INSERT ON DUPLICATE KEY UPDATE is not supported on column orientated table.
|
||||
---- VIEW
|
||||
insert into up_view values(1) on duplicate key update c3 = 1;
|
||||
ERROR: INSERT ON DUPLICATE KEY UPDATE is not supported on VIEW.
|
||||
-- matview
|
||||
refresh materialized view mat_view;
|
||||
insert into mat_view values(1) on duplicate key update c3 = 1;
|
||||
ERROR: cannot change materialized view "mat_view"
|
||||
-- index
|
||||
---- DEFERABLE index
|
||||
insert into up_neg_03 values(1,2,3) on duplicate key update c1 = 1;
|
||||
ERROR: INSERT ON DUPLICATE KEY UPDATE does not support deferrable unique constraints/exclusion constraints.
|
||||
insert into up_neg_03 values(1) on duplicate key update c1 = 1;
|
||||
ERROR: INSERT ON DUPLICATE KEY UPDATE does not support deferrable unique constraints/exclusion constraints.
|
||||
-- insert stmt
|
||||
----returning
|
||||
insert into up_neg_04 values(1,1,1) on duplicate key update c1 = 1 returning c1;
|
||||
ERROR: RETURNING clause is not yet supported whithin INSERT ON DUPLICATE KEY UPDATE statement.
|
||||
----with
|
||||
with sub as (select *from up_neg_04)
|
||||
insert into up_neg_04 select *from sub on duplicate key update c1 =1;
|
||||
ERROR: WITH clause is not yet supported whithin INSERT ON DUPLICATE KEY UPDATE statement.
|
||||
----with recur
|
||||
with RECURSIVE sub as (select *from up_neg_04)
|
||||
insert into up_neg_04 select *from sub on duplicate key update c1 =1;
|
||||
ERROR: WITH clause is not yet supported whithin INSERT ON DUPLICATE KEY UPDATE statement.
|
||||
with sub as (select *from up_neg_04)
|
||||
insert into up_neg_04 select *from sub on duplicate key update c1 =1 returning c1;
|
||||
ERROR: RETURNING clause is not yet supported whithin INSERT ON DUPLICATE KEY UPDATE statement.
|
||||
-- update stmt
|
||||
---- VALUES with expr
|
||||
insert into up_neg_05 values(1,1,1,1) on duplicate key update c3 = values(1+100);
|
||||
ERROR: syntax error at or near "1"
|
||||
LINE 1: ... values(1,1,1,1) on duplicate key update c3 = values(1+100);
|
||||
^
|
||||
insert into up_neg_05 values(1,1,1,1) on duplicate key update c3 = values(100);
|
||||
ERROR: syntax error at or near "100"
|
||||
LINE 1: ...05 values(1,1,1,1) on duplicate key update c3 = values(100);
|
||||
^
|
||||
insert into up_neg_05 values(1,1,1,1,1) on duplicate key update c1 = 1;
|
||||
---- update primary key
|
||||
insert into up_neg_05 values(1,1,1,1,1) on duplicate key update c5 = 1;
|
||||
ERROR: INSERT ON DUPLICATE KEY UPDATE don't allow update on primary key or unique key.
|
||||
---- update unique key
|
||||
insert into up_neg_05 values(1,1,1,1,1) on duplicate key update c4 = 1;
|
||||
ERROR: INSERT ON DUPLICATE KEY UPDATE don't allow update on primary key or unique key.
|
||||
insert into up_neg_05 values(1,1,1,1,1) on duplicate key update c2 = 1, c3=2;
|
||||
ERROR: INSERT ON DUPLICATE KEY UPDATE don't allow update on primary key or unique key.
|
||||
insert into up_neg_05 values(1,1,1,1,1) on duplicate key update c2 = 1;
|
||||
ERROR: INSERT ON DUPLICATE KEY UPDATE don't allow update on primary key or unique key.
|
||||
insert into up_neg_05 values(1,1,1,1,1) on duplicate key update c3 = 2;
|
||||
ERROR: INSERT ON DUPLICATE KEY UPDATE don't allow update on primary key or unique key.
|
||||
insert into up_neg_05 values(1,1,1,1,1) on duplicate key update c1 =1, c2 = 1, c3=2, c4=1,c5=1;
|
||||
ERROR: INSERT ON DUPLICATE KEY UPDATE don't allow update on primary key or unique key.
|
||||
---- where clause
|
||||
insert into up_neg_05 values(1,1,1,1,1) on duplicate key update c4 = 1 where c1=1;
|
||||
ERROR: syntax error at or near "where"
|
||||
LINE 1: ... values(1,1,1,1,1) on duplicate key update c4 = 1 where c1=1...
|
||||
^
|
||||
---- from clause
|
||||
insert into up_neg_05 values(1,1,1,1,1) on duplicate key update c4 = 1 from up_neg_04 where c1=1;
|
||||
ERROR: syntax error at or near "from"
|
||||
LINE 1: ... values(1,1,1,1,1) on duplicate key update c4 = 1 from up_ne...
|
||||
^
|
||||
---- sub query
|
||||
insert into up_neg_05 values(1,1,1,1,1) on duplicate key update (c2) = (select c2 from up_neg_05);
|
||||
ERROR: Update with subquery is not yet supported whithin INSERT ON DUPLICATE KEY UPDATE statement.
|
||||
---- update distribute key
|
||||
insert into up_neg_06 values(101, 1, 1) on duplicate key update c3=101;
|
||||
ERROR: INSERT ON DUPLICATE KEY UPDATE don't allow update on primary key or unique key.
|
||||
---- update partition key
|
||||
insert into up_neg_07 values(101, 1, 300) on duplicate key update c3=101;
|
||||
ERROR: INSERT ON DUPLICATE KEY UPDATE don't allow update on primary key or unique key.
|
||||
insert into up_neg_08 values(101, 1, 300) on duplicate key update c3=101;
|
||||
ERROR: INSERT ON DUPLICATE KEY UPDATE don't allow update on primary key or unique key.
|
||||
insert into up_neg_09 values(101, 1, 1) on duplicate key update c3=101;
|
||||
ERROR: INSERT ON DUPLICATE KEY UPDATE don't allow update on primary key or unique key.
|
||||
insert into up_neg_09 values(101, 1, 1) on duplicate key update c2=101;
|
||||
ERROR: INSERT ON DUPLICATE KEY UPDATE don't allow update on primary key or unique key.
|
||||
insert into up_neg_09 values(101, 1, 1) on duplicate key update c2 =1,c3=101;
|
||||
ERROR: INSERT ON DUPLICATE KEY UPDATE don't allow update on primary key or unique key.
|
||||
--update unique key mul type plans
|
||||
EXPLAIN (VERBOSE on, COSTS off) insert into up_neg_10 values(101, 1, 300) on duplicate key update c1=101;
|
||||
QUERY PLAN
|
||||
-------------------------------------------------
|
||||
Insert on upsert_test_etc.up_neg_10
|
||||
Conflict Resolution: UPDATE
|
||||
Conflict Arbiter Indexes: up_neg_10_c2_c3_key
|
||||
-> Result
|
||||
Output: 101, 1, 300
|
||||
(5 rows)
|
||||
|
||||
insert into up_neg_10 values(101, 1, 300) on duplicate key update c3=101;
|
||||
ERROR: INSERT ON DUPLICATE KEY UPDATE don't allow update on primary key or unique key.
|
||||
--trigger
|
||||
create table upsert_base
|
||||
(c1 int primary key,
|
||||
c2 varchar(100), --record the type
|
||||
cold varchar(1024),
|
||||
cnew varchar(1024) );
|
||||
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "upsert_base_pkey" for table "upsert_base"
|
||||
create table upsert_tri
|
||||
(c1 int,
|
||||
c2 varchar(100),
|
||||
c3 int,
|
||||
unique(c1,c3)
|
||||
);
|
||||
NOTICE: CREATE TABLE / UNIQUE will create implicit index "upsert_tri_c1_c3_key" for table "upsert_tri"
|
||||
--S1 after trigger
|
||||
CREATE OR REPLACE FUNCTION trig_after() RETURNS TRIGGER AS $emp_audit$
|
||||
BEGIN
|
||||
IF (TG_OP = 'INSERT') THEN
|
||||
insert into upsert_base(c2,cnew) values('after insert',new.c2);
|
||||
RETURN NEW;
|
||||
ELSIF (TG_OP = 'UPDATE') THEN
|
||||
insert into upsert_base(c2,cold,cnew) values('after update',old.c2,new.c2);
|
||||
RETURN NEW;
|
||||
END IF;
|
||||
RETURN NULL;
|
||||
END;
|
||||
$emp_audit$ LANGUAGE plpgsql;
|
||||
CREATE TRIGGER tri_after
|
||||
AFTER UPDATE OR INSERT ON upsert_tri
|
||||
FOR EACH ROW EXECUTE PROCEDURE trig_after();
|
||||
--S2 before trigger
|
||||
CREATE OR REPLACE FUNCTION trig_before() RETURNS TRIGGER AS $emp_audit$
|
||||
BEGIN
|
||||
IF (TG_OP = 'INSERT') THEN
|
||||
insert into upsert_base(c2,cnew) values('before insert',new.c2);
|
||||
RETURN NEW;
|
||||
ELSIF (TG_OP = 'UPDATE') THEN
|
||||
insert into upsert_base(c2,cold,cnew) values('before update',old.c2,new.c2);
|
||||
RETURN NEW;
|
||||
END IF;
|
||||
RETURN NULL;
|
||||
END;
|
||||
$emp_audit$ LANGUAGE plpgsql;
|
||||
CREATE TRIGGER tri_before
|
||||
BEFORE UPDATE OR INSERT ON upsert_tri
|
||||
FOR EACH ROW EXECUTE PROCEDURE trig_before();
|
||||
---- upsert-insert
|
||||
insert into upsert_tri(c1,c2,c3) values(1000,'abc',1) on duplicate key update nothing;
|
||||
ERROR: null value in column "c1" violates not-null constraint
|
||||
DETAIL: Failing row contains (null, before insert, null, abc).
|
||||
CONTEXT: SQL statement "insert into upsert_base(c2,cnew) values('before insert',new.c2)"
|
||||
PL/pgSQL function trig_before() line 4 at SQL statement
|
||||
insert into upsert_tri(c1,c2,c3) values(2000,'abc',1) on duplicate key update c2='bcd';
|
||||
ERROR: null value in column "c1" violates not-null constraint
|
||||
DETAIL: Failing row contains (null, before insert, null, abc).
|
||||
CONTEXT: SQL statement "insert into upsert_base(c2,cnew) values('before insert',new.c2)"
|
||||
PL/pgSQL function trig_before() line 4 at SQL statement
|
||||
---- upsert-nothing
|
||||
insert into upsert_tri(c1,c2,c3) values(1000,'abc',1) on duplicate key update nothing;
|
||||
ERROR: null value in column "c1" violates not-null constraint
|
||||
DETAIL: Failing row contains (null, before insert, null, abc).
|
||||
CONTEXT: SQL statement "insert into upsert_base(c2,cnew) values('before insert',new.c2)"
|
||||
PL/pgSQL function trig_before() line 4 at SQL statement
|
||||
---- upsert-update
|
||||
insert into upsert_tri(c1,c2,c3) values(2000,'abc',1) on duplicate key update c2='bcd';
|
||||
ERROR: null value in column "c1" violates not-null constraint
|
||||
DETAIL: Failing row contains (null, before insert, null, abc).
|
||||
CONTEXT: SQL statement "insert into upsert_base(c2,cnew) values('before insert',new.c2)"
|
||||
PL/pgSQL function trig_before() line 4 at SQL statement
|
||||
---- check results
|
||||
SELECT * from upsert_tri;
|
||||
c1 | c2 | c3
|
||||
----+----+----
|
||||
(0 rows)
|
||||
|
||||
SELECT * from upsert_base;
|
||||
c1 | c2 | cold | cnew
|
||||
----+----+------+------
|
||||
(0 rows)
|
||||
|
||||
-- foreign key
|
||||
insert into pkt values(1,1,1),(2,2,2),(3,3,3),(4,4,4),(5,5,5);
|
||||
insert into fkt values(1,1,1),(2,2,2),(3,3,3);
|
||||
insert into fkt values(1,1,1),(2,2,2),(3,3,3) on duplicate key update b=excluded.b+1, c=0;
|
||||
insert into fkt values(1,1,1),(2,2,2),(3,3,3) on duplicate key update b=excluded.b+3, c=-1;
|
||||
ERROR: insert or update on table "fkt" violates foreign key constraint "fkt_b_fkey"
|
||||
DETAIL: Key (b)=(6) is not present in table "pkt".
|
||||
|
|
@ -0,0 +1,173 @@
|
|||
\c upsert
|
||||
CREATE SCHEMA upsert_test_tmp;
|
||||
SET CURRENT_SCHEMA TO upsert_test_tmp;
|
||||
CREATE TYPE atype AS(a int, b int);
|
||||
CREATE TYPE btype AS(a int, b atype, c varchar[3]);
|
||||
CREATE TEMP TABLE t_hash_tmp_0 (c1 INT, c2 INT, c3 VARCHAR, c4 INT[3], c5 INT[5], c6 atype, c7 btype);
|
||||
CREATE TEMP TABLE t_hash_tmp_1 (c1 INT, c2 INT PRIMARY KEY, c3 VARCHAR, c4 INT[3], c5 INT[5], c6 atype, c7 btype);
|
||||
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "t_hash_tmp_1_pkey" for table "t_hash_tmp_1"
|
||||
CREATE TEMP TABLE t_rep_tmp_0 (c1 INT, c2 INT, c3 VARCHAR, c4 INT[3], c5 INT[5], c6 atype, c7 btype) ;
|
||||
CREATE TEMP TABLE t_rep_tmp_1 (c1 INT, c2 INT PRIMARY KEY, c3 VARCHAR, c4 INT[3], c5 INT[5], c6 atype, c7 btype) ;
|
||||
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "t_rep_tmp_1_pkey" for table "t_rep_tmp_1"
|
||||
-- enable_upsert_to_merge must be off, or upsert will be translated to merge.
|
||||
SET enable_upsert_to_merge TO OFF;
|
||||
SHOW enable_upsert_to_merge;
|
||||
enable_upsert_to_merge
|
||||
------------------------
|
||||
off
|
||||
(1 row)
|
||||
|
||||
-- hash table
|
||||
-- tmp table without primary key
|
||||
INSERT INTO t_hash_tmp_0 VALUES(1, 1, 'C3', '{1,2,3}', '{10,20,30,40,50}', ROW(10,20), ROW(100, ROW(10,20), '{100,200}')),
|
||||
(1, 2, 'C3', '{1,2,3}', '{10,20,30,40,50}', ROW(10,20), ROW(100, ROW(10,20), '{100,200}'))
|
||||
ON DUPLICATE KEY UPDATE NOTHING;
|
||||
INSERT INTO t_hash_tmp_0 VALUES(2, 3, 'C3', '{1,2,3}', '{10,20,30,40,50}', ROW(10,20), ROW(100, ROW(10,20), '{100,200}')),
|
||||
(2, 4, 'C3', '{1,2,3}', '{10,20,30,40,50}', ROW(10,20), ROW(100, ROW(10,20), '{100,200}'))
|
||||
ON DUPLICATE KEY UPDATE c2 = 100;
|
||||
-- tmp table with primary key
|
||||
-- multi insert
|
||||
INSERT INTO t_hash_tmp_1 VALUES(1, 1, 'C3', '{1,2,3}', '{10,20,30,40,50}', ROW(10,20), ROW(100, ROW(10,20), '{100,200}')),
|
||||
(1, 2, 'C3', '{1,2,3}', '{10,20,30,40,50}', ROW(10,20), ROW(100, ROW(10,20), '{100,200}'))
|
||||
ON DUPLICATE KEY UPDATE NOTHING;
|
||||
INSERT INTO t_hash_tmp_1 VALUES(2, 3, 'C3', '{1,2,3}', '{10,20,30,40,50}', ROW(10,20), ROW(100, ROW(10,20), '{100,200}')),
|
||||
(2, 4, 'C3', '{1,2,3}', '{10,20,30,40,50}', ROW(10,20), ROW(100, ROW(10,20), '{100,200}'))
|
||||
ON DUPLICATE KEY UPDATE c1 = EXCLUDED.c1, c3 = EXCLUDED.c3, c4 = EXCLUDED.c4, c5 = EXCLUDED.c5, c6 = EXCLUDED.c6, c7 = EXCLUDED.c7;
|
||||
SELECT * FROM t_hash_tmp_1 ORDER BY c2;
|
||||
c1 | c2 | c3 | c4 | c5 | c6 | c7
|
||||
----+----+----+---------+------------------+---------+-----------------------------
|
||||
1 | 1 | C3 | {1,2,3} | {10,20,30,40,50} | (10,20) | (100,"(10,20)","{100,200}")
|
||||
1 | 2 | C3 | {1,2,3} | {10,20,30,40,50} | (10,20) | (100,"(10,20)","{100,200}")
|
||||
2 | 3 | C3 | {1,2,3} | {10,20,30,40,50} | (10,20) | (100,"(10,20)","{100,200}")
|
||||
2 | 4 | C3 | {1,2,3} | {10,20,30,40,50} | (10,20) | (100,"(10,20)","{100,200}")
|
||||
(4 rows)
|
||||
|
||||
INSERT INTO t_hash_tmp_1 VALUES(10, 1, 'C30', '{10,20,30}', '{100,200,300,400,500}', ROW(100,200), ROW(1000, ROW(100,200), '{1000,2000}')),
|
||||
(11, 2, 'C31', '{11,21,31}', '{101,201,301,401,501}', ROW(101,201), ROW(1001, ROW(101,201), '{1001,2001}'))
|
||||
ON DUPLICATE KEY UPDATE NOTHING;
|
||||
INSERT INTO t_hash_tmp_1 VALUES(20, 3, 'C30', '{10,20,30}', '{10,20,30,40,50}', ROW(100,200), ROW(1000, ROW(100,200), '{1000,2000}')),
|
||||
(21, 4, 'C31', '{11,21,31}', '{101,201,301,401,501}', ROW(101,201), ROW(1001, ROW(101,201), '{1001,2001}'))
|
||||
ON DUPLICATE KEY UPDATE c1 = EXCLUDED.c1, c3 = EXCLUDED.c3, c4 = EXCLUDED.c4, c5 = EXCLUDED.c5, c6 = EXCLUDED.c6, c7 = EXCLUDED.c7;
|
||||
SELECT * FROM t_hash_tmp_1 ORDER BY c2;
|
||||
c1 | c2 | c3 | c4 | c5 | c6 | c7
|
||||
----+----+-----+------------+-----------------------+-----------+----------------------------------
|
||||
1 | 1 | C3 | {1,2,3} | {10,20,30,40,50} | (10,20) | (100,"(10,20)","{100,200}")
|
||||
1 | 2 | C3 | {1,2,3} | {10,20,30,40,50} | (10,20) | (100,"(10,20)","{100,200}")
|
||||
20 | 3 | C30 | {10,20,30} | {10,20,30,40,50} | (100,200) | (1000,"(100,200)","{1000,2000}")
|
||||
21 | 4 | C31 | {11,21,31} | {101,201,301,401,501} | (101,201) | (1001,"(101,201)","{1001,2001}")
|
||||
(4 rows)
|
||||
|
||||
-- insert and update same tuple, and update twice for another same tuple
|
||||
INSERT INTO t_hash_tmp_1 VALUES(0, 5, 'C30', '{10,20,30}', '{10,20,30,40,50}', ROW(100,200), ROW(1000, ROW(100,200), '{1000,2000}')),
|
||||
(1, 5, 'C31', '{11,21,31}', '{101,201,301,401,501}', ROW(101,201), ROW(1001, ROW(101,201), '{1001,2001}')),
|
||||
(10, 1, 'C30', '{10,20,30}', '{100,200,300,400,500}', ROW(100,200), ROW(1000, ROW(100,200), '{1000,2000}')),
|
||||
(11, 1, 'C31', '{11,21,31}', '{101,201,301,401,501}', ROW(101,201), ROW(1001, ROW(101,201), '{1001,2001}'))
|
||||
ON DUPLICATE KEY UPDATE NOTHING;
|
||||
SELECT * FROM t_hash_tmp_1 ORDER BY c2;
|
||||
c1 | c2 | c3 | c4 | c5 | c6 | c7
|
||||
----+----+-----+------------+-----------------------+-----------+----------------------------------
|
||||
1 | 1 | C3 | {1,2,3} | {10,20,30,40,50} | (10,20) | (100,"(10,20)","{100,200}")
|
||||
1 | 2 | C3 | {1,2,3} | {10,20,30,40,50} | (10,20) | (100,"(10,20)","{100,200}")
|
||||
20 | 3 | C30 | {10,20,30} | {10,20,30,40,50} | (100,200) | (1000,"(100,200)","{1000,2000}")
|
||||
21 | 4 | C31 | {11,21,31} | {101,201,301,401,501} | (101,201) | (1001,"(101,201)","{1001,2001}")
|
||||
0 | 5 | C30 | {10,20,30} | {10,20,30,40,50} | (100,200) | (1000,"(100,200)","{1000,2000}")
|
||||
(5 rows)
|
||||
|
||||
INSERT INTO t_hash_tmp_1 VALUES(0, 5, 'C30', '{10,20,30}', '{10,20,30,40,50}', ROW(100,200), ROW(1000, ROW(100,200), '{1000,2000}')),
|
||||
(1, 5, 'C31', '{11,21,31}', '{101,201,301,401,501}', ROW(101,201), ROW(1001, ROW(101,201), '{1001,2001}')),
|
||||
(10, 1, 'C30', '{10,20,30}', '{100,200,300,400,500}', ROW(100,200), ROW(1000, ROW(100,200), '{1000,2000}')),
|
||||
(11, 1, 'C31', '{11,21,31}', '{101,201,301,401,501}', ROW(101,201), ROW(1001, ROW(101,201), '{1001,2001}'))
|
||||
ON DUPLICATE KEY UPDATE c1 = EXCLUDED.c1, c3 = EXCLUDED.c3, c4 = EXCLUDED.c4, c5 = EXCLUDED.c5, c6 = EXCLUDED.c6, c7 = EXCLUDED.c7;
|
||||
SELECT * FROM t_hash_tmp_1 ORDER BY c2;
|
||||
c1 | c2 | c3 | c4 | c5 | c6 | c7
|
||||
----+----+-----+------------+-----------------------+-----------+----------------------------------
|
||||
11 | 1 | C31 | {11,21,31} | {101,201,301,401,501} | (101,201) | (1001,"(101,201)","{1001,2001}")
|
||||
1 | 2 | C3 | {1,2,3} | {10,20,30,40,50} | (10,20) | (100,"(10,20)","{100,200}")
|
||||
20 | 3 | C30 | {10,20,30} | {10,20,30,40,50} | (100,200) | (1000,"(100,200)","{1000,2000}")
|
||||
21 | 4 | C31 | {11,21,31} | {101,201,301,401,501} | (101,201) | (1001,"(101,201)","{1001,2001}")
|
||||
1 | 5 | C31 | {11,21,31} | {101,201,301,401,501} | (101,201) | (1001,"(101,201)","{1001,2001}")
|
||||
(5 rows)
|
||||
|
||||
-- replication table
|
||||
-- tmp table without primary key
|
||||
INSERT INTO t_rep_tmp_0 VALUES(1, 1, 'C3', '{1,2,3}', '{10,20,30,40,50}', ROW(10,20), ROW(100, ROW(10,20), '{100,200}')),
|
||||
(1, 2, 'C3', '{1,2,3}', '{10,20,30,40,50}', ROW(10,20), ROW(100, ROW(10,20), '{100,200}'))
|
||||
ON DUPLICATE KEY UPDATE NOTHING;
|
||||
INSERT INTO t_rep_tmp_0 VALUES(2, 3, 'C3', '{1,2,3}', '{10,20,30,40,50}', ROW(10,20), ROW(100, ROW(10,20), '{100,200}')),
|
||||
(2, 4, 'C3', '{1,2,3}', '{10,20,30,40,50}', ROW(10,20), ROW(100, ROW(10,20), '{100,200}'))
|
||||
ON DUPLICATE KEY UPDATE c2 = 100;
|
||||
-- tmp table with primary key
|
||||
-- multi insert
|
||||
INSERT INTO t_rep_tmp_1 VALUES(1, 1, 'C3', '{1,2,3}', '{10,20,30,40,50}', ROW(10,20), ROW(100, ROW(10,20), '{100,200}')),
|
||||
(1, 2, 'C3', '{1,2,3}', '{10,20,30,40,50}', ROW(10,20), ROW(100, ROW(10,20), '{100,200}'))
|
||||
ON DUPLICATE KEY UPDATE NOTHING;
|
||||
INSERT INTO t_rep_tmp_1 VALUES(2, 3, 'C3', '{1,2,3}', '{10,20,30,40,50}', ROW(10,20), ROW(100, ROW(10,20), '{100,200}')),
|
||||
(2, 4, 'C3', '{1,2,3}', '{10,20,30,40,50}', ROW(10,20), ROW(100, ROW(10,20), '{100,200}'))
|
||||
ON DUPLICATE KEY UPDATE c1 = EXCLUDED.c1, c3 = EXCLUDED.c3, c4 = EXCLUDED.c4, c5 = EXCLUDED.c5, c6 = EXCLUDED.c6, c7 = EXCLUDED.c7;
|
||||
SELECT * FROM t_rep_tmp_1 ORDER BY c2;
|
||||
c1 | c2 | c3 | c4 | c5 | c6 | c7
|
||||
----+----+----+---------+------------------+---------+-----------------------------
|
||||
1 | 1 | C3 | {1,2,3} | {10,20,30,40,50} | (10,20) | (100,"(10,20)","{100,200}")
|
||||
1 | 2 | C3 | {1,2,3} | {10,20,30,40,50} | (10,20) | (100,"(10,20)","{100,200}")
|
||||
2 | 3 | C3 | {1,2,3} | {10,20,30,40,50} | (10,20) | (100,"(10,20)","{100,200}")
|
||||
2 | 4 | C3 | {1,2,3} | {10,20,30,40,50} | (10,20) | (100,"(10,20)","{100,200}")
|
||||
(4 rows)
|
||||
|
||||
INSERT INTO t_rep_tmp_1 VALUES(10, 1, 'C30', '{10,20,30}', '{100,200,300,400,500}', ROW(100,200), ROW(1000, ROW(100,200), '{1000,2000}')),
|
||||
(11, 2, 'C31', '{11,21,31}', '{101,201,301,401,501}', ROW(101,201), ROW(1001, ROW(101,201), '{1001,2001}'))
|
||||
ON DUPLICATE KEY UPDATE NOTHING;
|
||||
INSERT INTO t_rep_tmp_1 VALUES(20, 3, 'C30', '{10,20,30}', '{10,20,30,40,50}', ROW(100,200), ROW(1000, ROW(100,200), '{1000,2000}')),
|
||||
(21, 4, 'C31', '{11,21,31}', '{101,201,301,401,501}', ROW(101,201), ROW(1001, ROW(101,201), '{1001,2001}'))
|
||||
ON DUPLICATE KEY UPDATE c1 = EXCLUDED.c1, c3 = EXCLUDED.c3, c4 = EXCLUDED.c4, c5 = EXCLUDED.c5, c6 = EXCLUDED.c6, c7 = EXCLUDED.c7;
|
||||
SELECT * FROM t_rep_tmp_1 ORDER BY c2;
|
||||
c1 | c2 | c3 | c4 | c5 | c6 | c7
|
||||
----+----+-----+------------+-----------------------+-----------+----------------------------------
|
||||
1 | 1 | C3 | {1,2,3} | {10,20,30,40,50} | (10,20) | (100,"(10,20)","{100,200}")
|
||||
1 | 2 | C3 | {1,2,3} | {10,20,30,40,50} | (10,20) | (100,"(10,20)","{100,200}")
|
||||
20 | 3 | C30 | {10,20,30} | {10,20,30,40,50} | (100,200) | (1000,"(100,200)","{1000,2000}")
|
||||
21 | 4 | C31 | {11,21,31} | {101,201,301,401,501} | (101,201) | (1001,"(101,201)","{1001,2001}")
|
||||
(4 rows)
|
||||
|
||||
-- insert and update same tuple, and update twice for another same tuple
|
||||
INSERT INTO t_rep_tmp_1 VALUES(0, 5, 'C30', '{10,20,30}', '{10,20,30,40,50}', ROW(100,200), ROW(1000, ROW(100,200), '{1000,2000}')),
|
||||
(1, 5, 'C31', '{11,21,31}', '{101,201,301,401,501}', ROW(101,201), ROW(1001, ROW(101,201), '{1001,2001}')),
|
||||
(10, 1, 'C30', '{10,20,30}', '{100,200,300,400,500}', ROW(100,200), ROW(1000, ROW(100,200), '{1000,2000}')),
|
||||
(11, 1, 'C31', '{11,21,31}', '{101,201,301,401,501}', ROW(101,201), ROW(1001, ROW(101,201), '{1001,2001}'))
|
||||
ON DUPLICATE KEY UPDATE NOTHING;
|
||||
SELECT * FROM t_rep_tmp_1 ORDER BY c2;
|
||||
c1 | c2 | c3 | c4 | c5 | c6 | c7
|
||||
----+----+-----+------------+-----------------------+-----------+----------------------------------
|
||||
1 | 1 | C3 | {1,2,3} | {10,20,30,40,50} | (10,20) | (100,"(10,20)","{100,200}")
|
||||
1 | 2 | C3 | {1,2,3} | {10,20,30,40,50} | (10,20) | (100,"(10,20)","{100,200}")
|
||||
20 | 3 | C30 | {10,20,30} | {10,20,30,40,50} | (100,200) | (1000,"(100,200)","{1000,2000}")
|
||||
21 | 4 | C31 | {11,21,31} | {101,201,301,401,501} | (101,201) | (1001,"(101,201)","{1001,2001}")
|
||||
0 | 5 | C30 | {10,20,30} | {10,20,30,40,50} | (100,200) | (1000,"(100,200)","{1000,2000}")
|
||||
(5 rows)
|
||||
|
||||
INSERT INTO t_rep_tmp_1 VALUES(0, 5, 'C30', '{10,20,30}', '{10,20,30,40,50}', ROW(100,200), ROW(1000, ROW(100,200), '{1000,2000}')),
|
||||
(1, 5, 'C31', '{11,21,31}', '{101,201,301,401,501}', ROW(101,201), ROW(1001, ROW(101,201), '{1001,2001}')),
|
||||
(10, 1, 'C30', '{10,20,30}', '{100,200,300,400,500}', ROW(100,200), ROW(1000, ROW(100,200), '{1000,2000}')),
|
||||
(11, 1, 'C31', '{11,21,31}', '{101,201,301,401,501}', ROW(101,201), ROW(1001, ROW(101,201), '{1001,2001}'))
|
||||
ON DUPLICATE KEY UPDATE c1 = EXCLUDED.c1, c3 = EXCLUDED.c3, c4 = EXCLUDED.c4, c5 = EXCLUDED.c5, c6 = EXCLUDED.c6, c7 = EXCLUDED.c7;
|
||||
SELECT * FROM t_rep_tmp_1 ORDER BY c2;
|
||||
c1 | c2 | c3 | c4 | c5 | c6 | c7
|
||||
----+----+-----+------------+-----------------------+-----------+----------------------------------
|
||||
11 | 1 | C31 | {11,21,31} | {101,201,301,401,501} | (101,201) | (1001,"(101,201)","{1001,2001}")
|
||||
1 | 2 | C3 | {1,2,3} | {10,20,30,40,50} | (10,20) | (100,"(10,20)","{100,200}")
|
||||
20 | 3 | C30 | {10,20,30} | {10,20,30,40,50} | (100,200) | (1000,"(100,200)","{1000,2000}")
|
||||
21 | 4 | C31 | {11,21,31} | {101,201,301,401,501} | (101,201) | (1001,"(101,201)","{1001,2001}")
|
||||
1 | 5 | C31 | {11,21,31} | {101,201,301,401,501} | (101,201) | (1001,"(101,201)","{1001,2001}")
|
||||
(5 rows)
|
||||
|
||||
DROP SCHEMA upsert_test_tmp CASCADE;
|
||||
NOTICE: drop cascades to 10 other objects
|
||||
DETAIL: drop cascades to type atype
|
||||
drop cascades to table t_hash_tmp_0 column c6
|
||||
drop cascades to table t_hash_tmp_1 column c6
|
||||
drop cascades to table t_rep_tmp_0 column c6
|
||||
drop cascades to table t_rep_tmp_1 column c6
|
||||
drop cascades to type btype
|
||||
drop cascades to table t_hash_tmp_0 column c7
|
||||
drop cascades to table t_hash_tmp_1 column c7
|
||||
drop cascades to table t_rep_tmp_0 column c7
|
||||
drop cascades to table t_rep_tmp_1 column c7
|
||||
|
|
@ -0,0 +1,148 @@
|
|||
\c upsert
|
||||
SET CURRENT_SCHEMA TO upsert_test;
|
||||
-- enable_upsert_to_merge must be off, or upsert will be translated to merge.
|
||||
SET enable_upsert_to_merge TO OFF;
|
||||
SHOW enable_upsert_to_merge;
|
||||
enable_upsert_to_merge
|
||||
------------------------
|
||||
off
|
||||
(1 row)
|
||||
|
||||
CREATE FUNCTION upsert_before_func()
|
||||
RETURNS TRIGGER language plpgsql AS
|
||||
$$
|
||||
BEGIN
|
||||
IF (TG_OP = 'UPDATE') THEN
|
||||
RAISE warning 'before update (old): %', old.*::TEXT;
|
||||
RAISE warning 'before update (new): %', new.*::TEXT;
|
||||
elsIF (TG_OP = 'INSERT') THEN
|
||||
RAISE warning 'before insert (new): %', new.*::TEXT;
|
||||
IF NEW.key % 2 = 0 THEN
|
||||
NEW.color := NEW.color || ' trig modified';
|
||||
RAISE warning 'before insert (new, modified): %', new.*::TEXT;
|
||||
END IF;
|
||||
END IF;
|
||||
RETURN new;
|
||||
END;
|
||||
$$;
|
||||
CREATE TRIGGER upsert_before_trig BEFORE INSERT OR UPDATE ON t_trigger
|
||||
FOR EACH ROW EXECUTE procedure upsert_before_func();
|
||||
CREATE FUNCTION upsert_after_func()
|
||||
RETURNS TRIGGER language plpgsql AS
|
||||
$$
|
||||
BEGIN
|
||||
IF (TG_OP = 'UPDATE') THEN
|
||||
RAISE warning 'after update (old): %', old.*::TEXT;
|
||||
RAISE warning 'after update (new): %', new.*::TEXT;
|
||||
elsIF (TG_OP = 'INSERT') THEN
|
||||
RAISE warning 'after insert (new): %', new.*::TEXT;
|
||||
END IF;
|
||||
RETURN null;
|
||||
END;
|
||||
$$;
|
||||
CREATE TRIGGER upsert_after_trig AFTER INSERT OR UPDATE ON t_trigger
|
||||
FOR EACH ROW EXECUTE procedure upsert_after_func();
|
||||
INSERT INTO t_trigger values(1, 'black') ON DUPLICATE KEY UPDATE color = 'updated ' || t_trigger.color;
|
||||
WARNING: before insert (new): (1,black)
|
||||
WARNING: after insert (new): (1,black)
|
||||
INSERT INTO t_trigger values(2, 'red') ON DUPLICATE KEY UPDATE color = 'updated ' || t_trigger.color;
|
||||
WARNING: before insert (new): (2,red)
|
||||
WARNING: before insert (new, modified): (2,"red trig modified")
|
||||
WARNING: after insert (new): (2,"red trig modified")
|
||||
INSERT INTO t_trigger values(3, 'orange') ON DUPLICATE KEY UPDATE color = 'updated ' || t_trigger.color;
|
||||
WARNING: before insert (new): (3,orange)
|
||||
WARNING: after insert (new): (3,orange)
|
||||
INSERT INTO t_trigger values(4, 'green') ON DUPLICATE KEY UPDATE color = 'updated ' || t_trigger.color;
|
||||
WARNING: before insert (new): (4,green)
|
||||
WARNING: before insert (new, modified): (4,"green trig modified")
|
||||
WARNING: after insert (new): (4,"green trig modified")
|
||||
INSERT INTO t_trigger values(5, 'purple') ON DUPLICATE KEY UPDATE color = 'updated ' || t_trigger.color;
|
||||
WARNING: before insert (new): (5,purple)
|
||||
WARNING: after insert (new): (5,purple)
|
||||
INSERT INTO t_trigger values(6, 'white') ON DUPLICATE KEY UPDATE color = 'updated ' || t_trigger.color;
|
||||
WARNING: before insert (new): (6,white)
|
||||
WARNING: before insert (new, modified): (6,"white trig modified")
|
||||
WARNING: after insert (new): (6,"white trig modified")
|
||||
INSERT INTO t_trigger values(7, 'pink') ON DUPLICATE KEY UPDATE color = 'updated ' || t_trigger.color;
|
||||
WARNING: before insert (new): (7,pink)
|
||||
WARNING: after insert (new): (7,pink)
|
||||
INSERT INTO t_trigger values(8, 'yellow') ON DUPLICATE KEY UPDATE color = 'updated ' || t_trigger.color;
|
||||
WARNING: before insert (new): (8,yellow)
|
||||
WARNING: before insert (new, modified): (8,"yellow trig modified")
|
||||
WARNING: after insert (new): (8,"yellow trig modified")
|
||||
SELECT * FROM t_trigger ORDER BY key;
|
||||
key | color
|
||||
-----+----------------------
|
||||
1 | black
|
||||
2 | red trig modified
|
||||
3 | orange
|
||||
4 | green trig modified
|
||||
5 | purple
|
||||
6 | white trig modified
|
||||
7 | pink
|
||||
8 | yellow trig modified
|
||||
(8 rows)
|
||||
|
||||
INSERT INTO t_trigger values(2, 'black') ON DUPLICATE KEY UPDATE color = 'updated ' || t_trigger.color;
|
||||
WARNING: before insert (new): (2,black)
|
||||
WARNING: before insert (new, modified): (2,"black trig modified")
|
||||
WARNING: before update (old): (2,"red trig modified")
|
||||
WARNING: before update (new): (2,"updated red trig modified")
|
||||
WARNING: after update (old): (2,"red trig modified")
|
||||
WARNING: after update (new): (2,"updated red trig modified")
|
||||
INSERT INTO t_trigger values(3, 'red') ON DUPLICATE KEY UPDATE color = 'updated ' || t_trigger.color;
|
||||
WARNING: before insert (new): (3,red)
|
||||
WARNING: before update (old): (3,orange)
|
||||
WARNING: before update (new): (3,"updated orange")
|
||||
WARNING: after update (old): (3,orange)
|
||||
WARNING: after update (new): (3,"updated orange")
|
||||
INSERT INTO t_trigger values(4, 'orange') ON DUPLICATE KEY UPDATE color = 'updated ' || t_trigger.color;
|
||||
WARNING: before insert (new): (4,orange)
|
||||
WARNING: before insert (new, modified): (4,"orange trig modified")
|
||||
WARNING: before update (old): (4,"green trig modified")
|
||||
WARNING: before update (new): (4,"updated green trig modified")
|
||||
WARNING: after update (old): (4,"green trig modified")
|
||||
WARNING: after update (new): (4,"updated green trig modified")
|
||||
INSERT INTO t_trigger values(5, 'green') ON DUPLICATE KEY UPDATE color = 'updated ' || t_trigger.color;
|
||||
WARNING: before insert (new): (5,green)
|
||||
WARNING: before update (old): (5,purple)
|
||||
WARNING: before update (new): (5,"updated purple")
|
||||
WARNING: after update (old): (5,purple)
|
||||
WARNING: after update (new): (5,"updated purple")
|
||||
INSERT INTO t_trigger values(6, 'purple') ON DUPLICATE KEY UPDATE color = 'updated ' || t_trigger.color;
|
||||
WARNING: before insert (new): (6,purple)
|
||||
WARNING: before insert (new, modified): (6,"purple trig modified")
|
||||
WARNING: before update (old): (6,"white trig modified")
|
||||
WARNING: before update (new): (6,"updated white trig modified")
|
||||
WARNING: after update (old): (6,"white trig modified")
|
||||
WARNING: after update (new): (6,"updated white trig modified")
|
||||
INSERT INTO t_trigger values(7, 'white') ON DUPLICATE KEY UPDATE color = 'updated ' || t_trigger.color;
|
||||
WARNING: before insert (new): (7,white)
|
||||
WARNING: before update (old): (7,pink)
|
||||
WARNING: before update (new): (7,"updated pink")
|
||||
WARNING: after update (old): (7,pink)
|
||||
WARNING: after update (new): (7,"updated pink")
|
||||
INSERT INTO t_trigger values(8, 'pink') ON DUPLICATE KEY UPDATE color = 'updated ' || t_trigger.color;
|
||||
WARNING: before insert (new): (8,pink)
|
||||
WARNING: before insert (new, modified): (8,"pink trig modified")
|
||||
WARNING: before update (old): (8,"yellow trig modified")
|
||||
WARNING: before update (new): (8,"updated yellow trig modified")
|
||||
WARNING: after update (old): (8,"yellow trig modified")
|
||||
WARNING: after update (new): (8,"updated yellow trig modified")
|
||||
INSERT INTO t_trigger values(9, 'yellow') ON DUPLICATE KEY UPDATE color = 'updated ' || t_trigger.color;
|
||||
WARNING: before insert (new): (9,yellow)
|
||||
WARNING: after insert (new): (9,yellow)
|
||||
SELECT * FROM t_trigger ORDER BY key;
|
||||
key | color
|
||||
-----+------------------------------
|
||||
1 | black
|
||||
2 | updated red trig modified
|
||||
3 | updated orange
|
||||
4 | updated green trig modified
|
||||
5 | updated purple
|
||||
6 | updated white trig modified
|
||||
7 | updated pink
|
||||
8 | updated yellow trig modified
|
||||
9 | yellow
|
||||
(9 rows)
|
||||
|
||||
|
|
@ -0,0 +1,152 @@
|
|||
\c upsert
|
||||
SET CURRENT_SCHEMA TO upsert_test_unlog;
|
||||
-- enable_upsert_to_merge must be off, or upsert will be translated to merge.
|
||||
SET enable_upsert_to_merge TO OFF;
|
||||
SHOW enable_upsert_to_merge;
|
||||
enable_upsert_to_merge
|
||||
------------------------
|
||||
off
|
||||
(1 row)
|
||||
|
||||
-- hash table
|
||||
-- unlogged table without primary key
|
||||
INSERT INTO t_hash_unlog_0 VALUES(1, 1, 'C3', '{1,2,3}', '{10,20,30,40,50}', ROW(10,20), ROW(100, ROW(10,20), '{100,200}')),
|
||||
(1, 2, 'C3', '{1,2,3}', '{10,20,30,40,50}', ROW(10,20), ROW(100, ROW(10,20), '{100,200}'))
|
||||
ON DUPLICATE KEY UPDATE NOTHING;
|
||||
INSERT INTO t_hash_unlog_0 VALUES(2, 3, 'C3', '{1,2,3}', '{10,20,30,40,50}', ROW(10,20), ROW(100, ROW(10,20), '{100,200}')),
|
||||
(2, 4, 'C3', '{1,2,3}', '{10,20,30,40,50}', ROW(10,20), ROW(100, ROW(10,20), '{100,200}'))
|
||||
ON DUPLICATE KEY UPDATE c2 = 100;
|
||||
-- unlogged table with primary key
|
||||
-- multi insert
|
||||
INSERT INTO t_hash_unlog_1 VALUES(1, 1, 'C3', '{1,2,3}', '{10,20,30,40,50}', ROW(10,20), ROW(100, ROW(10,20), '{100,200}')),
|
||||
(1, 2, 'C3', '{1,2,3}', '{10,20,30,40,50}', ROW(10,20), ROW(100, ROW(10,20), '{100,200}'))
|
||||
ON DUPLICATE KEY UPDATE NOTHING;
|
||||
INSERT INTO t_hash_unlog_1 VALUES(2, 3, 'C3', '{1,2,3}', '{10,20,30,40,50}', ROW(10,20), ROW(100, ROW(10,20), '{100,200}')),
|
||||
(2, 4, 'C3', '{1,2,3}', '{10,20,30,40,50}', ROW(10,20), ROW(100, ROW(10,20), '{100,200}'))
|
||||
ON DUPLICATE KEY UPDATE c1 = EXCLUDED.c1, c3 = EXCLUDED.c3, c4 = EXCLUDED.c4, c5 = EXCLUDED.c5, c6 = EXCLUDED.c6, c7 = EXCLUDED.c7;
|
||||
SELECT * FROM t_hash_unlog_1 ORDER BY c2;
|
||||
c1 | c2 | c3 | c4 | c5 | c6 | c7
|
||||
----+----+----+---------+------------------+---------+-----------------------------
|
||||
1 | 1 | C3 | {1,2,3} | {10,20,30,40,50} | (10,20) | (100,"(10,20)","{100,200}")
|
||||
1 | 2 | C3 | {1,2,3} | {10,20,30,40,50} | (10,20) | (100,"(10,20)","{100,200}")
|
||||
2 | 3 | C3 | {1,2,3} | {10,20,30,40,50} | (10,20) | (100,"(10,20)","{100,200}")
|
||||
2 | 4 | C3 | {1,2,3} | {10,20,30,40,50} | (10,20) | (100,"(10,20)","{100,200}")
|
||||
(4 rows)
|
||||
|
||||
INSERT INTO t_hash_unlog_1 VALUES(10, 1, 'C30', '{10,20,30}', '{100,200,300,400,500}', ROW(100,200), ROW(1000, ROW(100,200), '{1000,2000}')),
|
||||
(11, 2, 'C31', '{11,21,31}', '{101,201,301,401,501}', ROW(101,201), ROW(1001, ROW(101,201), '{1001,2001}'))
|
||||
ON DUPLICATE KEY UPDATE NOTHING;
|
||||
INSERT INTO t_hash_unlog_1 VALUES(20, 3, 'C30', '{10,20,30}', '{10,20,30,40,50}', ROW(100,200), ROW(1000, ROW(100,200), '{1000,2000}')),
|
||||
(21, 4, 'C31', '{11,21,31}', '{101,201,301,401,501}', ROW(101,201), ROW(1001, ROW(101,201), '{1001,2001}'))
|
||||
ON DUPLICATE KEY UPDATE c1 = EXCLUDED.c1, c3 = EXCLUDED.c3, c4 = EXCLUDED.c4, c5 = EXCLUDED.c5, c6 = EXCLUDED.c6, c7 = EXCLUDED.c7;
|
||||
SELECT * FROM t_hash_unlog_1 ORDER BY c2;
|
||||
c1 | c2 | c3 | c4 | c5 | c6 | c7
|
||||
----+----+-----+------------+-----------------------+-----------+----------------------------------
|
||||
1 | 1 | C3 | {1,2,3} | {10,20,30,40,50} | (10,20) | (100,"(10,20)","{100,200}")
|
||||
1 | 2 | C3 | {1,2,3} | {10,20,30,40,50} | (10,20) | (100,"(10,20)","{100,200}")
|
||||
20 | 3 | C30 | {10,20,30} | {10,20,30,40,50} | (100,200) | (1000,"(100,200)","{1000,2000}")
|
||||
21 | 4 | C31 | {11,21,31} | {101,201,301,401,501} | (101,201) | (1001,"(101,201)","{1001,2001}")
|
||||
(4 rows)
|
||||
|
||||
-- insert and update same tuple, and update twice for another same tuple
|
||||
INSERT INTO t_hash_unlog_1 VALUES(0, 5, 'C30', '{10,20,30}', '{10,20,30,40,50}', ROW(100,200), ROW(1000, ROW(100,200), '{1000,2000}')),
|
||||
(1, 5, 'C31', '{11,21,31}', '{101,201,301,401,501}', ROW(101,201), ROW(1001, ROW(101,201), '{1001,2001}')),
|
||||
(10, 1, 'C30', '{10,20,30}', '{100,200,300,400,500}', ROW(100,200), ROW(1000, ROW(100,200), '{1000,2000}')),
|
||||
(11, 1, 'C31', '{11,21,31}', '{101,201,301,401,501}', ROW(101,201), ROW(1001, ROW(101,201), '{1001,2001}'))
|
||||
ON DUPLICATE KEY UPDATE NOTHING;
|
||||
SELECT * FROM t_hash_unlog_1 ORDER BY c2;
|
||||
c1 | c2 | c3 | c4 | c5 | c6 | c7
|
||||
----+----+-----+------------+-----------------------+-----------+----------------------------------
|
||||
1 | 1 | C3 | {1,2,3} | {10,20,30,40,50} | (10,20) | (100,"(10,20)","{100,200}")
|
||||
1 | 2 | C3 | {1,2,3} | {10,20,30,40,50} | (10,20) | (100,"(10,20)","{100,200}")
|
||||
20 | 3 | C30 | {10,20,30} | {10,20,30,40,50} | (100,200) | (1000,"(100,200)","{1000,2000}")
|
||||
21 | 4 | C31 | {11,21,31} | {101,201,301,401,501} | (101,201) | (1001,"(101,201)","{1001,2001}")
|
||||
0 | 5 | C30 | {10,20,30} | {10,20,30,40,50} | (100,200) | (1000,"(100,200)","{1000,2000}")
|
||||
(5 rows)
|
||||
|
||||
INSERT INTO t_hash_unlog_1 VALUES(0, 5, 'C30', '{10,20,30}', '{10,20,30,40,50}', ROW(100,200), ROW(1000, ROW(100,200), '{1000,2000}')),
|
||||
(1, 5, 'C31', '{11,21,31}', '{101,201,301,401,501}', ROW(101,201), ROW(1001, ROW(101,201), '{1001,2001}')),
|
||||
(10, 1, 'C30', '{10,20,30}', '{100,200,300,400,500}', ROW(100,200), ROW(1000, ROW(100,200), '{1000,2000}')),
|
||||
(11, 1, 'C31', '{11,21,31}', '{101,201,301,401,501}', ROW(101,201), ROW(1001, ROW(101,201), '{1001,2001}'))
|
||||
ON DUPLICATE KEY UPDATE c1 = EXCLUDED.c1, c3 = EXCLUDED.c3, c4 = EXCLUDED.c4, c5 = EXCLUDED.c5, c6 = EXCLUDED.c6, c7 = EXCLUDED.c7;
|
||||
SELECT * FROM t_hash_unlog_1 ORDER BY c2;
|
||||
c1 | c2 | c3 | c4 | c5 | c6 | c7
|
||||
----+----+-----+------------+-----------------------+-----------+----------------------------------
|
||||
11 | 1 | C31 | {11,21,31} | {101,201,301,401,501} | (101,201) | (1001,"(101,201)","{1001,2001}")
|
||||
1 | 2 | C3 | {1,2,3} | {10,20,30,40,50} | (10,20) | (100,"(10,20)","{100,200}")
|
||||
20 | 3 | C30 | {10,20,30} | {10,20,30,40,50} | (100,200) | (1000,"(100,200)","{1000,2000}")
|
||||
21 | 4 | C31 | {11,21,31} | {101,201,301,401,501} | (101,201) | (1001,"(101,201)","{1001,2001}")
|
||||
1 | 5 | C31 | {11,21,31} | {101,201,301,401,501} | (101,201) | (1001,"(101,201)","{1001,2001}")
|
||||
(5 rows)
|
||||
|
||||
-- replication table
|
||||
-- unlogged table without primary key
|
||||
INSERT INTO t_rep_unlog_0 VALUES(1, 1, 'C3', '{1,2,3}', '{10,20,30,40,50}', ROW(10,20), ROW(100, ROW(10,20), '{100,200}')),
|
||||
(1, 2, 'C3', '{1,2,3}', '{10,20,30,40,50}', ROW(10,20), ROW(100, ROW(10,20), '{100,200}'))
|
||||
ON DUPLICATE KEY UPDATE NOTHING;
|
||||
INSERT INTO t_rep_unlog_0 VALUES(2, 3, 'C3', '{1,2,3}', '{10,20,30,40,50}', ROW(10,20), ROW(100, ROW(10,20), '{100,200}')),
|
||||
(2, 4, 'C3', '{1,2,3}', '{10,20,30,40,50}', ROW(10,20), ROW(100, ROW(10,20), '{100,200}'))
|
||||
ON DUPLICATE KEY UPDATE c2 = 100;
|
||||
-- unlogged table with primary key
|
||||
-- multi insert
|
||||
INSERT INTO t_rep_unlog_1 VALUES(1, 1, 'C3', '{1,2,3}', '{10,20,30,40,50}', ROW(10,20), ROW(100, ROW(10,20), '{100,200}')),
|
||||
(1, 2, 'C3', '{1,2,3}', '{10,20,30,40,50}', ROW(10,20), ROW(100, ROW(10,20), '{100,200}'))
|
||||
ON DUPLICATE KEY UPDATE NOTHING;
|
||||
INSERT INTO t_rep_unlog_1 VALUES(2, 3, 'C3', '{1,2,3}', '{10,20,30,40,50}', ROW(10,20), ROW(100, ROW(10,20), '{100,200}')),
|
||||
(2, 4, 'C3', '{1,2,3}', '{10,20,30,40,50}', ROW(10,20), ROW(100, ROW(10,20), '{100,200}'))
|
||||
ON DUPLICATE KEY UPDATE c1 = EXCLUDED.c1, c3 = EXCLUDED.c3, c4 = EXCLUDED.c4, c5 = EXCLUDED.c5, c6 = EXCLUDED.c6, c7 = EXCLUDED.c7;
|
||||
SELECT * FROM t_rep_unlog_1 ORDER BY c2;
|
||||
c1 | c2 | c3 | c4 | c5 | c6 | c7
|
||||
----+----+----+---------+------------------+---------+-----------------------------
|
||||
1 | 1 | C3 | {1,2,3} | {10,20,30,40,50} | (10,20) | (100,"(10,20)","{100,200}")
|
||||
1 | 2 | C3 | {1,2,3} | {10,20,30,40,50} | (10,20) | (100,"(10,20)","{100,200}")
|
||||
2 | 3 | C3 | {1,2,3} | {10,20,30,40,50} | (10,20) | (100,"(10,20)","{100,200}")
|
||||
2 | 4 | C3 | {1,2,3} | {10,20,30,40,50} | (10,20) | (100,"(10,20)","{100,200}")
|
||||
(4 rows)
|
||||
|
||||
INSERT INTO t_rep_unlog_1 VALUES(10, 1, 'C30', '{10,20,30}', '{100,200,300,400,500}', ROW(100,200), ROW(1000, ROW(100,200), '{1000,2000}')),
|
||||
(11, 2, 'C31', '{11,21,31}', '{101,201,301,401,501}', ROW(101,201), ROW(1001, ROW(101,201), '{1001,2001}'))
|
||||
ON DUPLICATE KEY UPDATE NOTHING;
|
||||
INSERT INTO t_rep_unlog_1 VALUES(20, 3, 'C30', '{10,20,30}', '{10,20,30,40,50}', ROW(100,200), ROW(1000, ROW(100,200), '{1000,2000}')),
|
||||
(21, 4, 'C31', '{11,21,31}', '{101,201,301,401,501}', ROW(101,201), ROW(1001, ROW(101,201), '{1001,2001}'))
|
||||
ON DUPLICATE KEY UPDATE c1 = EXCLUDED.c1, c3 = EXCLUDED.c3, c4 = EXCLUDED.c4, c5 = EXCLUDED.c5, c6 = EXCLUDED.c6, c7 = EXCLUDED.c7;
|
||||
SELECT * FROM t_rep_unlog_1 ORDER BY c2;
|
||||
c1 | c2 | c3 | c4 | c5 | c6 | c7
|
||||
----+----+-----+------------+-----------------------+-----------+----------------------------------
|
||||
1 | 1 | C3 | {1,2,3} | {10,20,30,40,50} | (10,20) | (100,"(10,20)","{100,200}")
|
||||
1 | 2 | C3 | {1,2,3} | {10,20,30,40,50} | (10,20) | (100,"(10,20)","{100,200}")
|
||||
20 | 3 | C30 | {10,20,30} | {10,20,30,40,50} | (100,200) | (1000,"(100,200)","{1000,2000}")
|
||||
21 | 4 | C31 | {11,21,31} | {101,201,301,401,501} | (101,201) | (1001,"(101,201)","{1001,2001}")
|
||||
(4 rows)
|
||||
|
||||
-- insert and update same tuple, and update twice for another same tuple
|
||||
INSERT INTO t_rep_unlog_1 VALUES(0, 5, 'C30', '{10,20,30}', '{10,20,30,40,50}', ROW(100,200), ROW(1000, ROW(100,200), '{1000,2000}')),
|
||||
(1, 5, 'C31', '{11,21,31}', '{101,201,301,401,501}', ROW(101,201), ROW(1001, ROW(101,201), '{1001,2001}')),
|
||||
(10, 1, 'C30', '{10,20,30}', '{100,200,300,400,500}', ROW(100,200), ROW(1000, ROW(100,200), '{1000,2000}')),
|
||||
(11, 1, 'C31', '{11,21,31}', '{101,201,301,401,501}', ROW(101,201), ROW(1001, ROW(101,201), '{1001,2001}'))
|
||||
ON DUPLICATE KEY UPDATE NOTHING;
|
||||
SELECT * FROM t_rep_unlog_1 ORDER BY c2;
|
||||
c1 | c2 | c3 | c4 | c5 | c6 | c7
|
||||
----+----+-----+------------+-----------------------+-----------+----------------------------------
|
||||
1 | 1 | C3 | {1,2,3} | {10,20,30,40,50} | (10,20) | (100,"(10,20)","{100,200}")
|
||||
1 | 2 | C3 | {1,2,3} | {10,20,30,40,50} | (10,20) | (100,"(10,20)","{100,200}")
|
||||
20 | 3 | C30 | {10,20,30} | {10,20,30,40,50} | (100,200) | (1000,"(100,200)","{1000,2000}")
|
||||
21 | 4 | C31 | {11,21,31} | {101,201,301,401,501} | (101,201) | (1001,"(101,201)","{1001,2001}")
|
||||
0 | 5 | C30 | {10,20,30} | {10,20,30,40,50} | (100,200) | (1000,"(100,200)","{1000,2000}")
|
||||
(5 rows)
|
||||
|
||||
INSERT INTO t_rep_unlog_1 VALUES(0, 5, 'C30', '{10,20,30}', '{10,20,30,40,50}', ROW(100,200), ROW(1000, ROW(100,200), '{1000,2000}')),
|
||||
(1, 5, 'C31', '{11,21,31}', '{101,201,301,401,501}', ROW(101,201), ROW(1001, ROW(101,201), '{1001,2001}')),
|
||||
(10, 1, 'C30', '{10,20,30}', '{100,200,300,400,500}', ROW(100,200), ROW(1000, ROW(100,200), '{1000,2000}')),
|
||||
(11, 1, 'C31', '{11,21,31}', '{101,201,301,401,501}', ROW(101,201), ROW(1001, ROW(101,201), '{1001,2001}'))
|
||||
ON DUPLICATE KEY UPDATE c1 = EXCLUDED.c1, c3 = EXCLUDED.c3, c4 = EXCLUDED.c4, c5 = EXCLUDED.c5, c6 = EXCLUDED.c6, c7 = EXCLUDED.c7;
|
||||
SELECT * FROM t_rep_unlog_1 ORDER BY c2;
|
||||
c1 | c2 | c3 | c4 | c5 | c6 | c7
|
||||
----+----+-----+------------+-----------------------+-----------+----------------------------------
|
||||
11 | 1 | C31 | {11,21,31} | {101,201,301,401,501} | (101,201) | (1001,"(101,201)","{1001,2001}")
|
||||
1 | 2 | C3 | {1,2,3} | {10,20,30,40,50} | (10,20) | (100,"(10,20)","{100,200}")
|
||||
20 | 3 | C30 | {10,20,30} | {10,20,30,40,50} | (100,200) | (1000,"(100,200)","{1000,2000}")
|
||||
21 | 4 | C31 | {11,21,31} | {101,201,301,401,501} | (101,201) | (1001,"(101,201)","{1001,2001}")
|
||||
1 | 5 | C31 | {11,21,31} | {101,201,301,401,501} | (101,201) | (1001,"(101,201)","{1001,2001}")
|
||||
(5 rows)
|
||||
|
||||
|
|
@ -227,6 +227,7 @@ select name,vartype,unit,min_val,max_val from pg_settings where name <> 'qunit_c
|
|||
enable_tsdb | bool | | |
|
||||
enable_twophase_commit | bool | | |
|
||||
enable_upgrade_merge_lock_mode | bool | | |
|
||||
enable_upsert_to_merge | bool | | |
|
||||
enable_user_metric_persistent | bool | | |
|
||||
enable_valuepartition_pruning | bool | | |
|
||||
enable_vector_engine | bool | | |
|
||||
|
|
|
|||
|
|
@ -44,12 +44,18 @@ test: hw_smp
|
|||
|
||||
# test MERGE INTO
|
||||
|
||||
# test INSERT UPDATE
|
||||
# test INSERT UPDATE UPSERT
|
||||
test: insert_update_001 insert_update_002 insert_update_003 insert_update_008 insert_update_009 insert_update_010
|
||||
test: delete update namespace case select_having select_implicit
|
||||
test: hw_test_operate_user
|
||||
test: hw_createtbl_llt gsqlerr
|
||||
test: hw_sql_llt sqlLLT
|
||||
test: upsert_prepare
|
||||
test: upsert_001 upsert_002 upsert_003 upsert_008 upsert_009 upsert_010
|
||||
test: upsert_grammer_test_01 upsert_unlog_test upsert_tmp_test
|
||||
test: upsert_grammer_test_02 upsert_restriction upsert_composite
|
||||
test: upsert_trigger_test upsert_explain
|
||||
test: upsert_clean
|
||||
|
||||
# all pass
|
||||
# run tablespace by itself, and first, because it forces a checkpoint;
|
||||
|
|
|
|||
|
|
@ -17,3 +17,11 @@ test: delete update namespace case select_having select_implicit
|
|||
test: hw_test_operate_user
|
||||
test: hw_createtbl_llt gsqlerr
|
||||
test: hw_sql_llt sqlLLT
|
||||
|
||||
# test UPSERT
|
||||
test: upsert_prepare
|
||||
test: upsert_001 upsert_002 upsert_003 upsert_008 upsert_009 upsert_010
|
||||
test: upsert_grammer_test_01 upsert_unlog_test upsert_tmp_test
|
||||
test: upsert_grammer_test_02 upsert_restriction upsert_composite
|
||||
test: upsert_trigger_test upsert_explain
|
||||
test: upsert_clean
|
||||
|
|
|
|||
|
|
@ -2,6 +2,10 @@ DROP SCHEMA test_insert_update_001 CASCADE;
|
|||
CREATE SCHEMA test_insert_update_001;
|
||||
SET CURRENT_SCHEMA TO test_insert_update_001;
|
||||
|
||||
-- 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 description
|
||||
\h INSERT
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,10 @@ DROP SCHEMA test_insert_update_002 CASCADE;
|
|||
CREATE SCHEMA test_insert_update_002;
|
||||
SET CURRENT_SCHEMA TO test_insert_update_002;
|
||||
|
||||
-- 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 t1 with no index
|
||||
CREATE TABLE t1 (
|
||||
col1 INT,
|
||||
|
|
|
|||
|
|
@ -2,6 +2,10 @@ DROP SCHEMA test_insert_update_003 CASCADE;
|
|||
CREATE SCHEMA test_insert_update_003;
|
||||
SET CURRENT_SCHEMA TO test_insert_update_003;
|
||||
|
||||
-- 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,
|
||||
|
|
|
|||
|
|
@ -6,6 +6,10 @@
|
|||
CREATE SCHEMA test_insert_update_008;
|
||||
SET current_schema = test_insert_update_008;
|
||||
|
||||
-- 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;
|
||||
|
||||
CREATE TABLE products_base
|
||||
(
|
||||
product_id INTEGER DEFAULT 0,
|
||||
|
|
@ -66,9 +70,9 @@ EXPLAIN (VERBOSE on, COSTS off)
|
|||
INSERT INTO products_row
|
||||
SELECT product_id, product_name, category, total FROM newproducts_row
|
||||
ON DUPLICATE KEY UPDATE
|
||||
product_name = __unnamed_subquery_source__.product_name,
|
||||
category = __unnamed_subquery_source__.category,
|
||||
total = __unnamed_subquery_source__.total;
|
||||
product_name = excluded.product_name,
|
||||
category = excluded.category,
|
||||
total = excluded.total;
|
||||
|
||||
EXPLAIN (VERBOSE on, COSTS off)
|
||||
INSERT INTO products_row
|
||||
|
|
@ -79,18 +83,18 @@ INSERT INTO products_row
|
|||
FROM newproducts_row, products_row
|
||||
WHERE products_row.total + newproducts_row.total < 1000
|
||||
ON DUPLICATE KEY UPDATE
|
||||
product_name = __unnamed_subquery_source__.product_name,
|
||||
category = __unnamed_subquery_source__.category,
|
||||
total = __unnamed_subquery_source__.total;
|
||||
product_name = excluded.product_name,
|
||||
category = excluded.category,
|
||||
total = excluded.total;
|
||||
|
||||
EXPLAIN (VERBOSE on, COSTS off)
|
||||
INSERT INTO products_row
|
||||
SELECT product_id, product_name, category, total
|
||||
FROM newproducts_row WHERE product_id IS NOT NULL AND product_name IS NOT NULL
|
||||
ON DUPLICATE KEY UPDATE
|
||||
product_name = __unnamed_subquery_source__.product_name,
|
||||
category = __unnamed_subquery_source__.category,
|
||||
total = __unnamed_subquery_source__.total;
|
||||
product_name = excluded.product_name,
|
||||
category = excluded.category,
|
||||
total = excluded.total;
|
||||
|
||||
-- explain analyze
|
||||
BEGIN;
|
||||
|
|
@ -98,9 +102,9 @@ EXPLAIN (ANALYZE on, COSTS off, TIMING off)
|
|||
INSERT INTO products_row
|
||||
SELECT product_id, product_name, category, total FROM newproducts_row
|
||||
ON DUPLICATE KEY UPDATE
|
||||
product_name = __unnamed_subquery_source__.product_name,
|
||||
category = __unnamed_subquery_source__.category,
|
||||
total = __unnamed_subquery_source__.total;
|
||||
product_name = excluded.product_name,
|
||||
category = excluded.category,
|
||||
total = excluded.total;
|
||||
ROLLBACK;
|
||||
|
||||
-- explain performance
|
||||
|
|
@ -110,9 +114,9 @@ EXPLAIN PERFORMANCE
|
|||
INSERT INTO products_row
|
||||
SELECT product_id, product_name, category, total FROM newproducts_row
|
||||
ON DUPLICATE KEY UPDATE
|
||||
product_name = __unnamed_subquery_source__.product_name,
|
||||
category = __unnamed_subquery_source__.category,
|
||||
total = __unnamed_subquery_source__.total;
|
||||
product_name = excluded.product_name,
|
||||
category = excluded.category,
|
||||
total = excluded.total;
|
||||
ROLLBACK;
|
||||
\o
|
||||
|
||||
|
|
@ -122,9 +126,9 @@ EXPLAIN (ANALYZE on, COSTS off, TIMING off)
|
|||
INSERT INTO products_row
|
||||
SELECT product_id, product_name, category, total FROM newproducts_row
|
||||
ON DUPLICATE KEY UPDATE
|
||||
product_name = __unnamed_subquery_source__.product_name,
|
||||
category = __unnamed_subquery_source__.category,
|
||||
total = __unnamed_subquery_source__.total;
|
||||
product_name = excluded.product_name,
|
||||
category = excluded.category,
|
||||
total = excluded.total;
|
||||
ROLLBACK;
|
||||
|
||||
-- pretty mode performance
|
||||
|
|
@ -135,9 +139,9 @@ EXPLAIN (VERBOSE on, COSTS off)
|
|||
INSERT INTO products_row
|
||||
SELECT product_id, product_name, category, total FROM newproducts_row
|
||||
ON DUPLICATE KEY UPDATE
|
||||
product_name = __unnamed_subquery_source__.product_name,
|
||||
category = __unnamed_subquery_source__.category,
|
||||
total = __unnamed_subquery_source__.total;
|
||||
product_name = excluded.product_name,
|
||||
category = excluded.category,
|
||||
total = excluded.total;
|
||||
|
||||
-- explain analyze
|
||||
BEGIN;
|
||||
|
|
@ -145,9 +149,9 @@ EXPLAIN (ANALYZE on, COSTS off, TIMING off)
|
|||
INSERT INTO products_row
|
||||
SELECT product_id, product_name, category, total FROM newproducts_row
|
||||
ON DUPLICATE KEY UPDATE
|
||||
product_name = __unnamed_subquery_source__.product_name,
|
||||
category = __unnamed_subquery_source__.category,
|
||||
total = __unnamed_subquery_source__.total;
|
||||
product_name = excluded.product_name,
|
||||
category = excluded.category,
|
||||
total = excluded.total;
|
||||
ROLLBACK;
|
||||
|
||||
-- explain analyze
|
||||
|
|
@ -156,9 +160,9 @@ EXPLAIN (ANALYZE on, COSTS off, TIMING off)
|
|||
INSERT INTO products_row
|
||||
SELECT product_id, product_name, category, total FROM newproducts_row
|
||||
ON DUPLICATE KEY UPDATE
|
||||
product_name = __unnamed_subquery_source__.product_name,
|
||||
category = __unnamed_subquery_source__.category,
|
||||
total = __unnamed_subquery_source__.total;
|
||||
product_name = excluded.product_name,
|
||||
category = excluded.category,
|
||||
total = excluded.total;
|
||||
ROLLBACK;
|
||||
|
||||
-- explain performance
|
||||
|
|
@ -168,9 +172,9 @@ EXPLAIN PERFORMANCE
|
|||
INSERT INTO products_row
|
||||
SELECT product_id, product_name, category, total FROM newproducts_row
|
||||
ON DUPLICATE KEY UPDATE
|
||||
product_name = __unnamed_subquery_source__.product_name,
|
||||
category = __unnamed_subquery_source__.category,
|
||||
total = __unnamed_subquery_source__.total;
|
||||
product_name = excluded.product_name,
|
||||
category = excluded.category,
|
||||
total = excluded.total;
|
||||
ROLLBACK;
|
||||
|
||||
SET explain_perf_mode = run;
|
||||
|
|
@ -180,9 +184,9 @@ EXPLAIN PERFORMANCE
|
|||
INSERT INTO products_row
|
||||
SELECT product_id, product_name, category, total FROM newproducts_row
|
||||
ON DUPLICATE KEY UPDATE
|
||||
product_name = __unnamed_subquery_source__.product_name,
|
||||
category = __unnamed_subquery_source__.category,
|
||||
total = __unnamed_subquery_source__.total;
|
||||
product_name = excluded.product_name,
|
||||
category = excluded.category,
|
||||
total = excluded.total;
|
||||
ROLLBACK;
|
||||
|
||||
SET explain_perf_mode = summary;
|
||||
|
|
@ -192,9 +196,9 @@ EXPLAIN PERFORMANCE
|
|||
INSERT INTO products_row
|
||||
SELECT product_id, product_name, category, total FROM newproducts_row
|
||||
ON DUPLICATE KEY UPDATE
|
||||
product_name = __unnamed_subquery_source__.product_name,
|
||||
category = __unnamed_subquery_source__.category,
|
||||
total = __unnamed_subquery_source__.total;
|
||||
product_name = excluded.product_name,
|
||||
category = excluded.category,
|
||||
total = excluded.total;
|
||||
ROLLBACK;
|
||||
\o
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,11 @@ DROP SCHEMA test_insert_update_009 CASCADE;
|
|||
CREATE SCHEMA test_insert_update_009;
|
||||
SET CURRENT_SCHEMA TO test_insert_update_009;
|
||||
SET enable_light_proxy=off;
|
||||
|
||||
-- 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 t1 with no index
|
||||
CREATE TABLE t1 (
|
||||
col1 INT,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,11 @@
|
|||
DROP SCHEMA test_insert_update_010 CASCADE;
|
||||
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,
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
-- 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;
|
||||
|
||||
SELECT name, setting FROM pg_settings WHERE name LIKE 'enable%' ORDER BY name;
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,284 @@
|
|||
DROP SCHEMA test_upsert_001 CASCADE;
|
||||
CREATE SCHEMA test_upsert_001;
|
||||
SET CURRENT_SCHEMA TO test_upsert_001;
|
||||
|
||||
-- enable_upsert_to_merge must is off, or upsert will be translated to merge.
|
||||
SET enable_upsert_to_merge TO OFF;
|
||||
|
||||
-- test description
|
||||
\h INSERT
|
||||
|
||||
-- test permission
|
||||
--- test with no sequence column
|
||||
CREATE TABLE t00 (col1 INT DEFAULT 1 PRIMARY KEY, col2 INT);
|
||||
CREATE USER upsert_tester PASSWORD '123456@cc';
|
||||
GRANT ALL PRIVILEGES ON SCHEMA test_upsert_001 TO upsert_tester;
|
||||
|
||||
SET SESSION SESSION AUTHORIZATION upsert_tester PASSWORD '123456@cc';
|
||||
INSERT INTO test_upsert_001.t00 VALUES(1) ON DUPLICATE KEY UPDATE col2 = 5;
|
||||
RESET SESSION AUTHORIZATION;
|
||||
|
||||
---- error: only have INSERT permission
|
||||
GRANT INSERT ON test_upsert_001.t00 TO upsert_tester;
|
||||
SET SESSION SESSION AUTHORIZATION upsert_tester PASSWORD '123456@cc';
|
||||
INSERT INTO test_upsert_001.t00 VALUES(1) ON DUPLICATE KEY UPDATE col2 = 5;
|
||||
RESET SESSION AUTHORIZATION;
|
||||
|
||||
---- success: have INSERT UPDATE permission
|
||||
GRANT INSERT, UPDATE ON test_upsert_001.t00 TO upsert_tester;
|
||||
SET SESSION SESSION AUTHORIZATION upsert_tester PASSWORD '123456@cc';
|
||||
INSERT INTO test_upsert_001.t00 VALUES(1) ON DUPLICATE KEY UPDATE col2 = 5;
|
||||
RESET SESSION AUTHORIZATION;
|
||||
|
||||
--- have SELECT INSERT UPDATE permission
|
||||
GRANT SELECT, INSERT, UPDATE ON test_upsert_001.t00 TO upsert_tester;
|
||||
SET SESSION SESSION AUTHORIZATION upsert_tester PASSWORD '123456@cc';
|
||||
INSERT INTO test_upsert_001.t00 VALUES(1) ON DUPLICATE KEY UPDATE col2 = 5;
|
||||
INSERT INTO test_upsert_001.t00 VALUES(1) ON DUPLICATE KEY UPDATE col3 = 5;
|
||||
RESET SESSION AUTHORIZATION;
|
||||
|
||||
--- test with sequnce column
|
||||
CREATE TABLE t01 (col1 INT , col2 BIGSERIAL PRIMARY KEY, col3 INT) ;
|
||||
|
||||
---- error: don't have UPDATE permission on sequence table.
|
||||
GRANT SELECT, INSERT, UPDATE ON test_upsert_001.t01 TO upsert_tester;
|
||||
SET SESSION SESSION AUTHORIZATION upsert_tester PASSWORD '123456@cc';
|
||||
INSERT INTO test_upsert_001.t01 VALUES(1) ON DUPLICATE KEY UPDATE col3 = 5;
|
||||
RESET SESSION AUTHORIZATION;
|
||||
|
||||
---- have SELECT INSERT UPDATE permission on target relation, and UPDATE permission on sequence table.
|
||||
GRANT UPDATE ON test_upsert_001.t01_col2_seq TO upsert_tester;
|
||||
SET SESSION SESSION AUTHORIZATION upsert_tester PASSWORD '123456@cc';
|
||||
INSERT INTO test_upsert_001.t01 VALUES(1) ON DUPLICATE KEY UPDATE col3 = 5;
|
||||
INSERT INTO test_upsert_001.t01 VALUES(1) ON DUPLICATE KEY UPDATE col3 = 5;
|
||||
RESET SESSION AUTHORIZATION;
|
||||
|
||||
-- test ommit INSERT target column
|
||||
CREATE TABLE t02 (col1 INT DEFAULT 1 PRIMARY KEY, col2 INT, col3 INT);
|
||||
INSERT INTO t02 VALUES(1, 2, 3) ON DUPLICATE KEY UPDATE col2 = 20;
|
||||
SELECT * FROM t02 ORDER BY 1, 2;
|
||||
INSERT INTO t02 VALUES(1, 2, 3) ON DUPLICATE KEY UPDATE col2 = 20;
|
||||
SELECT * FROM t02 ORDER BY 1, 2;
|
||||
|
||||
ALTER TABLE t02 DROP COLUMN col2;
|
||||
ALTER TABLE t02 ADD COLUMN col4 INT;
|
||||
INSERT INTO t02 VALUES(1, 2, 3) ON DUPLICATE KEY UPDATE col4 = 40;
|
||||
SELECT * FROM t02 ORDER BY 1, 2;
|
||||
INSERT INTO t02 VALUES(2, 3, 4) ON DUPLICATE KEY UPDATE col4 = 40;
|
||||
SELECT * FROM t02 ORDER BY 1, 2;
|
||||
INSERT INTO t02 VALUES(2, 3, 4) ON DUPLICATE KEY UPDATE col4 = 40;
|
||||
SELECT * FROM t02 ORDER BY 1, 2;
|
||||
|
||||
-- test restriction
|
||||
--- test replication table
|
||||
CREATE TABLE t03 (col1 int PRIMARY KEY, col2 INT, col3 smallserial) ;
|
||||
--- error: not allowed volatile function as default value
|
||||
INSERT INTO t03(col2) VALUES(1) ON DUPLICATE KEY UPDATE col2 = 100;
|
||||
|
||||
ALTER TABLE t03 DROP COLUMN col3;
|
||||
--- error: primary key are not allowed to update
|
||||
INSERT INTO t03 VALUES(1) ON DUPLICATE KEY UPDATE col1 = 1;
|
||||
--- error: clause other than VALUSES are not allowed to use
|
||||
INSERT INTO t03 SELECT * FROM t03 ON DUPLICATE KEY UPDATE col2 = 1;
|
||||
--- success: expression index are supported
|
||||
CREATE UNIQUE INDEX u_expr_index ON t03 USING btree (abs(col1));
|
||||
INSERT INTO t03 VALUES(-10, 10) ON DUPLICATE KEY UPDATE col2 = 20;
|
||||
DROP INDEX u_expr_index;
|
||||
|
||||
-- test with stream operator on
|
||||
INSERT INTO t03 VALUES(1) ON DUPLICATE KEY UPDATE col2 = 100;
|
||||
SELECT * FROM t03;
|
||||
|
||||
INSERT INTO t03 VALUES(1) ON DUPLICATE KEY UPDATE col2 = 100;
|
||||
SELECT * FROM t03;
|
||||
SELECT * FROM t03;
|
||||
|
||||
--- test PBE
|
||||
PREPARE p1 AS INSERT INTO t03 VALUES($1, $2) ON DUPLICATE KEY UPDATE col2 = $1*100;
|
||||
EXECUTE p1(5, 50);
|
||||
SELECT * FROM t03 WHERE col1 = 5;
|
||||
EXECUTE p1(5, 50);
|
||||
SELECT * FROM t03 WHERE col1 = 5;
|
||||
DELETE t03 WHERE col1 = 5;
|
||||
|
||||
---- test with primary key
|
||||
INSERT INTO t03 VALUES(2) ON DUPLICATE KEY UPDATE col2 = 200;
|
||||
SELECT * FROM t03;
|
||||
|
||||
INSERT INTO t03 VALUES(2) ON DUPLICATE KEY UPDATE col2 = 200;
|
||||
SELECT * FROM t03;
|
||||
SELECT * FROM t03;
|
||||
|
||||
---- test with unique key without NOT NULL constraint
|
||||
ALTER TABLE t03 DROP CONSTRAINT t03_pkey;
|
||||
ALTER TABLE t03 ADD COLUMN col3 INT;
|
||||
CREATE UNIQUE INDEX ON t03 (col1, col3);
|
||||
---- unique constraints might contain NULL, depends on the plan
|
||||
----- for cn light and fqs, it can be done
|
||||
INSERT INTO t03 VALUES(3) ON DUPLICATE KEY UPDATE col2 = 300;
|
||||
----- for stream or pgxc it can not be done
|
||||
INSERT INTO t03 VALUES(3) ON DUPLICATE KEY UPDATE col2 = 300;
|
||||
|
||||
---- test with unique key with NOT NULL constraint, should success
|
||||
CREATE UNIQUE INDEX ON t03 (col1);
|
||||
INSERT INTO t03 VALUES(3) ON DUPLICATE KEY UPDATE col2 = 300;
|
||||
SELECT * FROM t03;
|
||||
|
||||
INSERT INTO t03 VALUES(3) ON DUPLICATE KEY UPDATE col2 = 300;
|
||||
SELECT * FROM t03;
|
||||
SELECT * FROM t03;
|
||||
|
||||
---- test PBE
|
||||
PREPARE p2 AS INSERT INTO t03 VALUES($1, $2) ON DUPLICATE KEY UPDATE col2 = $1*100;
|
||||
EXECUTE p2(5, 50);
|
||||
SELECT * FROM t03 WHERE col1 = 5;
|
||||
EXECUTE p2(5, 50);
|
||||
SELECT * FROM t03 WHERE col1 = 5;
|
||||
|
||||
--- error: test with clause
|
||||
WITH tmp(col1, col2) AS (SELECT * FROM t01)
|
||||
INSERT INTO t01 SELECT * FROM tmp ON DUPLICATE KEY UPDATE col1 = 1;
|
||||
|
||||
WITH RECURSIVE rq AS
|
||||
(
|
||||
SELECT col1, col2 FROM t00 WHERE col1 = 1
|
||||
UNION ALL
|
||||
SELECT origin.col1, rq.col2
|
||||
FROM rq JOIN t00 AS origin ON origin.col1 = rq.col1
|
||||
)
|
||||
INSERT INTO t03 SELECT * FROM rq ON DUPLICATE KEY UPDATE col1 = rq.col1;
|
||||
|
||||
--- error: test returning clause
|
||||
INSERT INTO t01 VALUES (1) ON DUPLICATE KEY UPDATE col1 = 1 RETURNING NOT(1::bool);
|
||||
|
||||
--- error: distribute key are not allowed to UPDATE
|
||||
CREATE TABLE t04 (col1 INT, col2 INT) ;
|
||||
INSERT INTO t04 VALUES (1) ON DUPLICATE KEY UPDATE col1 = 5;
|
||||
|
||||
--- error: unique index referenced column are not allowed to UPDATE
|
||||
CREATE UNIQUE INDEX t04_u_index ON t04(col1, col2);
|
||||
INSERT INTO t04 VALUES (1) ON DUPLICATE KEY UPDATE col2 = 5;
|
||||
DROP INDEX t04_u_index;
|
||||
|
||||
--- error: primary key referenced column are not allowed to UPDATE
|
||||
ALTER TABLE t04 ADD PRIMARY KEY (col1, col2);
|
||||
INSERT INTO t04 VALUES (1) ON DUPLICATE KEY UPDATE col2 = 5;
|
||||
|
||||
--- error: invalid column
|
||||
INSERT INTO t04 (col2, col3) VALUES (2, 3) ON DUPLICATE KEY UPDATE col2 = 5;
|
||||
|
||||
--- error: duplicate column
|
||||
INSERT INTO t04 (col2, col2) VALUES (2, 3) ON DUPLICATE KEY UPDATE col2 = 5;
|
||||
|
||||
-- error: target column more than insert target
|
||||
INSERT INTO t04 (col1, col2) VALUES (2, 3, 4) ON DUPLICATE KEY UPDATE col2 = 5;
|
||||
INSERT INTO t04 (col1, col2) VALUES (1) ON DUPLICATE KEY UPDATE col2 = 5;
|
||||
INSERT INTO t04 (col1, col2) SELECT col1 FROM t04 ON DUPLICATE KEY UPDATE col2 = 5;
|
||||
INSERT INTO t04 (col1, col2) SELECT *, col1 FROM t04 ON DUPLICATE KEY UPDATE col2 = 5;
|
||||
INSERT INTO t04 VALUES (2, 3, 4) ON DUPLICATE KEY UPDATE col2 = 5;
|
||||
INSERT INTO t04 VALUES (1) ON DUPLICATE KEY UPDATE col2 = 5;
|
||||
INSERT INTO t04 SELECT col1 FROM t04 ON DUPLICATE KEY UPDATE col2 = 5;
|
||||
INSERT INTO t04 SELECT *, col1 FROM t04 ON DUPLICATE KEY UPDATE col2 = 5;
|
||||
|
||||
-- test DEFAULT VALUES
|
||||
TRUNCATE t00;
|
||||
TRUNCATE t01;
|
||||
|
||||
--- without sequence
|
||||
----should insert
|
||||
INSERT INTO t00 DEFAULT VALUES ON DUPLICATE KEY UPDATE col2 = col1;
|
||||
SELECT * FROM t00 ORDER BY 1, 2;
|
||||
---- should update
|
||||
INSERT INTO t00 DEFAULT VALUES ON DUPLICATE KEY UPDATE col2 = col1;
|
||||
SELECT * FROM t00 ORDER BY 1, 2;
|
||||
|
||||
--- test drop column
|
||||
TRUNCATE t00;
|
||||
ALTER TABLE t00 DROP COLUMN col2;
|
||||
ALTER TABLE t00 ADD COLUMN col3 INT DEFAULT 100;
|
||||
----should insert
|
||||
INSERT INTO t00 DEFAULT VALUES ON DUPLICATE KEY UPDATE col3 = col1;
|
||||
SELECT * FROM t00 ORDER BY 1, 2;
|
||||
---- should update
|
||||
INSERT INTO t00 DEFAULT VALUES ON DUPLICATE KEY UPDATE col3 = col1;
|
||||
SELECT * FROM t00 ORDER BY 1, 2;
|
||||
|
||||
--- with sequence
|
||||
----should insert
|
||||
INSERT INTO t01 DEFAULT VALUES ON DUPLICATE KEY UPDATE col1 = col2;
|
||||
INSERT INTO t01 (col2) SELECT col2 + 1 FROM t01 LIMIT 1;
|
||||
SELECT * FROM t01 ORDER BY 1, 2, 3;
|
||||
|
||||
---- should update
|
||||
INSERT INTO t01 DEFAULT VALUES ON DUPLICATE KEY UPDATE col1 = col2;
|
||||
SELECT * FROM t01 ORDER BY 1, 2, 3;
|
||||
|
||||
-- test VALUES(DEFAULT)
|
||||
CREATE TABLE t05 (col1 INT , col2 INT DEFAULT 1 PRIMARY KEY, col3 INT DEFAULT 100) ;
|
||||
--- should insert
|
||||
INSERT INTO t05 VALUES(DEFAULT) ON DUPLICATE KEY UPDATE col3 = 1000;
|
||||
SELECT * FROM t05 ORDER BY 1, 2, 3;
|
||||
|
||||
--- should update
|
||||
INSERT INTO t05 VALUES(DEFAULT) ON DUPLICATE KEY UPDATE col3 = 1000;
|
||||
SELECT * FROM t05 ORDER BY 1, 2, 3;
|
||||
|
||||
-- test UPDATE DEFAULT
|
||||
INSERT INTO t05 (col1, col2, col3) VALUES (2, 2, 2) ON DUPLICATE KEY UPDATE col3 = DEFAULT;
|
||||
SELECT * FROM t05 ORDER BY 1, 2, 3;
|
||||
INSERT INTO t05 (col1, col2, col3) VALUES (2, 2, 2) ON DUPLICATE KEY UPDATE col3 = DEFAULT;
|
||||
SELECT * FROM t05 ORDER BY 1, 2, 3;
|
||||
|
||||
-- test VALUES (DEFAULT, ...)
|
||||
TRUNCATE t05;
|
||||
--- should insert
|
||||
INSERT INTO t05 VALUES(DEFAULT, DEFAULT, 200), (DEFAULT, 200, DEFAULT)
|
||||
ON DUPLICATE KEY UPDATE col3 = DEFAULT, col1 = col3;
|
||||
SELECT * FROM t05 ORDER BY 1, 2, 3;
|
||||
|
||||
--- should update
|
||||
INSERT INTO t05 VALUES(DEFAULT, DEFAULT, 200), (DEFAULT, 200, DEFAULT)
|
||||
ON DUPLICATE KEY UPDATE col3 = DEFAULT, col1 = col3;
|
||||
SELECT * FROM t05 ORDER BY 1, 2, 3;
|
||||
|
||||
--- test drop coulmn
|
||||
BEGIN;
|
||||
ALTER TABLE t05 ADD COLUMN col4 INT;
|
||||
ALTER TABLE t05 ADD COLUMN col5 INT DEFAULT 500;
|
||||
ALTER TABLE t05 DROP COLUMN col3;
|
||||
TRUNCATE t05;
|
||||
INSERT INTO t05 VALUES(DEFAULT, DEFAULT, DEFAULT, 600) ON DUPLICATE KEY UPDATE col5 = DEFAULT;
|
||||
SELECT * FROM t05 ORDER BY 1, 2, 3;
|
||||
INSERT INTO t05 VALUES(DEFAULT, DEFAULT, DEFAULT, 600) ON DUPLICATE KEY UPDATE col5 = DEFAULT;
|
||||
SELECT * FROM t05 ORDER BY 1, 2, 3;
|
||||
ROLLBACK;
|
||||
|
||||
-- test schema
|
||||
SET current_schema = public;
|
||||
TRUNCATE test_upsert_001.t05;
|
||||
--- should insert
|
||||
INSERT INTO test_upsert_001.t05 VALUES(DEFAULT, DEFAULT, 200), (DEFAULT, 200, DEFAULT)
|
||||
ON DUPLICATE KEY UPDATE col3 = DEFAULT, col1 = col3;
|
||||
SELECT * FROM test_upsert_001.t05 ORDER BY 1, 2, 3;
|
||||
|
||||
--- should update
|
||||
INSERT INTO test_upsert_001.t05 VALUES(DEFAULT, DEFAULT, 200), (DEFAULT, 200, DEFAULT)
|
||||
ON DUPLICATE KEY UPDATE col3 = DEFAULT, col1 = col3;
|
||||
SELECT * FROM test_upsert_001.t05 ORDER BY 1, 2, 3;
|
||||
|
||||
--- test using schema on update
|
||||
INSERT INTO test_upsert_001.t05 VALUES(DEFAULT, DEFAULT, 200), (DEFAULT, 200, DEFAULT)
|
||||
ON DUPLICATE KEY UPDATE t05.col3 = DEFAULT, t05.col1 = t05.col3 + 1;
|
||||
SELECT * FROM test_upsert_001.t05 ORDER BY 1, 2, 3;
|
||||
|
||||
--- error: should not append schema
|
||||
INSERT INTO test_upsert_001.t05 VALUES(DEFAULT, DEFAULT, 200), (DEFAULT, 200, DEFAULT)
|
||||
ON DUPLICATE KEY UPDATE test_upsert_001.t05.col3 = DEFAULT, t05.col1 = t05.col3 + 1;
|
||||
|
||||
INSERT INTO test_upsert_001.t05 VALUES(DEFAULT, DEFAULT, 200), (DEFAULT, 200, DEFAULT)
|
||||
ON DUPLICATE KEY UPDATE t05.col3 = DEFAULT, t05.col1 = test_upsert_001.t05.col3 + 1;
|
||||
|
||||
SET CURRENT_SCHEMA TO test_upsert_001;
|
||||
|
||||
DROP USER upsert_tester CASCADE;
|
||||
DROP SCHEMA test_upsert_001 CASCADE;
|
||||
|
|
@ -0,0 +1,279 @@
|
|||
DROP SCHEMA test_upsert_002 CASCADE;
|
||||
CREATE SCHEMA test_upsert_002;
|
||||
SET CURRENT_SCHEMA TO test_upsert_002;
|
||||
|
||||
-- enable_upsert_to_merge must is off, or upsert will be translated to merge.
|
||||
SET enable_upsert_to_merge TO OFF;
|
||||
|
||||
-- test t1 with no index
|
||||
CREATE TABLE t1 (
|
||||
col1 INT,
|
||||
col2 INT,
|
||||
col3 INT DEFAULT 1,
|
||||
-- col4 TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
col5 BIGSERIAL
|
||||
) ;
|
||||
|
||||
INSERT INTO t1 VALUES (1, 2) ON DUPLICATE KEY UPDATE col1 = 3;
|
||||
|
||||
--- should always insert
|
||||
INSERT INTO t1 VALUES (1, 2) ON DUPLICATE KEY UPDATE col2 = 3;
|
||||
INSERT INTO t1 VALUES (1, 2) ON DUPLICATE KEY UPDATE t1.col2 = 4;
|
||||
|
||||
--- appoint column list in insert clause, should always insert
|
||||
INSERT INTO t1(col1, col3) VALUES (1, 3) ON DUPLICATE KEY UPDATE col2 = 5;
|
||||
INSERT INTO t1(col1, col3) VALUES (1, 3) ON DUPLICATE KEY UPDATE t1.col2 = 6;
|
||||
|
||||
--- multiple rows, should always insert
|
||||
INSERT INTO t1 VALUES (2, 1), (2, 1) ON DUPLICATE KEY UPDATE col2 = 7, col3 = 7;
|
||||
SELECT * FROM t1 ORDER BY col5;
|
||||
|
||||
--- test union, should insert
|
||||
INSERT INTO t1 (col1, col2)
|
||||
SELECT * FROM
|
||||
(SELECT col1, col2 FROM t1
|
||||
UNION
|
||||
SELECT col1, col3 FROM t1) AS union_table
|
||||
ON DUPLICATE KEY UPDATE col3 = (col1 + col2 + col3) * 10;
|
||||
SELECT col1, col2, col3 FROM t1 WHERE col5 > 6 ORDER BY col1, col2;
|
||||
|
||||
--- test subquery, should insert
|
||||
INSERT INTO t1
|
||||
(SELECT col1 || col2 || '00' FROM t1 ORDER BY col5)
|
||||
ON DUPLICATE KEY UPDATE col3 = col1 * 100;
|
||||
SELECT col1, col2, col3 FROM t1 WHERE col1 >= 100 ORDER BY col1;
|
||||
|
||||
-- test t2 with one primary key
|
||||
CREATE TABLE t2 (
|
||||
col1 INT,
|
||||
col2 INT PRIMARY KEY,
|
||||
col3 INT DEFAULT 1,
|
||||
col4 TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
col5 BIGSERIAL
|
||||
) ;
|
||||
|
||||
--- primary key or unique key are not allowed to update
|
||||
INSERT INTO t2 VALUES (1, 1) ON DUPLICATE KEY UPDATE col2 = 3;
|
||||
INSERT INTO t2 VALUES (1, 1) ON DUPLICATE KEY UPDATE t2.col2 = 3;
|
||||
INSERT INTO t2 (col2, col3, col4, col5)
|
||||
VALUES (10, 10, CURRENT_TIMESTAMP(0), 10),
|
||||
(20, 20, CURRENT_TIMESTAMP(1), 20),
|
||||
(30, 30, CURRENT_TIMESTAMP(2), 30)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
col1 = 100,
|
||||
col2 = 100,
|
||||
col3 = 100,
|
||||
col4 = '2019-08-09'::TIMESTAMP,
|
||||
col5 = 100;
|
||||
|
||||
--- should insert
|
||||
INSERT INTO t2 VALUES (1, 1) ON DUPLICATE KEY UPDATE col1 = 30;
|
||||
INSERT INTO t2 VALUES (2, 2) ON DUPLICATE KEY UPDATE t2.col1 = 40;
|
||||
INSERT INTO t2 VALUES (3, 3) ON DUPLICATE KEY UPDATE col1 = col1 * 2;
|
||||
INSERT INTO t2 VALUES (4, 4) ON DUPLICATE KEY UPDATE t2.col1 = t2.col1 * 2 ;
|
||||
INSERT INTO t2 VALUES (5, 5) ON DUPLICATE KEY UPDATE col1 = col2 + 1;
|
||||
INSERT INTO t2 VALUES (6, 6) ON DUPLICATE KEY UPDATE t2.col1 = t2.col2 + 1;
|
||||
INSERT INTO t2 VALUES (7, 7) ON DUPLICATE KEY UPDATE col1 = extract(dow from col4) + 10;
|
||||
INSERT INTO t2 VALUES (8, 8) ON DUPLICATE KEY UPDATE t2.col1 = extract(century from col4) * 100 + extract(isodow from col4);
|
||||
SELECT col1, col2, col3, col5 FROM t2 ORDER BY col5;
|
||||
|
||||
--- should update
|
||||
INSERT INTO t2 VALUES (3, 1) ON DUPLICATE KEY UPDATE col1 = 30, col3 = col5 + 1;
|
||||
INSERT INTO t2 VALUES (4, 2) ON DUPLICATE KEY UPDATE t2.col1 = 40, t2.col3 = t2.col5;
|
||||
INSERT INTO t2 VALUES (3, 3), (4, 4) ON DUPLICATE KEY UPDATE col3 = t2.col5 + 1;
|
||||
INSERT INTO t2 VALUES (5, 5) ON DUPLICATE KEY UPDATE col1 = extract(dow from col4) + 10;
|
||||
INSERT INTO t2 VALUES (6, 6) ON DUPLICATE KEY UPDATE t2.col1 = extract(century from col4) * 100 + extract(isodow from col4);
|
||||
SELECT col1, col2, col3, col5 FROM t2 ORDER BY col5;
|
||||
|
||||
-- primary key are not allowed to be null
|
||||
INSERT INTO t2 (col1) VALUES (10) ON DUPLICATE KEY UPDATE col1 = 10;
|
||||
|
||||
--- appoint column list in insert clause
|
||||
---- should insert
|
||||
INSERT INTO t2 (col2, col3) VALUES (9, 9) ON DUPLICATE KEY UPDATE col1 = 90;
|
||||
INSERT INTO t2 (col2, col3, col4, col5)
|
||||
VALUES (10, 10, CURRENT_TIMESTAMP(0), 10),
|
||||
(20, 20, CURRENT_TIMESTAMP(1), 20),
|
||||
(30, 30, CURRENT_TIMESTAMP(2), 30)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
col1 = 100,
|
||||
col3 = 100,
|
||||
col4 = '2019-08-20'::TIMESTAMP,
|
||||
col5 = 100;
|
||||
SELECT * FROM t2 ORDER BY col5;
|
||||
|
||||
---- should update
|
||||
INSERT INTO t2 (col2, col3) VALUES (9, 9) ON DUPLICATE KEY UPDATE col1 = 90;
|
||||
INSERT INTO t2 (col2, col3, col4, col5)
|
||||
VALUES (10, 10, CURRENT_TIMESTAMP(0), 10),
|
||||
(20, 20, CURRENT_TIMESTAMP(1), 20),
|
||||
(30, 30, CURRENT_TIMESTAMP(2), 30)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
col1 = 100,
|
||||
col3 = 100,
|
||||
col4 = '2019-08-20'::TIMESTAMP,
|
||||
col5 = 100;
|
||||
SELECT * FROM t2 ORDER BY col5, col2;
|
||||
|
||||
--- test subquery
|
||||
---- should insert
|
||||
INSERT INTO t2
|
||||
(SELECT col1 * 1000, col2 * 1000 + 1 FROM t2 ORDER BY col5 LIMIT 2)
|
||||
ON DUPLICATE KEY UPDATE col3 = col2 + 1;
|
||||
INSERT INTO t2 (col2, col3)
|
||||
(SELECT col1 * 1000 + 2, col2 * 1000 FROM t2 ORDER BY col5 LIMIT 2 OFFSET 1)
|
||||
ON DUPLICATE KEY UPDATE col3 = col2 + 1;
|
||||
SELECT col1, col2, col3, col5 FROM t2 ORDER BY col5, col2;
|
||||
|
||||
---- should update
|
||||
INSERT INTO t2
|
||||
(SELECT col1 * 1000, col2 * 1000 + 1 FROM t2 ORDER BY col5 LIMIT 2)
|
||||
ON DUPLICATE KEY UPDATE col3 = col2 + 1;
|
||||
INSERT INTO t2 (col2, col3)
|
||||
(SELECT col1 * 1000 + 2, col2 * 1000 FROM t2 ORDER BY col5 LIMIT 2 OFFSET 1)
|
||||
ON DUPLICATE KEY UPDATE col3 = col2 + 1;
|
||||
SELECT col1, col2, col3, col5 FROM t2 ORDER BY col5, col2;
|
||||
|
||||
--- test union, some insert some update
|
||||
SELECT col1, col2 FROM t1 WHERE col2 IS NOT NULL
|
||||
UNION
|
||||
SELECT col1, col3 FROM t1 ORDER BY 1, 2;
|
||||
INSERT INTO t2 (col1, col2)
|
||||
SELECT * FROM
|
||||
(SELECT col1, col2 FROM t1 WHERE col2 IS NOT NULL
|
||||
UNION
|
||||
SELECT col1, col3 FROM t1) AS union_table
|
||||
ON DUPLICATE KEY UPDATE col3 = (col1 + col2 + col3);
|
||||
|
||||
SELECT col1, col2, col3, col5 FROM t2 ORDER BY col5, col2;
|
||||
|
||||
INSERT INTO t2 (col1, col2)
|
||||
SELECT col1, col2 FROM t1 WHERE col2 IS NOT NULL
|
||||
UNION
|
||||
SELECT col1, col3 FROM t1
|
||||
ON DUPLICATE KEY UPDATE col3 = col3 + 1;
|
||||
SELECT col1, col2, col3, col5 FROM t2 ORDER BY col5, col2;
|
||||
reset behavior_compat_options;
|
||||
|
||||
-- test INTERSECT, should update
|
||||
(SELECT col1, col1 + col2 FROM t1 WHERE col2 IS NOT NULL
|
||||
UNION
|
||||
SELECT 1, 2)
|
||||
INTERSECT
|
||||
SELECT col1, col3 FROM t1;
|
||||
|
||||
INSERT INTO t2 (col1, col2)
|
||||
(SELECT col1, col1 + col2 FROM t1 WHERE col2 IS NOT NULL
|
||||
UNION
|
||||
SELECT 1, 2)
|
||||
INTERSECT
|
||||
SELECT col1, col3 FROM t1
|
||||
ON DUPLICATE KEY UPDATE col3 = col3 + 1;
|
||||
SELECT col1, col2, col3, col5 FROM t2 WHERE col2 = 3 ORDER BY col5, col2;
|
||||
|
||||
-- test EXCEPT, should update
|
||||
SELECT col1, col2 FROM t1 WHERE col2 IS NOT NULL
|
||||
EXCEPT
|
||||
(SELECT col1, col3 FROM t1
|
||||
UNION
|
||||
SELECT NULL, NULL);
|
||||
|
||||
INSERT INTO t2 (col1, col2)
|
||||
SELECT col1, col2 FROM t1 WHERE col2 IS NOT NULL
|
||||
EXCEPT
|
||||
(SELECT col1, col3 FROM t1
|
||||
UNION
|
||||
SELECT NULL, NULL)
|
||||
ON DUPLICATE KEY UPDATE col3 = col3 + 1;
|
||||
SELECT col1, col2, col3, col5 FROM t2 WHERE col2 = 2 ORDER BY col5, col2;
|
||||
|
||||
-- test unique index with not default value
|
||||
ALTER TABLE t2 DROP CONSTRAINT t2_pkey;
|
||||
CREATE UNIQUE INDEX t2_u_index ON t2(col2, col5);
|
||||
SELECT col1, col2 FROM t1 WHERE col2 IS NOT NULL
|
||||
EXCEPT
|
||||
(SELECT col1, col3 FROM t1
|
||||
UNION
|
||||
SELECT NULL, NULL);
|
||||
INSERT INTO t2
|
||||
SELECT col1, col2 FROM t1 WHERE col2 IS NOT NULL
|
||||
EXCEPT
|
||||
(SELECT col1, col3 FROM t1
|
||||
UNION
|
||||
SELECT NULL, NULL)
|
||||
ON DUPLICATE KEY UPDATE col3 = col3 + 1;
|
||||
SELECT col1, col2, col3, col5 FROM t2 WHERE col2 = 2 ORDER BY col5, col2;
|
||||
|
||||
-- test t3 with one primary index with two columns
|
||||
CREATE TABLE t3 (
|
||||
col1 INT,
|
||||
col2 INT,
|
||||
col3 INT DEFAULT 1,
|
||||
-- col4 TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
col5 BIGSERIAL,
|
||||
PRIMARY KEY (col2, col3)
|
||||
) ;
|
||||
|
||||
--- column referenced by primary key are not allowed to update
|
||||
INSERT INTO t3 VALUES (1, 1) ON DUPLICATE KEY UPDATE col3 = 3;
|
||||
|
||||
--- should insert when not contains primary key and not all primary key referred columns have default value.
|
||||
--- but will fail cause primary key should not be null
|
||||
INSERT INTO t3 (col1) VALUES (1) ON DUPLICATE KEY UPDATE col1 = 2;
|
||||
|
||||
--- should insert
|
||||
--- (SEQUENCE BUG: the serial column will starts from 2 since the above statement has applied for a sequence)
|
||||
INSERT INTO t3 VALUES (1, 1) ON DUPLICATE KEY UPDATE col1 = 10;
|
||||
INSERT INTO t3 VALUES (2, 2, 2) ON DUPLICATE KEY UPDATE col5 = 20;
|
||||
SELECT * FROM t3 order by col5;
|
||||
|
||||
--- should update
|
||||
INSERT INTO t3 VALUES (1, 1) ON DUPLICATE KEY UPDATE col1 = 10;
|
||||
INSERT INTO t3 VALUES (2, 2, 2) ON DUPLICATE KEY UPDATE col5 = 20;
|
||||
SELECT * FROM t3 order by col5;
|
||||
|
||||
--- test subquery
|
||||
---- should insert
|
||||
INSERT INTO t3 (col2, col3) (SELECT max(col2) + 1, max(col3) + 1 FROM t3) ON DUPLICATE KEY UPDATE col1 = col2 + col3;
|
||||
SELECT * FROM t3 order by col5;
|
||||
|
||||
---- should update
|
||||
INSERT INTO t3 (col2, col3) (SELECT max(col2), max(col3) FROM t3) ON DUPLICATE KEY UPDATE col1 = col2 + col3;
|
||||
SELECT * FROM t3 order by col5;
|
||||
|
||||
-- test t3 with one unique index with two columns
|
||||
TRUNCATE t3;
|
||||
ALTER TABLE t3 DROP CONSTRAINT t3_pkey;
|
||||
ALTER TABLE t3 ALTER COLUMN col2 DROP NOT NULL;
|
||||
CREATE UNIQUE INDEX t3_ukey ON t3 (col2, col3);
|
||||
|
||||
--- column referenced by unique key are not allowed to update
|
||||
INSERT INTO t3 VALUES (1, 1) ON DUPLICATE KEY UPDATE col3 = 3;
|
||||
|
||||
--- should insert cause not contains unique key and not all unique key referred columns have default value.
|
||||
INSERT INTO t3 (col1) VALUES (1) ON DUPLICATE KEY UPDATE col1 = 2;
|
||||
INSERT INTO t3 (col1) VALUES (1) ON DUPLICATE KEY UPDATE col1 = 2;
|
||||
SELECT * FROM t3 order by col5;
|
||||
|
||||
--- should insert
|
||||
INSERT INTO t3 VALUES (1, 1) ON DUPLICATE KEY UPDATE col1 = 10;
|
||||
INSERT INTO t3 VALUES (2, 2, 2) ON DUPLICATE KEY UPDATE t3.col5 = 20;
|
||||
SELECT * FROM t3 ORDER BY col5;
|
||||
|
||||
--- should update
|
||||
INSERT INTO t3 VALUES (1, 1) ON DUPLICATE KEY UPDATE t3.col1 = 10;
|
||||
INSERT INTO t3 VALUES (2, 2, 2) ON DUPLICATE KEY UPDATE col5 = 20;
|
||||
SELECT * FROM t3 ORDER BY col5;
|
||||
|
||||
--- test subquery
|
||||
---- should insert
|
||||
INSERT INTO t3 (SELECT 100, NULL, max(col3) FROM t3) ON DUPLICATE KEY UPDATE col1 = col2 + col3;
|
||||
INSERT INTO t3 (SELECT 100, NULL, max(col3) FROM t3) ON DUPLICATE KEY UPDATE col1 = col2 + col3;
|
||||
INSERT INTO t3 (col2, col3) (SELECT max(col2) + 1, max(col3) + 1 FROM t3) ON DUPLICATE KEY UPDATE col1 = col2 + col3;
|
||||
SELECT * FROM t3 ORDER BY col5;
|
||||
|
||||
---- should update
|
||||
INSERT INTO t3 (col2, col3) (SELECT max(col2), max(col3) FROM t3) ON DUPLICATE KEY UPDATE col1 = col2 + col3;
|
||||
SELECT * FROM t3 ORDER BY col5;
|
||||
|
||||
DROP SCHEMA test_upsert_002 CASCADE;
|
||||
|
|
@ -0,0 +1,144 @@
|
|||
DROP SCHEMA test_insert_update_003 CASCADE;
|
||||
CREATE SCHEMA test_insert_update_003;
|
||||
SET CURRENT_SCHEMA TO test_insert_update_003;
|
||||
|
||||
-- enable_upsert_to_merge must is off, or upsert will be translated to merge.
|
||||
SET enable_upsert_to_merge TO OFF;
|
||||
|
||||
-- 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)
|
||||
) ;
|
||||
|
||||
--- 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;
|
||||
|
||||
--- 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;
|
||||
|
||||
--- 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;
|
||||
INSERT INTO t4 (col1, col5)
|
||||
(SELECT col3, sum(col3) * 10 FROM t4 GROUP BY col3)
|
||||
ON DUPLICATE KEY UPDATE col1 = 3;
|
||||
|
||||
-- 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
|
||||
) ;
|
||||
|
||||
-- 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;
|
||||
|
||||
--- 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;
|
||||
|
||||
--- should some insert some update
|
||||
INSERT INTO t5 (col1, col3) VALUES (2, 5), (2, 6);
|
||||
SELECT col1, col2, col3 FROM t5 ORDER BY col3;
|
||||
INSERT INTO t5 (col1) VALUES (2), (2), (2) ON DUPLICATE KEY UPDATE col2 = col3;
|
||||
SELECT col1, col2, col3 FROM t5 ORDER BY col3;
|
||||
|
||||
--- should INSERT and sequence starting from 7
|
||||
INSERT INTO t5 VALUES (2), (2);
|
||||
SELECT col1, col2, col3 FROM t5 ORDER BY col3;
|
||||
|
||||
-- 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;
|
||||
|
||||
--- 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;
|
||||
|
||||
--- 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;
|
||||
|
||||
---- should update
|
||||
INSERT INTO t5 SELECT * FROM t5 ON DUPLICATE KEY UPDATE col2 = col5 * 1000;
|
||||
SELECT * FROM t5 ORDER BY col3;
|
||||
|
||||
-- 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
|
||||
) ;
|
||||
|
||||
ALTER TABLE t6 ADD PRIMARY KEY (col1, col3);
|
||||
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;
|
||||
|
||||
--- should not 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;
|
||||
|
||||
--- 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;
|
||||
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;
|
||||
|
||||
--- 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;
|
||||
|
||||
--- 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;
|
||||
|
||||
--- 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;
|
||||
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;
|
||||
|
||||
DROP SCHEMA test_insert_update_003 CASCADE;
|
||||
|
|
@ -0,0 +1,359 @@
|
|||
--
|
||||
-- INSERT UPDATE, test explain command, comes from merge_explain and merge_explain_pretty
|
||||
--
|
||||
|
||||
-- initial
|
||||
CREATE SCHEMA test_insert_update_008;
|
||||
SET current_schema = test_insert_update_008;
|
||||
|
||||
-- enable_upsert_to_merge must is off, or upsert will be translated to merge.
|
||||
SET enable_upsert_to_merge TO OFF;
|
||||
|
||||
CREATE TABLE products_base
|
||||
(
|
||||
product_id INTEGER DEFAULT 0,
|
||||
product_name VARCHAR(60) DEFAULT 'null',
|
||||
category VARCHAR(60) DEFAULT 'unknown',
|
||||
total INTEGER DEFAULT '0'
|
||||
);
|
||||
|
||||
INSERT INTO products_base VALUES (1501, 'vivitar 35mm', 'electrncs', 100);
|
||||
INSERT INTO products_base VALUES (1502, 'olympus is50', 'electrncs', 100);
|
||||
INSERT INTO products_base VALUES (1600, 'play gym', 'toys', 100);
|
||||
INSERT INTO products_base VALUES (1601, 'lamaze', 'toys', 100);
|
||||
INSERT INTO products_base VALUES (1666, 'harry potter', 'dvd', 100);
|
||||
|
||||
CREATE TABLE newproducts_base
|
||||
(
|
||||
product_id INTEGER DEFAULT 0,
|
||||
product_name VARCHAR(60) DEFAULT 'null',
|
||||
category VARCHAR(60) DEFAULT 'unknown',
|
||||
total INTEGER DEFAULT '0'
|
||||
);
|
||||
|
||||
INSERT INTO newproducts_base VALUES (1502, 'olympus camera', 'electrncs', 200);
|
||||
INSERT INTO newproducts_base VALUES (1601, 'lamaze', 'toys', 200);
|
||||
INSERT INTO newproducts_base VALUES (1666, 'harry potter', 'toys', 200);
|
||||
INSERT INTO newproducts_base VALUES (1700, 'wait interface', 'books', 200);
|
||||
|
||||
ANALYZE products_base;
|
||||
ANALYZE newproducts_base;
|
||||
|
||||
--
|
||||
-- row table
|
||||
--
|
||||
CREATE TABLE products_row
|
||||
(
|
||||
product_id INTEGER DEFAULT 0 PRIMARY KEY,
|
||||
product_name VARCHAR(60) DEFAULT 'null',
|
||||
category VARCHAR(60) DEFAULT 'unknown',
|
||||
total INTEGER DEFAULT '0'
|
||||
);
|
||||
|
||||
CREATE TABLE newproducts_row
|
||||
(
|
||||
product_id INTEGER DEFAULT 0 PRIMARY KEY,
|
||||
product_name VARCHAR(60) DEFAULT 'null',
|
||||
category VARCHAR(60) DEFAULT 'unknown',
|
||||
total INTEGER DEFAULT '0'
|
||||
);
|
||||
|
||||
INSERT INTO products_row SELECT * FROM products_base;
|
||||
INSERT INTO newproducts_row SELECT * FROM newproducts_base;
|
||||
ANALYZE products_row;
|
||||
ANALYZE newproducts_row;
|
||||
|
||||
SET explain_perf_mode = normal;
|
||||
-- explain verbose
|
||||
EXPLAIN (VERBOSE on, COSTS off)
|
||||
INSERT INTO products_row
|
||||
SELECT product_id, product_name, category, total FROM newproducts_row
|
||||
ON DUPLICATE KEY UPDATE
|
||||
product_name = excluded.product_name,
|
||||
category = excluded.category,
|
||||
total = excluded.total;
|
||||
|
||||
EXPLAIN (VERBOSE on, COSTS off)
|
||||
INSERT INTO products_row
|
||||
SELECT newproducts_row.product_id,
|
||||
newproducts_row.product_name,
|
||||
newproducts_row.category,
|
||||
newproducts_row.total
|
||||
FROM newproducts_row, products_row
|
||||
WHERE products_row.total + newproducts_row.total < 1000
|
||||
ON DUPLICATE KEY UPDATE
|
||||
product_name = excluded.product_name,
|
||||
category = excluded.category,
|
||||
total = excluded.total;
|
||||
|
||||
EXPLAIN (VERBOSE on, COSTS off)
|
||||
INSERT INTO products_row
|
||||
SELECT product_id, product_name, category, total
|
||||
FROM newproducts_row WHERE product_id IS NOT NULL AND product_name IS NOT NULL
|
||||
ON DUPLICATE KEY UPDATE
|
||||
product_name = excluded.product_name,
|
||||
category = excluded.category,
|
||||
total = excluded.total;
|
||||
|
||||
-- explain analyze
|
||||
BEGIN;
|
||||
EXPLAIN (ANALYZE on, COSTS off, TIMING off)
|
||||
INSERT INTO products_row
|
||||
SELECT product_id, product_name, category, total FROM newproducts_row
|
||||
ON DUPLICATE KEY UPDATE
|
||||
product_name = excluded.product_name,
|
||||
category = excluded.category,
|
||||
total = excluded.total;
|
||||
ROLLBACK;
|
||||
|
||||
-- explain performance
|
||||
\o insert_update_explain.txt
|
||||
BEGIN;
|
||||
EXPLAIN PERFORMANCE
|
||||
INSERT INTO products_row
|
||||
SELECT product_id, product_name, category, total FROM newproducts_row
|
||||
ON DUPLICATE KEY UPDATE
|
||||
product_name = excluded.product_name,
|
||||
category = excluded.category,
|
||||
total = excluded.total;
|
||||
ROLLBACK;
|
||||
\o
|
||||
|
||||
-- explain analyze
|
||||
BEGIN;
|
||||
EXPLAIN (ANALYZE on, COSTS off, TIMING off)
|
||||
INSERT INTO products_row
|
||||
SELECT product_id, product_name, category, total FROM newproducts_row
|
||||
ON DUPLICATE KEY UPDATE
|
||||
product_name = excluded.product_name,
|
||||
category = excluded.category,
|
||||
total = excluded.total;
|
||||
ROLLBACK;
|
||||
|
||||
-- pretty mode performance
|
||||
SET explain_perf_mode = pretty;
|
||||
|
||||
-- explain verbose
|
||||
EXPLAIN (VERBOSE on, COSTS off)
|
||||
INSERT INTO products_row
|
||||
SELECT product_id, product_name, category, total FROM newproducts_row
|
||||
ON DUPLICATE KEY UPDATE
|
||||
product_name = excluded.product_name,
|
||||
category = excluded.category,
|
||||
total = excluded.total;
|
||||
|
||||
-- explain analyze
|
||||
BEGIN;
|
||||
EXPLAIN (ANALYZE on, COSTS off, TIMING off)
|
||||
INSERT INTO products_row
|
||||
SELECT product_id, product_name, category, total FROM newproducts_row
|
||||
ON DUPLICATE KEY UPDATE
|
||||
product_name = excluded.product_name,
|
||||
category = excluded.category,
|
||||
total = excluded.total;
|
||||
ROLLBACK;
|
||||
|
||||
-- explain analyze
|
||||
BEGIN;
|
||||
EXPLAIN (ANALYZE on, COSTS off, TIMING off)
|
||||
INSERT INTO products_row
|
||||
SELECT product_id, product_name, category, total FROM newproducts_row
|
||||
ON DUPLICATE KEY UPDATE
|
||||
product_name = excluded.product_name,
|
||||
category = excluded.category,
|
||||
total = excluded.total;
|
||||
ROLLBACK;
|
||||
|
||||
-- explain performance
|
||||
\o insert_update_explain_pretty.txt
|
||||
BEGIN;
|
||||
EXPLAIN PERFORMANCE
|
||||
INSERT INTO products_row
|
||||
SELECT product_id, product_name, category, total FROM newproducts_row
|
||||
ON DUPLICATE KEY UPDATE
|
||||
product_name = excluded.product_name,
|
||||
category = excluded.category,
|
||||
total = excluded.total;
|
||||
ROLLBACK;
|
||||
|
||||
SET explain_perf_mode = run;
|
||||
|
||||
BEGIN;
|
||||
EXPLAIN PERFORMANCE
|
||||
INSERT INTO products_row
|
||||
SELECT product_id, product_name, category, total FROM newproducts_row
|
||||
ON DUPLICATE KEY UPDATE
|
||||
product_name = excluded.product_name,
|
||||
category = excluded.category,
|
||||
total = excluded.total;
|
||||
ROLLBACK;
|
||||
|
||||
SET explain_perf_mode = summary;
|
||||
|
||||
BEGIN;
|
||||
EXPLAIN PERFORMANCE
|
||||
INSERT INTO products_row
|
||||
SELECT product_id, product_name, category, total FROM newproducts_row
|
||||
ON DUPLICATE KEY UPDATE
|
||||
product_name = excluded.product_name,
|
||||
category = excluded.category,
|
||||
total = excluded.total;
|
||||
ROLLBACK;
|
||||
\o
|
||||
|
||||
CREATE TABLE item
|
||||
(
|
||||
a INT DEFAULT 3,
|
||||
item_id NUMERIC(18,10),
|
||||
item_name VARCHAR(100),
|
||||
item_level NUMERIC(39,0),
|
||||
item_desc VARCHAR(250),
|
||||
item_subclass_cd VARCHAR(50),
|
||||
item_type_cd VARCHAR(50),
|
||||
inventory_ind CHAR(300),
|
||||
vendor_party_id SMALLINT,
|
||||
commodity_cd VARCHAR(50),
|
||||
brand_cd VARCHAR(50),
|
||||
item_available CHAR(100),
|
||||
CONSTRAINT u_item_index UNIQUE (item_subclass_cd, vendor_party_id)
|
||||
)
|
||||
PARTITION BY RANGE (vendor_party_id)
|
||||
(
|
||||
PARTITION item_1 VALUES LESS THAN (0),
|
||||
PARTITION item_2 VALUES LESS THAN (1),
|
||||
PARTITION item_3 VALUES LESS THAN (2),
|
||||
PARTITION item_4 VALUES LESS THAN (3),
|
||||
PARTITION item_5 VALUES LESS THAN (6),
|
||||
PARTITION item_6 VALUES LESS THAN (8),
|
||||
PARTITION item_7 VALUES LESS THAN (10),
|
||||
PARTITION item_8 VALUES LESS THAN (15),
|
||||
PARTITION item_9 VALUES LESS THAN (MAXVALUE)
|
||||
) ENABLE ROW MOVEMENT;
|
||||
|
||||
CREATE TABLE region
|
||||
(
|
||||
a INT DEFAULT 8,
|
||||
region_cd VARCHAR(50),
|
||||
region_name VARCHAR(100),
|
||||
division_cd VARCHAR(50),
|
||||
region_mgr_associate_id number(18,9)
|
||||
);
|
||||
|
||||
CREATE TABLE associate_benefit_expense
|
||||
(
|
||||
a INT DEFAULT 44,
|
||||
period_end_dt DATE,
|
||||
associate_expns_type_cd VARCHAR(50),
|
||||
associate_party_id INTEGER,
|
||||
benefit_hours_qty decimal(38,11),
|
||||
benefit_cost_amt number(38,4)
|
||||
)
|
||||
PARTITION BY RANGE (associate_expns_type_cd)
|
||||
(
|
||||
PARTITION associate_benefit_expense_1 VALUES LESS THAN ('B'),
|
||||
PARTITION associate_benefit_expense_2 VALUES LESS THAN ('E'),
|
||||
PARTITION associate_benefit_expense_3 VALUES LESS THAN ('G'),
|
||||
PARTITION associate_benefit_expense_4 VALUES LESS THAN ('I'),
|
||||
PARTITION associate_benefit_expense_5 VALUES LESS THAN ('L'),
|
||||
PARTITION associate_benefit_expense_6 VALUES LESS THAN ('N'),
|
||||
PARTITION associate_benefit_expense_7 VALUES LESS THAN ('P'),
|
||||
PARTITION associate_benefit_expense_8 VALUES LESS THAN ('Q'),
|
||||
PARTITION associate_benefit_expense_9 VALUES LESS THAN ('R'),
|
||||
PARTITION associate_benefit_expense_10 VALUES LESS THAN ('T'),
|
||||
PARTITION associate_benefit_expense_11 VALUES LESS THAN ('U'),
|
||||
PARTITION associate_benefit_expense_12 VALUES LESS THAN ('V'),
|
||||
PARTITION associate_benefit_expense_13 VALUES LESS THAN (MAXVALUE)
|
||||
) ENABLE ROW MOVEMENT;
|
||||
|
||||
INSERT INTO item (ITEM_ID, ITEM_NAME, ITEM_DESC, ITEM_SUBCLASS_CD, ITEM_TYPE_CD, INVENTORY_IND, VENDOR_PARTY_ID, COMMODITY_CD, BRAND_CD,ITEM_AVAILABLE) VALUES (0.12, ' ' , 'A' , NULL, 'TGK' , 'A' , 2, 'A' , 'A' , 'Y');
|
||||
INSERT INTO item (ITEM_ID, ITEM_NAME, ITEM_DESC, ITEM_SUBCLASS_CD, ITEM_TYPE_CD, INVENTORY_IND, VENDOR_PARTY_ID, COMMODITY_CD, BRAND_CD,ITEM_AVAILABLE) VALUES (1.3, 'B' , NULL, 'B' , 'B' , NULL, 1, 'B' , NULL , 'N');
|
||||
INSERT INTO item (ITEM_ID, ITEM_NAME, ITEM_DESC, ITEM_SUBCLASS_CD, ITEM_TYPE_CD, INVENTORY_IND, VENDOR_PARTY_ID, COMMODITY_CD, BRAND_CD,ITEM_AVAILABLE) VALUES (2.23, 'C' , 'C' , NULL, 'C' , 'C' , 2, 'C' , 'C' , 'N');
|
||||
INSERT INTO item (ITEM_ID, ITEM_NAME, ITEM_DESC, ITEM_SUBCLASS_CD, ITEM_TYPE_CD, INVENTORY_IND, VENDOR_PARTY_ID, COMMODITY_CD, BRAND_CD,ITEM_AVAILABLE) VALUES (3.33, 'D' , 'D' , 'PT' , NULL, 'D' , 3, 'D' , 'D' , 'N');
|
||||
INSERT INTO item (ITEM_ID, ITEM_NAME, ITEM_DESC, ITEM_SUBCLASS_CD, ITEM_TYPE_CD, INVENTORY_IND, VENDOR_PARTY_ID, COMMODITY_CD, BRAND_CD,ITEM_AVAILABLE) VALUES (4.98, ' ' , NULL, 'E' , 'E' , 'E' , 4, 'E' , 'E' , 'Y');
|
||||
INSERT INTO item (ITEM_ID, ITEM_NAME, ITEM_DESC, ITEM_SUBCLASS_CD, ITEM_TYPE_CD, INVENTORY_IND, VENDOR_PARTY_ID, COMMODITY_CD, BRAND_CD,ITEM_AVAILABLE) VALUES (5.01, NULL, 'F' , ' ' , 'F' , 'F' , 5, 'F' , 'F' , 'N');
|
||||
INSERT INTO item (ITEM_ID, ITEM_NAME, ITEM_DESC, ITEM_SUBCLASS_CD, ITEM_TYPE_CD, INVENTORY_IND, VENDOR_PARTY_ID, COMMODITY_CD, BRAND_CD,ITEM_AVAILABLE) VALUES (6, 'G' , 'G' , 'G' , '_D' , 'G' , 6, 'G' , NULL ,'N');
|
||||
INSERT INTO item (ITEM_ID, ITEM_NAME, ITEM_DESC, ITEM_SUBCLASS_CD, ITEM_TYPE_CD, INVENTORY_IND, VENDOR_PARTY_ID, COMMODITY_CD, BRAND_CD,ITEM_AVAILABLE) VALUES (0.7, NULL, NULL, NULL, 'H' , 'H' , 7, NULL, 'G' , 'Y');
|
||||
INSERT INTO item (ITEM_ID, ITEM_NAME, ITEM_DESC, ITEM_SUBCLASS_CD, ITEM_TYPE_CD, INVENTORY_IND, VENDOR_PARTY_ID, COMMODITY_CD, BRAND_CD,ITEM_AVAILABLE) VALUES (0.08, 'I' , ' ' , ' T ' , NULL, 'I' , 8, 'I' , '' , 'N');
|
||||
INSERT INTO item (ITEM_ID, ITEM_NAME, ITEM_DESC, ITEM_SUBCLASS_CD, ITEM_TYPE_CD, INVENTORY_IND, VENDOR_PARTY_ID, COMMODITY_CD, BRAND_CD,ITEM_AVAILABLE) VALUES (9.12, ' ' , 'J' , ' PP' , 'J' , 'J' , 9, 'J' , NULL , 'Y');
|
||||
INSERT INTO item (ITEM_ID, ITEM_NAME, ITEM_DESC, ITEM_SUBCLASS_CD, ITEM_TYPE_CD, INVENTORY_IND, VENDOR_PARTY_ID, COMMODITY_CD, BRAND_CD,ITEM_AVAILABLE) VALUES (10.10, NULL, ' ' , 'A' , 'A' , 'A' , 2, NULL, 'A','Y');
|
||||
--INSERT INTO item (ITEM_ID, ITEM_NAME, ITEM_DESC, ITEM_SUBCLASS_CD, ITEM_TYPE_CD, INVENTORY_IND, VENDOR_PARTY_ID, COMMODITY_CD, BRAND_CD,ITEM_AVAILABLE) VALUES (11.11, 'B' , 'B' , 'B' , 'BCDAA' , NULL, 1, 'B' , 'B','N');
|
||||
INSERT INTO item (ITEM_ID, ITEM_NAME, ITEM_DESC, ITEM_SUBCLASS_CD, ITEM_TYPE_CD, INVENTORY_IND, VENDOR_PARTY_ID, COMMODITY_CD, BRAND_CD,ITEM_AVAILABLE) VALUES (12.02, 'D' , NULL, NULL, 'C' , 'C' , 2, 'C' , 'C','N');
|
||||
INSERT INTO item (ITEM_ID, ITEM_NAME, ITEM_DESC, ITEM_SUBCLASS_CD, ITEM_TYPE_CD, INVENTORY_IND, VENDOR_PARTY_ID, COMMODITY_CD, BRAND_CD,ITEM_AVAILABLE) VALUES (13.99, NULL, ' ' , 'D' , 'D' , 'D' , 3, 'D' , 'D','Y');
|
||||
--INSERT INTO item (ITEM_ID, ITEM_NAME, ITEM_DESC, ITEM_SUBCLASS_CD, ITEM_TYPE_CD, INVENTORY_IND, VENDOR_PARTY_ID, COMMODITY_CD, BRAND_CD,ITEM_AVAILABLE) VALUES (14, 'G' , 'E' , 'E' , NULL, 'E' , 4, 'E' , 'E','N');
|
||||
INSERT INTO item (ITEM_ID, ITEM_NAME, ITEM_DESC, ITEM_SUBCLASS_CD, ITEM_TYPE_CD, INVENTORY_IND, VENDOR_PARTY_ID, COMMODITY_CD, BRAND_CD,ITEM_AVAILABLE) VALUES (15, 'F' , ' ' , 'C' , 'CLEANING' , 'F' , 5, 'F' , 'F','Y');
|
||||
INSERT INTO item (ITEM_ID, ITEM_NAME, ITEM_DESC, ITEM_SUBCLASS_CD, ITEM_TYPE_CD, INVENTORY_IND, VENDOR_PARTY_ID, COMMODITY_CD, BRAND_CD,ITEM_AVAILABLE) VALUES (16, '' , 'Z' , NULL, 'G' , 'G' , 6, 'G' , NULL,'N');
|
||||
INSERT INTO item (ITEM_ID, ITEM_NAME, ITEM_DESC, ITEM_SUBCLASS_CD, ITEM_TYPE_CD, INVENTORY_IND, VENDOR_PARTY_ID, COMMODITY_CD, BRAND_CD,ITEM_AVAILABLE) VALUES (17, NULL, '' , ' PAPER' , 'H' , '' , 7, NULL, NULL,'Y');
|
||||
INSERT INTO item (ITEM_ID, ITEM_NAME, ITEM_DESC, ITEM_SUBCLASS_CD, ITEM_TYPE_CD, INVENTORY_IND, VENDOR_PARTY_ID, COMMODITY_CD, BRAND_CD,ITEM_AVAILABLE) VALUES (19, ' ' , 'B' , '' , '' , 'I' , 8, 'I' , NULL,'N');
|
||||
INSERT INTO item (ITEM_ID, ITEM_NAME, ITEM_DESC, ITEM_SUBCLASS_CD, ITEM_TYPE_CD, INVENTORY_IND, VENDOR_PARTY_ID, COMMODITY_CD, BRAND_CD,ITEM_AVAILABLE) VALUES (20 , 'A' , 'J' , 'J' , 'J' , NULL, 9, 'J' , 'G','Y');
|
||||
|
||||
/*--REGION--*/
|
||||
INSERT INTO REGION (REGION_CD, REGION_NAME, DIVISION_CD, REGION_MGR_ASSOCIATE_ID) VALUES ('A', 'A ', 'A', 0.123433);
|
||||
INSERT INTO REGION (REGION_CD, REGION_NAME, DIVISION_CD, REGION_MGR_ASSOCIATE_ID) VALUES ('B', 'B', 'B', NULL);
|
||||
INSERT INTO REGION (REGION_CD, REGION_NAME, DIVISION_CD, REGION_MGR_ASSOCIATE_ID) VALUES ('C', 'C', 'C', 2.232008908);
|
||||
INSERT INTO REGION (REGION_CD, REGION_NAME, DIVISION_CD, REGION_MGR_ASSOCIATE_ID) VALUES ('D', ' DD', 'D', 3.878789);
|
||||
INSERT INTO REGION (REGION_CD, REGION_NAME, DIVISION_CD, REGION_MGR_ASSOCIATE_ID) VALUES ('E', 'A', 'E', 4.89060603);
|
||||
INSERT INTO REGION (REGION_CD, REGION_NAME, DIVISION_CD, REGION_MGR_ASSOCIATE_ID) VALUES ('F', 'F', 'F', 5.82703827);
|
||||
INSERT INTO REGION (REGION_CD, REGION_NAME, DIVISION_CD, REGION_MGR_ASSOCIATE_ID) VALUES ('G', 'G', 'TTT', NULL);
|
||||
INSERT INTO REGION (REGION_CD, REGION_NAME, DIVISION_CD, REGION_MGR_ASSOCIATE_ID) VALUES ('H', 'H', 'G', 7.3829083);
|
||||
INSERT INTO REGION (REGION_CD, REGION_NAME, DIVISION_CD, REGION_MGR_ASSOCIATE_ID) VALUES ('I', 'C', 'M', 8.983989);
|
||||
INSERT INTO REGION (REGION_CD, REGION_NAME, DIVISION_CD, REGION_MGR_ASSOCIATE_ID) VALUES ('J', 'J', 'G', NULL);
|
||||
INSERT INTO REGION (REGION_CD, REGION_NAME, DIVISION_CD, REGION_MGR_ASSOCIATE_ID) VALUES ('K', ' ', 'C', 2.232008908);
|
||||
INSERT INTO REGION (REGION_CD, REGION_NAME, DIVISION_CD, REGION_MGR_ASSOCIATE_ID) VALUES ('L', 'D', 'X', 3.878789);
|
||||
INSERT INTO REGION (REGION_CD, REGION_NAME, DIVISION_CD, REGION_MGR_ASSOCIATE_ID) VALUES ('M', 'TTTTTT ', 'D' , 4.89060603);
|
||||
INSERT INTO REGION (REGION_CD, REGION_NAME, DIVISION_CD, REGION_MGR_ASSOCIATE_ID) VALUES ('N', 'G' , 'B' , NULL);
|
||||
INSERT INTO REGION (REGION_CD, REGION_NAME, DIVISION_CD, REGION_MGR_ASSOCIATE_ID) VALUES ('O' , 'G', 'F', 6.6703972);
|
||||
|
||||
INSERT INTO ASSOCIATE_BENEFIT_EXPENSE (PERIOD_END_DT, ASSOCIATE_EXPNS_TYPE_CD, ASSOCIATE_PARTY_ID, BENEFIT_HOURS_QTY, BENEFIT_COST_AMT) VALUES (DATE '1970-01-01', 'A', 5, 0.5 , 0.5);
|
||||
INSERT INTO ASSOCIATE_BENEFIT_EXPENSE (PERIOD_END_DT, ASSOCIATE_EXPNS_TYPE_CD, ASSOCIATE_PARTY_ID, BENEFIT_HOURS_QTY, BENEFIT_COST_AMT) VALUES (DATE '1973-01-01', 'B', 1, NULL, 1.0);
|
||||
INSERT INTO ASSOCIATE_BENEFIT_EXPENSE (PERIOD_END_DT, ASSOCIATE_EXPNS_TYPE_CD, ASSOCIATE_PARTY_ID, BENEFIT_HOURS_QTY, BENEFIT_COST_AMT) VALUES (DATE '1976-01-01', 'C', 2, 2.0 , NULL);
|
||||
INSERT INTO ASSOCIATE_BENEFIT_EXPENSE (PERIOD_END_DT, ASSOCIATE_EXPNS_TYPE_CD, ASSOCIATE_PARTY_ID, BENEFIT_HOURS_QTY, BENEFIT_COST_AMT) VALUES (DATE '1979-01-01', 'D', 3, 3.0 , 3.0);
|
||||
INSERT INTO ASSOCIATE_BENEFIT_EXPENSE (PERIOD_END_DT, ASSOCIATE_EXPNS_TYPE_CD, ASSOCIATE_PARTY_ID, BENEFIT_HOURS_QTY, BENEFIT_COST_AMT) VALUES (DATE '1982-01-01', 'E', 4, 4.0 , 4.0);
|
||||
INSERT INTO ASSOCIATE_BENEFIT_EXPENSE (PERIOD_END_DT, ASSOCIATE_EXPNS_TYPE_CD, ASSOCIATE_PARTY_ID, BENEFIT_HOURS_QTY, BENEFIT_COST_AMT) VALUES (DATE '1985-01-01', 'F', 5, 5.0 , 5.0);
|
||||
INSERT INTO ASSOCIATE_BENEFIT_EXPENSE (PERIOD_END_DT, ASSOCIATE_EXPNS_TYPE_CD, ASSOCIATE_PARTY_ID, BENEFIT_HOURS_QTY, BENEFIT_COST_AMT) VALUES (DATE '1988-01-01', 'F', 6, NULL, 6.0);
|
||||
INSERT INTO ASSOCIATE_BENEFIT_EXPENSE (PERIOD_END_DT, ASSOCIATE_EXPNS_TYPE_CD, ASSOCIATE_PARTY_ID, BENEFIT_HOURS_QTY, BENEFIT_COST_AMT) VALUES (DATE '1991-01-01', 'G', 6, NULL, NULL);
|
||||
INSERT INTO ASSOCIATE_BENEFIT_EXPENSE (PERIOD_END_DT, ASSOCIATE_EXPNS_TYPE_CD, ASSOCIATE_PARTY_ID, BENEFIT_HOURS_QTY, BENEFIT_COST_AMT) VALUES (DATE '1994-01-01', 'G', 15, 8.0 , 8.0);
|
||||
INSERT INTO ASSOCIATE_BENEFIT_EXPENSE (PERIOD_END_DT, ASSOCIATE_EXPNS_TYPE_CD, ASSOCIATE_PARTY_ID, BENEFIT_HOURS_QTY, BENEFIT_COST_AMT) VALUES (DATE '1997-01-01', 'G', 16, 9.0 , 9.0);
|
||||
INSERT INTO ASSOCIATE_BENEFIT_EXPENSE (PERIOD_END_DT, ASSOCIATE_EXPNS_TYPE_CD, ASSOCIATE_PARTY_ID, BENEFIT_HOURS_QTY, BENEFIT_COST_AMT) VALUES (DATE '1983-01-03', 'I', 14, 4.0 , 4.0);
|
||||
INSERT INTO ASSOCIATE_BENEFIT_EXPENSE (PERIOD_END_DT, ASSOCIATE_EXPNS_TYPE_CD, ASSOCIATE_PARTY_ID, BENEFIT_HOURS_QTY, BENEFIT_COST_AMT) VALUES (DATE '1984-01-01', 'GO', 15, 5.0 , NULL);
|
||||
INSERT INTO ASSOCIATE_BENEFIT_EXPENSE (PERIOD_END_DT, ASSOCIATE_EXPNS_TYPE_CD, ASSOCIATE_PARTY_ID, BENEFIT_HOURS_QTY, BENEFIT_COST_AMT) VALUES (DATE '1985-05-01', 'I', 16, 6.0 , 6.0);
|
||||
INSERT INTO ASSOCIATE_BENEFIT_EXPENSE (PERIOD_END_DT, ASSOCIATE_EXPNS_TYPE_CD, ASSOCIATE_PARTY_ID, BENEFIT_HOURS_QTY, BENEFIT_COST_AMT) VALUES (DATE '1990-01-01', 'TTT', 16, NULL, 7.0);
|
||||
INSERT INTO ASSOCIATE_BENEFIT_EXPENSE (PERIOD_END_DT, ASSOCIATE_EXPNS_TYPE_CD, ASSOCIATE_PARTY_ID, BENEFIT_HOURS_QTY, BENEFIT_COST_AMT) VALUES (DATE '1992-02-01', 'A', 15, 8.0 , 8.0);
|
||||
INSERT INTO ASSOCIATE_BENEFIT_EXPENSE (PERIOD_END_DT, ASSOCIATE_EXPNS_TYPE_CD, ASSOCIATE_PARTY_ID, BENEFIT_HOURS_QTY, BENEFIT_COST_AMT) VALUES (DATE '1997-02-01', 'G', 17, 9.0 , NULL);
|
||||
INSERT INTO ASSOCIATE_BENEFIT_EXPENSE (PERIOD_END_DT, ASSOCIATE_EXPNS_TYPE_CD, ASSOCIATE_PARTY_ID, BENEFIT_HOURS_QTY, BENEFIT_COST_AMT) VALUES (DATE '1997-05-01', 'G' , 17, 9.0 , NULL);
|
||||
|
||||
ANALYZE item;
|
||||
ANALYZE region;
|
||||
ANALYZE associate_benefit_expense;
|
||||
|
||||
EXPLAIN (VERBOSE ON, COSTS OFF)
|
||||
INSERT INTO item (item_level, item_subclass_cd, item_desc, vendor_party_id)
|
||||
SELECT Table_001.REGION_MGR_ASSOCIATE_ID Column_003,
|
||||
Table_002.associate_expns_type_cd Column_004,
|
||||
CAST(Table_001.region_name AS VARCHAR) Column_005,
|
||||
10 Column_006
|
||||
-- 'o' Column_007,
|
||||
-- 'F' Column_008,
|
||||
-- pg_client_encoding() Column_009
|
||||
FROM region Table_001, associate_benefit_expense Table_002
|
||||
ON DUPLICATE KEY UPDATE item_level = -1000;
|
||||
|
||||
EXPLAIN (VERBOSE ON, COSTS OFF)
|
||||
INSERT INTO products_row VALUES(100)
|
||||
ON DUPLICATE KEY UPDATE total=100;
|
||||
|
||||
SET enable_light_proxy=off;
|
||||
EXPLAIN (VERBOSE ON, COSTS OFF)
|
||||
INSERT INTO products_row VALUES(100)
|
||||
ON DUPLICATE KEY UPDATE total=100;
|
||||
|
||||
EXPLAIN (VERBOSE ON, COSTS OFF)
|
||||
INSERT INTO products_row VALUES(100)
|
||||
ON DUPLICATE KEY UPDATE total=100;
|
||||
|
||||
EXPLAIN (VERBOSE ON, COSTS OFF)
|
||||
INSERT INTO products_row VALUES(100)
|
||||
ON DUPLICATE KEY UPDATE total=100;
|
||||
|
||||
RESET enable_light_proxy;
|
||||
|
||||
DROP SCHEMA test_insert_update_008 CASCADE;
|
||||
|
|
@ -0,0 +1,281 @@
|
|||
DROP SCHEMA test_insert_update_009 CASCADE;
|
||||
CREATE SCHEMA test_insert_update_009;
|
||||
SET CURRENT_SCHEMA TO test_insert_update_009;
|
||||
SET enable_light_proxy=off;
|
||||
|
||||
-- enable_upsert_to_merge must is off, or upsert will be translated to merge.
|
||||
SET enable_upsert_to_merge TO OFF;
|
||||
|
||||
-- test t1 with no index
|
||||
CREATE TABLE t1 (
|
||||
col1 INT,
|
||||
col2 INT,
|
||||
col3 INT DEFAULT 1,
|
||||
-- col4 TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
col5 BIGSERIAL
|
||||
) ;
|
||||
|
||||
--- distribute key are not allowed to update
|
||||
INSERT INTO t1 VALUES (1, 2) ON DUPLICATE KEY UPDATE col1 = 3;
|
||||
|
||||
--- should always insert
|
||||
INSERT INTO t1 VALUES (1, 2) ON DUPLICATE KEY UPDATE col2 = 3;
|
||||
INSERT INTO t1 VALUES (1, 2) ON DUPLICATE KEY UPDATE t1.col2 = 4;
|
||||
|
||||
--- appoint column list in insert clause, should always insert
|
||||
INSERT INTO t1(col1, col3) VALUES (1, 3) ON DUPLICATE KEY UPDATE col2 = 5;
|
||||
INSERT INTO t1(col1, col3) VALUES (1, 3) ON DUPLICATE KEY UPDATE t1.col2 = 6;
|
||||
|
||||
--- multiple rows, should always insert
|
||||
INSERT INTO t1 VALUES (2, 1), (2, 1) ON DUPLICATE KEY UPDATE col2 = 7, col3 = 7;
|
||||
SELECT * FROM t1 ORDER BY col5;
|
||||
|
||||
--- test union, should insert
|
||||
INSERT INTO t1 (col1, col2)
|
||||
SELECT * FROM
|
||||
(SELECT col1, col2 FROM t1
|
||||
UNION
|
||||
SELECT col1, col3 FROM t1) AS union_table
|
||||
ON DUPLICATE KEY UPDATE col3 = (col1 + col2 + col3);
|
||||
SELECT col1, col2, col3 FROM t1 WHERE col5 > 6 ORDER BY col1, col2;
|
||||
|
||||
--- test subquery, should insert
|
||||
INSERT INTO t1
|
||||
(SELECT col1 || col2 || '00' FROM t1 ORDER BY col5)
|
||||
ON DUPLICATE KEY UPDATE col3 = col1 * 100;
|
||||
SELECT col1, col2, col3 FROM t1 WHERE col1 >= 100 ORDER BY col1;
|
||||
|
||||
-- test t2 with one primary key
|
||||
CREATE TABLE t2 (
|
||||
col1 INT,
|
||||
col2 INT PRIMARY KEY,
|
||||
col3 INT DEFAULT 1,
|
||||
col4 TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
col5 BIGSERIAL
|
||||
) ;
|
||||
|
||||
--- distribute key are not allowed to update
|
||||
INSERT INTO t2 VALUES (1, 1) ON DUPLICATE KEY UPDATE col2 = 3;
|
||||
INSERT INTO t2 VALUES (1, 1) ON DUPLICATE KEY UPDATE t2.col2 = 3;
|
||||
INSERT INTO t2 (col2, col3, col4, col5)
|
||||
VALUES (10, 10, CURRENT_TIMESTAMP(0), 10),
|
||||
(20, 20, CURRENT_TIMESTAMP(1), 20),
|
||||
(30, 30, CURRENT_TIMESTAMP(2), 30)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
col1 = 100,
|
||||
col2 = 100,
|
||||
col3 = 100,
|
||||
col4 = '2019-08-09'::TIMESTAMP,
|
||||
col5 = 100;
|
||||
|
||||
--- should insert
|
||||
INSERT INTO t2 VALUES (1, 1) ON DUPLICATE KEY UPDATE col1 = 30;
|
||||
INSERT INTO t2 VALUES (2, 2) ON DUPLICATE KEY UPDATE t2.col1 = 40;
|
||||
INSERT INTO t2 VALUES (3, 3) ON DUPLICATE KEY UPDATE col1 = col1 * 2;
|
||||
INSERT INTO t2 VALUES (4, 4) ON DUPLICATE KEY UPDATE t2.col1 = t2.col1 * 2 ;
|
||||
INSERT INTO t2 VALUES (5, 5) ON DUPLICATE KEY UPDATE col1 = col2 + 1;
|
||||
INSERT INTO t2 VALUES (6, 6) ON DUPLICATE KEY UPDATE t2.col1 = t2.col2 + 1;
|
||||
INSERT INTO t2 VALUES (7, 7) ON DUPLICATE KEY UPDATE col1 = extract(dow from col4) + 10;
|
||||
INSERT INTO t2 VALUES (8, 8) ON DUPLICATE KEY UPDATE t2.col1 = extract(century from col4) * 100 + extract(isodow from col4);
|
||||
SELECT col1, col2, col3, col5 FROM t2 ORDER BY col5;
|
||||
|
||||
--- should update
|
||||
INSERT INTO t2 VALUES (3, 1) ON DUPLICATE KEY UPDATE col1 = 30, col3 = col5 + 1;
|
||||
INSERT INTO t2 VALUES (4, 2) ON DUPLICATE KEY UPDATE t2.col1 = 40, t2.col3 = t2.col5;
|
||||
INSERT INTO t2 VALUES (3, 3), (4, 4) ON DUPLICATE KEY UPDATE col3 = t2.col5 + 1;
|
||||
INSERT INTO t2 VALUES (5, 5) ON DUPLICATE KEY UPDATE col1 = extract(dow from col4) + 10;
|
||||
INSERT INTO t2 VALUES (6, 6) ON DUPLICATE KEY UPDATE t2.col1 = extract(century from col4) * 100 + extract(isodow from col4);
|
||||
SELECT col1, col2, col3, col5 FROM t2 ORDER BY col5;
|
||||
|
||||
-- primary key are not allowed to be null
|
||||
INSERT INTO t2 (col1) VALUES (10) ON DUPLICATE KEY UPDATE col1 = 10;
|
||||
|
||||
--- appoint column list in insert clause
|
||||
---- should insert
|
||||
INSERT INTO t2 (col2, col3) VALUES (9, 9) ON DUPLICATE KEY UPDATE col1 = 90;
|
||||
INSERT INTO t2 (col2, col3, col4, col5)
|
||||
VALUES (10, 10, CURRENT_TIMESTAMP(0), 10),
|
||||
(20, 20, CURRENT_TIMESTAMP(1), 20),
|
||||
(30, 30, CURRENT_TIMESTAMP(2), 30)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
col1 = 100,
|
||||
col3 = 100,
|
||||
col4 = '2019-08-20'::TIMESTAMP,
|
||||
col5 = 100;
|
||||
SELECT * FROM t2 ORDER BY col5;
|
||||
|
||||
---- should update
|
||||
INSERT INTO t2 (col2, col3) VALUES (9, 9) ON DUPLICATE KEY UPDATE col1 = 90;
|
||||
INSERT INTO t2 (col2, col3, col4, col5)
|
||||
VALUES (10, 10, CURRENT_TIMESTAMP(0), 10),
|
||||
(20, 20, CURRENT_TIMESTAMP(1), 20),
|
||||
(30, 30, CURRENT_TIMESTAMP(2), 30)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
col1 = 100,
|
||||
col3 = 100,
|
||||
col4 = '2019-08-20'::TIMESTAMP,
|
||||
col5 = 100;
|
||||
SELECT * FROM t2 ORDER BY col5, col2;
|
||||
|
||||
--- test subquery
|
||||
---- should insert
|
||||
INSERT INTO t2
|
||||
(SELECT col1 * 1000, col2 * 1000 + 1 FROM t2 ORDER BY col5 LIMIT 2)
|
||||
ON DUPLICATE KEY UPDATE col3 = col2 + 1;
|
||||
INSERT INTO t2 (col2, col3)
|
||||
(SELECT col1 * 1000 + 2, col2 * 1000 FROM t2 ORDER BY col5 LIMIT 2 OFFSET 1)
|
||||
ON DUPLICATE KEY UPDATE col3 = col2 + 1;
|
||||
SELECT col1, col2, col3, col5 FROM t2 ORDER BY col5, col2;
|
||||
|
||||
---- should update
|
||||
INSERT INTO t2
|
||||
(SELECT col1 * 1000, col2 * 1000 + 1 FROM t2 ORDER BY col5 LIMIT 2)
|
||||
ON DUPLICATE KEY UPDATE col3 = col2 + 1;
|
||||
INSERT INTO t2 (col2, col3)
|
||||
(SELECT col1 * 1000 + 2, col2 * 1000 FROM t2 ORDER BY col5 LIMIT 2 OFFSET 1)
|
||||
ON DUPLICATE KEY UPDATE col3 = col2 + 1;
|
||||
SELECT col1, col2, col3, col5 FROM t2 ORDER BY col5, col2;
|
||||
|
||||
--- test union, some insert some update
|
||||
SELECT col1, col2 FROM t1 WHERE col2 IS NOT NULL
|
||||
UNION
|
||||
SELECT col1, col3 FROM t1 ORDER BY 1, 2;
|
||||
INSERT INTO t2 (col1, col2)
|
||||
SELECT * FROM
|
||||
(SELECT col1, col2 FROM t1 WHERE col2 IS NOT NULL
|
||||
UNION
|
||||
SELECT col1, col3 FROM t1) AS union_table
|
||||
ON DUPLICATE KEY UPDATE col3 = (col1 + col2 + col3);
|
||||
SELECT col1, col2, col3, col5 FROM t2 ORDER BY col5, col2;
|
||||
|
||||
INSERT INTO t2 (col1, col2)
|
||||
SELECT col1, col2 FROM t1 WHERE col2 IS NOT NULL
|
||||
UNION
|
||||
SELECT col1, col3 FROM t1
|
||||
ON DUPLICATE KEY UPDATE col3 = (col1 + col2 + col3);
|
||||
SELECT col1, col2, col3, col5 FROM t2 ORDER BY col5, col2;
|
||||
reset behavior_compat_options;
|
||||
|
||||
-- test INTERSECT, should update
|
||||
(SELECT col1, col1 + col2 FROM t1 WHERE col2 IS NOT NULL
|
||||
UNION
|
||||
SELECT 1, 2)
|
||||
INTERSECT
|
||||
SELECT col1, col3 FROM t1;
|
||||
|
||||
INSERT INTO t2 (col1, col2)
|
||||
(SELECT col1, col1 + col2 FROM t1 WHERE col2 IS NOT NULL
|
||||
UNION
|
||||
SELECT 1, 2)
|
||||
INTERSECT
|
||||
SELECT col1, col3 FROM t1
|
||||
ON DUPLICATE KEY UPDATE col3 = (col1 + col2 + col3);
|
||||
SELECT col1, col2, col3, col5 FROM t2 WHERE col2 = 3 ORDER BY col5, col2;
|
||||
|
||||
-- test EXCEPT, should update
|
||||
SELECT col1, col2 FROM t1 WHERE col2 IS NOT NULL
|
||||
EXCEPT
|
||||
(SELECT col1, col3 FROM t1
|
||||
UNION
|
||||
SELECT NULL, NULL);
|
||||
|
||||
INSERT INTO t2 (col1, col2)
|
||||
SELECT col1, col2 FROM t1 WHERE col2 IS NOT NULL
|
||||
EXCEPT
|
||||
(SELECT col1, col3 FROM t1
|
||||
UNION
|
||||
SELECT NULL, NULL)
|
||||
ON DUPLICATE KEY UPDATE col3 = (col1 + col2 + col3);
|
||||
SELECT col1, col2, col3, col5 FROM t2 WHERE col2 = 2 ORDER BY col5, col2;
|
||||
|
||||
-- test unique index with not default value
|
||||
ALTER TABLE t2 DROP CONSTRAINT t2_pkey;
|
||||
CREATE UNIQUE INDEX t2_u_index ON t2(col2, col5);
|
||||
SELECT col1, col2 FROM t1 WHERE col2 IS NOT NULL
|
||||
EXCEPT
|
||||
(SELECT col1, col3 FROM t1
|
||||
UNION
|
||||
SELECT NULL, NULL);
|
||||
INSERT INTO t2
|
||||
SELECT col1, col2 FROM t1 WHERE col2 IS NOT NULL
|
||||
EXCEPT
|
||||
(SELECT col1, col3 FROM t1
|
||||
UNION
|
||||
SELECT NULL, NULL)
|
||||
ON DUPLICATE KEY UPDATE col3 = (col1 + col2 + col3);
|
||||
SELECT col1, col2, col3, col5 FROM t2 WHERE col2 = 2 ORDER BY col5, col2;
|
||||
|
||||
-- test t3 with one primary index with two columns
|
||||
CREATE TABLE t3 (
|
||||
col1 INT,
|
||||
col2 INT,
|
||||
col3 INT DEFAULT 1,
|
||||
-- col4 TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
col5 BIGSERIAL,
|
||||
PRIMARY KEY (col2, col3)
|
||||
) ;
|
||||
|
||||
--- column referenced by primary key are not allowed to update
|
||||
INSERT INTO t3 VALUES (1, 1) ON DUPLICATE KEY UPDATE col3 = 3;
|
||||
|
||||
--- should insert when not contains primary key and not all primary key referred columns have default value.
|
||||
--- but will fail cause primary key should not be null
|
||||
INSERT INTO t3 (col1) VALUES (1) ON DUPLICATE KEY UPDATE col1 = 2;
|
||||
|
||||
--- should insert
|
||||
--- (SEQUENCE BUG: the serial column will starts from 2 since the above statement has applied for a sequence)
|
||||
INSERT INTO t3 VALUES (1, 1) ON DUPLICATE KEY UPDATE col1 = 10;
|
||||
INSERT INTO t3 VALUES (2, 2, 2) ON DUPLICATE KEY UPDATE col5 = 20;
|
||||
SELECT * FROM t3 order by col5;
|
||||
|
||||
--- should update
|
||||
INSERT INTO t3 VALUES (1, 1) ON DUPLICATE KEY UPDATE col1 = 10;
|
||||
INSERT INTO t3 VALUES (2, 2, 2) ON DUPLICATE KEY UPDATE col5 = 20;
|
||||
SELECT * FROM t3 order by col5;
|
||||
|
||||
--- test subquery
|
||||
---- should insert
|
||||
INSERT INTO t3 (col2, col3) (SELECT max(col2) + 1, max(col3) + 1 FROM t3) ON DUPLICATE KEY UPDATE col1 = col2 + col3;
|
||||
SELECT * FROM t3 order by col5;
|
||||
|
||||
---- should update
|
||||
INSERT INTO t3 (col2, col3) (SELECT max(col2), max(col3) FROM t3) ON DUPLICATE KEY UPDATE col1 = col2 + col3;
|
||||
SELECT * FROM t3 order by col5;
|
||||
|
||||
-- test t3 with one unique index with two columns
|
||||
TRUNCATE t3;
|
||||
ALTER TABLE t3 DROP CONSTRAINT t3_pkey;
|
||||
ALTER TABLE t3 ALTER COLUMN col2 DROP NOT NULL;
|
||||
CREATE UNIQUE INDEX t3_ukey ON t3 (col2, col3);
|
||||
|
||||
--- column referenced by unique key are not allowed to update
|
||||
INSERT INTO t3 VALUES (1, 1) ON DUPLICATE KEY UPDATE col3 = 3;
|
||||
|
||||
--- should insert cause not contains unique key and not all unique key referred columns have default value.
|
||||
INSERT INTO t3 (col1) VALUES (1) ON DUPLICATE KEY UPDATE col1 = 2;
|
||||
INSERT INTO t3 (col1) VALUES (1) ON DUPLICATE KEY UPDATE col1 = 2;
|
||||
SELECT * FROM t3 order by col5;
|
||||
|
||||
--- should insert
|
||||
INSERT INTO t3 VALUES (1, 1) ON DUPLICATE KEY UPDATE col1 = 10;
|
||||
INSERT INTO t3 VALUES (2, 2, 2) ON DUPLICATE KEY UPDATE t3.col5 = 20;
|
||||
SELECT * FROM t3 ORDER BY col5;
|
||||
|
||||
--- should update
|
||||
INSERT INTO t3 VALUES (1, 1) ON DUPLICATE KEY UPDATE t3.col1 = 10;
|
||||
INSERT INTO t3 VALUES (2, 2, 2) ON DUPLICATE KEY UPDATE col5 = 20;
|
||||
SELECT * FROM t3 ORDER BY col5;
|
||||
|
||||
--- test subquery
|
||||
---- should insert
|
||||
INSERT INTO t3 (SELECT 100, NULL, max(col3) FROM t3) ON DUPLICATE KEY UPDATE col1 = col2 + col3;
|
||||
INSERT INTO t3 (SELECT 100, NULL, max(col3) FROM t3) ON DUPLICATE KEY UPDATE col1 = col2 + col3;
|
||||
INSERT INTO t3 (col2, col3) (SELECT max(col2) + 1, max(col3) + 1 FROM t3) ON DUPLICATE KEY UPDATE col1 = col2 + col3;
|
||||
SELECT * FROM t3 ORDER BY col5;
|
||||
|
||||
---- should update
|
||||
INSERT INTO t3 (col2, col3) (SELECT max(col2), max(col3) FROM t3) ON DUPLICATE KEY UPDATE col1 = col2 + col3;
|
||||
SELECT * FROM t3 ORDER BY col5;
|
||||
|
||||
RESET enable_light_proxy;
|
||||
DROP SCHEMA test_insert_update_009 CASCADE;
|
||||
|
|
@ -0,0 +1,144 @@
|
|||
DROP SCHEMA test_insert_update_010 CASCADE;
|
||||
CREATE SCHEMA test_insert_update_010;
|
||||
SET CURRENT_SCHEMA TO test_insert_update_010;
|
||||
|
||||
-- enable_upsert_to_merge must is off, or upsert will be translated to merge.
|
||||
SET enable_upsert_to_merge TO OFF;
|
||||
|
||||
-- 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)
|
||||
) ;
|
||||
|
||||
--- 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;
|
||||
|
||||
--- 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;
|
||||
|
||||
--- 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;
|
||||
INSERT INTO t4 (col1, col5)
|
||||
(SELECT col3, sum(col3) * 10 FROM t4 GROUP BY col3)
|
||||
ON DUPLICATE KEY UPDATE col1 = 3;
|
||||
|
||||
-- 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
|
||||
) ;
|
||||
|
||||
-- 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;
|
||||
|
||||
--- 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;
|
||||
|
||||
--- should some insert some update
|
||||
INSERT INTO t5 (col1, col3) VALUES (2, 5), (2, 6);
|
||||
SELECT col1, col2, col3 FROM t5 ORDER BY col3;
|
||||
INSERT INTO t5 (col1) VALUES (2), (2), (2) ON DUPLICATE KEY UPDATE col2 = col3;
|
||||
SELECT col1, col2, col3 FROM t5 ORDER BY col3;
|
||||
|
||||
--- should INSERT and sequence starting from 7
|
||||
INSERT INTO t5 VALUES (2), (2);
|
||||
SELECT col1, col2, col3 FROM t5 ORDER BY col3;
|
||||
|
||||
-- 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;
|
||||
|
||||
--- 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;
|
||||
|
||||
--- 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;
|
||||
|
||||
---- should update
|
||||
INSERT INTO t5 SELECT * FROM t5 ON DUPLICATE KEY UPDATE col2 = col5 * 1000;
|
||||
SELECT * FROM t5 ORDER BY col3;
|
||||
|
||||
-- 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
|
||||
) ;
|
||||
|
||||
ALTER TABLE t6 ADD PRIMARY KEY (col1, col3);
|
||||
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;
|
||||
|
||||
--- 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;
|
||||
|
||||
--- 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;
|
||||
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;
|
||||
|
||||
--- 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;
|
||||
|
||||
--- 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;
|
||||
|
||||
--- 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;
|
||||
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;
|
||||
|
||||
DROP SCHEMA test_insert_update_010 CASCADE;
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
\c upsert
|
||||
DROP SCHEMA upsert_test CASCADE;
|
||||
DROP SCHEMA upsert_test_unlog CASCADE;
|
||||
|
|
@ -0,0 +1,146 @@
|
|||
--------------------------------------------------------------------------------------------
|
||||
/*
|
||||
* procedure
|
||||
*/
|
||||
--------------------------------------------------------------------------------------------
|
||||
\c upsert;
|
||||
SET CURRENT_SCHEMA TO upsert_test_procedure;
|
||||
-- enable_upsert_to_merge must be off, or upsert will be translated to merge.
|
||||
SET enable_upsert_to_merge TO OFF;
|
||||
SHOW enable_upsert_to_merge;
|
||||
|
||||
drop table IF EXISTS t_proc;
|
||||
create table t_proc(c1 int, c2 int, c3 int unique);
|
||||
insert into t_proc select a,a,a from generate_series(1,20) as a;
|
||||
select *from t_proc order by c3;
|
||||
|
||||
create or replace procedure mul_ups( c in INTEGER)
|
||||
as
|
||||
declare
|
||||
val int;
|
||||
begin
|
||||
for val in select c3 from t_proc loop
|
||||
insert into t_proc values(c,c, val) on duplicate key update c1 = c, c2 =c;
|
||||
end loop;
|
||||
end;
|
||||
/
|
||||
|
||||
call mul_ups(100);
|
||||
select *from t_proc order by c3;
|
||||
|
||||
create or replace procedure mul_ups( c in INTEGER)
|
||||
as
|
||||
declare
|
||||
val int;
|
||||
begin
|
||||
for val in select c3 from t_proc loop
|
||||
insert into t_proc values(c,c, val) on duplicate key update c1 = $1, c2 =$1;
|
||||
end loop;
|
||||
end;
|
||||
/
|
||||
|
||||
call mul_ups(200);
|
||||
select *from t_proc order by c3;
|
||||
|
||||
create or replace procedure mul_ups_00()
|
||||
as
|
||||
declare
|
||||
val int;
|
||||
begin
|
||||
for val in select c3 from t_proc loop
|
||||
insert into t_proc values(val,val,val) on duplicate key update c1 = 300, c2 =300;
|
||||
end loop;
|
||||
end;
|
||||
/
|
||||
|
||||
call mul_ups_00();
|
||||
select *from t_proc order by c3;
|
||||
|
||||
declare
|
||||
val int;
|
||||
c int :=400;
|
||||
begin
|
||||
for val in select c3 from t_proc loop
|
||||
insert into t_proc values(c,c, val) on duplicate key update c1 = c, c2 =c;
|
||||
end loop;
|
||||
end;
|
||||
/
|
||||
select *from t_proc order by c3;
|
||||
|
||||
create or replace procedure mul_ups( c in INTEGER)
|
||||
as
|
||||
declare
|
||||
val int;
|
||||
begin
|
||||
for val in select c3 from t_proc loop
|
||||
insert into t_proc values(c,c, val+100) on duplicate key update c1 = $1, c2 =$1;
|
||||
end loop;
|
||||
end;
|
||||
/
|
||||
|
||||
call mul_ups(500);
|
||||
select *from t_proc order by c3;
|
||||
|
||||
/*
|
||||
* insert
|
||||
*/
|
||||
drop table if exists t_default;
|
||||
CREATE TABLE t_default (c1 INT PRIMARY KEY DEFAULT 10, c2 FLOAT DEFAULT 3.0, c3 TIMESTAMP DEFAULT '20200508');
|
||||
create view v_default as select *from t_default order by c1;
|
||||
|
||||
-- insert src
|
||||
---- insert values
|
||||
truncate t_default;
|
||||
insert into t_default values(DEFAULT, DEFAULT, DEFAULT);
|
||||
insert into t_default values(1, 2, '20200630');
|
||||
select *from t_default order by c1;
|
||||
|
||||
insert into t_default values(DEFAULT, DEFAULT, DEFAULT) on duplicate key update c2 = 1;
|
||||
select *from t_default order by c1;
|
||||
|
||||
insert into t_default values(1, 2, '20200630') on duplicate key update c2 = 2;
|
||||
select *from t_default order by c1;
|
||||
|
||||
insert into t_default values(DEFAULT, DEFAULT, DEFAULT),(1, 2, '20200630') on duplicate key update c2 = 3;
|
||||
select *from t_default order by c1;
|
||||
|
||||
---- insert subquery
|
||||
insert into t_default select *from t_default order by c1 on duplicate key update c2 = 4;
|
||||
select *from t_default order by c1;
|
||||
|
||||
insert into t_default select *from t_default order by c1 limit 1 on duplicate key update c2 = 5;
|
||||
select *from t_default order by c1;
|
||||
|
||||
insert into t_default select *from t_default where c1=10 on duplicate key update c2 = 6;
|
||||
select *from t_default order by c1;
|
||||
|
||||
insert into t_default select *from t_default order by c1 on duplicate key update c2 = 7;
|
||||
select *from t_default order by c1;
|
||||
|
||||
insert into t_default select *from v_default order by c1 on duplicate key update c2 = 8;
|
||||
select *from t_default order by c1;
|
||||
|
||||
insert into t_default select *from t_default union select c1+1,c2+1,c3+1 from t_default order by c1 on duplicate key update c2 = 9;
|
||||
select *from t_default order by c1;
|
||||
|
||||
insert into t_default(c1,c2) select max(c1),c2 from t_default group by c2 on duplicate key update c2 = 10;
|
||||
|
||||
-- index
|
||||
---- mul index
|
||||
truncate t_default;
|
||||
create unique index t_default_mul on t_default(c1,c3);
|
||||
insert into t_default values(DEFAULT, DEFAULT, DEFAULT);
|
||||
insert into t_default values(1, 2, '20200630');
|
||||
select *from t_default order by c1;
|
||||
|
||||
insert into t_default values(DEFAULT, DEFAULT, DEFAULT) on duplicate key update c2 = 1;
|
||||
select *from t_default order by c1;
|
||||
|
||||
insert into t_default values(1, 2, '20200630') on duplicate key update c2 = 2;
|
||||
select *from t_default order by c1;
|
||||
|
||||
insert into t_default values(DEFAULT, DEFAULT, DEFAULT),(1, 2, '20200630') on duplicate key update c2 = 3;
|
||||
select *from t_default order by c1;
|
||||
|
||||
insert into t_default select *from t_default on duplicate key update c2 = 4;
|
||||
select *from t_default order by c1;
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
--------------------------------------------------------------------------------------------
|
||||
/*
|
||||
* explain upsert
|
||||
*/
|
||||
--------------------------------------------------------------------------------------------
|
||||
\c upsert;
|
||||
SET CURRENT_SCHEMA TO upsert_test_explain;
|
||||
-- enable_upsert_to_merge must be off, or upsert will be translated to merge.
|
||||
SET enable_upsert_to_merge TO OFF;
|
||||
SHOW enable_upsert_to_merge;
|
||||
|
||||
create temp table up_expl_temp(c1 int, c2 int, c3 int unique) ;
|
||||
|
||||
|
||||
insert into up_expl_hash select a,a,a from generate_series(1,20) as a;
|
||||
insert into up_expl_repl select a,a,a from generate_series(1,20) as a;
|
||||
insert into up_expl_part select a,a,a from generate_series(1,20) as a;
|
||||
insert into up_expl_temp select a,a,a from generate_series(1,20) as a;
|
||||
insert into up_expl_unlog select a,a,a from generate_series(1,20) as a;
|
||||
insert into up_expl_node select a,a,a from generate_series(1,20) as a;
|
||||
insert into up_expl_repl2 select a,a,a,a,a from generate_series(1,20) as a;
|
||||
|
||||
EXPLAIN (VERBOSE on, COSTS off, TIMING off) insert into up_expl_hash values(1,1,1) on duplicate key update c1 = 2;
|
||||
EXPLAIN (ANALYZE on, COSTS off, TIMING off) insert into up_expl_hash values(1,1,1) on duplicate key update c1 = 2;
|
||||
EXPLAIN PERFORMANCE insert into up_expl_hash values(1,1,1) on duplicate key update c1 = 2;
|
||||
|
||||
EXPLAIN (VERBOSE on, COSTS off, TIMING off) insert into up_expl_hash values(1,1,1),(2,2,2)on duplicate key update c1 = 2;
|
||||
EXPLAIN (ANALYZE on, COSTS off, TIMING off) insert into up_expl_hash values(1,1,1),(2,2,2)on duplicate key update c1 = 2;
|
||||
|
||||
EXPLAIN (VERBOSE on, COSTS off, TIMING off) insert into up_expl_repl values(1,1,1) on duplicate key update c1 = 2;
|
||||
EXPLAIN (ANALYZE on, COSTS off, TIMING off) insert into up_expl_repl values(1,1,1) on duplicate key update c1 = 2;
|
||||
|
||||
EXPLAIN (VERBOSE on, COSTS off, TIMING off) insert into up_expl_part values(1,1,1) on duplicate key update c1 = 2;
|
||||
EXPLAIN (ANALYZE on, COSTS off, TIMING off) insert into up_expl_part values(1,1,1) on duplicate key update c1 = 2;
|
||||
|
||||
EXPLAIN (VERBOSE on, COSTS off, TIMING off) insert into up_expl_temp values(1,1,1) on duplicate key update c1 = 2;
|
||||
EXPLAIN (ANALYZE on, COSTS off, TIMING off) insert into up_expl_temp values(1,1,1) on duplicate key update c1 = 2;
|
||||
|
||||
EXPLAIN (VERBOSE on, COSTS off, TIMING off) insert into up_expl_unlog values(1,1,1) on duplicate key update c1 = 2;
|
||||
EXPLAIN (ANALYZE on, COSTS off, TIMING off) insert into up_expl_unlog values(1,1,1) on duplicate key update c1 = 2;
|
||||
|
||||
EXPLAIN (VERBOSE on, COSTS off, TIMING off) insert into up_expl_node values(1,1,1) on duplicate key update c1 = 2;
|
||||
EXPLAIN (ANALYZE on, COSTS off, TIMING off) insert into up_expl_node values(1,1,1) on duplicate key update c1 = 2;
|
||||
|
||||
|
||||
EXPLAIN (VERBOSE on, COSTS off, TIMING off) insert into up_expl_hash values(1,1,1),(2,2,2)on duplicate key update nothing;
|
||||
EXPLAIN (ANALYZE on, COSTS off, TIMING off) insert into up_expl_hash values(1,1,1),(2,2,2)on duplicate key update nothing;
|
||||
|
||||
EXPLAIN (VERBOSE on, COSTS off, TIMING off) insert into up_expl_repl values(1,1,1) on duplicate key update nothing;
|
||||
EXPLAIN (ANALYZE on, COSTS off, TIMING off) insert into up_expl_repl values(1,1,1) on duplicate key update nothing;
|
||||
|
||||
EXPLAIN (VERBOSE on, COSTS off, TIMING off) insert into up_expl_part values(1,1,1) on duplicate key update nothing;
|
||||
EXPLAIN (ANALYZE on, COSTS off, TIMING off) insert into up_expl_part values(1,1,1) on duplicate key update nothing;
|
||||
|
||||
EXPLAIN (VERBOSE on, COSTS off, TIMING off) insert into up_expl_temp values(1,1,1) on duplicate key update nothing;
|
||||
EXPLAIN (ANALYZE on, COSTS off, TIMING off) insert into up_expl_temp values(1,1,1) on duplicate key update nothing;
|
||||
|
||||
EXPLAIN (VERBOSE on, COSTS off, TIMING off) insert into up_expl_unlog values(1,1,1) on duplicate key update nothing;
|
||||
EXPLAIN (ANALYZE on, COSTS off, TIMING off) insert into up_expl_unlog values(1,1,1) on duplicate key update nothing;
|
||||
|
||||
EXPLAIN (VERBOSE on, COSTS off, TIMING off) insert into up_expl_node values(1,1,1) on duplicate key update nothing;
|
||||
EXPLAIN (ANALYZE on, COSTS off, TIMING off) insert into up_expl_node values(1,1,1) on duplicate key update nothing;
|
||||
|
||||
|
|
@ -0,0 +1,113 @@
|
|||
\c upsert
|
||||
SET CURRENT_SCHEMA TO upsert_test;
|
||||
-- enable_upsert_to_merge must be off, or upsert will be translated to merge.
|
||||
SET enable_upsert_to_merge TO OFF;
|
||||
SHOW enable_upsert_to_merge;
|
||||
|
||||
-- support multiple set
|
||||
INSERT INTO t_grammer VALUES(11, 1) ON DUPLICATE KEY UPDATE c2 = 2, c4 = ROW(10, 20), c3 = '{10, 20, 30}';
|
||||
INSERT INTO t_grammer VALUES(12, 2) ON DUPLICATE KEY UPDATE c2 = 2, c3[1] = 3;
|
||||
|
||||
-- support const value and expr
|
||||
INSERT INTO t_grammer VALUES(23) ON DUPLICATE KEY UPDATE c2 = 2;
|
||||
INSERT INTO t_grammer VALUES(24) ON DUPLICATE KEY UPDATE c2 = length('test') + 100;
|
||||
|
||||
-- support without table name
|
||||
INSERT INTO t_grammer VALUES(31, 1) ON DUPLICATE KEY UPDATE c2 = c1, c4.a = VALUES(c1);
|
||||
INSERT INTO t_grammer VALUES(32, 2) ON DUPLICATE KEY UPDATE c2 = c1 + 5, c4.a = VALUES(c1);
|
||||
|
||||
-- support with table name
|
||||
INSERT INTO t_grammer VALUES(41, 1) ON DUPLICATE KEY UPDATE c2 = t_grammer.c1, c4.a = VALUES(c1);
|
||||
INSERT INTO t_grammer VALUES(42, 2) ON DUPLICATE KEY UPDATE c2 = t_grammer.c1 + 5, c4.a = VALUES(c1);
|
||||
|
||||
-- support EXCLUDED alone and with expr
|
||||
INSERT INTO t_grammer VALUES(51, 1) ON DUPLICATE KEY UPDATE c2 = c1 + 5, c4.a = EXCLUDED.c1;
|
||||
INSERT INTO t_grammer VALUES(52, 2) ON DUPLICATE KEY UPDATE c2 = t_grammer.c1 + 5, c4.a = EXCLUDED.c1 + 5;
|
||||
INSERT INTO t_grammer VALUES(53, 3) ON DUPLICATE KEY UPDATE c4.a = sqrt(EXCLUDED.c1 - EXCLUDED.c2 - 1) + 1, c2 = t_grammer.c1 + 5;
|
||||
INSERT INTO t_grammer VALUES(54, 4) ON DUPLICATE KEY UPDATE c4.b = EXCLUDED.c1 + t_grammer.c1;
|
||||
INSERT INTO t_grammer VALUES(55, 5) ON DUPLICATE KEY UPDATE c4.a = EXCLUDED.c2, c4.b = EXCLUDED.c1 + sqrt(c1 - 6);
|
||||
|
||||
-- support ARRAY
|
||||
INSERT INTO t_grammer VALUES(61, 1) ON DUPLICATE KEY UPDATE c2 = VALUES(c3[1]);
|
||||
INSERT INTO t_grammer VALUES(62, 2) ON DUPLICATE KEY UPDATE c5 = VALUES(c3[2,3]);
|
||||
INSERT INTO t_grammer VALUES(63, 3) ON DUPLICATE KEY UPDATE c5 = VALUES(c3[2:3]);
|
||||
INSERT INTO t_grammer VALUES(64, 4, '{10, 20, 30}') ON DUPLICATE KEY UPDATE c2 = EXCLUDED.c3[1];
|
||||
INSERT INTO t_grammer VALUES(65, 5, '{10, 20, 30}') ON DUPLICATE KEY UPDATE c5 = EXCLUDED.c3[2,3];
|
||||
INSERT INTO t_grammer VALUES(66, 6, '{10, 20, 30}') ON DUPLICATE KEY UPDATE c5 = EXCLUDED.c3[1:2];
|
||||
INSERT INTO t_grammer VALUES(67, 7, '{10, 20, 30}') ON DUPLICATE KEY UPDATE c2 = c3[1];
|
||||
INSERT INTO t_grammer VALUES(68, 8, '{10, 20, 30}') ON DUPLICATE KEY UPDATE c5 = c3[2,3];
|
||||
INSERT INTO t_grammer VALUES(69, 9, '{10, 20, 30}') ON DUPLICATE KEY UPDATE c5 = c3[1:2];
|
||||
|
||||
-- support user defined type
|
||||
INSERT INTO t_grammer VALUES(71, 1) ON DUPLICATE KEY UPDATE c4.a = c3[1] + c1;
|
||||
INSERT INTO t_grammer VALUES(72, 2, '{71, 72, 73}') ON DUPLICATE KEY UPDATE c4.a = c3[1] + c1;
|
||||
INSERT INTO t_grammer VALUES(73, 3, '{71, 72, 73}') ON DUPLICATE KEY UPDATE c4.a = c3[1] + c1, c4.b = c3[2];
|
||||
INSERT INTO t_grammer VALUES(74, 4, '{71, 72, 73}', ROW(74, 75)) ON DUPLICATE KEY UPDATE c4 = ROW(740, 750);
|
||||
|
||||
-- appoint INSERT target column
|
||||
INSERT INTO t_grammer (c5, c1, c2) VALUES('{81,82}', 81, DEFAULT) ON DUPLICATE KEY UPDATE c2 = VALUES(c1);
|
||||
INSERT INTO t_grammer (c3[1], c3[2], c1) VALUES(881, 882, 82) ON DUPLICATE KEY UPDATE c5 = VALUES(c3), c2 = VALUES(c3[1]);
|
||||
INSERT INTO t_grammer (c1, c3, c4) VALUES(83, '{81, 82, 83}', ROW(810, 820)) ON DUPLICATE KEY UPDATE c4 = EXCLUDED.c4;
|
||||
INSERT INTO t_grammer (c1, c3, c4.a) VALUES(84, '{81, 82, 83}', 850) ON DUPLICATE KEY UPDATE c4.b = c3[3];
|
||||
|
||||
-- support UPDATE NOTHING
|
||||
INSERT INTO t_grammer VALUES(91, 1, '{91, 92, 93}', ROW(94, 95)) ON DUPLICATE KEY UPDATE NOTHING;
|
||||
INSERT INTO t_grammer (c5, c1, c2, c4) VALUES('{91,92}', 92, DEFAULT, ROW(910, 920)) ON DUPLICATE KEY UPDATE NOTHING;
|
||||
|
||||
-- UPDATE target: unsupport with schema but support with tablename
|
||||
INSERT INTO t_grammer VALUES(0, 0, '{0,0}', ROW(0, 0), '{107, 108}') ON DUPLICATE KEY UPDATE
|
||||
upsert_test.t_grammer.c2 = c2 * 10, upsert_test.t_grammer.c3[1:2] = c5[1:2], upsert_test.t_grammer.c4.a = c1;
|
||||
INSERT INTO t_grammer VALUES(101, 1, '{102, 103, 104}', ROW(105, 106), '{107, 108}') ON DUPLICATE KEY UPDATE
|
||||
t_grammer.c2 = c2 * 10, t_grammer.c3[1:2] = c5[1:2], t_grammer.c4.a = c1;
|
||||
|
||||
-- INSERT target: appoint schema
|
||||
INSERT INTO upsert_test.t_grammer VALUES(102, 2, '{102, 103, 104}', ROW(105, 106), '{107, 108}') ON DUPLICATE KEY UPDATE
|
||||
t_grammer.c2 = EXCLUDED.c2 * 10, t_grammer.c3[1:2] = c5[1:2], t_grammer.c4.a = VALUES(c1);
|
||||
CREATE SCHEMA upsert_test_tmpschema;
|
||||
SET CURRENT_SCHEMA TO upsert_test_tmpschema;
|
||||
INSERT INTO upsert_test.t_grammer VALUES(103, 3, '{102, 103, 104}', ROW(105, 106), '{107, 108}') ON DUPLICATE KEY UPDATE
|
||||
t_grammer.c2 = EXCLUDED.c2 * 10, t_grammer.c3[1:2] = c5[1:2], t_grammer.c4.a = VALUES(c1);
|
||||
SET CURRENT_SCHEMA TO upsert_test;
|
||||
DROP SCHEMA upsert_test_tmpschema;
|
||||
|
||||
-- support data type
|
||||
INSERT INTO t_data VALUES(11, 11, 11, 11, 11, '11', '11', '11', '2020-04-23', '2020-04-23 11:00', '1:00') ON DUPLICATE KEY UPDATE NOTHING;
|
||||
INSERT INTO t_data VALUES(12, 12, 12, 12, 12, '12', '12', '12', '2020-04-24', '2020-04-24 11:00', '2:00')
|
||||
ON DUPLICATE KEY UPDATE
|
||||
c_tiny = 13, c_smallint = 13, c_bigint = 13, c_numeric = 13,
|
||||
c_var = '13', c_text = '13', c_bytea = '13', c_date = '2020-05-24', c_timestamp = '2020-05-24 11:00', c_time = '3:00';
|
||||
INSERT INTO t_data VALUES(13, 13, 13, 13, 13, '13', '13', '13', '2020-04-25', '2020-04-25 11:00', '4:00')
|
||||
ON DUPLICATE KEY UPDATE
|
||||
c_tiny = EXCLUDED.c_tiny + 1, c_smallint = EXCLUDED.c_smallint + 1, c_bigint = EXCLUDED.c_bigint + 1, c_numeric = EXCLUDED.c_numeric + 1,
|
||||
c_var = EXCLUDED.c_var || '3', c_text = EXCLUDED.c_text || '3', c_bytea = EXCLUDED.c_bytea || '3',
|
||||
c_date = EXCLUDED.c_date + '1 day'::interval, c_timestamp = EXCLUDED.c_timestamp + '1 day'::interval, c_time = EXCLUDED.c_time + '1 hour'::interval;
|
||||
|
||||
-- support UPDATE to default
|
||||
INSERT INTO t_default DEFAULT VALUES ON DUPLICATE KEY UPDATE c2 = 100, c3 = '2020-05-17';
|
||||
INSERT INTO t_default VALUES(91, 0.91, '2020-05-17') ON DUPLICATE KEY UPDATE c2 = DEFAULT, c3 = DEFAULT;
|
||||
INSERT INTO t_default VALUES(92, DEFAULT, '2020-05-17') ON DUPLICATE KEY UPDATE c2 = 10, c3 = DEFAULT;
|
||||
|
||||
-- unsupport alias
|
||||
INSERT INTO t_grammer AS alias VALUES (91) ON DUPLICATE KEY UPDATE c2 = VALUES(c1);
|
||||
|
||||
-- unsupport VALUES with expr
|
||||
INSERT INTO t_grammer VALUES(0, 0) ON DUPLICATE KEY UPDATE c2 = sqrt(VALUES(c2));
|
||||
INSERT INTO t_grammer VALUES(0, 0) ON DUPLICATE KEY UPDATE c2 = VALUES(c3[1]) + 1;
|
||||
INSERT INTO t_grammer VALUES(0, 0) ON DUPLICATE KEY UPDATE c2 = VALUES(c4.a) + 1;
|
||||
INSERT INTO t_grammer VALUES(0, 0) ON DUPLICATE KEY UPDATE c2 = VALUES(t_grammer.c3[1]) + 1;
|
||||
|
||||
-- unsupport VALUES with table name
|
||||
INSERT INTO t_grammer VALUES(0, 0) ON DUPLICATE KEY UPDATE c2 = VALUES(t_grammer.c4.a);
|
||||
INSERT INTO t_grammer VALUES(0, 0) ON DUPLICATE KEY UPDATE c2 = VALUES(t_grammer.c2);
|
||||
|
||||
-- unsupport DEFAULT with expr
|
||||
INSERT INTO t_grammer VALUES(0, 0) ON DUPLICATE KEY UPDATE c2 = DEFAULT + 1;
|
||||
|
||||
-- unsupport user defined typed column's element
|
||||
INSERT INTO t_grammer VALUES(0, 0) ON DUPLICATE KEY UPDATE c2 = VALUES(c4.a);
|
||||
INSERT INTO t_grammer VALUES(0, 0) ON DUPLICATE KEY UPDATE c2 = EXCLUDED.c4.a;
|
||||
INSERT INTO t_grammer VALUES(0, 0) ON DUPLICATE KEY UPDATE c2 = c4.a;
|
||||
|
||||
SELECT * FROM t_data ORDER BY 1;
|
||||
SELECT * FROM t_grammer ORDER BY 1;
|
||||
SELECT * FROM t_default ORDER BY 1;
|
||||
|
|
@ -0,0 +1,113 @@
|
|||
\c upsert
|
||||
SET CURRENT_SCHEMA TO upsert_test;
|
||||
-- enable_upsert_to_merge must be off, or upsert will be translated to merge.
|
||||
SET enable_upsert_to_merge TO OFF;
|
||||
SHOW enable_upsert_to_merge;
|
||||
|
||||
-- support multiple set
|
||||
INSERT INTO t_grammer VALUES(11, 1) ON DUPLICATE KEY UPDATE c2 = 2, c4 = ROW(10, 20), c3 = '{10, 20, 30}';
|
||||
INSERT INTO t_grammer VALUES(12, 2) ON DUPLICATE KEY UPDATE c2 = 2, c3[1] = 3;
|
||||
|
||||
-- support const value and expr
|
||||
INSERT INTO t_grammer VALUES(23) ON DUPLICATE KEY UPDATE c2 = 2;
|
||||
INSERT INTO t_grammer VALUES(24) ON DUPLICATE KEY UPDATE c2 = length('test') + 100;
|
||||
|
||||
-- support without table name
|
||||
INSERT INTO t_grammer VALUES(31, 1) ON DUPLICATE KEY UPDATE c2 = c1, c4.a = VALUES(c1);
|
||||
INSERT INTO t_grammer VALUES(32, 2) ON DUPLICATE KEY UPDATE c2 = c1 + 5, c4.a = VALUES(c1);
|
||||
|
||||
-- support with table name
|
||||
INSERT INTO t_grammer VALUES(41, 1) ON DUPLICATE KEY UPDATE c2 = t_grammer.c1, c4.a = VALUES(c1);
|
||||
INSERT INTO t_grammer VALUES(42, 2) ON DUPLICATE KEY UPDATE c2 = t_grammer.c1 + 5, c4.a = VALUES(c1);
|
||||
|
||||
-- support EXCLUDED alone and with expr
|
||||
INSERT INTO t_grammer VALUES(51, 1) ON DUPLICATE KEY UPDATE c2 = c1 + 5, c4.a = EXCLUDED.c1;
|
||||
INSERT INTO t_grammer VALUES(52, 2) ON DUPLICATE KEY UPDATE c2 = t_grammer.c1 + 5, c4.a = EXCLUDED.c1 + 5;
|
||||
INSERT INTO t_grammer VALUES(53, 3) ON DUPLICATE KEY UPDATE c4.a = sqrt(EXCLUDED.c1 - EXCLUDED.c2 - 1) + 1, c2 = t_grammer.c1 + 5;
|
||||
INSERT INTO t_grammer VALUES(54, 4) ON DUPLICATE KEY UPDATE c4.b = EXCLUDED.c1 + t_grammer.c1;
|
||||
INSERT INTO t_grammer VALUES(55, 5) ON DUPLICATE KEY UPDATE c4.a = EXCLUDED.c2, c4.b = EXCLUDED.c1 + sqrt(c1 - 6);
|
||||
|
||||
-- support ARRAY
|
||||
INSERT INTO t_grammer VALUES(61, 1) ON DUPLICATE KEY UPDATE c2 = VALUES(c3[1]);
|
||||
INSERT INTO t_grammer VALUES(62, 2) ON DUPLICATE KEY UPDATE c5 = VALUES(c3[2,3]);
|
||||
INSERT INTO t_grammer VALUES(63, 3) ON DUPLICATE KEY UPDATE c5 = VALUES(c3[2:3]);
|
||||
INSERT INTO t_grammer VALUES(64, 4, '{10, 20, 30}') ON DUPLICATE KEY UPDATE c2 = EXCLUDED.c3[1];
|
||||
INSERT INTO t_grammer VALUES(65, 5, '{10, 20, 30}') ON DUPLICATE KEY UPDATE c5 = EXCLUDED.c3[2,3];
|
||||
INSERT INTO t_grammer VALUES(66, 6, '{10, 20, 30}') ON DUPLICATE KEY UPDATE c5 = EXCLUDED.c3[1:2];
|
||||
INSERT INTO t_grammer VALUES(67, 7, '{10, 20, 30}') ON DUPLICATE KEY UPDATE c2 = c3[1];
|
||||
INSERT INTO t_grammer VALUES(68, 8, '{10, 20, 30}') ON DUPLICATE KEY UPDATE c5 = c3[2,3];
|
||||
INSERT INTO t_grammer VALUES(69, 9, '{10, 20, 30}') ON DUPLICATE KEY UPDATE c5 = c3[1:2];
|
||||
|
||||
-- support user defined type
|
||||
INSERT INTO t_grammer VALUES(71, 1) ON DUPLICATE KEY UPDATE c4.a = c3[1] + c1;
|
||||
INSERT INTO t_grammer VALUES(72, 2, '{71, 72, 73}') ON DUPLICATE KEY UPDATE c4.a = c3[1] + c1;
|
||||
INSERT INTO t_grammer VALUES(73, 3, '{71, 72, 73}') ON DUPLICATE KEY UPDATE c4.a = c3[1] + c1, c4.b = c3[2];
|
||||
INSERT INTO t_grammer VALUES(74, 4, '{71, 72, 73}', ROW(74, 75)) ON DUPLICATE KEY UPDATE c4 = ROW(740, 750);
|
||||
|
||||
-- appoint INSERT target column
|
||||
INSERT INTO t_grammer (c5, c1, c2) VALUES('{81,82}', 81, DEFAULT) ON DUPLICATE KEY UPDATE c2 = VALUES(c1);
|
||||
INSERT INTO t_grammer (c3[1], c3[2], c1) VALUES(881, 882, 82) ON DUPLICATE KEY UPDATE c5 = VALUES(c3), c2 = VALUES(c3[1]);
|
||||
INSERT INTO t_grammer (c1, c3, c4) VALUES(83, '{81, 82, 83}', ROW(810, 820)) ON DUPLICATE KEY UPDATE c4 = EXCLUDED.c4;
|
||||
INSERT INTO t_grammer (c1, c3, c4.a) VALUES(84, '{81, 82, 83}', 850) ON DUPLICATE KEY UPDATE c4.b = c3[3];
|
||||
|
||||
-- support UPDATE NOTHING
|
||||
INSERT INTO t_grammer VALUES(91, 1, '{91, 92, 93}', ROW(94, 95)) ON DUPLICATE KEY UPDATE NOTHING;
|
||||
INSERT INTO t_grammer (c5, c1, c2, c4) VALUES('{91,92}', 92, DEFAULT, ROW(910, 920)) ON DUPLICATE KEY UPDATE NOTHING;
|
||||
|
||||
-- UPDATE target: unsupport with schema but support with tablename
|
||||
INSERT INTO t_grammer VALUES(0, 0, '{0,0}', ROW(0, 0), '{107, 108}') ON DUPLICATE KEY UPDATE
|
||||
upsert_test.t_grammer.c2 = c2 * 10, upsert_test.t_grammer.c3[1:2] = c5[1:2], upsert_test.t_grammer.c4.a = c1;
|
||||
INSERT INTO t_grammer VALUES(101, 1, '{102, 103, 104}', ROW(105, 106), '{107, 108}') ON DUPLICATE KEY UPDATE
|
||||
t_grammer.c2 = c2 * 10, t_grammer.c3[1:2] = c5[1:2], t_grammer.c4.a = c1;
|
||||
|
||||
-- INSERT target: appoint schema
|
||||
INSERT INTO upsert_test.t_grammer VALUES(102, 2, '{102, 103, 104}', ROW(105, 106), '{107, 108}') ON DUPLICATE KEY UPDATE
|
||||
t_grammer.c2 = EXCLUDED.c2 * 10, t_grammer.c3[1:2] = c5[1:2], t_grammer.c4.a = VALUES(c1);
|
||||
CREATE SCHEMA upsert_test_tmp;
|
||||
SET CURRENT_SCHEMA TO upsert_test_tmp;
|
||||
INSERT INTO upsert_test.t_grammer VALUES(103, 3, '{102, 103, 104}', ROW(105, 106), '{107, 108}') ON DUPLICATE KEY UPDATE
|
||||
t_grammer.c2 = EXCLUDED.c2 * 10, t_grammer.c3[1:2] = c5[1:2], t_grammer.c4.a = VALUES(c1);
|
||||
SET CURRENT_SCHEMA TO upsert_test;
|
||||
DROP SCHEMA upsert_test_tmp;
|
||||
|
||||
-- support data type
|
||||
INSERT INTO t_data VALUES(11, 11, 11, 11, 11, '11', '11', '11', '2020-04-23', '2020-04-23 11:00', '1:00') ON DUPLICATE KEY UPDATE NOTHING;
|
||||
INSERT INTO t_data VALUES(12, 12, 12, 12, 12, '12', '12', '12', '2020-04-24', '2020-04-24 11:00', '2:00')
|
||||
ON DUPLICATE KEY UPDATE
|
||||
c_tiny = 13, c_smallint = 13, c_bigint = 13, c_numeric = 13,
|
||||
c_var = '13', c_text = '13', c_bytea = '13', c_date = '2020-05-24', c_timestamp = '2020-05-24 11:00', c_time = '3:00';
|
||||
INSERT INTO t_data VALUES(13, 13, 13, 13, 13, '13', '13', '13', '2020-04-25', '2020-04-25 11:00', '4:00')
|
||||
ON DUPLICATE KEY UPDATE
|
||||
c_tiny = EXCLUDED.c_tiny + 1, c_smallint = EXCLUDED.c_smallint + 1, c_bigint = EXCLUDED.c_bigint + 1, c_numeric = EXCLUDED.c_numeric + 1,
|
||||
c_var = EXCLUDED.c_var || '3', c_text = EXCLUDED.c_text || '3', c_bytea = EXCLUDED.c_bytea || '3',
|
||||
c_date = EXCLUDED.c_date + '1 day'::interval, c_timestamp = EXCLUDED.c_timestamp + '1 day'::interval, c_time = EXCLUDED.c_time + '1 hour'::interval;
|
||||
|
||||
-- support UPDATE to default
|
||||
INSERT INTO t_default DEFAULT VALUES ON DUPLICATE KEY UPDATE c2 = 100, c3 = '2020-05-17';
|
||||
INSERT INTO t_default VALUES(91, 0.91, '2020-05-17') ON DUPLICATE KEY UPDATE c2 = DEFAULT, c3 = DEFAULT;
|
||||
INSERT INTO t_default VALUES(92, DEFAULT, '2020-05-17') ON DUPLICATE KEY UPDATE c2 = 10, c3 = DEFAULT;
|
||||
|
||||
-- unsupport alias
|
||||
INSERT INTO t_grammer AS alias VALUES (91) ON DUPLICATE KEY UPDATE c2 = VALUES(c1);
|
||||
|
||||
-- unsupport VALUES with expr
|
||||
INSERT INTO t_grammer VALUES(0, 0) ON DUPLICATE KEY UPDATE c2 = sqrt(VALUES(c2));
|
||||
INSERT INTO t_grammer VALUES(0, 0) ON DUPLICATE KEY UPDATE c2 = VALUES(c3[1]) + 1;
|
||||
INSERT INTO t_grammer VALUES(0, 0) ON DUPLICATE KEY UPDATE c2 = VALUES(c4.a) + 1;
|
||||
INSERT INTO t_grammer VALUES(0, 0) ON DUPLICATE KEY UPDATE c2 = VALUES(t_grammer.c3[1]) + 1;
|
||||
|
||||
-- unsupport VALUES with table name
|
||||
INSERT INTO t_grammer VALUES(0, 0) ON DUPLICATE KEY UPDATE c2 = VALUES(t_grammer.c4.a);
|
||||
INSERT INTO t_grammer VALUES(0, 0) ON DUPLICATE KEY UPDATE c2 = VALUES(t_grammer.c2);
|
||||
|
||||
-- unsupport DEFAULT with expr
|
||||
INSERT INTO t_grammer VALUES(0, 0) ON DUPLICATE KEY UPDATE c2 = DEFAULT + 1;
|
||||
|
||||
-- unsupport user defined typed column's element
|
||||
INSERT INTO t_grammer VALUES(0, 0) ON DUPLICATE KEY UPDATE c2 = VALUES(c4.a);
|
||||
INSERT INTO t_grammer VALUES(0, 0) ON DUPLICATE KEY UPDATE c2 = EXCLUDED.c4.a;
|
||||
INSERT INTO t_grammer VALUES(0, 0) ON DUPLICATE KEY UPDATE c2 = c4.a;
|
||||
|
||||
SELECT * FROM t_data ORDER BY 1;
|
||||
SELECT * FROM t_grammer ORDER BY 1;
|
||||
SELECT * FROM t_default ORDER BY 1;
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
-- Note: about upsert test
|
||||
-- test point:
|
||||
-- grammer
|
||||
-- table, unlogged table, temp table, matview
|
||||
-- constraint(primary key, index, foreign key, null ...)
|
||||
-- trigger
|
||||
-- sequence
|
||||
|
||||
CREATE DATABASE upsert WITH TEMPLATE template0 ENCODING 'UTF8';
|
||||
\c upsert
|
||||
|
||||
-- grammer test
|
||||
CREATE SCHEMA upsert_test;
|
||||
SET CURRENT_SCHEMA TO upsert_test;
|
||||
CREATE TYPE atype AS(a int, b int);
|
||||
CREATE TYPE btype AS(a int, b atype, c varchar[3]);
|
||||
CREATE TABLE t_grammer (c1 INT PRIMARY KEY, c2 INT DEFAULT -100, c3 int[3], c4 atype, c5 int[2]);
|
||||
CREATE TABLE t_default (c1 INT PRIMARY KEY DEFAULT 10, c2 FLOAT DEFAULT random(), c3 TIMESTAMP DEFAULT current_timestamp);
|
||||
CREATE TABLE t_data (c_int INT PRIMARY KEY, c_tiny TINYINT, c_smallint SMALLINT, c_bigint BIGINT, c_numeric NUMERIC,
|
||||
c_var VARCHAR, c_text TEXT, c_bytea BYTEA, c_date DATE, c_timestamp TIMESTAMP, c_time TIME,
|
||||
c_intarray INT[3], c_com atype);
|
||||
CREATE TABLE t_trigger (key INT PRIMARY KEY, color TEXT);
|
||||
|
||||
-- unlogged table
|
||||
CREATE SCHEMA upsert_test_unlog;
|
||||
SET CURRENT_SCHEMA TO upsert_test_unlog;
|
||||
CREATE TYPE atype AS(a int, b int);
|
||||
CREATE TYPE btype AS(a int, b atype, c varchar[3]);
|
||||
CREATE UNLOGGED TABLE t_hash_unlog_0 (c1 INT, c2 INT, c3 VARCHAR, c4 INT[3], c5 INT[5], c6 atype, c7 btype);
|
||||
CREATE UNLOGGED TABLE t_hash_unlog_1 (c1 INT, c2 INT PRIMARY KEY, c3 VARCHAR, c4 INT[3], c5 INT[5], c6 atype, c7 btype);
|
||||
CREATE UNLOGGED TABLE t_rep_unlog_0 (c1 INT, c2 INT, c3 VARCHAR, c4 INT[3], c5 INT[5], c6 atype, c7 btype) ;
|
||||
CREATE UNLOGGED TABLE t_rep_unlog_1 (c1 INT, c2 INT PRIMARY KEY, c3 VARCHAR, c4 INT[3], c5 INT[5], c6 atype, c7 btype);
|
||||
|
||||
-- temp table
|
||||
-- temp table can not be created here, we create it in upsert_tmp_test.
|
||||
|
||||
|
||||
-- restriction test
|
||||
CREATE SCHEMA upsert_test_etc;
|
||||
SET CURRENT_SCHEMA TO upsert_test_etc;
|
||||
create table up_neg_01 (c1 int, c2 int, c3 int) with (ORIENTATION = COLUMN);
|
||||
create table up_neg_02 (c1 int, c2 int, c3 int) with (ORIENTATION = COLUMN);
|
||||
create table up_neg_03 (c1 int, c2 int UNIQUE DEFERRABLE, c3 int);
|
||||
create table up_neg_04 (c1 int, c2 int UNIQUE, c3 int);
|
||||
|
||||
create table up_neg_05(c1 int, c2 int, c3 int, c4 int unique, c5 int primary key, unique(c2,c3));
|
||||
|
||||
create table up_neg_0(c1 int, c2 int, c3 int, c4 int unique, c5 int primary key, unique(c2,c3)) ;
|
||||
|
||||
create table up_neg_06(c1 int, c2 int, c3 int unique) ;
|
||||
create table up_neg_07(c1 int, c2 int, c3 int unique) ;
|
||||
create table up_neg_08(c1 int, c2 int, c3 int unique) ;
|
||||
create table up_neg_09(c1 int, c2 int, c3 int, unique(c2,c3)) ;
|
||||
create table up_neg_10(c1 int, c2 int, c3 int, unique(c2,c3)) ;
|
||||
create view up_view as select *from up_neg_01;
|
||||
create materialized view mat_view as select *from up_neg_01;
|
||||
create table pkt (a int primary key, b int, c int);
|
||||
create table fkt (a int primary key, b int references pkt, c int);
|
||||
|
||||
|
||||
-- procedure test
|
||||
CREATE SCHEMA upsert_test_procedure;
|
||||
|
||||
|
||||
-- explain test
|
||||
CREATE SCHEMA upsert_test_explain;
|
||||
SET CURRENT_SCHEMA TO upsert_test_explain;
|
||||
create table up_expl_hash(c1 int, c2 int, c3 int unique) ;
|
||||
create table up_expl_repl(c1 int, c2 int, c3 int unique) ;
|
||||
create table up_expl_part(c1 int, c2 int, c3 int unique) ;
|
||||
create unlogged table up_expl_unlog(c1 int, c2 int, c3 int unique) ;
|
||||
create table up_expl_node(c1 int, c2 int, c3 int unique) ;
|
||||
create table up_expl_repl(c1 int, c2 int, c3 int unique) ;
|
||||
create table up_expl_repl2(c1 int, c2 int, c3 int, c4 int unique, c5 int primary key, unique(c2,c3));
|
||||
-- create temp table up_expl_temp(c1 int, c2 int, c3 int unique);
|
||||
|
||||
|
|
@ -0,0 +1,170 @@
|
|||
/*
|
||||
* upsert negative test cases
|
||||
*
|
||||
table cases
|
||||
col table
|
||||
ORC table
|
||||
VIEW
|
||||
MAT view
|
||||
index
|
||||
DEFERABLE index
|
||||
insert stmt
|
||||
returning
|
||||
with
|
||||
with recur
|
||||
update stmt
|
||||
VALUES with expr
|
||||
update distribute key
|
||||
update primary key
|
||||
update unique key
|
||||
update partition key
|
||||
where clause
|
||||
with clause
|
||||
sub query
|
||||
*/
|
||||
--------------------------------------------------------------------------------------------
|
||||
\c upsert
|
||||
SET CURRENT_SCHEMA TO upsert_test_etc;
|
||||
-- enable_upsert_to_merge must be off, or upsert will be translated to merge.
|
||||
SET enable_upsert_to_merge TO OFF;
|
||||
SHOW enable_upsert_to_merge;
|
||||
|
||||
insert into up_neg_04 select a,a,a from generate_series(1,20) as a;
|
||||
insert into up_neg_05 select a,a,a,a,a from generate_series(1,20) as a;
|
||||
insert into up_neg_06 select a,a,a from generate_series(1,20) as a;
|
||||
insert into up_neg_07 select a,a,a from generate_series(1,20) as a;
|
||||
insert into up_neg_08 select a,a,a from generate_series(1,20) as a;
|
||||
insert into up_neg_09 select a,a,a from generate_series(1,20) as a;
|
||||
insert into up_neg_10 select a,a,a from generate_series(1,20) as a;
|
||||
|
||||
-- table cases
|
||||
---- col table
|
||||
insert into up_neg_01 values(1,2,3) on duplicate key update c3 = 1;
|
||||
|
||||
---- ORC table
|
||||
insert into up_neg_02 values(1,2,3) on duplicate key update c3 = 1;
|
||||
|
||||
---- VIEW
|
||||
insert into up_view values(1) on duplicate key update c3 = 1;
|
||||
|
||||
-- matview
|
||||
refresh materialized view mat_view;
|
||||
insert into mat_view values(1) on duplicate key update c3 = 1;
|
||||
|
||||
-- index
|
||||
---- DEFERABLE index
|
||||
insert into up_neg_03 values(1,2,3) on duplicate key update c1 = 1;
|
||||
insert into up_neg_03 values(1) on duplicate key update c1 = 1;
|
||||
|
||||
-- insert stmt
|
||||
----returning
|
||||
insert into up_neg_04 values(1,1,1) on duplicate key update c1 = 1 returning c1;
|
||||
----with
|
||||
with sub as (select *from up_neg_04)
|
||||
insert into up_neg_04 select *from sub on duplicate key update c1 =1;
|
||||
|
||||
----with recur
|
||||
with RECURSIVE sub as (select *from up_neg_04)
|
||||
insert into up_neg_04 select *from sub on duplicate key update c1 =1;
|
||||
|
||||
with sub as (select *from up_neg_04)
|
||||
insert into up_neg_04 select *from sub on duplicate key update c1 =1 returning c1;
|
||||
|
||||
-- update stmt
|
||||
---- VALUES with expr
|
||||
insert into up_neg_05 values(1,1,1,1) on duplicate key update c3 = values(1+100);
|
||||
insert into up_neg_05 values(1,1,1,1) on duplicate key update c3 = values(100);
|
||||
|
||||
insert into up_neg_05 values(1,1,1,1,1) on duplicate key update c1 = 1;
|
||||
---- update primary key
|
||||
insert into up_neg_05 values(1,1,1,1,1) on duplicate key update c5 = 1;
|
||||
---- update unique key
|
||||
insert into up_neg_05 values(1,1,1,1,1) on duplicate key update c4 = 1;
|
||||
insert into up_neg_05 values(1,1,1,1,1) on duplicate key update c2 = 1, c3=2;
|
||||
insert into up_neg_05 values(1,1,1,1,1) on duplicate key update c2 = 1;
|
||||
insert into up_neg_05 values(1,1,1,1,1) on duplicate key update c3 = 2;
|
||||
insert into up_neg_05 values(1,1,1,1,1) on duplicate key update c1 =1, c2 = 1, c3=2, c4=1,c5=1;
|
||||
|
||||
---- where clause
|
||||
insert into up_neg_05 values(1,1,1,1,1) on duplicate key update c4 = 1 where c1=1;
|
||||
---- from clause
|
||||
insert into up_neg_05 values(1,1,1,1,1) on duplicate key update c4 = 1 from up_neg_04 where c1=1;
|
||||
---- sub query
|
||||
insert into up_neg_05 values(1,1,1,1,1) on duplicate key update (c2) = (select c2 from up_neg_05);
|
||||
|
||||
---- update distribute key
|
||||
insert into up_neg_06 values(101, 1, 1) on duplicate key update c3=101;
|
||||
---- update partition key
|
||||
insert into up_neg_07 values(101, 1, 300) on duplicate key update c3=101;
|
||||
insert into up_neg_08 values(101, 1, 300) on duplicate key update c3=101;
|
||||
insert into up_neg_09 values(101, 1, 1) on duplicate key update c3=101;
|
||||
insert into up_neg_09 values(101, 1, 1) on duplicate key update c2=101;
|
||||
insert into up_neg_09 values(101, 1, 1) on duplicate key update c2 =1,c3=101;
|
||||
|
||||
--update unique key mul type plans
|
||||
EXPLAIN (VERBOSE on, COSTS off) insert into up_neg_10 values(101, 1, 300) on duplicate key update c1=101;
|
||||
insert into up_neg_10 values(101, 1, 300) on duplicate key update c3=101;
|
||||
|
||||
--trigger
|
||||
create table upsert_base
|
||||
(c1 int primary key,
|
||||
c2 varchar(100), --record the type
|
||||
cold varchar(1024),
|
||||
cnew varchar(1024) );
|
||||
create table upsert_tri
|
||||
(c1 int,
|
||||
c2 varchar(100),
|
||||
c3 int,
|
||||
unique(c1,c3)
|
||||
);
|
||||
|
||||
--S1 after trigger
|
||||
CREATE OR REPLACE FUNCTION trig_after() RETURNS TRIGGER AS $emp_audit$
|
||||
BEGIN
|
||||
IF (TG_OP = 'INSERT') THEN
|
||||
insert into upsert_base(c2,cnew) values('after insert',new.c2);
|
||||
RETURN NEW;
|
||||
ELSIF (TG_OP = 'UPDATE') THEN
|
||||
insert into upsert_base(c2,cold,cnew) values('after update',old.c2,new.c2);
|
||||
RETURN NEW;
|
||||
END IF;
|
||||
RETURN NULL;
|
||||
END;
|
||||
$emp_audit$ LANGUAGE plpgsql;
|
||||
CREATE TRIGGER tri_after
|
||||
AFTER UPDATE OR INSERT ON upsert_tri
|
||||
FOR EACH ROW EXECUTE PROCEDURE trig_after();
|
||||
--S2 before trigger
|
||||
CREATE OR REPLACE FUNCTION trig_before() RETURNS TRIGGER AS $emp_audit$
|
||||
BEGIN
|
||||
IF (TG_OP = 'INSERT') THEN
|
||||
insert into upsert_base(c2,cnew) values('before insert',new.c2);
|
||||
RETURN NEW;
|
||||
ELSIF (TG_OP = 'UPDATE') THEN
|
||||
insert into upsert_base(c2,cold,cnew) values('before update',old.c2,new.c2);
|
||||
RETURN NEW;
|
||||
END IF;
|
||||
RETURN NULL;
|
||||
END;
|
||||
$emp_audit$ LANGUAGE plpgsql;
|
||||
CREATE TRIGGER tri_before
|
||||
BEFORE UPDATE OR INSERT ON upsert_tri
|
||||
FOR EACH ROW EXECUTE PROCEDURE trig_before();
|
||||
---- upsert-insert
|
||||
insert into upsert_tri(c1,c2,c3) values(1000,'abc',1) on duplicate key update nothing;
|
||||
insert into upsert_tri(c1,c2,c3) values(2000,'abc',1) on duplicate key update c2='bcd';
|
||||
---- upsert-nothing
|
||||
insert into upsert_tri(c1,c2,c3) values(1000,'abc',1) on duplicate key update nothing;
|
||||
---- upsert-update
|
||||
insert into upsert_tri(c1,c2,c3) values(2000,'abc',1) on duplicate key update c2='bcd';
|
||||
---- check results
|
||||
SELECT * from upsert_tri;
|
||||
SELECT * from upsert_base;
|
||||
|
||||
-- foreign key
|
||||
insert into pkt values(1,1,1),(2,2,2),(3,3,3),(4,4,4),(5,5,5);
|
||||
insert into fkt values(1,1,1),(2,2,2),(3,3,3);
|
||||
|
||||
insert into fkt values(1,1,1),(2,2,2),(3,3,3) on duplicate key update b=excluded.b+1, c=0;
|
||||
insert into fkt values(1,1,1),(2,2,2),(3,3,3) on duplicate key update b=excluded.b+3, c=-1;
|
||||
|
||||
|
|
@ -0,0 +1,99 @@
|
|||
\c upsert
|
||||
CREATE SCHEMA upsert_test_tmp;
|
||||
SET CURRENT_SCHEMA TO upsert_test_tmp;
|
||||
CREATE TYPE atype AS(a int, b int);
|
||||
CREATE TYPE btype AS(a int, b atype, c varchar[3]);
|
||||
CREATE TEMP TABLE t_hash_tmp_0 (c1 INT, c2 INT, c3 VARCHAR, c4 INT[3], c5 INT[5], c6 atype, c7 btype);
|
||||
CREATE TEMP TABLE t_hash_tmp_1 (c1 INT, c2 INT PRIMARY KEY, c3 VARCHAR, c4 INT[3], c5 INT[5], c6 atype, c7 btype);
|
||||
CREATE TEMP TABLE t_rep_tmp_0 (c1 INT, c2 INT, c3 VARCHAR, c4 INT[3], c5 INT[5], c6 atype, c7 btype) ;
|
||||
CREATE TEMP TABLE t_rep_tmp_1 (c1 INT, c2 INT PRIMARY KEY, c3 VARCHAR, c4 INT[3], c5 INT[5], c6 atype, c7 btype) ;
|
||||
|
||||
-- enable_upsert_to_merge must be off, or upsert will be translated to merge.
|
||||
SET enable_upsert_to_merge TO OFF;
|
||||
SHOW enable_upsert_to_merge;
|
||||
|
||||
-- hash table
|
||||
-- tmp table without primary key
|
||||
INSERT INTO t_hash_tmp_0 VALUES(1, 1, 'C3', '{1,2,3}', '{10,20,30,40,50}', ROW(10,20), ROW(100, ROW(10,20), '{100,200}')),
|
||||
(1, 2, 'C3', '{1,2,3}', '{10,20,30,40,50}', ROW(10,20), ROW(100, ROW(10,20), '{100,200}'))
|
||||
ON DUPLICATE KEY UPDATE NOTHING;
|
||||
INSERT INTO t_hash_tmp_0 VALUES(2, 3, 'C3', '{1,2,3}', '{10,20,30,40,50}', ROW(10,20), ROW(100, ROW(10,20), '{100,200}')),
|
||||
(2, 4, 'C3', '{1,2,3}', '{10,20,30,40,50}', ROW(10,20), ROW(100, ROW(10,20), '{100,200}'))
|
||||
ON DUPLICATE KEY UPDATE c2 = 100;
|
||||
|
||||
-- tmp table with primary key
|
||||
-- multi insert
|
||||
INSERT INTO t_hash_tmp_1 VALUES(1, 1, 'C3', '{1,2,3}', '{10,20,30,40,50}', ROW(10,20), ROW(100, ROW(10,20), '{100,200}')),
|
||||
(1, 2, 'C3', '{1,2,3}', '{10,20,30,40,50}', ROW(10,20), ROW(100, ROW(10,20), '{100,200}'))
|
||||
ON DUPLICATE KEY UPDATE NOTHING;
|
||||
INSERT INTO t_hash_tmp_1 VALUES(2, 3, 'C3', '{1,2,3}', '{10,20,30,40,50}', ROW(10,20), ROW(100, ROW(10,20), '{100,200}')),
|
||||
(2, 4, 'C3', '{1,2,3}', '{10,20,30,40,50}', ROW(10,20), ROW(100, ROW(10,20), '{100,200}'))
|
||||
ON DUPLICATE KEY UPDATE c1 = EXCLUDED.c1, c3 = EXCLUDED.c3, c4 = EXCLUDED.c4, c5 = EXCLUDED.c5, c6 = EXCLUDED.c6, c7 = EXCLUDED.c7;
|
||||
SELECT * FROM t_hash_tmp_1 ORDER BY c2;
|
||||
|
||||
INSERT INTO t_hash_tmp_1 VALUES(10, 1, 'C30', '{10,20,30}', '{100,200,300,400,500}', ROW(100,200), ROW(1000, ROW(100,200), '{1000,2000}')),
|
||||
(11, 2, 'C31', '{11,21,31}', '{101,201,301,401,501}', ROW(101,201), ROW(1001, ROW(101,201), '{1001,2001}'))
|
||||
ON DUPLICATE KEY UPDATE NOTHING;
|
||||
INSERT INTO t_hash_tmp_1 VALUES(20, 3, 'C30', '{10,20,30}', '{10,20,30,40,50}', ROW(100,200), ROW(1000, ROW(100,200), '{1000,2000}')),
|
||||
(21, 4, 'C31', '{11,21,31}', '{101,201,301,401,501}', ROW(101,201), ROW(1001, ROW(101,201), '{1001,2001}'))
|
||||
ON DUPLICATE KEY UPDATE c1 = EXCLUDED.c1, c3 = EXCLUDED.c3, c4 = EXCLUDED.c4, c5 = EXCLUDED.c5, c6 = EXCLUDED.c6, c7 = EXCLUDED.c7;
|
||||
SELECT * FROM t_hash_tmp_1 ORDER BY c2;
|
||||
|
||||
-- insert and update same tuple, and update twice for another same tuple
|
||||
INSERT INTO t_hash_tmp_1 VALUES(0, 5, 'C30', '{10,20,30}', '{10,20,30,40,50}', ROW(100,200), ROW(1000, ROW(100,200), '{1000,2000}')),
|
||||
(1, 5, 'C31', '{11,21,31}', '{101,201,301,401,501}', ROW(101,201), ROW(1001, ROW(101,201), '{1001,2001}')),
|
||||
(10, 1, 'C30', '{10,20,30}', '{100,200,300,400,500}', ROW(100,200), ROW(1000, ROW(100,200), '{1000,2000}')),
|
||||
(11, 1, 'C31', '{11,21,31}', '{101,201,301,401,501}', ROW(101,201), ROW(1001, ROW(101,201), '{1001,2001}'))
|
||||
ON DUPLICATE KEY UPDATE NOTHING;
|
||||
SELECT * FROM t_hash_tmp_1 ORDER BY c2;
|
||||
|
||||
INSERT INTO t_hash_tmp_1 VALUES(0, 5, 'C30', '{10,20,30}', '{10,20,30,40,50}', ROW(100,200), ROW(1000, ROW(100,200), '{1000,2000}')),
|
||||
(1, 5, 'C31', '{11,21,31}', '{101,201,301,401,501}', ROW(101,201), ROW(1001, ROW(101,201), '{1001,2001}')),
|
||||
(10, 1, 'C30', '{10,20,30}', '{100,200,300,400,500}', ROW(100,200), ROW(1000, ROW(100,200), '{1000,2000}')),
|
||||
(11, 1, 'C31', '{11,21,31}', '{101,201,301,401,501}', ROW(101,201), ROW(1001, ROW(101,201), '{1001,2001}'))
|
||||
ON DUPLICATE KEY UPDATE c1 = EXCLUDED.c1, c3 = EXCLUDED.c3, c4 = EXCLUDED.c4, c5 = EXCLUDED.c5, c6 = EXCLUDED.c6, c7 = EXCLUDED.c7;
|
||||
SELECT * FROM t_hash_tmp_1 ORDER BY c2;
|
||||
|
||||
-- replication table
|
||||
-- tmp table without primary key
|
||||
INSERT INTO t_rep_tmp_0 VALUES(1, 1, 'C3', '{1,2,3}', '{10,20,30,40,50}', ROW(10,20), ROW(100, ROW(10,20), '{100,200}')),
|
||||
(1, 2, 'C3', '{1,2,3}', '{10,20,30,40,50}', ROW(10,20), ROW(100, ROW(10,20), '{100,200}'))
|
||||
ON DUPLICATE KEY UPDATE NOTHING;
|
||||
INSERT INTO t_rep_tmp_0 VALUES(2, 3, 'C3', '{1,2,3}', '{10,20,30,40,50}', ROW(10,20), ROW(100, ROW(10,20), '{100,200}')),
|
||||
(2, 4, 'C3', '{1,2,3}', '{10,20,30,40,50}', ROW(10,20), ROW(100, ROW(10,20), '{100,200}'))
|
||||
ON DUPLICATE KEY UPDATE c2 = 100;
|
||||
|
||||
-- tmp table with primary key
|
||||
-- multi insert
|
||||
INSERT INTO t_rep_tmp_1 VALUES(1, 1, 'C3', '{1,2,3}', '{10,20,30,40,50}', ROW(10,20), ROW(100, ROW(10,20), '{100,200}')),
|
||||
(1, 2, 'C3', '{1,2,3}', '{10,20,30,40,50}', ROW(10,20), ROW(100, ROW(10,20), '{100,200}'))
|
||||
ON DUPLICATE KEY UPDATE NOTHING;
|
||||
INSERT INTO t_rep_tmp_1 VALUES(2, 3, 'C3', '{1,2,3}', '{10,20,30,40,50}', ROW(10,20), ROW(100, ROW(10,20), '{100,200}')),
|
||||
(2, 4, 'C3', '{1,2,3}', '{10,20,30,40,50}', ROW(10,20), ROW(100, ROW(10,20), '{100,200}'))
|
||||
ON DUPLICATE KEY UPDATE c1 = EXCLUDED.c1, c3 = EXCLUDED.c3, c4 = EXCLUDED.c4, c5 = EXCLUDED.c5, c6 = EXCLUDED.c6, c7 = EXCLUDED.c7;
|
||||
SELECT * FROM t_rep_tmp_1 ORDER BY c2;
|
||||
|
||||
INSERT INTO t_rep_tmp_1 VALUES(10, 1, 'C30', '{10,20,30}', '{100,200,300,400,500}', ROW(100,200), ROW(1000, ROW(100,200), '{1000,2000}')),
|
||||
(11, 2, 'C31', '{11,21,31}', '{101,201,301,401,501}', ROW(101,201), ROW(1001, ROW(101,201), '{1001,2001}'))
|
||||
ON DUPLICATE KEY UPDATE NOTHING;
|
||||
INSERT INTO t_rep_tmp_1 VALUES(20, 3, 'C30', '{10,20,30}', '{10,20,30,40,50}', ROW(100,200), ROW(1000, ROW(100,200), '{1000,2000}')),
|
||||
(21, 4, 'C31', '{11,21,31}', '{101,201,301,401,501}', ROW(101,201), ROW(1001, ROW(101,201), '{1001,2001}'))
|
||||
ON DUPLICATE KEY UPDATE c1 = EXCLUDED.c1, c3 = EXCLUDED.c3, c4 = EXCLUDED.c4, c5 = EXCLUDED.c5, c6 = EXCLUDED.c6, c7 = EXCLUDED.c7;
|
||||
SELECT * FROM t_rep_tmp_1 ORDER BY c2;
|
||||
|
||||
-- insert and update same tuple, and update twice for another same tuple
|
||||
INSERT INTO t_rep_tmp_1 VALUES(0, 5, 'C30', '{10,20,30}', '{10,20,30,40,50}', ROW(100,200), ROW(1000, ROW(100,200), '{1000,2000}')),
|
||||
(1, 5, 'C31', '{11,21,31}', '{101,201,301,401,501}', ROW(101,201), ROW(1001, ROW(101,201), '{1001,2001}')),
|
||||
(10, 1, 'C30', '{10,20,30}', '{100,200,300,400,500}', ROW(100,200), ROW(1000, ROW(100,200), '{1000,2000}')),
|
||||
(11, 1, 'C31', '{11,21,31}', '{101,201,301,401,501}', ROW(101,201), ROW(1001, ROW(101,201), '{1001,2001}'))
|
||||
ON DUPLICATE KEY UPDATE NOTHING;
|
||||
SELECT * FROM t_rep_tmp_1 ORDER BY c2;
|
||||
|
||||
INSERT INTO t_rep_tmp_1 VALUES(0, 5, 'C30', '{10,20,30}', '{10,20,30,40,50}', ROW(100,200), ROW(1000, ROW(100,200), '{1000,2000}')),
|
||||
(1, 5, 'C31', '{11,21,31}', '{101,201,301,401,501}', ROW(101,201), ROW(1001, ROW(101,201), '{1001,2001}')),
|
||||
(10, 1, 'C30', '{10,20,30}', '{100,200,300,400,500}', ROW(100,200), ROW(1000, ROW(100,200), '{1000,2000}')),
|
||||
(11, 1, 'C31', '{11,21,31}', '{101,201,301,401,501}', ROW(101,201), ROW(1001, ROW(101,201), '{1001,2001}'))
|
||||
ON DUPLICATE KEY UPDATE c1 = EXCLUDED.c1, c3 = EXCLUDED.c3, c4 = EXCLUDED.c4, c5 = EXCLUDED.c5, c6 = EXCLUDED.c6, c7 = EXCLUDED.c7;
|
||||
SELECT * FROM t_rep_tmp_1 ORDER BY c2;
|
||||
|
||||
DROP SCHEMA upsert_test_tmp CASCADE;
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
\c upsert
|
||||
SET CURRENT_SCHEMA TO upsert_test;
|
||||
-- enable_upsert_to_merge must be off, or upsert will be translated to merge.
|
||||
SET enable_upsert_to_merge TO OFF;
|
||||
SHOW enable_upsert_to_merge;
|
||||
|
||||
CREATE FUNCTION upsert_before_func()
|
||||
RETURNS TRIGGER language plpgsql AS
|
||||
$$
|
||||
BEGIN
|
||||
IF (TG_OP = 'UPDATE') THEN
|
||||
RAISE warning 'before update (old): %', old.*::TEXT;
|
||||
RAISE warning 'before update (new): %', new.*::TEXT;
|
||||
elsIF (TG_OP = 'INSERT') THEN
|
||||
RAISE warning 'before insert (new): %', new.*::TEXT;
|
||||
IF NEW.key % 2 = 0 THEN
|
||||
NEW.color := NEW.color || ' trig modified';
|
||||
RAISE warning 'before insert (new, modified): %', new.*::TEXT;
|
||||
END IF;
|
||||
END IF;
|
||||
RETURN new;
|
||||
END;
|
||||
$$;
|
||||
CREATE TRIGGER upsert_before_trig BEFORE INSERT OR UPDATE ON t_trigger
|
||||
FOR EACH ROW EXECUTE procedure upsert_before_func();
|
||||
|
||||
CREATE FUNCTION upsert_after_func()
|
||||
RETURNS TRIGGER language plpgsql AS
|
||||
$$
|
||||
BEGIN
|
||||
IF (TG_OP = 'UPDATE') THEN
|
||||
RAISE warning 'after update (old): %', old.*::TEXT;
|
||||
RAISE warning 'after update (new): %', new.*::TEXT;
|
||||
elsIF (TG_OP = 'INSERT') THEN
|
||||
RAISE warning 'after insert (new): %', new.*::TEXT;
|
||||
END IF;
|
||||
RETURN null;
|
||||
END;
|
||||
$$;
|
||||
CREATE TRIGGER upsert_after_trig AFTER INSERT OR UPDATE ON t_trigger
|
||||
FOR EACH ROW EXECUTE procedure upsert_after_func();
|
||||
|
||||
INSERT INTO t_trigger values(1, 'black') ON DUPLICATE KEY UPDATE color = 'updated ' || t_trigger.color;
|
||||
INSERT INTO t_trigger values(2, 'red') ON DUPLICATE KEY UPDATE color = 'updated ' || t_trigger.color;
|
||||
INSERT INTO t_trigger values(3, 'orange') ON DUPLICATE KEY UPDATE color = 'updated ' || t_trigger.color;
|
||||
INSERT INTO t_trigger values(4, 'green') ON DUPLICATE KEY UPDATE color = 'updated ' || t_trigger.color;
|
||||
INSERT INTO t_trigger values(5, 'purple') ON DUPLICATE KEY UPDATE color = 'updated ' || t_trigger.color;
|
||||
INSERT INTO t_trigger values(6, 'white') ON DUPLICATE KEY UPDATE color = 'updated ' || t_trigger.color;
|
||||
INSERT INTO t_trigger values(7, 'pink') ON DUPLICATE KEY UPDATE color = 'updated ' || t_trigger.color;
|
||||
INSERT INTO t_trigger values(8, 'yellow') ON DUPLICATE KEY UPDATE color = 'updated ' || t_trigger.color;
|
||||
|
||||
SELECT * FROM t_trigger ORDER BY key;
|
||||
|
||||
INSERT INTO t_trigger values(2, 'black') ON DUPLICATE KEY UPDATE color = 'updated ' || t_trigger.color;
|
||||
INSERT INTO t_trigger values(3, 'red') ON DUPLICATE KEY UPDATE color = 'updated ' || t_trigger.color;
|
||||
INSERT INTO t_trigger values(4, 'orange') ON DUPLICATE KEY UPDATE color = 'updated ' || t_trigger.color;
|
||||
INSERT INTO t_trigger values(5, 'green') ON DUPLICATE KEY UPDATE color = 'updated ' || t_trigger.color;
|
||||
INSERT INTO t_trigger values(6, 'purple') ON DUPLICATE KEY UPDATE color = 'updated ' || t_trigger.color;
|
||||
INSERT INTO t_trigger values(7, 'white') ON DUPLICATE KEY UPDATE color = 'updated ' || t_trigger.color;
|
||||
INSERT INTO t_trigger values(8, 'pink') ON DUPLICATE KEY UPDATE color = 'updated ' || t_trigger.color;
|
||||
INSERT INTO t_trigger values(9, 'yellow') ON DUPLICATE KEY UPDATE color = 'updated ' || t_trigger.color;
|
||||
|
||||
SELECT * FROM t_trigger ORDER BY key;
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
\c upsert
|
||||
SET CURRENT_SCHEMA TO upsert_test_unlog;
|
||||
-- enable_upsert_to_merge must be off, or upsert will be translated to merge.
|
||||
SET enable_upsert_to_merge TO OFF;
|
||||
SHOW enable_upsert_to_merge;
|
||||
|
||||
-- hash table
|
||||
-- unlogged table without primary key
|
||||
INSERT INTO t_hash_unlog_0 VALUES(1, 1, 'C3', '{1,2,3}', '{10,20,30,40,50}', ROW(10,20), ROW(100, ROW(10,20), '{100,200}')),
|
||||
(1, 2, 'C3', '{1,2,3}', '{10,20,30,40,50}', ROW(10,20), ROW(100, ROW(10,20), '{100,200}'))
|
||||
ON DUPLICATE KEY UPDATE NOTHING;
|
||||
INSERT INTO t_hash_unlog_0 VALUES(2, 3, 'C3', '{1,2,3}', '{10,20,30,40,50}', ROW(10,20), ROW(100, ROW(10,20), '{100,200}')),
|
||||
(2, 4, 'C3', '{1,2,3}', '{10,20,30,40,50}', ROW(10,20), ROW(100, ROW(10,20), '{100,200}'))
|
||||
ON DUPLICATE KEY UPDATE c2 = 100;
|
||||
|
||||
-- unlogged table with primary key
|
||||
-- multi insert
|
||||
INSERT INTO t_hash_unlog_1 VALUES(1, 1, 'C3', '{1,2,3}', '{10,20,30,40,50}', ROW(10,20), ROW(100, ROW(10,20), '{100,200}')),
|
||||
(1, 2, 'C3', '{1,2,3}', '{10,20,30,40,50}', ROW(10,20), ROW(100, ROW(10,20), '{100,200}'))
|
||||
ON DUPLICATE KEY UPDATE NOTHING;
|
||||
INSERT INTO t_hash_unlog_1 VALUES(2, 3, 'C3', '{1,2,3}', '{10,20,30,40,50}', ROW(10,20), ROW(100, ROW(10,20), '{100,200}')),
|
||||
(2, 4, 'C3', '{1,2,3}', '{10,20,30,40,50}', ROW(10,20), ROW(100, ROW(10,20), '{100,200}'))
|
||||
ON DUPLICATE KEY UPDATE c1 = EXCLUDED.c1, c3 = EXCLUDED.c3, c4 = EXCLUDED.c4, c5 = EXCLUDED.c5, c6 = EXCLUDED.c6, c7 = EXCLUDED.c7;
|
||||
SELECT * FROM t_hash_unlog_1 ORDER BY c2;
|
||||
|
||||
INSERT INTO t_hash_unlog_1 VALUES(10, 1, 'C30', '{10,20,30}', '{100,200,300,400,500}', ROW(100,200), ROW(1000, ROW(100,200), '{1000,2000}')),
|
||||
(11, 2, 'C31', '{11,21,31}', '{101,201,301,401,501}', ROW(101,201), ROW(1001, ROW(101,201), '{1001,2001}'))
|
||||
ON DUPLICATE KEY UPDATE NOTHING;
|
||||
INSERT INTO t_hash_unlog_1 VALUES(20, 3, 'C30', '{10,20,30}', '{10,20,30,40,50}', ROW(100,200), ROW(1000, ROW(100,200), '{1000,2000}')),
|
||||
(21, 4, 'C31', '{11,21,31}', '{101,201,301,401,501}', ROW(101,201), ROW(1001, ROW(101,201), '{1001,2001}'))
|
||||
ON DUPLICATE KEY UPDATE c1 = EXCLUDED.c1, c3 = EXCLUDED.c3, c4 = EXCLUDED.c4, c5 = EXCLUDED.c5, c6 = EXCLUDED.c6, c7 = EXCLUDED.c7;
|
||||
SELECT * FROM t_hash_unlog_1 ORDER BY c2;
|
||||
|
||||
-- insert and update same tuple, and update twice for another same tuple
|
||||
INSERT INTO t_hash_unlog_1 VALUES(0, 5, 'C30', '{10,20,30}', '{10,20,30,40,50}', ROW(100,200), ROW(1000, ROW(100,200), '{1000,2000}')),
|
||||
(1, 5, 'C31', '{11,21,31}', '{101,201,301,401,501}', ROW(101,201), ROW(1001, ROW(101,201), '{1001,2001}')),
|
||||
(10, 1, 'C30', '{10,20,30}', '{100,200,300,400,500}', ROW(100,200), ROW(1000, ROW(100,200), '{1000,2000}')),
|
||||
(11, 1, 'C31', '{11,21,31}', '{101,201,301,401,501}', ROW(101,201), ROW(1001, ROW(101,201), '{1001,2001}'))
|
||||
ON DUPLICATE KEY UPDATE NOTHING;
|
||||
SELECT * FROM t_hash_unlog_1 ORDER BY c2;
|
||||
|
||||
INSERT INTO t_hash_unlog_1 VALUES(0, 5, 'C30', '{10,20,30}', '{10,20,30,40,50}', ROW(100,200), ROW(1000, ROW(100,200), '{1000,2000}')),
|
||||
(1, 5, 'C31', '{11,21,31}', '{101,201,301,401,501}', ROW(101,201), ROW(1001, ROW(101,201), '{1001,2001}')),
|
||||
(10, 1, 'C30', '{10,20,30}', '{100,200,300,400,500}', ROW(100,200), ROW(1000, ROW(100,200), '{1000,2000}')),
|
||||
(11, 1, 'C31', '{11,21,31}', '{101,201,301,401,501}', ROW(101,201), ROW(1001, ROW(101,201), '{1001,2001}'))
|
||||
ON DUPLICATE KEY UPDATE c1 = EXCLUDED.c1, c3 = EXCLUDED.c3, c4 = EXCLUDED.c4, c5 = EXCLUDED.c5, c6 = EXCLUDED.c6, c7 = EXCLUDED.c7;
|
||||
SELECT * FROM t_hash_unlog_1 ORDER BY c2;
|
||||
|
||||
-- replication table
|
||||
-- unlogged table without primary key
|
||||
INSERT INTO t_rep_unlog_0 VALUES(1, 1, 'C3', '{1,2,3}', '{10,20,30,40,50}', ROW(10,20), ROW(100, ROW(10,20), '{100,200}')),
|
||||
(1, 2, 'C3', '{1,2,3}', '{10,20,30,40,50}', ROW(10,20), ROW(100, ROW(10,20), '{100,200}'))
|
||||
ON DUPLICATE KEY UPDATE NOTHING;
|
||||
INSERT INTO t_rep_unlog_0 VALUES(2, 3, 'C3', '{1,2,3}', '{10,20,30,40,50}', ROW(10,20), ROW(100, ROW(10,20), '{100,200}')),
|
||||
(2, 4, 'C3', '{1,2,3}', '{10,20,30,40,50}', ROW(10,20), ROW(100, ROW(10,20), '{100,200}'))
|
||||
ON DUPLICATE KEY UPDATE c2 = 100;
|
||||
|
||||
-- unlogged table with primary key
|
||||
-- multi insert
|
||||
INSERT INTO t_rep_unlog_1 VALUES(1, 1, 'C3', '{1,2,3}', '{10,20,30,40,50}', ROW(10,20), ROW(100, ROW(10,20), '{100,200}')),
|
||||
(1, 2, 'C3', '{1,2,3}', '{10,20,30,40,50}', ROW(10,20), ROW(100, ROW(10,20), '{100,200}'))
|
||||
ON DUPLICATE KEY UPDATE NOTHING;
|
||||
INSERT INTO t_rep_unlog_1 VALUES(2, 3, 'C3', '{1,2,3}', '{10,20,30,40,50}', ROW(10,20), ROW(100, ROW(10,20), '{100,200}')),
|
||||
(2, 4, 'C3', '{1,2,3}', '{10,20,30,40,50}', ROW(10,20), ROW(100, ROW(10,20), '{100,200}'))
|
||||
ON DUPLICATE KEY UPDATE c1 = EXCLUDED.c1, c3 = EXCLUDED.c3, c4 = EXCLUDED.c4, c5 = EXCLUDED.c5, c6 = EXCLUDED.c6, c7 = EXCLUDED.c7;
|
||||
SELECT * FROM t_rep_unlog_1 ORDER BY c2;
|
||||
|
||||
INSERT INTO t_rep_unlog_1 VALUES(10, 1, 'C30', '{10,20,30}', '{100,200,300,400,500}', ROW(100,200), ROW(1000, ROW(100,200), '{1000,2000}')),
|
||||
(11, 2, 'C31', '{11,21,31}', '{101,201,301,401,501}', ROW(101,201), ROW(1001, ROW(101,201), '{1001,2001}'))
|
||||
ON DUPLICATE KEY UPDATE NOTHING;
|
||||
INSERT INTO t_rep_unlog_1 VALUES(20, 3, 'C30', '{10,20,30}', '{10,20,30,40,50}', ROW(100,200), ROW(1000, ROW(100,200), '{1000,2000}')),
|
||||
(21, 4, 'C31', '{11,21,31}', '{101,201,301,401,501}', ROW(101,201), ROW(1001, ROW(101,201), '{1001,2001}'))
|
||||
ON DUPLICATE KEY UPDATE c1 = EXCLUDED.c1, c3 = EXCLUDED.c3, c4 = EXCLUDED.c4, c5 = EXCLUDED.c5, c6 = EXCLUDED.c6, c7 = EXCLUDED.c7;
|
||||
SELECT * FROM t_rep_unlog_1 ORDER BY c2;
|
||||
|
||||
-- insert and update same tuple, and update twice for another same tuple
|
||||
INSERT INTO t_rep_unlog_1 VALUES(0, 5, 'C30', '{10,20,30}', '{10,20,30,40,50}', ROW(100,200), ROW(1000, ROW(100,200), '{1000,2000}')),
|
||||
(1, 5, 'C31', '{11,21,31}', '{101,201,301,401,501}', ROW(101,201), ROW(1001, ROW(101,201), '{1001,2001}')),
|
||||
(10, 1, 'C30', '{10,20,30}', '{100,200,300,400,500}', ROW(100,200), ROW(1000, ROW(100,200), '{1000,2000}')),
|
||||
(11, 1, 'C31', '{11,21,31}', '{101,201,301,401,501}', ROW(101,201), ROW(1001, ROW(101,201), '{1001,2001}'))
|
||||
ON DUPLICATE KEY UPDATE NOTHING;
|
||||
SELECT * FROM t_rep_unlog_1 ORDER BY c2;
|
||||
|
||||
INSERT INTO t_rep_unlog_1 VALUES(0, 5, 'C30', '{10,20,30}', '{10,20,30,40,50}', ROW(100,200), ROW(1000, ROW(100,200), '{1000,2000}')),
|
||||
(1, 5, 'C31', '{11,21,31}', '{101,201,301,401,501}', ROW(101,201), ROW(1001, ROW(101,201), '{1001,2001}')),
|
||||
(10, 1, 'C30', '{10,20,30}', '{100,200,300,400,500}', ROW(100,200), ROW(1000, ROW(100,200), '{1000,2000}')),
|
||||
(11, 1, 'C31', '{11,21,31}', '{101,201,301,401,501}', ROW(101,201), ROW(1001, ROW(101,201), '{1001,2001}'))
|
||||
ON DUPLICATE KEY UPDATE c1 = EXCLUDED.c1, c3 = EXCLUDED.c3, c4 = EXCLUDED.c4, c5 = EXCLUDED.c5, c6 = EXCLUDED.c6, c7 = EXCLUDED.c7;
|
||||
SELECT * FROM t_rep_unlog_1 ORDER BY c2;
|
||||
Loading…
Reference in New Issue