You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
postgres_fdw: Avoid 'variable not found in subplan target list' error.
The tlist of the EvalPlanQual outer plan for a ForeignScan node is
adjusted to produce a tuple whose descriptor matches the scan tuple slot
for the ForeignScan node. But in the case where the outer plan contains
an extra Sort node, if the new tlist contained columns required only for
evaluating PlaceHolderVars or columns required only for evaluating local
conditions, this would cause setrefs.c to fail with the error.
The cause of this is that when creating the outer plan by injecting the
Sort node into an alternative local join plan that could emit such extra
columns as well, we fail to arrange for the outer plan to propagate them
up through the Sort node, causing setrefs.c to fail to match up them in
the new tlist to what is available from the outer plan. Repair.
Per report from Alexander Pyhalov.
Richard Guo and Etsuro Fujita, reviewed by Alexander Pyhalov and Tom Lane.
Backpatch to all supported versions.
Discussion: http://postgr.es/m/cfb17bf6dfdf876467bd5ef533852d18%40postgrespro.ru
Copy file name to clipboardExpand all lines: contrib/postgres_fdw/expected/postgres_fdw.out
+79Lines changed: 79 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -2474,6 +2474,85 @@ SELECT * FROM ft1, ft2, ft4, ft5, local_tbl WHERE ft1.c1 = ft2.c1 AND ft1.c2 = f
2474
2474
2475
2475
RESET enable_nestloop;
2476
2476
RESET enable_hashjoin;
2477
+
-- test that add_paths_with_pathkeys_for_rel() arranges for the epq_path to
2478
+
-- return columns needed by the parent ForeignScan node
2479
+
EXPLAIN (VERBOSE, COSTS OFF)
2480
+
SELECT * FROM local_tbl LEFT JOIN (SELECT ft1.*, COALESCE(ft1.c3 || ft2.c3, 'foobar') FROM ft1 INNER JOIN ft2 ON (ft1.c1 = ft2.c1 AND ft1.c1 < 100)) ss ON (local_tbl.c1 = ss.c1) ORDER BY local_tbl.c1 FOR UPDATE OF local_tbl;
Remote SQL: SELECT r4."C 1", r4.c2, r4.c3, r4.c4, r4.c5, r4.c6, r4.c7, r4.c8, CASE WHEN (r4.*)::text IS NOT NULL THEN ROW(r4."C 1", r4.c2, r4.c3, r4.c4, r4.c5, r4.c6, r4.c7, r4.c8) END, CASE WHEN (r5.*)::text IS NOT NULL THEN ROW(r5."C 1", r5.c2, r5.c3, r5.c4, r5.c5, r5.c6, r5.c7, r5.c8) END, r5.c3 FROM ("S 1"."T 1" r4 INNER JOIN "S 1"."T 1" r5 ON (((r4."C 1" = r5."C 1")) AND ((r4."C 1" < 100)))) ORDER BY r4."C 1" ASC NULLS LAST
ALTER SERVER loopback OPTIONS (ADD fdw_startup_cost '10000.0');
2516
+
EXPLAIN (VERBOSE, COSTS OFF)
2517
+
SELECT * FROM local_tbl LEFT JOIN (SELECT ft1.* FROM ft1 INNER JOIN ft2 ON (ft1.c1 = ft2.c1 AND ft1.c1 < 100 AND ft1.c1 = postgres_fdw_abs(ft2.c2))) ss ON (local_tbl.c3 = ss.c3) ORDER BY local_tbl.c1 FOR UPDATE OF local_tbl;
Remote SQL: SELECT r4."C 1", r4.c2, r4.c3, r4.c4, r4.c5, r4.c6, r4.c7, r4.c8, CASE WHEN (r4.*)::text IS NOT NULL THEN ROW(r4."C 1", r4.c2, r4.c3, r4.c4, r4.c5, r4.c6, r4.c7, r4.c8) END, CASE WHEN (r5.*)::text IS NOT NULL THEN ROW(r5."C 1", r5.c2, r5.c3, r5.c4, r5.c5, r5.c6, r5.c7, r5.c8) END, r5.c2 FROM ("S 1"."T 1" r4 INNER JOIN "S 1"."T 1" r5 ON (((r4."C 1" = r5."C 1")) AND ((r4."C 1" < 100)))) ORDER BY r4.c3 ASC NULLS LAST
Copy file name to clipboardExpand all lines: contrib/postgres_fdw/sql/postgres_fdw.sql
+13Lines changed: 13 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -672,6 +672,19 @@ SELECT * FROM ft1, ft2, ft4, ft5, local_tbl WHERE ft1.c1 = ft2.c1 AND ft1.c2 = f
672
672
ANDft1.c2=ft5.c1ANDft1.c2=local_tbl.c1ANDft1.c1<100ANDft2.c1<100 FOR UPDATE;
673
673
RESET enable_nestloop;
674
674
RESET enable_hashjoin;
675
+
676
+
-- test that add_paths_with_pathkeys_for_rel() arranges for the epq_path to
677
+
-- return columns needed by the parent ForeignScan node
678
+
EXPLAIN (VERBOSE, COSTS OFF)
679
+
SELECT*FROM local_tbl LEFT JOIN (SELECT ft1.*, COALESCE(ft1.c3||ft2.c3, 'foobar') FROM ft1 INNER JOIN ft2 ON (ft1.c1=ft2.c1ANDft1.c1<100)) ss ON (local_tbl.c1=ss.c1) ORDER BYlocal_tbl.c1 FOR UPDATE OF local_tbl;
680
+
681
+
ALTER SERVER loopback OPTIONS (DROP extensions);
682
+
ALTER SERVER loopback OPTIONS (ADD fdw_startup_cost '10000.0');
683
+
EXPLAIN (VERBOSE, COSTS OFF)
684
+
SELECT*FROM local_tbl LEFT JOIN (SELECT ft1.*FROM ft1 INNER JOIN ft2 ON (ft1.c1=ft2.c1ANDft1.c1<100ANDft1.c1= postgres_fdw_abs(ft2.c2))) ss ON (local_tbl.c3=ss.c3) ORDER BYlocal_tbl.c1 FOR UPDATE OF local_tbl;
685
+
ALTER SERVER loopback OPTIONS (DROP fdw_startup_cost);
686
+
ALTER SERVER loopback OPTIONS (ADD extensions 'postgres_fdw');
687
+
675
688
DROPTABLE local_tbl;
676
689
677
690
-- check join pushdown in situations where multiple userids are involved
0 commit comments