Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
81 commits
Select commit Hold shift + click to select a range
34d2881
bigquery: support CREATE TABLE FUNCTION with RETURNS TABLE<...> AS query
lustefaniak Feb 16, 2026
1545cf7
bigquery: support multiple comma-separated tables in UPDATE FROM
lustefaniak Feb 16, 2026
f94ec2d
bigquery: fix SELECT DISTINCT AS STRUCT/VALUE parsing order
lustefaniak Feb 16, 2026
f35c853
bigquery: support wildcard table references (FROM dataset.table_prefix*)
lustefaniak Feb 16, 2026
d378b12
bigquery: support dot field access after CAST expressions
lustefaniak Feb 17, 2026
c76a76c
clickhouse: support EXPLAIN type keywords and key=value options
lustefaniak Feb 17, 2026
2ede8c8
clickhouse: support ALTER TABLE DROP PART 'part_name' syntax
lustefaniak Feb 17, 2026
6f3f317
clickhouse: enable trailing commas in SELECT projection list
lustefaniak Feb 17, 2026
549d1ff
clickhouse: support EXECUTE AS <user> impersonation statement
lustefaniak Feb 17, 2026
f50a5c9
clickhouse: support COLUMNS('pattern') with APPLY/EXCEPT/REPLACE tran…
lustefaniak Feb 17, 2026
c37629b
databricks: support DESCRIBE HISTORY <table> statement
lustefaniak Feb 17, 2026
05c1f3a
databricks: support ${variable} widget placeholder syntax
lustefaniak Feb 17, 2026
127db53
databricks: support backtick-quoted keys and single-quoted strings in…
lustefaniak Feb 17, 2026
3aa6a9c
databricks: support ?:: try cast operator
lustefaniak Feb 17, 2026
9a94e7d
duckdb: support underscore digit separators in numeric literals
lustefaniak Feb 17, 2026
4b8cca8
duckdb: support prefix alias colon syntax in SELECT and FROM
lustefaniak Feb 17, 2026
e6f088a
duckdb: support FROM-first query syntax as shorthand for SELECT *
lustefaniak Feb 17, 2026
5842072
duckdb: support MAP {'key': value} literal constructor syntax
lustefaniak Feb 17, 2026
756f313
duckdb: support FILTER (expr) without WHERE keyword in aggregates
lustefaniak Feb 17, 2026
ef5dc5a
mysql: support := assignment operator in SELECT expressions
lustefaniak Feb 17, 2026
4b0f5d7
mysql: support STRAIGHT_JOIN join type
lustefaniak Feb 17, 2026
36059c7
mysql: support DISTINCTROW as synonym for DISTINCT in SELECT
lustefaniak Feb 17, 2026
3bc7627
mysql: support comma-separated assignments in SET statement
lustefaniak Feb 17, 2026
466c5d1
postgres: support DROP INDEX CONCURRENTLY syntax
lustefaniak Feb 17, 2026
13c8265
postgres: support ?| and ?& JSONB array-key existence operators
lustefaniak Feb 17, 2026
a4a726e
postgres: support OVERLAPS operator for datetime range comparison
lustefaniak Feb 17, 2026
003e181
postgres: support table inheritance wildcard syntax (FROM t1*)
lustefaniak Feb 17, 2026
21e0f69
postgres: support OVER window clause after FILTER in aggregates
lustefaniak Feb 17, 2026
1da4548
redshift: support UNPIVOT for SUPER type iteration as table factor
lustefaniak Feb 17, 2026
8e76efe
redshift: add regression test for CTE combined with UNPIVOT
lustefaniak Feb 17, 2026
3cbd7e3
redshift: support CREATE DATABASE COLLATE syntax
lustefaniak Feb 17, 2026
8059270
redshift: support GROUP/APPLICATION grantee type prefixes in GRANT/RE…
lustefaniak Feb 17, 2026
e01aef7
redshift: add test for column-level GRANT without space before parens
lustefaniak Feb 17, 2026
027eb6d
redshift: support MINUS as synonym for EXCEPT set operator
lustefaniak Feb 17, 2026
17d94f7
redshift: support APPROXIMATE COUNT(DISTINCT x) function prefix
lustefaniak Feb 17, 2026
cc73920
snowflake: unwrap parenthesized function before attaching OVER clause
lustefaniak Feb 17, 2026
77dfd3d
snowflake: support SHOW COLUMNS IN [TABLE|VIEW] <name> syntax
lustefaniak Feb 17, 2026
8e38a31
snowflake: generalize DESCRIBE to support multiple object types
lustefaniak Feb 17, 2026
bbb0f82
snowflake: support ALTER TABLE ADD/DROP ROW ACCESS POLICY
lustefaniak Feb 17, 2026
963624c
snowflake: support CREATE TABLE USING TEMPLATE (query)
lustefaniak Feb 17, 2026
5e4ba12
snowflake: support DESCRIBE FUNCTION with parameter type signatures
lustefaniak Feb 17, 2026
2821597
snowflake: preserve object type keyword in GRANT/REVOKE roundtrip
lustefaniak Feb 17, 2026
9d0881a
snowflake: support comma-separated role list in USE SECONDARY ROLES
lustefaniak Feb 17, 2026
ac6480d
snowflake: support IDENTITY column option as AUTOINCREMENT synonym
lustefaniak Feb 17, 2026
1075d3c
snowflake: support multiple key=value pairs in ALTER SESSION SET
lustefaniak Feb 17, 2026
664a126
snowflake: support key=value options after DESCRIBE TABLE
lustefaniak Feb 17, 2026
75c1648
snowflake: support model!METHOD syntax and {*} object wildcards
lustefaniak Feb 17, 2026
43a2a37
snowflake: support field access on positional placeholders ($1.field)
lustefaniak Feb 17, 2026
6a69912
snowflake: support stage paths with quoted identifiers (@"schema"."st…
lustefaniak Feb 17, 2026
592c444
sqlite: support GLOB pattern matching operator
lustefaniak Feb 17, 2026
652b975
bigquery: support typed array constructors ARRAY<type>[...]
lustefaniak Feb 17, 2026
0c99f1c
bigquery: support MODEL/TABLE keyword prefixes in ML function arguments
lustefaniak Feb 17, 2026
f7bfe8c
bigquery: support chained subscript access col[OFFSET(0)].field[OFFSE…
lustefaniak Feb 17, 2026
31f6eaa
bigquery: support empty STRUCT() constructor with no arguments
lustefaniak Feb 17, 2026
4b029cc
duckdb: support TRIM(expr, characters) comma syntax
lustefaniak Feb 17, 2026
19c2b49
all dialects: support bitwise NOT (~) as unary prefix operator
lustefaniak Feb 17, 2026
5df11b8
databricks: support [*] wildcard subscript in colon JSON paths
lustefaniak Feb 17, 2026
64f3d2e
duckdb: support #N positional column references
lustefaniak Feb 17, 2026
b77991a
duckdb, redshift: accept E'...' escape string literals
lustefaniak Feb 17, 2026
ae8a447
postgres: support -|- range adjacency operator
lustefaniak Feb 17, 2026
56de0a0
postgres: support <-> distance operator
lustefaniak Feb 17, 2026
f1f4000
postgres, redshift: support %s and %(name)s DB-API placeholders
lustefaniak Feb 17, 2026
b2511c7
redshift: support >> and << bitwise shift operators
lustefaniak Feb 17, 2026
d513e73
multi-dialect: fix "Expected literal string" parse errors
lustefaniak Feb 17, 2026
76bf5d4
multi-dialect: fix "Expected end of statement, found: WITH" errors
lustefaniak Feb 17, 2026
313dcbb
bigquery: support ALTER TABLE DROP PRIMARY KEY
lustefaniak Feb 17, 2026
cdd85ec
clickhouse: support {name:Type} query parameters in FROM clause
lustefaniak Feb 17, 2026
0a9efa7
clickhouse: support comma-separated expressions in ARRAY JOIN
lustefaniak Feb 17, 2026
1426671
duckdb: support @ as prefix absolute value operator
lustefaniak Feb 17, 2026
0728b76
redshift: support integer column indexes in DISTKEY and SORTKEY
lustefaniak Feb 17, 2026
6c7183e
snowflake: allow PRIMARY keyword as column name in CREATE TABLE
lustefaniak Feb 17, 2026
ac0bdf1
snowflake: support :1, :2 numeric positional parameters
lustefaniak Feb 17, 2026
00ddf9b
bigquery: support multi-column UNPIVOT with tuple values and IN aliases
lustefaniak Feb 17, 2026
f5a5762
duckdb: add test for @ absolute value with parenthesized argument
lustefaniak Feb 17, 2026
4433228
postgres: support ALTER TABLE SET (key = value) storage parameters
lustefaniak Feb 17, 2026
c33d37b
snowflake: support SET (var1, var2) = (expr1, expr2) tuple assignment
lustefaniak Feb 17, 2026
bf24cd2
bigquery: support bare window name reference in WINDOW clause
lustefaniak Feb 17, 2026
6833cef
clickhouse: support ALTER TABLE DROP PARTITION without parentheses
lustefaniak Feb 17, 2026
27b0b08
fix: resolve all corpus test regressions (14 fixes)
lustefaniak Feb 17, 2026
6f5bccc
fix: resolve CI failures - bigdecimal compat, warnings, and formatting
lustefaniak Feb 17, 2026
6232d31
ci: set RUST_MIN_STACK for recursion limit tests
lustefaniak Feb 17, 2026
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
2 changes: 2 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,5 @@ jobs:
- uses: taiki-e/install-action@nextest
- name: Run tests
run: cargo nextest run --all-features
env:
RUST_MIN_STACK: 8388608
11 changes: 11 additions & 0 deletions src/ast/data_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,10 @@ pub enum DataType {
/// [hive]: https://docs.cloudera.com/cdw-runtime/cloud/impala-sql-reference/topics/impala-struct.html
/// [bigquery]: https://cloud.google.com/bigquery/docs/reference/standard-sql/data-types#struct_type
Struct(Vec<StructField>),
/// TABLE type used in BigQuery for table-valued function return types.
///
/// [bigquery]: https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#create_table_function
Table(Vec<StructField>),
/// MAP<>
DatabricksMap(Vec<StructField>),
/// Nullable - special marker NULL represents in ClickHouse as a data type.
Expand Down Expand Up @@ -536,6 +540,13 @@ impl fmt::Display for DataType {
write!(f, "STRUCT")
}
}
DataType::Table(fields) => {
if !fields.is_empty() {
write!(f, "TABLE<{}>", display_comma_separated(fields))
} else {
write!(f, "TABLE")
}
}
DataType::DatabricksMap(fields) => {
if !fields.is_empty() {
write!(f, "MAP<{}>", display_comma_separated(fields))
Expand Down
52 changes: 52 additions & 0 deletions src/ast/dcl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,58 @@ use sqlparser_derive::{Visit, VisitMut};
use super::{Expr, Ident, Password};
use crate::ast::{display_separated, ObjectName};

/// The type prefix for a grantee in GRANT/REVOKE statements.
///
/// Examples:
/// - `GRANT ... TO GROUP qa_users`
/// - `GRANT ... TO ROLE admin`
/// - `REVOKE ... FROM APPLICATION app`
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum GranteesType {
Role,
User,
Share,
Group,
Application,
}

impl fmt::Display for GranteesType {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
GranteesType::Role => write!(f, "ROLE"),
GranteesType::User => write!(f, "USER"),
GranteesType::Share => write!(f, "SHARE"),
GranteesType::Group => write!(f, "GROUP"),
GranteesType::Application => write!(f, "APPLICATION"),
}
}
}

/// A grantee in a GRANT/REVOKE statement, optionally prefixed with a type keyword.
///
/// Examples:
/// - `qa_users` (no type)
/// - `GROUP qa_users`
/// - `ROLE admin`
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct Grantee {
pub grantee_type: Option<GranteesType>,
pub name: Ident,
}

impl fmt::Display for Grantee {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if let Some(ref grantee_type) = self.grantee_type {
write!(f, "{} ", grantee_type)?;
}
write!(f, "{}", self.name)
}
}

/// An option in `ROLE` statement.
///
/// <https://www.postgresql.org/docs/current/sql-createrole.html>
Expand Down
90 changes: 85 additions & 5 deletions src/ast/ddl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@ pub enum AlterTableOperation {
// See `AttachPartition` for more details
partition: Partition,
},
/// `DROP PART|PARTITION <partition_expr>`
/// Note: this is a ClickHouse-specific operation, please refer to
/// [ClickHouse](https://clickhouse.com/docs/en/sql-reference/statements/alter/partition#drop-partitionpart)
DropPartition { partition: Partition },
/// `DROP PRIMARY KEY`
///
/// Note: this is a MySQL-specific operation.
Expand Down Expand Up @@ -120,10 +124,40 @@ pub enum AlterTableOperation {
/// Note: this is Snowflake specific <https://docs.snowflake.com/en/sql-reference/sql/alter-table>
SwapWith { table_name: ObjectName },

/// `SET OPTIONS(table_set_options_list)`
/// `SET OPTIONS(table_set_options_list)` (BigQuery)
/// or `SET (key = value, ...)` (PostgreSQL storage parameters)
///
/// Note: BigQuery uses `SET OPTIONS(...)`, PostgreSQL uses `SET (...)`
SetOptions {
options: Vec<SqlOption>,
/// Whether the `OPTIONS` keyword is used (BigQuery style)
has_options_keyword: bool,
},

/// `ADD ROW ACCESS POLICY <policy_name> ON (<col_name>, ...)`
///
/// Note: this is Snowflake specific <https://docs.snowflake.com/en/sql-reference/sql/alter-table>
AddRowAccessPolicy { policy: ObjectName, on: Vec<Ident> },

/// `DROP ROW ACCESS POLICY <policy_name>`
///
/// Note: this is Snowflake specific <https://docs.snowflake.com/en/sql-reference/sql/alter-table>
DropRowAccessPolicy { policy: ObjectName },

/// `ADD PROJECTION [IF NOT EXISTS] <name> (<select> [ORDER BY ...]) [WITH SETTINGS (...)]`
///
/// Note: this is a ClickHouse-specific operation
/// <https://clickhouse.com/docs/sql-reference/statements/alter/projection>
AddProjection {
if_not_exists: bool,
projection: TableProjection,
},

/// `DROP PROJECTION [IF EXISTS] <name>`
///
/// Note: this is BigQuery specific <https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#alter_table_set_options_statement>
SetOptions { options: Vec<SqlOption> },
/// Note: this is a ClickHouse-specific operation
/// <https://clickhouse.com/docs/sql-reference/statements/alter/projection>
DropProjection { if_exists: bool, name: Ident },
}

#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
Expand Down Expand Up @@ -187,6 +221,9 @@ impl fmt::Display for AlterTableOperation {
if *cascade { " CASCADE" } else { "" },
)
}
AlterTableOperation::DropPartition { partition } => {
write!(f, "DROP {partition}")
}
AlterTableOperation::DropPrimaryKey => write!(f, "DROP PRIMARY KEY"),
AlterTableOperation::DropColumn {
column_name,
Expand Down Expand Up @@ -240,8 +277,42 @@ impl fmt::Display for AlterTableOperation {
AlterTableOperation::SwapWith { table_name } => {
write!(f, "SWAP WITH {table_name}")
}
AlterTableOperation::SetOptions { options } => {
write!(f, "SET OPTIONS({})", display_comma_separated(options))
AlterTableOperation::SetOptions {
options,
has_options_keyword,
} => {
if *has_options_keyword {
write!(f, "SET OPTIONS({})", display_comma_separated(options))
} else {
write!(f, "SET ({})", display_comma_separated(options))
}
}
AlterTableOperation::AddRowAccessPolicy { policy, on } => {
write!(
f,
"ADD ROW ACCESS POLICY {policy} ON ({})",
display_comma_separated(on)
)
}
AlterTableOperation::DropRowAccessPolicy { policy } => {
write!(f, "DROP ROW ACCESS POLICY {policy}")
}
AlterTableOperation::AddProjection {
if_not_exists,
projection,
} => {
write!(f, "ADD")?;
if *if_not_exists {
write!(f, " IF NOT EXISTS")?;
}
write!(f, " {projection}")
}
AlterTableOperation::DropProjection { if_exists, name } => {
write!(f, "DROP PROJECTION")?;
if *if_exists {
write!(f, " IF EXISTS")?;
}
write!(f, " {name}")
}
}
}
Expand Down Expand Up @@ -1030,6 +1101,8 @@ pub struct TableProjection {
pub name: WithSpan<Ident>,
pub select: Select,
pub order_by: Option<OrderBy>,
/// ClickHouse: `WITH SETTINGS (key = value, ...)`
pub settings: Vec<SqlOption>,
}

impl fmt::Display for TableProjection {
Expand All @@ -1047,6 +1120,13 @@ impl fmt::Display for TableProjection {
}
}
write!(f, ")")?;
if !self.settings.is_empty() {
write!(
f,
" WITH SETTINGS ({})",
display_comma_separated(&self.settings)
)?;
}
Ok(())
}
}
Expand Down
10 changes: 10 additions & 0 deletions src/ast/helpers/stmt_create_table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ pub struct CreateTableBuilder {
pub table_ttl: Option<Expr>,
pub clickhouse_settings: Option<Vec<SqlOption>>,
pub using: Option<ObjectName>,
pub using_template: Option<Box<Expr>>,
pub copy_grants: bool,
}

