1use std::collections::HashMap;
20use std::str::FromStr;
21use std::sync::{Arc, Mutex};
22use std::vec;
23
24use crate::utils::make_decimal_type;
25use arrow::datatypes::*;
26use datafusion_common::TableReference;
27use datafusion_common::config::SqlParserOptions;
28use datafusion_common::datatype::{DataTypeExt, FieldExt};
29use datafusion_common::error::add_possible_columns_to_diag;
30use datafusion_common::{DFSchema, DataFusionError, Result, not_impl_err, plan_err};
31use datafusion_common::{
32 DFSchemaRef, Diagnostic, SchemaError, field_not_found, internal_err,
33 plan_datafusion_err,
34};
35use datafusion_expr::Expr;
36use datafusion_expr::logical_plan::{LogicalPlan, LogicalPlanBuilder};
37pub use datafusion_expr::planner::ContextProvider;
38use datafusion_expr::utils::find_column_exprs;
39use sqlparser::ast::{ArrayElemTypeDef, ExactNumberInfo, TimezoneInfo};
40use sqlparser::ast::{ColumnDef as SQLColumnDef, ColumnOption};
41use sqlparser::ast::{DataType as SQLDataType, Ident, ObjectName, TableAlias};
42
43#[derive(Debug, Clone, Copy)]
45pub struct ParserOptions {
46 pub parse_float_as_decimal: bool,
48 pub enable_ident_normalization: bool,
50 pub support_varchar_with_length: bool,
52 pub enable_options_value_normalization: bool,
54 pub collect_spans: bool,
56 pub map_string_types_to_utf8view: bool,
58 pub default_null_ordering: NullOrdering,
60}
61
62impl ParserOptions {
63 pub fn new() -> Self {
74 Self {
75 parse_float_as_decimal: false,
76 enable_ident_normalization: true,
77 support_varchar_with_length: true,
78 map_string_types_to_utf8view: true,
79 enable_options_value_normalization: false,
80 collect_spans: false,
81 default_null_ordering: NullOrdering::NullsMax,
84 }
85 }
86
87 pub fn with_parse_float_as_decimal(mut self, value: bool) -> Self {
97 self.parse_float_as_decimal = value;
98 self
99 }
100
101 pub fn with_enable_ident_normalization(mut self, value: bool) -> Self {
111 self.enable_ident_normalization = value;
112 self
113 }
114
115 pub fn with_support_varchar_with_length(mut self, value: bool) -> Self {
117 self.support_varchar_with_length = value;
118 self
119 }
120
121 pub fn with_map_string_types_to_utf8view(mut self, value: bool) -> Self {
123 self.map_string_types_to_utf8view = value;
124 self
125 }
126
127 pub fn with_enable_options_value_normalization(mut self, value: bool) -> Self {
129 self.enable_options_value_normalization = value;
130 self
131 }
132
133 pub fn with_collect_spans(mut self, value: bool) -> Self {
135 self.collect_spans = value;
136 self
137 }
138
139 pub fn with_default_null_ordering(mut self, value: NullOrdering) -> Self {
141 self.default_null_ordering = value;
142 self
143 }
144}
145
146impl Default for ParserOptions {
147 fn default() -> Self {
148 Self::new()
149 }
150}
151
152impl From<&SqlParserOptions> for ParserOptions {
153 fn from(options: &SqlParserOptions) -> Self {
154 Self {
155 parse_float_as_decimal: options.parse_float_as_decimal,
156 enable_ident_normalization: options.enable_ident_normalization,
157 support_varchar_with_length: options.support_varchar_with_length,
158 map_string_types_to_utf8view: options.map_string_types_to_utf8view,
159 enable_options_value_normalization: options
160 .enable_options_value_normalization,
161 collect_spans: options.collect_spans,
162 default_null_ordering: options.default_null_ordering.as_str().into(),
163 }
164 }
165}
166
167#[derive(Debug, Clone, Copy)]
169pub enum NullOrdering {
170 NullsMax,
172 NullsMin,
174 NullsFirst,
176 NullsLast,
178}
179
180impl NullOrdering {
181 pub fn nulls_first(&self, asc: bool) -> bool {
187 match self {
188 Self::NullsMax => !asc,
189 Self::NullsMin => asc,
190 Self::NullsFirst => true,
191 Self::NullsLast => false,
192 }
193 }
194}
195
196impl FromStr for NullOrdering {
197 type Err = DataFusionError;
198
199 fn from_str(s: &str) -> Result<Self> {
200 match s {
201 "nulls_max" => Ok(Self::NullsMax),
202 "nulls_min" => Ok(Self::NullsMin),
203 "nulls_first" => Ok(Self::NullsFirst),
204 "nulls_last" => Ok(Self::NullsLast),
205 _ => plan_err!(
206 "Unknown null ordering: Expected one of 'nulls_first', 'nulls_last', 'nulls_min' or 'nulls_max'. Got {s}"
207 ),
208 }
209 }
210}
211
212impl From<&str> for NullOrdering {
213 fn from(s: &str) -> Self {
214 Self::from_str(s).unwrap_or(Self::NullsMax)
215 }
216}
217
218#[derive(Debug)]
220pub struct IdentNormalizer {
221 normalize: bool,
222}
223
224impl Default for IdentNormalizer {
225 fn default() -> Self {
226 Self { normalize: true }
227 }
228}
229
230impl IdentNormalizer {
231 pub fn new(normalize: bool) -> Self {
232 Self { normalize }
233 }
234
235 pub fn normalize(&self, ident: Ident) -> String {
236 if self.normalize {
237 crate::utils::normalize_ident(ident)
238 } else {
239 ident.value
240 }
241 }
242}
243
244#[derive(Debug, Clone)]
257pub struct PlannerContext {
258 prepare_param_data_types: Arc<Vec<Option<FieldRef>>>,
261 ctes: HashMap<String, Arc<LogicalPlan>>,
264
265 outer_queries_schemas_stack: Vec<DFSchemaRef>,
268 outer_from_schema: Option<DFSchemaRef>,
271 create_table_schema: Option<DFSchemaRef>,
273 set_expr_left_schema: Option<DFSchemaRef>,
277 lambda_parameters: HashMap<String, FieldRef>,
279}
280
281impl Default for PlannerContext {
282 fn default() -> Self {
283 Self::new()
284 }
285}
286
287impl PlannerContext {
288 pub fn new() -> Self {
290 Self {
291 prepare_param_data_types: Arc::new(vec![]),
292 ctes: HashMap::new(),
293 outer_queries_schemas_stack: vec![],
294 outer_from_schema: None,
295 create_table_schema: None,
296 set_expr_left_schema: None,
297 lambda_parameters: HashMap::new(),
298 }
299 }
300
301 pub fn with_prepare_param_data_types(
303 mut self,
304 prepare_param_data_types: Vec<Option<FieldRef>>,
305 ) -> Self {
306 self.prepare_param_data_types = prepare_param_data_types.into();
307 self
308 }
309
310 pub fn outer_queries_schemas(&self) -> &[DFSchemaRef] {
313 &self.outer_queries_schemas_stack
314 }
315
316 pub fn outer_schemas_iter(&self) -> impl Iterator<Item = &DFSchemaRef> {
329 self.outer_queries_schemas_stack.iter().rev()
330 }
331
332 pub fn append_outer_query_schema(&mut self, schema: DFSchemaRef) {
335 self.outer_queries_schemas_stack.push(schema);
336 }
337
338 pub fn latest_outer_query_schema(&self) -> Option<&DFSchemaRef> {
340 self.outer_queries_schemas_stack.last()
341 }
342
343 pub fn pop_outer_query_schema(&mut self) -> Option<DFSchemaRef> {
345 self.outer_queries_schemas_stack.pop()
346 }
347
348 pub fn set_table_schema(
349 &mut self,
350 mut schema: Option<DFSchemaRef>,
351 ) -> Option<DFSchemaRef> {
352 std::mem::swap(&mut self.create_table_schema, &mut schema);
353 schema
354 }
355
356 pub fn table_schema(&self) -> Option<DFSchemaRef> {
357 self.create_table_schema.clone()
358 }
359
360 pub fn outer_from_schema(&self) -> Option<Arc<DFSchema>> {
362 self.outer_from_schema.clone()
363 }
364
365 pub fn set_outer_from_schema(
367 &mut self,
368 mut schema: Option<DFSchemaRef>,
369 ) -> Option<DFSchemaRef> {
370 std::mem::swap(&mut self.outer_from_schema, &mut schema);
371 schema
372 }
373
374 pub fn extend_outer_from_schema(&mut self, schema: &DFSchemaRef) -> Result<()> {
376 match self.outer_from_schema.as_mut() {
377 Some(from_schema) => Arc::make_mut(from_schema).merge(schema),
378 None => self.outer_from_schema = Some(Arc::clone(schema)),
379 };
380 Ok(())
381 }
382
383 pub fn prepare_param_data_types(&self) -> &[Option<FieldRef>] {
385 &self.prepare_param_data_types
386 }
387
388 pub fn contains_cte(&self, cte_name: &str) -> bool {
391 self.ctes.contains_key(cte_name)
392 }
393
394 pub fn insert_cte(&mut self, cte_name: impl Into<String>, plan: LogicalPlan) {
397 let cte_name = cte_name.into();
398 self.ctes.insert(cte_name, Arc::new(plan));
399 }
400
401 pub fn get_cte(&self, cte_name: &str) -> Option<&LogicalPlan> {
404 self.ctes.get(cte_name).map(|cte| cte.as_ref())
405 }
406
407 pub fn lambda_parameters(&self) -> &HashMap<String, FieldRef> {
408 &self.lambda_parameters
409 }
410
411 pub fn with_lambda_parameters(
412 mut self,
413 parameters: impl IntoIterator<Item = FieldRef>,
414 ) -> Self {
415 self.lambda_parameters
416 .extend(parameters.into_iter().map(|f| (f.name().clone(), f)));
417
418 self
419 }
420
421 pub(super) fn remove_cte(&mut self, cte_name: &str) {
423 self.ctes.remove(cte_name);
424 }
425
426 pub(super) fn set_set_expr_left_schema(
428 &mut self,
429 schema: Option<DFSchemaRef>,
430 ) -> Option<DFSchemaRef> {
431 std::mem::replace(&mut self.set_expr_left_schema, schema)
432 }
433}
434
435pub struct SqlToRel<'a, S: ContextProvider> {
455 pub(crate) context_provider: &'a S,
456 pub(crate) options: ParserOptions,
457 pub(crate) ident_normalizer: IdentNormalizer,
458 warnings: Mutex<Vec<Diagnostic>>,
459}
460
461impl<'a, S: ContextProvider> SqlToRel<'a, S> {
462 pub fn new(context_provider: &'a S) -> Self {
466 let parser_options = ParserOptions::from(&context_provider.options().sql_parser);
467 Self::new_with_options(context_provider, parser_options)
468 }
469
470 pub fn new_with_options(context_provider: &'a S, options: ParserOptions) -> Self {
475 let ident_normalize = options.enable_ident_normalization;
476
477 SqlToRel {
478 context_provider,
479 options,
480 ident_normalizer: IdentNormalizer::new(ident_normalize),
481 warnings: Mutex::new(vec![]),
482 }
483 }
484
485 pub(crate) fn add_warning(&self, warning: Diagnostic) {
486 self.warnings
487 .lock()
488 .expect("warning diagnostic lock poisoned")
489 .push(warning);
490 }
491
492 pub fn take_warnings(&self) -> Vec<Diagnostic> {
494 std::mem::take(
495 &mut self
496 .warnings
497 .lock()
498 .expect("warning diagnostic lock poisoned"),
499 )
500 }
501
502 pub fn build_schema(&self, columns: Vec<SQLColumnDef>) -> Result<Schema> {
503 let mut fields = Vec::with_capacity(columns.len());
504
505 for column in columns {
506 let data_type = self.convert_data_type_to_field(&column.data_type)?;
507 let not_nullable = column
508 .options
509 .iter()
510 .any(|x| x.option == ColumnOption::NotNull);
511 fields.push(
512 data_type
513 .as_ref()
514 .clone()
515 .with_name(self.ident_normalizer.normalize(column.name))
516 .with_nullable(!not_nullable),
517 );
518 }
519
520 Ok(Schema::new(fields))
521 }
522
523 pub(super) fn build_column_defaults(
525 &self,
526 columns: &Vec<SQLColumnDef>,
527 planner_context: &mut PlannerContext,
528 ) -> Result<Vec<(String, Expr)>> {
529 let mut column_defaults = vec![];
530 let empty_schema = DFSchema::empty();
532 let error_desc = |e: DataFusionError| match e {
533 DataFusionError::SchemaError(ref err, _)
534 if matches!(**err, SchemaError::FieldNotFound { .. }) =>
535 {
536 plan_datafusion_err!(
537 "Column reference is not allowed in the DEFAULT expression : {}",
538 e
539 )
540 }
541 _ => e,
542 };
543
544 for column in columns {
545 if let Some(default_sql_expr) =
546 column.options.iter().find_map(|o| match &o.option {
547 ColumnOption::Default(expr) => Some(expr),
548 _ => None,
549 })
550 {
551 let default_expr = self
552 .sql_to_expr(default_sql_expr.clone(), &empty_schema, planner_context)
553 .map_err(error_desc)?;
554 column_defaults.push((
555 self.ident_normalizer.normalize(column.name.clone()),
556 default_expr,
557 ));
558 }
559 }
560 Ok(column_defaults)
561 }
562
563 pub(crate) fn apply_table_alias(
565 &self,
566 plan: LogicalPlan,
567 alias: TableAlias,
568 ) -> Result<LogicalPlan> {
569 let idents = alias.columns.into_iter().map(|c| c.name).collect();
570 let plan = self.apply_expr_alias(plan, idents)?;
571
572 LogicalPlanBuilder::from(plan)
573 .alias(TableReference::bare(
574 self.ident_normalizer.normalize(alias.name),
575 ))?
576 .build()
577 }
578
579 pub(crate) fn apply_expr_alias(
580 &self,
581 plan: LogicalPlan,
582 idents: Vec<Ident>,
583 ) -> Result<LogicalPlan> {
584 if idents.is_empty() {
585 Ok(plan)
586 } else if idents.len() != plan.schema().fields().len() {
587 plan_err!(
588 "Source table contains {} columns but only {} \
589 names given as column alias",
590 plan.schema().fields().len(),
591 idents.len()
592 )
593 } else {
594 let columns = plan.schema().columns();
595 LogicalPlanBuilder::from(plan)
596 .project(columns.into_iter().zip(idents).map(|(col, ident)| {
597 Expr::Column(col).alias(self.ident_normalizer.normalize(ident))
598 }))?
599 .build()
600 }
601 }
602
603 pub(crate) fn validate_schema_satisfies_exprs(
605 &self,
606 schema: &DFSchema,
607 exprs: &[Expr],
608 ) -> Result<()> {
609 find_column_exprs(exprs)
610 .iter()
611 .try_for_each(|col| match col {
612 Expr::Column(col) => match &col.relation {
613 Some(r) => schema.field_with_qualified_name(r, &col.name).map(|_| ()),
614 None => {
615 if !schema.fields_with_unqualified_name(&col.name).is_empty() {
616 Ok(())
617 } else {
618 Err(field_not_found(
619 col.relation.clone(),
620 col.name.as_str(),
621 schema,
622 ))
623 }
624 }
625 }
626 .map_err(|err: DataFusionError| match &err {
627 DataFusionError::SchemaError(inner, _)
628 if matches!(
629 inner.as_ref(),
630 SchemaError::FieldNotFound { .. }
631 ) =>
632 {
633 let SchemaError::FieldNotFound {
634 field,
635 valid_fields,
636 } = inner.as_ref()
637 else {
638 unreachable!()
639 };
640 let mut diagnostic = if let Some(relation) = &col.relation {
641 Diagnostic::new_error(
642 format!(
643 "column '{}' not found in '{}'",
644 col.name, relation
645 ),
646 col.spans().first(),
647 )
648 } else {
649 Diagnostic::new_error(
650 format!("column '{}' not found", col.name),
651 col.spans().first(),
652 )
653 };
654 add_possible_columns_to_diag(
655 &mut diagnostic,
656 field,
657 valid_fields,
658 );
659 err.with_diagnostic(diagnostic)
660 }
661 _ => err,
662 }),
663 _ => internal_err!("Not a column"),
664 })
665 }
666
667 pub(crate) fn convert_data_type_to_field(
668 &self,
669 sql_type: &SQLDataType,
670 ) -> Result<FieldRef> {
671 if let Some(type_planner) = self.context_provider.get_type_planner()
673 && let Some(data_type) = type_planner.plan_type_field(sql_type)?
674 {
675 return Ok(data_type);
676 }
677
678 match sql_type {
680 SQLDataType::Array(ArrayElemTypeDef::AngleBracket(inner_sql_type)) => {
681 Ok(self.convert_data_type_to_field(inner_sql_type)?.into_list())
683 }
684 SQLDataType::Array(ArrayElemTypeDef::SquareBracket(
685 inner_sql_type,
686 maybe_array_size,
687 )) => {
688 let inner_field = self.convert_data_type_to_field(inner_sql_type)?;
689 if let Some(array_size) = maybe_array_size {
690 let array_size: i32 = (*array_size).try_into().map_err(|_| {
691 plan_datafusion_err!(
692 "Array size must be a positive 32 bit integer, got {array_size}"
693 )
694 })?;
695 Ok(inner_field.into_fixed_size_list(array_size))
696 } else {
697 Ok(inner_field.into_list())
698 }
699 }
700 SQLDataType::Array(ArrayElemTypeDef::None) => {
701 not_impl_err!("Arrays with unspecified type is not supported")
702 }
703 other => Ok(self
704 .convert_simple_data_type(other)?
705 .into_nullable_field_ref()),
706 }
707 }
708
709 fn convert_simple_data_type(&self, sql_type: &SQLDataType) -> Result<DataType> {
710 match sql_type {
711 SQLDataType::Boolean | SQLDataType::Bool => Ok(DataType::Boolean),
712 SQLDataType::TinyInt(_) => Ok(DataType::Int8),
713 SQLDataType::SmallInt(_) | SQLDataType::Int2(_) => Ok(DataType::Int16),
714 SQLDataType::Int(_) | SQLDataType::Integer(_) | SQLDataType::Int4(_) => {
715 Ok(DataType::Int32)
716 }
717 SQLDataType::BigInt(_) | SQLDataType::Int8(_) => Ok(DataType::Int64),
718 SQLDataType::TinyIntUnsigned(_) => Ok(DataType::UInt8),
719 SQLDataType::SmallIntUnsigned(_) | SQLDataType::Int2Unsigned(_) => {
720 Ok(DataType::UInt16)
721 }
722 SQLDataType::IntUnsigned(_)
723 | SQLDataType::IntegerUnsigned(_)
724 | SQLDataType::Int4Unsigned(_) => Ok(DataType::UInt32),
725 SQLDataType::Varchar(length) => {
726 match (length, self.options.support_varchar_with_length) {
727 (Some(_), false) => plan_err!(
728 "does not support Varchar with length, \
729 please set `support_varchar_with_length` to be true"
730 ),
731 _ => {
732 if self.options.map_string_types_to_utf8view {
733 Ok(DataType::Utf8View)
734 } else {
735 Ok(DataType::Utf8)
736 }
737 }
738 }
739 }
740 SQLDataType::BigIntUnsigned(_) | SQLDataType::Int8Unsigned(_) => {
741 Ok(DataType::UInt64)
742 }
743 SQLDataType::Float(_) => Ok(DataType::Float32),
744 SQLDataType::Real | SQLDataType::Float4 => Ok(DataType::Float32),
745 SQLDataType::Double(ExactNumberInfo::None)
746 | SQLDataType::DoublePrecision
747 | SQLDataType::Float8 => Ok(DataType::Float64),
748 SQLDataType::Double(
749 ExactNumberInfo::Precision(_) | ExactNumberInfo::PrecisionAndScale(_, _),
750 ) => {
751 not_impl_err!(
752 "Unsupported SQL type (precision/scale not supported) {sql_type}"
753 )
754 }
755 SQLDataType::Char(_) | SQLDataType::Text | SQLDataType::String(_) => {
756 if self.options.map_string_types_to_utf8view {
757 Ok(DataType::Utf8View)
758 } else {
759 Ok(DataType::Utf8)
760 }
761 }
762 SQLDataType::Timestamp(precision, tz_info)
763 if precision.is_none() || [0, 3, 6, 9].contains(&precision.unwrap()) =>
764 {
765 let tz = if *tz_info == TimezoneInfo::Tz
766 || *tz_info == TimezoneInfo::WithTimeZone
767 {
768 self.context_provider.options().execution.time_zone.clone()
772 } else {
773 None
775 };
776 let precision = match precision {
777 Some(0) => TimeUnit::Second,
778 Some(3) => TimeUnit::Millisecond,
779 Some(6) => TimeUnit::Microsecond,
780 None | Some(9) => TimeUnit::Nanosecond,
781 _ => unreachable!(),
782 };
783 Ok(DataType::Timestamp(precision, tz.map(Into::into)))
784 }
785 SQLDataType::Date => Ok(DataType::Date32),
786 SQLDataType::Time(None, tz_info) => {
787 if *tz_info == TimezoneInfo::None
788 || *tz_info == TimezoneInfo::WithoutTimeZone
789 {
790 Ok(DataType::Time64(TimeUnit::Nanosecond))
791 } else {
792 not_impl_err!("Unsupported SQL type {sql_type}")
794 }
795 }
796 SQLDataType::Numeric(exact_number_info)
797 | SQLDataType::Decimal(exact_number_info) => {
798 let (precision, scale) = match *exact_number_info {
799 ExactNumberInfo::None => (None, None),
800 ExactNumberInfo::Precision(precision) => (Some(precision), None),
801 ExactNumberInfo::PrecisionAndScale(precision, scale) => {
802 (Some(precision), Some(scale))
803 }
804 };
805 make_decimal_type(precision, scale.map(|s| s as u64))
806 }
807 SQLDataType::Bytea => Ok(DataType::Binary),
808 SQLDataType::Interval { fields, precision } => {
809 if fields.is_some() || precision.is_some() {
810 return not_impl_err!("Unsupported SQL type {sql_type}");
811 }
812 Ok(DataType::Interval(IntervalUnit::MonthDayNano))
813 }
814 SQLDataType::Struct(fields, _) => {
815 let fields = fields
816 .iter()
817 .enumerate()
818 .map(|(idx, sql_struct_field)| {
819 let field = self.convert_data_type_to_field(&sql_struct_field.field_type)?;
820 let field_name = match &sql_struct_field.field_name {
821 Some(ident) => ident.clone(),
822 None => Ident::new(format!("c{idx}")),
823 };
824 Ok(field.as_ref().clone().with_name(self.ident_normalizer.normalize(field_name)))
825 })
826 .collect::<Result<Vec<_>>>()?;
827 Ok(DataType::Struct(Fields::from(fields)))
828 }
829 SQLDataType::Nvarchar(_)
830 | SQLDataType::JSON
831 | SQLDataType::Uuid
832 | SQLDataType::Binary(_)
833 | SQLDataType::Varbinary(_)
834 | SQLDataType::Blob(_)
835 | SQLDataType::Datetime(_)
836 | SQLDataType::Regclass
837 | SQLDataType::Custom(_, _)
838 | SQLDataType::Array(_)
839 | SQLDataType::Enum(_, _)
840 | SQLDataType::Set(_)
841 | SQLDataType::MediumInt(_)
842 | SQLDataType::MediumIntUnsigned(_)
843 | SQLDataType::Character(_)
844 | SQLDataType::CharacterVarying(_)
845 | SQLDataType::CharVarying(_)
846 | SQLDataType::CharacterLargeObject(_)
847 | SQLDataType::CharLargeObject(_)
848 | SQLDataType::Timestamp(_, _)
849 | SQLDataType::Time(Some(_), _)
850 | SQLDataType::Dec(_)
851 | SQLDataType::BigNumeric(_)
852 | SQLDataType::BigDecimal(_)
853 | SQLDataType::Clob(_)
854 | SQLDataType::Bytes(_)
855 | SQLDataType::Int64
856 | SQLDataType::Float64
857 | SQLDataType::JSONB
858 | SQLDataType::Unspecified
859 | SQLDataType::Int16
860 | SQLDataType::Int32
861 | SQLDataType::Int128
862 | SQLDataType::Int256
863 | SQLDataType::UInt8
864 | SQLDataType::UInt16
865 | SQLDataType::UInt32
866 | SQLDataType::UInt64
867 | SQLDataType::UInt128
868 | SQLDataType::UInt256
869 | SQLDataType::Float32
870 | SQLDataType::Date32
871 | SQLDataType::Datetime64(_, _)
872 | SQLDataType::FixedString(_)
873 | SQLDataType::Map(_, _)
874 | SQLDataType::Tuple(_)
875 | SQLDataType::Nested(_)
876 | SQLDataType::Union(_)
877 | SQLDataType::Nullable(_)
878 | SQLDataType::LowCardinality(_)
879 | SQLDataType::Trigger
880 | SQLDataType::TinyBlob
881 | SQLDataType::MediumBlob
882 | SQLDataType::LongBlob
883 | SQLDataType::TinyText
884 | SQLDataType::MediumText
885 | SQLDataType::LongText
886 | SQLDataType::Bit(_)
887 | SQLDataType::BitVarying(_)
888 | SQLDataType::Signed
889 | SQLDataType::SignedInteger
890 | SQLDataType::Unsigned
891 | SQLDataType::UnsignedInteger
892 | SQLDataType::AnyType
893 | SQLDataType::Table(_)
894 | SQLDataType::VarBit(_)
895 | SQLDataType::UTinyInt
896 | SQLDataType::USmallInt
897 | SQLDataType::HugeInt
898 | SQLDataType::UHugeInt
899 | SQLDataType::UBigInt
900 | SQLDataType::TimestampNtz{..}
901 | SQLDataType::NamedTable { .. }
902 | SQLDataType::TsVector
903 | SQLDataType::TsQuery
904 | SQLDataType::GeometricType(_)
905 | SQLDataType::DecimalUnsigned(_) | SQLDataType::FloatUnsigned(_) | SQLDataType::RealUnsigned | SQLDataType::DecUnsigned(_) | SQLDataType::DoubleUnsigned(_) | SQLDataType::DoublePrecisionUnsigned => {
912 not_impl_err!("Unsupported SQL type {sql_type}")
913 }
914 }
915 }
916
917 pub(crate) fn object_name_to_table_reference(
918 &self,
919 object_name: ObjectName,
920 ) -> Result<TableReference> {
921 object_name_to_table_reference(
922 object_name,
923 self.options.enable_ident_normalization,
924 )
925 }
926}
927
928pub fn object_name_to_table_reference(
939 object_name: ObjectName,
940 enable_normalization: bool,
941) -> Result<TableReference> {
942 let ObjectName(object_name_parts) = object_name;
944 let idents = object_name_parts
945 .into_iter()
946 .map(|object_name_part| {
947 object_name_part.as_ident().cloned().ok_or_else(|| {
948 plan_datafusion_err!(
949 "Expected identifier, but found: {:?}",
950 object_name_part
951 )
952 })
953 })
954 .collect::<Result<Vec<_>>>()?;
955 idents_to_table_reference(idents, enable_normalization)
956}
957
958struct IdentTaker {
959 normalizer: IdentNormalizer,
960 idents: Vec<Ident>,
961}
962
963impl IdentTaker {
966 fn new(idents: Vec<Ident>, enable_normalization: bool) -> Self {
967 Self {
968 normalizer: IdentNormalizer::new(enable_normalization),
969 idents,
970 }
971 }
972
973 fn take(&mut self) -> String {
974 let ident = self.idents.pop().expect("no more identifiers");
975 self.normalizer.normalize(ident)
976 }
977
978 fn len(&self) -> usize {
980 self.idents.len()
981 }
982}
983
984impl std::fmt::Display for IdentTaker {
986 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
987 let mut first = true;
988 for ident in self.idents.iter() {
989 if !first {
990 write!(f, ".")?;
991 }
992 write!(f, "{ident}")?;
993 first = false;
994 }
995
996 Ok(())
997 }
998}
999
1000pub(crate) fn idents_to_table_reference(
1002 idents: Vec<Ident>,
1003 enable_normalization: bool,
1004) -> Result<TableReference> {
1005 let mut taker = IdentTaker::new(idents, enable_normalization);
1006
1007 match taker.len() {
1008 1 => {
1009 let table = taker.take();
1010 Ok(TableReference::bare(table))
1011 }
1012 2 => {
1013 let table = taker.take();
1014 let schema = taker.take();
1015 Ok(TableReference::partial(schema, table))
1016 }
1017 3 => {
1018 let table = taker.take();
1019 let schema = taker.take();
1020 let catalog = taker.take();
1021 Ok(TableReference::full(catalog, schema, table))
1022 }
1023 _ => plan_err!(
1024 "Unsupported compound identifier '{}'. Expected 1, 2 or 3 parts, got {}",
1025 taker,
1026 taker.len()
1027 ),
1028 }
1029}
1030
1031pub fn object_name_to_qualifier(
1034 sql_table_name: &ObjectName,
1035 enable_normalization: bool,
1036) -> Result<String> {
1037 let columns = vec!["table_name", "table_schema", "table_catalog"].into_iter();
1038 let normalizer = IdentNormalizer::new(enable_normalization);
1039 sql_table_name
1040 .0
1041 .iter()
1042 .rev()
1043 .zip(columns)
1044 .map(|(object_name_part, column_name)| {
1045 object_name_part
1046 .as_ident()
1047 .map(|ident| {
1048 format!(
1049 r#"{} = '{}'"#,
1050 column_name,
1051 normalizer.normalize(ident.clone())
1052 )
1053 })
1054 .ok_or_else(|| {
1055 plan_datafusion_err!(
1056 "Expected identifier, but found: {:?}",
1057 object_name_part
1058 )
1059 })
1060 })
1061 .collect::<Result<Vec<_>>>()
1062 .map(|parts| parts.join(" AND "))
1063}