Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions src/backend/gpopt/translate/CTranslatorQueryToDXL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4142,9 +4142,13 @@ CTranslatorQueryToDXL::TranslateJoinExprInFromToDXL(JoinExpr *join_expr)
{
continue;
}
GPOS_ASSERT(IsA(join_alias_node, Var) ||
IsA(join_alias_node, FuncExpr) ||
IsA(join_alias_node, CoalesceExpr));
// A merged USING column is a plain Var when both inputs have the same
// type, a CoalesceExpr for a FULL JOIN, or the left input coerced to
// the common type otherwise (FuncExpr, RelabelType, ...). References
// to join alias columns have already been flattened by
// CQueryMutators::NormalizeQuery, so any expression the scalar
// translator understands is acceptable here; unsupported nodes raise
// a regular "unsupported feature" exception from TranslateExprToDXL.
CHAR *col_name_char_array = strVal(lfirst(lc_col_name));

// create the DXL node holding the target list entry and add it to proj list
Expand Down
53 changes: 53 additions & 0 deletions src/test/regress/expected/join_gp.out
Original file line number Diff line number Diff line change
Expand Up @@ -3672,3 +3672,56 @@ select * from generate_series(1,2) t1, lateral (select t3.i from lat_oq_t2 t2 jo

drop table lat_oq_t2;
drop table lat_oq_t3;
--
-- Test that ORCA can plan a USING join whose merged column is the left input
-- coerced with a binary-compatible cast (RelabelType), e.g. varchar vs text or
-- int vs oid. The query-to-DXL translator used to assert on such join alias
-- vars and fall back to the Postgres planner.
--
create table using_coerce_t1(k varchar(10), f2 int) distributed by (f2);
create table using_coerce_t2(k text, f2 oid) distributed by (f2);
insert into using_coerce_t1 values ('a', 1), ('b', 2);
insert into using_coerce_t2 values ('a', 1), ('c', 3);
explain (costs off) select k from using_coerce_t1 left join using_coerce_t2 using(k) order by 1;
QUERY PLAN
--------------------------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3)
Merge Key: ((using_coerce_t1.k)::character varying)
-> Sort
Sort Key: ((using_coerce_t1.k)::character varying)
-> Hash Right Join
Hash Cond: (using_coerce_t2.k = (using_coerce_t1.k)::text)
-> Redistribute Motion 3:3 (slice2; segments: 3)
Hash Key: using_coerce_t2.k
-> Seq Scan on using_coerce_t2
-> Hash
-> Redistribute Motion 3:3 (slice3; segments: 3)
Hash Key: using_coerce_t1.k
-> Seq Scan on using_coerce_t1
Optimizer: Postgres query optimizer
(14 rows)

select k from using_coerce_t1 left join using_coerce_t2 using(k) order by 1;
k
---
a
b
(2 rows)

select f2, count(*) from using_coerce_t1 left join using_coerce_t2 using(f2) group by f2 order by 1;
f2 | count
----+-------
1 | 1
2 | 1
(2 rows)

select f2, count(*) from using_coerce_t1 x(x0,x1) left join (using_coerce_t1 left join using_coerce_t2 using(f2)) on (x0 = 'a') group by f2 order by 1;
f2 | count
----+-------
1 | 1
2 | 1
| 1
(3 rows)

drop table using_coerce_t1;
drop table using_coerce_t2;
50 changes: 50 additions & 0 deletions src/test/regress/expected/join_gp_optimizer.out
Original file line number Diff line number Diff line change
Expand Up @@ -3634,3 +3634,53 @@ select * from generate_series(1,2) t1, lateral (select t3.i from lat_oq_t2 t2 jo

drop table lat_oq_t2;
drop table lat_oq_t3;
--
-- Test that ORCA can plan a USING join whose merged column is the left input
-- coerced with a binary-compatible cast (RelabelType), e.g. varchar vs text or
-- int vs oid. The query-to-DXL translator used to assert on such join alias
-- vars and fall back to the Postgres planner.
--
create table using_coerce_t1(k varchar(10), f2 int) distributed by (f2);
create table using_coerce_t2(k text, f2 oid) distributed by (f2);
insert into using_coerce_t1 values ('a', 1), ('b', 2);
insert into using_coerce_t2 values ('a', 1), ('c', 3);
explain (costs off) select k from using_coerce_t1 left join using_coerce_t2 using(k) order by 1;
QUERY PLAN
--------------------------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3)
Merge Key: ((using_coerce_t1.k)::character varying)
-> Sort
Sort Key: ((using_coerce_t1.k)::character varying)
-> Hash Left Join
Hash Cond: ((using_coerce_t1.k)::text = using_coerce_t2.k)
-> Seq Scan on using_coerce_t1
-> Hash
-> Broadcast Motion 3:3 (slice2; segments: 3)
-> Seq Scan on using_coerce_t2
Optimizer: GPORCA
(11 rows)

select k from using_coerce_t1 left join using_coerce_t2 using(k) order by 1;
k
---
a
b
(2 rows)

select f2, count(*) from using_coerce_t1 left join using_coerce_t2 using(f2) group by f2 order by 1;
f2 | count
----+-------
1 | 1
2 | 1
(2 rows)

select f2, count(*) from using_coerce_t1 x(x0,x1) left join (using_coerce_t1 left join using_coerce_t2 using(f2)) on (x0 = 'a') group by f2 order by 1;
f2 | count
----+-------
1 | 1
2 | 1
| 1
(3 rows)

drop table using_coerce_t1;
drop table using_coerce_t2;
19 changes: 19 additions & 0 deletions src/test/regress/sql/join_gp.sql
Original file line number Diff line number Diff line change
Expand Up @@ -1332,3 +1332,22 @@ select * from generate_series(1,2) t1, lateral (select t3.i from lat_oq_t2 t2 jo

drop table lat_oq_t2;
drop table lat_oq_t3;

--
-- Test that ORCA can plan a USING join whose merged column is the left input
-- coerced with a binary-compatible cast (RelabelType), e.g. varchar vs text or
-- int vs oid. The query-to-DXL translator used to assert on such join alias
-- vars and fall back to the Postgres planner.
--
create table using_coerce_t1(k varchar(10), f2 int) distributed by (f2);
create table using_coerce_t2(k text, f2 oid) distributed by (f2);
insert into using_coerce_t1 values ('a', 1), ('b', 2);
insert into using_coerce_t2 values ('a', 1), ('c', 3);

explain (costs off) select k from using_coerce_t1 left join using_coerce_t2 using(k) order by 1;
select k from using_coerce_t1 left join using_coerce_t2 using(k) order by 1;
select f2, count(*) from using_coerce_t1 left join using_coerce_t2 using(f2) group by f2 order by 1;
select f2, count(*) from using_coerce_t1 x(x0,x1) left join (using_coerce_t1 left join using_coerce_t2 using(f2)) on (x0 = 'a') group by f2 order by 1;

drop table using_coerce_t1;
drop table using_coerce_t2;
Loading