From 968d1c543e6c2f2720f8e62f4ca674d75eeaacc7 Mon Sep 17 00:00:00 2001 From: shuvamk Date: Tue, 4 Aug 2026 22:18:51 +0530 Subject: [PATCH] Databricks: support CREATE TABLE USING, MAP columns and LONG as BIGINT Databricks SQL is built on Spark SQL, but DatabricksDialect never got three of the flags SparkSqlDialect sets, so these fail on Databricks and parse on Spark: CREATE TABLE t (id BIGINT) USING DELTA CREATE TABLE t (m MAP) with "Expected: end of statement, found: USING at Line: 1, Column: 28" and "Expected: ',' or ')' after column definition, found: < at Line: 1, Column: 22". CREATE TABLE t (id LONG) parses, but builds DataType::Custom("LONG") instead of DataType::BigInt(None). Databricks documents the type as { BIGINT | LONG }. Set supports_create_table_using, supports_long_type_as_bigint and supports_map_literal_with_angle_brackets on DatabricksDialect, mirroring src/dialect/spark.rs. No parser change and no other dialect is affected. Regression tests in tests/sqlparser_databricks.rs; all three fail with src/dialect/databricks.rs reverted. Co-Authored-By: Claude Opus 5 --- src/dialect/databricks.rs | 17 ++++++++++++ tests/sqlparser_databricks.rs | 52 +++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+) diff --git a/src/dialect/databricks.rs b/src/dialect/databricks.rs index 3bc187a7f..036d7808a 100644 --- a/src/dialect/databricks.rs +++ b/src/dialect/databricks.rs @@ -113,4 +113,21 @@ impl Dialect for DatabricksDialect { fn supports_select_item_multi_column_alias(&self) -> bool { true } + + /// See + fn supports_create_table_using(&self) -> bool { + true + } + + /// `LONG` is an alias for `BIGINT` in Databricks SQL. + /// + /// See + fn supports_long_type_as_bigint(&self) -> bool { + true + } + + /// See + fn supports_map_literal_with_angle_brackets(&self) -> bool { + true + } } diff --git a/tests/sqlparser_databricks.rs b/tests/sqlparser_databricks.rs index 7c582546f..23c263263 100644 --- a/tests/sqlparser_databricks.rs +++ b/tests/sqlparser_databricks.rs @@ -737,3 +737,55 @@ fn parse_cte_without_as() { .parse_sql_statements("WITH cte (SELECT 1) SELECT * FROM cte") .is_err()); } + +#[test] +fn parse_create_table_using() { + match databricks().verified_stmt("CREATE TABLE t (id BIGINT) USING DELTA") { + Statement::CreateTable(CreateTable { hive_formats, .. }) => { + assert_eq!( + hive_formats.unwrap().storage, + Some(HiveIOFormat::Using { + format: Ident::new("DELTA") + }) + ); + } + s => panic!("Unexpected statement: {s:?}"), + } + + databricks().verified_stmt("CREATE TABLE IF NOT EXISTS t (id BIGINT) USING PARQUET"); + + assert!(all_dialects_where(|d| !d.supports_create_table_using()) + .parse_sql_statements("CREATE TABLE t (id BIGINT) USING DELTA") + .is_err()); +} + +#[test] +fn parse_create_table_map_type() { + match databricks().verified_stmt("CREATE TABLE t (m MAP)") { + Statement::CreateTable(CreateTable { columns, .. }) => { + assert_eq!( + columns[0].data_type, + DataType::Map( + Box::new(DataType::String(None)), + Box::new(DataType::Int(None)), + MapBracketKind::AngleBrackets + ) + ); + } + s => panic!("Unexpected statement: {s:?}"), + } + + databricks().verified_stmt("CREATE TABLE t (m MAP>)"); +} + +#[test] +fn parse_long_type_as_bigint() { + match databricks() + .one_statement_parses_to("CREATE TABLE t (id LONG)", "CREATE TABLE t (id BIGINT)") + { + Statement::CreateTable(CreateTable { columns, .. }) => { + assert_eq!(columns[0].data_type, DataType::BigInt(None)); + } + s => panic!("Unexpected statement: {s:?}"), + } +}