Expand Down Expand Up @@ -131,6 +132,7 @@ impl CreateTableBuilder {
table_ttl: None,
clickhouse_settings: None,
using: None,
using_template: None,
copy_grants: false,
}
}
Expand Down Expand Up @@ -322,6 +324,11 @@ impl CreateTableBuilder {
self
}

pub fn using_template(mut self, using_template: Option<Box<Expr>>) -> Self {
self.using_template = using_template;
self
}

pub fn copy_grants(mut self, copy_grants: bool) -> Self {
self.copy_grants = copy_grants;
self
Expand Down Expand Up @@ -368,6 +375,7 @@ impl CreateTableBuilder {
table_ttl: self.table_ttl,
clickhouse_settings: self.clickhouse_settings,
using: self.using,
using_template: self.using_template,
copy_grants: self.copy_grants,
}
}
Expand Down Expand Up @@ -420,6 +428,7 @@ impl TryFrom<Statement> for CreateTableBuilder {
table_ttl,
clickhouse_settings,
using,
using_template,
copy_grants,
} => Ok(Self {
or_replace,
Expand Down Expand Up @@ -461,6 +470,7 @@ impl TryFrom<Statement> for CreateTableBuilder {
table_ttl,
clickhouse_settings,
using,
using_template,
copy_grants,
}),
_ => Err(ParserError::ParserError(format!(
Expand Down
Loading