diff --git a/src/execution/volcano/mod.rs b/src/execution/volcano/mod.rs index d228ed1d..472ace14 100644 --- a/src/execution/volcano/mod.rs +++ b/src/execution/volcano/mod.rs @@ -78,7 +78,9 @@ pub fn build_read(plan: LogicalPlan, transaction: &T) -> BoxedEx let left_input = childrens.pop().unwrap(); match &op.on { - JoinCondition::On { on, .. } if !on.is_empty() => { + JoinCondition::On { on, .. } + if !on.is_empty() && plan.physical_option == Some(PhysicalOption::HashJoin) => + { HashJoin::from((op, left_input, right_input)).execute(transaction) } _ => NestedLoopJoin::from((op, left_input, right_input)).execute(transaction), diff --git a/src/optimizer/rule/implementation/dql/join.rs b/src/optimizer/rule/implementation/dql/join.rs index a85d92c0..caf2edf4 100644 --- a/src/optimizer/rule/implementation/dql/join.rs +++ b/src/optimizer/rule/implementation/dql/join.rs @@ -3,8 +3,8 @@ use crate::optimizer::core::memo::{Expression, GroupExpression}; use crate::optimizer::core::pattern::{Pattern, PatternChildrenPredicate}; use crate::optimizer::core::rule::{ImplementationRule, MatchPattern}; use crate::optimizer::core::statistics_meta::StatisticMetaLoader; +use crate::planner::operator::join::{JoinCondition, JoinOperator}; use crate::planner::operator::{Operator, PhysicalOption}; -use crate::single_mapping; use crate::storage::Transaction; use lazy_static::lazy_static; @@ -18,10 +18,36 @@ lazy_static! { } #[derive(Clone)] -pub struct HashJoinImplementation; +pub struct JoinImplementation; -single_mapping!( - HashJoinImplementation, - JOIN_PATTERN, - PhysicalOption::HashJoin -); +impl MatchPattern for JoinImplementation { + fn pattern(&self) -> &Pattern { + &JOIN_PATTERN + } +} + +impl ImplementationRule for JoinImplementation { + fn to_expression( + &self, + op: &Operator, + _: &StatisticMetaLoader<'_, T>, + group_expr: &mut GroupExpression, + ) -> Result<(), DatabaseError> { + let mut physical_option = PhysicalOption::NestLoopJoin; + + if let Operator::Join(JoinOperator { + on: JoinCondition::On { on, .. }, + .. + }) = op + { + if !on.is_empty() { + physical_option = PhysicalOption::HashJoin; + } + } + group_expr.append_expr(Expression { + op: physical_option, + cost: None, + }); + Ok(()) + } +} diff --git a/src/optimizer/rule/implementation/mod.rs b/src/optimizer/rule/implementation/mod.rs index fd0efbf3..9f35b245 100644 --- a/src/optimizer/rule/implementation/mod.rs +++ b/src/optimizer/rule/implementation/mod.rs @@ -24,7 +24,7 @@ use crate::optimizer::rule::implementation::dql::aggregate::{ }; use crate::optimizer::rule::implementation::dql::dummy::DummyImplementation; use crate::optimizer::rule::implementation::dql::filter::FilterImplementation; -use crate::optimizer::rule::implementation::dql::join::HashJoinImplementation; +use crate::optimizer::rule::implementation::dql::join::JoinImplementation; use crate::optimizer::rule::implementation::dql::limit::LimitImplementation; use crate::optimizer::rule::implementation::dql::projection::ProjectionImplementation; use crate::optimizer::rule::implementation::dql::scan::{ @@ -71,7 +71,7 @@ impl MatchPattern for ImplementationRuleImpl { ImplementationRuleImpl::SimpleAggregate => SimpleAggregateImplementation.pattern(), ImplementationRuleImpl::Dummy => DummyImplementation.pattern(), ImplementationRuleImpl::Filter => FilterImplementation.pattern(), - ImplementationRuleImpl::HashJoin => HashJoinImplementation.pattern(), + ImplementationRuleImpl::HashJoin => JoinImplementation.pattern(), ImplementationRuleImpl::Limit => LimitImplementation.pattern(), ImplementationRuleImpl::Projection => ProjectionImplementation.pattern(), ImplementationRuleImpl::SeqScan => SeqScanImplementation.pattern(), @@ -114,7 +114,7 @@ impl ImplementationRule for ImplementationRuleImpl { FilterImplementation.to_expression(operator, loader, group_expr)? } ImplementationRuleImpl::HashJoin => { - HashJoinImplementation.to_expression(operator, loader, group_expr)? + JoinImplementation.to_expression(operator, loader, group_expr)? } ImplementationRuleImpl::Limit => { LimitImplementation.to_expression(operator, loader, group_expr)? diff --git a/src/planner/operator/mod.rs b/src/planner/operator/mod.rs index bc2ba605..e7ae73bd 100644 --- a/src/planner/operator/mod.rs +++ b/src/planner/operator/mod.rs @@ -88,6 +88,7 @@ pub enum PhysicalOption { HashAggregate, Filter, HashJoin, + NestLoopJoin, Project, SeqScan, IndexScan(IndexInfo), @@ -270,6 +271,7 @@ impl fmt::Display for PhysicalOption { PhysicalOption::HashAggregate => write!(f, "HashAggregate"), PhysicalOption::Filter => write!(f, "Filter"), PhysicalOption::HashJoin => write!(f, "HashJoin"), + PhysicalOption::NestLoopJoin => write!(f, "NestLoopJoin"), PhysicalOption::Project => write!(f, "Project"), PhysicalOption::SeqScan => write!(f, "SeqScan"), PhysicalOption::IndexScan(index) => write!(f, "IndexScan By {}", index), diff --git a/tests/slt/crdb/sqlite.slt b/tests/slt/crdb/sqlite.slt index cc5a7337..b37840ea 100644 --- a/tests/slt/crdb/sqlite.slt +++ b/tests/slt/crdb/sqlite.slt @@ -30,16 +30,15 @@ CREATE TABLE tab64784(pk INTEGER primary key, col0 INTEGER, col1 FLOAT, col2 VAR statement ok INSERT INTO tab64784 VALUES(0,212,202.62,'nshdy',212,208.79,'wsxfc'),(1,213,203.64,'xwfuo',213,209.26,'lyswz'),(2,214,204.82,'jnued',216,210.48,'qczzf'),(3,215,205.40,'jtijf',217,211.96,'dpugl'),(4,216,206.3,'dpdzk',219,212.43,'xfirg'),(5,218,207.43,'qpwyw',220,213.50,'fmgky'),(6,219,208.3,'uooxb',221,215.30,'xpmdy'),(7,220,209.54,'ndtbb',225,218.8,'ivqyw'),(8,221,210.65,'zjpts',226,219.82,'sezsm'),(9,222,211.57,'slaxq',227,220.91,'bdqyb') -# TODO: Support `NestLoopJoin` -# query II -# SELECT pk, col0 FROM tab64784 WHERE (col0 IN (SELECT col3 FROM tab64784 WHERE col3 IS NULL OR (col1 < 22.54) OR col4 > 85.74) OR ((col4 IS NULL)) AND col3 < 8 OR (col4 > 82.93 AND (col0 <= 61) AND col0 > 94 AND col0 > 15)) ORDER BY 2 DESC -# ---- -# 0 212 -# 1 213 -# 4 216 -# 6 219 -# 7 220 -# 8 221 +query II +SELECT pk, col0 FROM tab64784 WHERE (col0 IN (SELECT col3 FROM tab64784 WHERE col3 IS NULL OR (col1 < 22.54) OR col4 > 85.74) OR ((col4 IS NULL)) AND col3 < 8 OR (col4 > 82.93 AND (col0 <= 61) AND col0 > 94 AND col0 > 15)) ORDER BY 2 DESC +---- +0 212 +1 213 +4 216 +6 219 +7 220 +8 221 statement ok drop table tab64784 diff --git a/tests/slt/sql_2016/F041_08.slt b/tests/slt/sql_2016/F041_08.slt index d54dce2a..50e31c01 100644 --- a/tests/slt/sql_2016/F041_08.slt +++ b/tests/slt/sql_2016/F041_08.slt @@ -1,33 +1,31 @@ # F041-08: All comparison operators are supported (rather than just =) -# TODO: NestLoopJoin - -# statement ok -# CREATE TABLE TABLE_F041_08_01_011 ( ID INT PRIMARY KEY, A INTEGER ); +statement ok +CREATE TABLE TABLE_F041_08_01_011 ( ID INT PRIMARY KEY, A INTEGER ); -# statement ok -# CREATE TABLE TABLE_F041_08_01_012 ( ID INT PRIMARY KEY, B INTEGER ); +statement ok +CREATE TABLE TABLE_F041_08_01_012 ( ID INT PRIMARY KEY, B INTEGER ); -# query II -# SELECT TABLE_F041_08_01_011.A, TABLE_F041_08_01_012.B FROM TABLE_F041_08_01_011 JOIN TABLE_F041_08_01_012 ON TABLE_F041_08_01_011.A < TABLE_F041_08_01_012.B +query II +SELECT TABLE_F041_08_01_011.A, TABLE_F041_08_01_012.B FROM TABLE_F041_08_01_011 JOIN TABLE_F041_08_01_012 ON TABLE_F041_08_01_011.A < TABLE_F041_08_01_012.B -# statement ok -# CREATE TABLE TABLE_F041_08_01_021 ( ID INT PRIMARY KEY, A INTEGER ); +statement ok +CREATE TABLE TABLE_F041_08_01_021 ( ID INT PRIMARY KEY, A INTEGER ); -# statement ok -# CREATE TABLE TABLE_F041_08_01_022 ( ID INT PRIMARY KEY, B INTEGER ); +statement ok +CREATE TABLE TABLE_F041_08_01_022 ( ID INT PRIMARY KEY, B INTEGER ); -# query II -# SELECT TABLE_F041_08_01_021.A, TABLE_F041_08_01_022.B FROM TABLE_F041_08_01_021 JOIN TABLE_F041_08_01_022 ON TABLE_F041_08_01_021.A <= TABLE_F041_08_01_022.B +query II +SELECT TABLE_F041_08_01_021.A, TABLE_F041_08_01_022.B FROM TABLE_F041_08_01_021 JOIN TABLE_F041_08_01_022 ON TABLE_F041_08_01_021.A <= TABLE_F041_08_01_022.B -# statement ok -# CREATE TABLE TABLE_F041_08_01_031 ( ID INT PRIMARY KEY, A INTEGER ); +statement ok +CREATE TABLE TABLE_F041_08_01_031 ( ID INT PRIMARY KEY, A INTEGER ); -# statement ok -# CREATE TABLE TABLE_F041_08_01_032 ( ID INT PRIMARY KEY, B INTEGER ); +statement ok +CREATE TABLE TABLE_F041_08_01_032 ( ID INT PRIMARY KEY, B INTEGER ); -# query II -# SELECT TABLE_F041_08_01_031.A, TABLE_F041_08_01_032.B FROM TABLE_F041_08_01_031 JOIN TABLE_F041_08_01_032 ON TABLE_F041_08_01_031.A <> TABLE_F041_08_01_032.B +query II +SELECT TABLE_F041_08_01_031.A, TABLE_F041_08_01_032.B FROM TABLE_F041_08_01_031 JOIN TABLE_F041_08_01_032 ON TABLE_F041_08_01_031.A <> TABLE_F041_08_01_032.B statement ok CREATE TABLE TABLE_F041_08_01_041 ( ID INT PRIMARY KEY, A INTEGER ); @@ -38,20 +36,20 @@ CREATE TABLE TABLE_F041_08_01_042 ( ID INT PRIMARY KEY, B INTEGER ); query II SELECT TABLE_F041_08_01_041.A, TABLE_F041_08_01_042.B FROM TABLE_F041_08_01_041 JOIN TABLE_F041_08_01_042 ON TABLE_F041_08_01_041.A = TABLE_F041_08_01_042.B -# statement ok -# CREATE TABLE TABLE_F041_08_01_051 ( ID INT PRIMARY KEY, A INTEGER ); +statement ok +CREATE TABLE TABLE_F041_08_01_051 ( ID INT PRIMARY KEY, A INTEGER ); -# statement ok -# CREATE TABLE TABLE_F041_08_01_052 ( ID INT PRIMARY KEY, B INTEGER ); +statement ok +CREATE TABLE TABLE_F041_08_01_052 ( ID INT PRIMARY KEY, B INTEGER ); -# query II -# SELECT TABLE_F041_08_01_051.A, TABLE_F041_08_01_052.B FROM TABLE_F041_08_01_051 JOIN TABLE_F041_08_01_052 ON TABLE_F041_08_01_051.A > TABLE_F041_08_01_052.B +query II +SELECT TABLE_F041_08_01_051.A, TABLE_F041_08_01_052.B FROM TABLE_F041_08_01_051 JOIN TABLE_F041_08_01_052 ON TABLE_F041_08_01_051.A > TABLE_F041_08_01_052.B -# statement ok -# CREATE TABLE TABLE_F041_08_01_061 ( ID INT PRIMARY KEY, A INTEGER ); +statement ok +CREATE TABLE TABLE_F041_08_01_061 ( ID INT PRIMARY KEY, A INTEGER ); -# statement ok -# CREATE TABLE TABLE_F041_08_01_062 ( ID INT PRIMARY KEY, B INTEGER ); +statement ok +CREATE TABLE TABLE_F041_08_01_062 ( ID INT PRIMARY KEY, B INTEGER ); -# query II -# SELECT TABLE_F041_08_01_061.A, TABLE_F041_08_01_062.B FROM TABLE_F041_08_01_061 JOIN TABLE_F041_08_01_062 ON TABLE_F041_08_01_061.A >= TABLE_F041_08_01_062.B +query II +SELECT TABLE_F041_08_01_061.A, TABLE_F041_08_01_062.B FROM TABLE_F041_08_01_061 JOIN TABLE_F041_08_01_062 ON TABLE_F041_08_01_061.A >= TABLE_F041_08_01_062.B diff --git a/tests/slt/subquery.slt b/tests/slt/subquery.slt index c6f394d1..a90fe587 100644 --- a/tests/slt/subquery.slt +++ b/tests/slt/subquery.slt @@ -34,11 +34,10 @@ select x.a from (select -a as a from t1) as x; -1 -3 -# TODO: NestLoopJoin -# query III -# select * from t1 where a <= (select 4) and a > (select 1) -# ---- -# 1 3 4 +query III +select * from t1 where a <= (select 4) and a > (select 1) +---- +1 3 4 # query III # select * from t1 where a <= (select 4) and (-a + 1) < (select 1) - 1