#[cfg(not(feature = "std"))]
use alloc::{
boxed::Box,
format,
string::{String, ToString},
vec,
vec::Vec,
};
use core::fmt::{self, Display, Write};
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
#[cfg(feature = "visitor")]
use sqlparser_derive::{Visit, VisitMut};
use crate::ast::value::escape_single_quote_string;
use crate::ast::{
display_comma_separated, display_separated,
table_constraints::{
CheckConstraint, ForeignKeyConstraint, PrimaryKeyConstraint, TableConstraint,
UniqueConstraint,
},
ArgMode, AttachedToken, CommentDef, ConditionalStatements, CreateFunctionBody,
CreateFunctionUsing, CreateTableLikeKind, CreateTableOptions, CreateViewParams, DataType, Expr,
FileFormat, FunctionBehavior, FunctionCalledOnNull, FunctionDefinitionSetParam, FunctionDesc,
FunctionDeterminismSpecifier, FunctionParallel, FunctionSecurity, HiveDistributionStyle,
HiveFormat, HiveIOFormat, HiveRowFormat, HiveSetLocation, Ident, InitializeKind,
MySQLColumnPosition, ObjectName, OnCommit, OneOrManyWithParens, OperateFunctionArg,
OrderByExpr, ProjectionSelect, Query, RefreshModeKind, RowAccessPolicy, SequenceOptions,
Spanned, SqlOption, StorageSerializationPolicy, TableVersion, Tag, TriggerEvent,
TriggerExecBody, TriggerObject, TriggerPeriod, TriggerReferencing, Value, ValueWithSpan,
WrappedCollection,
};
use crate::display_utils::{DisplayCommaSeparated, Indent, NewLine, SpaceOrNewline};
use crate::keywords::Keyword;
use crate::tokenizer::{Span, Token};
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct IndexColumn {
pub column: OrderByExpr,
pub operator_class: Option<ObjectName>,
}
impl From<Ident> for IndexColumn {
fn from(c: Ident) -> Self {
Self {
column: OrderByExpr::from(c),
operator_class: None,
}
}
}
impl<'a> From<&'a str> for IndexColumn {
fn from(c: &'a str) -> Self {
let ident = Ident::new(c);
ident.into()
}
}
impl fmt::Display for IndexColumn {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.column)?;
if let Some(operator_class) = &self.operator_class {
write!(f, " {operator_class}")?;
}
Ok(())
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum ReplicaIdentity {
Nothing,
Full,
Default,
Index(Ident),
}
impl fmt::Display for ReplicaIdentity {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
ReplicaIdentity::Nothing => f.write_str("NOTHING"),
ReplicaIdentity::Full => f.write_str("FULL"),
ReplicaIdentity::Default => f.write_str("DEFAULT"),
ReplicaIdentity::Index(idx) => write!(f, "USING INDEX {idx}"),
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum AlterTableOperation {
AddConstraint {
constraint: TableConstraint,
not_valid: bool,
},
AddColumn {
column_keyword: bool,
if_not_exists: bool,
column_def: ColumnDef,
column_position: Option<MySQLColumnPosition>,
},
AddProjection {
if_not_exists: bool,
name: Ident,
select: ProjectionSelect,
},
DropProjection {
if_exists: bool,
name: Ident,
},
MaterializeProjection {
if_exists: bool,
name: Ident,
partition: Option<Ident>,
},
ClearProjection {
if_exists: bool,
name: Ident,
partition: Option<Ident>,
},
DisableRowLevelSecurity,
DisableRule {
name: Ident,
},
DisableTrigger {
name: Ident,
},
DropConstraint {
if_exists: bool,
name: Ident,
drop_behavior: Option<DropBehavior>,
},
DropColumn {
has_column_keyword: bool,
column_names: Vec<Ident>,
if_exists: bool,
drop_behavior: Option<DropBehavior>,
},
AttachPartition {
partition: Partition,
},
DetachPartition {
partition: Partition,
},
FreezePartition {
partition: Partition,
with_name: Option<Ident>,
},
UnfreezePartition {
partition: Partition,
with_name: Option<Ident>,
},
DropPrimaryKey {
drop_behavior: Option<DropBehavior>,
},
DropForeignKey {
name: Ident,
drop_behavior: Option<DropBehavior>,
},
DropIndex {
name: Ident,
},
EnableAlwaysRule {
name: Ident,
},
EnableAlwaysTrigger {
name: Ident,
},
EnableReplicaRule {
name: Ident,
},
EnableReplicaTrigger {
name: Ident,
},
EnableRowLevelSecurity,
ForceRowLevelSecurity,
NoForceRowLevelSecurity,
EnableRule {
name: Ident,
},
EnableTrigger {
name: Ident,
},
RenamePartitions {
old_partitions: Vec<Expr>,
new_partitions: Vec<Expr>,
},
ReplicaIdentity {
identity: ReplicaIdentity,
},
AddPartitions {
if_not_exists: bool,
new_partitions: Vec<Partition>,
},
DropPartitions {
partitions: Vec<Expr>,
if_exists: bool,
},
RenameColumn {
old_column_name: Ident,
new_column_name: Ident,
},
RenameTable {
table_name: RenameTableNameKind,
},
ChangeColumn {
old_name: Ident,
new_name: Ident,
data_type: DataType,
options: Vec<ColumnOption>,
column_position: Option<MySQLColumnPosition>,
},
ModifyColumn {
col_name: Ident,
data_type: DataType,
options: Vec<ColumnOption>,
column_position: Option<MySQLColumnPosition>,
},
RenameConstraint {
old_name: Ident,
new_name: Ident,
},
AlterColumn {
column_name: Ident,
op: AlterColumnOperation,
},
SwapWith {
table_name: ObjectName,
},
SetTblProperties {
table_properties: Vec<SqlOption>,
},
OwnerTo {
new_owner: Owner,
},
ClusterBy {
exprs: Vec<Expr>,
},
DropClusteringKey,
SuspendRecluster,
ResumeRecluster,
Refresh {
subpath: Option<String>,
},
Suspend,
Resume,
Algorithm {
equals: bool,
algorithm: AlterTableAlgorithm,
},
Lock {
equals: bool,
lock: AlterTableLock,
},
AutoIncrement {
equals: bool,
value: ValueWithSpan,
},
ValidateConstraint {
name: Ident,
},
SetOptionsParens {
options: Vec<SqlOption>,
},
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum AlterPolicyOperation {
Rename {
new_name: Ident,
},
Apply {
to: Option<Vec<Owner>>,
using: Option<Expr>,
with_check: Option<Expr>,
},
}
impl fmt::Display for AlterPolicyOperation {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
AlterPolicyOperation::Rename { new_name } => {
write!(f, " RENAME TO {new_name}")
}
AlterPolicyOperation::Apply {
to,
using,
with_check,
} => {
if let Some(to) = to {
write!(f, " TO {}", display_comma_separated(to))?;
}
if let Some(using) = using {
write!(f, " USING ({using})")?;
}
if let Some(with_check) = with_check {
write!(f, " WITH CHECK ({with_check})")?;
}
Ok(())
}
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum AlterTableAlgorithm {
Default,
Instant,
Inplace,
Copy,
}
impl fmt::Display for AlterTableAlgorithm {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str(match self {
Self::Default => "DEFAULT",
Self::Instant => "INSTANT",
Self::Inplace => "INPLACE",
Self::Copy => "COPY",
})
}
}
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum AlterTableLock {
Default,
None,
Shared,
Exclusive,
}
impl fmt::Display for AlterTableLock {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str(match self {
Self::Default => "DEFAULT",
Self::None => "NONE",
Self::Shared => "SHARED",
Self::Exclusive => "EXCLUSIVE",
})
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum Owner {
Ident(Ident),
CurrentRole,
CurrentUser,
SessionUser,
}
impl fmt::Display for Owner {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Owner::Ident(ident) => write!(f, "{ident}"),
Owner::CurrentRole => write!(f, "CURRENT_ROLE"),
Owner::CurrentUser => write!(f, "CURRENT_USER"),
Owner::SessionUser => write!(f, "SESSION_USER"),
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum AlterConnectorOwner {
User(Ident),
Role(Ident),
}
impl fmt::Display for AlterConnectorOwner {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
AlterConnectorOwner::User(ident) => write!(f, "USER {ident}"),
AlterConnectorOwner::Role(ident) => write!(f, "ROLE {ident}"),
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum AlterIndexOperation {
RenameIndex {
index_name: ObjectName,
},
}
impl fmt::Display for AlterTableOperation {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
AlterTableOperation::AddPartitions {
if_not_exists,
new_partitions,
} => write!(
f,
"ADD{ine} {}",
display_separated(new_partitions, " "),
ine = if *if_not_exists { " IF NOT EXISTS" } else { "" }
),
AlterTableOperation::AddConstraint {
not_valid,
constraint,
} => {
write!(f, "ADD {constraint}")?;
if *not_valid {
write!(f, " NOT VALID")?;
}
Ok(())
}
AlterTableOperation::AddColumn {
column_keyword,
if_not_exists,
column_def,
column_position,
} => {
write!(f, "ADD")?;
if *column_keyword {
write!(f, " COLUMN")?;
}
if *if_not_exists {
write!(f, " IF NOT EXISTS")?;
}
write!(f, " {column_def}")?;
if let Some(position) = column_position {
write!(f, " {position}")?;
}
Ok(())
}
AlterTableOperation::AddProjection {
if_not_exists,
name,
select: query,
} => {
write!(f, "ADD PROJECTION")?;
if *if_not_exists {
write!(f, " IF NOT EXISTS")?;
}
write!(f, " {name} ({query})")
}
AlterTableOperation::Algorithm { equals, algorithm } => {
write!(
f,
"ALGORITHM {}{}",
if *equals { "= " } else { "" },
algorithm
)
}
AlterTableOperation::DropProjection { if_exists, name } => {
write!(f, "DROP PROJECTION")?;
if *if_exists {
write!(f, " IF EXISTS")?;
}
write!(f, " {name}")
}
AlterTableOperation::MaterializeProjection {
if_exists,
name,
partition,
} => {
write!(f, "MATERIALIZE PROJECTION")?;
if *if_exists {
write!(f, " IF EXISTS")?;
}
write!(f, " {name}")?;
if let Some(partition) = partition {
write!(f, " IN PARTITION {partition}")?;
}
Ok(())
}
AlterTableOperation::ClearProjection {
if_exists,
name,
partition,
} => {
write!(f, "CLEAR PROJECTION")?;
if *if_exists {
write!(f, " IF EXISTS")?;
}
write!(f, " {name}")?;
if let Some(partition) = partition {
write!(f, " IN PARTITION {partition}")?;
}
Ok(())
}
AlterTableOperation::AlterColumn { column_name, op } => {
write!(f, "ALTER COLUMN {column_name} {op}")
}
AlterTableOperation::DisableRowLevelSecurity => {
write!(f, "DISABLE ROW LEVEL SECURITY")
}
AlterTableOperation::DisableRule { name } => {
write!(f, "DISABLE RULE {name}")
}
AlterTableOperation::DisableTrigger { name } => {
write!(f, "DISABLE TRIGGER {name}")
}
AlterTableOperation::DropPartitions {
partitions,
if_exists,
} => write!(
f,
"DROP{ie} PARTITION ({})",
display_comma_separated(partitions),
ie = if *if_exists { " IF EXISTS" } else { "" }
),
AlterTableOperation::DropConstraint {
if_exists,
name,
drop_behavior,
} => {
write!(
f,
"DROP CONSTRAINT {}{}",
if *if_exists { "IF EXISTS " } else { "" },
name
)?;
if let Some(drop_behavior) = drop_behavior {
write!(f, " {drop_behavior}")?;
}
Ok(())
}
AlterTableOperation::DropPrimaryKey { drop_behavior } => {
write!(f, "DROP PRIMARY KEY")?;
if let Some(drop_behavior) = drop_behavior {
write!(f, " {drop_behavior}")?;
}
Ok(())
}
AlterTableOperation::DropForeignKey {
name,
drop_behavior,
} => {
write!(f, "DROP FOREIGN KEY {name}")?;
if let Some(drop_behavior) = drop_behavior {
write!(f, " {drop_behavior}")?;
}
Ok(())
}
AlterTableOperation::DropIndex { name } => write!(f, "DROP INDEX {name}"),
AlterTableOperation::DropColumn {
has_column_keyword,
column_names: column_name,
if_exists,
drop_behavior,
} => {
write!(
f,
"DROP {}{}{}",
if *has_column_keyword { "COLUMN " } else { "" },
if *if_exists { "IF EXISTS " } else { "" },
display_comma_separated(column_name),
)?;
if let Some(drop_behavior) = drop_behavior {
write!(f, " {drop_behavior}")?;
}
Ok(())
}
AlterTableOperation::AttachPartition { partition } => {
write!(f, "ATTACH {partition}")
}
AlterTableOperation::DetachPartition { partition } => {
write!(f, "DETACH {partition}")
}
AlterTableOperation::EnableAlwaysRule { name } => {
write!(f, "ENABLE ALWAYS RULE {name}")
}
AlterTableOperation::EnableAlwaysTrigger { name } => {
write!(f, "ENABLE ALWAYS TRIGGER {name}")
}
AlterTableOperation::EnableReplicaRule { name } => {
write!(f, "ENABLE REPLICA RULE {name}")
}
AlterTableOperation::EnableReplicaTrigger { name } => {
write!(f, "ENABLE REPLICA TRIGGER {name}")
}
AlterTableOperation::EnableRowLevelSecurity => {
write!(f, "ENABLE ROW LEVEL SECURITY")
}
AlterTableOperation::ForceRowLevelSecurity => {
write!(f, "FORCE ROW LEVEL SECURITY")
}
AlterTableOperation::NoForceRowLevelSecurity => {
write!(f, "NO FORCE ROW LEVEL SECURITY")
}
AlterTableOperation::EnableRule { name } => {
write!(f, "ENABLE RULE {name}")
}
AlterTableOperation::EnableTrigger { name } => {
write!(f, "ENABLE TRIGGER {name}")
}
AlterTableOperation::RenamePartitions {
old_partitions,
new_partitions,
} => write!(
f,
"PARTITION ({}) RENAME TO PARTITION ({})",
display_comma_separated(old_partitions),
display_comma_separated(new_partitions)
),
AlterTableOperation::RenameColumn {
old_column_name,
new_column_name,
} => write!(f, "RENAME COLUMN {old_column_name} TO {new_column_name}"),
AlterTableOperation::RenameTable { table_name } => {
write!(f, "RENAME {table_name}")
}
AlterTableOperation::ChangeColumn {
old_name,
new_name,
data_type,
options,
column_position,
} => {
write!(f, "CHANGE COLUMN {old_name} {new_name} {data_type}")?;
if !options.is_empty() {
write!(f, " {}", display_separated(options, " "))?;
}
if let Some(position) = column_position {
write!(f, " {position}")?;
}
Ok(())
}
AlterTableOperation::ModifyColumn {
col_name,
data_type,
options,
column_position,
} => {
write!(f, "MODIFY COLUMN {col_name} {data_type}")?;
if !options.is_empty() {
write!(f, " {}", display_separated(options, " "))?;
}
if let Some(position) = column_position {
write!(f, " {position}")?;
}
Ok(())
}
AlterTableOperation::RenameConstraint { old_name, new_name } => {
write!(f, "RENAME CONSTRAINT {old_name} TO {new_name}")
}
AlterTableOperation::SwapWith { table_name } => {
write!(f, "SWAP WITH {table_name}")
}
AlterTableOperation::OwnerTo { new_owner } => {
write!(f, "OWNER TO {new_owner}")
}
AlterTableOperation::SetTblProperties { table_properties } => {
write!(
f,
"SET TBLPROPERTIES({})",
display_comma_separated(table_properties)
)
}
AlterTableOperation::FreezePartition {
partition,
with_name,
} => {
write!(f, "FREEZE {partition}")?;
if let Some(name) = with_name {
write!(f, " WITH NAME {name}")?;
}
Ok(())
}
AlterTableOperation::UnfreezePartition {
partition,
with_name,
} => {
write!(f, "UNFREEZE {partition}")?;
if let Some(name) = with_name {
write!(f, " WITH NAME {name}")?;
}
Ok(())
}
AlterTableOperation::ClusterBy { exprs } => {
write!(f, "CLUSTER BY ({})", display_comma_separated(exprs))?;
Ok(())
}
AlterTableOperation::DropClusteringKey => {
write!(f, "DROP CLUSTERING KEY")?;
Ok(())
}
AlterTableOperation::SuspendRecluster => {
write!(f, "SUSPEND RECLUSTER")?;
Ok(())
}
AlterTableOperation::ResumeRecluster => {
write!(f, "RESUME RECLUSTER")?;
Ok(())
}
AlterTableOperation::Refresh { subpath } => {
write!(f, "REFRESH")?;
if let Some(path) = subpath {
write!(f, " '{path}'")?;
}
Ok(())
}
AlterTableOperation::Suspend => {
write!(f, "SUSPEND")
}
AlterTableOperation::Resume => {
write!(f, "RESUME")
}
AlterTableOperation::AutoIncrement { equals, value } => {
write!(
f,
"AUTO_INCREMENT {}{}",
if *equals { "= " } else { "" },
value
)
}
AlterTableOperation::Lock { equals, lock } => {
write!(f, "LOCK {}{}", if *equals { "= " } else { "" }, lock)
}
AlterTableOperation::ReplicaIdentity { identity } => {
write!(f, "REPLICA IDENTITY {identity}")
}
AlterTableOperation::ValidateConstraint { name } => {
write!(f, "VALIDATE CONSTRAINT {name}")
}
AlterTableOperation::SetOptionsParens { options } => {
write!(f, "SET ({})", display_comma_separated(options))
}
}
}
}
impl fmt::Display for AlterIndexOperation {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
AlterIndexOperation::RenameIndex { index_name } => {
write!(f, "RENAME TO {index_name}")
}
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct AlterType {
pub name: ObjectName,
pub operation: AlterTypeOperation,
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum AlterTypeOperation {
Rename(AlterTypeRename),
AddValue(AlterTypeAddValue),
RenameValue(AlterTypeRenameValue),
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct AlterTypeRename {
pub new_name: Ident,
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct AlterTypeAddValue {
pub if_not_exists: bool,
pub value: Ident,
pub position: Option<AlterTypeAddValuePosition>,
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum AlterTypeAddValuePosition {
Before(Ident),
After(Ident),
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct AlterTypeRenameValue {
pub from: Ident,
pub to: Ident,
}
impl fmt::Display for AlterTypeOperation {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::Rename(AlterTypeRename { new_name }) => {
write!(f, "RENAME TO {new_name}")
}
Self::AddValue(AlterTypeAddValue {
if_not_exists,
value,
position,
}) => {
write!(f, "ADD VALUE")?;
if *if_not_exists {
write!(f, " IF NOT EXISTS")?;
}
write!(f, " {value}")?;
match position {
Some(AlterTypeAddValuePosition::Before(neighbor_value)) => {
write!(f, " BEFORE {neighbor_value}")?;
}
Some(AlterTypeAddValuePosition::After(neighbor_value)) => {
write!(f, " AFTER {neighbor_value}")?;
}
None => {}
};
Ok(())
}
Self::RenameValue(AlterTypeRenameValue { from, to }) => {
write!(f, "RENAME VALUE {from} TO {to}")
}
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct AlterOperator {
pub name: ObjectName,
pub left_type: Option<DataType>,
pub right_type: DataType,
pub operation: AlterOperatorOperation,
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum AlterOperatorOperation {
OwnerTo(Owner),
SetSchema {
schema_name: ObjectName,
},
Set {
options: Vec<OperatorOption>,
},
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum OperatorOption {
Restrict(Option<ObjectName>),
Join(Option<ObjectName>),
Commutator(ObjectName),
Negator(ObjectName),
Hashes,
Merges,
}
impl fmt::Display for AlterOperator {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "ALTER OPERATOR {} (", self.name)?;
if let Some(left_type) = &self.left_type {
write!(f, "{}", left_type)?;
} else {
write!(f, "NONE")?;
}
write!(f, ", {}) {}", self.right_type, self.operation)
}
}
impl fmt::Display for AlterOperatorOperation {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::OwnerTo(owner) => write!(f, "OWNER TO {}", owner),
Self::SetSchema { schema_name } => write!(f, "SET SCHEMA {}", schema_name),
Self::Set { options } => {
write!(f, "SET (")?;
for (i, option) in options.iter().enumerate() {
if i > 0 {
write!(f, ", ")?;
}
write!(f, "{}", option)?;
}
write!(f, ")")
}
}
}
}
impl fmt::Display for OperatorOption {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::Restrict(Some(proc_name)) => write!(f, "RESTRICT = {}", proc_name),
Self::Restrict(None) => write!(f, "RESTRICT = NONE"),
Self::Join(Some(proc_name)) => write!(f, "JOIN = {}", proc_name),
Self::Join(None) => write!(f, "JOIN = NONE"),
Self::Commutator(op_name) => write!(f, "COMMUTATOR = {}", op_name),
Self::Negator(op_name) => write!(f, "NEGATOR = {}", op_name),
Self::Hashes => write!(f, "HASHES"),
Self::Merges => write!(f, "MERGES"),
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum AlterColumnOperation {
SetNotNull,
DropNotNull,
SetDefault {
value: Expr,
},
DropDefault,
SetDataType {
data_type: DataType,
using: Option<Expr>,
had_set: bool,
},
AddGenerated {
generated_as: Option<GeneratedAs>,
sequence_options: Option<Vec<SequenceOptions>>,
},
}
impl fmt::Display for AlterColumnOperation {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
AlterColumnOperation::SetNotNull => write!(f, "SET NOT NULL",),
AlterColumnOperation::DropNotNull => write!(f, "DROP NOT NULL",),
AlterColumnOperation::SetDefault { value } => {
write!(f, "SET DEFAULT {value}")
}
AlterColumnOperation::DropDefault => {
write!(f, "DROP DEFAULT")
}
AlterColumnOperation::SetDataType {
data_type,
using,
had_set,
} => {
if *had_set {
write!(f, "SET DATA ")?;
}
write!(f, "TYPE {data_type}")?;
if let Some(expr) = using {
write!(f, " USING {expr}")?;
}
Ok(())
}
AlterColumnOperation::AddGenerated {
generated_as,
sequence_options,
} => {
let generated_as = match generated_as {
Some(GeneratedAs::Always) => " ALWAYS",
Some(GeneratedAs::ByDefault) => " BY DEFAULT",
_ => "",
};
write!(f, "ADD GENERATED{generated_as} AS IDENTITY",)?;
if let Some(options) = sequence_options {
write!(f, " (")?;
for sequence_option in options {
write!(f, "{sequence_option}")?;
}
write!(f, " )")?;
}
Ok(())
}
}
}
}
#[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 KeyOrIndexDisplay {
None,
Key,
Index,
}
impl KeyOrIndexDisplay {
pub fn is_none(self) -> bool {
matches!(self, Self::None)
}
}
impl fmt::Display for KeyOrIndexDisplay {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let left_space = matches!(f.align(), Some(fmt::Alignment::Right));
if left_space && !self.is_none() {
f.write_char(' ')?
}
match self {
KeyOrIndexDisplay::None => {
write!(f, "")
}
KeyOrIndexDisplay::Key => {
write!(f, "KEY")
}
KeyOrIndexDisplay::Index => {
write!(f, "INDEX")
}
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum IndexType {
BTree,
Hash,
GIN,
GiST,
SPGiST,
BRIN,
Bloom,
Custom(Ident),
}
impl fmt::Display for IndexType {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::BTree => write!(f, "BTREE"),
Self::Hash => write!(f, "HASH"),
Self::GIN => write!(f, "GIN"),
Self::GiST => write!(f, "GIST"),
Self::SPGiST => write!(f, "SPGIST"),
Self::BRIN => write!(f, "BRIN"),
Self::Bloom => write!(f, "BLOOM"),
Self::Custom(name) => write!(f, "{name}"),
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum IndexOption {
Using(IndexType),
Comment(String),
}
impl fmt::Display for IndexOption {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::Using(index_type) => write!(f, "USING {index_type}"),
Self::Comment(s) => write!(f, "COMMENT '{s}'"),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum NullsDistinctOption {
None,
Distinct,
NotDistinct,
}
impl fmt::Display for NullsDistinctOption {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::None => Ok(()),
Self::Distinct => write!(f, " NULLS DISTINCT"),
Self::NotDistinct => write!(f, " NULLS NOT DISTINCT"),
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct ProcedureParam {
pub name: Ident,
pub data_type: DataType,
pub mode: Option<ArgMode>,
pub default: Option<Expr>,
}
impl fmt::Display for ProcedureParam {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if let Some(mode) = &self.mode {
if let Some(default) = &self.default {
write!(f, "{mode} {} {} = {}", self.name, self.data_type, default)
} else {
write!(f, "{mode} {} {}", self.name, self.data_type)
}
} else if let Some(default) = &self.default {
write!(f, "{} {} = {}", self.name, self.data_type, default)
} else {
write!(f, "{} {}", self.name, self.data_type)
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct ColumnDef {
pub name: Ident,
pub data_type: DataType,
pub options: Vec<ColumnOptionDef>,
}
impl fmt::Display for ColumnDef {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if self.data_type == DataType::Unspecified {
write!(f, "{}", self.name)?;
} else {
write!(f, "{} {}", self.name, self.data_type)?;
}
for option in &self.options {
write!(f, " {option}")?;
}
Ok(())
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct ViewColumnDef {
pub name: Ident,
pub data_type: Option<DataType>,
pub options: Option<ColumnOptions>,
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum ColumnOptions {
CommaSeparated(Vec<ColumnOption>),
SpaceSeparated(Vec<ColumnOption>),
}
impl ColumnOptions {
pub fn as_slice(&self) -> &[ColumnOption] {
match self {
ColumnOptions::CommaSeparated(options) => options.as_slice(),
ColumnOptions::SpaceSeparated(options) => options.as_slice(),
}
}
}
impl fmt::Display for ViewColumnDef {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.name)?;
if let Some(data_type) = self.data_type.as_ref() {
write!(f, " {data_type}")?;
}
if let Some(options) = self.options.as_ref() {
match options {
ColumnOptions::CommaSeparated(column_options) => {
write!(f, " {}", display_comma_separated(column_options.as_slice()))?;
}
ColumnOptions::SpaceSeparated(column_options) => {
write!(f, " {}", display_separated(column_options.as_slice(), " "))?
}
}
}
Ok(())
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct ColumnOptionDef {
pub name: Option<Ident>,
pub option: ColumnOption,
}
impl fmt::Display for ColumnOptionDef {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}{}", display_constraint_name(&self.name), self.option)
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum IdentityPropertyKind {
Autoincrement(IdentityProperty),
Identity(IdentityProperty),
}
impl fmt::Display for IdentityPropertyKind {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let (command, property) = match self {
IdentityPropertyKind::Identity(property) => ("IDENTITY", property),
IdentityPropertyKind::Autoincrement(property) => ("AUTOINCREMENT", property),
};
write!(f, "{command}")?;
if let Some(parameters) = &property.parameters {
write!(f, "{parameters}")?;
}
if let Some(order) = &property.order {
write!(f, "{order}")?;
}
Ok(())
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct IdentityProperty {
pub parameters: Option<IdentityPropertyFormatKind>,
pub order: Option<IdentityPropertyOrder>,
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum IdentityPropertyFormatKind {
FunctionCall(IdentityParameters),
StartAndIncrement(IdentityParameters),
}
impl fmt::Display for IdentityPropertyFormatKind {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
IdentityPropertyFormatKind::FunctionCall(parameters) => {
write!(f, "({}, {})", parameters.seed, parameters.increment)
}
IdentityPropertyFormatKind::StartAndIncrement(parameters) => {
write!(
f,
" START {} INCREMENT {}",
parameters.seed, parameters.increment
)
}
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct IdentityParameters {
pub seed: Expr,
pub increment: Expr,
}
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum IdentityPropertyOrder {
Order,
NoOrder,
}
impl fmt::Display for IdentityPropertyOrder {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
IdentityPropertyOrder::Order => write!(f, " ORDER"),
IdentityPropertyOrder::NoOrder => write!(f, " NOORDER"),
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum ColumnPolicy {
MaskingPolicy(ColumnPolicyProperty),
ProjectionPolicy(ColumnPolicyProperty),
}
impl fmt::Display for ColumnPolicy {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let (command, property) = match self {
ColumnPolicy::MaskingPolicy(property) => ("MASKING POLICY", property),
ColumnPolicy::ProjectionPolicy(property) => ("PROJECTION POLICY", property),
};
if property.with {
write!(f, "WITH ")?;
}
write!(f, "{command} {}", property.policy_name)?;
if let Some(using_columns) = &property.using_columns {
write!(f, " USING ({})", display_comma_separated(using_columns))?;
}
Ok(())
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct ColumnPolicyProperty {
pub with: bool,
pub policy_name: ObjectName,
pub using_columns: Option<Vec<Ident>>,
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct TagsColumnOption {
pub with: bool,
pub tags: Vec<Tag>,
}
impl fmt::Display for TagsColumnOption {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if self.with {
write!(f, "WITH ")?;
}
write!(f, "TAG ({})", display_comma_separated(&self.tags))?;
Ok(())
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum ColumnOption {
Null,
NotNull,
Default(Expr),
Materialized(Expr),
Ephemeral(Option<Expr>),
Alias(Expr),
PrimaryKey(PrimaryKeyConstraint),
Unique(UniqueConstraint),
ForeignKey(ForeignKeyConstraint),
Check(CheckConstraint),
DialectSpecific(Vec<Token>),
CharacterSet(ObjectName),
Collation(ObjectName),
Comment(String),
OnUpdate(Expr),
Generated {
generated_as: GeneratedAs,
sequence_options: Option<Vec<SequenceOptions>>,
generation_expr: Option<Expr>,
generation_expr_mode: Option<GeneratedExpressionMode>,
generated_keyword: bool,
},
Options(Vec<SqlOption>),
Identity(IdentityPropertyKind),
OnConflict(Keyword),
Policy(ColumnPolicy),
Tags(TagsColumnOption),
Srid(Box<Expr>),
Invisible,
}
impl From<UniqueConstraint> for ColumnOption {
fn from(c: UniqueConstraint) -> Self {
ColumnOption::Unique(c)
}
}
impl From<PrimaryKeyConstraint> for ColumnOption {
fn from(c: PrimaryKeyConstraint) -> Self {
ColumnOption::PrimaryKey(c)
}
}
impl From<CheckConstraint> for ColumnOption {
fn from(c: CheckConstraint) -> Self {
ColumnOption::Check(c)
}
}
impl From<ForeignKeyConstraint> for ColumnOption {
fn from(fk: ForeignKeyConstraint) -> Self {
ColumnOption::ForeignKey(fk)
}
}
impl fmt::Display for ColumnOption {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use ColumnOption::*;
match self {
Null => write!(f, "NULL"),
NotNull => write!(f, "NOT NULL"),
Default(expr) => write!(f, "DEFAULT {expr}"),
Materialized(expr) => write!(f, "MATERIALIZED {expr}"),
Ephemeral(expr) => {
if let Some(e) = expr {
write!(f, "EPHEMERAL {e}")
} else {
write!(f, "EPHEMERAL")
}
}
Alias(expr) => write!(f, "ALIAS {expr}"),
PrimaryKey(constraint) => {
write!(f, "PRIMARY KEY")?;
if let Some(characteristics) = &constraint.characteristics {
write!(f, " {characteristics}")?;
}
Ok(())
}
Unique(constraint) => {
write!(f, "UNIQUE")?;
if let Some(characteristics) = &constraint.characteristics {
write!(f, " {characteristics}")?;
}
Ok(())
}
ForeignKey(constraint) => {
write!(f, "REFERENCES {}", constraint.foreign_table)?;
if !constraint.referred_columns.is_empty() {
write!(
f,
" ({})",
display_comma_separated(&constraint.referred_columns)
)?;
}
if let Some(match_kind) = &constraint.match_kind {
write!(f, " {match_kind}")?;
}
if let Some(action) = &constraint.on_delete {
write!(f, " ON DELETE {action}")?;
}
if let Some(action) = &constraint.on_update {
write!(f, " ON UPDATE {action}")?;
}
if let Some(characteristics) = &constraint.characteristics {
write!(f, " {characteristics}")?;
}
Ok(())
}
Check(constraint) => write!(f, "{constraint}"),
DialectSpecific(val) => write!(f, "{}", display_separated(val, " ")),
CharacterSet(n) => write!(f, "CHARACTER SET {n}"),
Collation(n) => write!(f, "COLLATE {n}"),
Comment(v) => write!(f, "COMMENT '{}'", escape_single_quote_string(v)),
OnUpdate(expr) => write!(f, "ON UPDATE {expr}"),
Generated {
generated_as,
sequence_options,
generation_expr,
generation_expr_mode,
generated_keyword,
} => {
if let Some(expr) = generation_expr {
let modifier = match generation_expr_mode {
None => "",
Some(GeneratedExpressionMode::Virtual) => " VIRTUAL",
Some(GeneratedExpressionMode::Stored) => " STORED",
};
if *generated_keyword {
write!(f, "GENERATED ALWAYS AS ({expr}){modifier}")?;
} else {
write!(f, "AS ({expr}){modifier}")?;
}
Ok(())
} else {
let when = match generated_as {
GeneratedAs::Always => "ALWAYS",
GeneratedAs::ByDefault => "BY DEFAULT",
GeneratedAs::ExpStored => "",
};
write!(f, "GENERATED {when} AS IDENTITY")?;
if sequence_options.is_some() {
let so = sequence_options.as_ref().unwrap();
if !so.is_empty() {
write!(f, " (")?;
}
for sequence_option in so {
write!(f, "{sequence_option}")?;
}
if !so.is_empty() {
write!(f, " )")?;
}
}
Ok(())
}
}
Options(options) => {
write!(f, "OPTIONS({})", display_comma_separated(options))
}
Identity(parameters) => {
write!(f, "{parameters}")
}
OnConflict(keyword) => {
write!(f, "ON CONFLICT {keyword:?}")?;
Ok(())
}
Policy(parameters) => {
write!(f, "{parameters}")
}
Tags(tags) => {
write!(f, "{tags}")
}
Srid(srid) => {
write!(f, "SRID {srid}")
}
Invisible => {
write!(f, "INVISIBLE")
}
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum GeneratedAs {
Always,
ByDefault,
ExpStored,
}
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum GeneratedExpressionMode {
Virtual,
Stored,
}
#[must_use]
pub(crate) fn display_constraint_name(name: &'_ Option<Ident>) -> impl fmt::Display + '_ {
struct ConstraintName<'a>(&'a Option<Ident>);
impl fmt::Display for ConstraintName<'_> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if let Some(name) = self.0 {
write!(f, "CONSTRAINT {name} ")?;
}
Ok(())
}
}
ConstraintName(name)
}
#[must_use]
pub(crate) fn display_option<'a, T: fmt::Display>(
prefix: &'a str,
postfix: &'a str,
option: &'a Option<T>,
) -> impl fmt::Display + 'a {
struct OptionDisplay<'a, T>(&'a str, &'a str, &'a Option<T>);
impl<T: fmt::Display> fmt::Display for OptionDisplay<'_, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if let Some(inner) = self.2 {
let (prefix, postfix) = (self.0, self.1);
write!(f, "{prefix}{inner}{postfix}")?;
}
Ok(())
}
}
OptionDisplay(prefix, postfix, option)
}
#[must_use]
pub(crate) fn display_option_spaced<T: fmt::Display>(option: &Option<T>) -> impl fmt::Display + '_ {
display_option(" ", "", option)
}
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Default, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct ConstraintCharacteristics {
pub deferrable: Option<bool>,
pub initially: Option<DeferrableInitial>,
pub enforced: Option<bool>,
}
#[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 DeferrableInitial {
Immediate,
Deferred,
}
impl ConstraintCharacteristics {
fn deferrable_text(&self) -> Option<&'static str> {
self.deferrable.map(|deferrable| {
if deferrable {
"DEFERRABLE"
} else {
"NOT DEFERRABLE"
}
})
}
fn initially_immediate_text(&self) -> Option<&'static str> {
self.initially
.map(|initially_immediate| match initially_immediate {
DeferrableInitial::Immediate => "INITIALLY IMMEDIATE",
DeferrableInitial::Deferred => "INITIALLY DEFERRED",
})
}
fn enforced_text(&self) -> Option<&'static str> {
self.enforced.map(
|enforced| {
if enforced {
"ENFORCED"
} else {
"NOT ENFORCED"
}
},
)
}
}
impl fmt::Display for ConstraintCharacteristics {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let deferrable = self.deferrable_text();
let initially_immediate = self.initially_immediate_text();
let enforced = self.enforced_text();
match (deferrable, initially_immediate, enforced) {
(None, None, None) => Ok(()),
(None, None, Some(enforced)) => write!(f, "{enforced}"),
(None, Some(initial), None) => write!(f, "{initial}"),
(None, Some(initial), Some(enforced)) => write!(f, "{initial} {enforced}"),
(Some(deferrable), None, None) => write!(f, "{deferrable}"),
(Some(deferrable), None, Some(enforced)) => write!(f, "{deferrable} {enforced}"),
(Some(deferrable), Some(initial), None) => write!(f, "{deferrable} {initial}"),
(Some(deferrable), Some(initial), Some(enforced)) => {
write!(f, "{deferrable} {initial} {enforced}")
}
}
}
}
#[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 ReferentialAction {
Restrict,
Cascade,
SetNull,
NoAction,
SetDefault,
}
impl fmt::Display for ReferentialAction {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str(match self {
ReferentialAction::Restrict => "RESTRICT",
ReferentialAction::Cascade => "CASCADE",
ReferentialAction::SetNull => "SET NULL",
ReferentialAction::NoAction => "NO ACTION",
ReferentialAction::SetDefault => "SET DEFAULT",
})
}
}
#[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 DropBehavior {
Restrict,
Cascade,
}
impl fmt::Display for DropBehavior {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str(match self {
DropBehavior::Restrict => "RESTRICT",
DropBehavior::Cascade => "CASCADE",
})
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum UserDefinedTypeRepresentation {
Composite {
attributes: Vec<UserDefinedTypeCompositeAttributeDef>,
},
Enum {
labels: Vec<Ident>,
},
Range {
options: Vec<UserDefinedTypeRangeOption>,
},
SqlDefinition {
options: Vec<UserDefinedTypeSqlDefinitionOption>,
},
}
impl fmt::Display for UserDefinedTypeRepresentation {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::Composite { attributes } => {
write!(f, "AS ({})", display_comma_separated(attributes))
}
Self::Enum { labels } => {
write!(f, "AS ENUM ({})", display_comma_separated(labels))
}
Self::Range { options } => {
write!(f, "AS RANGE ({})", display_comma_separated(options))
}
Self::SqlDefinition { options } => {
write!(f, "({})", display_comma_separated(options))
}
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct UserDefinedTypeCompositeAttributeDef {
pub name: Ident,
pub data_type: DataType,
pub collation: Option<ObjectName>,
}
impl fmt::Display for UserDefinedTypeCompositeAttributeDef {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{} {}", self.name, self.data_type)?;
if let Some(collation) = &self.collation {
write!(f, " COLLATE {collation}")?;
}
Ok(())
}
}
#[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 UserDefinedTypeInternalLength {
Fixed(u64),
Variable,
}
impl fmt::Display for UserDefinedTypeInternalLength {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
UserDefinedTypeInternalLength::Fixed(n) => write!(f, "{}", n),
UserDefinedTypeInternalLength::Variable => write!(f, "VARIABLE"),
}
}
}
#[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 Alignment {
Char,
Int2,
Int4,
Double,
}
impl fmt::Display for Alignment {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Alignment::Char => write!(f, "char"),
Alignment::Int2 => write!(f, "int2"),
Alignment::Int4 => write!(f, "int4"),
Alignment::Double => write!(f, "double"),
}
}
}
#[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 UserDefinedTypeStorage {
Plain,
External,
Extended,
Main,
}
impl fmt::Display for UserDefinedTypeStorage {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
UserDefinedTypeStorage::Plain => write!(f, "plain"),
UserDefinedTypeStorage::External => write!(f, "external"),
UserDefinedTypeStorage::Extended => write!(f, "extended"),
UserDefinedTypeStorage::Main => write!(f, "main"),
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum UserDefinedTypeRangeOption {
Subtype(DataType),
SubtypeOpClass(ObjectName),
Collation(ObjectName),
Canonical(ObjectName),
SubtypeDiff(ObjectName),
MultirangeTypeName(ObjectName),
}
impl fmt::Display for UserDefinedTypeRangeOption {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
UserDefinedTypeRangeOption::Subtype(dt) => write!(f, "SUBTYPE = {}", dt),
UserDefinedTypeRangeOption::SubtypeOpClass(name) => {
write!(f, "SUBTYPE_OPCLASS = {}", name)
}
UserDefinedTypeRangeOption::Collation(name) => write!(f, "COLLATION = {}", name),
UserDefinedTypeRangeOption::Canonical(name) => write!(f, "CANONICAL = {}", name),
UserDefinedTypeRangeOption::SubtypeDiff(name) => write!(f, "SUBTYPE_DIFF = {}", name),
UserDefinedTypeRangeOption::MultirangeTypeName(name) => {
write!(f, "MULTIRANGE_TYPE_NAME = {}", name)
}
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum UserDefinedTypeSqlDefinitionOption {
Input(ObjectName),
Output(ObjectName),
Receive(ObjectName),
Send(ObjectName),
TypmodIn(ObjectName),
TypmodOut(ObjectName),
Analyze(ObjectName),
Subscript(ObjectName),
InternalLength(UserDefinedTypeInternalLength),
PassedByValue,
Alignment(Alignment),
Storage(UserDefinedTypeStorage),
Like(ObjectName),
Category(char),
Preferred(bool),
Default(Expr),
Element(DataType),
Delimiter(String),
Collatable(bool),
}
impl fmt::Display for UserDefinedTypeSqlDefinitionOption {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
UserDefinedTypeSqlDefinitionOption::Input(name) => write!(f, "INPUT = {}", name),
UserDefinedTypeSqlDefinitionOption::Output(name) => write!(f, "OUTPUT = {}", name),
UserDefinedTypeSqlDefinitionOption::Receive(name) => write!(f, "RECEIVE = {}", name),
UserDefinedTypeSqlDefinitionOption::Send(name) => write!(f, "SEND = {}", name),
UserDefinedTypeSqlDefinitionOption::TypmodIn(name) => write!(f, "TYPMOD_IN = {}", name),
UserDefinedTypeSqlDefinitionOption::TypmodOut(name) => {
write!(f, "TYPMOD_OUT = {}", name)
}
UserDefinedTypeSqlDefinitionOption::Analyze(name) => write!(f, "ANALYZE = {}", name),
UserDefinedTypeSqlDefinitionOption::Subscript(name) => {
write!(f, "SUBSCRIPT = {}", name)
}
UserDefinedTypeSqlDefinitionOption::InternalLength(len) => {
write!(f, "INTERNALLENGTH = {}", len)
}
UserDefinedTypeSqlDefinitionOption::PassedByValue => write!(f, "PASSEDBYVALUE"),
UserDefinedTypeSqlDefinitionOption::Alignment(align) => {
write!(f, "ALIGNMENT = {}", align)
}
UserDefinedTypeSqlDefinitionOption::Storage(storage) => {
write!(f, "STORAGE = {}", storage)
}
UserDefinedTypeSqlDefinitionOption::Like(name) => write!(f, "LIKE = {}", name),
UserDefinedTypeSqlDefinitionOption::Category(c) => write!(f, "CATEGORY = '{}'", c),
UserDefinedTypeSqlDefinitionOption::Preferred(b) => write!(f, "PREFERRED = {}", b),
UserDefinedTypeSqlDefinitionOption::Default(expr) => write!(f, "DEFAULT = {}", expr),
UserDefinedTypeSqlDefinitionOption::Element(dt) => write!(f, "ELEMENT = {}", dt),
UserDefinedTypeSqlDefinitionOption::Delimiter(s) => {
write!(f, "DELIMITER = '{}'", escape_single_quote_string(s))
}
UserDefinedTypeSqlDefinitionOption::Collatable(b) => write!(f, "COLLATABLE = {}", b),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum Partition {
Identifier(Ident),
Expr(Expr),
Part(Expr),
Partitions(Vec<Expr>),
}
impl fmt::Display for Partition {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Partition::Identifier(id) => write!(f, "PARTITION ID {id}"),
Partition::Expr(expr) => write!(f, "PARTITION {expr}"),
Partition::Part(expr) => write!(f, "PART {expr}"),
Partition::Partitions(partitions) => {
write!(f, "PARTITION ({})", display_comma_separated(partitions))
}
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum Deduplicate {
All,
ByExpression(Expr),
}
impl fmt::Display for Deduplicate {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Deduplicate::All => write!(f, "DEDUPLICATE"),
Deduplicate::ByExpression(expr) => write!(f, "DEDUPLICATE BY {expr}"),
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct ClusteredBy {
pub columns: Vec<Ident>,
pub sorted_by: Option<Vec<OrderByExpr>>,
pub num_buckets: Value,
}
impl fmt::Display for ClusteredBy {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"CLUSTERED BY ({})",
display_comma_separated(&self.columns)
)?;
if let Some(ref sorted_by) = self.sorted_by {
write!(f, " SORTED BY ({})", display_comma_separated(sorted_by))?;
}
write!(f, " INTO {} BUCKETS", self.num_buckets)
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct CreateIndex {
pub name: Option<ObjectName>,
#[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
pub table_name: ObjectName,
pub using: Option<IndexType>,
pub columns: Vec<IndexColumn>,
pub unique: bool,
pub concurrently: bool,
pub if_not_exists: bool,
pub include: Vec<Ident>,
pub nulls_distinct: Option<bool>,
pub with: Vec<Expr>,
pub predicate: Option<Expr>,
pub index_options: Vec<IndexOption>,
pub alter_options: Vec<AlterTableOperation>,
}
impl fmt::Display for CreateIndex {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"CREATE {unique}INDEX {concurrently}{if_not_exists}",
unique = if self.unique { "UNIQUE " } else { "" },
concurrently = if self.concurrently {
"CONCURRENTLY "
} else {
""
},
if_not_exists = if self.if_not_exists {
"IF NOT EXISTS "
} else {
""
},
)?;
if let Some(value) = &self.name {
write!(f, "{value} ")?;
}
write!(f, "ON {}", self.table_name)?;
if let Some(value) = &self.using {
write!(f, " USING {value} ")?;
}
write!(f, "({})", display_comma_separated(&self.columns))?;
if !self.include.is_empty() {
write!(f, " INCLUDE ({})", display_comma_separated(&self.include))?;
}
if let Some(value) = self.nulls_distinct {
if value {
write!(f, " NULLS DISTINCT")?;
} else {
write!(f, " NULLS NOT DISTINCT")?;
}
}
if !self.with.is_empty() {
write!(f, " WITH ({})", display_comma_separated(&self.with))?;
}
if let Some(predicate) = &self.predicate {
write!(f, " WHERE {predicate}")?;
}
if !self.index_options.is_empty() {
write!(f, " {}", display_separated(&self.index_options, " "))?;
}
if !self.alter_options.is_empty() {
write!(f, " {}", display_separated(&self.alter_options, " "))?;
}
Ok(())
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct CreateTable {
pub or_replace: bool,
pub temporary: bool,
pub external: bool,
pub dynamic: bool,
pub global: Option<bool>,
pub if_not_exists: bool,
pub transient: bool,
pub volatile: bool,
pub iceberg: bool,
#[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
pub name: ObjectName,
pub columns: Vec<ColumnDef>,
pub constraints: Vec<TableConstraint>,
pub hive_distribution: HiveDistributionStyle,
pub hive_formats: Option<HiveFormat>,
pub table_options: CreateTableOptions,
pub file_format: Option<FileFormat>,
pub location: Option<String>,
pub query: Option<Box<Query>>,
pub without_rowid: bool,
pub like: Option<CreateTableLikeKind>,
pub clone: Option<ObjectName>,
pub version: Option<TableVersion>,
pub comment: Option<CommentDef>,
pub on_commit: Option<OnCommit>,
pub on_cluster: Option<Ident>,
pub primary_key: Option<Box<Expr>>,
pub order_by: Option<OneOrManyWithParens<Expr>>,
pub partition_by: Option<Box<Expr>>,
pub cluster_by: Option<WrappedCollection<Vec<Expr>>>,
pub clustered_by: Option<ClusteredBy>,
pub inherits: Option<Vec<ObjectName>>,
#[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
pub partition_of: Option<ObjectName>,
pub for_values: Option<ForValues>,
pub strict: bool,
pub copy_grants: bool,
pub enable_schema_evolution: Option<bool>,
pub change_tracking: Option<bool>,
pub data_retention_time_in_days: Option<u64>,
pub max_data_extension_time_in_days: Option<u64>,
pub default_ddl_collation: Option<String>,
pub with_aggregation_policy: Option<ObjectName>,
pub with_row_access_policy: Option<RowAccessPolicy>,
pub with_tags: Option<Vec<Tag>>,
pub external_volume: Option<String>,
pub base_location: Option<String>,
pub catalog: Option<String>,
pub catalog_sync: Option<String>,
pub storage_serialization_policy: Option<StorageSerializationPolicy>,
pub target_lag: Option<String>,
pub warehouse: Option<Ident>,
pub refresh_mode: Option<RefreshModeKind>,
pub initialize: Option<InitializeKind>,
pub require_user: bool,
}
impl fmt::Display for CreateTable {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"CREATE {or_replace}{external}{global}{temporary}{transient}{volatile}{dynamic}{iceberg}TABLE {if_not_exists}{name}",
or_replace = if self.or_replace { "OR REPLACE " } else { "" },
external = if self.external { "EXTERNAL " } else { "" },
global = self.global
.map(|global| {
if global {
"GLOBAL "
} else {
"LOCAL "
}
})
.unwrap_or(""),
if_not_exists = if self.if_not_exists { "IF NOT EXISTS " } else { "" },
temporary = if self.temporary { "TEMPORARY " } else { "" },
transient = if self.transient { "TRANSIENT " } else { "" },
volatile = if self.volatile { "VOLATILE " } else { "" },
iceberg = if self.iceberg { "ICEBERG " } else { "" },
dynamic = if self.dynamic { "DYNAMIC " } else { "" },
name = self.name,
)?;
if let Some(partition_of) = &self.partition_of {
write!(f, " PARTITION OF {partition_of}")?;
}
if let Some(on_cluster) = &self.on_cluster {
write!(f, " ON CLUSTER {on_cluster}")?;
}
if !self.columns.is_empty() || !self.constraints.is_empty() {
f.write_str(" (")?;
NewLine.fmt(f)?;
Indent(DisplayCommaSeparated(&self.columns)).fmt(f)?;
if !self.columns.is_empty() && !self.constraints.is_empty() {
f.write_str(",")?;
SpaceOrNewline.fmt(f)?;
}
Indent(DisplayCommaSeparated(&self.constraints)).fmt(f)?;
NewLine.fmt(f)?;
f.write_str(")")?;
} else if self.query.is_none()
&& self.like.is_none()
&& self.clone.is_none()
&& self.partition_of.is_none()
{
f.write_str(" ()")?;
} else if let Some(CreateTableLikeKind::Parenthesized(like_in_columns_list)) = &self.like {
write!(f, " ({like_in_columns_list})")?;
}
if let Some(for_values) = &self.for_values {
write!(f, " {for_values}")?;
}
if let Some(comment) = &self.comment {
write!(f, " COMMENT '{comment}'")?;
}
if self.without_rowid {
write!(f, " WITHOUT ROWID")?;
}
if let Some(CreateTableLikeKind::Plain(like)) = &self.like {
write!(f, " {like}")?;
}
if let Some(c) = &self.clone {
write!(f, " CLONE {c}")?;
}
if let Some(version) = &self.version {
write!(f, " {version}")?;
}
match &self.hive_distribution {
HiveDistributionStyle::PARTITIONED { columns } => {
write!(f, " PARTITIONED BY ({})", display_comma_separated(columns))?;
}
HiveDistributionStyle::SKEWED {
columns,
on,
stored_as_directories,
} => {
write!(
f,
" SKEWED BY ({})) ON ({})",
display_comma_separated(columns),
display_comma_separated(on)
)?;
if *stored_as_directories {
write!(f, " STORED AS DIRECTORIES")?;
}
}
_ => (),
}
if let Some(clustered_by) = &self.clustered_by {
write!(f, " {clustered_by}")?;
}
if let Some(HiveFormat {
row_format,
serde_properties,
storage,
location,
}) = &self.hive_formats
{
match row_format {
Some(HiveRowFormat::SERDE { class }) => write!(f, " ROW FORMAT SERDE '{class}'")?,
Some(HiveRowFormat::DELIMITED { delimiters }) => {
write!(f, " ROW FORMAT DELIMITED")?;
if !delimiters.is_empty() {
write!(f, " {}", display_separated(delimiters, " "))?;
}
}
None => (),
}
match storage {
Some(HiveIOFormat::IOF {
input_format,
output_format,
}) => write!(
f,
" STORED AS INPUTFORMAT {input_format} OUTPUTFORMAT {output_format}"
)?,
Some(HiveIOFormat::FileFormat { format }) if !self.external => {
write!(f, " STORED AS {format}")?
}
_ => (),
}
if let Some(serde_properties) = serde_properties.as_ref() {
write!(
f,
" WITH SERDEPROPERTIES ({})",
display_comma_separated(serde_properties)
)?;
}
if !self.external {
if let Some(loc) = location {
write!(f, " LOCATION '{loc}'")?;
}
}
}
if self.external {
if let Some(file_format) = self.file_format {
write!(f, " STORED AS {file_format}")?;
}
if let Some(location) = &self.location {
write!(f, " LOCATION '{location}'")?;
}
}
match &self.table_options {
options @ CreateTableOptions::With(_)
| options @ CreateTableOptions::Plain(_)
| options @ CreateTableOptions::TableProperties(_) => write!(f, " {options}")?,
_ => (),
}
if let Some(primary_key) = &self.primary_key {
write!(f, " PRIMARY KEY {primary_key}")?;
}
if let Some(order_by) = &self.order_by {
write!(f, " ORDER BY {order_by}")?;
}
if let Some(inherits) = &self.inherits {
write!(f, " INHERITS ({})", display_comma_separated(inherits))?;
}
if let Some(partition_by) = self.partition_by.as_ref() {
write!(f, " PARTITION BY {partition_by}")?;
}
if let Some(cluster_by) = self.cluster_by.as_ref() {
write!(f, " CLUSTER BY {cluster_by}")?;
}
if let options @ CreateTableOptions::Options(_) = &self.table_options {
write!(f, " {options}")?;
}
if let Some(external_volume) = self.external_volume.as_ref() {
write!(f, " EXTERNAL_VOLUME='{external_volume}'")?;
}
if let Some(catalog) = self.catalog.as_ref() {
write!(f, " CATALOG='{catalog}'")?;
}
if self.iceberg {
if let Some(base_location) = self.base_location.as_ref() {
write!(f, " BASE_LOCATION='{base_location}'")?;
}
}
if let Some(catalog_sync) = self.catalog_sync.as_ref() {
write!(f, " CATALOG_SYNC='{catalog_sync}'")?;
}
if let Some(storage_serialization_policy) = self.storage_serialization_policy.as_ref() {
write!(
f,
" STORAGE_SERIALIZATION_POLICY={storage_serialization_policy}"
)?;
}
if self.copy_grants {
write!(f, " COPY GRANTS")?;
}
if let Some(is_enabled) = self.enable_schema_evolution {
write!(
f,
" ENABLE_SCHEMA_EVOLUTION={}",
if is_enabled { "TRUE" } else { "FALSE" }
)?;
}
if let Some(is_enabled) = self.change_tracking {
write!(
f,
" CHANGE_TRACKING={}",
if is_enabled { "TRUE" } else { "FALSE" }
)?;
}
if let Some(data_retention_time_in_days) = self.data_retention_time_in_days {
write!(
f,
" DATA_RETENTION_TIME_IN_DAYS={data_retention_time_in_days}",
)?;
}
if let Some(max_data_extension_time_in_days) = self.max_data_extension_time_in_days {
write!(
f,
" MAX_DATA_EXTENSION_TIME_IN_DAYS={max_data_extension_time_in_days}",
)?;
}
if let Some(default_ddl_collation) = &self.default_ddl_collation {
write!(f, " DEFAULT_DDL_COLLATION='{default_ddl_collation}'",)?;
}
if let Some(with_aggregation_policy) = &self.with_aggregation_policy {
write!(f, " WITH AGGREGATION POLICY {with_aggregation_policy}",)?;
}
if let Some(row_access_policy) = &self.with_row_access_policy {
write!(f, " {row_access_policy}",)?;
}
if let Some(tag) = &self.with_tags {
write!(f, " WITH TAG ({})", display_comma_separated(tag.as_slice()))?;
}
if let Some(target_lag) = &self.target_lag {
write!(f, " TARGET_LAG='{target_lag}'")?;
}
if let Some(warehouse) = &self.warehouse {
write!(f, " WAREHOUSE={warehouse}")?;
}
if let Some(refresh_mode) = &self.refresh_mode {
write!(f, " REFRESH_MODE={refresh_mode}")?;
}
if let Some(initialize) = &self.initialize {
write!(f, " INITIALIZE={initialize}")?;
}
if self.require_user {
write!(f, " REQUIRE USER")?;
}
if self.on_commit.is_some() {
let on_commit = match self.on_commit {
Some(OnCommit::DeleteRows) => "ON COMMIT DELETE ROWS",
Some(OnCommit::PreserveRows) => "ON COMMIT PRESERVE ROWS",
Some(OnCommit::Drop) => "ON COMMIT DROP",
None => "",
};
write!(f, " {on_commit}")?;
}
if self.strict {
write!(f, " STRICT")?;
}
if let Some(query) = &self.query {
write!(f, " AS {query}")?;
}
Ok(())
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum ForValues {
In(Vec<Expr>),
From {
from: Vec<PartitionBoundValue>,
to: Vec<PartitionBoundValue>,
},
With {
modulus: u64,
remainder: u64,
},
Default,
}
impl fmt::Display for ForValues {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
ForValues::In(values) => {
write!(f, "FOR VALUES IN ({})", display_comma_separated(values))
}
ForValues::From { from, to } => {
write!(
f,
"FOR VALUES FROM ({}) TO ({})",
display_comma_separated(from),
display_comma_separated(to)
)
}
ForValues::With { modulus, remainder } => {
write!(
f,
"FOR VALUES WITH (MODULUS {modulus}, REMAINDER {remainder})"
)
}
ForValues::Default => write!(f, "DEFAULT"),
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum PartitionBoundValue {
Expr(Expr),
MinValue,
MaxValue,
}
impl fmt::Display for PartitionBoundValue {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
PartitionBoundValue::Expr(expr) => write!(f, "{expr}"),
PartitionBoundValue::MinValue => write!(f, "MINVALUE"),
PartitionBoundValue::MaxValue => write!(f, "MAXVALUE"),
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct CreateDomain {
pub name: ObjectName,
pub data_type: DataType,
pub collation: Option<Ident>,
pub default: Option<Expr>,
pub constraints: Vec<TableConstraint>,
}
impl fmt::Display for CreateDomain {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"CREATE DOMAIN {name} AS {data_type}",
name = self.name,
data_type = self.data_type
)?;
if let Some(collation) = &self.collation {
write!(f, " COLLATE {collation}")?;
}
if let Some(default) = &self.default {
write!(f, " DEFAULT {default}")?;
}
if !self.constraints.is_empty() {
write!(f, " {}", display_separated(&self.constraints, " "))?;
}
Ok(())
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct CreateFunction {
pub or_alter: bool,
pub or_replace: bool,
pub temporary: bool,
pub if_not_exists: bool,
pub name: ObjectName,
pub args: Option<Vec<OperateFunctionArg>>,
pub return_type: Option<DataType>,
pub function_body: Option<CreateFunctionBody>,
pub behavior: Option<FunctionBehavior>,
pub called_on_null: Option<FunctionCalledOnNull>,
pub parallel: Option<FunctionParallel>,
pub security: Option<FunctionSecurity>,
pub set_params: Vec<FunctionDefinitionSetParam>,
pub using: Option<CreateFunctionUsing>,
pub language: Option<Ident>,
pub determinism_specifier: Option<FunctionDeterminismSpecifier>,
pub options: Option<Vec<SqlOption>>,
pub remote_connection: Option<ObjectName>,
}
impl fmt::Display for CreateFunction {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"CREATE {or_alter}{or_replace}{temp}FUNCTION {if_not_exists}{name}",
name = self.name,
temp = if self.temporary { "TEMPORARY " } else { "" },
or_alter = if self.or_alter { "OR ALTER " } else { "" },
or_replace = if self.or_replace { "OR REPLACE " } else { "" },
if_not_exists = if self.if_not_exists {
"IF NOT EXISTS "
} else {
""
},
)?;
if let Some(args) = &self.args {
write!(f, "({})", display_comma_separated(args))?;
}
if let Some(return_type) = &self.return_type {
write!(f, " RETURNS {return_type}")?;
}
if let Some(determinism_specifier) = &self.determinism_specifier {
write!(f, " {determinism_specifier}")?;
}
if let Some(language) = &self.language {
write!(f, " LANGUAGE {language}")?;
}
if let Some(behavior) = &self.behavior {
write!(f, " {behavior}")?;
}
if let Some(called_on_null) = &self.called_on_null {
write!(f, " {called_on_null}")?;
}
if let Some(parallel) = &self.parallel {
write!(f, " {parallel}")?;
}
if let Some(security) = &self.security {
write!(f, " {security}")?;
}
for set_param in &self.set_params {
write!(f, " {set_param}")?;
}
if let Some(remote_connection) = &self.remote_connection {
write!(f, " REMOTE WITH CONNECTION {remote_connection}")?;
}
if let Some(CreateFunctionBody::AsBeforeOptions { body, link_symbol }) = &self.function_body
{
write!(f, " AS {body}")?;
if let Some(link_symbol) = link_symbol {
write!(f, ", {link_symbol}")?;
}
}
if let Some(CreateFunctionBody::Return(function_body)) = &self.function_body {
write!(f, " RETURN {function_body}")?;
}
if let Some(CreateFunctionBody::AsReturnExpr(function_body)) = &self.function_body {
write!(f, " AS RETURN {function_body}")?;
}
if let Some(CreateFunctionBody::AsReturnSelect(function_body)) = &self.function_body {
write!(f, " AS RETURN {function_body}")?;
}
if let Some(using) = &self.using {
write!(f, " {using}")?;
}
if let Some(options) = &self.options {
write!(
f,
" OPTIONS({})",
display_comma_separated(options.as_slice())
)?;
}
if let Some(CreateFunctionBody::AsAfterOptions(function_body)) = &self.function_body {
write!(f, " AS {function_body}")?;
}
if let Some(CreateFunctionBody::AsBeginEnd(bes)) = &self.function_body {
write!(f, " AS {bes}")?;
}
Ok(())
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct CreateConnector {
pub name: Ident,
pub if_not_exists: bool,
pub connector_type: Option<String>,
pub url: Option<String>,
pub comment: Option<CommentDef>,
pub with_dcproperties: Option<Vec<SqlOption>>,
}
impl fmt::Display for CreateConnector {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"CREATE CONNECTOR {if_not_exists}{name}",
if_not_exists = if self.if_not_exists {
"IF NOT EXISTS "
} else {
""
},
name = self.name,
)?;
if let Some(connector_type) = &self.connector_type {
write!(f, " TYPE '{connector_type}'")?;
}
if let Some(url) = &self.url {
write!(f, " URL '{url}'")?;
}
if let Some(comment) = &self.comment {
write!(f, " COMMENT = '{comment}'")?;
}
if let Some(with_dcproperties) = &self.with_dcproperties {
write!(
f,
" WITH DCPROPERTIES({})",
display_comma_separated(with_dcproperties)
)?;
}
Ok(())
}
}
#[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>,
},
Rename {
name: ObjectName,
},
OwnerTo {
owner: Owner,
},
}
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))
}
AlterSchemaOperation::Rename { name } => write!(f, "RENAME TO {name}"),
AlterSchemaOperation::OwnerTo { owner } => write!(f, "OWNER TO {owner}"),
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum RenameTableNameKind {
As(ObjectName),
To(ObjectName),
}
impl fmt::Display for RenameTableNameKind {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
RenameTableNameKind::As(name) => write!(f, "AS {name}"),
RenameTableNameKind::To(name) => write!(f, "TO {name}"),
}
}
}
#[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 {
RenameTableNameKind::As(name) => name.span(),
RenameTableNameKind::To(name) => name.span(),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum TriggerObjectKind {
For(TriggerObject),
ForEach(TriggerObject),
}
impl Display for TriggerObjectKind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
TriggerObjectKind::For(obj) => write!(f, "FOR {obj}"),
TriggerObjectKind::ForEach(obj) => write!(f, "FOR EACH {obj}"),
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct CreateTrigger {
pub or_alter: bool,
pub temporary: bool,
pub or_replace: bool,
pub is_constraint: bool,
pub name: ObjectName,
pub period: Option<TriggerPeriod>,
pub period_before_table: bool,
pub events: Vec<TriggerEvent>,
pub table_name: ObjectName,
pub referenced_table_name: Option<ObjectName>,
pub referencing: Vec<TriggerReferencing>,
pub trigger_object: Option<TriggerObjectKind>,
pub condition: Option<Expr>,
pub exec_body: Option<TriggerExecBody>,
pub statements_as: bool,
pub statements: Option<ConditionalStatements>,
pub characteristics: Option<ConstraintCharacteristics>,
}
impl Display for CreateTrigger {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let CreateTrigger {
or_alter,
temporary,
or_replace,
is_constraint,
name,
period_before_table,
period,
events,
table_name,
referenced_table_name,
referencing,
trigger_object,
condition,
exec_body,
statements_as,
statements,
characteristics,
} = self;
write!(
f,
"CREATE {temporary}{or_alter}{or_replace}{is_constraint}TRIGGER {name} ",
temporary = if *temporary { "TEMPORARY " } else { "" },
or_alter = if *or_alter { "OR ALTER " } else { "" },
or_replace = if *or_replace { "OR REPLACE " } else { "" },
is_constraint = if *is_constraint { "CONSTRAINT " } else { "" },
)?;
if *period_before_table {
if let Some(p) = period {
write!(f, "{p} ")?;
}
if !events.is_empty() {
write!(f, "{} ", display_separated(events, " OR "))?;
}
write!(f, "ON {table_name}")?;
} else {
write!(f, "ON {table_name} ")?;
if let Some(p) = period {
write!(f, "{p}")?;
}
if !events.is_empty() {
write!(f, " {}", display_separated(events, ", "))?;
}
}
if let Some(referenced_table_name) = referenced_table_name {
write!(f, " FROM {referenced_table_name}")?;
}
if let Some(characteristics) = characteristics {
write!(f, " {characteristics}")?;
}
if !referencing.is_empty() {
write!(f, " REFERENCING {}", display_separated(referencing, " "))?;
}
if let Some(trigger_object) = trigger_object {
write!(f, " {trigger_object}")?;
}
if let Some(condition) = condition {
write!(f, " WHEN {condition}")?;
}
if let Some(exec_body) = exec_body {
write!(f, " EXECUTE {exec_body}")?;
}
if let Some(statements) = statements {
if *statements_as {
write!(f, " AS")?;
}
write!(f, " {statements}")?;
}
Ok(())
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct DropTrigger {
pub if_exists: bool,
pub trigger_name: ObjectName,
pub table_name: Option<ObjectName>,
pub option: Option<ReferentialAction>,
}
impl fmt::Display for DropTrigger {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let DropTrigger {
if_exists,
trigger_name,
table_name,
option,
} = self;
write!(f, "DROP TRIGGER")?;
if *if_exists {
write!(f, " IF EXISTS")?;
}
match &table_name {
Some(table_name) => write!(f, " {trigger_name} ON {table_name}")?,
None => write!(f, " {trigger_name}")?,
};
if let Some(option) = option {
write!(f, " {option}")?;
}
Ok(())
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct Truncate {
pub table_names: Vec<super::TruncateTableTarget>,
pub partitions: Option<Vec<Expr>>,
pub table: bool,
pub if_exists: bool,
pub identity: Option<super::TruncateIdentityOption>,
pub cascade: Option<super::CascadeOption>,
pub on_cluster: Option<Ident>,
}
impl fmt::Display for Truncate {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let table = if self.table { "TABLE " } else { "" };
let if_exists = if self.if_exists { "IF EXISTS " } else { "" };
write!(
f,
"TRUNCATE {table}{if_exists}{table_names}",
table_names = display_comma_separated(&self.table_names)
)?;
if let Some(identity) = &self.identity {
match identity {
super::TruncateIdentityOption::Restart => write!(f, " RESTART IDENTITY")?,
super::TruncateIdentityOption::Continue => write!(f, " CONTINUE IDENTITY")?,
}
}
if let Some(cascade) = &self.cascade {
match cascade {
super::CascadeOption::Cascade => write!(f, " CASCADE")?,
super::CascadeOption::Restrict => write!(f, " RESTRICT")?,
}
}
if let Some(ref parts) = &self.partitions {
if !parts.is_empty() {
write!(f, " PARTITION ({})", display_comma_separated(parts))?;
}
}
if let Some(on_cluster) = &self.on_cluster {
write!(f, " ON CLUSTER {on_cluster}")?;
}
Ok(())
}
}
impl Spanned for Truncate {
fn span(&self) -> Span {
Span::union_iter(
self.table_names.iter().map(|i| i.name.span()).chain(
self.partitions
.iter()
.flat_map(|i| i.iter().map(|k| k.span())),
),
)
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct Msck {
#[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
pub table_name: ObjectName,
pub repair: bool,
pub partition_action: Option<super::AddDropSync>,
}
impl fmt::Display for Msck {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"MSCK {repair}TABLE {table}",
repair = if self.repair { "REPAIR " } else { "" },
table = self.table_name
)?;
if let Some(pa) = &self.partition_action {
write!(f, " {pa}")?;
}
Ok(())
}
}
impl Spanned for Msck {
fn span(&self) -> Span {
self.table_name.span()
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct CreateView {
pub or_alter: bool,
pub or_replace: bool,
pub materialized: bool,
pub secure: bool,
pub name: ObjectName,
pub name_before_not_exists: bool,
pub columns: Vec<ViewColumnDef>,
pub query: Box<Query>,
pub options: CreateTableOptions,
pub cluster_by: Vec<Ident>,
pub comment: Option<String>,
pub with_no_schema_binding: bool,
pub if_not_exists: bool,
pub temporary: bool,
pub to: Option<ObjectName>,
pub params: Option<CreateViewParams>,
}
impl fmt::Display for CreateView {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"CREATE {or_alter}{or_replace}",
or_alter = if self.or_alter { "OR ALTER " } else { "" },
or_replace = if self.or_replace { "OR REPLACE " } else { "" },
)?;
if let Some(ref params) = self.params {
params.fmt(f)?;
}
write!(
f,
"{secure}{materialized}{temporary}VIEW {if_not_and_name}{to}",
if_not_and_name = if self.if_not_exists {
if self.name_before_not_exists {
format!("{} IF NOT EXISTS", self.name)
} else {
format!("IF NOT EXISTS {}", self.name)
}
} else {
format!("{}", self.name)
},
secure = if self.secure { "SECURE " } else { "" },
materialized = if self.materialized {
"MATERIALIZED "
} else {
""
},
temporary = if self.temporary { "TEMPORARY " } else { "" },
to = self
.to
.as_ref()
.map(|to| format!(" TO {to}"))
.unwrap_or_default()
)?;
if !self.columns.is_empty() {
write!(f, " ({})", display_comma_separated(&self.columns))?;
}
if matches!(self.options, CreateTableOptions::With(_)) {
write!(f, " {}", self.options)?;
}
if let Some(ref comment) = self.comment {
write!(f, " COMMENT = '{}'", escape_single_quote_string(comment))?;
}
if !self.cluster_by.is_empty() {
write!(
f,
" CLUSTER BY ({})",
display_comma_separated(&self.cluster_by)
)?;
}
if matches!(self.options, CreateTableOptions::Options(_)) {
write!(f, " {}", self.options)?;
}
f.write_str(" AS")?;
SpaceOrNewline.fmt(f)?;
self.query.fmt(f)?;
if self.with_no_schema_binding {
write!(f, " WITH NO SCHEMA BINDING")?;
}
Ok(())
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct CreateExtension {
pub name: Ident,
pub if_not_exists: bool,
pub cascade: bool,
pub schema: Option<Ident>,
pub version: Option<Ident>,
}
impl fmt::Display for CreateExtension {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"CREATE EXTENSION {if_not_exists}{name}",
if_not_exists = if self.if_not_exists {
"IF NOT EXISTS "
} else {
""
},
name = self.name
)?;
if self.cascade || self.schema.is_some() || self.version.is_some() {
write!(f, " WITH")?;
if let Some(name) = &self.schema {
write!(f, " SCHEMA {name}")?;
}
if let Some(version) = &self.version {
write!(f, " VERSION {version}")?;
}
if self.cascade {
write!(f, " CASCADE")?;
}
}
Ok(())
}
}
impl Spanned for CreateExtension {
fn span(&self) -> Span {
Span::empty()
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct DropExtension {
pub names: Vec<Ident>,
pub if_exists: bool,
pub cascade_or_restrict: Option<ReferentialAction>,
}
impl fmt::Display for DropExtension {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "DROP EXTENSION")?;
if self.if_exists {
write!(f, " IF EXISTS")?;
}
write!(f, " {}", display_comma_separated(&self.names))?;
if let Some(cascade_or_restrict) = &self.cascade_or_restrict {
write!(f, " {cascade_or_restrict}")?;
}
Ok(())
}
}
impl Spanned for DropExtension {
fn span(&self) -> Span {
Span::empty()
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum AlterTableType {
Iceberg,
Dynamic,
External,
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct AlterTable {
#[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
pub name: ObjectName,
pub if_exists: bool,
pub only: bool,
pub operations: Vec<AlterTableOperation>,
pub location: Option<HiveSetLocation>,
pub on_cluster: Option<Ident>,
pub table_type: Option<AlterTableType>,
pub end_token: AttachedToken,
}
impl fmt::Display for AlterTable {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match &self.table_type {
Some(AlterTableType::Iceberg) => write!(f, "ALTER ICEBERG TABLE ")?,
Some(AlterTableType::Dynamic) => write!(f, "ALTER DYNAMIC TABLE ")?,
Some(AlterTableType::External) => write!(f, "ALTER EXTERNAL TABLE ")?,
None => write!(f, "ALTER TABLE ")?,
}
if self.if_exists {
write!(f, "IF EXISTS ")?;
}
if self.only {
write!(f, "ONLY ")?;
}
write!(f, "{} ", &self.name)?;
if let Some(cluster) = &self.on_cluster {
write!(f, "ON CLUSTER {cluster} ")?;
}
write!(f, "{}", display_comma_separated(&self.operations))?;
if let Some(loc) = &self.location {
write!(f, " {loc}")?
}
Ok(())
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct DropFunction {
pub if_exists: bool,
pub func_desc: Vec<FunctionDesc>,
pub drop_behavior: Option<DropBehavior>,
}
impl fmt::Display for DropFunction {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"DROP FUNCTION{} {}",
if self.if_exists { " IF EXISTS" } else { "" },
display_comma_separated(&self.func_desc),
)?;
if let Some(op) = &self.drop_behavior {
write!(f, " {op}")?;
}
Ok(())
}
}
impl Spanned for DropFunction {
fn span(&self) -> Span {
Span::empty()
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct CreateOperator {
pub name: ObjectName,
pub function: ObjectName,
pub is_procedure: bool,
pub left_arg: Option<DataType>,
pub right_arg: Option<DataType>,
pub options: Vec<OperatorOption>,
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct CreateOperatorFamily {
pub name: ObjectName,
pub using: Ident,
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct CreateOperatorClass {
pub name: ObjectName,
pub default: bool,
pub for_type: DataType,
pub using: Ident,
pub family: Option<ObjectName>,
pub items: Vec<OperatorClassItem>,
}
impl fmt::Display for CreateOperator {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "CREATE OPERATOR {} (", self.name)?;
let function_keyword = if self.is_procedure {
"PROCEDURE"
} else {
"FUNCTION"
};
let mut params = vec![format!("{} = {}", function_keyword, self.function)];
if let Some(left_arg) = &self.left_arg {
params.push(format!("LEFTARG = {}", left_arg));
}
if let Some(right_arg) = &self.right_arg {
params.push(format!("RIGHTARG = {}", right_arg));
}
for option in &self.options {
params.push(option.to_string());
}
write!(f, "{}", params.join(", "))?;
write!(f, ")")
}
}
impl fmt::Display for CreateOperatorFamily {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"CREATE OPERATOR FAMILY {} USING {}",
self.name, self.using
)
}
}
impl fmt::Display for CreateOperatorClass {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "CREATE OPERATOR CLASS {}", self.name)?;
if self.default {
write!(f, " DEFAULT")?;
}
write!(f, " FOR TYPE {} USING {}", self.for_type, self.using)?;
if let Some(family) = &self.family {
write!(f, " FAMILY {}", family)?;
}
write!(f, " AS {}", display_comma_separated(&self.items))
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct OperatorArgTypes {
pub left: DataType,
pub right: DataType,
}
impl fmt::Display for OperatorArgTypes {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}, {}", self.left, self.right)
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum OperatorClassItem {
Operator {
strategy_number: u64,
operator_name: ObjectName,
op_types: Option<OperatorArgTypes>,
purpose: Option<OperatorPurpose>,
},
Function {
support_number: u64,
op_types: Option<Vec<DataType>>,
function_name: ObjectName,
argument_types: Vec<DataType>,
},
Storage {
storage_type: DataType,
},
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum OperatorPurpose {
ForSearch,
ForOrderBy {
sort_family: ObjectName,
},
}
impl fmt::Display for OperatorClassItem {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
OperatorClassItem::Operator {
strategy_number,
operator_name,
op_types,
purpose,
} => {
write!(f, "OPERATOR {strategy_number} {operator_name}")?;
if let Some(types) = op_types {
write!(f, " ({types})")?;
}
if let Some(purpose) = purpose {
write!(f, " {purpose}")?;
}
Ok(())
}
OperatorClassItem::Function {
support_number,
op_types,
function_name,
argument_types,
} => {
write!(f, "FUNCTION {support_number}")?;
if let Some(types) = op_types {
write!(f, " ({})", display_comma_separated(types))?;
}
write!(f, " {function_name}")?;
if !argument_types.is_empty() {
write!(f, "({})", display_comma_separated(argument_types))?;
}
Ok(())
}
OperatorClassItem::Storage { storage_type } => {
write!(f, "STORAGE {storage_type}")
}
}
}
}
impl fmt::Display for OperatorPurpose {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
OperatorPurpose::ForSearch => write!(f, "FOR SEARCH"),
OperatorPurpose::ForOrderBy { sort_family } => {
write!(f, "FOR ORDER BY {sort_family}")
}
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct DropOperator {
pub if_exists: bool,
pub operators: Vec<DropOperatorSignature>,
pub drop_behavior: Option<DropBehavior>,
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct DropOperatorSignature {
pub name: ObjectName,
pub left_type: Option<DataType>,
pub right_type: DataType,
}
impl fmt::Display for DropOperatorSignature {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{} (", self.name)?;
if let Some(left_type) = &self.left_type {
write!(f, "{}", left_type)?;
} else {
write!(f, "NONE")?;
}
write!(f, ", {})", self.right_type)
}
}
impl fmt::Display for DropOperator {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "DROP OPERATOR")?;
if self.if_exists {
write!(f, " IF EXISTS")?;
}
write!(f, " {}", display_comma_separated(&self.operators))?;
if let Some(drop_behavior) = &self.drop_behavior {
write!(f, " {}", drop_behavior)?;
}
Ok(())
}
}
impl Spanned for DropOperator {
fn span(&self) -> Span {
Span::empty()
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct DropOperatorFamily {
pub if_exists: bool,
pub names: Vec<ObjectName>,
pub using: Ident,
pub drop_behavior: Option<DropBehavior>,
}
impl fmt::Display for DropOperatorFamily {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "DROP OPERATOR FAMILY")?;
if self.if_exists {
write!(f, " IF EXISTS")?;
}
write!(f, " {}", display_comma_separated(&self.names))?;
write!(f, " USING {}", self.using)?;
if let Some(drop_behavior) = &self.drop_behavior {
write!(f, " {}", drop_behavior)?;
}
Ok(())
}
}
impl Spanned for DropOperatorFamily {
fn span(&self) -> Span {
Span::empty()
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct DropOperatorClass {
pub if_exists: bool,
pub names: Vec<ObjectName>,
pub using: Ident,
pub drop_behavior: Option<DropBehavior>,
}
impl fmt::Display for DropOperatorClass {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "DROP OPERATOR CLASS")?;
if self.if_exists {
write!(f, " IF EXISTS")?;
}
write!(f, " {}", display_comma_separated(&self.names))?;
write!(f, " USING {}", self.using)?;
if let Some(drop_behavior) = &self.drop_behavior {
write!(f, " {}", drop_behavior)?;
}
Ok(())
}
}
impl Spanned for DropOperatorClass {
fn span(&self) -> Span {
Span::empty()
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum OperatorFamilyItem {
Operator {
strategy_number: u64,
operator_name: ObjectName,
op_types: Vec<DataType>,
purpose: Option<OperatorPurpose>,
},
Function {
support_number: u64,
op_types: Option<Vec<DataType>>,
function_name: ObjectName,
argument_types: Vec<DataType>,
},
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum OperatorFamilyDropItem {
Operator {
strategy_number: u64,
op_types: Vec<DataType>,
},
Function {
support_number: u64,
op_types: Vec<DataType>,
},
}
impl fmt::Display for OperatorFamilyItem {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
OperatorFamilyItem::Operator {
strategy_number,
operator_name,
op_types,
purpose,
} => {
write!(
f,
"OPERATOR {strategy_number} {operator_name} ({})",
display_comma_separated(op_types)
)?;
if let Some(purpose) = purpose {
write!(f, " {purpose}")?;
}
Ok(())
}
OperatorFamilyItem::Function {
support_number,
op_types,
function_name,
argument_types,
} => {
write!(f, "FUNCTION {support_number}")?;
if let Some(types) = op_types {
write!(f, " ({})", display_comma_separated(types))?;
}
write!(f, " {function_name}")?;
if !argument_types.is_empty() {
write!(f, "({})", display_comma_separated(argument_types))?;
}
Ok(())
}
}
}
}
impl fmt::Display for OperatorFamilyDropItem {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
OperatorFamilyDropItem::Operator {
strategy_number,
op_types,
} => {
write!(
f,
"OPERATOR {strategy_number} ({})",
display_comma_separated(op_types)
)
}
OperatorFamilyDropItem::Function {
support_number,
op_types,
} => {
write!(
f,
"FUNCTION {support_number} ({})",
display_comma_separated(op_types)
)
}
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct AlterOperatorFamily {
pub name: ObjectName,
pub using: Ident,
pub operation: AlterOperatorFamilyOperation,
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum AlterOperatorFamilyOperation {
Add {
items: Vec<OperatorFamilyItem>,
},
Drop {
items: Vec<OperatorFamilyDropItem>,
},
RenameTo {
new_name: ObjectName,
},
OwnerTo(Owner),
SetSchema {
schema_name: ObjectName,
},
}
impl fmt::Display for AlterOperatorFamily {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"ALTER OPERATOR FAMILY {} USING {}",
self.name, self.using
)?;
write!(f, " {}", self.operation)
}
}
impl fmt::Display for AlterOperatorFamilyOperation {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
AlterOperatorFamilyOperation::Add { items } => {
write!(f, "ADD {}", display_comma_separated(items))
}
AlterOperatorFamilyOperation::Drop { items } => {
write!(f, "DROP {}", display_comma_separated(items))
}
AlterOperatorFamilyOperation::RenameTo { new_name } => {
write!(f, "RENAME TO {new_name}")
}
AlterOperatorFamilyOperation::OwnerTo(owner) => {
write!(f, "OWNER TO {owner}")
}
AlterOperatorFamilyOperation::SetSchema { schema_name } => {
write!(f, "SET SCHEMA {schema_name}")
}
}
}
}
impl Spanned for AlterOperatorFamily {
fn span(&self) -> Span {
Span::empty()
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct AlterOperatorClass {
pub name: ObjectName,
pub using: Ident,
pub operation: AlterOperatorClassOperation,
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum AlterOperatorClassOperation {
RenameTo {
new_name: ObjectName,
},
OwnerTo(Owner),
SetSchema {
schema_name: ObjectName,
},
}
impl fmt::Display for AlterOperatorClass {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "ALTER OPERATOR CLASS {} USING {}", self.name, self.using)?;
write!(f, " {}", self.operation)
}
}
impl fmt::Display for AlterOperatorClassOperation {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
AlterOperatorClassOperation::RenameTo { new_name } => {
write!(f, "RENAME TO {new_name}")
}
AlterOperatorClassOperation::OwnerTo(owner) => {
write!(f, "OWNER TO {owner}")
}
AlterOperatorClassOperation::SetSchema { schema_name } => {
write!(f, "SET SCHEMA {schema_name}")
}
}
}
}
impl Spanned for AlterOperatorClass {
fn span(&self) -> Span {
Span::empty()
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct CreatePolicy {
pub name: Ident,
#[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
pub table_name: ObjectName,
pub policy_type: Option<CreatePolicyType>,
pub command: Option<CreatePolicyCommand>,
pub to: Option<Vec<Owner>>,
pub using: Option<Expr>,
pub with_check: Option<Expr>,
}
impl fmt::Display for CreatePolicy {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"CREATE POLICY {name} ON {table_name}",
name = self.name,
table_name = self.table_name,
)?;
if let Some(ref policy_type) = self.policy_type {
write!(f, " AS {policy_type}")?;
}
if let Some(ref command) = self.command {
write!(f, " FOR {command}")?;
}
if let Some(ref to) = self.to {
write!(f, " TO {}", display_comma_separated(to))?;
}
if let Some(ref using) = self.using {
write!(f, " USING ({using})")?;
}
if let Some(ref with_check) = self.with_check {
write!(f, " WITH CHECK ({with_check})")?;
}
Ok(())
}
}
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum CreatePolicyType {
Permissive,
Restrictive,
}
impl fmt::Display for CreatePolicyType {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
CreatePolicyType::Permissive => write!(f, "PERMISSIVE"),
CreatePolicyType::Restrictive => write!(f, "RESTRICTIVE"),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum CreatePolicyCommand {
All,
Select,
Insert,
Update,
Delete,
}
impl fmt::Display for CreatePolicyCommand {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
CreatePolicyCommand::All => write!(f, "ALL"),
CreatePolicyCommand::Select => write!(f, "SELECT"),
CreatePolicyCommand::Insert => write!(f, "INSERT"),
CreatePolicyCommand::Update => write!(f, "UPDATE"),
CreatePolicyCommand::Delete => write!(f, "DELETE"),
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct DropPolicy {
pub if_exists: bool,
pub name: Ident,
#[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
pub table_name: ObjectName,
pub drop_behavior: Option<DropBehavior>,
}
impl fmt::Display for DropPolicy {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"DROP POLICY {if_exists}{name} ON {table_name}",
if_exists = if self.if_exists { "IF EXISTS " } else { "" },
name = self.name,
table_name = self.table_name
)?;
if let Some(ref behavior) = self.drop_behavior {
write!(f, " {behavior}")?;
}
Ok(())
}
}
impl From<CreatePolicy> for crate::ast::Statement {
fn from(v: CreatePolicy) -> Self {
crate::ast::Statement::CreatePolicy(v)
}
}
impl From<DropPolicy> for crate::ast::Statement {
fn from(v: DropPolicy) -> Self {
crate::ast::Statement::DropPolicy(v)
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct AlterPolicy {
pub name: Ident,
#[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
pub table_name: ObjectName,
pub operation: AlterPolicyOperation,
}
impl fmt::Display for AlterPolicy {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"ALTER POLICY {name} ON {table_name}{operation}",
name = self.name,
table_name = self.table_name,
operation = self.operation
)
}
}
impl From<AlterPolicy> for crate::ast::Statement {
fn from(v: AlterPolicy) -> Self {
crate::ast::Statement::AlterPolicy(v)
}
}