# LogicTest: local

statement ok
CREATE TABLE kv (
  k INT PRIMARY KEY,
  v INT
)

query TTT
SELECT tree, field, description FROM [
EXPLAIN (VERBOSE) UPSERT INTO kv TABLE kv ORDER BY v DESC
]
----
count                ·         ·
 └── upsert          ·         ·
      │              into      kv(k, v)
      │              strategy  fast upserter
      └── sort       ·         ·
           │         order     -v
           └── scan  ·         ·
·                    table     kv@primary
·                    spans     ALL

# Regression test for #25726.
# UPSERT over tables with column families, on the fast path, use the
# INSERT logic. This has special casing for column families of 1
# column, and another special casing for column families of 2+
# columns. The special casing is only for families that do not include
# the primary key. So we need a table with 3 families: 1 for the PK, 1
# with just 1 col, and 1 with 2+ cols.
statement ok
CREATE TABLE tu (a INT PRIMARY KEY, b INT, c INT, d INT, FAMILY (a), FAMILY (b), FAMILY (c,d));
  INSERT INTO tu VALUES (1, 2, 3, 4)

statement ok
SET tracing = on,kv,results; UPSERT INTO tu VALUES (1, NULL, NULL, NULL); SET tracing = off

query T
SELECT message FROM [SHOW KV TRACE FOR SESSION]
 WHERE operation != 'dist sender send'
----
Put /Table/54/1/1/0 -> /TUPLE/
Del /Table/54/1/1/1/1
Del /Table/54/1/1/2/1
fast path completed
rows affected: 1

# KV operations.
statement ok
CREATE DATABASE t; CREATE TABLE t.kv(k INT PRIMARY KEY, v INT)

statement ok
CREATE UNIQUE INDEX woo ON t.kv(v)

statement ok
SET tracing = on,kv,results; UPSERT INTO t.kv(k, v) VALUES (2,3); SET tracing = off

query TT
SELECT operation, message FROM [SHOW KV TRACE FOR SESSION]
 WHERE operation != 'dist sender send'
----
flow     Scan /Table/56/1/2{-/#}
flow     CPut /Table/56/1/2/0 -> /TUPLE/2:2:Int/3
flow     InitPut /Table/56/2/3/0 -> /BYTES/0x8a
flow     fast path completed
sql txn  rows affected: 1

statement ok
SET tracing = on,kv,results; UPSERT INTO t.kv(k, v) VALUES (1,2); SET tracing = off

query TT
SELECT operation, message FROM [SHOW KV TRACE FOR SESSION]
 WHERE operation != 'dist sender send'
----
flow     Scan /Table/56/1/1{-/#}
flow     CPut /Table/56/1/1/0 -> /TUPLE/2:2:Int/2
flow     InitPut /Table/56/2/2/0 -> /BYTES/0x89
flow     fast path completed
sql txn  rows affected: 1

statement error duplicate key value
SET tracing = on,kv,results; UPSERT INTO t.kv(k, v) VALUES (2,2); SET tracing = off

query TT
set tracing=off;
SELECT operation, message FROM [SHOW KV TRACE FOR SESSION]
 WHERE operation != 'dist sender send'
----
flow     Scan /Table/56/1/2{-/#}
flow     fetched: /kv/primary/2/v -> /3
flow     Put /Table/56/1/2/0 -> /TUPLE/2:2:Int/2
flow     Del /Table/56/2/3/0
flow     CPut /Table/56/2/2/0 -> /BYTES/0x8a (expecting does not exist)
sql txn  execution failed after 0 rows: duplicate key value (v)=(2) violates unique constraint "woo"

subtest regression_32834

statement ok
CREATE TABLE test_table (
  id BIGINT PRIMARY KEY,
  a BIGINT,
  b BIGINT
);

statement ok
INSERT INTO test_table (id, a) VALUES
  (123, 456), (123, 456)
  ON CONFLICT (id) DO UPDATE SET a = EXCLUDED.a;

query II colnames
SELECT id, a
FROM test_table
----
id   a
123  456

statement ok
INSERT INTO test_table (id, a) VALUES
  (123, 1), (123, 2), (123, 1)
  ON CONFLICT (id) DO UPDATE SET a = EXCLUDED.a;

query II colnames
SELECT id, a
FROM test_table
----
id   a
123  1

statement ok
INSERT INTO test_table (id, a) VALUES
  (123, 1), (123, 2), (123, 3)
  ON CONFLICT (id) DO UPDATE SET a = EXCLUDED.a;

query II colnames
SELECT id, a
FROM test_table
----
id   a
123  3

statement ok
DROP TABLE test_table;

subtest regression_32473

statement ok
CREATE TABLE customers (
  customer_id serial PRIMARY KEY,
  name VARCHAR UNIQUE,
  email VARCHAR NOT NULL
);

# The heuristic planner does not support non-tuple expressions on the RHS, throwing
# a planning error immediately.
statement error unimplemented: cannot use this type of expression on the right of UPDATE SET
INSERT INTO customers (name, email) VALUES ('bob', 'bob@email.com') ON CONFLICT (name)
  DO UPDATE SET (name, email) = (
    SELECT 'bob', 'otherbob@email.com'
  )

statement ok
DROP TABLE customers

# The heuristic planner behaves differently than the CBO in this case. It always
# checks constraints, even if no insert or update actually occurs.
statement ok
CREATE TABLE t5 (k INT PRIMARY KEY, a INT, b int CHECK (a > b))

statement ok
INSERT INTO t5 VALUES (1, 10, 9) ON CONFLICT (k) DO NOTHING

statement error pgcode 23514 failed to satisfy CHECK constraint
INSERT INTO t5 VALUES (1, 10, 20) ON CONFLICT (k) DO NOTHING
