PolarDB-for-PostgreSQL
441 строка · 15.3 Кб
1--
2-- Test foreign-data wrapper file_fdw.
3--
4-- Clean up in case a prior regression run failed
5SET client_min_messages TO 'warning';
6DROP ROLE IF EXISTS regress_file_fdw_superuser, regress_file_fdw_user, regress_no_priv_user;
7RESET client_min_messages;
8CREATE ROLE regress_file_fdw_superuser LOGIN SUPERUSER; -- is a superuser
9CREATE ROLE regress_file_fdw_user LOGIN; -- has priv and user mapping
10CREATE ROLE regress_no_priv_user LOGIN; -- has priv but no user mapping
11-- Install file_fdw
12CREATE EXTENSION file_fdw;
13-- regress_file_fdw_superuser owns fdw-related objects
14SET ROLE regress_file_fdw_superuser;
15CREATE SERVER file_server FOREIGN DATA WRAPPER file_fdw;
16-- privilege tests
17SET ROLE regress_file_fdw_user;
18CREATE FOREIGN DATA WRAPPER file_fdw2 HANDLER file_fdw_handler VALIDATOR file_fdw_validator; -- ERROR
19ERROR: permission denied to create foreign-data wrapper "file_fdw2"
20HINT: Must be superuser to create a foreign-data wrapper.
21CREATE SERVER file_server2 FOREIGN DATA WRAPPER file_fdw; -- ERROR
22ERROR: permission denied for foreign-data wrapper file_fdw
23CREATE USER MAPPING FOR regress_file_fdw_user SERVER file_server; -- ERROR
24ERROR: permission denied for foreign server file_server
25SET ROLE regress_file_fdw_superuser;
26GRANT USAGE ON FOREIGN SERVER file_server TO regress_file_fdw_user;
27SET ROLE regress_file_fdw_user;
28CREATE USER MAPPING FOR regress_file_fdw_user SERVER file_server;
29-- create user mappings and grant privilege to test users
30SET ROLE regress_file_fdw_superuser;
31CREATE USER MAPPING FOR regress_file_fdw_superuser SERVER file_server;
32CREATE USER MAPPING FOR regress_no_priv_user SERVER file_server;
33-- validator tests
34CREATE FOREIGN TABLE tbl () SERVER file_server OPTIONS (format 'xml'); -- ERROR
35ERROR: COPY format "xml" not recognized
36CREATE FOREIGN TABLE tbl () SERVER file_server OPTIONS (format 'text', header 'true'); -- ERROR
37ERROR: COPY HEADER available only in CSV mode
38CREATE FOREIGN TABLE tbl () SERVER file_server OPTIONS (format 'text', quote ':'); -- ERROR
39ERROR: COPY quote available only in CSV mode
40CREATE FOREIGN TABLE tbl () SERVER file_server OPTIONS (format 'text', escape ':'); -- ERROR
41ERROR: COPY escape available only in CSV mode
42CREATE FOREIGN TABLE tbl () SERVER file_server OPTIONS (format 'binary', header 'true'); -- ERROR
43ERROR: COPY HEADER available only in CSV mode
44CREATE FOREIGN TABLE tbl () SERVER file_server OPTIONS (format 'binary', quote ':'); -- ERROR
45ERROR: COPY quote available only in CSV mode
46CREATE FOREIGN TABLE tbl () SERVER file_server OPTIONS (format 'binary', escape ':'); -- ERROR
47ERROR: COPY escape available only in CSV mode
48CREATE FOREIGN TABLE tbl () SERVER file_server OPTIONS (format 'text', delimiter 'a'); -- ERROR
49ERROR: COPY delimiter cannot be "a"
50CREATE FOREIGN TABLE tbl () SERVER file_server OPTIONS (format 'text', escape '-'); -- ERROR
51ERROR: COPY escape available only in CSV mode
52CREATE FOREIGN TABLE tbl () SERVER file_server OPTIONS (format 'csv', quote '-', null '=-='); -- ERROR
53ERROR: CSV quote character must not appear in the NULL specification
54CREATE FOREIGN TABLE tbl () SERVER file_server OPTIONS (format 'csv', delimiter '-', null '=-='); -- ERROR
55ERROR: COPY delimiter must not appear in the NULL specification
56CREATE FOREIGN TABLE tbl () SERVER file_server OPTIONS (format 'csv', delimiter '-', quote '-'); -- ERROR
57ERROR: COPY delimiter and quote must be different
58CREATE FOREIGN TABLE tbl () SERVER file_server OPTIONS (format 'csv', delimiter '---'); -- ERROR
59ERROR: COPY delimiter must be a single one-byte character
60CREATE FOREIGN TABLE tbl () SERVER file_server OPTIONS (format 'csv', quote '---'); -- ERROR
61ERROR: COPY quote must be a single one-byte character
62CREATE FOREIGN TABLE tbl () SERVER file_server OPTIONS (format 'csv', escape '---'); -- ERROR
63ERROR: COPY escape must be a single one-byte character
64CREATE FOREIGN TABLE tbl () SERVER file_server OPTIONS (format 'text', delimiter '\'); -- ERROR
65ERROR: COPY delimiter cannot be "\"
66CREATE FOREIGN TABLE tbl () SERVER file_server OPTIONS (format 'text', delimiter '.'); -- ERROR
67ERROR: COPY delimiter cannot be "."
68CREATE FOREIGN TABLE tbl () SERVER file_server OPTIONS (format 'text', delimiter '1'); -- ERROR
69ERROR: COPY delimiter cannot be "1"
70CREATE FOREIGN TABLE tbl () SERVER file_server OPTIONS (format 'text', delimiter 'a'); -- ERROR
71ERROR: COPY delimiter cannot be "a"
72CREATE FOREIGN TABLE tbl () SERVER file_server OPTIONS (format 'csv', delimiter '
73'); -- ERROR
74ERROR: COPY delimiter cannot be newline or carriage return
75CREATE FOREIGN TABLE tbl () SERVER file_server OPTIONS (format 'csv', null '
76'); -- ERROR
77ERROR: COPY null representation cannot use newline or carriage return
78CREATE FOREIGN TABLE tbl () SERVER file_server; -- ERROR
79ERROR: either filename or program is required for file_fdw foreign tables
80CREATE FOREIGN TABLE agg_text (
81a int2 CHECK (a >= 0),
82b float4
83) SERVER file_server
84OPTIONS (format 'text', filename '@abs_srcdir@/data/agg.data', delimiter ' ', null '\N');
85GRANT SELECT ON agg_text TO regress_file_fdw_user;
86CREATE FOREIGN TABLE agg_csv (
87a int2,
88b float4
89) SERVER file_server
90OPTIONS (format 'csv', filename '@abs_srcdir@/data/agg.csv', header 'true', delimiter ';', quote '@', escape '"', null '');
91ALTER FOREIGN TABLE agg_csv ADD CHECK (a >= 0);
92CREATE FOREIGN TABLE agg_bad (
93a int2,
94b float4
95) SERVER file_server
96OPTIONS (format 'csv', filename '@abs_srcdir@/data/agg.bad', header 'true', delimiter ';', quote '@', escape '"', null '');
97ALTER FOREIGN TABLE agg_bad ADD CHECK (a >= 0);
98-- per-column options tests
99CREATE FOREIGN TABLE text_csv (
100word1 text OPTIONS (force_not_null 'true'),
101word2 text OPTIONS (force_not_null 'off'),
102word3 text OPTIONS (force_null 'true'),
103word4 text OPTIONS (force_null 'off')
104) SERVER file_server
105OPTIONS (format 'text', filename '@abs_srcdir@/data/text.csv', null 'NULL');
106SELECT * FROM text_csv; -- ERROR
107ERROR: COPY force not null available only in CSV mode
108ALTER FOREIGN TABLE text_csv OPTIONS (SET format 'csv');
109\pset null _null_
110SELECT * FROM text_csv;
111word1 | word2 | word3 | word4
112-------+--------+--------+--------
113AAA | aaa | 123 |
114XYZ | xyz | | 321
115NULL | _null_ | _null_ | _null_
116NULL | _null_ | _null_ | _null_
117ABC | abc | |
118(5 rows)
119
120-- force_not_null and force_null can be used together on the same column
121ALTER FOREIGN TABLE text_csv ALTER COLUMN word1 OPTIONS (force_null 'true');
122ALTER FOREIGN TABLE text_csv ALTER COLUMN word3 OPTIONS (force_not_null 'true');
123-- force_not_null is not allowed to be specified at any foreign object level:
124ALTER FOREIGN DATA WRAPPER file_fdw OPTIONS (ADD force_not_null '*'); -- ERROR
125ERROR: invalid option "force_not_null"
126HINT: There are no valid options in this context.
127ALTER SERVER file_server OPTIONS (ADD force_not_null '*'); -- ERROR
128ERROR: invalid option "force_not_null"
129HINT: There are no valid options in this context.
130CREATE USER MAPPING FOR public SERVER file_server OPTIONS (force_not_null '*'); -- ERROR
131ERROR: invalid option "force_not_null"
132HINT: There are no valid options in this context.
133CREATE FOREIGN TABLE tbl () SERVER file_server OPTIONS (force_not_null '*'); -- ERROR
134ERROR: invalid option "force_not_null"
135HINT: Valid options in this context are: filename, program, format, header, delimiter, quote, escape, null, encoding
136-- force_null is not allowed to be specified at any foreign object level:
137ALTER FOREIGN DATA WRAPPER file_fdw OPTIONS (ADD force_null '*'); -- ERROR
138ERROR: invalid option "force_null"
139HINT: There are no valid options in this context.
140ALTER SERVER file_server OPTIONS (ADD force_null '*'); -- ERROR
141ERROR: invalid option "force_null"
142HINT: There are no valid options in this context.
143CREATE USER MAPPING FOR public SERVER file_server OPTIONS (force_null '*'); -- ERROR
144ERROR: invalid option "force_null"
145HINT: There are no valid options in this context.
146CREATE FOREIGN TABLE tbl () SERVER file_server OPTIONS (force_null '*'); -- ERROR
147ERROR: invalid option "force_null"
148HINT: Valid options in this context are: filename, program, format, header, delimiter, quote, escape, null, encoding
149-- basic query tests
150SELECT * FROM agg_text WHERE b > 10.0 ORDER BY a;
151a | b
152-----+--------
15342 | 324.78
154100 | 99.097
155(2 rows)
156
157SELECT * FROM agg_csv ORDER BY a;
158a | b
159-----+---------
1600 | 0.09561
16142 | 324.78
162100 | 99.097
163(3 rows)
164
165SELECT * FROM agg_csv c JOIN agg_text t ON (t.a = c.a) ORDER BY c.a;
166a | b | a | b
167-----+---------+-----+---------
1680 | 0.09561 | 0 | 0.09561
16942 | 324.78 | 42 | 324.78
170100 | 99.097 | 100 | 99.097
171(3 rows)
172
173-- error context report tests
174SELECT * FROM agg_bad; -- ERROR
175ERROR: invalid input syntax for type real: "aaa"
176CONTEXT: COPY agg_bad, line 3, column b: "aaa"
177-- misc query tests
178\t on
179EXPLAIN (VERBOSE, COSTS FALSE) SELECT * FROM agg_csv;
180Foreign Scan on public.agg_csv
181Output: a, b
182Foreign File: @abs_srcdir@/data/agg.csv
183
184\t off
185PREPARE st(int) AS SELECT * FROM agg_csv WHERE a = $1;
186EXECUTE st(100);
187a | b
188-----+--------
189100 | 99.097
190(1 row)
191
192EXECUTE st(100);
193a | b
194-----+--------
195100 | 99.097
196(1 row)
197
198DEALLOCATE st;
199-- tableoid
200SELECT tableoid::regclass, b FROM agg_csv;
201tableoid | b
202----------+---------
203agg_csv | 99.097
204agg_csv | 0.09561
205agg_csv | 324.78
206(3 rows)
207
208-- updates aren't supported
209INSERT INTO agg_csv VALUES(1,2.0);
210ERROR: cannot insert into foreign table "agg_csv"
211UPDATE agg_csv SET a = 1;
212ERROR: cannot update foreign table "agg_csv"
213DELETE FROM agg_csv WHERE a = 100;
214ERROR: cannot delete from foreign table "agg_csv"
215-- but this should be allowed
216SELECT * FROM agg_csv FOR UPDATE;
217a | b
218-----+---------
219100 | 99.097
2200 | 0.09561
22142 | 324.78
222(3 rows)
223
224-- copy from isn't supported either
225COPY agg_csv FROM STDIN;
226ERROR: cannot insert into foreign table "agg_csv"
227-- constraint exclusion tests
228\t on
229EXPLAIN (VERBOSE, COSTS FALSE) SELECT * FROM agg_csv WHERE a < 0;
230Foreign Scan on public.agg_csv
231Output: a, b
232Filter: (agg_csv.a < 0)
233Foreign File: @abs_srcdir@/data/agg.csv
234
235\t off
236SELECT * FROM agg_csv WHERE a < 0;
237a | b
238---+---
239(0 rows)
240
241SET constraint_exclusion = 'on';
242\t on
243EXPLAIN (VERBOSE, COSTS FALSE) SELECT * FROM agg_csv WHERE a < 0;
244Result
245Output: a, b
246One-Time Filter: false
247
248\t off
249SELECT * FROM agg_csv WHERE a < 0;
250a | b
251---+---
252(0 rows)
253
254RESET constraint_exclusion;
255-- table inheritance tests
256CREATE TABLE agg (a int2, b float4);
257ALTER FOREIGN TABLE agg_csv INHERIT agg;
258SELECT tableoid::regclass, * FROM agg;
259tableoid | a | b
260----------+-----+---------
261agg_csv | 100 | 99.097
262agg_csv | 0 | 0.09561
263agg_csv | 42 | 324.78
264(3 rows)
265
266SELECT tableoid::regclass, * FROM agg_csv;
267tableoid | a | b
268----------+-----+---------
269agg_csv | 100 | 99.097
270agg_csv | 0 | 0.09561
271agg_csv | 42 | 324.78
272(3 rows)
273
274SELECT tableoid::regclass, * FROM ONLY agg;
275tableoid | a | b
276----------+---+---
277(0 rows)
278
279-- updates aren't supported
280UPDATE agg SET a = 1;
281ERROR: cannot update foreign table "agg_csv"
282DELETE FROM agg WHERE a = 100;
283ERROR: cannot delete from foreign table "agg_csv"
284-- but this should be allowed
285SELECT tableoid::regclass, * FROM agg FOR UPDATE;
286tableoid | a | b
287----------+-----+---------
288agg_csv | 100 | 99.097
289agg_csv | 0 | 0.09561
290agg_csv | 42 | 324.78
291(3 rows)
292
293ALTER FOREIGN TABLE agg_csv NO INHERIT agg;
294DROP TABLE agg;
295-- declarative partitioning tests
296SET ROLE regress_file_fdw_superuser;
297CREATE TABLE pt (a int, b text) partition by list (a);
298CREATE FOREIGN TABLE p1 partition of pt for values in (1) SERVER file_server
299OPTIONS (format 'csv', filename '@abs_srcdir@/data/list1.csv', delimiter ',');
300CREATE TABLE p2 partition of pt for values in (2);
301SELECT tableoid::regclass, * FROM pt;
302tableoid | a | b
303----------+---+-----
304p1 | 1 | foo
305p1 | 1 | bar
306(2 rows)
307
308SELECT tableoid::regclass, * FROM p1;
309tableoid | a | b
310----------+---+-----
311p1 | 1 | foo
312p1 | 1 | bar
313(2 rows)
314
315SELECT tableoid::regclass, * FROM p2;
316tableoid | a | b
317----------+---+---
318(0 rows)
319
320COPY pt FROM '@abs_srcdir@/data/list2.bad' with (format 'csv', delimiter ','); -- ERROR
321ERROR: cannot insert into foreign table "p1"
322CONTEXT: COPY pt, line 2: "1,qux"
323COPY pt FROM '@abs_srcdir@/data/list2.csv' with (format 'csv', delimiter ',');
324SELECT tableoid::regclass, * FROM pt;
325tableoid | a | b
326----------+---+-----
327p1 | 1 | foo
328p1 | 1 | bar
329p2 | 2 | baz
330p2 | 2 | qux
331(4 rows)
332
333SELECT tableoid::regclass, * FROM p1;
334tableoid | a | b
335----------+---+-----
336p1 | 1 | foo
337p1 | 1 | bar
338(2 rows)
339
340SELECT tableoid::regclass, * FROM p2;
341tableoid | a | b
342----------+---+-----
343p2 | 2 | baz
344p2 | 2 | qux
345(2 rows)
346
347INSERT INTO pt VALUES (1, 'xyzzy'); -- ERROR
348ERROR: cannot insert into foreign table "p1"
349INSERT INTO pt VALUES (2, 'xyzzy');
350UPDATE pt set a = 1 where a = 2; -- ERROR
351ERROR: cannot insert into foreign table "p1"
352SELECT tableoid::regclass, * FROM pt;
353tableoid | a | b
354----------+---+-------
355p1 | 1 | foo
356p1 | 1 | bar
357p2 | 2 | baz
358p2 | 2 | qux
359p2 | 2 | xyzzy
360(5 rows)
361
362SELECT tableoid::regclass, * FROM p1;
363tableoid | a | b
364----------+---+-----
365p1 | 1 | foo
366p1 | 1 | bar
367(2 rows)
368
369SELECT tableoid::regclass, * FROM p2;
370tableoid | a | b
371----------+---+-------
372p2 | 2 | baz
373p2 | 2 | qux
374p2 | 2 | xyzzy
375(3 rows)
376
377DROP TABLE pt;
378-- privilege tests
379SET ROLE regress_file_fdw_superuser;
380SELECT * FROM agg_text ORDER BY a;
381a | b
382-----+---------
3830 | 0.09561
38442 | 324.78
38556 | 7.8
386100 | 99.097
387(4 rows)
388
389SET ROLE regress_file_fdw_user;
390SELECT * FROM agg_text ORDER BY a;
391a | b
392-----+---------
3930 | 0.09561
39442 | 324.78
39556 | 7.8
396100 | 99.097
397(4 rows)
398
399SET ROLE regress_no_priv_user;
400SELECT * FROM agg_text ORDER BY a; -- ERROR
401ERROR: permission denied for foreign table agg_text
402SET ROLE regress_file_fdw_user;
403\t on
404EXPLAIN (VERBOSE, COSTS FALSE) SELECT * FROM agg_text WHERE a > 0;
405Foreign Scan on public.agg_text
406Output: a, b
407Filter: (agg_text.a > 0)
408Foreign File: @abs_srcdir@/data/agg.data
409
410\t off
411-- file FDW allows foreign tables to be accessed without user mapping
412DROP USER MAPPING FOR regress_file_fdw_user SERVER file_server;
413SELECT * FROM agg_text ORDER BY a;
414a | b
415-----+---------
4160 | 0.09561
41742 | 324.78
41856 | 7.8
419100 | 99.097
420(4 rows)
421
422-- privilege tests for object
423SET ROLE regress_file_fdw_superuser;
424ALTER FOREIGN TABLE agg_text OWNER TO regress_file_fdw_user;
425ALTER FOREIGN TABLE agg_text OPTIONS (SET format 'text');
426SET ROLE regress_file_fdw_user;
427ALTER FOREIGN TABLE agg_text OPTIONS (SET format 'text');
428ERROR: only superuser or a member of the pg_read_server_files role may specify the filename option of a file_fdw foreign table
429SET ROLE regress_file_fdw_superuser;
430-- cleanup
431RESET ROLE;
432DROP EXTENSION file_fdw CASCADE;
433NOTICE: drop cascades to 7 other objects
434DETAIL: drop cascades to server file_server
435drop cascades to user mapping for regress_file_fdw_superuser on server file_server
436drop cascades to user mapping for regress_no_priv_user on server file_server
437drop cascades to foreign table agg_text
438drop cascades to foreign table agg_csv
439drop cascades to foreign table agg_bad
440drop cascades to foreign table text_csv
441DROP ROLE regress_file_fdw_superuser, regress_file_fdw_user, regress_no_priv_user;
442