diff --git a/src/query/sql/src/executor/physical_plans/physical_hash_join.rs b/src/query/sql/src/executor/physical_plans/physical_hash_join.rs index fa2127c585d1..ce30264a7419 100644 --- a/src/query/sql/src/executor/physical_plans/physical_hash_join.rs +++ b/src/query/sql/src/executor/physical_plans/physical_hash_join.rs @@ -249,7 +249,7 @@ impl PhysicalPlanBuilder { let mut probe_projections = ColumnSet::new(); let mut build_projections = ColumnSet::new(); - for column in pre_column_projections { + for column in pre_column_projections.iter() { if let Some((index, _)) = probe_schema.column_with_name(&column.to_string()) { probe_projections.insert(index); } @@ -320,8 +320,29 @@ impl PhysicalPlanBuilder { probe_fields.extend(build_fields); probe_fields } - JoinType::LeftSemi | JoinType::LeftAnti => probe_fields, - JoinType::RightSemi | JoinType::RightAnti => build_fields, + JoinType::LeftSemi | JoinType::LeftAnti | JoinType::RightSemi | JoinType::RightAnti => { + let (result_fields, dropped_fields) = if join.join_type == JoinType::LeftSemi + || join.join_type == JoinType::LeftAnti + { + (probe_fields, build_fields) + } else { + (build_fields, probe_fields) + }; + for field in dropped_fields.iter() { + if result_fields.iter().all(|x| x.name() != field.name()) && + let Ok(index) = field.name().parse::() && + column_projections.contains(&index) + { + let metadata = self.metadata.read(); + return Err(ErrorCode::SemanticError(format!( + "cannot access the {:?}.{:?} in ANTI or SEMI join", + metadata.table(index).name(), + metadata.column(index).name() + ))); + } + } + result_fields + } JoinType::LeftMark => { let name = if let Some(idx) = join.marker_index { idx.to_string() diff --git a/tests/sqllogictests/suites/query/join/join.test b/tests/sqllogictests/suites/query/join/join.test index 18cc2eeac7db..8041c03249ae 100644 --- a/tests/sqllogictests/suites/query/join/join.test +++ b/tests/sqllogictests/suites/query/join/join.test @@ -194,4 +194,44 @@ statement ok drop table t; statement ok -drop table t1; \ No newline at end of file +drop table t1; + +statement ok +drop table if exists t1; + +statement ok +drop table if exists t2; + +statement ok +create table t1(a int, b int); + +statement ok +insert into t1 values(1, 1),(2, 2),(3, 3); + +statement ok +create table t2(a int, b int); + +statement ok +insert into t2 values(1, 1),(2, 2); + +statement error 1065 +SELECT t1.a FROM t1 RIGHT ANTI JOIN t2 ON t1.a = t2.a; +--- + +statement error 1065 +SELECT t1.a FROM t1 RIGHT SEMI JOIN t2 ON t1.a = t2.a; +--- + +statement error 1065 +SELECT t2.a FROM t1 LEFT ANTI JOIN t2 ON t1.a = t2.a; +--- + +statement error 1065 +SELECT t2.a FROM t1 LEFT SEMI JOIN t2 ON t1.a = t2.a; +--- + +statement ok +drop table t1; + +statement ok +drop table t2;