--- --- Test foreign-data wrapper file_fdw. --- --- Clean up in case a prior regression run failed SET client_min_messages TO 'error'; DROP ROLE IF EXISTS file_fdw_superuser, file_fdw_user, no_priv_user; RESET client_min_messages; CREATE ROLE file_fdw_superuser LOGIN SYSADMIN PASSWORD 'Gauss_123'; -- is a sysadmin CREATE ROLE file_fdw_user LOGIN PGUSER PASSWORD 'Gauss_123'; -- has priv and user mapping CREATE ROLE no_priv_user LOGIN PASSWORD 'Gauss_123'; -- has priv but no user mapping -- file_fdw_superuser owns fdw-related objects SET ROLE file_fdw_superuser PASSWORD 'Gauss_123'; CREATE SERVER file_server FOREIGN DATA WRAPPER file_fdw; -- privilege tests SET ROLE file_fdw_user PASSWORD 'Gauss_123'; CREATE FOREIGN DATA WRAPPER file_fdw2 HANDLER file_fdw_handler VALIDATOR file_fdw_validator; -- ERROR ERROR: permission denied to create foreign-data wrapper "file_fdw2" HINT: Must be system admin to create a foreign-data wrapper. CREATE SERVER file_server2 FOREIGN DATA WRAPPER file_fdw; -- ERROR ERROR: permission denied for foreign-data wrapper file_fdw CREATE USER MAPPING FOR file_fdw_user SERVER file_server; -- ERROR ERROR: permission denied for foreign server file_server SET ROLE file_fdw_superuser PASSWORD 'Gauss_123'; GRANT USAGE ON FOREIGN SERVER file_server TO file_fdw_user; SET ROLE file_fdw_user PASSWORD 'Gauss_123'; CREATE USER MAPPING FOR file_fdw_user SERVER file_server; -- create user mappings and grant privilege to test users SET ROLE file_fdw_superuser PASSWORD 'Gauss_123'; CREATE USER MAPPING FOR file_fdw_superuser SERVER file_server; CREATE USER MAPPING FOR no_priv_user SERVER file_server; -- validator tests CREATE FOREIGN TABLE tbl (a int) SERVER file_server OPTIONS (format 'xml'); -- ERROR ERROR: COPY format "xml" not recognized CREATE FOREIGN TABLE tbl (a int) SERVER file_server OPTIONS (format 'text', header 'true'); -- ERROR ERROR: COPY HEADER available only in CSV mode CREATE FOREIGN TABLE tbl (a int) SERVER file_server OPTIONS (format 'text', quote ':'); -- ERROR ERROR: COPY quote available only in CSV mode CREATE FOREIGN TABLE tbl (a int) SERVER file_server OPTIONS (format 'text', escape ':'); -- ERROR ERROR: COPY escape available only in CSV mode CREATE FOREIGN TABLE tbl (a int) SERVER file_server OPTIONS (format 'binary', header 'true'); -- ERROR ERROR: COPY HEADER available only in CSV mode CREATE FOREIGN TABLE tbl (a int) SERVER file_server OPTIONS (format 'binary', quote ':'); -- ERROR ERROR: COPY quote available only in CSV mode CREATE FOREIGN TABLE tbl (a int) SERVER file_server OPTIONS (format 'binary', escape ':'); -- ERROR ERROR: COPY escape available only in CSV mode CREATE FOREIGN TABLE tbl (a int) SERVER file_server OPTIONS (format 'text', delimiter 'a'); -- ERROR ERROR: delimiter "a" cannot contain any characters in"\.abcdefghijklmnopqrstuvwxyz0123456789" CREATE FOREIGN TABLE tbl (a int) SERVER file_server OPTIONS (format 'text', escape '-'); -- ERROR ERROR: COPY escape available only in CSV mode CREATE FOREIGN TABLE tbl (a int) SERVER file_server OPTIONS (format 'csv', quote '-', null '=-='); -- ERROR ERROR: CSV quote character must not appear in the NULL specification CREATE FOREIGN TABLE tbl (a int) SERVER file_server OPTIONS (format 'csv', delimiter '-', null '=-='); -- ERROR ERROR: COPY delimiter must not appear in the NULL specification CREATE FOREIGN TABLE tbl (a int) SERVER file_server OPTIONS (format 'csv', delimiter '-', quote '-'); -- ERROR ERROR: delimiter cannot contain quote character CREATE FOREIGN TABLE tbl (a int) SERVER file_server OPTIONS (format 'csv', delimiter '---'); -- ERROR ERROR: filename is required for file_fdw foreign tables CREATE FOREIGN TABLE tbl (a int) SERVER file_server OPTIONS (format 'csv', quote '---'); -- ERROR ERROR: COPY quote must be a single one-byte character CREATE FOREIGN TABLE tbl (a int) SERVER file_server OPTIONS (format 'csv', escape '---'); -- ERROR ERROR: COPY escape must be a single one-byte character CREATE FOREIGN TABLE tbl (a int) SERVER file_server OPTIONS (format 'text', delimiter '\'); -- ERROR ERROR: delimiter "\" cannot contain any characters in"\.abcdefghijklmnopqrstuvwxyz0123456789" CREATE FOREIGN TABLE tbl (a int) SERVER file_server OPTIONS (format 'text', delimiter '.'); -- ERROR ERROR: delimiter "." cannot contain any characters in"\.abcdefghijklmnopqrstuvwxyz0123456789" CREATE FOREIGN TABLE tbl (a int) SERVER file_server OPTIONS (format 'text', delimiter '1'); -- ERROR ERROR: delimiter "1" cannot contain any characters in"\.abcdefghijklmnopqrstuvwxyz0123456789" CREATE FOREIGN TABLE tbl (a int) SERVER file_server OPTIONS (format 'text', delimiter 'a'); -- ERROR ERROR: delimiter "a" cannot contain any characters in"\.abcdefghijklmnopqrstuvwxyz0123456789" CREATE FOREIGN TABLE tbl (a int) SERVER file_server OPTIONS (format 'csv', delimiter ' '); -- ERROR ERROR: COPY delimiter cannot be newline or carriage return CREATE FOREIGN TABLE tbl (a int) SERVER file_server OPTIONS (format 'csv', null ' '); -- ERROR ERROR: COPY null representation cannot use newline or carriage return CREATE FOREIGN TABLE tbl (a int) SERVER file_server; -- ERROR ERROR: filename is required for file_fdw foreign tables CREATE FOREIGN TABLE tbl (a int2,b float4) SERVER file_server OPTIONS (format 'text', filename '', delimiter ' ', null '\n'); -- SUCCESS DROP FOREIGN TABLE tbl; CREATE FOREIGN TABLE tbl (id int) SERVER file_server OPTIONS (filename '', format 'text'); -- SUCCESS DROP FOREIGN TABLE tbl; CREATE FOREIGN TABLE tbl (id int) SERVER file_server OPTIONS (filename '', format 'binary'); -- SUCCESS DROP FOREIGN TABLE tbl; CREATE FOREIGN TABLE tbl (id int) SERVER file_server OPTIONS (filename '', format 'csv'); -- SUCCESS DROP FOREIGN TABLE tbl; CREATE FOREIGN TABLE tbl (id int) SERVER file_server OPTIONS (filename '',format 'text', header 'false'); -- SUCCESS DROP FOREIGN TABLE tbl; CREATE FOREIGN TABLE tbl (id int) SERVER file_server OPTIONS (filename '',format 'binary', header 'off'); -- SUCCESS DROP FOREIGN TABLE tbl; CREATE FOREIGN TABLE agg_text ( a int2, b float4 ) SERVER file_server OPTIONS (format 'text', filename '@abs_srcdir@/data/agg.data', delimiter ' ', null '\N'); GRANT SELECT ON agg_text TO file_fdw_user; CREATE FOREIGN TABLE agg_csv ( a int2, b float4 ) SERVER file_server OPTIONS (format 'csv', filename '@abs_srcdir@/data/agg.csv', header 'true', delimiter ';', quote '@', escape '"', null ''); CREATE FOREIGN TABLE agg_bad ( a int2, b float4 ) SERVER file_server OPTIONS (format 'csv', filename '@abs_srcdir@/data/agg.bad', header 'true', delimiter ';', quote '@', escape '"', null ''); -- per-column options tests CREATE FOREIGN TABLE text_csv ( word1 text OPTIONS (force_not_null 'true'), word2 text OPTIONS (force_not_null 'off') ) SERVER file_server OPTIONS (format 'text', filename '@abs_srcdir@/data/text.csv', null 'NULL'); SELECT * FROM text_csv; -- ERROR ERROR: COPY force not null available only in CSV mode ALTER FOREIGN TABLE text_csv OPTIONS (SET format 'csv'); SELECT * FROM text_csv; word1 | word2 -------+------- AAA | aaa XYZ | xyz NULL | ABC | abc (4 rows) -- force_not_null is not allowed to be specified at any foreign object level: ALTER FOREIGN DATA WRAPPER file_fdw OPTIONS (ADD force_not_null '*'); -- ERROR ERROR: invalid option "force_not_null" HINT: There are no valid options in this context. ALTER SERVER file_server OPTIONS (ADD force_not_null '*'); -- ERROR ERROR: invalid option "force_not_null" HINT: There are no valid options in this context. CREATE USER MAPPING FOR public SERVER file_server OPTIONS (force_not_null '*'); -- ERROR ERROR: invalid option "force_not_null" HINT: There are no valid options in this context. CREATE FOREIGN TABLE tbl (a int) SERVER file_server OPTIONS (force_not_null '*'); -- ERROR ERROR: invalid option "force_not_null" HINT: Valid options in this context are: filename, format, header, delimiter, quote, escape, null, encoding -- basic query tests SELECT * FROM agg_text WHERE b > 10.0 ORDER BY a; a | b -----+-------- 42 | 324.78 100 | 99.097 (2 rows) SELECT * FROM agg_csv ORDER BY a; a | b -----+--------- 0 | .09561 42 | 324.78 100 | 99.097 (3 rows) SELECT * FROM agg_csv c JOIN agg_text t ON (t.a = c.a) ORDER BY c.a; a | b | a | b -----+---------+-----+--------- 0 | .09561 | 0 | .09561 42 | 324.78 | 42 | 324.78 100 | 99.097 | 100 | 99.097 (3 rows) -- error context report tests SELECT * FROM agg_bad; -- ERROR ERROR: invalid input syntax for type real: "aaa" CONTEXT: COPY agg_bad, line 3, column b: "aaa" -- misc query tests \t on EXPLAIN (VERBOSE, COSTS FALSE) SELECT * FROM agg_csv; Foreign Scan on public.agg_csv Output: a, b Foreign File: @abs_srcdir@/data/agg.csv \t off PREPARE st(int) AS SELECT * FROM agg_csv WHERE a = $1; EXECUTE st(100); a | b -----+-------- 100 | 99.097 (1 row) EXECUTE st(100); a | b -----+-------- 100 | 99.097 (1 row) DEALLOCATE st; SELECT b FROM agg_csv; b -------- 99.097 .09561 324.78 (3 rows) -- updates aren't supported INSERT INTO agg_csv VALUES(1,2.0); ERROR: Un-support feature DETAIL: insert statement is an INSERT INTO VALUES(...) UPDATE agg_csv SET a = 1; ERROR: Un-support feature DETAIL: statements contains unsupport feature to foreign table DELETE FROM agg_csv WHERE a = 100; ERROR: Un-support feature DETAIL: statements contains unsupport feature to foreign table -- but this should be ignored SELECT * FROM agg_csv FOR UPDATE; a | b -----+--------- 100 | 99.097 0 | .09561 42 | 324.78 (3 rows) -- privilege tests SET ROLE file_fdw_superuser PASSWORD 'Gauss_123'; SELECT * FROM agg_text ORDER BY a; a | b -----+--------- 0 | .09561 42 | 324.78 56 | 7.8 100 | 99.097 (4 rows) SET ROLE file_fdw_user PASSWORD 'Gauss_123'; SELECT * FROM agg_text ORDER BY a; a | b -----+--------- 0 | .09561 42 | 324.78 56 | 7.8 100 | 99.097 (4 rows) SET ROLE no_priv_user PASSWORD 'Gauss_123'; SELECT * FROM agg_text ORDER BY a; -- ERROR ERROR: permission denied for relation agg_text SET ROLE file_fdw_user PASSWORD 'Gauss_123'; \t on EXPLAIN (VERBOSE, COSTS FALSE) SELECT * FROM agg_text WHERE a > 0; Foreign Scan on public.agg_text Output: a, b Filter: (agg_text.a > 0) Foreign File: @abs_srcdir@/data/agg.data \t off -- privilege tests for object SET ROLE file_fdw_superuser PASSWORD 'Gauss_123'; ALTER FOREIGN TABLE agg_text OWNER TO file_fdw_user; ALTER FOREIGN TABLE agg_text OPTIONS (SET format 'text'); SET ROLE file_fdw_user PASSWORD 'Gauss_123'; ALTER FOREIGN TABLE agg_text OPTIONS (SET format 'text'); SET ROLE file_fdw_superuser PASSWORD 'Gauss_123'; -- cleanup RESET ROLE; DROP FOREIGN TABLE agg_bad, agg_csv, text_csv; DROP USER MAPPING FOR file_fdw_user SERVER file_server; DROP SERVER file_server CASCADE; NOTICE: drop cascades to 3 other objects DETAIL: drop cascades to user mapping for file_fdw_user drop cascades to user mapping for no_priv_user drop cascades to foreign table agg_text DROP ROLE file_fdw_superuser, file_fdw_user, no_priv_user;