Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit cb7a51e

Browse files
feat: Add ALTER SCHEMA support (#1980)
1 parent 56848b0 commit cb7a51e

File tree

5 files changed

+164
-11
lines changed

5 files changed

+164
-11
lines changed

‎src/ast/ddl.rs‎

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3080,6 +3080,48 @@ impl fmt::Display for CreateConnector {
30803080
}
30813081
}
30823082

3083+
/// An `ALTER SCHEMA` (`Statement::AlterSchema`) operation.
3084+
///
3085+
/// See [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#alter_schema_collate_statement)
3086+
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
3087+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3088+
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
3089+
pub enum AlterSchemaOperation {
3090+
SetDefaultCollate {
3091+
collate: Expr,
3092+
},
3093+
AddReplica {
3094+
replica: Ident,
3095+
options: Option<Vec<SqlOption>>,
3096+
},
3097+
DropReplica {
3098+
replica: Ident,
3099+
},
3100+
SetOptionsParens {
3101+
options: Vec<SqlOption>,
3102+
},
3103+
}
3104+
3105+
impl fmt::Display for AlterSchemaOperation {
3106+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3107+
match self {
3108+
AlterSchemaOperation::SetDefaultCollate { collate } => {
3109+
write!(f, "SET DEFAULT COLLATE {collate}")
3110+
}
3111+
AlterSchemaOperation::AddReplica { replica, options } => {
3112+
write!(f, "ADD REPLICA {replica}")?;
3113+
if let Some(options) = options {
3114+
write!(f, " OPTIONS ({})", display_comma_separated(options))?;
3115+
}
3116+
Ok(())
3117+
}
3118+
AlterSchemaOperation::DropReplica { replica } => write!(f, "DROP REPLICA {replica}"),
3119+
AlterSchemaOperation::SetOptionsParens { options } => {
3120+
write!(f, "SET OPTIONS ({})", display_comma_separated(options))
3121+
}
3122+
}
3123+
}
3124+
}
30833125
/// `RenameTableNameKind` is the kind used in an `ALTER TABLE _ RENAME` statement.
30843126
///
30853127
/// Note: [MySQL] is the only database that supports the AS keyword for this operation.
@@ -3102,6 +3144,30 @@ impl fmt::Display for RenameTableNameKind {
31023144
}
31033145
}
31043146

