1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-13 07:41:39 +03:00

Don't require a user mapping for FDWs to work.

Commit fbe5a3fb73 accidentally changed
this behavior; put things back the way they were, and add some
regression tests.

Report by Andres Freund; patch by Ashutosh Bapat, with a bit of
kibitzing by me.
This commit is contained in:
Robert Haas
2016-03-28 21:50:28 -04:00
parent 868628e4fd
commit 5d4171d1c7
8 changed files with 125 additions and 22 deletions

View File

@ -1958,13 +1958,30 @@ EXECUTE join_stmt;
-- change the session user to view_owner and execute the statement. Because of
-- change in session user, the plan should get invalidated and created again.
-- While creating the plan, it should throw error since there is no user mapping
-- available for view_owner.
-- The join will not be pushed down since the joining relations do not have a
-- valid user mapping.
SET SESSION ROLE view_owner;
EXPLAIN (COSTS OFF, VERBOSE) EXECUTE join_stmt;
ERROR: user mapping not found for "view_owner"
EXECUTE join_stmt;
ERROR: user mapping not found for "view_owner"
QUERY PLAN
------------------------------------------------------------------
Limit
Output: t1.c1, t2.c1
-> Sort
Output: t1.c1, t2.c1
Sort Key: t1.c1, t2.c1
-> Hash Left Join
Output: t1.c1, t2.c1
Hash Cond: (t1.c1 = t2.c1)
-> Foreign Scan on public.ft4 t1
Output: t1.c1, t1.c2, t1.c3
Remote SQL: SELECT c1 FROM "S 1"."T 3"
-> Hash
Output: t2.c1
-> Foreign Scan on public.ft5 t2
Output: t2.c1
Remote SQL: SELECT c1 FROM "S 1"."T 4"
(16 rows)
RESET ROLE;
DEALLOCATE join_stmt;
CREATE VIEW v_ft5 AS SELECT * FROM ft5;
@ -2021,6 +2038,40 @@ EXECUTE join_stmt;
----+----
(0 rows)
-- If a sub-join can't be pushed down, upper level join shouldn't be either.
EXPLAIN (COSTS false, VERBOSE)
SELECT t1.c1, t2.c1 FROM (ft5 t1 JOIN v_ft5 t2 ON (t1.c1 = t2.c1)) left join (ft5 t3 JOIN v_ft5 t4 ON (t3.c1 = t4.c1)) ON (t1.c1 = t3.c1);
QUERY PLAN
------------------------------------------------------------------
Hash Join
Output: t1.c1, ft5.c1
Hash Cond: (t1.c1 = ft5.c1)
-> Hash Right Join
Output: t1.c1
Hash Cond: (t3.c1 = t1.c1)
-> Hash Join
Output: t3.c1
Hash Cond: (t3.c1 = ft5_1.c1)
-> Foreign Scan on public.ft5 t3
Output: t3.c1, t3.c2, t3.c3
Remote SQL: SELECT c1 FROM "S 1"."T 4"
-> Hash
Output: ft5_1.c1
-> Foreign Scan on public.ft5 ft5_1
Output: ft5_1.c1
Remote SQL: SELECT c1 FROM "S 1"."T 4"
-> Hash
Output: t1.c1
-> Foreign Scan on public.ft5 t1
Output: t1.c1
Remote SQL: SELECT c1 FROM "S 1"."T 4"
-> Hash
Output: ft5.c1
-> Foreign Scan on public.ft5
Output: ft5.c1
Remote SQL: SELECT c1 FROM "S 1"."T 4"
(27 rows)
-- recreate the dropped user mapping for further tests
CREATE USER MAPPING FOR CURRENT_USER SERVER loopback;
DROP USER MAPPING FOR PUBLIC SERVER loopback;

View File

@ -3910,6 +3910,16 @@ foreign_join_ok(PlannerInfo *root, RelOptInfo *joinrel, JoinType jointype,
List *joinclauses;
List *otherclauses;
/*
* Core code may call GetForeignJoinPaths hook even when the join
* relation doesn't have a valid user mapping associated with it. See
* build_join_rel() for details. We can't push down such join, since
* there doesn't exist a user mapping which can be used to connect to the
* foreign server.
*/
if (!OidIsValid(joinrel->umid))
return false;
/*
* We support pushing down INNER, LEFT, RIGHT and FULL OUTER joins.
* Constructing queries representing SEMI and ANTI joins is hard, hence

View File

@ -478,11 +478,10 @@ EXPLAIN (COSTS OFF, VERBOSE) EXECUTE join_stmt;
EXECUTE join_stmt;
-- change the session user to view_owner and execute the statement. Because of
-- change in session user, the plan should get invalidated and created again.
-- While creating the plan, it should throw error since there is no user mapping
-- available for view_owner.
-- The join will not be pushed down since the joining relations do not have a
-- valid user mapping.
SET SESSION ROLE view_owner;
EXPLAIN (COSTS OFF, VERBOSE) EXECUTE join_stmt;
EXECUTE join_stmt;
RESET ROLE;
DEALLOCATE join_stmt;
@ -506,6 +505,10 @@ CREATE USER MAPPING FOR view_owner SERVER loopback;
EXPLAIN (COSTS false, VERBOSE) EXECUTE join_stmt;
EXECUTE join_stmt;
-- If a sub-join can't be pushed down, upper level join shouldn't be either.
EXPLAIN (COSTS false, VERBOSE)
SELECT t1.c1, t2.c1 FROM (ft5 t1 JOIN v_ft5 t2 ON (t1.c1 = t2.c1)) left join (ft5 t3 JOIN v_ft5 t4 ON (t3.c1 = t4.c1)) ON (t1.c1 = t3.c1);
-- recreate the dropped user mapping for further tests
CREATE USER MAPPING FOR CURRENT_USER SERVER loopback;
DROP USER MAPPING FOR PUBLIC SERVER loopback;