diff options
author | Teodor Sigaev <teodor@sigaev.ru> | 2015-11-27 19:11:22 +0300 |
---|---|---|
committer | Teodor Sigaev <teodor@sigaev.ru> | 2015-11-27 19:11:22 +0300 |
commit | 92e38182d7c8947a4ebbc1123b44f1245e232e85 (patch) | |
tree | f01ec11404a9b554cd9dc108409701e0fc86e001 /src/test | |
parent | 0da3a9bef7ad36dc640aebf2d0482e18f21561f6 (diff) |
COPY (INSERT/UPDATE/DELETE .. RETURNING ..)
Attached is a patch for being able to do COPY (query) without a CTE.
Author: Marko Tiikkaja
Review: Michael Paquier
Diffstat (limited to 'src/test')
-rw-r--r-- | src/test/regress/expected/copydml.out | 112 | ||||
-rw-r--r-- | src/test/regress/parallel_schedule | 2 | ||||
-rw-r--r-- | src/test/regress/serial_schedule | 1 | ||||
-rw-r--r-- | src/test/regress/sql/copydml.sql | 91 |
4 files changed, 205 insertions, 1 deletions
diff --git a/src/test/regress/expected/copydml.out b/src/test/regress/expected/copydml.out new file mode 100644 index 00000000000..1b533962c6b --- /dev/null +++ b/src/test/regress/expected/copydml.out @@ -0,0 +1,112 @@ +-- +-- Test cases for COPY (INSERT/UPDATE/DELETE) TO +-- +create table copydml_test (id serial, t text); +insert into copydml_test (t) values ('a'); +insert into copydml_test (t) values ('b'); +insert into copydml_test (t) values ('c'); +insert into copydml_test (t) values ('d'); +insert into copydml_test (t) values ('e'); +-- +-- Test COPY (insert/update/delete ...) +-- +copy (insert into copydml_test (t) values ('f') returning id) to stdout; +6 +copy (update copydml_test set t = 'g' where t = 'f' returning id) to stdout; +6 +copy (delete from copydml_test where t = 'g' returning id) to stdout; +6 +-- +-- Test \copy (insert/update/delete ...) +-- +\copy (insert into copydml_test (t) values ('f') returning id) to stdout; +7 +\copy (update copydml_test set t = 'g' where t = 'f' returning id) to stdout; +7 +\copy (delete from copydml_test where t = 'g' returning id) to stdout; +7 +-- Error cases +copy (insert into copydml_test default values) to stdout; +ERROR: COPY query must have a RETURNING clause +copy (update copydml_test set t = 'g') to stdout; +ERROR: COPY query must have a RETURNING clause +copy (delete from copydml_test) to stdout; +ERROR: COPY query must have a RETURNING clause +create rule qqq as on insert to copydml_test do instead nothing; +copy (insert into copydml_test default values) to stdout; +ERROR: DO INSTEAD NOTHING rules are not supported for COPY +drop rule qqq on copydml_test; +create rule qqq as on insert to copydml_test do also delete from copydml_test; +copy (insert into copydml_test default values) to stdout; +ERROR: DO ALSO rules are not supported for the COPY +drop rule qqq on copydml_test; +create rule qqq as on insert to copydml_test do instead (delete from copydml_test; delete from copydml_test); +copy (insert into copydml_test default values) to stdout; +ERROR: multi-statement DO INSTEAD rules are not supported for COPY +drop rule qqq on copydml_test; +create rule qqq as on insert to copydml_test where new.t <> 'f' do instead delete from copydml_test; +copy (insert into copydml_test default values) to stdout; +ERROR: conditional DO INSTEAD rules are not supported for COPY +drop rule qqq on copydml_test; +create rule qqq as on update to copydml_test do instead nothing; +copy (update copydml_test set t = 'f') to stdout; +ERROR: DO INSTEAD NOTHING rules are not supported for COPY +drop rule qqq on copydml_test; +create rule qqq as on update to copydml_test do also delete from copydml_test; +copy (update copydml_test set t = 'f') to stdout; +ERROR: DO ALSO rules are not supported for the COPY +drop rule qqq on copydml_test; +create rule qqq as on update to copydml_test do instead (delete from copydml_test; delete from copydml_test); +copy (update copydml_test set t = 'f') to stdout; +ERROR: multi-statement DO INSTEAD rules are not supported for COPY +drop rule qqq on copydml_test; +create rule qqq as on update to copydml_test where new.t <> 'f' do instead delete from copydml_test; +copy (update copydml_test set t = 'f') to stdout; +ERROR: conditional DO INSTEAD rules are not supported for COPY +drop rule qqq on copydml_test; +create rule qqq as on delete to copydml_test do instead nothing; +copy (delete from copydml_test) to stdout; +ERROR: DO INSTEAD NOTHING rules are not supported for COPY +drop rule qqq on copydml_test; +create rule qqq as on delete to copydml_test do also insert into copydml_test default values; +copy (delete from copydml_test) to stdout; +ERROR: DO ALSO rules are not supported for the COPY +drop rule qqq on copydml_test; +create rule qqq as on delete to copydml_test do instead (insert into copydml_test default values; insert into copydml_test default values); +copy (delete from copydml_test) to stdout; +ERROR: multi-statement DO INSTEAD rules are not supported for COPY +drop rule qqq on copydml_test; +create rule qqq as on delete to copydml_test where old.t <> 'f' do instead insert into copydml_test default values; +copy (delete from copydml_test) to stdout; +ERROR: conditional DO INSTEAD rules are not supported for COPY +drop rule qqq on copydml_test; +-- triggers +create function qqq_trig() returns trigger as $$ +begin +if tg_op in ('INSERT', 'UPDATE') then + raise notice '% %', tg_op, new.id; + return new; +else + raise notice '% %', tg_op, old.id; + return old; +end if; +end +$$ language plpgsql; +create trigger qqqbef before insert or update or delete on copydml_test + for each row execute procedure qqq_trig(); +create trigger qqqaf after insert or update or delete on copydml_test + for each row execute procedure qqq_trig(); +copy (insert into copydml_test (t) values ('f') returning id) to stdout; +NOTICE: INSERT 8 +8 +NOTICE: INSERT 8 +copy (update copydml_test set t = 'g' where t = 'f' returning id) to stdout; +NOTICE: UPDATE 8 +8 +NOTICE: UPDATE 8 +copy (delete from copydml_test where t = 'g' returning id) to stdout; +NOTICE: DELETE 8 +8 +NOTICE: DELETE 8 +drop table copydml_test; +drop function qqq_trig(); diff --git a/src/test/regress/parallel_schedule b/src/test/regress/parallel_schedule index 3987b4c700f..b1bc7c716a3 100644 --- a/src/test/regress/parallel_schedule +++ b/src/test/regress/parallel_schedule @@ -48,7 +48,7 @@ test: create_function_2 # execute two copy tests parallel, to check that copy itself # is concurrent safe. # ---------- -test: copy copyselect +test: copy copyselect copydml # ---------- # More groups of parallel tests diff --git a/src/test/regress/serial_schedule b/src/test/regress/serial_schedule index 379f2729be4..ade9ef15530 100644 --- a/src/test/regress/serial_schedule +++ b/src/test/regress/serial_schedule @@ -57,6 +57,7 @@ test: create_table test: create_function_2 test: copy test: copyselect +test: copydml test: create_misc test: create_operator test: create_index diff --git a/src/test/regress/sql/copydml.sql b/src/test/regress/sql/copydml.sql new file mode 100644 index 00000000000..9a29f9c9acc --- /dev/null +++ b/src/test/regress/sql/copydml.sql @@ -0,0 +1,91 @@ +-- +-- Test cases for COPY (INSERT/UPDATE/DELETE) TO +-- +create table copydml_test (id serial, t text); +insert into copydml_test (t) values ('a'); +insert into copydml_test (t) values ('b'); +insert into copydml_test (t) values ('c'); +insert into copydml_test (t) values ('d'); +insert into copydml_test (t) values ('e'); + +-- +-- Test COPY (insert/update/delete ...) +-- +copy (insert into copydml_test (t) values ('f') returning id) to stdout; +copy (update copydml_test set t = 'g' where t = 'f' returning id) to stdout; +copy (delete from copydml_test where t = 'g' returning id) to stdout; + +-- +-- Test \copy (insert/update/delete ...) +-- +\copy (insert into copydml_test (t) values ('f') returning id) to stdout; +\copy (update copydml_test set t = 'g' where t = 'f' returning id) to stdout; +\copy (delete from copydml_test where t = 'g' returning id) to stdout; + +-- Error cases +copy (insert into copydml_test default values) to stdout; +copy (update copydml_test set t = 'g') to stdout; +copy (delete from copydml_test) to stdout; + +create rule qqq as on insert to copydml_test do instead nothing; +copy (insert into copydml_test default values) to stdout; +drop rule qqq on copydml_test; +create rule qqq as on insert to copydml_test do also delete from copydml_test; +copy (insert into copydml_test default values) to stdout; +drop rule qqq on copydml_test; +create rule qqq as on insert to copydml_test do instead (delete from copydml_test; delete from copydml_test); +copy (insert into copydml_test default values) to stdout; +drop rule qqq on copydml_test; +create rule qqq as on insert to copydml_test where new.t <> 'f' do instead delete from copydml_test; +copy (insert into copydml_test default values) to stdout; +drop rule qqq on copydml_test; + +create rule qqq as on update to copydml_test do instead nothing; +copy (update copydml_test set t = 'f') to stdout; +drop rule qqq on copydml_test; +create rule qqq as on update to copydml_test do also delete from copydml_test; +copy (update copydml_test set t = 'f') to stdout; +drop rule qqq on copydml_test; +create rule qqq as on update to copydml_test do instead (delete from copydml_test; delete from copydml_test); +copy (update copydml_test set t = 'f') to stdout; +drop rule qqq on copydml_test; +create rule qqq as on update to copydml_test where new.t <> 'f' do instead delete from copydml_test; +copy (update copydml_test set t = 'f') to stdout; +drop rule qqq on copydml_test; + +create rule qqq as on delete to copydml_test do instead nothing; +copy (delete from copydml_test) to stdout; +drop rule qqq on copydml_test; +create rule qqq as on delete to copydml_test do also insert into copydml_test default values; +copy (delete from copydml_test) to stdout; +drop rule qqq on copydml_test; +create rule qqq as on delete to copydml_test do instead (insert into copydml_test default values; insert into copydml_test default values); +copy (delete from copydml_test) to stdout; +drop rule qqq on copydml_test; +create rule qqq as on delete to copydml_test where old.t <> 'f' do instead insert into copydml_test default values; +copy (delete from copydml_test) to stdout; +drop rule qqq on copydml_test; + +-- triggers +create function qqq_trig() returns trigger as $$ +begin +if tg_op in ('INSERT', 'UPDATE') then + raise notice '% %', tg_op, new.id; + return new; +else + raise notice '% %', tg_op, old.id; + return old; +end if; +end +$$ language plpgsql; +create trigger qqqbef before insert or update or delete on copydml_test + for each row execute procedure qqq_trig(); +create trigger qqqaf after insert or update or delete on copydml_test + for each row execute procedure qqq_trig(); + +copy (insert into copydml_test (t) values ('f') returning id) to stdout; +copy (update copydml_test set t = 'g' where t = 'f' returning id) to stdout; +copy (delete from copydml_test where t = 'g' returning id) to stdout; + +drop table copydml_test; +drop function qqq_trig(); |