3147+
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
3148+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3149+
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
3150+
pub struct AlterSchema {
3151+
pub name: ObjectName,
3152+
pub if_exists: bool,
3153+
pub operations: Vec<AlterSchemaOperation>,
3154+
}
3155+
3156+
impl fmt::Display for AlterSchema {
3157+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3158+
write!(f, "ALTER SCHEMA ")?;
3159+
if self.if_exists {
3160+
write!(f, "IF EXISTS ")?;
3161+
}
3162+
write!(f, "{}", self.name)?;
3163+
for operation in &self.operations {
3164+
write!(f, " {operation}")?;
3165+
}
3166+
3167+
Ok(())
3168+
}
3169+
}
3170+
31053171
impl Spanned for RenameTableNameKind {
31063172
fn span(&self) -> Span {
31073173
match self {

‎src/ast/mod.rs‎

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -59,16 +59,17 @@ pub use self::dcl::{
5959
};
6060
pub use self::ddl::{
6161
AlterColumnOperation, AlterConnectorOwner, AlterIndexOperation, AlterPolicyOperation,
62-
AlterTableAlgorithm, AlterTableLock, AlterTableOperation, AlterType, AlterTypeAddValue,
63-
AlterTypeAddValuePosition, AlterTypeOperation, AlterTypeRename, AlterTypeRenameValue,
64-
ClusteredBy, ColumnDef, ColumnOption, ColumnOptionDef, ColumnOptions, ColumnPolicy,
65-
ColumnPolicyProperty, ConstraintCharacteristics, CreateConnector, CreateDomain, CreateFunction,
66-
CreateIndex, CreateTable, Deduplicate, DeferrableInitial, DropBehavior, GeneratedAs,
67-
GeneratedExpressionMode, IdentityParameters, IdentityProperty, IdentityPropertyFormatKind,
68-
IdentityPropertyKind, IdentityPropertyOrder, IndexColumn, IndexOption, IndexType,
69-
KeyOrIndexDisplay, NullsDistinctOption, Owner, Partition, ProcedureParam, ReferentialAction,
70-
RenameTableNameKind, ReplicaIdentity, TableConstraint, TagsColumnOption,
71-
UserDefinedTypeCompositeAttributeDef, UserDefinedTypeRepresentation, ViewColumnDef,
62+
AlterSchema, AlterSchemaOperation, AlterTableAlgorithm, AlterTableLock, AlterTableOperation,
63+
AlterType, AlterTypeAddValue, AlterTypeAddValuePosition, AlterTypeOperation, AlterTypeRename,
64+
AlterTypeRenameValue, ClusteredBy, ColumnDef, ColumnOption, ColumnOptionDef, ColumnOptions,
65+
ColumnPolicy, ColumnPolicyProperty, ConstraintCharacteristics, CreateConnector, CreateDomain,
66+
CreateFunction, CreateIndex, CreateTable, Deduplicate, DeferrableInitial, DropBehavior,
67+
GeneratedAs, GeneratedExpressionMode, IdentityParameters, IdentityProperty,
68+
IdentityPropertyFormatKind, IdentityPropertyKind, IdentityPropertyOrder, IndexColumn,
69+
IndexOption, IndexType, KeyOrIndexDisplay, NullsDistinctOption, Owner, Partition,
70+
ProcedureParam, ReferentialAction, RenameTableNameKind, ReplicaIdentity, TableConstraint,
71+
TagsColumnOption, UserDefinedTypeCompositeAttributeDef, UserDefinedTypeRepresentation,
72+
ViewColumnDef,
7273
};
7374
pub use self::dml::{Delete, Insert};
7475
pub use self::operator::{BinaryOperator, UnaryOperator};
@@ -3388,6 +3389,11 @@ pub enum Statement {
33883389
end_token: AttachedToken,
33893390
},
33903391
/// ```sql
3392+
/// ALTER SCHEMA
3393+
/// ```
3394+
/// See [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#alter_schema_collate_statement)
3395+
AlterSchema(AlterSchema),
3396+
/// ```sql
33913397
/// ALTER INDEX
33923398
/// ```
33933399
AlterIndex {
@@ -6336,6 +6342,7 @@ impl fmt::Display for Statement {
63366342
Statement::Remove(command) => write!(f, "REMOVE {command}"),
63376343
Statement::ExportData(e) => write!(f, "{e}"),
63386344
Statement::CreateUser(s) => write!(f, "{s}"),
6345+
Statement::AlterSchema(s) => write!(f, "{s}"),
63396346
}
63406347
}
63416348
}

‎src/ast/spans.rs‎

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@
1515
// specific language governing permissions and limitations
1616
// under the License.
1717

18-
use crate::ast::{query::SelectItemQualifiedWildcardKind, ColumnOptions, ExportData, TypedString};
18+
use crate::ast::{
19+
ddl::AlterSchema, query::SelectItemQualifiedWildcardKind, AlterSchemaOperation, ColumnOptions,
20+
ExportData, TypedString,
21+
};
1922
use core::iter;
2023

2124
use crate::tokenizer::Span;
@@ -548,6 +551,7 @@ impl Spanned for Statement {
548551
.chain(connection.iter().map(|i| i.span())),
549552
),
550553
Statement::CreateUser(..) => Span::empty(),
554+
Statement::AlterSchema(s) => s.span(),
551555
}
552556
}
553557
}
@@ -2387,6 +2391,30 @@ impl Spanned for OpenStatement {
23872391
}
23882392
}
23892393

