Hi Ashutosh & PG Hackers, I have fixed the code to produce desired output by adding a few lines in pull_up_simple_subquery(). Attached patch is divided in 2 files: - 001-Fix-Alias-VALUES-RTE.patch contains the actual fix. - 002-Fix-Alias-VALUES-RTE.patch contains the expected output changes against the actual fix.
I also have verified regression tests, all seems good. Respected hackers please have a look. Thanks and regards... Yasir On Thu, Aug 15, 2024 at 7:13 PM Yasir <yasir.hussain.s...@gmail.com> wrote: > > > On Mon, Jul 1, 2024 at 3:17 PM Ashutosh Bapat < > ashutosh.bapat....@gmail.com> wrote: > >> Hi All, >> While reviewing Richard's patch for grouping sets, I stumbled upon >> following explain output >> >> explain (costs off) >> select distinct on (a, b) a, b >> from (values (1, 1), (2, 2)) as t (a, b) where a = b >> group by grouping sets((a, b), (a)) >> order by a, b; >> QUERY PLAN >> ---------------------------------------------------------------- >> Unique >> -> Sort >> Sort Key: "*VALUES*".column1, "*VALUES*".column2 >> -> HashAggregate >> Hash Key: "*VALUES*".column1, "*VALUES*".column2 >> Hash Key: "*VALUES*".column1 >> -> Values Scan on "*VALUES*" >> Filter: (column1 = column2) >> (8 rows) >> >> There is no VALUES.column1 and VALUES.column2 in the query. The alias t.a >> and t.b do not appear anywhere in the explain output. I think explain >> output should look like >> explain (costs off) >> select distinct on (a, b) a, b >> from (values (1, 1), (2, 2)) as t (a, b) where a = b >> group by grouping sets((a, b), (a)) >> order by a, b; >> QUERY PLAN >> ---------------------------------------------------------------- >> Unique >> -> Sort >> Sort Key: t.a, t.b >> -> HashAggregate >> Hash Key: t.a, t.b >> Hash Key: t.a >> -> Values Scan on "*VALUES*" t >> Filter: (a = b) >> (8 rows) >> >> I didn't get time to figure out the reason behind this, nor the history. >> But I thought I would report it nonetheless. >> > > I have looked into the issue and found that when subqueries are pulled up, > a modifiable copy of the subquery is created for modification in the > pull_up_simple_subquery() function. During this process, > flatten_join_alias_vars() is called to flatten any join alias variables > in the subquery's target list. However at this point, we lose > subquery's alias. > If you/hackers agree with my findings, I can provide a working patch soon. > > >> -- >> Best Wishes, >> Ashutosh Bapat >> >
diff --git a/src/backend/optimizer/prep/prepjointree.c b/src/backend/optimizer/prep/prepjointree.c index 5482ab85a7..e751ae21d1 100644 --- a/src/backend/optimizer/prep/prepjointree.c +++ b/src/backend/optimizer/prep/prepjointree.c @@ -98,7 +98,8 @@ static bool is_simple_subquery(PlannerInfo *root, Query *subquery, JoinExpr *lowest_outer_join); static Node *pull_up_simple_values(PlannerInfo *root, Node *jtnode, RangeTblEntry *rte); -static bool is_simple_values(PlannerInfo *root, RangeTblEntry *rte); +static bool is_simple_values(PlannerInfo *root, RangeTblEntry *rte, + bool allow_multi_values); static Node *pull_up_constant_function(PlannerInfo *root, Node *jtnode, RangeTblEntry *rte, AppendRelInfo *containing_appendrel); @@ -910,7 +911,7 @@ pull_up_subqueries_recurse(PlannerInfo *root, Node *jtnode, if (rte->rtekind == RTE_VALUES && lowest_outer_join == NULL && containing_appendrel == NULL && - is_simple_values(root, rte)) + is_simple_values(root, rte, false)) return pull_up_simple_values(root, jtnode, rte); /* @@ -990,6 +991,33 @@ pull_up_subqueries_recurse(PlannerInfo *root, Node *jtnode, return jtnode; } +static RangeTblEntry *get_rte_from_values_query(PlannerInfo *root, Query *subquery) +{ + RangeTblRef *rtr = NULL; + RangeTblEntry *rte = NULL; + Node *node; + + if (subquery->jointree == NULL || + list_length(subquery->jointree->fromlist) != 1) + return NULL; + + if (list_length(subquery->rtable) != 1) + return NULL; + + node = linitial(subquery->jointree->fromlist); + if (!IsA(node, RangeTblRef)) + return NULL; + + rtr = castNode(RangeTblRef, node); + rte = rt_fetch(rtr->rtindex, subquery->rtable); + + /* elog_node_display(LOG, "YH | rte tree", root->parse, true); */ + if (rte == NULL || rte->rtekind != RTE_VALUES) + return NULL; + + return is_simple_values(root, rte, true) ? rte : NULL; +} + /* * pull_up_simple_subquery * Attempt to pull up a single simple subquery. @@ -1014,6 +1042,7 @@ pull_up_simple_subquery(PlannerInfo *root, Node *jtnode, RangeTblEntry *rte, int rtoffset; pullup_replace_vars_context rvcontext; ListCell *lc; + RangeTblEntry *values_rte = NULL; /* * Make a modifiable copy of the subquery to hack on, so that the RTE will @@ -1124,6 +1153,12 @@ pull_up_simple_subquery(PlannerInfo *root, Node *jtnode, RangeTblEntry *rte, return jtnode; } + if ((values_rte = get_rte_from_values_query(subroot, subquery)) != NULL) + { + values_rte->alias = copyObject(rte->alias); + values_rte->eref = copyObject(rte->eref); + } + /* * We must flatten any join alias Vars in the subquery's targetlist, * because pulling up the subquery's subqueries might have changed their @@ -1765,7 +1800,7 @@ pull_up_simple_values(PlannerInfo *root, Node *jtnode, RangeTblEntry *rte) * rte is the RTE_VALUES RangeTblEntry to check. */ static bool -is_simple_values(PlannerInfo *root, RangeTblEntry *rte) +is_simple_values(PlannerInfo *root, RangeTblEntry *rte, bool allow_multi_values) { Assert(rte->rtekind == RTE_VALUES); @@ -1774,7 +1809,7 @@ is_simple_values(PlannerInfo *root, RangeTblEntry *rte) * correct to replace the VALUES RTE with a RESULT RTE, nor would we have * a unique set of expressions to substitute into the parent query. */ - if (list_length(rte->values_lists) != 1) + if (!allow_multi_values && list_length(rte->values_lists) != 1) return false; /*
diff --git a/contrib/postgres_fdw/expected/postgres_fdw.out b/contrib/postgres_fdw/expected/postgres_fdw.out index 063869c2ad..f8c5459cb7 100644 --- a/contrib/postgres_fdw/expected/postgres_fdw.out +++ b/contrib/postgres_fdw/expected/postgres_fdw.out @@ -8985,16 +8985,16 @@ insert into utrtest values (2, 'qux'); -- with a non-direct modification plan explain (verbose, costs off) update utrtest set a = 1 from (values (1), (2)) s(x) where a = s.x returning *; - QUERY PLAN ------------------------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------------- Update on public.utrtest - Output: utrtest_1.a, utrtest_1.b, "*VALUES*".column1 + Output: utrtest_1.a, utrtest_1.b, s.x Foreign Update on public.remp utrtest_1 Remote SQL: UPDATE public.loct SET a = $2 WHERE ctid = $1 RETURNING a, b Update on public.locp utrtest_2 -> Hash Join - Output: 1, "*VALUES*".*, "*VALUES*".column1, utrtest.tableoid, utrtest.ctid, utrtest.* - Hash Cond: (utrtest.a = "*VALUES*".column1) + Output: 1, s.*, s.x, utrtest.tableoid, utrtest.ctid, utrtest.* + Hash Cond: (utrtest.a = s.x) -> Append -> Foreign Scan on public.remp utrtest_1 Output: utrtest_1.a, utrtest_1.tableoid, utrtest_1.ctid, utrtest_1.* @@ -9002,9 +9002,9 @@ update utrtest set a = 1 from (values (1), (2)) s(x) where a = s.x returning *; -> Seq Scan on public.locp utrtest_2 Output: utrtest_2.a, utrtest_2.tableoid, utrtest_2.ctid, NULL::record -> Hash - Output: "*VALUES*".*, "*VALUES*".column1 - -> Values Scan on "*VALUES*" - Output: "*VALUES*".*, "*VALUES*".column1 + Output: s.*, s.x + -> Values Scan on s + Output: s.*, s.x (18 rows) update utrtest set a = 1 from (values (1), (2)) s(x) where a = s.x returning *; @@ -9042,16 +9042,16 @@ ERROR: cannot route tuples into foreign table to be updated "remp" -- with a non-direct modification plan explain (verbose, costs off) update utrtest set a = 3 from (values (2), (3)) s(x) where a = s.x returning *; - QUERY PLAN ------------------------------------------------------------------------------------------------------ + QUERY PLAN +------------------------------------------------------------------------------------------- Update on public.utrtest - Output: utrtest_1.a, utrtest_1.b, "*VALUES*".column1 + Output: utrtest_1.a, utrtest_1.b, s.x Update on public.locp utrtest_1 Foreign Update on public.remp utrtest_2 Remote SQL: UPDATE public.loct SET a = $2 WHERE ctid = $1 RETURNING a, b -> Hash Join - Output: 3, "*VALUES*".*, "*VALUES*".column1, utrtest.tableoid, utrtest.ctid, (NULL::record) - Hash Cond: (utrtest.a = "*VALUES*".column1) + Output: 3, s.*, s.x, utrtest.tableoid, utrtest.ctid, (NULL::record) + Hash Cond: (utrtest.a = s.x) -> Append -> Seq Scan on public.locp utrtest_1 Output: utrtest_1.a, utrtest_1.tableoid, utrtest_1.ctid, NULL::record @@ -9059,9 +9059,9 @@ update utrtest set a = 3 from (values (2), (3)) s(x) where a = s.x returning *; Output: utrtest_2.a, utrtest_2.tableoid, utrtest_2.ctid, utrtest_2.* Remote SQL: SELECT a, b, ctid FROM public.loct FOR UPDATE -> Hash - Output: "*VALUES*".*, "*VALUES*".column1 - -> Values Scan on "*VALUES*" - Output: "*VALUES*".*, "*VALUES*".column1 + Output: s.*, s.x + -> Values Scan on s + Output: s.*, s.x (18 rows) update utrtest set a = 3 from (values (2), (3)) s(x) where a = s.x returning *; -- ERROR diff --git a/contrib/tsm_system_rows/expected/tsm_system_rows.out b/contrib/tsm_system_rows/expected/tsm_system_rows.out index 87b4a8fc64..cd472d2605 100644 --- a/contrib/tsm_system_rows/expected/tsm_system_rows.out +++ b/contrib/tsm_system_rows/expected/tsm_system_rows.out @@ -49,13 +49,13 @@ SELECT * FROM (VALUES (0),(10),(100)) v(nrows), LATERAL (SELECT count(*) FROM test_tablesample TABLESAMPLE system_rows (nrows)) ss; - QUERY PLAN ----------------------------------------------------------- + QUERY PLAN +----------------------------------------------- Nested Loop - -> Values Scan on "*VALUES*" + -> Values Scan on v -> Aggregate -> Sample Scan on test_tablesample - Sampling: system_rows ("*VALUES*".column1) + Sampling: system_rows (v.nrows) (5 rows) SELECT * FROM diff --git a/contrib/tsm_system_time/expected/tsm_system_time.out b/contrib/tsm_system_time/expected/tsm_system_time.out index ac44f30be9..6c5aac3709 100644 --- a/contrib/tsm_system_time/expected/tsm_system_time.out +++ b/contrib/tsm_system_time/expected/tsm_system_time.out @@ -47,7 +47,7 @@ SELECT * FROM -> Materialize -> Sample Scan on test_tablesample Sampling: system_time ('100000'::double precision) - -> Values Scan on "*VALUES*" + -> Values Scan on v (6 rows) SELECT * FROM @@ -65,14 +65,14 @@ SELECT * FROM (VALUES (0),(100000)) v(time), LATERAL (SELECT COUNT(*) FROM test_tablesample TABLESAMPLE system_time (time)) ss; - QUERY PLAN ----------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------ Nested Loop - -> Values Scan on "*VALUES*" + -> Values Scan on v -> Aggregate -> Materialize -> Sample Scan on test_tablesample - Sampling: system_time ("*VALUES*".column1) + Sampling: system_time (v."time") (6 rows) SELECT * FROM diff --git a/src/test/regress/expected/create_view.out b/src/test/regress/expected/create_view.out index f3f8c7b5a2..35655d7bc6 100644 --- a/src/test/regress/expected/create_view.out +++ b/src/test/regress/expected/create_view.out @@ -2141,34 +2141,34 @@ select pg_get_viewdef('tt25v', true); -- also check cases seen only in EXPLAIN explain (verbose, costs off) select * from tt24v; - QUERY PLAN ------------------------------------------------------------------------------------------- + QUERY PLAN +-------------------------------------------------------------------------- Hash Join - Output: (cte.r).column2, ((ROW("*VALUES*".column1, "*VALUES*".column2))).column2 - Hash Cond: ((cte.r).column1 = ((ROW("*VALUES*".column1, "*VALUES*".column2))).column1) + Output: (cte.r).column2, ((ROW(rr.column1, rr.column2))).column2 + Hash Cond: ((cte.r).column1 = ((ROW(rr.column1, rr.column2))).column1) CTE cte - -> Values Scan on "*VALUES*_1" - Output: ROW("*VALUES*_1".column1, "*VALUES*_1".column2) + -> Values Scan on r + Output: ROW(r.column1, r.column2) -> CTE Scan on cte Output: cte.r -> Hash - Output: (ROW("*VALUES*".column1, "*VALUES*".column2)) + Output: (ROW(rr.column1, rr.column2)) -> Limit - Output: (ROW("*VALUES*".column1, "*VALUES*".column2)) - -> Values Scan on "*VALUES*" - Output: ROW("*VALUES*".column1, "*VALUES*".column2) + Output: (ROW(rr.column1, rr.column2)) + -> Values Scan on rr + Output: ROW(rr.column1, rr.column2) (14 rows) explain (verbose, costs off) select (r).column2 from (select r from (values(1,2),(3,4)) r limit 1) ss; - QUERY PLAN -------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------- Subquery Scan on ss Output: (ss.r).column2 -> Limit - Output: (ROW("*VALUES*".column1, "*VALUES*".column2)) - -> Values Scan on "*VALUES*" - Output: ROW("*VALUES*".column1, "*VALUES*".column2) + Output: (ROW(r.column1, r.column2)) + -> Values Scan on r + Output: ROW(r.column1, r.column2) (6 rows) -- test pretty-print parenthesization rules, and SubLink deparsing diff --git a/src/test/regress/expected/gist.out b/src/test/regress/expected/gist.out index c75bbb23b6..af85945ea4 100644 --- a/src/test/regress/expected/gist.out +++ b/src/test/regress/expected/gist.out @@ -141,11 +141,11 @@ cross join lateral QUERY PLAN -------------------------------------------------------------------- Nested Loop - -> Values Scan on "*VALUES*" + -> Values Scan on v -> Limit -> Index Only Scan using gist_tbl_point_index on gist_tbl - Index Cond: (p <@ "*VALUES*".column1) - Order By: (p <-> ("*VALUES*".column1)[0]) + Index Cond: (p <@ v.bb) + Order By: (p <-> (v.bb)[0]) (6 rows) select p from diff --git a/src/test/regress/expected/groupingsets.out b/src/test/regress/expected/groupingsets.out index e1f0660810..3ce907081b 100644 --- a/src/test/regress/expected/groupingsets.out +++ b/src/test/regress/expected/groupingsets.out @@ -736,14 +736,14 @@ select a, b, sum(v.x) -- Test reordering of grouping sets explain (costs off) select * from gstest1 group by grouping sets((a,b,v),(v)) order by v,b,a; - QUERY PLAN ------------------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------- GroupAggregate - Group Key: "*VALUES*".column3, "*VALUES*".column2, "*VALUES*".column1 - Group Key: "*VALUES*".column3 + Group Key: gstest1.v, gstest1.b, gstest1.a + Group Key: gstest1.v -> Sort - Sort Key: "*VALUES*".column3, "*VALUES*".column2, "*VALUES*".column1 - -> Values Scan on "*VALUES*" + Sort Key: gstest1.v, gstest1.b, gstest1.a + -> Values Scan on gstest1 (6 rows) -- Agg level check. This query should error out. @@ -838,17 +838,17 @@ select v.c, (select count(*) from gstest2 group by () having v.c) explain (costs off) select v.c, (select count(*) from gstest2 group by () having v.c) from (values (false),(true)) v(c) order by v.c; - QUERY PLAN ------------------------------------------------------------ + QUERY PLAN +----------------------------------------------- Sort - Sort Key: "*VALUES*".column1 - -> Values Scan on "*VALUES*" + Sort Key: v.c + -> Values Scan on v SubPlan 1 -> Aggregate Group Key: () - Filter: "*VALUES*".column1 + Filter: v.c -> Result - One-Time Filter: "*VALUES*".column1 + One-Time Filter: v.c -> Seq Scan on gstest2 (10 rows) @@ -1064,14 +1064,14 @@ select a, b, grouping(a,b), sum(v), count(*), max(v) explain (costs off) select a, b, grouping(a,b), sum(v), count(*), max(v) from gstest1 group by grouping sets ((a),(b)) order by 3,1,2; - QUERY PLAN --------------------------------------------------------------------------------------------------------- + QUERY PLAN +-------------------------------------------------------------------- Sort - Sort Key: (GROUPING("*VALUES*".column1, "*VALUES*".column2)), "*VALUES*".column1, "*VALUES*".column2 + Sort Key: (GROUPING(gstest1.a, gstest1.b)), gstest1.a, gstest1.b -> HashAggregate - Hash Key: "*VALUES*".column1 - Hash Key: "*VALUES*".column2 - -> Values Scan on "*VALUES*" + Hash Key: gstest1.a + Hash Key: gstest1.b + -> Values Scan on gstest1 (6 rows) select a, b, grouping(a,b), sum(v), count(*), max(v) @@ -1098,33 +1098,33 @@ select a, b, grouping(a,b), sum(v), count(*), max(v) explain (costs off) select a, b, grouping(a,b), sum(v), count(*), max(v) from gstest1 group by cube(a,b) order by 3,1,2; - QUERY PLAN --------------------------------------------------------------------------------------------------------- + QUERY PLAN +-------------------------------------------------------------------- Sort - Sort Key: (GROUPING("*VALUES*".column1, "*VALUES*".column2)), "*VALUES*".column1, "*VALUES*".column2 + Sort Key: (GROUPING(gstest1.a, gstest1.b)), gstest1.a, gstest1.b -> MixedAggregate - Hash Key: "*VALUES*".column1, "*VALUES*".column2 - Hash Key: "*VALUES*".column1 - Hash Key: "*VALUES*".column2 + Hash Key: gstest1.a, gstest1.b + Hash Key: gstest1.a + Hash Key: gstest1.b Group Key: () - -> Values Scan on "*VALUES*" + -> Values Scan on gstest1 (8 rows) -- shouldn't try and hash explain (costs off) select a, b, grouping(a,b), array_agg(v order by v) from gstest1 group by cube(a,b); - QUERY PLAN ----------------------------------------------------------- + QUERY PLAN +---------------------------------------- GroupAggregate - Group Key: "*VALUES*".column1, "*VALUES*".column2 - Group Key: "*VALUES*".column1 + Group Key: gstest1.a, gstest1.b + Group Key: gstest1.a Group Key: () - Sort Key: "*VALUES*".column2 - Group Key: "*VALUES*".column2 + Sort Key: gstest1.b + Group Key: gstest1.b -> Sort - Sort Key: "*VALUES*".column1, "*VALUES*".column2 - -> Values Scan on "*VALUES*" + Sort Key: gstest1.a, gstest1.b + -> Values Scan on gstest1 (9 rows) -- unsortable cases @@ -1320,15 +1320,15 @@ explain (costs off) from (values (1),(2)) v(x), gstest_data(v.x) group by grouping sets (a,b) order by 3, 1, 2; - QUERY PLAN ---------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------ Sort - Sort Key: (sum("*VALUES*".column1)), gstest_data.a, gstest_data.b + Sort Key: (sum(v.x)), gstest_data.a, gstest_data.b -> HashAggregate Hash Key: gstest_data.a Hash Key: gstest_data.b -> Nested Loop - -> Values Scan on "*VALUES*" + -> Values Scan on v -> Function Scan on gstest_data (8 rows) @@ -1376,15 +1376,15 @@ select a, b, grouping(a,b), sum(v), count(*), max(v) explain (costs off) select a, b, grouping(a,b), sum(v), count(*), max(v) from gstest1 group by grouping sets ((a,b),(a+1,b+1),(a+2,b+2)) order by 3,6; - QUERY PLAN -------------------------------------------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------------- Sort - Sort Key: (GROUPING("*VALUES*".column1, "*VALUES*".column2)), (max("*VALUES*".column3)) + Sort Key: (GROUPING(gstest1.a, gstest1.b)), (max(gstest1.v)) -> HashAggregate - Hash Key: "*VALUES*".column1, "*VALUES*".column2 - Hash Key: ("*VALUES*".column1 + 1), ("*VALUES*".column2 + 1) - Hash Key: ("*VALUES*".column1 + 2), ("*VALUES*".column2 + 2) - -> Values Scan on "*VALUES*" + Hash Key: gstest1.a, gstest1.b + Hash Key: (gstest1.a + 1), (gstest1.b + 1) + Hash Key: (gstest1.a + 2), (gstest1.b + 2) + -> Values Scan on gstest1 (7 rows) select a, b, sum(c), sum(sum(c)) over (order by a,b) as rsum @@ -1452,7 +1452,7 @@ explain (costs off) Hash Key: gstest_data.b Group Key: () -> Nested Loop - -> Values Scan on "*VALUES*" + -> Values Scan on v -> Function Scan on gstest_data (10 rows) diff --git a/src/test/regress/expected/join.out b/src/test/regress/expected/join.out index 8d1d3ec1dc..8dea16cd86 100644 --- a/src/test/regress/expected/join.out +++ b/src/test/regress/expected/join.out @@ -4437,16 +4437,16 @@ select * from (values (1, array[10,20]), (2, array[20,30])) as v1(v1x,v1ys) left join (values (1, 10), (2, 20)) as v2(v2x,v2y) on v2x = v1x left join unnest(v1ys) as u1(u1y) on u1y = v2y; - QUERY PLAN -------------------------------------------------------------- + QUERY PLAN +---------------------------------------- Nested Loop Left Join - -> Values Scan on "*VALUES*" + -> Values Scan on v1 -> Hash Right Join - Hash Cond: (u1.u1y = "*VALUES*_1".column2) - Filter: ("*VALUES*_1".column1 = "*VALUES*".column1) + Hash Cond: (u1.u1y = v2.v2y) + Filter: (v2.v2x = v1.v1x) -> Function Scan on unnest u1 -> Hash - -> Values Scan on "*VALUES*_1" + -> Values Scan on v2 (8 rows) select * from @@ -4583,10 +4583,10 @@ using (join_key); QUERY PLAN -------------------------------------------------------------------------- Nested Loop Left Join - Output: "*VALUES*".column1, i1.f1, (666) - Join Filter: ("*VALUES*".column1 = i1.f1) - -> Values Scan on "*VALUES*" - Output: "*VALUES*".column1 + Output: foo1.join_key, i1.f1, (666) + Join Filter: (foo1.join_key = i1.f1) + -> Values Scan on foo1 + Output: foo1.join_key -> Materialize Output: i1.f1, (666) -> Nested Loop Left Join @@ -6460,12 +6460,12 @@ explain (costs off) -> Nested Loop -> Nested Loop -> Index Only Scan using tenk1_unique1 on tenk1 a - -> Values Scan on "*VALUES*" + -> Values Scan on ss -> Memoize - Cache Key: "*VALUES*".column1 + Cache Key: ss.x Cache Mode: logical -> Index Only Scan using tenk1_unique2 on tenk1 b - Index Cond: (unique2 = "*VALUES*".column1) + Index Cond: (unique2 = ss.x) (10 rows) select count(*) from tenk1 a, @@ -7245,12 +7245,12 @@ select * from lateral (select f1 from int4_tbl where f1 = any (select unique1 from tenk1 where unique2 = v.x offset 0)) ss; - QUERY PLAN ----------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------ Nested Loop - Output: "*VALUES*".column1, "*VALUES*".column2, int4_tbl.f1 - -> Values Scan on "*VALUES*" - Output: "*VALUES*".column1, "*VALUES*".column2 + Output: v.id, v.x, int4_tbl.f1 + -> Values Scan on v + Output: v.id, v.x -> Nested Loop Semi Join Output: int4_tbl.f1 Join Filter: (int4_tbl.f1 = tenk1.unique1) @@ -7260,7 +7260,7 @@ select * from Output: tenk1.unique1 -> Index Scan using tenk1_unique2 on public.tenk1 Output: tenk1.unique1 - Index Cond: (tenk1.unique2 = "*VALUES*".column2) + Index Cond: (tenk1.unique2 = v.x) (14 rows) select * from @@ -7287,13 +7287,13 @@ lateral (select * from int8_tbl t1, QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------- Nested Loop - Output: "*VALUES*".column1, t1.q1, t1.q2, ss2.q1, ss2.q2 + Output: v.id, t1.q1, t1.q2, ss2.q1, ss2.q2 -> Seq Scan on public.int8_tbl t1 Output: t1.q1, t1.q2 -> Nested Loop - Output: "*VALUES*".column1, ss2.q1, ss2.q2 - -> Values Scan on "*VALUES*" - Output: "*VALUES*".column1 + Output: v.id, ss2.q1, ss2.q2 + -> Values Scan on v + Output: v.id -> Subquery Scan on ss2 Output: ss2.q1, ss2.q2 Filter: (t1.q1 = ss2.q2) @@ -7309,7 +7309,7 @@ lateral (select * from int8_tbl t1, Output: GREATEST(t1.q1, t2.q2) InitPlan 2 -> Result - Output: ("*VALUES*".column1 = 0) + Output: (v.id = 0) -> Seq Scan on public.int8_tbl t3 Output: t3.q1, t3.q2 Filter: (t3.q2 = (InitPlan 1).col1) diff --git a/src/test/regress/expected/plpgsql.out b/src/test/regress/expected/plpgsql.out index 074af8f33a..cbfdde8a08 100644 --- a/src/test/regress/expected/plpgsql.out +++ b/src/test/regress/expected/plpgsql.out @@ -5180,10 +5180,10 @@ select consumes_rw_array(a), a from returns_rw_array(1) a; explain (verbose, costs off) select consumes_rw_array(a), a from (values (returns_rw_array(1)), (returns_rw_array(2))) v(a); - QUERY PLAN ---------------------------------------------------------------------- - Values Scan on "*VALUES*" - Output: consumes_rw_array("*VALUES*".column1), "*VALUES*".column1 + QUERY PLAN +--------------------------------------- + Values Scan on v + Output: consumes_rw_array(v.a), v.a (2 rows) select consumes_rw_array(a), a from diff --git a/src/test/regress/expected/rowtypes.out b/src/test/regress/expected/rowtypes.out index b400b58f76..fb8dd1e78d 100644 --- a/src/test/regress/expected/rowtypes.out +++ b/src/test/regress/expected/rowtypes.out @@ -1193,10 +1193,10 @@ explain (verbose, costs off) select r, r is null as isnull, r is not null as isnotnull from (values (1,row(1,2)), (1,row(null,null)), (1,null), (null,row(1,2)), (null,row(null,null)), (null,null) ) r(a,b); - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ - Values Scan on "*VALUES*" - Output: ROW("*VALUES*".column1, "*VALUES*".column2), (("*VALUES*".column1 IS NULL) AND ("*VALUES*".column2 IS NOT DISTINCT FROM NULL)), (("*VALUES*".column1 IS NOT NULL) AND ("*VALUES*".column2 IS DISTINCT FROM NULL)) + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------- + Values Scan on r + Output: ROW(r.a, r.b), ((r.a IS NULL) AND (r.b IS NOT DISTINCT FROM NULL)), ((r.a IS NOT NULL) AND (r.b IS DISTINCT FROM NULL)) (2 rows) select r, r is null as isnull, r is not null as isnotnull diff --git a/src/test/regress/expected/select_parallel.out b/src/test/regress/expected/select_parallel.out index 87273fa635..5c26d8c9fe 100644 --- a/src/test/regress/expected/select_parallel.out +++ b/src/test/regress/expected/select_parallel.out @@ -432,7 +432,7 @@ select * from QUERY PLAN -------------------------------------------------------------------------- Nested Loop Left Join - -> Values Scan on "*VALUES*" + -> Values Scan on v -> Finalize Aggregate -> Gather Workers Planned: 4 @@ -458,7 +458,7 @@ select * from QUERY PLAN -------------------------------------------------------------------------------------- Nested Loop Left Join - -> Values Scan on "*VALUES*" + -> Values Scan on v -> Finalize Aggregate -> Gather Workers Planned: 4 @@ -606,7 +606,7 @@ select * from explain_parallel_sort_stats(); explain_parallel_sort_stats -------------------------------------------------------------------------- Nested Loop Left Join (actual rows=30000 loops=1) - -> Values Scan on "*VALUES*" (actual rows=3 loops=1) + -> Values Scan on v (actual rows=3 loops=1) -> Gather Merge (actual rows=10000 loops=3) Workers Planned: 4 Workers Launched: 4 @@ -835,7 +835,7 @@ select * from QUERY PLAN ---------------------------------------------------------- Nested Loop Left Join - -> Values Scan on "*VALUES*" + -> Values Scan on v -> Finalize GroupAggregate Group Key: tenk1.string4 -> Gather Merge diff --git a/src/test/regress/expected/sqljson.out b/src/test/regress/expected/sqljson.out index 4f91e2117e..d5859e5e1a 100644 --- a/src/test/regress/expected/sqljson.out +++ b/src/test/regress/expected/sqljson.out @@ -1061,15 +1061,15 @@ DROP VIEW json_arrayagg_view; -- Test JSON_ARRAY(subquery) deparsing EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON_ARRAY(SELECT i FROM (VALUES (1), (2), (NULL), (4)) foo(i) RETURNING jsonb); - QUERY PLAN ---------------------------------------------------------------------- + QUERY PLAN +-------------------------------------------------------- Result Output: (InitPlan 1).col1 InitPlan 1 -> Aggregate - Output: JSON_ARRAYAGG("*VALUES*".column1 RETURNING jsonb) - -> Values Scan on "*VALUES*" - Output: "*VALUES*".column1 + Output: JSON_ARRAYAGG(foo.i RETURNING jsonb) + -> Values Scan on foo + Output: foo.i (7 rows) CREATE VIEW json_array_subquery_view AS diff --git a/src/test/regress/expected/subselect.out b/src/test/regress/expected/subselect.out index 9eecdc1e92..abcdb05d32 100644 --- a/src/test/regress/expected/subselect.out +++ b/src/test/regress/expected/subselect.out @@ -1124,7 +1124,7 @@ explain (verbose, costs off) (select (select now()) as x from (values(1),(2)) v(y)) ss; QUERY PLAN ------------------------------------------------ - Values Scan on "*VALUES*" + Values Scan on v Output: (InitPlan 1).col1, (InitPlan 2).col1 InitPlan 1 -> Result @@ -1141,7 +1141,7 @@ explain (verbose, costs off) ----------------------------------- Subquery Scan on ss Output: ss.x, ss.x - -> Values Scan on "*VALUES*" + -> Values Scan on v Output: (InitPlan 1).col1 InitPlan 1 -> Result @@ -1151,33 +1151,33 @@ explain (verbose, costs off) explain (verbose, costs off) select x, x from (select (select now() where y=y) as x from (values(1),(2)) v(y)) ss; - QUERY PLAN ----------------------------------------------------------------------- - Values Scan on "*VALUES*" + QUERY PLAN +---------------------------------------- + Values Scan on v Output: (SubPlan 1), (SubPlan 2) SubPlan 1 -> Result Output: now() - One-Time Filter: ("*VALUES*".column1 = "*VALUES*".column1) + One-Time Filter: (v.y = v.y) SubPlan 2 -> Result Output: now() - One-Time Filter: ("*VALUES*".column1 = "*VALUES*".column1) + One-Time Filter: (v.y = v.y) (10 rows) explain (verbose, costs off) select x, x from (select (select random() where y=y) as x from (values(1),(2)) v(y)) ss; - QUERY PLAN ----------------------------------------------------------------------------- + QUERY PLAN +---------------------------------------------- Subquery Scan on ss Output: ss.x, ss.x - -> Values Scan on "*VALUES*" + -> Values Scan on v Output: (SubPlan 1) SubPlan 1 -> Result Output: random() - One-Time Filter: ("*VALUES*".column1 = "*VALUES*".column1) + One-Time Filter: (v.y = v.y) (8 rows) -- @@ -1366,13 +1366,13 @@ select * from (3 not in (select * from (values (1), (2)) ss1)), (false) ) ss; - QUERY PLAN ----------------------------------------- - Values Scan on "*VALUES*" - Output: "*VALUES*".column1 + QUERY PLAN +------------------------------- + Values Scan on ss + Output: ss.column1 SubPlan 1 - -> Values Scan on "*VALUES*_1" - Output: "*VALUES*_1".column1 + -> Values Scan on ss1 + Output: ss1.column1 (5 rows) select * from diff --git a/src/test/regress/expected/tablesample.out b/src/test/regress/expected/tablesample.out index 9ff4611640..34b39a7153 100644 --- a/src/test/regress/expected/tablesample.out +++ b/src/test/regress/expected/tablesample.out @@ -251,14 +251,14 @@ select pct, count(unique1) from (values (0),(100)) v(pct), lateral (select * from tenk1 tablesample bernoulli (pct)) ss group by pct; - QUERY PLAN --------------------------------------------------------- + QUERY PLAN +------------------------------------------- HashAggregate - Group Key: "*VALUES*".column1 + Group Key: v.pct -> Nested Loop - -> Values Scan on "*VALUES*" + -> Values Scan on v -> Sample Scan on tenk1 - Sampling: bernoulli ("*VALUES*".column1) + Sampling: bernoulli (v.pct) (6 rows) select pct, count(unique1) from diff --git a/src/test/regress/expected/union.out b/src/test/regress/expected/union.out index 0fd0e1c38b..6b49cd225d 100644 --- a/src/test/regress/expected/union.out +++ b/src/test/regress/expected/union.out @@ -481,27 +481,27 @@ reset enable_hashagg; set enable_hashagg to on; explain (costs off) select x from (values ('11'::varbit), ('10'::varbit)) _(x) union select x from (values ('11'::varbit), ('10'::varbit)) _(x); - QUERY PLAN ------------------------------------------------ + QUERY PLAN +-------------------------------------- Unique -> Sort - Sort Key: "*VALUES*".column1 + Sort Key: _.x -> Append - -> Values Scan on "*VALUES*" - -> Values Scan on "*VALUES*_1" + -> Values Scan on _ + -> Values Scan on __1 (6 rows) set enable_hashagg to off; explain (costs off) select x from (values ('11'::varbit), ('10'::varbit)) _(x) union select x from (values ('11'::varbit), ('10'::varbit)) _(x); - QUERY PLAN ------------------------------------------------ + QUERY PLAN +-------------------------------------- Unique -> Sort - Sort Key: "*VALUES*".column1 + Sort Key: _.x -> Append - -> Values Scan on "*VALUES*" - -> Values Scan on "*VALUES*_1" + -> Values Scan on _ + -> Values Scan on __1 (6 rows) reset enable_hashagg; @@ -509,13 +509,13 @@ reset enable_hashagg; set enable_hashagg to on; explain (costs off) select x from (values (array[1, 2]), (array[1, 3])) _(x) union select x from (values (array[1, 2]), (array[1, 4])) _(x); - QUERY PLAN ------------------------------------------ + QUERY PLAN +-------------------------------- HashAggregate - Group Key: "*VALUES*".column1 + Group Key: _.x -> Append - -> Values Scan on "*VALUES*" - -> Values Scan on "*VALUES*_1" + -> Values Scan on _ + -> Values Scan on __1 (5 rows) select x from (values (array[1, 2]), (array[1, 3])) _(x) union select x from (values (array[1, 2]), (array[1, 4])) _(x); @@ -528,14 +528,14 @@ select x from (values (array[1, 2]), (array[1, 3])) _(x) union select x from (va explain (costs off) select x from (values (array[1, 2]), (array[1, 3])) _(x) intersect select x from (values (array[1, 2]), (array[1, 4])) _(x); - QUERY PLAN ------------------------------------------------ + QUERY PLAN +------------------------------------------- HashSetOp Intersect -> Append -> Subquery Scan on "*SELECT* 1" - -> Values Scan on "*VALUES*" + -> Values Scan on _ -> Subquery Scan on "*SELECT* 2" - -> Values Scan on "*VALUES*_1" + -> Values Scan on __1 (6 rows) select x from (values (array[1, 2]), (array[1, 3])) _(x) intersect select x from (values (array[1, 2]), (array[1, 4])) _(x); @@ -546,14 +546,14 @@ select x from (values (array[1, 2]), (array[1, 3])) _(x) intersect select x from explain (costs off) select x from (values (array[1, 2]), (array[1, 3])) _(x) except select x from (values (array[1, 2]), (array[1, 4])) _(x); - QUERY PLAN ------------------------------------------------ + QUERY PLAN +------------------------------------------- HashSetOp Except -> Append -> Subquery Scan on "*SELECT* 1" - -> Values Scan on "*VALUES*" + -> Values Scan on _ -> Subquery Scan on "*SELECT* 2" - -> Values Scan on "*VALUES*_1" + -> Values Scan on __1 (6 rows) select x from (values (array[1, 2]), (array[1, 3])) _(x) except select x from (values (array[1, 2]), (array[1, 4])) _(x); @@ -565,14 +565,14 @@ select x from (values (array[1, 2]), (array[1, 3])) _(x) except select x from (v -- non-hashable type explain (costs off) select x from (values (array['10'::varbit]), (array['11'::varbit])) _(x) union select x from (values (array['10'::varbit]), (array['01'::varbit])) _(x); - QUERY PLAN ------------------------------------------------ + QUERY PLAN +-------------------------------------- Unique -> Sort - Sort Key: "*VALUES*".column1 + Sort Key: _.x -> Append - -> Values Scan on "*VALUES*" - -> Values Scan on "*VALUES*_1" + -> Values Scan on _ + -> Values Scan on __1 (6 rows) select x from (values (array['10'::varbit]), (array['11'::varbit])) _(x) union select x from (values (array['10'::varbit]), (array['01'::varbit])) _(x); @@ -586,14 +586,14 @@ select x from (values (array['10'::varbit]), (array['11'::varbit])) _(x) union s set enable_hashagg to off; explain (costs off) select x from (values (array[1, 2]), (array[1, 3])) _(x) union select x from (values (array[1, 2]), (array[1, 4])) _(x); - QUERY PLAN ------------------------------------------------ + QUERY PLAN +-------------------------------------- Unique -> Sort - Sort Key: "*VALUES*".column1 + Sort Key: _.x -> Append - -> Values Scan on "*VALUES*" - -> Values Scan on "*VALUES*_1" + -> Values Scan on _ + -> Values Scan on __1 (6 rows) select x from (values (array[1, 2]), (array[1, 3])) _(x) union select x from (values (array[1, 2]), (array[1, 4])) _(x); @@ -606,16 +606,16 @@ select x from (values (array[1, 2]), (array[1, 3])) _(x) union select x from (va explain (costs off) select x from (values (array[1, 2]), (array[1, 3])) _(x) intersect select x from (values (array[1, 2]), (array[1, 4])) _(x); - QUERY PLAN ------------------------------------------------------ + QUERY PLAN +------------------------------------------------- SetOp Intersect -> Sort Sort Key: "*SELECT* 1".x -> Append -> Subquery Scan on "*SELECT* 1" - -> Values Scan on "*VALUES*" + -> Values Scan on _ -> Subquery Scan on "*SELECT* 2" - -> Values Scan on "*VALUES*_1" + -> Values Scan on __1 (8 rows) select x from (values (array[1, 2]), (array[1, 3])) _(x) intersect select x from (values (array[1, 2]), (array[1, 4])) _(x); @@ -626,16 +626,16 @@ select x from (values (array[1, 2]), (array[1, 3])) _(x) intersect select x from explain (costs off) select x from (values (array[1, 2]), (array[1, 3])) _(x) except select x from (values (array[1, 2]), (array[1, 4])) _(x); - QUERY PLAN ------------------------------------------------------ + QUERY PLAN +------------------------------------------------- SetOp Except -> Sort Sort Key: "*SELECT* 1".x -> Append -> Subquery Scan on "*SELECT* 1" - -> Values Scan on "*VALUES*" + -> Values Scan on _ -> Subquery Scan on "*SELECT* 2" - -> Values Scan on "*VALUES*_1" + -> Values Scan on __1 (8 rows) select x from (values (array[1, 2]), (array[1, 3])) _(x) except select x from (values (array[1, 2]), (array[1, 4])) _(x); @@ -649,14 +649,14 @@ reset enable_hashagg; set enable_hashagg to on; explain (costs off) select x from (values (row(1, 2)), (row(1, 3))) _(x) union select x from (values (row(1, 2)), (row(1, 4))) _(x); - QUERY PLAN ------------------------------------------------ + QUERY PLAN +-------------------------------------- Unique -> Sort - Sort Key: "*VALUES*".column1 + Sort Key: _.x -> Append - -> Values Scan on "*VALUES*" - -> Values Scan on "*VALUES*_1" + -> Values Scan on _ + -> Values Scan on __1 (6 rows) select x from (values (row(1, 2)), (row(1, 3))) _(x) union select x from (values (row(1, 2)), (row(1, 4))) _(x); @@ -669,16 +669,16 @@ select x from (values (row(1, 2)), (row(1, 3))) _(x) union select x from (values explain (costs off) select x from (values (row(1, 2)), (row(1, 3))) _(x) intersect select x from (values (row(1, 2)), (row(1, 4))) _(x); - QUERY PLAN ------------------------------------------------------ + QUERY PLAN +------------------------------------------------- SetOp Intersect -> Sort Sort Key: "*SELECT* 1".x -> Append -> Subquery Scan on "*SELECT* 1" - -> Values Scan on "*VALUES*" + -> Values Scan on _ -> Subquery Scan on "*SELECT* 2" - -> Values Scan on "*VALUES*_1" + -> Values Scan on __1 (8 rows) select x from (values (row(1, 2)), (row(1, 3))) _(x) intersect select x from (values (row(1, 2)), (row(1, 4))) _(x); @@ -689,16 +689,16 @@ select x from (values (row(1, 2)), (row(1, 3))) _(x) intersect select x from (va explain (costs off) select x from (values (row(1, 2)), (row(1, 3))) _(x) except select x from (values (row(1, 2)), (row(1, 4))) _(x); - QUERY PLAN ------------------------------------------------------ + QUERY PLAN +------------------------------------------------- SetOp Except -> Sort Sort Key: "*SELECT* 1".x -> Append -> Subquery Scan on "*SELECT* 1" - -> Values Scan on "*VALUES*" + -> Values Scan on _ -> Subquery Scan on "*SELECT* 2" - -> Values Scan on "*VALUES*_1" + -> Values Scan on __1 (8 rows) select x from (values (row(1, 2)), (row(1, 3))) _(x) except select x from (values (row(1, 2)), (row(1, 4))) _(x); @@ -712,14 +712,14 @@ select x from (values (row(1, 2)), (row(1, 3))) _(x) except select x from (value -- type is hashable. (Otherwise, this would fail at execution time.) explain (costs off) select x from (values (row('10'::varbit)), (row('11'::varbit))) _(x) union select x from (values (row('10'::varbit)), (row('01'::varbit))) _(x); - QUERY PLAN ------------------------------------------------ + QUERY PLAN +-------------------------------------- Unique -> Sort - Sort Key: "*VALUES*".column1 + Sort Key: _.x -> Append - -> Values Scan on "*VALUES*" - -> Values Scan on "*VALUES*_1" + -> Values Scan on _ + -> Values Scan on __1 (6 rows) select x from (values (row('10'::varbit)), (row('11'::varbit))) _(x) union select x from (values (row('10'::varbit)), (row('01'::varbit))) _(x); @@ -735,14 +735,14 @@ select x from (values (row('10'::varbit)), (row('11'::varbit))) _(x) union selec create type ct1 as (f1 varbit); explain (costs off) select x from (values (row('10'::varbit)::ct1), (row('11'::varbit)::ct1)) _(x) union select x from (values (row('10'::varbit)::ct1), (row('01'::varbit)::ct1)) _(x); - QUERY PLAN ------------------------------------------------ + QUERY PLAN +-------------------------------------- Unique -> Sort - Sort Key: "*VALUES*".column1 + Sort Key: _.x -> Append - -> Values Scan on "*VALUES*" - -> Values Scan on "*VALUES*_1" + -> Values Scan on _ + -> Values Scan on __1 (6 rows) select x from (values (row('10'::varbit)::ct1), (row('11'::varbit)::ct1)) _(x) union select x from (values (row('10'::varbit)::ct1), (row('01'::varbit)::ct1)) _(x); @@ -757,14 +757,14 @@ drop type ct1; set enable_hashagg to off; explain (costs off) select x from (values (row(1, 2)), (row(1, 3))) _(x) union select x from (values (row(1, 2)), (row(1, 4))) _(x); - QUERY PLAN ------------------------------------------------ + QUERY PLAN +-------------------------------------- Unique -> Sort - Sort Key: "*VALUES*".column1 + Sort Key: _.x -> Append - -> Values Scan on "*VALUES*" - -> Values Scan on "*VALUES*_1" + -> Values Scan on _ + -> Values Scan on __1 (6 rows) select x from (values (row(1, 2)), (row(1, 3))) _(x) union select x from (values (row(1, 2)), (row(1, 4))) _(x); @@ -777,16 +777,16 @@ select x from (values (row(1, 2)), (row(1, 3))) _(x) union select x from (values explain (costs off) select x from (values (row(1, 2)), (row(1, 3))) _(x) intersect select x from (values (row(1, 2)), (row(1, 4))) _(x); - QUERY PLAN ------------------------------------------------------ + QUERY PLAN +------------------------------------------------- SetOp Intersect -> Sort Sort Key: "*SELECT* 1".x -> Append -> Subquery Scan on "*SELECT* 1" - -> Values Scan on "*VALUES*" + -> Values Scan on _ -> Subquery Scan on "*SELECT* 2" - -> Values Scan on "*VALUES*_1" + -> Values Scan on __1 (8 rows) select x from (values (row(1, 2)), (row(1, 3))) _(x) intersect select x from (values (row(1, 2)), (row(1, 4))) _(x); @@ -797,16 +797,16 @@ select x from (values (row(1, 2)), (row(1, 3))) _(x) intersect select x from (va explain (costs off) select x from (values (row(1, 2)), (row(1, 3))) _(x) except select x from (values (row(1, 2)), (row(1, 4))) _(x); - QUERY PLAN ------------------------------------------------------ + QUERY PLAN +------------------------------------------------- SetOp Except -> Sort Sort Key: "*SELECT* 1".x -> Append -> Subquery Scan on "*SELECT* 1" - -> Values Scan on "*VALUES*" + -> Values Scan on _ -> Subquery Scan on "*SELECT* 2" - -> Values Scan on "*VALUES*_1" + -> Values Scan on __1 (8 rows) select x from (values (row(1, 2)), (row(1, 3))) _(x) except select x from (values (row(1, 2)), (row(1, 4))) _(x); diff --git a/src/test/regress/expected/updatable_views.out b/src/test/regress/expected/updatable_views.out index 96609a38f5..9f37d4ee1b 100644 --- a/src/test/regress/expected/updatable_views.out +++ b/src/test/regress/expected/updatable_views.out @@ -2988,15 +2988,15 @@ EXPLAIN (costs off) MERGE INTO rw_view1 t USING (VALUES ('Tom'), ('Dick'), ('Harry')) AS v(person) ON t.person = v.person WHEN MATCHED AND snoop(t.person) THEN UPDATE SET person = v.person; - QUERY PLAN -------------------------------------------------------------- + QUERY PLAN +----------------------------------------------------- Merge on base_tbl -> Nested Loop - Join Filter: (base_tbl.person = "*VALUES*".column1) + Join Filter: (base_tbl.person = v.person) -> Seq Scan on base_tbl Filter: (visibility = 'public'::text) -> Materialize - -> Values Scan on "*VALUES*" + -> Values Scan on v (7 rows) -- security barrier view on top of security barrier view @@ -3090,10 +3090,10 @@ MERGE INTO rw_view2 t ------------------------------------------------------------------------- Merge on base_tbl -> Nested Loop - Join Filter: (base_tbl.person = "*VALUES*".column1) + Join Filter: (base_tbl.person = v.person) -> Seq Scan on base_tbl Filter: ((visibility = 'public'::text) AND snoop(person)) - -> Values Scan on "*VALUES*" + -> Values Scan on v (6 rows) DROP TABLE base_tbl CASCADE;