diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2015-11-04 12:03:30 -0500 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2015-11-04 12:03:30 -0500 |
commit | b9f117d6cd3c79780b0c0e57068f0837f7493aa6 (patch) | |
tree | db30bd3990804e89f467b31d3e51f1dc7ae0f129 | |
parent | d89494166351e1fdac77d87c6af500401deb2422 (diff) | |
download | postgresql-b9f117d6cd3c79780b0c0e57068f0837f7493aa6.tar.gz postgresql-b9f117d6cd3c79780b0c0e57068f0837f7493aa6.zip |
Add regression tests for remote execution of extension operators/functions.
Rather than relying on other extensions to be available for installation,
let's just add some test objects to the postgres_fdw extension itself
within the regression script.
-rw-r--r-- | contrib/postgres_fdw/expected/postgres_fdw.out | 178 | ||||
-rw-r--r-- | contrib/postgres_fdw/sql/postgres_fdw.sql | 68 |
2 files changed, 182 insertions, 64 deletions
diff --git a/contrib/postgres_fdw/expected/postgres_fdw.out b/contrib/postgres_fdw/expected/postgres_fdw.out index 0159bf52ad0..866a09bea52 100644 --- a/contrib/postgres_fdw/expected/postgres_fdw.out +++ b/contrib/postgres_fdw/expected/postgres_fdw.out @@ -112,6 +112,14 @@ ALTER SERVER testserver1 OPTIONS ( -- gsslib 'value', --replication 'value' ); +-- Error, invalid list syntax +ALTER SERVER testserver1 OPTIONS (ADD extensions 'foo; bar'); +ERROR: parameter "extensions" must be a list of extension names +-- OK but gets a warning +ALTER SERVER testserver1 OPTIONS (ADD extensions 'foo, bar'); +WARNING: extension "foo" is not installed +WARNING: extension "bar" is not installed +ALTER SERVER testserver1 OPTIONS (DROP extensions); ALTER USER MAPPING FOR public SERVER testserver1 OPTIONS (DROP user, DROP password); ALTER FOREIGN TABLE ft1 OPTIONS (schema_name 'S 1', table_name 'T 1'); @@ -335,53 +343,6 @@ SELECT 'fixed', NULL FROM ft1 t1 WHERE c1 = 1; fixed | (1 row) --- user-defined operator/function -CREATE FUNCTION postgres_fdw_abs(int) RETURNS int AS $$ -BEGIN -RETURN abs($1); -END -$$ LANGUAGE plpgsql IMMUTABLE; -CREATE OPERATOR === ( - LEFTARG = int, - RIGHTARG = int, - PROCEDURE = int4eq, - COMMUTATOR = ===, - NEGATOR = !== -); -EXPLAIN (VERBOSE, COSTS false) SELECT * FROM ft1 t1 WHERE t1.c1 = postgres_fdw_abs(t1.c2); - QUERY PLAN -------------------------------------------------------------------------- - Foreign Scan on public.ft1 t1 - Output: c1, c2, c3, c4, c5, c6, c7, c8 - Filter: (t1.c1 = postgres_fdw_abs(t1.c2)) - Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" -(4 rows) - -EXPLAIN (VERBOSE, COSTS false) SELECT * FROM ft1 t1 WHERE t1.c1 === t1.c2; - QUERY PLAN -------------------------------------------------------------------------- - Foreign Scan on public.ft1 t1 - Output: c1, c2, c3, c4, c5, c6, c7, c8 - Filter: (t1.c1 === t1.c2) - Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" -(4 rows) - -EXPLAIN (VERBOSE, COSTS false) SELECT * FROM ft1 t1 WHERE t1.c1 = abs(t1.c2); - QUERY PLAN ---------------------------------------------------------------------------------------------------- - Foreign Scan on public.ft1 t1 - Output: c1, c2, c3, c4, c5, c6, c7, c8 - Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE (("C 1" = abs(c2))) -(3 rows) - -EXPLAIN (VERBOSE, COSTS false) SELECT * FROM ft1 t1 WHERE t1.c1 = t1.c2; - QUERY PLAN ----------------------------------------------------------------------------------------------- - Foreign Scan on public.ft1 t1 - Output: c1, c2, c3, c4, c5, c6, c7, c8 - Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE (("C 1" = c2)) -(3 rows) - -- =================================================================== -- WHERE with remotely-executable conditions -- =================================================================== @@ -672,6 +633,129 @@ EXPLAIN (VERBOSE, COSTS false) Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" (6 rows) +-- user-defined operator/function +CREATE FUNCTION postgres_fdw_abs(int) RETURNS int AS $$ +BEGIN +RETURN abs($1); +END +$$ LANGUAGE plpgsql IMMUTABLE; +CREATE OPERATOR === ( + LEFTARG = int, + RIGHTARG = int, + PROCEDURE = int4eq, + COMMUTATOR = === +); +-- built-in operators and functions can be shipped for remote execution +EXPLAIN (VERBOSE, COSTS false) + SELECT count(c3) FROM ft1 t1 WHERE t1.c1 = abs(t1.c2); + QUERY PLAN +-------------------------------------------------------------------------- + Aggregate + Output: count(c3) + -> Foreign Scan on public.ft1 t1 + Output: c3 + Remote SQL: SELECT c3 FROM "S 1"."T 1" WHERE (("C 1" = abs(c2))) +(5 rows) + +SELECT count(c3) FROM ft1 t1 WHERE t1.c1 = abs(t1.c2); + count +------- + 9 +(1 row) + +EXPLAIN (VERBOSE, COSTS false) + SELECT count(c3) FROM ft1 t1 WHERE t1.c1 = t1.c2; + QUERY PLAN +--------------------------------------------------------------------- + Aggregate + Output: count(c3) + -> Foreign Scan on public.ft1 t1 + Output: c3 + Remote SQL: SELECT c3 FROM "S 1"."T 1" WHERE (("C 1" = c2)) +(5 rows) + +SELECT count(c3) FROM ft1 t1 WHERE t1.c1 = t1.c2; + count +------- + 9 +(1 row) + +-- by default, user-defined ones cannot +EXPLAIN (VERBOSE, COSTS false) + SELECT count(c3) FROM ft1 t1 WHERE t1.c1 = postgres_fdw_abs(t1.c2); + QUERY PLAN +----------------------------------------------------------- + Aggregate + Output: count(c3) + -> Foreign Scan on public.ft1 t1 + Output: c3 + Filter: (t1.c1 = postgres_fdw_abs(t1.c2)) + Remote SQL: SELECT "C 1", c2, c3 FROM "S 1"."T 1" +(6 rows) + +SELECT count(c3) FROM ft1 t1 WHERE t1.c1 = postgres_fdw_abs(t1.c2); + count +------- + 9 +(1 row) + +EXPLAIN (VERBOSE, COSTS false) + SELECT count(c3) FROM ft1 t1 WHERE t1.c1 === t1.c2; + QUERY PLAN +----------------------------------------------------------- + Aggregate + Output: count(c3) + -> Foreign Scan on public.ft1 t1 + Output: c3 + Filter: (t1.c1 === t1.c2) + Remote SQL: SELECT "C 1", c2, c3 FROM "S 1"."T 1" +(6 rows) + +SELECT count(c3) FROM ft1 t1 WHERE t1.c1 === t1.c2; + count +------- + 9 +(1 row) + +-- but let's put them in an extension ... +ALTER EXTENSION postgres_fdw ADD FUNCTION postgres_fdw_abs(int); +ALTER EXTENSION postgres_fdw ADD OPERATOR === (int, int); +ALTER SERVER loopback OPTIONS (ADD extensions 'postgres_fdw'); +-- ... now they can be shipped +EXPLAIN (VERBOSE, COSTS false) + SELECT count(c3) FROM ft1 t1 WHERE t1.c1 = postgres_fdw_abs(t1.c2); + QUERY PLAN +---------------------------------------------------------------------------------------------- + Aggregate + Output: count(c3) + -> Foreign Scan on public.ft1 t1 + Output: c3 + Remote SQL: SELECT c3 FROM "S 1"."T 1" WHERE (("C 1" = public.postgres_fdw_abs(c2))) +(5 rows) + +SELECT count(c3) FROM ft1 t1 WHERE t1.c1 = postgres_fdw_abs(t1.c2); + count +------- + 9 +(1 row) + +EXPLAIN (VERBOSE, COSTS false) + SELECT count(c3) FROM ft1 t1 WHERE t1.c1 === t1.c2; + QUERY PLAN +---------------------------------------------------------------------------------------- + Aggregate + Output: count(c3) + -> Foreign Scan on public.ft1 t1 + Output: c3 + Remote SQL: SELECT c3 FROM "S 1"."T 1" WHERE (("C 1" OPERATOR(public.===) c2)) +(5 rows) + +SELECT count(c3) FROM ft1 t1 WHERE t1.c1 === t1.c2; + count +------- + 9 +(1 row) + -- =================================================================== -- parameterized queries -- =================================================================== diff --git a/contrib/postgres_fdw/sql/postgres_fdw.sql b/contrib/postgres_fdw/sql/postgres_fdw.sql index a87a63fe845..671e38ceaa3 100644 --- a/contrib/postgres_fdw/sql/postgres_fdw.sql +++ b/contrib/postgres_fdw/sql/postgres_fdw.sql @@ -121,8 +121,17 @@ ALTER SERVER testserver1 OPTIONS ( -- gsslib 'value', --replication 'value' ); + +-- Error, invalid list syntax +ALTER SERVER testserver1 OPTIONS (ADD extensions 'foo; bar'); + +-- OK but gets a warning +ALTER SERVER testserver1 OPTIONS (ADD extensions 'foo, bar'); +ALTER SERVER testserver1 OPTIONS (DROP extensions); + ALTER USER MAPPING FOR public SERVER testserver1 OPTIONS (DROP user, DROP password); + ALTER FOREIGN TABLE ft1 OPTIONS (schema_name 'S 1', table_name 'T 1'); ALTER FOREIGN TABLE ft2 OPTIONS (schema_name 'S 1', table_name 'T 1'); ALTER FOREIGN TABLE ft1 ALTER COLUMN c1 OPTIONS (column_name 'C 1'); @@ -169,23 +178,6 @@ SELECT * FROM ft1 t1 WHERE t1.c3 = (SELECT MAX(c3) FROM ft2 t2) ORDER BY c1; WITH t1 AS (SELECT * FROM ft1 WHERE c1 <= 10) SELECT t2.c1, t2.c2, t2.c3, t2.c4 FROM t1, ft2 t2 WHERE t1.c1 = t2.c1 ORDER BY t1.c1; -- fixed values SELECT 'fixed', NULL FROM ft1 t1 WHERE c1 = 1; --- user-defined operator/function -CREATE FUNCTION postgres_fdw_abs(int) RETURNS int AS $$ -BEGIN -RETURN abs($1); -END -$$ LANGUAGE plpgsql IMMUTABLE; -CREATE OPERATOR === ( - LEFTARG = int, - RIGHTARG = int, - PROCEDURE = int4eq, - COMMUTATOR = ===, - NEGATOR = !== -); -EXPLAIN (VERBOSE, COSTS false) SELECT * FROM ft1 t1 WHERE t1.c1 = postgres_fdw_abs(t1.c2); -EXPLAIN (VERBOSE, COSTS false) SELECT * FROM ft1 t1 WHERE t1.c1 === t1.c2; -EXPLAIN (VERBOSE, COSTS false) SELECT * FROM ft1 t1 WHERE t1.c1 = abs(t1.c2); -EXPLAIN (VERBOSE, COSTS false) SELECT * FROM ft1 t1 WHERE t1.c1 = t1.c2; -- =================================================================== -- WHERE with remotely-executable conditions @@ -222,6 +214,48 @@ EXPLAIN (VERBOSE, COSTS false) EXPLAIN (VERBOSE, COSTS false) SELECT * FROM ft2 ORDER BY ft2.c1, ft2.c3 collate "C"; +-- user-defined operator/function +CREATE FUNCTION postgres_fdw_abs(int) RETURNS int AS $$ +BEGIN +RETURN abs($1); +END +$$ LANGUAGE plpgsql IMMUTABLE; +CREATE OPERATOR === ( + LEFTARG = int, + RIGHTARG = int, + PROCEDURE = int4eq, + COMMUTATOR = === +); + +-- built-in operators and functions can be shipped for remote execution +EXPLAIN (VERBOSE, COSTS false) + SELECT count(c3) FROM ft1 t1 WHERE t1.c1 = abs(t1.c2); +SELECT count(c3) FROM ft1 t1 WHERE t1.c1 = abs(t1.c2); +EXPLAIN (VERBOSE, COSTS false) + SELECT count(c3) FROM ft1 t1 WHERE t1.c1 = t1.c2; +SELECT count(c3) FROM ft1 t1 WHERE t1.c1 = t1.c2; + +-- by default, user-defined ones cannot +EXPLAIN (VERBOSE, COSTS false) + SELECT count(c3) FROM ft1 t1 WHERE t1.c1 = postgres_fdw_abs(t1.c2); +SELECT count(c3) FROM ft1 t1 WHERE t1.c1 = postgres_fdw_abs(t1.c2); +EXPLAIN (VERBOSE, COSTS false) + SELECT count(c3) FROM ft1 t1 WHERE t1.c1 === t1.c2; +SELECT count(c3) FROM ft1 t1 WHERE t1.c1 === t1.c2; + +-- but let's put them in an extension ... +ALTER EXTENSION postgres_fdw ADD FUNCTION postgres_fdw_abs(int); +ALTER EXTENSION postgres_fdw ADD OPERATOR === (int, int); +ALTER SERVER loopback OPTIONS (ADD extensions 'postgres_fdw'); + +-- ... now they can be shipped +EXPLAIN (VERBOSE, COSTS false) + SELECT count(c3) FROM ft1 t1 WHERE t1.c1 = postgres_fdw_abs(t1.c2); +SELECT count(c3) FROM ft1 t1 WHERE t1.c1 = postgres_fdw_abs(t1.c2); +EXPLAIN (VERBOSE, COSTS false) + SELECT count(c3) FROM ft1 t1 WHERE t1.c1 === t1.c2; +SELECT count(c3) FROM ft1 t1 WHERE t1.c1 === t1.c2; + -- =================================================================== -- parameterized queries -- =================================================================== |