2394+
impl Spanned for AlterSchemaOperation {
2395+
fn span(&self) -> Span {
2396+
match self {
2397+
AlterSchemaOperation::SetDefaultCollate { collate } => collate.span(),
2398+
AlterSchemaOperation::AddReplica { replica, options } => union_spans(
2399+
core::iter::once(replica.span)
2400+
.chain(options.iter().flat_map(|i| i.iter().map(|i| i.span()))),
2401+
),
2402+
AlterSchemaOperation::DropReplica { replica } => replica.span,
2403+
AlterSchemaOperation::SetOptionsParens { options } => {
2404+
union_spans(options.iter().map(|i| i.span()))
2405+
}
2406+
}
2407+
}
2408+
}
2409+
2410+
impl Spanned for AlterSchema {
2411+
fn span(&self) -> Span {
2412+
union_spans(
2413+
core::iter::once(self.name.span()).chain(self.operations.iter().map(|i| i.span())),
2414+
)
2415+
}
2416+
}
2417+
23902418
#[cfg(test)]
23912419
pub mod tests {
23922420
use crate::dialect::{Dialect, GenericDialect, SnowflakeDialect};

‎src/parser/mod.rs‎

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9247,8 +9247,14 @@ impl<'a> Parser<'a> {
92479247
Keyword::POLICY,
92489248
Keyword::CONNECTOR,
92499249
Keyword::ICEBERG,
9250+
Keyword::SCHEMA,
92509251
])?;
92519252
match object_type {
9253+
Keyword::SCHEMA => {
9254+
self.prev_token();
9255+
self.prev_token();
9256+
self.parse_alter_schema()
9257+
}
92529258
Keyword::VIEW => self.parse_alter_view(),
92539259
Keyword::TYPE => self.parse_alter_type(),
92549260
Keyword::TABLE => self.parse_alter_table(false),
@@ -9387,6 +9393,40 @@ impl<'a> Parser<'a> {
93879393
}
93889394
}
93899395

9396+
// Parse a [Statement::AlterSchema]
9397+
// ALTER SCHEMA [ IF EXISTS ] schema_name
9398+
pub fn parse_alter_schema(&mut self) -> Result<Statement, ParserError> {
9399+
self.expect_keywords(&[Keyword::ALTER, Keyword::SCHEMA])?;
9400+
let if_exists = self.parse_keywords(&[Keyword::IF, Keyword::EXISTS]);
9401+
let name = self.parse_object_name(false)?;
9402+
let operation = if self.parse_keywords(&[Keyword::SET, Keyword::OPTIONS]) {
9403+
self.prev_token();
9404+
let options = self.parse_options(Keyword::OPTIONS)?;
9405+
AlterSchemaOperation::SetOptionsParens { options }
9406+
} else if self.parse_keywords(&[Keyword::SET, Keyword::DEFAULT, Keyword::COLLATE]) {
9407+
let collate = self.parse_expr()?;
9408+
AlterSchemaOperation::SetDefaultCollate { collate }
9409+
} else if self.parse_keywords(&[Keyword::ADD, Keyword::REPLICA]) {
9410+
let replica = self.parse_identifier()?;
9411+
let options = if self.peek_keyword(Keyword::OPTIONS) {
9412+
Some(self.parse_options(Keyword::OPTIONS)?)
9413+
} else {
9414+
None
9415+
};
9416+
AlterSchemaOperation::AddReplica { replica, options }
9417+
} else if self.parse_keywords(&[Keyword::DROP, Keyword::REPLICA]) {
9418+
let replica = self.parse_identifier()?;
9419+
AlterSchemaOperation::DropReplica { replica }
9420+
} else {
9421+
return self.expected_ref("ALTER SCHEMA operation", self.peek_token_ref());
9422+
};
9423+
Ok(Statement::AlterSchema(AlterSchema {
9424+
name,
9425+
if_exists,
9426+
operations: vec![operation],
9427+
}))
9428+
}
9429+
93909430
/// Parse a `CALL procedure_name(arg1, arg2, ...)`
93919431
/// or `CALL procedure_name` statement
93929432
pub fn parse_call(&mut self) -> Result<Statement, ParserError> {

‎tests/sqlparser_bigquery.rs‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2825,3 +2825,15 @@ fn test_begin_transaction() {
28252825
fn test_begin_statement() {
28262826
bigquery().verified_stmt("BEGIN");
28272827
}
2828+
2829+
#[test]
2830+
fn test_alter_schema() {
2831+
bigquery_and_generic().verified_stmt("ALTER SCHEMA mydataset SET DEFAULT COLLATE 'und:ci'");
2832+
bigquery_and_generic().verified_stmt("ALTER SCHEMA mydataset ADD REPLICA 'us'");
2833+
bigquery_and_generic()
2834+
.verified_stmt("ALTER SCHEMA mydataset ADD REPLICA 'us' OPTIONS (location = 'us')");
2835+
bigquery_and_generic().verified_stmt("ALTER SCHEMA mydataset DROP REPLICA 'us'");
2836+
bigquery_and_generic().verified_stmt("ALTER SCHEMA mydataset SET OPTIONS (location = 'us')");
2837+
bigquery_and_generic()
2838+
.verified_stmt("ALTER SCHEMA IF EXISTS mydataset SET OPTIONS (location = 'us')");
2839+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /