mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-08-22 06:54:07 +00:00
feat: Add ALTER SCHEMA
support (#1980)
Some checks are pending
license / Release Audit Tool (RAT) (push) Waiting to run
Rust / codestyle (push) Waiting to run
Rust / lint (push) Waiting to run
Rust / benchmark-lint (push) Waiting to run
Rust / compile (push) Waiting to run
Rust / docs (push) Waiting to run
Rust / compile-no-std (push) Waiting to run
Rust / test (beta) (push) Waiting to run
Rust / test (nightly) (push) Waiting to run
Rust / test (stable) (push) Waiting to run
Some checks are pending
license / Release Audit Tool (RAT) (push) Waiting to run
Rust / codestyle (push) Waiting to run
Rust / lint (push) Waiting to run
Rust / benchmark-lint (push) Waiting to run
Rust / compile (push) Waiting to run
Rust / docs (push) Waiting to run
Rust / compile-no-std (push) Waiting to run
Rust / test (beta) (push) Waiting to run
Rust / test (nightly) (push) Waiting to run
Rust / test (stable) (push) Waiting to run
This commit is contained in:
parent
56848b03dd
commit
cb7a51e85f
5 changed files with 164 additions and 11 deletions
|
@ -3080,6 +3080,48 @@ impl fmt::Display for CreateConnector {
|
|||
}
|
||||
}
|
||||
|
||||
/// An `ALTER SCHEMA` (`Statement::AlterSchema`) operation.
|
||||
///
|
||||
/// See [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#alter_schema_collate_statement)
|
||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
|
||||
pub enum AlterSchemaOperation {
|
||||
SetDefaultCollate {
|
||||
collate: Expr,
|
||||
},
|
||||
AddReplica {
|
||||
replica: Ident,
|
||||
options: Option<Vec<SqlOption>>,
|
||||
},
|
||||
DropReplica {
|
||||
replica: Ident,
|
||||
},
|
||||
SetOptionsParens {
|
||||
options: Vec<SqlOption>,
|
||||
},
|
||||
}
|
||||
|
||||
impl fmt::Display for AlterSchemaOperation {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
AlterSchemaOperation::SetDefaultCollate { collate } => {
|
||||
write!(f, "SET DEFAULT COLLATE {collate}")
|
||||
}
|
||||
AlterSchemaOperation::AddReplica { replica, options } => {
|
||||
write!(f, "ADD REPLICA {replica}")?;
|
||||
if let Some(options) = options {
|
||||
write!(f, " OPTIONS ({})", display_comma_separated(options))?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
AlterSchemaOperation::DropReplica { replica } => write!(f, "DROP REPLICA {replica}"),
|
||||
AlterSchemaOperation::SetOptionsParens { options } => {
|
||||
write!(f, "SET OPTIONS ({})", display_comma_separated(options))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/// `RenameTableNameKind` is the kind used in an `ALTER TABLE _ RENAME` statement.
|
||||
///
|
||||
/// Note: [MySQL] is the only database that supports the AS keyword for this operation.
|
||||
|
@ -3102,6 +3144,30 @@ impl fmt::Display for RenameTableNameKind {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
|
||||
pub struct AlterSchema {
|
||||
pub name: ObjectName,
|
||||
pub if_exists: bool,
|
||||
pub operations: Vec<AlterSchemaOperation>,
|
||||
}
|
||||
|
||||
impl fmt::Display for AlterSchema {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "ALTER SCHEMA ")?;
|
||||
if self.if_exists {
|
||||
write!(f, "IF EXISTS ")?;
|
||||
}
|
||||
write!(f, "{}", self.name)?;
|
||||
for operation in &self.operations {
|
||||
write!(f, " {operation}")?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Spanned for RenameTableNameKind {
|
||||
fn span(&self) -> Span {
|
||||
match self {
|
||||
|
|
|
@ -59,16 +59,17 @@ pub use self::dcl::{
|
|||
};
|
||||
pub use self::ddl::{
|
||||
AlterColumnOperation, AlterConnectorOwner, AlterIndexOperation, AlterPolicyOperation,
|
||||
AlterTableAlgorithm, AlterTableLock, AlterTableOperation, AlterType, AlterTypeAddValue,
|
||||
AlterTypeAddValuePosition, AlterTypeOperation, AlterTypeRename, AlterTypeRenameValue,
|
||||
ClusteredBy, ColumnDef, ColumnOption, ColumnOptionDef, ColumnOptions, ColumnPolicy,
|
||||
ColumnPolicyProperty, ConstraintCharacteristics, CreateConnector, CreateDomain, CreateFunction,
|
||||
CreateIndex, CreateTable, Deduplicate, DeferrableInitial, DropBehavior, GeneratedAs,
|
||||
GeneratedExpressionMode, IdentityParameters, IdentityProperty, IdentityPropertyFormatKind,
|
||||
IdentityPropertyKind, IdentityPropertyOrder, IndexColumn, IndexOption, IndexType,
|
||||
KeyOrIndexDisplay, NullsDistinctOption, Owner, Partition, ProcedureParam, ReferentialAction,
|
||||
RenameTableNameKind, ReplicaIdentity, TableConstraint, TagsColumnOption,
|
||||
UserDefinedTypeCompositeAttributeDef, UserDefinedTypeRepresentation, ViewColumnDef,
|
||||
AlterSchema, AlterSchemaOperation, AlterTableAlgorithm, AlterTableLock, AlterTableOperation,
|
||||
AlterType, AlterTypeAddValue, AlterTypeAddValuePosition, AlterTypeOperation, AlterTypeRename,
|
||||
AlterTypeRenameValue, ClusteredBy, ColumnDef, ColumnOption, ColumnOptionDef, ColumnOptions,
|
||||
ColumnPolicy, ColumnPolicyProperty, ConstraintCharacteristics, CreateConnector, CreateDomain,
|
||||
CreateFunction, CreateIndex, CreateTable, Deduplicate, DeferrableInitial, DropBehavior,
|
||||
GeneratedAs, GeneratedExpressionMode, IdentityParameters, IdentityProperty,
|
||||
IdentityPropertyFormatKind, IdentityPropertyKind, IdentityPropertyOrder, IndexColumn,
|
||||
IndexOption, IndexType, KeyOrIndexDisplay, NullsDistinctOption, Owner, Partition,
|
||||
ProcedureParam, ReferentialAction, RenameTableNameKind, ReplicaIdentity, TableConstraint,
|
||||
TagsColumnOption, UserDefinedTypeCompositeAttributeDef, UserDefinedTypeRepresentation,
|
||||
ViewColumnDef,
|
||||
};
|
||||
pub use self::dml::{Delete, Insert};
|
||||
pub use self::operator::{BinaryOperator, UnaryOperator};
|
||||
|
@ -3388,6 +3389,11 @@ pub enum Statement {
|
|||
end_token: AttachedToken,
|
||||
},
|
||||
/// ```sql
|
||||
/// ALTER SCHEMA
|
||||
/// ```
|
||||
/// See [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#alter_schema_collate_statement)
|
||||
AlterSchema(AlterSchema),
|
||||
/// ```sql
|
||||
/// ALTER INDEX
|
||||
/// ```
|
||||
AlterIndex {
|
||||
|
@ -6336,6 +6342,7 @@ impl fmt::Display for Statement {
|
|||
Statement::Remove(command) => write!(f, "REMOVE {command}"),
|
||||
Statement::ExportData(e) => write!(f, "{e}"),
|
||||
Statement::CreateUser(s) => write!(f, "{s}"),
|
||||
Statement::AlterSchema(s) => write!(f, "{s}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,10 @@
|
|||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
use crate::ast::{query::SelectItemQualifiedWildcardKind, ColumnOptions, ExportData, TypedString};
|
||||
use crate::ast::{
|
||||
ddl::AlterSchema, query::SelectItemQualifiedWildcardKind, AlterSchemaOperation, ColumnOptions,
|
||||
ExportData, TypedString,
|
||||
};
|
||||
use core::iter;
|
||||
|
||||
use crate::tokenizer::Span;
|
||||
|
@ -548,6 +551,7 @@ impl Spanned for Statement {
|
|||
.chain(connection.iter().map(|i| i.span())),
|
||||
),
|
||||
Statement::CreateUser(..) => Span::empty(),
|
||||
Statement::AlterSchema(s) => s.span(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2387,6 +2391,30 @@ impl Spanned for OpenStatement {
|
|||
}
|
||||
}
|
||||
|
||||
impl Spanned for AlterSchemaOperation {
|
||||
fn span(&self) -> Span {
|
||||
match self {
|
||||
AlterSchemaOperation::SetDefaultCollate { collate } => collate.span(),
|
||||
AlterSchemaOperation::AddReplica { replica, options } => union_spans(
|
||||
core::iter::once(replica.span)
|
||||
.chain(options.iter().flat_map(|i| i.iter().map(|i| i.span()))),
|
||||
),
|
||||
AlterSchemaOperation::DropReplica { replica } => replica.span,
|
||||
AlterSchemaOperation::SetOptionsParens { options } => {
|
||||
union_spans(options.iter().map(|i| i.span()))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Spanned for AlterSchema {
|
||||
fn span(&self) -> Span {
|
||||
union_spans(
|
||||
core::iter::once(self.name.span()).chain(self.operations.iter().map(|i| i.span())),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub mod tests {
|
||||
use crate::dialect::{Dialect, GenericDialect, SnowflakeDialect};
|
||||
|
|
|
@ -9247,8 +9247,14 @@ impl<'a> Parser<'a> {
|
|||
Keyword::POLICY,
|
||||
Keyword::CONNECTOR,
|
||||
Keyword::ICEBERG,
|
||||
Keyword::SCHEMA,
|
||||
])?;
|
||||
match object_type {
|
||||
Keyword::SCHEMA => {
|
||||
self.prev_token();
|
||||
self.prev_token();
|
||||
self.parse_alter_schema()
|
||||
}
|
||||
Keyword::VIEW => self.parse_alter_view(),
|
||||
Keyword::TYPE => self.parse_alter_type(),
|
||||
Keyword::TABLE => self.parse_alter_table(false),
|
||||
|
@ -9387,6 +9393,40 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
// Parse a [Statement::AlterSchema]
|
||||
// ALTER SCHEMA [ IF EXISTS ] schema_name
|
||||
pub fn parse_alter_schema(&mut self) -> Result<Statement, ParserError> {
|
||||
self.expect_keywords(&[Keyword::ALTER, Keyword::SCHEMA])?;
|
||||
let if_exists = self.parse_keywords(&[Keyword::IF, Keyword::EXISTS]);
|
||||
let name = self.parse_object_name(false)?;
|
||||
let operation = if self.parse_keywords(&[Keyword::SET, Keyword::OPTIONS]) {
|
||||
self.prev_token();
|
||||
let options = self.parse_options(Keyword::OPTIONS)?;
|
||||
AlterSchemaOperation::SetOptionsParens { options }
|
||||
} else if self.parse_keywords(&[Keyword::SET, Keyword::DEFAULT, Keyword::COLLATE]) {
|
||||
let collate = self.parse_expr()?;
|
||||
AlterSchemaOperation::SetDefaultCollate { collate }
|
||||
} else if self.parse_keywords(&[Keyword::ADD, Keyword::REPLICA]) {
|
||||
let replica = self.parse_identifier()?;
|
||||
let options = if self.peek_keyword(Keyword::OPTIONS) {
|
||||
Some(self.parse_options(Keyword::OPTIONS)?)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
AlterSchemaOperation::AddReplica { replica, options }
|
||||
} else if self.parse_keywords(&[Keyword::DROP, Keyword::REPLICA]) {
|
||||
let replica = self.parse_identifier()?;
|
||||
AlterSchemaOperation::DropReplica { replica }
|
||||
} else {
|
||||
return self.expected_ref("ALTER SCHEMA operation", self.peek_token_ref());
|
||||
};
|
||||
Ok(Statement::AlterSchema(AlterSchema {
|
||||
name,
|
||||
if_exists,
|
||||
operations: vec![operation],
|
||||
}))
|
||||
}
|
||||
|
||||
/// Parse a `CALL procedure_name(arg1, arg2, ...)`
|
||||
/// or `CALL procedure_name` statement
|
||||
pub fn parse_call(&mut self) -> Result<Statement, ParserError> {
|
||||
|
|
|
@ -2825,3 +2825,15 @@ fn test_begin_transaction() {
|
|||
fn test_begin_statement() {
|
||||
bigquery().verified_stmt("BEGIN");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_alter_schema() {
|
||||
bigquery_and_generic().verified_stmt("ALTER SCHEMA mydataset SET DEFAULT COLLATE 'und:ci'");
|
||||
bigquery_and_generic().verified_stmt("ALTER SCHEMA mydataset ADD REPLICA 'us'");
|
||||
bigquery_and_generic()
|
||||
.verified_stmt("ALTER SCHEMA mydataset ADD REPLICA 'us' OPTIONS (location = 'us')");
|
||||
bigquery_and_generic().verified_stmt("ALTER SCHEMA mydataset DROP REPLICA 'us'");
|
||||
bigquery_and_generic().verified_stmt("ALTER SCHEMA mydataset SET OPTIONS (location = 'us')");
|
||||
bigquery_and_generic()
|
||||
.verified_stmt("ALTER SCHEMA IF EXISTS mydataset SET OPTIONS (location = 'us')");
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue