mirror of
https://github.com/postgres/postgres.git
synced 2025-06-07 11:02:12 +03: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',
|
-- gsslib 'value',
|
||||||
--replication '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
|
ALTER USER MAPPING FOR public SERVER testserver1
|
||||||
OPTIONS (DROP user, DROP password);
|
OPTIONS (DROP user, DROP password);
|
||||||
ALTER FOREIGN TABLE ft1 OPTIONS (schema_name 'S 1', table_name 'T 1');
|
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 |
|
fixed |
|
||||||
(1 row)
|
(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
|
-- 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"
|
Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1"
|
||||||
(6 rows)
|
(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
|
-- parameterized queries
|
||||||
-- ===================================================================
|
-- ===================================================================
|
||||||
|
@ -121,8 +121,17 @@ ALTER SERVER testserver1 OPTIONS (
|
|||||||
-- gsslib 'value',
|
-- gsslib 'value',
|
||||||
--replication '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
|
ALTER USER MAPPING FOR public SERVER testserver1
|
||||||
OPTIONS (DROP user, DROP password);
|
OPTIONS (DROP user, DROP password);
|
||||||
|
|
||||||
ALTER FOREIGN TABLE ft1 OPTIONS (schema_name 'S 1', table_name 'T 1');
|
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 ft2 OPTIONS (schema_name 'S 1', table_name 'T 1');
|
||||||
ALTER FOREIGN TABLE ft1 ALTER COLUMN c1 OPTIONS (column_name 'C 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;
|
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
|
-- fixed values
|
||||||
SELECT 'fixed', NULL FROM ft1 t1 WHERE c1 = 1;
|
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
|
-- WHERE with remotely-executable conditions
|
||||||
@ -222,6 +214,48 @@ EXPLAIN (VERBOSE, COSTS false)
|
|||||||
EXPLAIN (VERBOSE, COSTS false)
|
EXPLAIN (VERBOSE, COSTS false)
|
||||||
SELECT * FROM ft2 ORDER BY ft2.c1, ft2.c3 collate "C";
|
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
|
-- parameterized queries
|
||||||
-- ===================================================================
|
-- ===================================================================
|
||||||
|
Loading…
x
Reference in New Issue
Block a user