Skip to content
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
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@

[package]
name = "sqlparser-dsql"
description = "SQL parser fork with Aurora DSQL extensions (CREATE INDEX ASYNC, ALTER TABLE ASYNC, order-independent CREATE SEQUENCE, INCLUDE on table constraints). Based on sqlparser 0.62.0."
version = "0.62.2"
description = "SQL parser fork with Aurora DSQL extensions (CREATE INDEX ASYNC, ALTER TABLE ASYNC, ALTER COLUMN SET STORAGE, order-independent CREATE SEQUENCE, INCLUDE on table constraints). Based on sqlparser 0.62.0."
version = "0.62.3"
authors = [
"Apache DataFusion <dev@datafusion.apache.org>",
"Amazon Web Services",
Expand Down
4 changes: 2 additions & 2 deletions examples/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,9 @@ $ cargo run --example cli - [--dialectname]
.expect("failed to read from stdin");
String::from_utf8(buf).expect("stdin content wasn't valid utf8")
} else {
println!("Parsing from file '{}' using {:?}", &filename, dialect);
println!("Parsing from file '{}' using {:?}", filename, dialect);
fs::read_to_string(&filename)
.unwrap_or_else(|_| panic!("Unable to read the file {}", &filename))
.unwrap_or_else(|_| panic!("Unable to read the file {}", filename))
};
let without_bom = if contents.chars().next().unwrap() as u64 != 0xfeff {
contents.as_str()
Expand Down
2 changes: 1 addition & 1 deletion sqlparser_bench/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ authors = ["Dandandan <danielheres@gmail.com>"]
edition = "2018"

[dependencies]
sqlparser = { path = "../" }
sqlparser = { package = "sqlparser-dsql", path = "../" }

[dev-dependencies]
criterion = "0.8"
Expand Down
39 changes: 38 additions & 1 deletion src/ast/ddl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1278,6 +1278,11 @@ pub enum AlterColumnOperation {
},
/// `DROP DEFAULT`
DropDefault,
/// `SET STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN | DEFAULT }`
SetStorage {
/// PostgreSQL column storage strategy.
storage: AlterColumnStorage,
},
/// `[SET DATA] TYPE <data_type> [USING <expr>]`
SetDataType {
/// Target data type for the column.
Expand Down Expand Up @@ -1310,6 +1315,9 @@ impl fmt::Display for AlterColumnOperation {
AlterColumnOperation::DropDefault => {
write!(f, "DROP DEFAULT")
}
AlterColumnOperation::SetStorage { storage } => {
write!(f, "SET STORAGE {storage}")
}
AlterColumnOperation::SetDataType {
data_type,
using,
Expand Down Expand Up @@ -1350,6 +1358,35 @@ impl fmt::Display for AlterColumnOperation {
}
}

/// PostgreSQL column storage strategy used by `ALTER COLUMN ... SET STORAGE`.
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum AlterColumnStorage {
/// No compression or out-of-line storage.
Plain,
/// Out-of-line storage without compression.
External,
/// Compression and out-of-line storage.
Extended,
/// Compression with a preference for in-line storage.
Main,
/// Reset to the data type's default storage strategy.
Default,
}

impl fmt::Display for AlterColumnStorage {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
AlterColumnStorage::Plain => write!(f, "PLAIN"),
AlterColumnStorage::External => write!(f, "EXTERNAL"),
AlterColumnStorage::Extended => write!(f, "EXTENDED"),
AlterColumnStorage::Main => write!(f, "MAIN"),
AlterColumnStorage::Default => write!(f, "DEFAULT"),
}
}
}

/// Representation whether a definition can can contains the KEY or INDEX keywords with the same
/// meaning.
///
Expand Down Expand Up @@ -4772,7 +4809,7 @@ impl fmt::Display for AlterTable {
if self.only {
write!(f, "ONLY ")?;
}
write!(f, "{} ", &self.name)?;
write!(f, "{} ", self.name)?;
if let Some(cluster) = &self.on_cluster {
write!(f, "ON CLUSTER {cluster} ")?;
}
Expand Down
47 changes: 24 additions & 23 deletions src/ast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,28 +60,29 @@ pub use self::dcl::{
SetConfigValue, Use,
};
pub use self::ddl::{
Alignment, AlterCollation, AlterCollationOperation, AlterColumnOperation, AlterConnectorOwner,
AlterFunction, AlterFunctionAction, AlterFunctionKind, AlterFunctionOperation,
AlterIndexOperation, AlterOperator, AlterOperatorClass, AlterOperatorClassOperation,
AlterOperatorFamily, AlterOperatorFamilyOperation, AlterOperatorOperation, AlterPolicy,
AlterPolicyOperation, AlterSchema, AlterSchemaOperation, AlterTable, AlterTableAlgorithm,
AlterTableLock, AlterTableOperation, AlterTableType, AlterType, AlterTypeAddValue,
AlterTypeAddValuePosition, AlterTypeOperation, AlterTypeRename, AlterTypeRenameValue,
ClusteredBy, ColumnDef, ColumnOption, ColumnOptionDef, ColumnOptions, ColumnPolicy,
ColumnPolicyProperty, ConstraintCharacteristics, CreateCollation, CreateCollationDefinition,
CreateConnector, CreateDomain, CreateExtension, CreateFunction, CreateIndex, CreateOperator,
CreateOperatorClass, CreateOperatorFamily, CreatePolicy, CreatePolicyCommand, CreatePolicyType,
CreateTable, CreateTrigger, CreateView, Deduplicate, DeferrableInitial, DistStyle,
DropBehavior, DropExtension, DropFunction, DropOperator, DropOperatorClass, DropOperatorFamily,
DropOperatorSignature, DropPolicy, DropTrigger, ForValues, FunctionReturnType, GeneratedAs,
GeneratedExpressionMode, IdentityParameters, IdentityProperty, IdentityPropertyFormatKind,
IdentityPropertyKind, IdentityPropertyOrder, IndexColumn, IndexOption, IndexType,
KeyOrIndexDisplay, Msck, NullsDistinctOption, OperatorArgTypes, OperatorClassItem,
OperatorFamilyDropItem, OperatorFamilyItem, OperatorOption, OperatorPurpose, Owner, Partition,
PartitionBoundValue, ProcedureParam, ReferentialAction, RenameTableNameKind, ReplicaIdentity,
TagsColumnOption, TriggerObjectKind, Truncate, UserDefinedTypeCompositeAttributeDef,
UserDefinedTypeInternalLength, UserDefinedTypeRangeOption, UserDefinedTypeRepresentation,
UserDefinedTypeSqlDefinitionOption, UserDefinedTypeStorage, ViewColumnDef, WithData,
Alignment, AlterCollation, AlterCollationOperation, AlterColumnOperation, AlterColumnStorage,
AlterConnectorOwner, AlterFunction, AlterFunctionAction, AlterFunctionKind,
AlterFunctionOperation, AlterIndexOperation, AlterOperator, AlterOperatorClass,
AlterOperatorClassOperation, AlterOperatorFamily, AlterOperatorFamilyOperation,
AlterOperatorOperation, AlterPolicy, AlterPolicyOperation, AlterSchema, AlterSchemaOperation,
AlterTable, AlterTableAlgorithm, AlterTableLock, AlterTableOperation, AlterTableType,
AlterType, AlterTypeAddValue, AlterTypeAddValuePosition, AlterTypeOperation, AlterTypeRename,
AlterTypeRenameValue, ClusteredBy, ColumnDef, ColumnOption, ColumnOptionDef, ColumnOptions,
ColumnPolicy, ColumnPolicyProperty, ConstraintCharacteristics, CreateCollation,
CreateCollationDefinition, CreateConnector, CreateDomain, CreateExtension, CreateFunction,
CreateIndex, CreateOperator, CreateOperatorClass, CreateOperatorFamily, CreatePolicy,
CreatePolicyCommand, CreatePolicyType, CreateTable, CreateTrigger, CreateView, Deduplicate,
DeferrableInitial, DistStyle, DropBehavior, DropExtension, DropFunction, DropOperator,
DropOperatorClass, DropOperatorFamily, DropOperatorSignature, DropPolicy, DropTrigger,
ForValues, FunctionReturnType, GeneratedAs, GeneratedExpressionMode, IdentityParameters,
IdentityProperty, IdentityPropertyFormatKind, IdentityPropertyKind, IdentityPropertyOrder,
IndexColumn, IndexOption, IndexType, KeyOrIndexDisplay, Msck, NullsDistinctOption,
OperatorArgTypes, OperatorClassItem, OperatorFamilyDropItem, OperatorFamilyItem,
OperatorOption, OperatorPurpose, Owner, Partition, PartitionBoundValue, ProcedureParam,
ReferentialAction, RenameTableNameKind, ReplicaIdentity, TagsColumnOption, TriggerObjectKind,
Truncate, UserDefinedTypeCompositeAttributeDef, UserDefinedTypeInternalLength,
UserDefinedTypeRangeOption, UserDefinedTypeRepresentation, UserDefinedTypeSqlDefinitionOption,
UserDefinedTypeStorage, ViewColumnDef, WithData,
};
pub use self::dml::{
Delete, Insert, Merge, MergeAction, MergeClause, MergeClauseKind, MergeInsertExpr,
Expand Down Expand Up @@ -11745,7 +11746,7 @@ impl fmt::Display for AlterUser {
let has_props = !self.set_props.options.is_empty();
if has_props {
write!(f, " SET")?;
write!(f, " {}", &self.set_props)?;
write!(f, " {}", self.set_props)?;
}
if !self.unset_props.is_empty() {
write!(f, " UNSET {}", display_comma_separated(&self.unset_props))?;
Expand Down
2 changes: 1 addition & 1 deletion src/ast/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3545,7 +3545,7 @@ pub struct LockClause {

impl fmt::Display for LockClause {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "FOR {}", &self.lock_type)?;
write!(f, "FOR {}", self.lock_type)?;
if let Some(ref of) = self.of {
write!(f, " OF {of}")?;
}
Expand Down
2 changes: 2 additions & 0 deletions src/ast/spans.rs
Original file line number Diff line number Diff line change
Expand Up @@ -891,6 +891,7 @@ impl Spanned for Analyze {
/// - [AlterColumnOperation::SetNotNull]
/// - [AlterColumnOperation::DropNotNull]
/// - [AlterColumnOperation::DropDefault]
/// - [AlterColumnOperation::SetStorage]
/// - [AlterColumnOperation::AddGenerated]
impl Spanned for AlterColumnOperation {
fn span(&self) -> Span {
Expand All @@ -899,6 +900,7 @@ impl Spanned for AlterColumnOperation {
AlterColumnOperation::DropNotNull => Span::empty(),
AlterColumnOperation::SetDefault { value } => value.span(),
AlterColumnOperation::DropDefault => Span::empty(),
AlterColumnOperation::SetStorage { .. } => Span::empty(),
AlterColumnOperation::SetDataType {
data_type: _,
using,
Expand Down
33 changes: 27 additions & 6 deletions src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4744,7 +4744,7 @@ impl<'a> Parser<'a> {
if self.parse_keyword(expected) {
Ok(self.get_current_token().clone())
} else {
self.expected_ref(format!("{:?}", &expected).as_str(), self.peek_token_ref())
self.expected_ref(format!("{:?}", expected).as_str(), self.peek_token_ref())
}
}

Expand All @@ -4757,7 +4757,7 @@ impl<'a> Parser<'a> {
if self.parse_keyword(expected) {
Ok(())
} else {
self.expected_ref(format!("{:?}", &expected).as_str(), self.peek_token_ref())
self.expected_ref(format!("{:?}", expected).as_str(), self.peek_token_ref())
}
}

Expand Down Expand Up @@ -10611,6 +10611,27 @@ impl<'a> Parser<'a> {
}
} else if self.parse_keywords(&[Keyword::DROP, Keyword::DEFAULT]) {
AlterColumnOperation::DropDefault {}
} else if self.parse_keywords(&[Keyword::SET, Keyword::STORAGE]) {
let storage = match self.parse_one_of_keywords(&[
Keyword::PLAIN,
Keyword::EXTERNAL,
Keyword::EXTENDED,
Keyword::MAIN,
Keyword::DEFAULT,
]) {
Some(Keyword::PLAIN) => AlterColumnStorage::Plain,
Some(Keyword::EXTERNAL) => AlterColumnStorage::External,
Some(Keyword::EXTENDED) => AlterColumnStorage::Extended,
Some(Keyword::MAIN) => AlterColumnStorage::Main,
Some(Keyword::DEFAULT) => AlterColumnStorage::Default,
_ => {
return self.expected_ref(
"storage value (PLAIN, EXTERNAL, EXTENDED, MAIN, or DEFAULT)",
self.peek_token_ref(),
)
}
};
AlterColumnOperation::SetStorage { storage }
} else if self.parse_keywords(&[Keyword::SET, Keyword::DATA, Keyword::TYPE]) {
self.parse_set_data_type(true)?
} else if self.parse_keyword(Keyword::TYPE) {
Expand Down Expand Up @@ -10640,9 +10661,9 @@ impl<'a> Parser<'a> {
}
} else {
let message = if is_postgresql {
"SET/DROP NOT NULL, SET DEFAULT, SET DATA TYPE, or ADD GENERATED after ALTER COLUMN"
"SET/DROP NOT NULL, SET DEFAULT, SET STORAGE, SET DATA TYPE, or ADD GENERATED after ALTER COLUMN"
} else {
"SET/DROP NOT NULL, SET DEFAULT, or SET DATA TYPE after ALTER COLUMN"
"SET/DROP NOT NULL, SET DEFAULT, SET STORAGE, or SET DATA TYPE after ALTER COLUMN"
};

return self.expected_ref(message, self.peek_token_ref());
Expand Down Expand Up @@ -13437,7 +13458,7 @@ impl<'a> Parser<'a> {
}
Token::EOF => break,
token => {
return Err(ParserError::ParserError(format!(
Err(ParserError::ParserError(format!(
"Unexpected token in identifier: {token}"
)))?;
}
Expand Down Expand Up @@ -16696,7 +16717,7 @@ impl<'a> Parser<'a> {
where_clause = Some(self.parse_expr()?);
} else {
let tok = self.peek_token_ref();
return parser_err!(
parser_err!(
format!(
"Expected one of DIMENSIONS, METRICS, FACTS or WHERE, got {}",
tok.token
Expand Down
6 changes: 3 additions & 3 deletions tests/sqlparser_common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1719,7 +1719,7 @@ fn parse_json_ops_without_colon() {
];

for (str_op, op, dialects) in binary_ops {
let select = dialects.verified_only_select(&format!("SELECT a {} b", &str_op));
let select = dialects.verified_only_select(&format!("SELECT a {} b", str_op));
assert_eq!(
SelectItem::UnnamedExpr(Expr::BinaryOp {
left: Box::new(Expr::Identifier(Ident::new("a"))),
Expand Down Expand Up @@ -2415,7 +2415,7 @@ fn parse_bitwise_ops() {
];

for (str_op, op, dialects) in bitwise_ops {
let select = dialects.verified_only_select(&format!("SELECT a {} b", &str_op));
let select = dialects.verified_only_select(&format!("SELECT a {} b", str_op));
assert_eq!(
SelectItem::UnnamedExpr(Expr::BinaryOp {
left: Box::new(Expr::Identifier(Ident::new("a"))),
Expand Down Expand Up @@ -18770,7 +18770,7 @@ fn parse_generic_unary_ops() {
("+", UnaryOperator::Plus),
];
for (str_op, op) in unary_ops {
let select = verified_only_select(&format!("SELECT {}expr", &str_op));
let select = verified_only_select(&format!("SELECT {}expr", str_op));
assert_eq!(
UnnamedExpr(UnaryOp {
op: *op,
Expand Down
32 changes: 28 additions & 4 deletions tests/sqlparser_postgres.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1085,6 +1085,31 @@ fn parse_alter_table_alter_column() {
}
}

#[test]
fn parse_alter_table_alter_column_set_storage() {
for storage in ["PLAIN", "EXTERNAL", "EXTENDED", "MAIN", "DEFAULT"] {
pg_and_generic().verified_stmt(&format!(
"ALTER TABLE tab ALTER COLUMN payload SET STORAGE {storage}"
));
}

match alter_table_op(pg().one_statement_parses_to(
"ALTER TABLE tab ALTER payload SET STORAGE DEFAULT",
"ALTER TABLE tab ALTER COLUMN payload SET STORAGE DEFAULT",
)) {
AlterTableOperation::AlterColumn { column_name, op } => {
assert_eq!("payload", column_name.to_string());
assert_eq!(
op,
AlterColumnOperation::SetStorage {
storage: AlterColumnStorage::Default,
}
);
}
_ => unreachable!(),
}
}

#[test]
fn parse_alter_table_alter_column_add_generated() {
pg_and_generic()
Expand Down Expand Up @@ -2505,7 +2530,7 @@ fn parse_pg_unary_ops() {
("@", UnaryOperator::PGAbs),
];
for (str_op, op) in pg_unary_ops {
let select = pg().verified_only_select(&format!("SELECT {}a", &str_op));
let select = pg().verified_only_select(&format!("SELECT {}a", str_op));
assert_eq!(
SelectItem::UnnamedExpr(Expr::UnaryOp {
op: *op,
Expand All @@ -2521,7 +2546,7 @@ fn parse_pg_postfix_factorial() {
let postfix_factorial = &[("!", UnaryOperator::PGPostfixFactorial)];

for (str_op, op) in postfix_factorial {
let select = pg().verified_only_select(&format!("SELECT a{}", &str_op));
let select = pg().verified_only_select(&format!("SELECT a{}", str_op));
assert_eq!(
SelectItem::UnnamedExpr(Expr::UnaryOp {
op: *op,
Expand Down Expand Up @@ -7251,8 +7276,7 @@ fn parse_alter_table_async_validate_constraint() {
}

// ASYNC composes with IF EXISTS and ONLY.
pg_and_generic()
.verified_stmt("ALTER TABLE ASYNC IF EXISTS ONLY foo VALIDATE CONSTRAINT bar");
pg_and_generic().verified_stmt("ALTER TABLE ASYNC IF EXISTS ONLY foo VALIDATE CONSTRAINT bar");
}

#[test]
Expand Down
Loading