Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions datafusion/sql/src/unparser/dialect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -645,6 +645,55 @@ impl Dialect for BigQueryDialect {
fn unnest_as_table_factor(&self) -> bool {
true
}

fn supports_column_alias_in_table_alias(&self) -> bool {
false
}

fn float64_ast_dtype(&self) -> ast::DataType {
ast::DataType::Float64
}

fn utf8_cast_dtype(&self) -> ast::DataType {
ast::DataType::String(None)
}

fn large_utf8_cast_dtype(&self) -> ast::DataType {
ast::DataType::String(None)
}

fn int64_cast_dtype(&self) -> ast::DataType {
ast::DataType::Int64
}

fn timestamp_cast_dtype(
&self,
_time_unit: &TimeUnit,
_tz: &Option<Arc<str>>,
) -> ast::DataType {
ast::DataType::Timestamp(None, TimezoneInfo::None)
}

fn date_field_extract_style(&self) -> DateFieldExtractStyle {
DateFieldExtractStyle::Extract
}

fn interval_style(&self) -> IntervalStyle {
IntervalStyle::SQLStandard
}

fn scalar_function_to_sql_overrides(
&self,
unparser: &Unparser,
func_name: &str,
args: &[Expr],
) -> Result<Option<ast::Expr>> {
if func_name == "date_part" {
return date_part_to_sql(unparser, self.date_field_extract_style(), args);
}

Ok(None)
}
}

impl BigQueryDialect {
Expand Down
54 changes: 54 additions & 0 deletions datafusion/sql/src/unparser/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3468,4 +3468,58 @@ mod tests {
}
Ok(())
}

#[test]
fn test_bigquery_dialect_overrides() -> Result<()> {
let bigquery_dialect: Arc<dyn Dialect> = Arc::new(BigQueryDialect::new());
let unparser = Unparser::new(bigquery_dialect.as_ref());

// date_field_extract_style: EXTRACT instead of date_part
let expr = Expr::ScalarFunction(ScalarFunction {
func: Arc::new(ScalarUDF::new_from_impl(
datafusion_functions::datetime::date_part::DatePartFunc::new(),
)),
args: vec![lit("YEAR"), col("date_col")],
});
let actual = format!("{}", unparser.expr_to_sql(&expr)?);
assert_eq!(actual, "EXTRACT(YEAR FROM `date_col`)");

// interval_style: SQL standard instead of PostgresVerbose
let expr = interval_year_month_lit("3 months");
let actual = format!("{}", unparser.expr_to_sql(&expr)?);
assert_eq!(actual, "INTERVAL '3' MONTH");

// float64_ast_dtype: FLOAT64 instead of DOUBLE
let expr = cast(col("a"), DataType::Float64);
let actual = format!("{}", unparser.expr_to_sql(&expr)?);
assert_eq!(actual, "CAST(`a` AS FLOAT64)");

// supports_column_alias_in_table_alias: false
assert!(!bigquery_dialect.supports_column_alias_in_table_alias());

// utf8_cast_dtype: STRING instead of VARCHAR
let expr = cast(col("a"), DataType::Utf8);
let actual = format!("{}", unparser.expr_to_sql(&expr)?);
assert_eq!(actual, "CAST(`a` AS STRING)");

// large_utf8_cast_dtype: STRING instead of TEXT
let expr = cast(col("a"), DataType::LargeUtf8);
let actual = format!("{}", unparser.expr_to_sql(&expr)?);
assert_eq!(actual, "CAST(`a` AS STRING)");

// int64_cast_dtype: INT64 instead of BIGINT
let expr = cast(col("a"), DataType::Int64);
let actual = format!("{}", unparser.expr_to_sql(&expr)?);
assert_eq!(actual, "CAST(`a` AS INT64)");
Comment thread
sgrebnov marked this conversation as resolved.
Outdated

// timestamp_cast_dtype: TIMESTAMP (no WITH TIME ZONE)
let expr = cast(
col("a"),
DataType::Timestamp(TimeUnit::Microsecond, Some("+00:00".into())),
);
let actual = format!("{}", unparser.expr_to_sql(&expr)?);
assert_eq!(actual, "CAST(`a` AS TIMESTAMP)");

Ok(())
}
}
Loading