diff --git a/src/query/sql/src/executor/format.rs b/src/query/sql/src/executor/format.rs index 1e15d2f7e961..c7829cd260fb 100644 --- a/src/query/sql/src/executor/format.rs +++ b/src/query/sql/src/executor/format.rs @@ -840,6 +840,10 @@ fn constant_table_scan_to_format_tree( plan: &ConstantTableScan, metadata: &Metadata, ) -> Result> { + if plan.num_rows == 0 { + return Ok(FormatTreeNode::new(plan.name().to_string())); + } + let mut children = Vec::with_capacity(plan.values.len() + 1); children.push(FormatTreeNode::new(format!( "output columns: [{}]", @@ -850,7 +854,7 @@ fn constant_table_scan_to_format_tree( children.push(FormatTreeNode::new(format!("column {}: [{}]", i, column))); } Ok(FormatTreeNode::with_children( - "ConstantTableScan".to_string(), + plan.name().to_string(), children, )) } diff --git a/src/query/sql/src/executor/physical_plan_display.rs b/src/query/sql/src/executor/physical_plan_display.rs index 68ad579959bd..953f3aa45725 100644 --- a/src/query/sql/src/executor/physical_plan_display.rs +++ b/src/query/sql/src/executor/physical_plan_display.rs @@ -179,7 +179,7 @@ impl Display for ConstantTableScan { }) .collect::>(); - write!(f, "ConstantTableScan: {}", columns.join(", ")) + write!(f, "{}: {}", self.name(), columns.join(", ")) } } diff --git a/src/query/sql/src/executor/physical_plans/physical_constant_table_scan.rs b/src/query/sql/src/executor/physical_plans/physical_constant_table_scan.rs index 00ace9dbd595..a70058fd4ef6 100644 --- a/src/query/sql/src/executor/physical_plans/physical_constant_table_scan.rs +++ b/src/query/sql/src/executor/physical_plans/physical_constant_table_scan.rs @@ -34,6 +34,14 @@ impl ConstantTableScan { pub fn output_schema(&self) -> Result { Ok(self.output_schema.clone()) } + + pub fn name(&self) -> &str { + if self.num_rows == 0 { + "EmptyResultScan" + } else { + "ConstantTableScan" + } + } } impl PhysicalPlanBuilder { diff --git a/src/query/sql/src/planner/expression_parser.rs b/src/query/sql/src/planner/expression_parser.rs index 34db80ad3362..eec13e6968b8 100644 --- a/src/query/sql/src/planner/expression_parser.rs +++ b/src/query/sql/src/planner/expression_parser.rs @@ -60,7 +60,7 @@ use crate::MetadataRef; use crate::ScalarExpr; use crate::Visibility; -pub fn bind_one_table(table_meta: Arc) -> Result<(BindContext, MetadataRef)> { +pub fn bind_table(table_meta: Arc) -> Result<(BindContext, MetadataRef)> { let mut bind_context = BindContext::new(); let metadata = Arc::new(RwLock::new(Metadata::default())); let table_index = metadata.write().add_table( @@ -117,7 +117,7 @@ pub fn parse_exprs( table_meta: Arc, sql: &str, ) -> Result> { - let (mut bind_context, metadata) = bind_one_table(table_meta)?; + let (mut bind_context, metadata) = bind_table(table_meta)?; let settings = Settings::create(Tenant::new_literal("dummy")); let name_resolution_ctx = NameResolutionContext::try_from(settings.as_ref())?; let sql_dialect = ctx.get_settings().get_sql_dialect().unwrap_or_default(); @@ -378,7 +378,7 @@ pub fn parse_cluster_keys( table_meta: Arc, cluster_key_str: &str, ) -> Result> { - let (mut bind_context, metadata) = bind_one_table(table_meta)?; + let (mut bind_context, metadata) = bind_table(table_meta)?; let settings = Settings::create(Tenant::new_literal("dummy")); let name_resolution_ctx = NameResolutionContext::try_from(settings.as_ref())?; let sql_dialect = ctx.get_settings().get_sql_dialect().unwrap_or_default(); @@ -455,7 +455,7 @@ pub fn parse_hilbert_cluster_key( table_meta: Arc, cluster_key_str: &str, ) -> Result> { - let (mut bind_context, metadata) = bind_one_table(table_meta)?; + let (mut bind_context, metadata) = bind_table(table_meta)?; let settings = Settings::create(Tenant::new_literal("dummy")); let name_resolution_ctx = NameResolutionContext::try_from(settings.as_ref())?; let sql_dialect = ctx.get_settings().get_sql_dialect().unwrap_or_default(); @@ -609,7 +609,7 @@ pub fn analyze_cluster_keys( } } - let (mut bind_context, metadata) = bind_one_table(table_meta)?; + let (mut bind_context, metadata) = bind_table(table_meta)?; let settings = Settings::create(Tenant::new_literal("dummy")); let name_resolution_ctx = NameResolutionContext::try_from(settings.as_ref())?; let mut type_checker = TypeChecker::try_create( diff --git a/src/query/sql/src/planner/format/display_rel_operator.rs b/src/query/sql/src/planner/format/display_rel_operator.rs index 024fde141297..f4d236f9c249 100644 --- a/src/query/sql/src/planner/format/display_rel_operator.rs +++ b/src/query/sql/src/planner/format/display_rel_operator.rs @@ -23,6 +23,7 @@ use crate::planner::format::display::TreeHumanizer; use crate::plans::Aggregate; use crate::plans::AggregateMode; use crate::plans::AsyncFunction; +use crate::plans::ConstantTableScan; use crate::plans::EvalScalar; use crate::plans::Exchange; use crate::plans::Filter; @@ -151,6 +152,7 @@ pub(super) fn to_format_tree sort_to_format_tree(id_humanizer, op), RelOperator::Limit(op) => limit_to_format_tree(id_humanizer, op), RelOperator::Exchange(op) => exchange_to_format_tree(id_humanizer, op), + RelOperator::ConstantTableScan(op) => constant_scan_to_format_tree(id_humanizer, op), _ => FormatTreeNode::with_children(format!("{:?}", op), vec![]), } } @@ -389,6 +391,26 @@ fn sort_to_format_tree ]) } +fn constant_scan_to_format_tree>( + id_humanizer: &I, + plan: &ConstantTableScan, +) -> FormatTreeNode { + if plan.num_rows == 0 { + return FormatTreeNode::new(plan.name().to_string()); + } + + FormatTreeNode::with_children(plan.name().to_string(), vec![ + FormatTreeNode::new(format!( + "columns: [{}]", + plan.columns + .iter() + .map(|col| id_humanizer.humanize_column_id(*col)) + .join(", ") + )), + FormatTreeNode::new(format!("num_rows: [{}]", plan.num_rows)), + ]) +} + fn limit_to_format_tree>( _id_humanizer: &I, op: &Limit, diff --git a/src/query/sql/src/planner/optimizer/format.rs b/src/query/sql/src/planner/optimizer/format.rs index 41d3d98550c7..b72f217ae4cb 100644 --- a/src/query/sql/src/planner/optimizer/format.rs +++ b/src/query/sql/src/planner/optimizer/format.rs @@ -67,7 +67,7 @@ pub fn display_rel_op(rel_op: &RelOperator) -> String { RelOperator::Window(_) => "WindowFunc".to_string(), RelOperator::CteScan(_) => "CteScan".to_string(), RelOperator::MaterializedCte(_) => "MaterializedCte".to_string(), - RelOperator::ConstantTableScan(_) => "ConstantTableScan".to_string(), + RelOperator::ConstantTableScan(s) => s.name().to_string(), RelOperator::ExpressionScan(_) => "ExpressionScan".to_string(), RelOperator::CacheScan(_) => "CacheScan".to_string(), RelOperator::Udf(_) => "Udf".to_string(), diff --git a/src/query/sql/src/planner/optimizer/rule/factory.rs b/src/query/sql/src/planner/optimizer/rule/factory.rs index 753cb6a43191..2a51d73c96f3 100644 --- a/src/query/sql/src/planner/optimizer/rule/factory.rs +++ b/src/query/sql/src/planner/optimizer/rule/factory.rs @@ -79,7 +79,7 @@ impl RuleFactory { RuleID::PushDownLimitAggregate => Ok(Box::new(RulePushDownLimitAggregate::new())), RuleID::PushDownFilterAggregate => Ok(Box::new(RulePushDownFilterAggregate::new())), RuleID::PushDownFilterWindow => Ok(Box::new(RulePushDownFilterWindow::new())), - RuleID::EliminateFilter => Ok(Box::new(RuleEliminateFilter::new())), + RuleID::EliminateFilter => Ok(Box::new(RuleEliminateFilter::new(metadata))), RuleID::MergeEvalScalar => Ok(Box::new(RuleMergeEvalScalar::new())), RuleID::MergeFilter => Ok(Box::new(RuleMergeFilter::new())), RuleID::NormalizeScalarFilter => Ok(Box::new(RuleNormalizeScalarFilter::new())), diff --git a/src/query/sql/src/planner/optimizer/rule/rewrite/rule_eliminate_filter.rs b/src/query/sql/src/planner/optimizer/rule/rewrite/rule_eliminate_filter.rs index 560d58203234..47ca97055bfe 100644 --- a/src/query/sql/src/planner/optimizer/rule/rewrite/rule_eliminate_filter.rs +++ b/src/query/sql/src/planner/optimizer/rule/rewrite/rule_eliminate_filter.rs @@ -15,24 +15,34 @@ use std::sync::Arc; use databend_common_exception::Result; +use databend_common_expression::DataField; +use databend_common_expression::DataSchemaRefExt; +use databend_common_expression::Scalar; use itertools::Itertools; use crate::optimizer::extract::Matcher; use crate::optimizer::rule::Rule; use crate::optimizer::rule::RuleID; use crate::optimizer::rule::TransformResult; +use crate::optimizer::RelExpr; use crate::optimizer::SExpr; +use crate::plans::ConstantExpr; +use crate::plans::ConstantTableScan; use crate::plans::Filter; +use crate::plans::Operator; use crate::plans::RelOp; +use crate::plans::RelOperator; use crate::plans::ScalarExpr; +use crate::MetadataRef; pub struct RuleEliminateFilter { id: RuleID, matchers: Vec, + metadata: MetadataRef, } impl RuleEliminateFilter { - pub fn new() -> Self { + pub fn new(metadata: MetadataRef) -> Self { Self { id: RuleID::EliminateFilter, // Filter @@ -42,6 +52,7 @@ impl RuleEliminateFilter { op_type: RelOp::Filter, children: vec![Matcher::Leaf], }], + metadata, } } } @@ -55,11 +66,45 @@ impl Rule for RuleEliminateFilter { let eval_scalar: Filter = s_expr.plan().clone().try_into()?; // First, de-duplication predicates. let origin_predicates = eval_scalar.predicates.clone(); - let predicates = eval_scalar - .predicates + let predicates = origin_predicates + .clone() .into_iter() .unique() .collect::>(); + + // Rewrite false filter to be empty scan + if predicates.iter().any(|predicate| { + matches!( + predicate, + ScalarExpr::ConstantExpr(ConstantExpr { + value: Scalar::Boolean(false), + .. + }) | ScalarExpr::ConstantExpr(ConstantExpr { + value: Scalar::Null, + .. + }) + ) + }) { + let output_columns = eval_scalar + .derive_relational_prop(&RelExpr::with_s_expr(s_expr))? + .output_columns + .clone(); + let metadata = self.metadata.read(); + let mut fields = Vec::with_capacity(output_columns.len()); + + for col in output_columns.iter().sorted() { + fields.push(DataField::new( + &col.to_string(), + metadata.column(*col).data_type(), + )); + } + let empty_scan = + ConstantTableScan::new_empty_scan(DataSchemaRefExt::create(fields), output_columns); + let result = SExpr::create_leaf(Arc::new(RelOperator::ConstantTableScan(empty_scan))); + state.add_result(result); + return Ok(()); + } + // Delete identically equal predicate // After constant fold is ready, we can delete the following code let predicates = predicates diff --git a/src/query/sql/src/planner/optimizer/rule/rewrite/rule_push_down_limit.rs b/src/query/sql/src/planner/optimizer/rule/rewrite/rule_push_down_limit.rs index 7177a9ee7fa0..19ca4f8f5ea3 100644 --- a/src/query/sql/src/planner/optimizer/rule/rewrite/rule_push_down_limit.rs +++ b/src/query/sql/src/planner/optimizer/rule/rewrite/rule_push_down_limit.rs @@ -15,9 +15,9 @@ use std::sync::Arc; use databend_common_exception::Result; -use databend_common_expression::Column; use databend_common_expression::DataField; use databend_common_expression::DataSchemaRefExt; +use itertools::Itertools; use crate::optimizer::extract::Matcher; use crate::optimizer::rule::Rule; @@ -67,18 +67,14 @@ impl Rule for RulePushDownLimit { .clone(); let metadata = self.metadata.read(); let mut fields = Vec::with_capacity(output_columns.len()); - for col in output_columns.iter() { + for col in output_columns.iter().sorted() { fields.push(DataField::new( &col.to_string(), metadata.column(*col).data_type(), )); } - let empty_scan = ConstantTableScan { - values: vec![Column::Null { len: 0 }; output_columns.len()], - num_rows: 0, - schema: DataSchemaRefExt::create(fields), - columns: output_columns, - }; + let empty_scan = + ConstantTableScan::new_empty_scan(DataSchemaRefExt::create(fields), output_columns); let result = SExpr::create_leaf(Arc::new(RelOperator::ConstantTableScan(empty_scan))); state.add_result(result); } diff --git a/src/query/sql/src/planner/optimizer/statistics/collect_statistics.rs b/src/query/sql/src/planner/optimizer/statistics/collect_statistics.rs index f9fe1554bb5b..e3f3e98b6fd1 100644 --- a/src/query/sql/src/planner/optimizer/statistics/collect_statistics.rs +++ b/src/query/sql/src/planner/optimizer/statistics/collect_statistics.rs @@ -22,7 +22,6 @@ use databend_common_expression::types::NumberScalar; use databend_common_expression::types::F64; use databend_common_expression::ColumnId; use databend_common_expression::Scalar; -use log::info; use crate::optimizer::RelExpr; use crate::optimizer::SExpr; @@ -91,9 +90,6 @@ impl CollectStatisticsOptimizer { if let Some(col_id) = *leaf_index { let col_stat = column_statistics_provider .column_statistics(col_id as ColumnId); - if col_stat.is_none() { - info!("column {} doesn't have global statistics", col_id); - } column_stats.insert(*column_index, col_stat.cloned()); let histogram = column_statistics_provider.histogram(col_id as ColumnId); diff --git a/src/query/sql/src/planner/plans/constant_table_scan.rs b/src/query/sql/src/planner/plans/constant_table_scan.rs index 5df78261bbb0..dae453f79e8e 100644 --- a/src/query/sql/src/planner/plans/constant_table_scan.rs +++ b/src/query/sql/src/planner/plans/constant_table_scan.rs @@ -20,6 +20,7 @@ use databend_common_exception::Result; use databend_common_expression::types::NumberType; use databend_common_expression::types::ValueType; use databend_common_expression::Column; +use databend_common_expression::ColumnBuilder; use databend_common_expression::DataSchemaRef; use databend_common_functions::aggregates::eval_aggr; use databend_common_storage::Datum; @@ -50,6 +51,24 @@ pub struct ConstantTableScan { } impl ConstantTableScan { + pub fn new_empty_scan(schema: DataSchemaRef, columns: ColumnSet) -> Self { + let values = schema + .fields + .iter() + .map(|f| { + let builder = ColumnBuilder::with_capacity(f.data_type(), 0); + builder.build() + }) + .collect::>(); + + Self { + values, + num_rows: 0, + schema, + columns, + } + } + pub fn prune_columns(&self, columns: ColumnSet) -> Self { let mut projection = columns .iter() @@ -74,6 +93,14 @@ impl ConstantTableScan { pub fn used_columns(&self) -> Result { Ok(self.columns.clone()) } + + pub fn name(&self) -> &str { + if self.num_rows == 0 { + "EmptyResultScan" + } else { + "ConstantTableScan" + } + } } impl PartialEq for ConstantTableScan { diff --git a/src/query/sql/src/planner/plans/dummy_table_scan.rs b/src/query/sql/src/planner/plans/dummy_table_scan.rs index 4aeb87c7ed70..11cbb433431a 100644 --- a/src/query/sql/src/planner/plans/dummy_table_scan.rs +++ b/src/query/sql/src/planner/plans/dummy_table_scan.rs @@ -28,7 +28,6 @@ use crate::optimizer::StatInfo; use crate::optimizer::Statistics; use crate::plans::Operator; use crate::plans::RelOp; -use crate::DUMMY_COLUMN_INDEX; #[derive(Clone, Debug, PartialEq, Eq, Hash)] pub struct DummyTableScan; @@ -50,7 +49,7 @@ impl Operator for DummyTableScan { fn derive_relational_prop(&self, _rel_expr: &RelExpr) -> Result> { Ok(Arc::new(RelationalProperty { - output_columns: ColumnSet::from([DUMMY_COLUMN_INDEX]), + output_columns: ColumnSet::new(), outer_columns: ColumnSet::new(), used_columns: ColumnSet::new(), orderings: vec![], diff --git a/tests/sqllogictests/suites/mode/standalone/explain/aggregate.test b/tests/sqllogictests/suites/mode/standalone/explain/aggregate.test index c5c80a449fb5..b04b904bbf36 100644 --- a/tests/sqllogictests/suites/mode/standalone/explain/aggregate.test +++ b/tests/sqllogictests/suites/mode/standalone/explain/aggregate.test @@ -118,33 +118,12 @@ EvalScalar statement ok -create table explain_agg_t1(a int not null, b int not null); +create or replace table explain_agg_t1(a int not null, b int not null); query T explain select a from explain_agg_t1 group by a having 1 = 0; ---- -AggregateFinal -├── output columns: [explain_agg_t1.a (#0)] -├── group by: [a] -├── aggregate functions: [] -├── estimated rows: 0.00 -└── AggregatePartial - ├── group by: [a] - ├── aggregate functions: [] - ├── estimated rows: 0.00 - └── Filter - ├── output columns: [explain_agg_t1.a (#0)] - ├── filters: [false] - ├── estimated rows: 0.00 - └── TableScan - ├── table: default.default.explain_agg_t1 - ├── output columns: [a (#0)] - ├── read rows: 0 - ├── read size: 0 - ├── partitions total: 0 - ├── partitions scanned: 0 - ├── push downs: [filters: [false], limit: NONE] - └── estimated rows: 0.00 +EmptyResultScan query T explain select a from explain_agg_t1 group by a having a > 3; @@ -410,13 +389,13 @@ statement ok drop table if exists t1 statement ok -create table t1 as select number as a from numbers(10) +create or replace table t1 as select number as a from numbers(10) statement ok drop table if exists t2 statement ok -create table t2 as select number as a from numbers(100) +create or replace table t2 as select number as a from numbers(100) query T explain select count() from t1, t2 where t1.a > t2.a; @@ -464,10 +443,7 @@ statement ok drop table t2; statement ok -DROP TABLE IF EXISTS t; - -statement ok -CREATE TABLE t (Referer TEXT NOT NULL, IsRefresh SMALLINT NOT NULL); +CREATE or replace TABLE t (Referer TEXT NOT NULL, IsRefresh SMALLINT NOT NULL); query T EXPLAIN SELECT referer, avg(isrefresh), count(distinct referer) FROM t GROUP BY referer; @@ -497,3 +473,6 @@ EvalScalar statement ok DROP TABLE IF EXISTS t; + +statement ok +DROP TABLE IF EXISTS explain_agg_t1; \ No newline at end of file diff --git a/tests/sqllogictests/suites/mode/standalone/explain/explain.test b/tests/sqllogictests/suites/mode/standalone/explain/explain.test index 663f80d37714..72441a3fc468 100644 --- a/tests/sqllogictests/suites/mode/standalone/explain/explain.test +++ b/tests/sqllogictests/suites/mode/standalone/explain/explain.test @@ -1251,19 +1251,7 @@ Sort ├── probe keys: [t1.i (#0)] ├── filters: [] ├── estimated rows: 3.00 - ├── Filter(Build) - │ ├── output columns: [t2.k (#2), t2.l (#3)] - │ ├── filters: [false] - │ ├── estimated rows: 0.00 - │ └── TableScan - │ ├── table: default.default.t2 - │ ├── output columns: [k (#2), l (#3)] - │ ├── read rows: 0 - │ ├── read size: 0 - │ ├── partitions total: 0 - │ ├── partitions scanned: 0 - │ ├── push downs: [filters: [false], limit: NONE] - │ └── estimated rows: 2.00 + ├── EmptyResultScan(Build) └── TableScan(Probe) ├── table: default.default.t1 ├── output columns: [i (#0), j (#1)] @@ -1292,13 +1280,7 @@ EvalScalar │ ├── filters: [] │ ├── order by: [] │ └── limit: NONE - └── Filter - ├── filters: [false] - └── Scan - ├── table: default.t2 - ├── filters: [false] - ├── order by: [] - └── limit: NONE + └── EmptyResultScan statement ok diff --git a/tests/sqllogictests/suites/mode/standalone/explain/filter.test b/tests/sqllogictests/suites/mode/standalone/explain/filter.test index 7ea0fe29ab66..7e3b369c3b71 100644 --- a/tests/sqllogictests/suites/mode/standalone/explain/filter.test +++ b/tests/sqllogictests/suites/mode/standalone/explain/filter.test @@ -10,6 +10,11 @@ create table t1(a int, b int); statement ok create table t2(a int, b int); +query T +explain select * from t1 where a = 1 and a = 2; +---- +EmptyResultScan + query T explain select * from t1 where (a = 1 and b > 2) or (a = 1 and b < 100) or (a = 1 and b > 2) or (a = 1 and b < 100); ---- diff --git a/tests/sqllogictests/suites/mode/standalone/explain/infer_filter.test b/tests/sqllogictests/suites/mode/standalone/explain/infer_filter.test index 16cdfd364980..9b379ba627c2 100644 --- a/tests/sqllogictests/suites/mode/standalone/explain/infer_filter.test +++ b/tests/sqllogictests/suites/mode/standalone/explain/infer_filter.test @@ -38,37 +38,13 @@ Filter query T explain select * from t1 where a = 1 and a = 2; ---- -Filter -├── output columns: [t1.a (#0), t1.b (#1)] -├── filters: [false] -├── estimated rows: 0.00 -└── TableScan - ├── table: default.default.t1 - ├── output columns: [a (#0), b (#1)] - ├── read rows: 0 - ├── read size: 0 - ├── partitions total: 0 - ├── partitions scanned: 0 - ├── push downs: [filters: [false], limit: NONE] - └── estimated rows: 0.00 +EmptyResultScan # false query T explain select * from t1 where a = 1 and a != 1 ---- -Filter -├── output columns: [t1.a (#0), t1.b (#1)] -├── filters: [false] -├── estimated rows: 0.00 -└── TableScan - ├── table: default.default.t1 - ├── output columns: [a (#0), b (#1)] - ├── read rows: 0 - ├── read size: 0 - ├── partitions total: 0 - ├── partitions scanned: 0 - ├── push downs: [filters: [false], limit: NONE] - └── estimated rows: 0.00 +EmptyResultScan # a = 1 query T @@ -110,19 +86,7 @@ Filter query T explain select * from t1 where a = 1 and a < 1; ---- -Filter -├── output columns: [t1.a (#0), t1.b (#1)] -├── filters: [false] -├── estimated rows: 0.00 -└── TableScan - ├── table: default.default.t1 - ├── output columns: [a (#0), b (#1)] - ├── read rows: 0 - ├── read size: 0 - ├── partitions total: 0 - ├── partitions scanned: 0 - ├── push downs: [filters: [false], limit: NONE] - └── estimated rows: 0.00 +EmptyResultScan # a = 1 query T @@ -182,19 +146,7 @@ Filter query T explain select * from t1 where a = 1 and a > 1; ---- -Filter -├── output columns: [t1.a (#0), t1.b (#1)] -├── filters: [false] -├── estimated rows: 0.00 -└── TableScan - ├── table: default.default.t1 - ├── output columns: [a (#0), b (#1)] - ├── read rows: 0 - ├── read size: 0 - ├── partitions total: 0 - ├── partitions scanned: 0 - ├── push downs: [filters: [false], limit: NONE] - └── estimated rows: 0.00 +EmptyResultScan # a = 1; query T @@ -237,19 +189,7 @@ Filter query T explain select * from t1 where a != 1 and a = 1; ---- -Filter -├── output columns: [t1.a (#0), t1.b (#1)] -├── filters: [false] -├── estimated rows: 0.00 -└── TableScan - ├── table: default.default.t1 - ├── output columns: [a (#0), b (#1)] - ├── read rows: 0 - ├── read size: 0 - ├── partitions total: 0 - ├── partitions scanned: 0 - ├── push downs: [filters: [false], limit: NONE] - └── estimated rows: 0.00 +EmptyResultScan # a = 2 query T @@ -453,19 +393,7 @@ Filter query T explain select * from t1 where a < 5 and a = 10; ---- -Filter -├── output columns: [t1.a (#0), t1.b (#1)] -├── filters: [false] -├── estimated rows: 0.00 -└── TableScan - ├── table: default.default.t1 - ├── output columns: [a (#0), b (#1)] - ├── read rows: 0 - ├── read size: 0 - ├── partitions total: 0 - ├── partitions scanned: 0 - ├── push downs: [filters: [false], limit: NONE] - └── estimated rows: 0.00 +EmptyResultScan # a = 2 query T @@ -543,19 +471,7 @@ Filter query T explain select * from t1 where a < 5 and a > 10; ---- -Filter -├── output columns: [t1.a (#0), t1.b (#1)] -├── filters: [false] -├── estimated rows: 0.00 -└── TableScan - ├── table: default.default.t1 - ├── output columns: [a (#0), b (#1)] - ├── read rows: 0 - ├── read size: 0 - ├── partitions total: 0 - ├── partitions scanned: 0 - ├── push downs: [filters: [false], limit: NONE] - └── estimated rows: 0.00 +EmptyResultScan # a < 5 and a > 2 query T @@ -763,97 +679,13 @@ MergeJoin query T explain select * from t1, t2 where t1.a = t2.a and t1.a > 5 and t2.a < 1; ---- -HashJoin -├── output columns: [t1.a (#0), t1.b (#1), t2.a (#2), t2.b (#3)] -├── join type: CROSS -├── build keys: [] -├── probe keys: [] -├── filters: [] -├── estimated rows: 0.00 -├── Filter(Build) -│ ├── output columns: [t2.a (#2), t2.b (#3)] -│ ├── filters: [false] -│ ├── estimated rows: 0.00 -│ └── TableScan -│ ├── table: default.default.t2 -│ ├── output columns: [a (#2), b (#3)] -│ ├── read rows: 0 -│ ├── read size: 0 -│ ├── partitions total: 0 -│ ├── partitions scanned: 0 -│ ├── push downs: [filters: [false], limit: NONE] -│ └── estimated rows: 0.00 -└── Filter(Probe) - ├── output columns: [t1.a (#0), t1.b (#1)] - ├── filters: [false] - ├── estimated rows: 0.00 - └── TableScan - ├── table: default.default.t1 - ├── output columns: [a (#0), b (#1)] - ├── read rows: 0 - ├── read size: 0 - ├── partitions total: 0 - ├── partitions scanned: 0 - ├── push downs: [filters: [false], limit: NONE] - └── estimated rows: 0.00 +EmptyResultScan # false query T explain select * from t1 left join t2 on t1.a = t2.a left join t3 on t2.a = t3.a where t2.b > 0 and t2.b < 0; ---- -HashJoin -├── output columns: [t1.a (#0), t1.b (#1), t2.a (#2), t2.b (#3), t3.a (#4), t3.b (#5)] -├── join type: LEFT OUTER -├── build keys: [t3.a (#4)] -├── probe keys: [t2.a (#2)] -├── filters: [] -├── estimated rows: 0.00 -├── Filter(Build) -│ ├── output columns: [t3.a (#4), t3.b (#5)] -│ ├── filters: [false] -│ ├── estimated rows: 0.00 -│ └── TableScan -│ ├── table: default.default.t3 -│ ├── output columns: [a (#4), b (#5)] -│ ├── read rows: 0 -│ ├── read size: 0 -│ ├── partitions total: 0 -│ ├── partitions scanned: 0 -│ ├── push downs: [filters: [false], limit: NONE] -│ └── estimated rows: 0.00 -└── HashJoin(Probe) - ├── output columns: [t1.a (#0), t1.b (#1), t2.a (#2), t2.b (#3)] - ├── join type: LEFT OUTER - ├── build keys: [t2.a (#2)] - ├── probe keys: [CAST(t1.a (#0) AS Int32 NULL)] - ├── filters: [] - ├── estimated rows: 0.00 - ├── Filter(Build) - │ ├── output columns: [t2.a (#2), t2.b (#3)] - │ ├── filters: [false] - │ ├── estimated rows: 0.00 - │ └── TableScan - │ ├── table: default.default.t2 - │ ├── output columns: [a (#2), b (#3)] - │ ├── read rows: 0 - │ ├── read size: 0 - │ ├── partitions total: 0 - │ ├── partitions scanned: 0 - │ ├── push downs: [filters: [false], limit: NONE] - │ └── estimated rows: 0.00 - └── Filter(Probe) - ├── output columns: [t1.a (#0), t1.b (#1)] - ├── filters: [false] - ├── estimated rows: 0.00 - └── TableScan - ├── table: default.default.t1 - ├── output columns: [a (#0), b (#1)] - ├── read rows: 0 - ├── read size: 0 - ├── partitions total: 0 - ├── partitions scanned: 0 - ├── push downs: [filters: [false], limit: NONE] - └── estimated rows: 0.00 +EmptyResultScan # t1.a = t2.a, t1.a = t3.a => t2.a = t3.a query T diff --git a/tests/sqllogictests/suites/mode/standalone/explain/limit.test b/tests/sqllogictests/suites/mode/standalone/explain/limit.test index 1c1a01eb88f2..0b8bc375d636 100644 --- a/tests/sqllogictests/suites/mode/standalone/explain/limit.test +++ b/tests/sqllogictests/suites/mode/standalone/explain/limit.test @@ -225,6 +225,4 @@ Limit query T explain select c1 from (select count(t1.number) as c1 from numbers(1) as t1 group by number) as t3 left join (select count(t.number) as c from numbers(2) as t group by number) as t4 on t3.c1=t4.c order by t3.c1 limit 0 ---- -ConstantTableScan -├── output columns: [count(t1.number) (#2)] -└── column 0: [] +EmptyResultScan diff --git a/tests/sqllogictests/suites/mode/standalone/explain/range_pruner.test b/tests/sqllogictests/suites/mode/standalone/explain/range_pruner.test index 044e82af9057..3de8d0440698 100644 --- a/tests/sqllogictests/suites/mode/standalone/explain/range_pruner.test +++ b/tests/sqllogictests/suites/mode/standalone/explain/range_pruner.test @@ -1,5 +1,5 @@ statement ok -create table range_t(c varchar, i int) +create or replace table range_t(c varchar, i int) statement ok insert into range_t values ('bcd', 1), ('efg', 10) @@ -52,37 +52,13 @@ EvalScalar query T explain select number from numbers(10) where number > 5 and try_cast(get(try_parse_json(number::String),'xx') as varchar) < '10' and 1 = 0; ---- -Filter -├── output columns: [numbers.number (#0)] -├── filters: [false] -├── estimated rows: 0.00 -└── TableScan - ├── table: default.system.numbers - ├── output columns: [number (#0)] - ├── read rows: 0 - ├── read size: 0 - ├── partitions total: 0 - ├── partitions scanned: 0 - ├── push downs: [filters: [false], limit: NONE] - └── estimated rows: 10.00 +EmptyResultScan query T explain select number from numbers(10) where number > 5 and try_cast(get(try_parse_json(number::String),'xx') as varchar) < '10' and 1 = 0; ---- -Filter -├── output columns: [numbers.number (#0)] -├── filters: [false] -├── estimated rows: 0.00 -└── TableScan - ├── table: default.system.numbers - ├── output columns: [number (#0)] - ├── read rows: 0 - ├── read size: 0 - ├── partitions total: 0 - ├── partitions scanned: 0 - ├── push downs: [filters: [false], limit: NONE] - └── estimated rows: 10.00 +EmptyResultScan statement ok drop table range_t diff --git a/tests/sqllogictests/suites/mode/standalone/explain/select.test b/tests/sqllogictests/suites/mode/standalone/explain/select.test index f1bbd85251fd..5f59d84c5973 100644 --- a/tests/sqllogictests/suites/mode/standalone/explain/select.test +++ b/tests/sqllogictests/suites/mode/standalone/explain/select.test @@ -103,53 +103,17 @@ TableScan query T explain select * from numbers(1) where number = 0 and false ---- -Filter -├── output columns: [numbers.number (#0)] -├── filters: [false] -├── estimated rows: 0.00 -└── TableScan - ├── table: default.system.numbers - ├── output columns: [number (#0)] - ├── read rows: 0 - ├── read size: 0 - ├── partitions total: 0 - ├── partitions scanned: 0 - ├── push downs: [filters: [false], limit: NONE] - └── estimated rows: 1.00 +EmptyResultScan query T explain select * from numbers(1) where number = 0 and null ---- -Filter -├── output columns: [numbers.number (#0)] -├── filters: [false] -├── estimated rows: 0.00 -└── TableScan - ├── table: default.system.numbers - ├── output columns: [number (#0)] - ├── read rows: 0 - ├── read size: 0 - ├── partitions total: 0 - ├── partitions scanned: 0 - ├── push downs: [filters: [false], limit: NONE] - └── estimated rows: 1.00 +EmptyResultScan query T explain select * from numbers(1) where null ---- -Filter -├── output columns: [numbers.number (#0)] -├── filters: [false] -├── estimated rows: 0.00 -└── TableScan - ├── table: default.system.numbers - ├── output columns: [number (#0)] - ├── read rows: 0 - ├── read size: 0 - ├── partitions total: 0 - ├── partitions scanned: 0 - ├── push downs: [filters: [false], limit: NONE] - └── estimated rows: 1.00 +EmptyResultScan query T explain select a from (select number as a, number as b from numbers(1)) @@ -180,16 +144,4 @@ TableScan query T explain select * from (select * from numbers(100) where number> 33 ) where 1=2; ---- -Filter -├── output columns: [numbers.number (#0)] -├── filters: [false] -├── estimated rows: 0.00 -└── TableScan - ├── table: default.system.numbers - ├── output columns: [number (#0)] - ├── read rows: 0 - ├── read size: 0 - ├── partitions total: 0 - ├── partitions scanned: 0 - ├── push downs: [filters: [false], limit: NONE] - └── estimated rows: 100.00 +EmptyResultScan diff --git a/tests/sqllogictests/suites/mode/standalone/explain_native/aggregate.test b/tests/sqllogictests/suites/mode/standalone/explain_native/aggregate.test index ad97d1510e1d..7c2e6d10ce26 100644 --- a/tests/sqllogictests/suites/mode/standalone/explain_native/aggregate.test +++ b/tests/sqllogictests/suites/mode/standalone/explain_native/aggregate.test @@ -118,29 +118,12 @@ EvalScalar statement ok -create table explain_agg_t1(a int not null, b int not null); +create or replace table explain_agg_t1(a int not null, b int not null); query T explain select a from explain_agg_t1 group by a having 1 = 0; ---- -AggregateFinal -├── output columns: [explain_agg_t1.a (#0)] -├── group by: [a] -├── aggregate functions: [] -├── estimated rows: 0.00 -└── AggregatePartial - ├── group by: [a] - ├── aggregate functions: [] - ├── estimated rows: 0.00 - └── TableScan - ├── table: default.default.explain_agg_t1 - ├── output columns: [a (#0)] - ├── read rows: 0 - ├── read size: 0 - ├── partitions total: 0 - ├── partitions scanned: 0 - ├── push downs: [filters: [false], limit: NONE] - └── estimated rows: 0.00 +EmptyResultScan query T explain select a from explain_agg_t1 group by a having a > 3; diff --git a/tests/sqllogictests/suites/mode/standalone/explain_native/explain.test b/tests/sqllogictests/suites/mode/standalone/explain_native/explain.test index 2386e5b31e17..898969bf34f9 100644 --- a/tests/sqllogictests/suites/mode/standalone/explain_native/explain.test +++ b/tests/sqllogictests/suites/mode/standalone/explain_native/explain.test @@ -922,15 +922,7 @@ Sort ├── probe keys: [t1.i (#0)] ├── filters: [] ├── estimated rows: 3.00 - ├── TableScan(Build) - │ ├── table: default.default.t2 - │ ├── output columns: [k (#2), l (#3)] - │ ├── read rows: 0 - │ ├── read size: 0 - │ ├── partitions total: 0 - │ ├── partitions scanned: 0 - │ ├── push downs: [filters: [false], limit: NONE] - │ └── estimated rows: 0.00 + ├── EmptyResultScan(Build) └── TableScan(Probe) ├── table: default.default.t1 ├── output columns: [i (#0), j (#1)] diff --git a/tests/sqllogictests/suites/mode/standalone/explain_native/infer_filter.test b/tests/sqllogictests/suites/mode/standalone/explain_native/infer_filter.test index 3ef10d3bffe6..3c86a2b9fe63 100644 --- a/tests/sqllogictests/suites/mode/standalone/explain_native/infer_filter.test +++ b/tests/sqllogictests/suites/mode/standalone/explain_native/infer_filter.test @@ -34,29 +34,13 @@ TableScan query T explain select * from t1 where a = 1 and a = 2; ---- -TableScan -├── table: default.default.t1 -├── output columns: [a (#0), b (#1)] -├── read rows: 0 -├── read size: 0 -├── partitions total: 0 -├── partitions scanned: 0 -├── push downs: [filters: [false], limit: NONE] -└── estimated rows: 0.00 +EmptyResultScan # false query T explain select * from t1 where a = 1 and a != 1 ---- -TableScan -├── table: default.default.t1 -├── output columns: [a (#0), b (#1)] -├── read rows: 0 -├── read size: 0 -├── partitions total: 0 -├── partitions scanned: 0 -├── push downs: [filters: [false], limit: NONE] -└── estimated rows: 0.00 +EmptyResultScan # a = 1 query T @@ -90,15 +74,7 @@ TableScan query T explain select * from t1 where a = 1 and a < 1; ---- -TableScan -├── table: default.default.t1 -├── output columns: [a (#0), b (#1)] -├── read rows: 0 -├── read size: 0 -├── partitions total: 0 -├── partitions scanned: 0 -├── push downs: [filters: [false], limit: NONE] -└── estimated rows: 0.00 +EmptyResultScan # a = 1 query T @@ -146,15 +122,7 @@ TableScan query T explain select * from t1 where a = 1 and a > 1; ---- -TableScan -├── table: default.default.t1 -├── output columns: [a (#0), b (#1)] -├── read rows: 0 -├── read size: 0 -├── partitions total: 0 -├── partitions scanned: 0 -├── push downs: [filters: [false], limit: NONE] -└── estimated rows: 0.00 +EmptyResultScan # a = 1; query T @@ -189,15 +157,7 @@ TableScan query T explain select * from t1 where a != 1 and a = 1; ---- -TableScan -├── table: default.default.t1 -├── output columns: [a (#0), b (#1)] -├── read rows: 0 -├── read size: 0 -├── partitions total: 0 -├── partitions scanned: 0 -├── push downs: [filters: [false], limit: NONE] -└── estimated rows: 0.00 +EmptyResultScan # a = 2 query T @@ -357,15 +317,7 @@ TableScan query T explain select * from t1 where a < 5 and a = 10; ---- -TableScan -├── table: default.default.t1 -├── output columns: [a (#0), b (#1)] -├── read rows: 0 -├── read size: 0 -├── partitions total: 0 -├── partitions scanned: 0 -├── push downs: [filters: [false], limit: NONE] -└── estimated rows: 0.00 +EmptyResultScan # a = 2 query T @@ -427,15 +379,7 @@ TableScan query T explain select * from t1 where a < 5 and a > 10; ---- -TableScan -├── table: default.default.t1 -├── output columns: [a (#0), b (#1)] -├── read rows: 0 -├── read size: 0 -├── partitions total: 0 -├── partitions scanned: 0 -├── push downs: [filters: [false], limit: NONE] -└── estimated rows: 0.00 +EmptyResultScan # a < 5 and a > 2 query T @@ -603,77 +547,13 @@ MergeJoin query T explain select * from t1, t2 where t1.a = t2.a and t1.a > 5 and t2.a < 1; ---- -HashJoin -├── output columns: [t1.a (#0), t1.b (#1), t2.a (#2), t2.b (#3)] -├── join type: CROSS -├── build keys: [] -├── probe keys: [] -├── filters: [] -├── estimated rows: 0.00 -├── TableScan(Build) -│ ├── table: default.default.t2 -│ ├── output columns: [a (#2), b (#3)] -│ ├── read rows: 0 -│ ├── read size: 0 -│ ├── partitions total: 0 -│ ├── partitions scanned: 0 -│ ├── push downs: [filters: [false], limit: NONE] -│ └── estimated rows: 0.00 -└── TableScan(Probe) - ├── table: default.default.t1 - ├── output columns: [a (#0), b (#1)] - ├── read rows: 0 - ├── read size: 0 - ├── partitions total: 0 - ├── partitions scanned: 0 - ├── push downs: [filters: [false], limit: NONE] - └── estimated rows: 0.00 +EmptyResultScan # false query T explain select * from t1 left join t2 on t1.a = t2.a left join t3 on t2.a = t3.a where t2.b > 0 and t2.b < 0; ---- -HashJoin -├── output columns: [t1.a (#0), t1.b (#1), t2.a (#2), t2.b (#3), t3.a (#4), t3.b (#5)] -├── join type: LEFT OUTER -├── build keys: [t3.a (#4)] -├── probe keys: [t2.a (#2)] -├── filters: [] -├── estimated rows: 0.00 -├── TableScan(Build) -│ ├── table: default.default.t3 -│ ├── output columns: [a (#4), b (#5)] -│ ├── read rows: 0 -│ ├── read size: 0 -│ ├── partitions total: 0 -│ ├── partitions scanned: 0 -│ ├── push downs: [filters: [false], limit: NONE] -│ └── estimated rows: 0.00 -└── HashJoin(Probe) - ├── output columns: [t1.a (#0), t1.b (#1), t2.a (#2), t2.b (#3)] - ├── join type: LEFT OUTER - ├── build keys: [t2.a (#2)] - ├── probe keys: [CAST(t1.a (#0) AS Int32 NULL)] - ├── filters: [] - ├── estimated rows: 0.00 - ├── TableScan(Build) - │ ├── table: default.default.t2 - │ ├── output columns: [a (#2), b (#3)] - │ ├── read rows: 0 - │ ├── read size: 0 - │ ├── partitions total: 0 - │ ├── partitions scanned: 0 - │ ├── push downs: [filters: [false], limit: NONE] - │ └── estimated rows: 0.00 - └── TableScan(Probe) - ├── table: default.default.t1 - ├── output columns: [a (#0), b (#1)] - ├── read rows: 0 - ├── read size: 0 - ├── partitions total: 0 - ├── partitions scanned: 0 - ├── push downs: [filters: [false], limit: NONE] - └── estimated rows: 0.00 +EmptyResultScan # t1.a = t2.a, t1.a = t3.a => t2.a = t3.a query T diff --git a/tests/sqllogictests/suites/mode/standalone/explain_native/range_pruner.test b/tests/sqllogictests/suites/mode/standalone/explain_native/range_pruner.test index 86ffd87dacf9..65ead88dd450 100644 --- a/tests/sqllogictests/suites/mode/standalone/explain_native/range_pruner.test +++ b/tests/sqllogictests/suites/mode/standalone/explain_native/range_pruner.test @@ -1,5 +1,5 @@ statement ok -create table range_t(c varchar, i int) +create or replace table range_t(c varchar, i int) statement ok insert into range_t values ('bcd', 1), ('efg', 10) @@ -43,37 +43,13 @@ EvalScalar query T explain select number from numbers(10) where number > 5 and try_cast(get(try_parse_json(number::String),'xx') as varchar) < '10' and 1 = 0; ---- -Filter -├── output columns: [numbers.number (#0)] -├── filters: [false] -├── estimated rows: 0.00 -└── TableScan - ├── table: default.system.numbers - ├── output columns: [number (#0)] - ├── read rows: 0 - ├── read size: 0 - ├── partitions total: 0 - ├── partitions scanned: 0 - ├── push downs: [filters: [false], limit: NONE] - └── estimated rows: 10.00 +EmptyResultScan query T explain select number from numbers(10) where number > 5 and try_cast(get(try_parse_json(number::String),'xx') as varchar) < '10' and 1 = 0; ---- -Filter -├── output columns: [numbers.number (#0)] -├── filters: [false] -├── estimated rows: 0.00 -└── TableScan - ├── table: default.system.numbers - ├── output columns: [number (#0)] - ├── read rows: 0 - ├── read size: 0 - ├── partitions total: 0 - ├── partitions scanned: 0 - ├── push downs: [filters: [false], limit: NONE] - └── estimated rows: 10.00 +EmptyResultScan statement ok drop table range_t diff --git a/tests/sqllogictests/suites/mode/standalone/explain_native/select.test b/tests/sqllogictests/suites/mode/standalone/explain_native/select.test index 623590188f4c..dc7f6179c585 100644 --- a/tests/sqllogictests/suites/mode/standalone/explain_native/select.test +++ b/tests/sqllogictests/suites/mode/standalone/explain_native/select.test @@ -103,53 +103,17 @@ TableScan query T explain select * from numbers(1) where number = 0 and false ---- -Filter -├── output columns: [numbers.number (#0)] -├── filters: [false] -├── estimated rows: 0.00 -└── TableScan - ├── table: default.system.numbers - ├── output columns: [number (#0)] - ├── read rows: 0 - ├── read size: 0 - ├── partitions total: 0 - ├── partitions scanned: 0 - ├── push downs: [filters: [false], limit: NONE] - └── estimated rows: 1.00 +EmptyResultScan query T explain select * from numbers(1) where number = 0 and null ---- -Filter -├── output columns: [numbers.number (#0)] -├── filters: [false] -├── estimated rows: 0.00 -└── TableScan - ├── table: default.system.numbers - ├── output columns: [number (#0)] - ├── read rows: 0 - ├── read size: 0 - ├── partitions total: 0 - ├── partitions scanned: 0 - ├── push downs: [filters: [false], limit: NONE] - └── estimated rows: 1.00 +EmptyResultScan query T explain select * from numbers(1) where null ---- -Filter -├── output columns: [numbers.number (#0)] -├── filters: [false] -├── estimated rows: 0.00 -└── TableScan - ├── table: default.system.numbers - ├── output columns: [number (#0)] - ├── read rows: 0 - ├── read size: 0 - ├── partitions total: 0 - ├── partitions scanned: 0 - ├── push downs: [filters: [false], limit: NONE] - └── estimated rows: 1.00 +EmptyResultScan query T explain select a from (select number as a, number as b from numbers(1)) @@ -180,19 +144,7 @@ TableScan query T explain select * from (select * from numbers(100) where number> 33 ) where 1=2; ---- -Filter -├── output columns: [numbers.number (#0)] -├── filters: [false] -├── estimated rows: 0.00 -└── TableScan - ├── table: default.system.numbers - ├── output columns: [number (#0)] - ├── read rows: 0 - ├── read size: 0 - ├── partitions total: 0 - ├── partitions scanned: 0 - ├── push downs: [filters: [false], limit: NONE] - └── estimated rows: 100.00 +EmptyResultScan statement ok drop table if exists t_json diff --git a/tests/suites/0_stateless/18_rbac/18_0001_udf_priv.sh b/tests/suites/0_stateless/18_rbac/18_0001_udf_priv.sh index f20897d31969..0722bfcbfcd3 100755 --- a/tests/suites/0_stateless/18_rbac/18_0001_udf_priv.sh +++ b/tests/suites/0_stateless/18_rbac/18_0001_udf_priv.sh @@ -44,8 +44,8 @@ echo "update t set i=f2(f1(2)) where i=f2(f1(1));" | $TEST_USER_CONNECT echo "SELECT i, nth_value(i, f2(f1(2))) OVER (PARTITION BY i) fv FROM t" | $TEST_USER_CONNECT echo "delete from t where f2(f1(1));" | $TEST_USER_CONNECT echo "select f2(f1(1)) union all select 2 order by \`f2(f1(1))\`" | $TEST_USER_CONNECT -echo "select 22, t.i as ti from t join (select f2(f1(1)), i from t) as t1 on false;" | $TEST_USER_CONNECT -echo "select f2(f1(1)), t.i as ti from t join (select 22, i from t) as t1 on false;" | $TEST_USER_CONNECT +echo "select 22, t.i as ti from t join (select f2(f1(1)), i from t) as t1 on 1 = 1 ignore_result;" | $TEST_USER_CONNECT +echo "select f2(f1(1)), t.i as ti from t join (select 22, i from t) as t1 on 1 = 1 ignore_result;" | $TEST_USER_CONNECT echo "select 22, t.i as ti from t join (select 22, i from t) as t1 on f2(f1(false));" | $TEST_USER_CONNECT echo "set enable_experimental_merge_into = 1; merge into t as t3 using (select * from t2) as t2 on t3.i = t2.i when matched then update set t3.i=f2(f1(13));" | $TEST_USER_CONNECT echo "set enable_experimental_merge_into = 1; merge into t as t3 using (select * from t2) as t2 on t3.i = t2.i when not matched then insert (i) values(f2(f1(100)));" | $TEST_USER_CONNECT @@ -76,8 +76,8 @@ echo "update t set i=f2(f1(2)) where i=f2(f1(1));" | $TEST_USER_CONNECT echo "SELECT i, nth_value(i, f2(f1(2))) OVER (PARTITION BY i) fv FROM t" | $TEST_USER_CONNECT echo "delete from t where f2(f1(1));" | $TEST_USER_CONNECT echo "select f2(f1(1)) union all select 2 order by \`f2(f1(1))\`" | $TEST_USER_CONNECT -echo "select 22, t.i as ti from t join (select f2(f1(1)), i from t) as t1 on false;" | $TEST_USER_CONNECT -echo "select f2(f1(1)), t.i as ti from t join (select 22, i from t) as t1 on false;" | $TEST_USER_CONNECT +echo "select 22, t.i as ti from t join (select f2(f1(1)), i from t) as t1 on 1 = 1 ignore_result;" | $TEST_USER_CONNECT +echo "select f2(f1(1)), t.i as ti from t join (select 22, i from t) as t1 on 1 = 1 ignore_result;" | $TEST_USER_CONNECT echo "select 22, t.i as ti from t join (select 22, i from t) as t1 on f2(f1(false));" | $TEST_USER_CONNECT echo "set enable_experimental_merge_into = 1; merge into t as t3 using (select * from t2) as t2 on t3.i = t2.i when matched then update set t3.i=f2(f1(13));" | $TEST_USER_CONNECT echo "set enable_experimental_merge_into = 1; merge into t as t3 using (select * from t2) as t2 on t3.i = t2.i when not matched then insert (i) values(f2(f1(100)));" | $TEST_USER_CONNECT @@ -106,8 +106,8 @@ echo "update t set i=f2(f1(2)) where i=f2(f1(1));" | $TEST_USER_CONNECT echo "SELECT i, nth_value(i, f2(f1(2))) OVER (PARTITION BY i) fv FROM t" | $TEST_USER_CONNECT echo "delete from t where f2(f1(1));" | $TEST_USER_CONNECT echo "select f2(f1(1)) union all select 2 order by \`f2(f1(1))\`" | $TEST_USER_CONNECT -echo "select 22, t.i as ti from t join (select f2(f1(1)), i from t) as t1 on false;" | $TEST_USER_CONNECT -echo "select f2(f1(1)), t.i as ti from t join (select 22, i from t) as t1 on false;" | $TEST_USER_CONNECT +echo "select 22, t.i as ti from t join (select f2(f1(1)), i from t) as t1 on 1 = 1 ignore_result;" | $TEST_USER_CONNECT +echo "select f2(f1(1)), t.i as ti from t join (select 22, i from t) as t1 on 1 = 1 ignore_result;" | $TEST_USER_CONNECT echo "select 22, t.i as ti from t join (select 22, i from t) as t1 on f2(f1(false));" | $TEST_USER_CONNECT echo "set enable_experimental_merge_into = 1; merge into t as t3 using (select * from t2) as t2 on t3.i = t2.i when matched then update set t3.i=f2(f1(13));" | $TEST_USER_CONNECT echo "set enable_experimental_merge_into = 1; merge into t as t3 using (select * from t2) as t2 on t3.i = t2.i when not matched then insert (i) values(f2(f1(100)));" | $TEST_USER_CONNECT diff --git a/tests/udf/udf_server.py b/tests/udf/udf_server.py index 249862bd0cec..46066c07a1d8 100644 --- a/tests/udf/udf_server.py +++ b/tests/udf/udf_server.py @@ -308,12 +308,50 @@ def return_all_non_nullable( ) +from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor +import time +executor = ThreadPoolExecutor() +executor2 = ProcessPoolExecutor() + +def cal_multi_thread(row): + r = sum(range(3500000 + row)) + return r + +def cal_sleep(row): + time.sleep(0.2) + return row + +@udf(input_types=["INT"], result_type="BIGINT", batch_mode = True) +def fib_async(x: List[int]) -> List[int]: + current_thread = threading.current_thread() + print("batchs {} {}".format(len(x), current_thread.name)) + + tasks = [executor2.submit(cal_multi_thread, row) for row in x] + result = [future.result() for future in tasks] + + tasks2 = [executor.submit(lambda row: cal_sleep(row), row) for row in x] + result2 = [future.result() for future in tasks] + + print("batchs done {}".format(len(x))) + return result + +import threading + +@udf(input_types=["INT"], result_type="BIGINT", batch_mode = True) +def fib(x: List[int]) -> List[int]: + current_thread = threading.current_thread() + print("batchs {} {}".format(len(x), current_thread.name)) + result = [sum(range(3500000 + row)) for row in x] + print("batchs done {}".format(len(x))) + # tasks = [executor.submit(lambda row: cal_sleep(row), row) for row in x] + # _column = [future.result() for future in tasks] + return result + @udf(input_types=["INT"], result_type="INT") def wait(x): time.sleep(0.1) return x - @udf(input_types=["INT"], result_type="INT", io_threads=32) def wait_concurrent(x): time.sleep(0.1)