mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-01-24 18:55:04 +08:00
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.
This commit is contained in:
parent
d894941663
commit
b9f117d6cd
@ -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
|
||||
-- ===================================================================
|
||||
|
@ -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
|
||||
-- ===================================================================
|
||||
|
Loading…
Reference in New Issue
Block a user