1
1
--
2
2
-- Test foreign-data wrapper file_fdw.
3
3
--
4
+ -- directory paths are passed to us in environment variables
5
+ \getenv abs_srcdir PG_ABS_SRCDIR
4
6
-- Clean up in case a prior regression run failed
5
7
SET client_min_messages TO 'warning';
6
8
DROP ROLE IF EXISTS regress_file_fdw_superuser, regress_file_fdw_user, regress_no_priv_user;
@@ -10,6 +12,21 @@ CREATE ROLE regress_file_fdw_user LOGIN; -- has priv and user map
10
12
CREATE ROLE regress_no_priv_user LOGIN; -- has priv but no user mapping
11
13
-- Install file_fdw
12
14
CREATE EXTENSION file_fdw;
15
+ -- create function to filter unstable results of EXPLAIN
16
+ CREATE FUNCTION explain_filter(text) RETURNS setof text
17
+ LANGUAGE plpgsql AS
18
+ $$
19
+ declare
20
+ ln text;
21
+ begin
22
+ for ln in execute $1
23
+ loop
24
+ -- Remove the path portion of foreign file names
25
+ ln := regexp_replace(ln, 'Foreign File: .*/([a-z.]+)$', 'Foreign File: .../\1');
26
+ return next ln;
27
+ end loop;
28
+ end;
29
+ $$;
13
30
-- regress_file_fdw_superuser owns fdw-related objects
14
31
SET ROLE regress_file_fdw_superuser;
15
32
CREATE SERVER file_server FOREIGN DATA WRAPPER file_fdw;
@@ -77,32 +94,36 @@ CREATE FOREIGN TABLE tbl () SERVER file_server OPTIONS (format 'csv', null '
77
94
ERROR: COPY null representation cannot use newline or carriage return
78
95
CREATE FOREIGN TABLE tbl () SERVER file_server; -- ERROR
79
96
ERROR: either filename or program is required for file_fdw foreign tables
97
+ \set filename :abs_srcdir '/data/agg.data'
80
98
CREATE FOREIGN TABLE agg_text (
81
99
a int2 CHECK (a >= 0),
82
100
b float4
83
101
) SERVER file_server
84
- OPTIONS (format 'text', filename '@abs_srcdir@/data/agg.data ', delimiter ' ', null '\N');
102
+ OPTIONS (format 'text', filename :'filename ', delimiter ' ', null '\N');
85
103
GRANT SELECT ON agg_text TO regress_file_fdw_user;
104
+ \set filename :abs_srcdir '/data/agg.csv'
86
105
CREATE FOREIGN TABLE agg_csv (
87
106
a int2,
88
107
b float4
89
108
) SERVER file_server
90
- OPTIONS (format 'csv', filename '@abs_srcdir@/data/agg.csv ', header 'true', delimiter ';', quote '@', escape '"', null '');
109
+ OPTIONS (format 'csv', filename :'filename ', header 'true', delimiter ';', quote '@', escape '"', null '');
91
110
ALTER FOREIGN TABLE agg_csv ADD CHECK (a >= 0);
111
+ \set filename :abs_srcdir '/data/agg.bad'
92
112
CREATE FOREIGN TABLE agg_bad (
93
113
a int2,
94
114
b float4
95
115
) SERVER file_server
96
- OPTIONS (format 'csv', filename '@abs_srcdir@/data/agg.bad ', header 'true', delimiter ';', quote '@', escape '"', null '');
116
+ OPTIONS (format 'csv', filename :'filename ', header 'true', delimiter ';', quote '@', escape '"', null '');
97
117
ALTER FOREIGN TABLE agg_bad ADD CHECK (a >= 0);
98
118
-- per-column options tests
119
+ \set filename :abs_srcdir '/data/text.csv'
99
120
CREATE FOREIGN TABLE text_csv (
100
121
word1 text OPTIONS (force_not_null 'true'),
101
122
word2 text OPTIONS (force_not_null 'off'),
102
123
word3 text OPTIONS (force_null 'true'),
103
124
word4 text OPTIONS (force_null 'off')
104
125
) SERVER file_server
105
- OPTIONS (format 'text', filename '@abs_srcdir@/data/text.csv ', null 'NULL');
126
+ OPTIONS (format 'text', filename :'filename ', null 'NULL');
106
127
SELECT * FROM text_csv; -- ERROR
107
128
ERROR: COPY force not null available only in CSV mode
108
129
ALTER FOREIGN TABLE text_csv OPTIONS (SET format 'csv');
@@ -176,10 +197,10 @@ ERROR: invalid input syntax for type real: "aaa"
176
197
CONTEXT: COPY agg_bad, line 3, column b: "aaa"
177
198
-- misc query tests
178
199
\t on
179
- EXPLAIN (VERBOSE, COSTS FALSE) SELECT * FROM agg_csv;
200
+ SELECT explain_filter(' EXPLAIN (VERBOSE, COSTS FALSE) SELECT * FROM agg_csv') ;
180
201
Foreign Scan on public.agg_csv
181
202
Output: a, b
182
- Foreign File: @abs_srcdir@/data /agg.csv
203
+ Foreign File: ... /agg.csv
183
204
184
205
\t off
185
206
PREPARE st(int) AS SELECT * FROM agg_csv WHERE a = $1;
@@ -226,11 +247,11 @@ COPY agg_csv FROM STDIN;
226
247
ERROR: cannot insert into foreign table "agg_csv"
227
248
-- constraint exclusion tests
228
249
\t on
229
- EXPLAIN (VERBOSE, COSTS FALSE) SELECT * FROM agg_csv WHERE a < 0;
250
+ SELECT explain_filter(' EXPLAIN (VERBOSE, COSTS FALSE) SELECT * FROM agg_csv WHERE a < 0') ;
230
251
Foreign Scan on public.agg_csv
231
252
Output: a, b
232
253
Filter: (agg_csv.a < 0)
233
- Foreign File: @abs_srcdir@/data /agg.csv
254
+ Foreign File: ... /agg.csv
234
255
235
256
\t off
236
257
SELECT * FROM agg_csv WHERE a < 0;
@@ -240,7 +261,7 @@ SELECT * FROM agg_csv WHERE a < 0;
240
261
241
262
SET constraint_exclusion = 'on';
242
263
\t on
243
- EXPLAIN (VERBOSE, COSTS FALSE) SELECT * FROM agg_csv WHERE a < 0;
264
+ SELECT explain_filter(' EXPLAIN (VERBOSE, COSTS FALSE) SELECT * FROM agg_csv WHERE a < 0') ;
244
265
Result
245
266
Output: a, b
246
267
One-Time Filter: false
@@ -295,8 +316,9 @@ DROP TABLE agg;
295
316
-- declarative partitioning tests
296
317
SET ROLE regress_file_fdw_superuser;
297
318
CREATE TABLE pt (a int, b text) partition by list (a);
319
+ \set filename :abs_srcdir '/data/list1.csv'
298
320
CREATE FOREIGN TABLE p1 partition of pt for values in (1) SERVER file_server
299
- OPTIONS (format 'csv', filename '@abs_srcdir@/data/list1.csv ', delimiter ',');
321
+ OPTIONS (format 'csv', filename :'filename ', delimiter ',');
300
322
CREATE TABLE p2 partition of pt for values in (2);
301
323
SELECT tableoid::regclass, * FROM pt;
302
324
tableoid | a | b
@@ -317,10 +339,12 @@ SELECT tableoid::regclass, * FROM p2;
317
339
----------+---+---
318
340
(0 rows)
319
341
320
- COPY pt FROM '@abs_srcdir@/data/list2.bad' with (format 'csv', delimiter ','); -- ERROR
342
+ \set filename :abs_srcdir '/data/list2.bad'
343
+ COPY pt FROM :'filename' with (format 'csv', delimiter ','); -- ERROR
321
344
ERROR: cannot insert into foreign table "p1"
322
345
CONTEXT: COPY pt, line 2: "1,qux"
323
- COPY pt FROM '@abs_srcdir@/data/list2.csv' with (format 'csv', delimiter ',');
346
+ \set filename :abs_srcdir '/data/list2.csv'
347
+ COPY pt FROM :'filename' with (format 'csv', delimiter ',');
324
348
SELECT tableoid::regclass, * FROM pt;
325
349
tableoid | a | b
326
350
----------+---+-----
@@ -376,8 +400,9 @@ SELECT tableoid::regclass, * FROM p2;
376
400
377
401
DROP TABLE pt;
378
402
-- generated column tests
403
+ \set filename :abs_srcdir '/data/list1.csv'
379
404
CREATE FOREIGN TABLE gft1 (a int, b text, c text GENERATED ALWAYS AS ('foo') STORED) SERVER file_server
380
- OPTIONS (format 'csv', filename '@abs_srcdir@/data/list1.csv ', delimiter ',');
405
+ OPTIONS (format 'csv', filename :'filename ', delimiter ',');
381
406
SELECT a, c FROM gft1;
382
407
a | c
383
408
---+--------
@@ -412,11 +437,11 @@ SELECT * FROM agg_text ORDER BY a; -- ERROR
412
437
ERROR: permission denied for foreign table agg_text
413
438
SET ROLE regress_file_fdw_user;
414
439
\t on
415
- EXPLAIN (VERBOSE, COSTS FALSE) SELECT * FROM agg_text WHERE a > 0;
440
+ SELECT explain_filter(' EXPLAIN (VERBOSE, COSTS FALSE) SELECT * FROM agg_text WHERE a > 0') ;
416
441
Foreign Scan on public.agg_text
417
442
Output: a, b
418
443
Filter: (agg_text.a > 0)
419
- Foreign File: @abs_srcdir@/data /agg.data
444
+ Foreign File: ... /agg.data
420
445
421
446
\t off
422
447
-- file FDW allows foreign tables to be accessed without user mapping
0 commit comments