-- Enforce use of COMMIT instead of 2PC for temporary objects CREATE TABLE x ( a int, b int, c text not null default 'stuff', d text, e text ); CREATE FUNCTION fn_x_before () RETURNS TRIGGER AS ' BEGIN NEW.e := ''before trigger fired''::text; return NEW; END; ' LANGUAGE plpgsql; CREATE FUNCTION fn_x_after () RETURNS TRIGGER AS ' BEGIN UPDATE x set e=''after trigger fired'' where c=''stuff''; return NULL; END; ' LANGUAGE plpgsql; CREATE TRIGGER trg_x_after AFTER INSERT ON x FOR EACH ROW EXECUTE PROCEDURE fn_x_after(); CREATE TRIGGER trg_x_before BEFORE INSERT ON x FOR EACH ROW EXECUTE PROCEDURE fn_x_before(); COPY x (a, b, c, d, e) from stdin; 9999 \N \\N \NN \N 10000 21 31 41 51 \. COPY x (b, d) from stdin; 1 test_1 \. COPY x (b, d) from stdin; 2 test_2 3 test_3 4 test_4 5 test_5 \. COPY x (a, b, c, d, e) from stdin; 10001 22 32 42 52 10002 23 33 43 53 10003 24 34 44 54 10004 25 35 45 55 10005 26 36 46 56 \. -- non-existent column in column list: should fail COPY x (xyz) from stdin; -- too many columns in column list: should fail COPY x (a, b, c, d, e, d, c) from stdin; -- missing data: should fail COPY x from stdin; \. COPY x from stdin; 2000 230 23 23 \. COPY x from stdin; 2001 231 \N \N \. -- extra data: should fail COPY x from stdin; 2002 232 40 50 60 70 80 \. -- various COPY options: delimiters, oids, NULL string, encoding COPY x (b, c, d, e) from stdin with oids delimiter ',' null 'x'; 500000,x,45,80,90 500001,x,\x,\\x,\\\x 500002,x,\,,\\\,,\\ \. COPY x from stdin WITH DELIMITER AS ';' NULL AS ''; 3000;;c;; \. COPY x from stdin WITH DELIMITER AS ':' NULL AS E'\\X' ENCODING 'sql_ascii'; 4000:\X:C:\X:\X 4001:1:empty:: 4002:2:null:\X:\X 4003:3:Backslash:\\:\\ 4004:4:BackslashX:\\X:\\X 4005:5:N:\N:\N 4006:6:BackslashN:\\N:\\N 4007:7:XX:\XX:\XX 4008:8:Delimiter:\::\: \. -- check results of copy in SELECT * FROM x ORDER BY a, b; -- COPY w/ oids on a table w/o oids should fail CREATE TABLE no_oids ( a int, b int ) WITHOUT OIDS; INSERT INTO no_oids (a, b) VALUES (5, 10); INSERT INTO no_oids (a, b) VALUES (20, 30); -- should fail COPY no_oids FROM stdin WITH OIDS; COPY no_oids TO stdout WITH OIDS; -- check copy out COPY (select * from x order by 1,2,3,4,5) TO stdout; COPY (select c,e from x where c != 'N' order by 1,2) TO stdout; COPY (select b,e from x order by 1,2) TO stdout WITH NULL 'I''m null'; CREATE TEMP TABLE y ( col1 text, col2 text ); INSERT INTO y VALUES ('Jackson, Sam', E'\\h'); INSERT INTO y VALUES ('It is "perfect".',E'\t'); INSERT INTO y VALUES ('', NULL); COPY y TO stdout WITH CSV; COPY y TO stdout WITH CSV QUOTE '''' DELIMITER '|'; COPY y TO stdout WITH CSV FORCE QUOTE col2 ESCAPE E'\\' ENCODING 'sql_ascii'; COPY y TO stdout WITH CSV FORCE QUOTE *; -- Repeat above tests with new 9.0 option syntax COPY y TO stdout (FORMAT CSV); COPY y TO stdout (FORMAT CSV, QUOTE '''', DELIMITER '|'); COPY y TO stdout (FORMAT CSV, FORCE_QUOTE (col2), ESCAPE E'\\'); COPY y TO stdout (FORMAT CSV, FORCE_QUOTE *); \copy y TO stdout (FORMAT CSV) \copy y TO stdout (FORMAT CSV, QUOTE '''', DELIMITER '|') \copy y TO stdout (FORMAT CSV, FORCE_QUOTE (col2), ESCAPE E'\\') \copy y TO stdout (FORMAT CSV, FORCE_QUOTE *) --test that we read consecutive LFs properly CREATE TEMP TABLE testnl (a int, b text, c int); COPY testnl FROM stdin CSV; 1,"a field with two LFs inside",2 \. -- test end of copy marker CREATE TABLE testeoc (a text); COPY testeoc FROM stdin CSV; a\. \.b c\.d "\." \. COPY (select * from testeoc order by a using ~<~) TO stdout CSV; -- test handling of nonstandard null marker that violates escaping rules CREATE TEMP TABLE testnull(a int, b text); INSERT INTO testnull VALUES (1, E'\\0'), (NULL, NULL); COPY (select * from testnull order by 1,2) TO stdout WITH NULL AS E'\\0'; COPY testnull FROM stdin WITH NULL AS E'\\0'; 42 \\0 \0 \0 \. SELECT * FROM testnull ORDER BY 1,2; START TRANSACTION; CREATE TABLE vistest (LIKE testeoc); COPY vistest FROM stdin CSV; a0 b \. COMMIT; SELECT * FROM vistest order by 1; START TRANSACTION; TRUNCATE vistest; COPY vistest FROM stdin CSV FREEZE; x y \. SELECT * FROM vistest order by 1; COMMIT; TRUNCATE vistest; COPY vistest FROM stdin CSV FREEZE; p g \. CREATE FUNCTION truncate_in_subxact() RETURNS VOID AS $$ BEGIN TRUNCATE vistest; --EXCEPTION -- WHEN OTHERS THEN -- INSERT INTO vistest VALUES ('subxact failure'); END; $$ language plpgsql; START TRANSACTION; INSERT INTO vistest VALUES ('z'); SELECT truncate_in_subxact(); COPY vistest FROM stdin CSV FREEZE; d4 e \. SELECT * FROM vistest order by 1; COMMIT; SELECT * FROM vistest order by 1; DROP TABLE vistest; DROP FUNCTION truncate_in_subxact(); DROP TABLE x; DROP TABLE y; DROP FUNCTION fn_x_before(); DROP FUNCTION fn_x_after(); CREATE TABLE measurement ( city_id int not null, logdate int not null, peaktemp int, unitsales int ); CREATE TABLE measurement_movement ( city_id int not null, logdate int not null, peaktemp int, unitsales int ); CREATE OR REPLACE FUNCTION measurement_insert_trigger() RETURNS TRIGGER AS $$ BEGIN INSERT INTO measurement_movement VALUES (NEW.*); RETURN NULL; END; $$ LANGUAGE plpgsql; CREATE TRIGGER insert_measurement_trigger BEFORE INSERT ON measurement FOR EACH ROW EXECUTE PROCEDURE measurement_insert_trigger(); COPY measurement from stdin; 10001 22 32 42 10002 23 33 43 10003 24 34 44 10004 25 35 45 10005 26 36 46 \. select * from measurement_movement order by city_id; select * from measurement order by city_id; drop trigger insert_measurement_trigger on measurement; drop function measurement_insert_trigger; drop table measurement; drop table measurement_movement; create table copy_header_src (c1 int); create table copy_header_dest (c1 int); insert into copy_header_src select generate_series(1,10); \copy copy_header_src to '~/copy_header_src.csv' with csv header; \copy copy_header_dest from '~/copy_header_src.csv' with csv header'on'; drop table copy_header_src; drop table copy_header_dest; create table copy_parallel_header_src (c1 int); create table copy_parallel_header_dest (c1 int); insert into copy_parallel_header_src select generate_series(1,100); \copy copy_parallel_header_src to '~/copy_parallel_header_src.csv' with csv header; \copy copy_parallel_header_dest from '~/copy_parallel_header_src.csv' parallel 8 with csv header; select count(*) from copy_parallel_header_dest; \copy copy_parallel_header_dest from '~/copy_parallel_header_src.csv' parallel 8 with csv header header; \copy copy_parallel_header_dest from '~/copy_parallel_header_src.csv' parallel 8 with csv header'on'; \copy copy_parallel_header_dest from '~/copy_parallel_header_src.csv' parallel 8 with csv header,; \copy copy_parallel_header_dest from '~/copy_parallel_header_src.csv' parallel 8 with csv, header; \copy copy_parallel_header_dest from '~/copy_parallel_header_src.csv' parallel 8 with (csv, header); \copy copy_parallel_header_dest from '~/copy_parallel_header_src.csv' parallel 8 with header; drop table copy_parallel_header_src; drop table copy_parallel_header_dest;