Remove old RULE privilege completely.
[pgsql.git] / src / test / regress / expected / copy.out
blob44114089a6dce9807223151ea9215e5247205575
1 --
2 -- COPY
3 --
4 -- directory paths are passed to us in environment variables
5 \getenv abs_srcdir PG_ABS_SRCDIR
6 \getenv abs_builddir PG_ABS_BUILDDIR
7 --- test copying in CSV mode with various styles
8 --- of embedded line ending characters
9 create temp table copytest (
10         style   text,
11         test    text,
12         filler  int);
13 insert into copytest values('DOS',E'abc\r\ndef',1);
14 insert into copytest values('Unix',E'abc\ndef',2);
15 insert into copytest values('Mac',E'abc\rdef',3);
16 insert into copytest values(E'esc\\ape',E'a\\r\\\r\\\n\\nb',4);
17 \set filename :abs_builddir '/results/copytest.csv'
18 copy copytest to :'filename' csv;
19 create temp table copytest2 (like copytest);
20 copy copytest2 from :'filename' csv;
21 select * from copytest except select * from copytest2;
22  style | test | filler 
23 -------+------+--------
24 (0 rows)
26 truncate copytest2;
27 --- same test but with an escape char different from quote char
28 copy copytest to :'filename' csv quote '''' escape E'\\';
29 copy copytest2 from :'filename' csv quote '''' escape E'\\';
30 select * from copytest except select * from copytest2;
31  style | test | filler 
32 -------+------+--------
33 (0 rows)
35 -- test header line feature
36 create temp table copytest3 (
37         c1 int,
38         "col with , comma" text,
39         "col with "" quote"  int);
40 copy copytest3 from stdin csv header;
41 copy copytest3 to stdout csv header;
42 c1,"col with , comma","col with "" quote"
43 1,a,1
44 2,b,2
45 create temp table copytest4 (
46         c1 int,
47         "colname with tab:      " text);
48 copy copytest4 from stdin (header);
49 copy copytest4 to stdout (header);
50 c1      colname with tab: \t
51 1       a
52 2       b
53 -- test copy from with a partitioned table
54 create table parted_copytest (
55         a int,
56         b int,
57         c text
58 ) partition by list (b);
59 create table parted_copytest_a1 (c text, b int, a int);
60 create table parted_copytest_a2 (a int, c text, b int);
61 alter table parted_copytest attach partition parted_copytest_a1 for values in(1);
62 alter table parted_copytest attach partition parted_copytest_a2 for values in(2);
63 -- We must insert enough rows to trigger multi-inserts.  These are only
64 -- enabled adaptively when there are few enough partition changes.
65 insert into parted_copytest select x,1,'One' from generate_series(1,1000) x;
66 insert into parted_copytest select x,2,'Two' from generate_series(1001,1010) x;
67 insert into parted_copytest select x,1,'One' from generate_series(1011,1020) x;
68 \set filename :abs_builddir '/results/parted_copytest.csv'
69 copy (select * from parted_copytest order by a) to :'filename';
70 truncate parted_copytest;
71 copy parted_copytest from :'filename';
72 -- Ensure COPY FREEZE errors for partitioned tables.
73 begin;
74 truncate parted_copytest;
75 copy parted_copytest from :'filename' (freeze);
76 ERROR:  cannot perform COPY FREEZE on a partitioned table
77 rollback;
78 select tableoid::regclass,count(*),sum(a) from parted_copytest
79 group by tableoid order by tableoid::regclass::name;
80       tableoid      | count |  sum   
81 --------------------+-------+--------
82  parted_copytest_a1 |  1010 | 510655
83  parted_copytest_a2 |    10 |  10055
84 (2 rows)
86 truncate parted_copytest;
87 -- create before insert row trigger on parted_copytest_a2
88 create function part_ins_func() returns trigger language plpgsql as $$
89 begin
90   return new;
91 end;
92 $$;
93 create trigger part_ins_trig
94         before insert on parted_copytest_a2
95         for each row
96         execute procedure part_ins_func();
97 copy parted_copytest from :'filename';
98 select tableoid::regclass,count(*),sum(a) from parted_copytest
99 group by tableoid order by tableoid::regclass::name;
100       tableoid      | count |  sum   
101 --------------------+-------+--------
102  parted_copytest_a1 |  1010 | 510655
103  parted_copytest_a2 |    10 |  10055
104 (2 rows)
106 truncate table parted_copytest;
107 create index on parted_copytest (b);
108 drop trigger part_ins_trig on parted_copytest_a2;
109 copy parted_copytest from stdin;
110 -- Ensure index entries were properly added during the copy.
111 select * from parted_copytest where b = 1;
112  a | b |  c   
113 ---+---+------
114  1 | 1 | str1
115 (1 row)
117 select * from parted_copytest where b = 2;
118  a | b |  c   
119 ---+---+------
120  2 | 2 | str2
121 (1 row)
123 drop table parted_copytest;
125 -- Progress reporting for COPY
127 create table tab_progress_reporting (
128         name text,
129         age int4,
130         location point,
131         salary int4,
132         manager name
134 -- Add a trigger to catch and print the contents of the catalog view
135 -- pg_stat_progress_copy during data insertion.  This allows to test
136 -- the validation of some progress reports for COPY FROM where the trigger
137 -- would fire.
138 create function notice_after_tab_progress_reporting() returns trigger AS
140 declare report record;
141 begin
142   -- The fields ignored here are the ones that may not remain
143   -- consistent across multiple runs.  The sizes reported may differ
144   -- across platforms, so just check if these are strictly positive.
145   with progress_data as (
146     select
147        relid::regclass::text as relname,
148        command,
149        type,
150        bytes_processed > 0 as has_bytes_processed,
151        bytes_total > 0 as has_bytes_total,
152        tuples_processed,
153        tuples_excluded
154       from pg_stat_progress_copy
155       where pid = pg_backend_pid())
156   select into report (to_jsonb(r)) as value
157     from progress_data r;
159   raise info 'progress: %', report.value::text;
160   return new;
161 end;
162 $$ language plpgsql;
163 create trigger check_after_tab_progress_reporting
164         after insert on tab_progress_reporting
165         for each statement
166         execute function notice_after_tab_progress_reporting();
167 -- Generate COPY FROM report with PIPE.
168 copy tab_progress_reporting from stdin;
169 INFO:  progress: {"type": "PIPE", "command": "COPY FROM", "relname": "tab_progress_reporting", "has_bytes_total": false, "tuples_excluded": 0, "tuples_processed": 3, "has_bytes_processed": true}
170 -- Generate COPY FROM report with FILE, with some excluded tuples.
171 truncate tab_progress_reporting;
172 \set filename :abs_srcdir '/data/emp.data'
173 copy tab_progress_reporting from :'filename'
174         where (salary < 2000);
175 INFO:  progress: {"type": "FILE", "command": "COPY FROM", "relname": "tab_progress_reporting", "has_bytes_total": true, "tuples_excluded": 1, "tuples_processed": 2, "has_bytes_processed": true}
176 drop trigger check_after_tab_progress_reporting on tab_progress_reporting;
177 drop function notice_after_tab_progress_reporting();
178 drop table tab_progress_reporting;
179 -- Test header matching feature
180 create table header_copytest (
181         a int,
182         b int,
183         c text
185 -- Make sure it works with dropped columns
186 alter table header_copytest drop column c;
187 alter table header_copytest add column c text;
188 copy header_copytest to stdout with (header match);
189 ERROR:  cannot use "match" with HEADER in COPY TO
190 copy header_copytest from stdin with (header wrong_choice);
191 ERROR:  header requires a Boolean value or "match"
192 -- works
193 copy header_copytest from stdin with (header match);
194 copy header_copytest (c, a, b) from stdin with (header match);
195 copy header_copytest from stdin with (header match, format csv);
196 -- errors
197 copy header_copytest (c, b, a) from stdin with (header match);
198 ERROR:  column name mismatch in header line field 1: got "a", expected "c"
199 CONTEXT:  COPY header_copytest, line 1: "a      b       c"
200 copy header_copytest from stdin with (header match);
201 ERROR:  column name mismatch in header line field 3: got null value ("\N"), expected "c"
202 CONTEXT:  COPY header_copytest, line 1: "a      b       \N"
203 copy header_copytest from stdin with (header match);
204 ERROR:  wrong number of fields in header line: got 2, expected 3
205 CONTEXT:  COPY header_copytest, line 1: "a      b"
206 copy header_copytest from stdin with (header match);
207 ERROR:  wrong number of fields in header line: got 4, expected 3
208 CONTEXT:  COPY header_copytest, line 1: "a      b       c       d"
209 copy header_copytest from stdin with (header match);
210 ERROR:  column name mismatch in header line field 3: got "d", expected "c"
211 CONTEXT:  COPY header_copytest, line 1: "a      b       d"
212 SELECT * FROM header_copytest ORDER BY a;
213  a | b |  c  
214 ---+---+-----
215  1 | 2 | foo
216  3 | 4 | bar
217  5 | 6 | baz
218 (3 rows)
220 -- Drop an extra column, in the middle of the existing set.
221 alter table header_copytest drop column b;
222 -- works
223 copy header_copytest (c, a) from stdin with (header match);
224 copy header_copytest (a, c) from stdin with (header match);
225 -- errors
226 copy header_copytest from stdin with (header match);
227 ERROR:  wrong number of fields in header line: got 3, expected 2
228 CONTEXT:  COPY header_copytest, line 1: "a      ........pg.dropped.2........    c"
229 copy header_copytest (a, c) from stdin with (header match);
230 ERROR:  wrong number of fields in header line: got 3, expected 2
231 CONTEXT:  COPY header_copytest, line 1: "a      c       b"
232 SELECT * FROM header_copytest ORDER BY a;
233  a |  c  
234 ---+-----
235  1 | foo
236  3 | bar
237  5 | baz
238  7 | foo
239  8 | foo
240 (5 rows)
242 drop table header_copytest;
243 -- test COPY with overlong column defaults
244 create temp table oversized_column_default (
245     col1 varchar(5) DEFAULT 'more than 5 chars',
246     col2 varchar(5));
247 -- normal COPY should work
248 copy oversized_column_default from stdin;
249 -- error if the column is excluded
250 copy oversized_column_default (col2) from stdin;
251 ERROR:  value too long for type character varying(5)
253 invalid command \.
254 -- error if the DEFAULT option is given
255 copy oversized_column_default from stdin (default '');
256 ERROR:  value too long for type character varying(5)
258 invalid command \.
259 drop table oversized_column_default;
261 -- Create partitioned table that does not allow bulk insertions, to test bugs
262 -- related to the reuse of BulkInsertState across partitions (only done when
263 -- not using bulk insert).  Switching between partitions often makes it more
264 -- likely to encounter these bugs, so we just switch on roughly every insert
265 -- by having an even/odd number partition and inserting evenly distributed
266 -- data.
268 CREATE TABLE parted_si (
269   id int not null,
270   data text not null,
271   -- prevent use of bulk insert by having a volatile function
272   rand float8 not null default random()
274 PARTITION BY LIST((id % 2));
275 CREATE TABLE parted_si_p_even PARTITION OF parted_si FOR VALUES IN (0);
276 CREATE TABLE parted_si_p_odd PARTITION OF parted_si FOR VALUES IN (1);
277 -- Test that bulk relation extension handles reusing a single BulkInsertState
278 -- across partitions.  Without the fix applied, this reliably reproduces
279 -- #18130 unless shared_buffers is extremely small (preventing any use of bulk
280 -- relation extension). See
281 -- https://postgr.es/m/18130-7a86a7356a75209d%40postgresql.org
282 -- https://postgr.es/m/257696.1695670946%40sss.pgh.pa.us
283 \set filename :abs_srcdir '/data/desc.data'
284 COPY parted_si(id, data) FROM :'filename';
285 -- An earlier bug (see commit b1ecb9b3fcf) could end up using a buffer from
286 -- the wrong partition. This test is *not* guaranteed to trigger that bug, but
287 -- does so when shared_buffers is small enough.  To test if we encountered the
288 -- bug, check that the partition condition isn't violated.
289 SELECT tableoid::regclass, id % 2 = 0 is_even, count(*) from parted_si GROUP BY 1, 2 ORDER BY 1;
290      tableoid     | is_even | count 
291 ------------------+---------+-------
292  parted_si_p_even | t       |  5000
293  parted_si_p_odd  | f       |  5000
294 (2 rows)
296 DROP TABLE parted_si;