1use std::{collections::HashMap, sync::Arc};
19
20use super::{
21 Unparser, utils::character_length_to_sql, utils::date_part_to_sql,
22 utils::sqlite_date_trunc_to_sql, utils::sqlite_from_unixtime_to_sql,
23};
24use arrow::array::timezone::Tz;
25use arrow::datatypes::TimeUnit;
26use chrono::DateTime;
27use datafusion_common::Result;
28use datafusion_expr::Expr;
29use regex::Regex;
30use sqlparser::tokenizer::Span;
31use sqlparser::{
32 ast::{
33 self, BinaryOperator, Function, Ident, ObjectName, TimezoneInfo, WindowFrameBound,
34 },
35 keywords::ALL_KEYWORDS,
36};
37
38pub type ScalarFnToSqlHandler =
39 Box<dyn Fn(&Unparser, &[Expr]) -> Result<Option<ast::Expr>> + Send + Sync>;
40
41pub trait Dialect: Send + Sync {
51 fn identifier_quote_style(&self, _identifier: &str) -> Option<char>;
53
54 fn supports_nulls_first_in_sort(&self) -> bool {
56 true
57 }
58
59 fn use_timestamp_for_date64(&self) -> bool {
62 false
63 }
64
65 fn interval_style(&self) -> IntervalStyle {
66 IntervalStyle::PostgresVerbose
67 }
68
69 fn float64_ast_dtype(&self) -> ast::DataType {
72 ast::DataType::Double(ast::ExactNumberInfo::None)
73 }
74
75 fn utf8_cast_dtype(&self) -> ast::DataType {
78 ast::DataType::Varchar(None)
79 }
80
81 fn large_utf8_cast_dtype(&self) -> ast::DataType {
84 ast::DataType::Text
85 }
86
87 fn date_field_extract_style(&self) -> DateFieldExtractStyle {
89 DateFieldExtractStyle::DatePart
90 }
91
92 fn character_length_style(&self) -> CharacterLengthStyle {
94 CharacterLengthStyle::CharacterLength
95 }
96
97 fn int64_cast_dtype(&self) -> ast::DataType {
100 ast::DataType::BigInt(None)
101 }
102
103 fn int32_cast_dtype(&self) -> ast::DataType {
106 ast::DataType::Integer(None)
107 }
108
109 fn timestamp_cast_dtype(
113 &self,
114 _time_unit: &TimeUnit,
115 tz: &Option<Arc<str>>,
116 ) -> ast::DataType {
117 let tz_info = match tz {
118 Some(_) => TimezoneInfo::WithTimeZone,
119 None => TimezoneInfo::None,
120 };
121
122 ast::DataType::Timestamp(None, tz_info)
123 }
124
125 fn date32_cast_dtype(&self) -> ast::DataType {
128 ast::DataType::Date
129 }
130
131 fn supports_column_alias_in_table_alias(&self) -> bool {
134 true
135 }
136
137 fn requires_derived_table_alias(&self) -> bool {
140 false
141 }
142
143 fn division_operator(&self) -> BinaryOperator {
147 BinaryOperator::Divide
148 }
149
150 fn scalar_function_to_sql_overrides(
154 &self,
155 _unparser: &Unparser,
156 _func_name: &str,
157 _args: &[Expr],
158 ) -> Result<Option<ast::Expr>> {
159 Ok(None)
160 }
161
162 fn window_func_support_window_frame(
166 &self,
167 _func_name: &str,
168 _start_bound: &WindowFrameBound,
169 _end_bound: &WindowFrameBound,
170 ) -> bool {
171 true
172 }
173
174 fn with_custom_scalar_overrides(
177 self,
178 _handlers: Vec<(&str, ScalarFnToSqlHandler)>,
179 ) -> Self
180 where
181 Self: Sized,
182 {
183 unimplemented!("Custom scalar overrides are not supported by this dialect yet");
184 }
185
186 fn full_qualified_col(&self) -> bool {
191 false
192 }
193
194 fn unnest_as_table_factor(&self) -> bool {
200 false
201 }
202
203 fn col_alias_overrides(&self, _alias: &str) -> Result<Option<String>> {
207 Ok(None)
208 }
209
210 fn supports_qualify(&self) -> bool {
214 true
215 }
216
217 fn timestamp_with_tz_to_string(&self, dt: DateTime<Tz>, _unit: TimeUnit) -> String {
219 dt.to_string()
220 }
221
222 fn supports_empty_select_list(&self) -> bool {
249 false
250 }
251}
252
253#[derive(Clone, Copy)]
262pub enum IntervalStyle {
263 PostgresVerbose,
264 SQLStandard,
265 MySQL,
266}
267
268#[derive(Clone, Copy, PartialEq)]
276pub enum DateFieldExtractStyle {
277 DatePart,
278 Extract,
279 Strftime,
280}
281
282#[derive(Clone, Copy, PartialEq)]
288pub enum CharacterLengthStyle {
289 Length,
290 CharacterLength,
291}
292
293pub struct DefaultDialect {}
294
295impl Dialect for DefaultDialect {
296 fn identifier_quote_style(&self, identifier: &str) -> Option<char> {
297 let identifier_regex = Regex::new(r"^[a-zA-Z_][a-zA-Z0-9_]*$").unwrap();
298 let id_upper = identifier.to_uppercase();
299 let needs_quote = (id_upper != "ID" && ALL_KEYWORDS.contains(&id_upper.as_str()))
304 || !identifier_regex.is_match(identifier)
305 || identifier.chars().any(|c| c.is_ascii_uppercase());
306 if needs_quote { Some('"') } else { None }
307 }
308}
309
310pub struct PostgreSqlDialect {}
311
312impl Dialect for PostgreSqlDialect {
313 fn supports_qualify(&self) -> bool {
314 false
315 }
316
317 fn requires_derived_table_alias(&self) -> bool {
318 true
319 }
320
321 fn supports_empty_select_list(&self) -> bool {
322 true
323 }
324
325 fn identifier_quote_style(&self, _: &str) -> Option<char> {
326 Some('"')
327 }
328
329 fn interval_style(&self) -> IntervalStyle {
330 IntervalStyle::PostgresVerbose
331 }
332
333 fn float64_ast_dtype(&self) -> ast::DataType {
334 ast::DataType::DoublePrecision
335 }
336
337 fn scalar_function_to_sql_overrides(
338 &self,
339 unparser: &Unparser,
340 func_name: &str,
341 args: &[Expr],
342 ) -> Result<Option<ast::Expr>> {
343 if func_name == "round" {
344 return Ok(Some(
345 self.round_to_sql_enforce_numeric(unparser, func_name, args)?,
346 ));
347 }
348
349 Ok(None)
350 }
351}
352
353impl PostgreSqlDialect {
354 fn round_to_sql_enforce_numeric(
355 &self,
356 unparser: &Unparser,
357 func_name: &str,
358 args: &[Expr],
359 ) -> Result<ast::Expr> {
360 let mut args = unparser.function_args_to_sql(args)?;
361
362 if let Some(ast::FunctionArg::Unnamed(ast::FunctionArgExpr::Expr(expr))) =
364 args.first_mut()
365 {
366 if let ast::Expr::Cast { data_type, .. } = expr {
367 *data_type = ast::DataType::Numeric(ast::ExactNumberInfo::None);
369 } else {
370 *expr = ast::Expr::Cast {
372 kind: ast::CastKind::Cast,
373 expr: Box::new(expr.clone()),
374 data_type: ast::DataType::Numeric(ast::ExactNumberInfo::None),
375 array: false,
376 format: None,
377 };
378 }
379 }
380
381 Ok(ast::Expr::Function(Function {
382 name: ObjectName::from(vec![Ident {
383 value: func_name.to_string(),
384 quote_style: None,
385 span: Span::empty(),
386 }]),
387 args: ast::FunctionArguments::List(ast::FunctionArgumentList {
388 duplicate_treatment: None,
389 args,
390 clauses: vec![],
391 }),
392 filter: None,
393 null_treatment: None,
394 over: None,
395 within_group: vec![],
396 parameters: ast::FunctionArguments::None,
397 uses_odbc_syntax: false,
398 }))
399 }
400}
401
402#[derive(Default)]
403pub struct DuckDBDialect {
404 custom_scalar_fn_overrides: HashMap<String, ScalarFnToSqlHandler>,
405}
406
407impl DuckDBDialect {
408 #[must_use]
409 pub fn new() -> Self {
410 Self {
411 custom_scalar_fn_overrides: HashMap::new(),
412 }
413 }
414}
415
416impl Dialect for DuckDBDialect {
417 fn identifier_quote_style(&self, _: &str) -> Option<char> {
418 Some('"')
419 }
420
421 fn character_length_style(&self) -> CharacterLengthStyle {
422 CharacterLengthStyle::Length
423 }
424
425 fn division_operator(&self) -> BinaryOperator {
426 BinaryOperator::DuckIntegerDivide
427 }
428
429 fn with_custom_scalar_overrides(
430 mut self,
431 handlers: Vec<(&str, ScalarFnToSqlHandler)>,
432 ) -> Self {
433 for (func_name, handler) in handlers {
434 self.custom_scalar_fn_overrides
435 .insert(func_name.to_string(), handler);
436 }
437 self
438 }
439
440 fn scalar_function_to_sql_overrides(
441 &self,
442 unparser: &Unparser,
443 func_name: &str,
444 args: &[Expr],
445 ) -> Result<Option<ast::Expr>> {
446 if let Some(handler) = self.custom_scalar_fn_overrides.get(func_name) {
447 return handler(unparser, args);
448 }
449
450 if func_name == "character_length" {
451 return character_length_to_sql(
452 unparser,
453 self.character_length_style(),
454 args,
455 );
456 }
457
458 Ok(None)
459 }
460
461 fn timestamp_with_tz_to_string(&self, dt: DateTime<Tz>, unit: TimeUnit) -> String {
462 let format = match unit {
463 TimeUnit::Second => "%Y-%m-%d %H:%M:%S%:z",
464 TimeUnit::Millisecond => "%Y-%m-%d %H:%M:%S%.3f%:z",
465 TimeUnit::Microsecond => "%Y-%m-%d %H:%M:%S%.6f%:z",
466 TimeUnit::Nanosecond => "%Y-%m-%d %H:%M:%S%.9f%:z",
467 };
468
469 dt.format(format).to_string()
470 }
471}
472
473pub struct MySqlDialect {}
474
475impl Dialect for MySqlDialect {
476 fn supports_qualify(&self) -> bool {
477 false
478 }
479
480 fn identifier_quote_style(&self, _: &str) -> Option<char> {
481 Some('`')
482 }
483
484 fn supports_nulls_first_in_sort(&self) -> bool {
485 false
486 }
487
488 fn interval_style(&self) -> IntervalStyle {
489 IntervalStyle::MySQL
490 }
491
492 fn utf8_cast_dtype(&self) -> ast::DataType {
493 ast::DataType::Char(None)
494 }
495
496 fn large_utf8_cast_dtype(&self) -> ast::DataType {
497 ast::DataType::Char(None)
498 }
499
500 fn date_field_extract_style(&self) -> DateFieldExtractStyle {
501 DateFieldExtractStyle::Extract
502 }
503
504 fn int64_cast_dtype(&self) -> ast::DataType {
505 ast::DataType::Custom(ObjectName::from(vec![Ident::new("SIGNED")]), vec![])
506 }
507
508 fn int32_cast_dtype(&self) -> ast::DataType {
509 ast::DataType::Custom(ObjectName::from(vec![Ident::new("SIGNED")]), vec![])
510 }
511
512 fn timestamp_cast_dtype(
513 &self,
514 _time_unit: &TimeUnit,
515 _tz: &Option<Arc<str>>,
516 ) -> ast::DataType {
517 ast::DataType::Datetime(None)
518 }
519
520 fn requires_derived_table_alias(&self) -> bool {
521 true
522 }
523
524 fn scalar_function_to_sql_overrides(
525 &self,
526 unparser: &Unparser,
527 func_name: &str,
528 args: &[Expr],
529 ) -> Result<Option<ast::Expr>> {
530 if func_name == "date_part" {
531 return date_part_to_sql(unparser, self.date_field_extract_style(), args);
532 }
533
534 Ok(None)
535 }
536}
537
538pub struct SqliteDialect {}
539
540impl Dialect for SqliteDialect {
541 fn supports_qualify(&self) -> bool {
542 false
543 }
544
545 fn identifier_quote_style(&self, _: &str) -> Option<char> {
546 Some('`')
547 }
548
549 fn date_field_extract_style(&self) -> DateFieldExtractStyle {
550 DateFieldExtractStyle::Strftime
551 }
552
553 fn date32_cast_dtype(&self) -> ast::DataType {
554 ast::DataType::Text
555 }
556
557 fn character_length_style(&self) -> CharacterLengthStyle {
558 CharacterLengthStyle::Length
559 }
560
561 fn supports_column_alias_in_table_alias(&self) -> bool {
562 false
563 }
564
565 fn timestamp_cast_dtype(
566 &self,
567 _time_unit: &TimeUnit,
568 _tz: &Option<Arc<str>>,
569 ) -> ast::DataType {
570 ast::DataType::Text
571 }
572
573 fn scalar_function_to_sql_overrides(
574 &self,
575 unparser: &Unparser,
576 func_name: &str,
577 args: &[Expr],
578 ) -> Result<Option<ast::Expr>> {
579 match func_name {
580 "date_part" => {
581 date_part_to_sql(unparser, self.date_field_extract_style(), args)
582 }
583 "character_length" => {
584 character_length_to_sql(unparser, self.character_length_style(), args)
585 }
586 "from_unixtime" => sqlite_from_unixtime_to_sql(unparser, args),
587 "date_trunc" => sqlite_date_trunc_to_sql(unparser, args),
588 _ => Ok(None),
589 }
590 }
591}
592
593#[derive(Default)]
594pub struct BigQueryDialect {}
595
596impl Dialect for BigQueryDialect {
597 fn identifier_quote_style(&self, _: &str) -> Option<char> {
598 Some('`')
599 }
600
601 fn col_alias_overrides(&self, alias: &str) -> Result<Option<String>> {
602 let special_chars: [char; 20] = [
605 '!', '"', '$', '(', ')', '*', ',', '.', '/', ';', '?', '@', '[', '\\', ']',
606 '^', '`', '{', '}', '~',
607 ];
608
609 if alias.chars().any(|c| special_chars.contains(&c)) {
610 let mut encoded_name = String::new();
611 for c in alias.chars() {
612 if special_chars.contains(&c) {
613 encoded_name.push_str(&format!("_{}", c as u32));
614 } else {
615 encoded_name.push(c);
616 }
617 }
618 Ok(Some(encoded_name))
619 } else {
620 Ok(Some(alias.to_string()))
621 }
622 }
623
624 fn unnest_as_table_factor(&self) -> bool {
625 true
626 }
627}
628
629impl BigQueryDialect {
630 #[must_use]
631 pub fn new() -> Self {
632 Self {}
633 }
634}
635
636pub struct CustomDialect {
637 identifier_quote_style: Option<char>,
638 supports_nulls_first_in_sort: bool,
639 use_timestamp_for_date64: bool,
640 interval_style: IntervalStyle,
641 float64_ast_dtype: ast::DataType,
642 utf8_cast_dtype: ast::DataType,
643 large_utf8_cast_dtype: ast::DataType,
644 date_field_extract_style: DateFieldExtractStyle,
645 character_length_style: CharacterLengthStyle,
646 int64_cast_dtype: ast::DataType,
647 int32_cast_dtype: ast::DataType,
648 timestamp_cast_dtype: ast::DataType,
649 timestamp_tz_cast_dtype: ast::DataType,
650 date32_cast_dtype: ast::DataType,
651 supports_column_alias_in_table_alias: bool,
652 requires_derived_table_alias: bool,
653 division_operator: BinaryOperator,
654 window_func_support_window_frame: bool,
655 full_qualified_col: bool,
656 unnest_as_table_factor: bool,
657}
658
659impl Default for CustomDialect {
660 fn default() -> Self {
661 Self {
662 identifier_quote_style: None,
663 supports_nulls_first_in_sort: true,
664 use_timestamp_for_date64: false,
665 interval_style: IntervalStyle::SQLStandard,
666 float64_ast_dtype: ast::DataType::Double(ast::ExactNumberInfo::None),
667 utf8_cast_dtype: ast::DataType::Varchar(None),
668 large_utf8_cast_dtype: ast::DataType::Text,
669 date_field_extract_style: DateFieldExtractStyle::DatePart,
670 character_length_style: CharacterLengthStyle::CharacterLength,
671 int64_cast_dtype: ast::DataType::BigInt(None),
672 int32_cast_dtype: ast::DataType::Integer(None),
673 timestamp_cast_dtype: ast::DataType::Timestamp(None, TimezoneInfo::None),
674 timestamp_tz_cast_dtype: ast::DataType::Timestamp(
675 None,
676 TimezoneInfo::WithTimeZone,
677 ),
678 date32_cast_dtype: ast::DataType::Date,
679 supports_column_alias_in_table_alias: true,
680 requires_derived_table_alias: false,
681 division_operator: BinaryOperator::Divide,
682 window_func_support_window_frame: true,
683 full_qualified_col: false,
684 unnest_as_table_factor: false,
685 }
686 }
687}
688
689impl Dialect for CustomDialect {
690 fn identifier_quote_style(&self, _: &str) -> Option<char> {
691 self.identifier_quote_style
692 }
693
694 fn supports_nulls_first_in_sort(&self) -> bool {
695 self.supports_nulls_first_in_sort
696 }
697
698 fn use_timestamp_for_date64(&self) -> bool {
699 self.use_timestamp_for_date64
700 }
701
702 fn interval_style(&self) -> IntervalStyle {
703 self.interval_style
704 }
705
706 fn float64_ast_dtype(&self) -> ast::DataType {
707 self.float64_ast_dtype.clone()
708 }
709
710 fn utf8_cast_dtype(&self) -> ast::DataType {
711 self.utf8_cast_dtype.clone()
712 }
713
714 fn large_utf8_cast_dtype(&self) -> ast::DataType {
715 self.large_utf8_cast_dtype.clone()
716 }
717
718 fn date_field_extract_style(&self) -> DateFieldExtractStyle {
719 self.date_field_extract_style
720 }
721
722 fn character_length_style(&self) -> CharacterLengthStyle {
723 self.character_length_style
724 }
725
726 fn int64_cast_dtype(&self) -> ast::DataType {
727 self.int64_cast_dtype.clone()
728 }
729
730 fn int32_cast_dtype(&self) -> ast::DataType {
731 self.int32_cast_dtype.clone()
732 }
733
734 fn timestamp_cast_dtype(
735 &self,
736 _time_unit: &TimeUnit,
737 tz: &Option<Arc<str>>,
738 ) -> ast::DataType {
739 if tz.is_some() {
740 self.timestamp_tz_cast_dtype.clone()
741 } else {
742 self.timestamp_cast_dtype.clone()
743 }
744 }
745
746 fn date32_cast_dtype(&self) -> ast::DataType {
747 self.date32_cast_dtype.clone()
748 }
749
750 fn supports_column_alias_in_table_alias(&self) -> bool {
751 self.supports_column_alias_in_table_alias
752 }
753
754 fn scalar_function_to_sql_overrides(
755 &self,
756 unparser: &Unparser,
757 func_name: &str,
758 args: &[Expr],
759 ) -> Result<Option<ast::Expr>> {
760 match func_name {
761 "date_part" => {
762 date_part_to_sql(unparser, self.date_field_extract_style(), args)
763 }
764 "character_length" => {
765 character_length_to_sql(unparser, self.character_length_style(), args)
766 }
767 _ => Ok(None),
768 }
769 }
770
771 fn requires_derived_table_alias(&self) -> bool {
772 self.requires_derived_table_alias
773 }
774
775 fn division_operator(&self) -> BinaryOperator {
776 self.division_operator.clone()
777 }
778
779 fn window_func_support_window_frame(
780 &self,
781 _func_name: &str,
782 _start_bound: &WindowFrameBound,
783 _end_bound: &WindowFrameBound,
784 ) -> bool {
785 self.window_func_support_window_frame
786 }
787
788 fn full_qualified_col(&self) -> bool {
789 self.full_qualified_col
790 }
791
792 fn unnest_as_table_factor(&self) -> bool {
793 self.unnest_as_table_factor
794 }
795}
796
797pub struct CustomDialectBuilder {
812 identifier_quote_style: Option<char>,
813 supports_nulls_first_in_sort: bool,
814 use_timestamp_for_date64: bool,
815 interval_style: IntervalStyle,
816 float64_ast_dtype: ast::DataType,
817 utf8_cast_dtype: ast::DataType,
818 large_utf8_cast_dtype: ast::DataType,
819 date_field_extract_style: DateFieldExtractStyle,
820 character_length_style: CharacterLengthStyle,
821 int64_cast_dtype: ast::DataType,
822 int32_cast_dtype: ast::DataType,
823 timestamp_cast_dtype: ast::DataType,
824 timestamp_tz_cast_dtype: ast::DataType,
825 date32_cast_dtype: ast::DataType,
826 supports_column_alias_in_table_alias: bool,
827 requires_derived_table_alias: bool,
828 division_operator: BinaryOperator,
829 window_func_support_window_frame: bool,
830 full_qualified_col: bool,
831 unnest_as_table_factor: bool,
832}
833
834impl Default for CustomDialectBuilder {
835 fn default() -> Self {
836 Self::new()
837 }
838}
839
840impl CustomDialectBuilder {
841 pub fn new() -> Self {
842 Self {
843 identifier_quote_style: None,
844 supports_nulls_first_in_sort: true,
845 use_timestamp_for_date64: false,
846 interval_style: IntervalStyle::PostgresVerbose,
847 float64_ast_dtype: ast::DataType::Double(ast::ExactNumberInfo::None),
848 utf8_cast_dtype: ast::DataType::Varchar(None),
849 large_utf8_cast_dtype: ast::DataType::Text,
850 date_field_extract_style: DateFieldExtractStyle::DatePart,
851 character_length_style: CharacterLengthStyle::CharacterLength,
852 int64_cast_dtype: ast::DataType::BigInt(None),
853 int32_cast_dtype: ast::DataType::Integer(None),
854 timestamp_cast_dtype: ast::DataType::Timestamp(None, TimezoneInfo::None),
855 timestamp_tz_cast_dtype: ast::DataType::Timestamp(
856 None,
857 TimezoneInfo::WithTimeZone,
858 ),
859 date32_cast_dtype: ast::DataType::Date,
860 supports_column_alias_in_table_alias: true,
861 requires_derived_table_alias: false,
862 division_operator: BinaryOperator::Divide,
863 window_func_support_window_frame: true,
864 full_qualified_col: false,
865 unnest_as_table_factor: false,
866 }
867 }
868
869 pub fn build(self) -> CustomDialect {
870 CustomDialect {
871 identifier_quote_style: self.identifier_quote_style,
872 supports_nulls_first_in_sort: self.supports_nulls_first_in_sort,
873 use_timestamp_for_date64: self.use_timestamp_for_date64,
874 interval_style: self.interval_style,
875 float64_ast_dtype: self.float64_ast_dtype,
876 utf8_cast_dtype: self.utf8_cast_dtype,
877 large_utf8_cast_dtype: self.large_utf8_cast_dtype,
878 date_field_extract_style: self.date_field_extract_style,
879 character_length_style: self.character_length_style,
880 int64_cast_dtype: self.int64_cast_dtype,
881 int32_cast_dtype: self.int32_cast_dtype,
882 timestamp_cast_dtype: self.timestamp_cast_dtype,
883 timestamp_tz_cast_dtype: self.timestamp_tz_cast_dtype,
884 date32_cast_dtype: self.date32_cast_dtype,
885 supports_column_alias_in_table_alias: self
886 .supports_column_alias_in_table_alias,
887 requires_derived_table_alias: self.requires_derived_table_alias,
888 division_operator: self.division_operator,
889 window_func_support_window_frame: self.window_func_support_window_frame,
890 full_qualified_col: self.full_qualified_col,
891 unnest_as_table_factor: self.unnest_as_table_factor,
892 }
893 }
894
895 pub fn with_identifier_quote_style(mut self, identifier_quote_style: char) -> Self {
897 self.identifier_quote_style = Some(identifier_quote_style);
898 self
899 }
900
901 pub fn with_supports_nulls_first_in_sort(
903 mut self,
904 supports_nulls_first_in_sort: bool,
905 ) -> Self {
906 self.supports_nulls_first_in_sort = supports_nulls_first_in_sort;
907 self
908 }
909
910 pub fn with_use_timestamp_for_date64(
912 mut self,
913 use_timestamp_for_date64: bool,
914 ) -> Self {
915 self.use_timestamp_for_date64 = use_timestamp_for_date64;
916 self
917 }
918
919 pub fn with_interval_style(mut self, interval_style: IntervalStyle) -> Self {
921 self.interval_style = interval_style;
922 self
923 }
924
925 pub fn with_character_length_style(
927 mut self,
928 character_length_style: CharacterLengthStyle,
929 ) -> Self {
930 self.character_length_style = character_length_style;
931 self
932 }
933
934 pub fn with_float64_ast_dtype(mut self, float64_ast_dtype: ast::DataType) -> Self {
936 self.float64_ast_dtype = float64_ast_dtype;
937 self
938 }
939
940 pub fn with_utf8_cast_dtype(mut self, utf8_cast_dtype: ast::DataType) -> Self {
942 self.utf8_cast_dtype = utf8_cast_dtype;
943 self
944 }
945
946 pub fn with_large_utf8_cast_dtype(
948 mut self,
949 large_utf8_cast_dtype: ast::DataType,
950 ) -> Self {
951 self.large_utf8_cast_dtype = large_utf8_cast_dtype;
952 self
953 }
954
955 pub fn with_date_field_extract_style(
957 mut self,
958 date_field_extract_style: DateFieldExtractStyle,
959 ) -> Self {
960 self.date_field_extract_style = date_field_extract_style;
961 self
962 }
963
964 pub fn with_int64_cast_dtype(mut self, int64_cast_dtype: ast::DataType) -> Self {
966 self.int64_cast_dtype = int64_cast_dtype;
967 self
968 }
969
970 pub fn with_int32_cast_dtype(mut self, int32_cast_dtype: ast::DataType) -> Self {
972 self.int32_cast_dtype = int32_cast_dtype;
973 self
974 }
975
976 pub fn with_timestamp_cast_dtype(
978 mut self,
979 timestamp_cast_dtype: ast::DataType,
980 timestamp_tz_cast_dtype: ast::DataType,
981 ) -> Self {
982 self.timestamp_cast_dtype = timestamp_cast_dtype;
983 self.timestamp_tz_cast_dtype = timestamp_tz_cast_dtype;
984 self
985 }
986
987 pub fn with_date32_cast_dtype(mut self, date32_cast_dtype: ast::DataType) -> Self {
988 self.date32_cast_dtype = date32_cast_dtype;
989 self
990 }
991
992 pub fn with_supports_column_alias_in_table_alias(
994 mut self,
995 supports_column_alias_in_table_alias: bool,
996 ) -> Self {
997 self.supports_column_alias_in_table_alias = supports_column_alias_in_table_alias;
998 self
999 }
1000
1001 pub fn with_requires_derived_table_alias(
1002 mut self,
1003 requires_derived_table_alias: bool,
1004 ) -> Self {
1005 self.requires_derived_table_alias = requires_derived_table_alias;
1006 self
1007 }
1008
1009 pub fn with_division_operator(mut self, division_operator: BinaryOperator) -> Self {
1010 self.division_operator = division_operator;
1011 self
1012 }
1013
1014 pub fn with_window_func_support_window_frame(
1015 mut self,
1016 window_func_support_window_frame: bool,
1017 ) -> Self {
1018 self.window_func_support_window_frame = window_func_support_window_frame;
1019 self
1020 }
1021
1022 pub fn with_full_qualified_col(mut self, full_qualified_col: bool) -> Self {
1024 self.full_qualified_col = full_qualified_col;
1025 self
1026 }
1027
1028 pub fn with_unnest_as_table_factor(mut self, unnest_as_table_factor: bool) -> Self {
1029 self.unnest_as_table_factor = unnest_as_table_factor;
1030 self
1031 }
1032}