Skip to content

Commit 89ca1c5

Browse files
committed
refactor: flatten union plan
1 parent 28a6090 commit 89ca1c5

File tree

2 files changed

+7
-146
lines changed

2 files changed

+7
-146
lines changed

src/query/sql/src/executor/physical_plans/physical_union_all.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ use crate::executor::explain::PlanStatsInfo;
2727
use crate::executor::PhysicalPlan;
2828
use crate::executor::PhysicalPlanBuilder;
2929
use crate::optimizer::SExpr;
30+
use crate::optimizer::StatInfo;
3031
use crate::plans::BoundColumnRef;
3132
use crate::plans::ScalarItem;
3233
use crate::ColumnBindingBuilder;

src/query/sql/src/planner/binder/select.rs

Lines changed: 6 additions & 146 deletions
Original file line numberDiff line numberDiff line change
@@ -507,7 +507,6 @@ impl Binder {
507507
}
508508
(SetOperator::Union, true) => self.bind_union(
509509
left.span(),
510-
right.span(),
511510
left_bind_context,
512511
right_bind_context,
513512
left_expr,
@@ -516,7 +515,6 @@ impl Binder {
516515
),
517516
(SetOperator::Union, false) => self.bind_union(
518517
left.span(),
519-
right.span(),
520518
left_bind_context,
521519
right_bind_context,
522520
left_expr,
@@ -533,48 +531,18 @@ impl Binder {
533531
pub fn bind_union(
534532
&mut self,
535533
left_span: Span,
536-
right_span: Span,
537534
left_context: BindContext,
538535
right_context: BindContext,
539536
left_expr: SExpr,
540537
right_expr: SExpr,
541538
distinct: bool,
542539
) -> Result<(SExpr, BindContext)> {
543-
let mut coercion_types = Vec::with_capacity(left_context.columns.len());
544-
for (left_col, right_col) in left_context
540+
let pairs = left_context
545541
.columns
546542
.iter()
547543
.zip(right_context.columns.iter())
548-
{
549-
if left_col.data_type != right_col.data_type {
550-
if let Some(data_type) = common_super_type(
551-
*left_col.data_type.clone(),
552-
*right_col.data_type.clone(),
553-
&BUILTIN_FUNCTIONS.default_cast_rules,
554-
) {
555-
coercion_types.push(data_type);
556-
} else {
557-
return Err(ErrorCode::SemanticError(format!(
558-
"SetOperation's types cannot be matched, left column {:?}, type: {:?}, right column {:?}, type: {:?}",
559-
left_col.column_name,
560-
left_col.data_type,
561-
right_col.column_name,
562-
right_col.data_type
563-
)));
564-
}
565-
} else {
566-
coercion_types.push(*left_col.data_type.clone());
567-
}
568-
}
569-
let (new_bind_context, pairs, left_expr, right_expr) = self.coercion_union_type(
570-
left_span,
571-
right_span,
572-
left_context,
573-
right_context,
574-
left_expr,
575-
right_expr,
576-
coercion_types,
577-
)?;
544+
.map(|(l, r)| (l.index, r.index))
545+
.collect();
578546

579547
let union_plan = UnionAll { pairs };
580548
let mut new_expr = SExpr::create_binary(
@@ -586,14 +554,14 @@ impl Binder {
586554
if distinct {
587555
new_expr = self.bind_distinct(
588556
left_span,
589-
&new_bind_context,
590-
new_bind_context.all_column_bindings(),
557+
&left_context,
558+
left_context.all_column_bindings(),
591559
&mut HashMap::new(),
592560
new_expr,
593561
)?;
594562
}
595563

596-
Ok((new_expr, new_bind_context))
564+
Ok((new_expr, left_context))
597565
}
598566

599567
pub fn bind_intersect(
@@ -687,114 +655,6 @@ impl Binder {
687655
Ok((s_expr, left_context))
688656
}
689657

690-
#[allow(clippy::type_complexity)]
691-
#[allow(clippy::too_many_arguments)]
692-
fn coercion_union_type(
693-
&self,
694-
left_span: Span,
695-
right_span: Span,
696-
left_bind_context: BindContext,
697-
right_bind_context: BindContext,
698-
mut left_expr: SExpr,
699-
mut right_expr: SExpr,
700-
coercion_types: Vec<DataType>,
701-
) -> Result<(BindContext, Vec<(IndexType, IndexType)>, SExpr, SExpr)> {
702-
let mut left_scalar_items = Vec::with_capacity(left_bind_context.columns.len());
703-
let mut right_scalar_items = Vec::with_capacity(right_bind_context.columns.len());
704-
let mut new_bind_context = BindContext::new();
705-
let mut pairs = Vec::with_capacity(left_bind_context.columns.len());
706-
for (idx, (left_col, right_col)) in left_bind_context
707-
.columns
708-
.iter()
709-
.zip(right_bind_context.columns.iter())
710-
.enumerate()
711-
{
712-
let left_index = if *left_col.data_type != coercion_types[idx] {
713-
let new_column_index = self
714-
.metadata
715-
.write()
716-
.add_derived_column(left_col.column_name.clone(), coercion_types[idx].clone());
717-
let column_binding = ColumnBindingBuilder::new(
718-
left_col.column_name.clone(),
719-
new_column_index,
720-
Box::new(coercion_types[idx].clone()),
721-
Visibility::Visible,
722-
)
723-
.build();
724-
let left_coercion_expr = CastExpr {
725-
span: left_span,
726-
is_try: false,
727-
argument: Box::new(
728-
BoundColumnRef {
729-
span: left_span,
730-
column: left_col.clone(),
731-
}
732-
.into(),
733-
),
734-
target_type: Box::new(coercion_types[idx].clone()),
735-
};
736-
left_scalar_items.push(ScalarItem {
737-
scalar: left_coercion_expr.into(),
738-
index: new_column_index,
739-
});
740-
new_bind_context.add_column_binding(column_binding);
741-
new_column_index
742-
} else {
743-
new_bind_context.add_column_binding(left_col.clone());
744-
left_col.index
745-
};
746-
let right_index = if *right_col.data_type != coercion_types[idx] {
747-
let new_column_index = self
748-
.metadata
749-
.write()
750-
.add_derived_column(right_col.column_name.clone(), coercion_types[idx].clone());
751-
let right_coercion_expr = CastExpr {
752-
span: right_span,
753-
is_try: false,
754-
argument: Box::new(
755-
BoundColumnRef {
756-
span: right_span,
757-
column: right_col.clone(),
758-
}
759-
.into(),
760-
),
761-
target_type: Box::new(coercion_types[idx].clone()),
762-
};
763-
right_scalar_items.push(ScalarItem {
764-
scalar: right_coercion_expr.into(),
765-
index: new_column_index,
766-
});
767-
new_column_index
768-
} else {
769-
right_col.index
770-
};
771-
pairs.push((left_index, right_index));
772-
}
773-
if !left_scalar_items.is_empty() {
774-
left_expr = SExpr::create_unary(
775-
Arc::new(
776-
EvalScalar {
777-
items: left_scalar_items,
778-
}
779-
.into(),
780-
),
781-
Arc::new(left_expr),
782-
);
783-
}
784-
if !right_scalar_items.is_empty() {
785-
right_expr = SExpr::create_unary(
786-
Arc::new(
787-
EvalScalar {
788-
items: right_scalar_items,
789-
}
790-
.into(),
791-
),
792-
Arc::new(right_expr),
793-
);
794-
}
795-
Ok((new_bind_context, pairs, left_expr, right_expr))
796-
}
797-
798658
#[allow(clippy::too_many_arguments)]
799659
fn analyze_lazy_materialization(
800660
&self,

0 commit comments

Comments
 (0)