Skip to content

Support additional DuckDB integer types such as HUGEINT, UHUGEINT, etc #1797

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 5, 2025
Merged
Show file tree
Hide file tree
Changes from all 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
391 changes: 214 additions & 177 deletions src/ast/data_type.rs

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions src/ast/ddl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1276,9 +1276,9 @@ impl fmt::Display for IndexOption {
}
}

/// [Postgres] unique index nulls handling option: `[ NULLS [ NOT ] DISTINCT ]`
/// [PostgreSQL] unique index nulls handling option: `[ NULLS [ NOT ] DISTINCT ]`
///
/// [Postgres]: https://www.postgresql.org/docs/17/sql-altertable.html
/// [PostgreSQL]: https://www.postgresql.org/docs/17/sql-altertable.html
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
Expand Down Expand Up @@ -2175,15 +2175,15 @@ pub struct CreateFunction {
///
/// IMMUTABLE | STABLE | VOLATILE
///
/// [Postgres](https://www.postgresql.org/docs/current/sql-createfunction.html)
/// [PostgreSQL](https://www.postgresql.org/docs/current/sql-createfunction.html)
pub behavior: Option<FunctionBehavior>,
/// CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT
///
/// [Postgres](https://www.postgresql.org/docs/current/sql-createfunction.html)
/// [PostgreSQL](https://www.postgresql.org/docs/current/sql-createfunction.html)
pub called_on_null: Option<FunctionCalledOnNull>,
/// PARALLEL { UNSAFE | RESTRICTED | SAFE }
///
/// [Postgres](https://www.postgresql.org/docs/current/sql-createfunction.html)
/// [PostgreSQL](https://www.postgresql.org/docs/current/sql-createfunction.html)
pub parallel: Option<FunctionParallel>,
/// USING ... (Hive only)
pub using: Option<CreateFunctionUsing>,
Expand Down
30 changes: 15 additions & 15 deletions src/ast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,7 @@ impl fmt::Display for Interval {

/// A field definition within a struct
///
/// [bigquery]: https://cloud.google.com/bigquery/docs/reference/standard-sql/data-types#struct_type
/// [BigQuery]: https://cloud.google.com/bigquery/docs/reference/standard-sql/data-types#struct_type
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
Expand All @@ -431,7 +431,7 @@ impl fmt::Display for StructField {

/// A field definition within a union
///
/// [duckdb]: https://duckdb.org/docs/sql/data_types/union.html
/// [DuckDB]: https://duckdb.org/docs/sql/data_types/union.html
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
Expand All @@ -448,7 +448,7 @@ impl fmt::Display for UnionField {

/// A dictionary field within a dictionary.
///
/// [duckdb]: https://duckdb.org/docs/sql/data_types/struct#creating-structs
/// [DuckDB]: https://duckdb.org/docs/sql/data_types/struct#creating-structs
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
Expand Down Expand Up @@ -479,7 +479,7 @@ impl Display for Map {

/// A map field within a map.
///
/// [duckdb]: https://duckdb.org/docs/sql/data_types/map.html#creating-maps
/// [DuckDB]: https://duckdb.org/docs/sql/data_types/map.html#creating-maps
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
Expand Down Expand Up @@ -2385,10 +2385,10 @@ impl fmt::Display for DeclareAssignment {
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum DeclareType {
/// Cursor variable type. e.g. [Snowflake] [Postgres]
/// Cursor variable type. e.g. [Snowflake] [PostgreSQL]
///
/// [Snowflake]: https://docs.snowflake.com/en/developer-guide/snowflake-scripting/cursors#declaring-a-cursor
/// [Postgres]: https://www.postgresql.org/docs/current/plpgsql-cursors.html
/// [PostgreSQL]: https://www.postgresql.org/docs/current/plpgsql-cursors.html
Cursor,

/// Result set variable type. [Snowflake]
Expand Down Expand Up @@ -2427,15 +2427,15 @@ impl fmt::Display for DeclareType {
}

/// A `DECLARE` statement.
/// [Postgres] [Snowflake] [BigQuery]
/// [PostgreSQL] [Snowflake] [BigQuery]
///
/// Examples:
/// ```sql
/// DECLARE variable_name := 42
/// DECLARE liahona CURSOR FOR SELECT * FROM films;
/// ```
///
/// [Postgres]: https://www.postgresql.org/docs/current/sql-declare.html
/// [PostgreSQL]: https://www.postgresql.org/docs/current/sql-declare.html
/// [Snowflake]: https://docs.snowflake.com/en/sql-reference/snowflake-scripting/declare
/// [BigQuery]: https://cloud.google.com/bigquery/docs/reference/standard-sql/procedural-language#declare
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
Expand Down Expand Up @@ -3020,7 +3020,7 @@ pub enum Statement {
/// ```sql
/// CREATE ROLE
/// ```
/// See [postgres](https://www.postgresql.org/docs/current/sql-createrole.html)
/// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-createrole.html)
CreateRole {
names: Vec<ObjectName>,
if_not_exists: bool,
Expand All @@ -3046,7 +3046,7 @@ pub enum Statement {
/// ```sql
/// CREATE SECRET
/// ```
/// See [duckdb](https://duckdb.org/docs/sql/statements/create_secret.html)
/// See [DuckDB](https://duckdb.org/docs/sql/statements/create_secret.html)
CreateSecret {
or_replace: bool,
temporary: Option<bool>,
Expand Down Expand Up @@ -3550,7 +3550,7 @@ pub enum Statement {
///
/// Supported variants:
/// 1. [Hive](https://cwiki.apache.org/confluence/display/hive/languagemanual+ddl#LanguageManualDDL-Create/Drop/ReloadFunction)
/// 2. [Postgres](https://www.postgresql.org/docs/15/sql-createfunction.html)
/// 2. [PostgreSQL](https://www.postgresql.org/docs/15/sql-createfunction.html)
/// 3. [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#create_function_statement)
CreateFunction(CreateFunction),
/// CREATE TRIGGER
Expand Down Expand Up @@ -8244,7 +8244,7 @@ impl fmt::Display for FunctionDeterminismSpecifier {
/// where within the statement, the body shows up.
///
/// [BigQuery]: https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#syntax_11
/// [Postgres]: https://www.postgresql.org/docs/15/sql-createfunction.html
/// [PostgreSQL]: https://www.postgresql.org/docs/15/sql-createfunction.html
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
Expand Down Expand Up @@ -8282,7 +8282,7 @@ pub enum CreateFunctionBody {
/// RETURN a + b;
/// ```
///
/// [Postgres]: https://www.postgresql.org/docs/current/sql-createfunction.html
/// [PostgreSQL]: https://www.postgresql.org/docs/current/sql-createfunction.html
Return(Expr),
}

Expand Down Expand Up @@ -8588,9 +8588,9 @@ impl Display for CreateViewParams {
}
}

/// Engine of DB. Some warehouse has parameters of engine, e.g. [clickhouse]
/// Engine of DB. Some warehouse has parameters of engine, e.g. [ClickHouse]
///
/// [clickhouse]: https://clickhouse.com/docs/en/engines/table-engines
/// [ClickHouse]: https://clickhouse.com/docs/en/engines/table-engines
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
Expand Down
2 changes: 1 addition & 1 deletion src/dialect/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -995,7 +995,7 @@ pub trait Dialect: Debug + Any {
/// Returns true if the dialect supports `SET NAMES <charset_name> [COLLATE <collation_name>]`.
///
/// - [MySQL](https://dev.mysql.com/doc/refman/8.4/en/set-names.html)
/// - [Postgres](https://www.postgresql.org/docs/17/sql-set.html)
/// - [PostgreSQL](https://www.postgresql.org/docs/17/sql-set.html)
///
/// Note: Postgres doesn't support the `COLLATE` clause, but we permissively parse it anyway.
fn supports_set_names(&self) -> bool {
Expand Down
5 changes: 5 additions & 0 deletions src/keywords.rs
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,7 @@ define_keywords!(
HOSTS,
HOUR,
HOURS,
HUGEINT,
ICEBERG,
ID,
IDENTITY,
Expand Down Expand Up @@ -907,7 +908,9 @@ define_keywords!(
TRY_CONVERT,
TUPLE,
TYPE,
UBIGINT,
UESCAPE,
UHUGEINT,
UINT128,
UINT16,
UINT256,
Expand Down Expand Up @@ -941,6 +944,8 @@ define_keywords!(
USER,
USER_RESOURCES,
USING,
USMALLINT,
UTINYINT,
UUID,
VACUUM,
VALID,
Expand Down
11 changes: 8 additions & 3 deletions src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3779,7 +3779,7 @@ impl<'a> Parser<'a> {
})
}

/// Parse a postgresql casting style which is in the form of `expr::datatype`.
/// Parse a PostgreSQL casting style which is in the form of `expr::datatype`.
pub fn parse_pg_cast(&mut self, expr: Expr) -> Result<Expr, ParserError> {
Ok(Expr::Cast {
kind: CastKind::DoubleColon,
Expand Down Expand Up @@ -4873,9 +4873,9 @@ impl<'a> Parser<'a> {
}
}

/// Parse `CREATE FUNCTION` for [Postgres]
/// Parse `CREATE FUNCTION` for [PostgreSQL]
///
/// [Postgres]: https://www.postgresql.org/docs/15/sql-createfunction.html
/// [PostgreSQL]: https://www.postgresql.org/docs/15/sql-createfunction.html
fn parse_postgres_create_function(
&mut self,
or_replace: bool,
Expand Down Expand Up @@ -9171,6 +9171,11 @@ impl<'a> Parser<'a> {
Ok(DataType::BigInt(optional_precision?))
}
}
Keyword::HUGEINT => Ok(DataType::HugeInt),
Keyword::UBIGINT => Ok(DataType::UBigInt),
Keyword::UHUGEINT => Ok(DataType::UHugeInt),
Keyword::USMALLINT => Ok(DataType::USmallInt),
Keyword::UTINYINT => Ok(DataType::UTinyInt),
Keyword::UINT8 => Ok(DataType::UInt8),
Keyword::UINT16 => Ok(DataType::UInt16),
Keyword::UINT32 => Ok(DataType::UInt32),
Expand Down
26 changes: 26 additions & 0 deletions tests/sqlparser_duckdb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,32 @@ fn test_duckdb_load_extension() {
);
}

#[test]
fn test_duckdb_specific_int_types() {
let duckdb_dtypes = vec![
("UTINYINT", DataType::UTinyInt),
("USMALLINT", DataType::USmallInt),
("UBIGINT", DataType::UBigInt),
("UHUGEINT", DataType::UHugeInt),
("HUGEINT", DataType::HugeInt),
];
for (dtype_string, data_type) in duckdb_dtypes {
let sql = format!("SELECT 123::{}", dtype_string);
let select = duckdb().verified_only_select(&sql);
assert_eq!(
&Expr::Cast {
kind: CastKind::DoubleColon,
expr: Box::new(Expr::Value(
Value::Number("123".parse().unwrap(), false).with_empty_span()
)),
data_type: data_type.clone(),
format: None,
},
expr_from_projection(&select.projection[0])
);
}
}

#[test]
fn test_duckdb_struct_literal() {
//struct literal syntax https://duckdb.org/docs/sql/data_types/struct#creating-structs
Expand Down
2 changes: 1 addition & 1 deletion tests/sqlparser_redshift.rs
Original file line number Diff line number Diff line change
Expand Up @@ -395,5 +395,5 @@ fn test_parse_nested_quoted_identifier() {
#[test]
fn parse_extract_single_quotes() {
let sql = "SELECT EXTRACT('month' FROM my_timestamp) FROM my_table";
redshift().verified_stmt(&sql);
redshift().verified_stmt(sql);
}