sqlite/test/upsert2.test
drh 5e3a6ebf34 Fix the table name aliasing on INSERT so that it occurs before the column list
rather than afterwards, just as it does for PostgreSQL.  Add table name
aliasing to UPDATE and DELETE.

FossilOrigin-Name: 861a2e2a4895f96a5d8e1730e744983b2ac4311d0c2cf201c0e59f409030d5d7
2018-04-19 11:45:16 +00:00

171 lines
5.9 KiB
Plaintext

# 2018-04-17
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
#
# Test cases for UPSERT
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix zipfile
do_execsql_test upsert2-100 {
CREATE TABLE t1(a INTEGER PRIMARY KEY, b int, c DEFAULT 0);
INSERT INTO t1(a,b) VALUES(1,2),(3,4);
INSERT INTO t1(a,b) VALUES(1,8),(2,11),(3,1)
ON CONFLICT(a) DO UPDATE SET b=excluded.b, c=c+1 WHERE t1.b<excluded.b;
SELECT *, 'x' FROM t1 ORDER BY a;
} {1 8 1 x 2 11 0 x 3 4 0 x}
do_execsql_test upsert2-110 {
DROP TABLE t1;
CREATE TABLE t1(a INT PRIMARY KEY, b int, c DEFAULT 0) WITHOUT ROWID;
INSERT INTO t1(a,b) VALUES(1,2),(3,4);
INSERT INTO t1(a,b) VALUES(1,8),(2,11),(3,1)
ON CONFLICT(a) DO UPDATE SET b=excluded.b, c=c+1 WHERE t1.b<excluded.b;
SELECT *, 'x' FROM t1 ORDER BY a;
} {1 8 1 x 2 11 0 x 3 4 0 x}
do_execsql_test upsert2-200 {
DROP TABLE t1;
CREATE TABLE t1(a INTEGER PRIMARY KEY, b int, c DEFAULT 0);
INSERT INTO t1(a,b) VALUES(1,2),(3,4);
WITH nx(a,b) AS (VALUES(1,8),(2,11),(3,1),(2,15),(1,4),(1,99))
INSERT INTO t1(a,b) SELECT a, b FROM nx WHERE true
ON CONFLICT(a) DO UPDATE SET b=excluded.b, c=c+1 WHERE t1.b<excluded.b;
SELECT *, 'x' FROM t1 ORDER BY a;
} {1 99 2 x 2 15 1 x 3 4 0 x}
do_execsql_test upsert2-201 {
DELETE FROM t1;
INSERT INTO t1(a,b) VALUES(1,2),(3,4);
WITH nx(a,b) AS (VALUES(1,8),(2,11),(3,1),(2,15),(1,4),(1,99))
INSERT INTO main.t1 AS t2(a,b) SELECT a, b FROM nx WHERE true
ON CONFLICT(a) DO UPDATE SET b=excluded.b, c=t2.c+1 WHERE t2.b<excluded.b;
SELECT *, 'x' FROM t1 ORDER BY a;
} {1 99 2 x 2 15 1 x 3 4 0 x}
do_catchsql_test upsert2-202 {
WITH nx(a,b) AS (VALUES(1,8),(2,11),(3,1),(2,15),(1,4),(1,99))
INSERT INTO t1 AS t2(a,b) SELECT a, b FROM nx WHERE true
ON CONFLICT(a) DO UPDATE SET b=excluded.b, c=t1.c+1 WHERE t1.b<excluded.b;
} {1 {no such column: t1.c}}
do_execsql_test upsert2-210 {
DROP TABLE t1;
CREATE TABLE t1(a INT PRIMARY KEY, b int, c DEFAULT 0) WITHOUT ROWID;
INSERT INTO t1(a,b) VALUES(1,2),(3,4);
WITH nx(a,b) AS (VALUES(1,8),(2,11),(3,1),(2,15),(1,4),(1,99))
INSERT INTO t1(a,b) SELECT a, b FROM nx WHERE true
ON CONFLICT(a) DO UPDATE SET b=excluded.b, c=c+1 WHERE t1.b<excluded.b;
SELECT *, 'x' FROM t1 ORDER BY a;
} {1 99 2 x 2 15 1 x 3 4 0 x}
# On an ON CONFLICT DO UPDATE, the before-insert, before-update, and
# after-update triggers fire.
#
do_execsql_test upsert2-300 {
DROP TABLE t1;
CREATE TABLE t1(a INTEGER PRIMARY KEY, b int, c DEFAULT 0);
CREATE TABLE record(x TEXT, y TEXT);
CREATE TRIGGER r1 BEFORE INSERT ON t1 BEGIN
INSERT INTO record(x,y)
VALUES('before-insert',printf('%d,%d,%d',new.a,new.b,new.c));
END;
CREATE TRIGGER r2 AFTER INSERT ON t1 BEGIN
INSERT INTO record(x,y)
VALUES('after-insert',printf('%d,%d,%d',new.a,new.b,new.c));
END;
CREATE TRIGGER r3 BEFORE UPDATE ON t1 BEGIN
INSERT INTO record(x,y)
VALUES('before-update',printf('%d,%d,%d/%d,%d,%d',
old.a,old.b,old.c,new.a,new.b,new.c));
END;
CREATE TRIGGER r4 AFTER UPDATE ON t1 BEGIN
INSERT INTO record(x,y)
VALUES('after-update',printf('%d,%d,%d/%d,%d,%d',
old.a,old.b,old.c,new.a,new.b,new.c));
END;
INSERT INTO t1(a,b) VALUES(1,2);
DELETE FROM record;
INSERT INTO t1(a,b) VALUES(1,2)
ON CONFLICT(a) DO UPDATE SET c=t1.c+1;
SELECT * FROM record
} {before-insert 1,2,0 before-update 1,2,0/1,2,1 after-update 1,2,0/1,2,1}
# On an ON CONFLICT DO NOTHING, only the before-insert trigger fires.
#
do_execsql_test upsert2-310 {
DELETE FROM record;
INSERT INTO t1(a,b) VALUES(1,2) ON CONFLICT DO NOTHING;
SELECT * FROM record;
} {before-insert 1,2,0}
# With ON CONFLICT DO UPDATE and a failed WHERE, only the before-insert
# trigger fires.
#
do_execsql_test upsert2-320 {
DELETE FROM record;
INSERT INTO t1(a,b) VALUES(1,2)
ON CONFLICT(a) DO UPDATE SET c=c+1 WHERE c<0;
SELECT * FROM record;
} {before-insert 1,2,0}
do_execsql_test upsert2-321 {
SELECT * FROM t1;
} {1 2 1}
# Trigger tests repeated for a WITHOUT ROWID table.
#
do_execsql_test upsert2-400 {
DROP TABLE t1;
CREATE TABLE t1(a INT PRIMARY KEY, b int, c DEFAULT 0) WITHOUT ROWID;
CREATE TRIGGER r1 BEFORE INSERT ON t1 BEGIN
INSERT INTO record(x,y)
VALUES('before-insert',printf('%d,%d,%d',new.a,new.b,new.c));
END;
CREATE TRIGGER r2 AFTER INSERT ON t1 BEGIN
INSERT INTO record(x,y)
VALUES('after-insert',printf('%d,%d,%d',new.a,new.b,new.c));
END;
CREATE TRIGGER r3 BEFORE UPDATE ON t1 BEGIN
INSERT INTO record(x,y)
VALUES('before-update',printf('%d,%d,%d/%d,%d,%d',
old.a,old.b,old.c,new.a,new.b,new.c));
END;
CREATE TRIGGER r4 AFTER UPDATE ON t1 BEGIN
INSERT INTO record(x,y)
VALUES('after-update',printf('%d,%d,%d/%d,%d,%d',
old.a,old.b,old.c,new.a,new.b,new.c));
END;
INSERT INTO t1(a,b) VALUES(1,2);
DELETE FROM record;
INSERT INTO t1(a,b) VALUES(1,2)
ON CONFLICT(a) DO UPDATE SET c=t1.c+1;
SELECT * FROM record
} {before-insert 1,2,0 before-update 1,2,0/1,2,1 after-update 1,2,0/1,2,1}
# On an ON CONFLICT DO NOTHING, only the before-insert trigger fires.
#
do_execsql_test upsert2-410 {
DELETE FROM record;
INSERT INTO t1(a,b) VALUES(1,2) ON CONFLICT DO NOTHING;
SELECT * FROM record;
} {before-insert 1,2,0}
# With ON CONFLICT DO UPDATE and a failed WHERE, only the before-insert
# trigger fires.
#
do_execsql_test upsert2-420 {
DELETE FROM record;
INSERT INTO t1(a,b) VALUES(1,2)
ON CONFLICT(a) DO UPDATE SET c=c+1 WHERE c<0;
SELECT * FROM record;
} {before-insert 1,2,0}
do_execsql_test upsert2-421 {
SELECT * FROM t1;
} {1 2 1}
finish_test