Postgres: Support parenthesized SET options for ALTER TABLE (#1947)

Co-authored-by: Ifeanyi Ubah <ify1992@yahoo.com>
This commit is contained in:
carl 2025-07-23 11:53:17 -04:00 committed by GitHub
parent 2ed2cbe291
commit f49c30feb6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 53 additions and 4 deletions

View file

@ -351,6 +351,16 @@ pub enum AlterTableOperation {
ValidateConstraint {
name: Ident,
},
/// Arbitrary parenthesized `SET` options.
///
/// Example:
/// ```sql
/// SET (scale_factor = 0.01, threshold = 500)`
/// ```
/// [PostgreSQL](https://www.postgresql.org/docs/current/sql-altertable.html)
SetOptionsParens {
options: Vec<SqlOption>,
},
}
/// An `ALTER Policy` (`Statement::AlterPolicy`) operation
@ -791,6 +801,9 @@ impl fmt::Display for AlterTableOperation {
AlterTableOperation::ValidateConstraint { name } => {
write!(f, "VALIDATE CONSTRAINT {name}")
}
AlterTableOperation::SetOptionsParens { options } => {
write!(f, "SET ({})", display_comma_separated(options))
}
}
}
}

View file

@ -1202,6 +1202,9 @@ impl Spanned for AlterTableOperation {
AlterTableOperation::Lock { .. } => Span::empty(),
AlterTableOperation::ReplicaIdentity { .. } => Span::empty(),
AlterTableOperation::ValidateConstraint { name } => name.span,
AlterTableOperation::SetOptionsParens { options } => {
union_spans(options.iter().map(|i| i.span()))
}
}
}
}

View file

@ -9045,17 +9045,22 @@ impl<'a> Parser<'a> {
let name = self.parse_identifier()?;
AlterTableOperation::ValidateConstraint { name }
} else {
let options: Vec<SqlOption> =
let mut options =
self.parse_options_with_keywords(&[Keyword::SET, Keyword::TBLPROPERTIES])?;
if !options.is_empty() {
AlterTableOperation::SetTblProperties {
table_properties: options,
}
} else {
return self.expected(
"ADD, RENAME, PARTITION, SWAP, DROP, REPLICA IDENTITY, or SET TBLPROPERTIES after ALTER TABLE",
options = self.parse_options(Keyword::SET)?;
if !options.is_empty() {
AlterTableOperation::SetOptionsParens { options }
} else {
return self.expected(
"ADD, RENAME, PARTITION, SWAP, DROP, REPLICA IDENTITY, SET, or SET TBLPROPERTIES after ALTER TABLE",
self.peek_token(),
);
);
}
}
};
Ok(operation)

View file

@ -4728,6 +4728,34 @@ fn parse_alter_table() {
}
_ => unreachable!(),
}
let set_storage_parameters = "ALTER TABLE tab SET (autovacuum_vacuum_scale_factor = 0.01, autovacuum_vacuum_threshold = 500)";
match alter_table_op(verified_stmt(set_storage_parameters)) {
AlterTableOperation::SetOptionsParens { options } => {
assert_eq!(
options,
[
SqlOption::KeyValue {
key: Ident {
value: "autovacuum_vacuum_scale_factor".to_string(),
quote_style: None,
span: Span::empty(),
},
value: Expr::Value(test_utils::number("0.01").with_empty_span()),
},
SqlOption::KeyValue {
key: Ident {
value: "autovacuum_vacuum_threshold".to_string(),
quote_style: None,
span: Span::empty(),
},
value: Expr::Value(test_utils::number("500").with_empty_span()),
}
],
);
}
_ => unreachable!(),
}
}
#[test]