#[cfg(not(feature = "std"))]
use alloc::{
boxed::Box,
format,
string::{String, ToString},
vec,
vec::Vec,
};
use helpers::{
attached_token::AttachedToken,
stmt_data_loading::{FileStagingCommand, StageLoadSelectItemKind},
};
use core::cmp::Ordering;
use core::ops::Deref;
use core::{
fmt::{self, Display},
hash,
};
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
#[cfg(feature = "visitor")]
use sqlparser_derive::{Visit, VisitMut};
use crate::{
display_utils::SpaceOrNewline,
tokenizer::{Span, Token},
};
use crate::{
display_utils::{Indent, NewLine},
keywords::Keyword,
};
pub use self::data_type::{
ArrayElemTypeDef, BinaryLength, CharLengthUnits, CharacterLength, DataType, EnumMember,
ExactNumberInfo, IntervalFields, StructBracketKind, TimezoneInfo,
};
pub use self::dcl::{
AlterRoleOperation, CreateRole, Grant, ResetConfig, Revoke, RoleOption, SecondaryRoles,
SetConfigValue, Use,
};
pub use self::ddl::{
Alignment, AlterColumnOperation, AlterConnectorOwner, AlterIndexOperation, AlterOperator,
AlterOperatorClass, AlterOperatorClassOperation, AlterOperatorFamily,
AlterOperatorFamilyOperation, AlterOperatorOperation, AlterPolicy, AlterPolicyOperation,
AlterSchema, AlterSchemaOperation, AlterTable, AlterTableAlgorithm, AlterTableLock,
AlterTableOperation, AlterTableType, AlterType, AlterTypeAddValue, AlterTypeAddValuePosition,
AlterTypeOperation, AlterTypeRename, AlterTypeRenameValue, ClusteredBy, ColumnDef,
ColumnOption, ColumnOptionDef, ColumnOptions, ColumnPolicy, ColumnPolicyProperty,
ConstraintCharacteristics, CreateConnector, CreateDomain, CreateExtension, CreateFunction,
CreateIndex, CreateOperator, CreateOperatorClass, CreateOperatorFamily, CreatePolicy,
CreatePolicyCommand, CreatePolicyType, CreateTable, CreateTrigger, CreateView, Deduplicate,
DeferrableInitial, DropBehavior, DropExtension, DropFunction, DropOperator, DropOperatorClass,
DropOperatorFamily, DropOperatorSignature, DropPolicy, DropTrigger, ForValues, GeneratedAs,
GeneratedExpressionMode, IdentityParameters, IdentityProperty, IdentityPropertyFormatKind,
IdentityPropertyKind, IdentityPropertyOrder, IndexColumn, IndexOption, IndexType,
KeyOrIndexDisplay, Msck, NullsDistinctOption, OperatorArgTypes, OperatorClassItem,
OperatorFamilyDropItem, OperatorFamilyItem, OperatorOption, OperatorPurpose, Owner, Partition,
PartitionBoundValue, ProcedureParam, ReferentialAction, RenameTableNameKind, ReplicaIdentity,
TagsColumnOption, TriggerObjectKind, Truncate, UserDefinedTypeCompositeAttributeDef,
UserDefinedTypeInternalLength, UserDefinedTypeRangeOption, UserDefinedTypeRepresentation,
UserDefinedTypeSqlDefinitionOption, UserDefinedTypeStorage, ViewColumnDef,
};
pub use self::dml::{
Delete, Insert, Merge, MergeAction, MergeClause, MergeClauseKind, MergeInsertExpr,
MergeInsertKind, MergeUpdateExpr, OutputClause, Update,
};
pub use self::operator::{BinaryOperator, UnaryOperator};
pub use self::query::{
AfterMatchSkip, ConnectByKind, Cte, CteAsMaterialized, Distinct, EmptyMatchesMode,
ExceptSelectItem, ExcludeSelectItem, ExprWithAlias, ExprWithAliasAndOrderBy, Fetch, ForClause,
ForJson, ForXml, FormatClause, GroupByExpr, GroupByWithModifier, IdentWithAlias,
IlikeSelectItem, InputFormatClause, Interpolate, InterpolateExpr, Join, JoinConstraint,
JoinOperator, JsonTableColumn, JsonTableColumnErrorHandling, JsonTableNamedColumn,
JsonTableNestedColumn, LateralView, LimitClause, LockClause, LockType, MatchRecognizePattern,
MatchRecognizeSymbol, Measure, NamedWindowDefinition, NamedWindowExpr, NonBlock, Offset,
OffsetRows, OpenJsonTableColumn, OrderBy, OrderByExpr, OrderByKind, OrderByOptions,
PipeOperator, PivotValueSource, ProjectionSelect, Query, RenameSelectItem,
RepetitionQuantifier, ReplaceSelectElement, ReplaceSelectItem, RowsPerMatch, Select,
SelectFlavor, SelectInto, SelectItem, SelectItemQualifiedWildcardKind, SelectModifiers,
SetExpr, SetOperator, SetQuantifier, Setting, SymbolDefinition, Table, TableAlias,
TableAliasColumnDef, TableFactor, TableFunctionArgs, TableIndexHintForClause,
TableIndexHintType, TableIndexHints, TableIndexType, TableSample, TableSampleBucket,
TableSampleKind, TableSampleMethod, TableSampleModifier, TableSampleQuantity, TableSampleSeed,
TableSampleSeedModifier, TableSampleUnit, TableVersion, TableWithJoins, Top, TopQuantity,
UpdateTableFromKind, ValueTableMode, Values, WildcardAdditionalOptions, With, WithFill,
XmlNamespaceDefinition, XmlPassingArgument, XmlPassingClause, XmlTableColumn,
XmlTableColumnOption,
};
pub use self::trigger::{
TriggerEvent, TriggerExecBody, TriggerExecBodyType, TriggerObject, TriggerPeriod,
TriggerReferencing, TriggerReferencingType,
};
pub use self::value::{
escape_double_quote_string, escape_quoted_string, DateTimeField, DollarQuotedString,
NormalizationForm, QuoteDelimitedString, TrimWhereField, Value, ValueWithSpan,
};
use crate::ast::helpers::key_value_options::KeyValueOptions;
use crate::ast::helpers::stmt_data_loading::StageParamsObject;
#[cfg(feature = "visitor")]
pub use visitor::*;
pub use self::data_type::GeometricTypeKind;
mod data_type;
mod dcl;
mod ddl;
mod dml;
pub mod helpers;
pub mod table_constraints;
pub use table_constraints::{
CheckConstraint, ForeignKeyConstraint, FullTextOrSpatialConstraint, IndexConstraint,
PrimaryKeyConstraint, TableConstraint, UniqueConstraint,
};
mod operator;
mod query;
mod spans;
pub use spans::Spanned;
pub mod comments;
mod trigger;
mod value;
#[cfg(feature = "visitor")]
mod visitor;
pub struct DisplaySeparated<'a, T>
where
T: fmt::Display,
{
slice: &'a [T],
sep: &'static str,
}
impl<T> fmt::Display for DisplaySeparated<'_, T>
where
T: fmt::Display,
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mut delim = "";
for t in self.slice {
f.write_str(delim)?;
delim = self.sep;
t.fmt(f)?;
}
Ok(())
}
}
pub(crate) fn display_separated<'a, T>(slice: &'a [T], sep: &'static str) -> DisplaySeparated<'a, T>
where
T: fmt::Display,
{
DisplaySeparated { slice, sep }
}
pub(crate) fn display_comma_separated<T>(slice: &[T]) -> DisplaySeparated<'_, T>
where
T: fmt::Display,
{
DisplaySeparated { slice, sep: ", " }
}
fn format_statement_list(f: &mut fmt::Formatter, statements: &[Statement]) -> fmt::Result {
write!(f, "{}", display_separated(statements, "; "))?;
write!(f, ";")
}
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct Ident {
pub value: String,
pub quote_style: Option<char>,
pub span: Span,
}
impl PartialEq for Ident {
fn eq(&self, other: &Self) -> bool {
let Ident {
value,
quote_style,
span: _,
} = self;
value == &other.value && quote_style == &other.quote_style
}
}
impl core::hash::Hash for Ident {
fn hash<H: hash::Hasher>(&self, state: &mut H) {
let Ident {
value,
quote_style,
span: _,
} = self;
value.hash(state);
quote_style.hash(state);
}
}
impl Eq for Ident {}
impl PartialOrd for Ident {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl Ord for Ident {
fn cmp(&self, other: &Self) -> Ordering {
let Ident {
value,
quote_style,
span: _,
} = self;
let Ident {
value: other_value,
quote_style: other_quote_style,
span: _,
} = other;
value
.cmp(other_value)
.then_with(|| quote_style.cmp(other_quote_style))
}
}
impl Ident {
pub fn new<S>(value: S) -> Self
where
S: Into<String>,
{
Ident {
value: value.into(),
quote_style: None,
span: Span::empty(),
}
}
pub fn with_quote<S>(quote: char, value: S) -> Self
where
S: Into<String>,
{
assert!(quote == '\'' || quote == '"' || quote == '`' || quote == '[');
Ident {
value: value.into(),
quote_style: Some(quote),
span: Span::empty(),
}
}
pub fn with_span<S>(span: Span, value: S) -> Self
where
S: Into<String>,
{
Ident {
value: value.into(),
quote_style: None,
span,
}
}
pub fn with_quote_and_span<S>(quote: char, span: Span, value: S) -> Self
where
S: Into<String>,
{
assert!(quote == '\'' || quote == '"' || quote == '`' || quote == '[');
Ident {
value: value.into(),
quote_style: Some(quote),
span,
}
}
}
impl From<&str> for Ident {
fn from(value: &str) -> Self {
Ident {
value: value.to_string(),
quote_style: None,
span: Span::empty(),
}
}
}
impl fmt::Display for Ident {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self.quote_style {
Some(q) if q == '"' || q == '\'' || q == '`' => {
let escaped = value::escape_quoted_string(&self.value, q);
write!(f, "{q}{escaped}{q}")
}
Some('[') => write!(f, "[{}]", self.value),
None => f.write_str(&self.value),
_ => panic!("unexpected quote style"),
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct ObjectName(pub Vec<ObjectNamePart>);
impl From<Vec<Ident>> for ObjectName {
fn from(idents: Vec<Ident>) -> Self {
ObjectName(idents.into_iter().map(ObjectNamePart::Identifier).collect())
}
}
impl From<Ident> for ObjectName {
fn from(ident: Ident) -> Self {
ObjectName(vec![ObjectNamePart::Identifier(ident)])
}
}
impl fmt::Display for ObjectName {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", display_separated(&self.0, "."))
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum ObjectNamePart {
Identifier(Ident),
Function(ObjectNamePartFunction),
}
impl ObjectNamePart {
pub fn as_ident(&self) -> Option<&Ident> {
match self {
ObjectNamePart::Identifier(ident) => Some(ident),
ObjectNamePart::Function(_) => None,
}
}
}
impl fmt::Display for ObjectNamePart {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
ObjectNamePart::Identifier(ident) => write!(f, "{ident}"),
ObjectNamePart::Function(func) => write!(f, "{func}"),
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct ObjectNamePartFunction {
pub name: Ident,
pub args: Vec<FunctionArg>,
}
impl fmt::Display for ObjectNamePartFunction {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}(", self.name)?;
write!(f, "{})", display_comma_separated(&self.args))
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct Array {
pub elem: Vec<Expr>,
pub named: bool,
}
impl fmt::Display for Array {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"{}[{}]",
if self.named { "ARRAY" } else { "" },
display_comma_separated(&self.elem)
)
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct Interval {
pub value: Box<Expr>,
pub leading_field: Option<DateTimeField>,
pub leading_precision: Option<u64>,
pub last_field: Option<DateTimeField>,
pub fractional_seconds_precision: Option<u64>,
}
impl fmt::Display for Interval {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let value = self.value.as_ref();
match (
&self.leading_field,
self.leading_precision,
self.fractional_seconds_precision,
) {
(
Some(DateTimeField::Second),
Some(leading_precision),
Some(fractional_seconds_precision),
) => {
assert!(self.last_field.is_none());
write!(
f,
"INTERVAL {value} SECOND ({leading_precision}, {fractional_seconds_precision})"
)
}
_ => {
write!(f, "INTERVAL {value}")?;
if let Some(leading_field) = &self.leading_field {
write!(f, " {leading_field}")?;
}
if let Some(leading_precision) = self.leading_precision {
write!(f, " ({leading_precision})")?;
}
if let Some(last_field) = &self.last_field {
write!(f, " TO {last_field}")?;
}
if let Some(fractional_seconds_precision) = self.fractional_seconds_precision {
write!(f, " ({fractional_seconds_precision})")?;
}
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 StructField {
pub field_name: Option<Ident>,
pub field_type: DataType,
pub options: Option<Vec<SqlOption>>,
}
impl fmt::Display for StructField {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if let Some(name) = &self.field_name {
write!(f, "{name} {}", self.field_type)?;
} else {
write!(f, "{}", self.field_type)?;
}
if let Some(options) = &self.options {
write!(f, " OPTIONS({})", display_separated(options, ", "))
} else {
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 UnionField {
pub field_name: Ident,
pub field_type: DataType,
}
impl fmt::Display for UnionField {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{} {}", self.field_name, self.field_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 DictionaryField {
pub key: Ident,
pub value: Box<Expr>,
}
impl fmt::Display for DictionaryField {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}: {}", self.key, self.value)
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct Map {
pub entries: Vec<MapEntry>,
}
impl Display for Map {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "MAP {{{}}}", display_comma_separated(&self.entries))
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct MapEntry {
pub key: Box<Expr>,
pub value: Box<Expr>,
}
impl fmt::Display for MapEntry {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}: {}", self.key, self.value)
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum CastFormat {
Value(Value),
ValueAtTimeZone(Value, Value),
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum JsonPathElem {
Dot {
key: String,
quoted: bool,
},
Bracket {
key: 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 JsonPath {
pub path: Vec<JsonPathElem>,
}
impl fmt::Display for JsonPath {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
for (i, elem) in self.path.iter().enumerate() {
match elem {
JsonPathElem::Dot { key, quoted } => {
if i == 0 {
write!(f, ":")?;
} else {
write!(f, ".")?;
}
if *quoted {
write!(f, "\"{}\"", escape_double_quote_string(key))?;
} else {
write!(f, "{key}")?;
}
}
JsonPathElem::Bracket { key } => {
write!(f, "[{key}]")?;
}
}
}
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 CastKind {
Cast,
TryCast,
SafeCast,
DoubleColon,
}
#[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 ConstraintReferenceMatchKind {
Full,
Partial,
Simple,
}
impl fmt::Display for ConstraintReferenceMatchKind {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::Full => write!(f, "MATCH FULL"),
Self::Partial => write!(f, "MATCH PARTIAL"),
Self::Simple => write!(f, "MATCH SIMPLE"),
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum ExtractSyntax {
From,
Comma,
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum CeilFloorKind {
DateTimeField(DateTimeField),
Scale(Value),
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct CaseWhen {
pub condition: Expr,
pub result: Expr,
}
impl fmt::Display for CaseWhen {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str("WHEN ")?;
self.condition.fmt(f)?;
f.write_str(" THEN")?;
SpaceOrNewline.fmt(f)?;
Indent(&self.result).fmt(f)?;
Ok(())
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(
feature = "visitor",
derive(Visit, VisitMut),
visit(with = "visit_expr")
)]
pub enum Expr {
Identifier(Ident),
CompoundIdentifier(Vec<Ident>),
CompoundFieldAccess {
root: Box<Expr>,
access_chain: Vec<AccessExpr>,
},
JsonAccess {
value: Box<Expr>,
path: JsonPath,
},
IsFalse(Box<Expr>),
IsNotFalse(Box<Expr>),
IsTrue(Box<Expr>),
IsNotTrue(Box<Expr>),
IsNull(Box<Expr>),
IsNotNull(Box<Expr>),
IsUnknown(Box<Expr>),
IsNotUnknown(Box<Expr>),
IsDistinctFrom(Box<Expr>, Box<Expr>),
IsNotDistinctFrom(Box<Expr>, Box<Expr>),
IsNormalized {
expr: Box<Expr>,
form: Option<NormalizationForm>,
negated: bool,
},
InList {
expr: Box<Expr>,
list: Vec<Expr>,
negated: bool,
},
InSubquery {
expr: Box<Expr>,
subquery: Box<Query>,
negated: bool,
},
InUnnest {
expr: Box<Expr>,
array_expr: Box<Expr>,
negated: bool,
},
Between {
expr: Box<Expr>,
negated: bool,
low: Box<Expr>,
high: Box<Expr>,
},
BinaryOp {
left: Box<Expr>,
op: BinaryOperator,
right: Box<Expr>,
},
Like {
negated: bool,
any: bool,
expr: Box<Expr>,
pattern: Box<Expr>,
escape_char: Option<Value>,
},
ILike {
negated: bool,
any: bool,
expr: Box<Expr>,
pattern: Box<Expr>,
escape_char: Option<Value>,
},
SimilarTo {
negated: bool,
expr: Box<Expr>,
pattern: Box<Expr>,
escape_char: Option<Value>,
},
RLike {
negated: bool,
expr: Box<Expr>,
pattern: Box<Expr>,
regexp: bool,
},
AnyOp {
left: Box<Expr>,
compare_op: BinaryOperator,
right: Box<Expr>,
is_some: bool,
},
AllOp {
left: Box<Expr>,
compare_op: BinaryOperator,
right: Box<Expr>,
},
UnaryOp {
op: UnaryOperator,
expr: Box<Expr>,
},
Convert {
is_try: bool,
expr: Box<Expr>,
data_type: Option<DataType>,
charset: Option<ObjectName>,
target_before_value: bool,
styles: Vec<Expr>,
},
Cast {
kind: CastKind,
expr: Box<Expr>,
data_type: DataType,
array: bool,
format: Option<CastFormat>,
},
AtTimeZone {
timestamp: Box<Expr>,
time_zone: Box<Expr>,
},
Extract {
field: DateTimeField,
syntax: ExtractSyntax,
expr: Box<Expr>,
},
Ceil {
expr: Box<Expr>,
field: CeilFloorKind,
},
Floor {
expr: Box<Expr>,
field: CeilFloorKind,
},
Position {
expr: Box<Expr>,
r#in: Box<Expr>,
},
Substring {
expr: Box<Expr>,
substring_from: Option<Box<Expr>>,
substring_for: Option<Box<Expr>>,
special: bool,
shorthand: bool,
},
Trim {
expr: Box<Expr>,
trim_where: Option<TrimWhereField>,
trim_what: Option<Box<Expr>>,
trim_characters: Option<Vec<Expr>>,
},
Overlay {
expr: Box<Expr>,
overlay_what: Box<Expr>,
overlay_from: Box<Expr>,
overlay_for: Option<Box<Expr>>,
},
Collate {
expr: Box<Expr>,
collation: ObjectName,
},
Nested(Box<Expr>),
Value(ValueWithSpan),
Prefixed {
prefix: Ident,
value: Box<Expr>,
},
TypedString(TypedString),
Function(Function),
Case {
case_token: AttachedToken,
end_token: AttachedToken,
operand: Option<Box<Expr>>,
conditions: Vec<CaseWhen>,
else_result: Option<Box<Expr>>,
},
Exists {
subquery: Box<Query>,
negated: bool,
},
Subquery(Box<Query>),
GroupingSets(Vec<Vec<Expr>>),
Cube(Vec<Vec<Expr>>),
Rollup(Vec<Vec<Expr>>),
Tuple(Vec<Expr>),
Struct {
values: Vec<Expr>,
fields: Vec<StructField>,
},
Named {
expr: Box<Expr>,
name: Ident,
},
Dictionary(Vec<DictionaryField>),
Map(Map),
Array(Array),
Interval(Interval),
MatchAgainst {
columns: Vec<ObjectName>,
match_value: Value,
opt_search_modifier: Option<SearchModifier>,
},
Wildcard(AttachedToken),
QualifiedWildcard(ObjectName, AttachedToken),
OuterJoin(Box<Expr>),
Prior(Box<Expr>),
Lambda(LambdaFunction),
MemberOf(MemberOf),
}
impl Expr {
pub fn value(value: impl Into<ValueWithSpan>) -> Self {
Expr::Value(value.into())
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum Subscript {
Index {
index: Expr,
},
Slice {
lower_bound: Option<Expr>,
upper_bound: Option<Expr>,
stride: Option<Expr>,
},
}
impl fmt::Display for Subscript {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Subscript::Index { index } => write!(f, "{index}"),
Subscript::Slice {
lower_bound,
upper_bound,
stride,
} => {
if let Some(lower) = lower_bound {
write!(f, "{lower}")?;
}
write!(f, ":")?;
if let Some(upper) = upper_bound {
write!(f, "{upper}")?;
}
if let Some(stride) = stride {
write!(f, ":")?;
write!(f, "{stride}")?;
}
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 AccessExpr {
Dot(Expr),
Subscript(Subscript),
}
impl fmt::Display for AccessExpr {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
AccessExpr::Dot(expr) => write!(f, ".{expr}"),
AccessExpr::Subscript(subscript) => write!(f, "[{subscript}]"),
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct LambdaFunction {
pub params: OneOrManyWithParens<Ident>,
pub body: Box<Expr>,
pub syntax: LambdaSyntax,
}
impl fmt::Display for LambdaFunction {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self.syntax {
LambdaSyntax::Arrow => write!(f, "{} -> {}", self.params, self.body),
LambdaSyntax::LambdaKeyword => {
write!(f, "lambda ")?;
match &self.params {
OneOrManyWithParens::One(p) => write!(f, "{p}")?,
OneOrManyWithParens::Many(ps) => write!(f, "{}", display_comma_separated(ps))?,
};
write!(f, " : {}", self.body)
}
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Copy)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum LambdaSyntax {
Arrow,
LambdaKeyword,
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum OneOrManyWithParens<T> {
One(T),
Many(Vec<T>),
}
impl<T> Deref for OneOrManyWithParens<T> {
type Target = [T];
fn deref(&self) -> &[T] {
match self {
OneOrManyWithParens::One(one) => core::slice::from_ref(one),
OneOrManyWithParens::Many(many) => many,
}
}
}
impl<T> AsRef<[T]> for OneOrManyWithParens<T> {
fn as_ref(&self) -> &[T] {
self
}
}
impl<'a, T> IntoIterator for &'a OneOrManyWithParens<T> {
type Item = &'a T;
type IntoIter = core::slice::Iter<'a, T>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
#[derive(Debug, Clone)]
pub struct OneOrManyWithParensIntoIter<T> {
inner: OneOrManyWithParensIntoIterInner<T>,
}
#[derive(Debug, Clone)]
enum OneOrManyWithParensIntoIterInner<T> {
One(core::iter::Once<T>),
Many(<Vec<T> as IntoIterator>::IntoIter),
}
impl<T> core::iter::FusedIterator for OneOrManyWithParensIntoIter<T>
where
core::iter::Once<T>: core::iter::FusedIterator,
<Vec<T> as IntoIterator>::IntoIter: core::iter::FusedIterator,
{
}
impl<T> core::iter::ExactSizeIterator for OneOrManyWithParensIntoIter<T>
where
core::iter::Once<T>: core::iter::ExactSizeIterator,
<Vec<T> as IntoIterator>::IntoIter: core::iter::ExactSizeIterator,
{
}
impl<T> core::iter::Iterator for OneOrManyWithParensIntoIter<T> {
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
match &mut self.inner {
OneOrManyWithParensIntoIterInner::One(one) => one.next(),
OneOrManyWithParensIntoIterInner::Many(many) => many.next(),
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
match &self.inner {
OneOrManyWithParensIntoIterInner::One(one) => one.size_hint(),
OneOrManyWithParensIntoIterInner::Many(many) => many.size_hint(),
}
}
fn count(self) -> usize
where
Self: Sized,
{
match self.inner {
OneOrManyWithParensIntoIterInner::One(one) => one.count(),
OneOrManyWithParensIntoIterInner::Many(many) => many.count(),
}
}
fn fold<B, F>(mut self, init: B, f: F) -> B
where
Self: Sized,
F: FnMut(B, Self::Item) -> B,
{
match &mut self.inner {
OneOrManyWithParensIntoIterInner::One(one) => one.fold(init, f),
OneOrManyWithParensIntoIterInner::Many(many) => many.fold(init, f),
}
}
}
impl<T> core::iter::DoubleEndedIterator for OneOrManyWithParensIntoIter<T> {
fn next_back(&mut self) -> Option<Self::Item> {
match &mut self.inner {
OneOrManyWithParensIntoIterInner::One(one) => one.next_back(),
OneOrManyWithParensIntoIterInner::Many(many) => many.next_back(),
}
}
}
impl<T> IntoIterator for OneOrManyWithParens<T> {
type Item = T;
type IntoIter = OneOrManyWithParensIntoIter<T>;
fn into_iter(self) -> Self::IntoIter {
let inner = match self {
OneOrManyWithParens::One(one) => {
OneOrManyWithParensIntoIterInner::One(core::iter::once(one))
}
OneOrManyWithParens::Many(many) => {
OneOrManyWithParensIntoIterInner::Many(many.into_iter())
}
};
OneOrManyWithParensIntoIter { inner }
}
}
impl<T> fmt::Display for OneOrManyWithParens<T>
where
T: fmt::Display,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
OneOrManyWithParens::One(value) => write!(f, "{value}"),
OneOrManyWithParens::Many(values) => {
write!(f, "({})", display_comma_separated(values))
}
}
}
}
impl fmt::Display for CastFormat {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
CastFormat::Value(v) => write!(f, "{v}"),
CastFormat::ValueAtTimeZone(v, tz) => write!(f, "{v} AT TIME ZONE {tz}"),
}
}
}
impl fmt::Display for Expr {
#[cfg_attr(feature = "recursive-protection", recursive::recursive)]
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Expr::Identifier(s) => write!(f, "{s}"),
Expr::Wildcard(_) => f.write_str("*"),
Expr::QualifiedWildcard(prefix, _) => write!(f, "{prefix}.*"),
Expr::CompoundIdentifier(s) => write!(f, "{}", display_separated(s, ".")),
Expr::CompoundFieldAccess { root, access_chain } => {
write!(f, "{root}")?;
for field in access_chain {
write!(f, "{field}")?;
}
Ok(())
}
Expr::IsTrue(ast) => write!(f, "{ast} IS TRUE"),
Expr::IsNotTrue(ast) => write!(f, "{ast} IS NOT TRUE"),
Expr::IsFalse(ast) => write!(f, "{ast} IS FALSE"),
Expr::IsNotFalse(ast) => write!(f, "{ast} IS NOT FALSE"),
Expr::IsNull(ast) => write!(f, "{ast} IS NULL"),
Expr::IsNotNull(ast) => write!(f, "{ast} IS NOT NULL"),
Expr::IsUnknown(ast) => write!(f, "{ast} IS UNKNOWN"),
Expr::IsNotUnknown(ast) => write!(f, "{ast} IS NOT UNKNOWN"),
Expr::InList {
expr,
list,
negated,
} => write!(
f,
"{} {}IN ({})",
expr,
if *negated { "NOT " } else { "" },
display_comma_separated(list)
),
Expr::InSubquery {
expr,
subquery,
negated,
} => write!(
f,
"{} {}IN ({})",
expr,
if *negated { "NOT " } else { "" },
subquery
),
Expr::InUnnest {
expr,
array_expr,
negated,
} => write!(
f,
"{} {}IN UNNEST({})",
expr,
if *negated { "NOT " } else { "" },
array_expr
),
Expr::Between {
expr,
negated,
low,
high,
} => write!(
f,
"{} {}BETWEEN {} AND {}",
expr,
if *negated { "NOT " } else { "" },
low,
high
),
Expr::BinaryOp { left, op, right } => write!(f, "{left} {op} {right}"),
Expr::Like {
negated,
expr,
pattern,
escape_char,
any,
} => match escape_char {
Some(ch) => write!(
f,
"{} {}LIKE {}{} ESCAPE {}",
expr,
if *negated { "NOT " } else { "" },
if *any { "ANY " } else { "" },
pattern,
ch
),
_ => write!(
f,
"{} {}LIKE {}{}",
expr,
if *negated { "NOT " } else { "" },
if *any { "ANY " } else { "" },
pattern
),
},
Expr::ILike {
negated,
expr,
pattern,
escape_char,
any,
} => match escape_char {
Some(ch) => write!(
f,
"{} {}ILIKE {}{} ESCAPE {}",
expr,
if *negated { "NOT " } else { "" },
if *any { "ANY" } else { "" },
pattern,
ch
),
_ => write!(
f,
"{} {}ILIKE {}{}",
expr,
if *negated { "NOT " } else { "" },
if *any { "ANY " } else { "" },
pattern
),
},
Expr::RLike {
negated,
expr,
pattern,
regexp,
} => write!(
f,
"{} {}{} {}",
expr,
if *negated { "NOT " } else { "" },
if *regexp { "REGEXP" } else { "RLIKE" },
pattern
),
Expr::IsNormalized {
expr,
form,
negated,
} => {
let not_ = if *negated { "NOT " } else { "" };
if form.is_none() {
write!(f, "{expr} IS {not_}NORMALIZED")
} else {
write!(
f,
"{} IS {}{} NORMALIZED",
expr,
not_,
form.as_ref().unwrap()
)
}
}
Expr::SimilarTo {
negated,
expr,
pattern,
escape_char,
} => match escape_char {
Some(ch) => write!(
f,
"{} {}SIMILAR TO {} ESCAPE {}",
expr,
if *negated { "NOT " } else { "" },
pattern,
ch
),
_ => write!(
f,
"{} {}SIMILAR TO {}",
expr,
if *negated { "NOT " } else { "" },
pattern
),
},
Expr::AnyOp {
left,
compare_op,
right,
is_some,
} => {
let add_parens = !matches!(right.as_ref(), Expr::Subquery(_));
write!(
f,
"{left} {compare_op} {}{}{right}{}",
if *is_some { "SOME" } else { "ANY" },
if add_parens { "(" } else { "" },
if add_parens { ")" } else { "" },
)
}
Expr::AllOp {
left,
compare_op,
right,
} => {
let add_parens = !matches!(right.as_ref(), Expr::Subquery(_));
write!(
f,
"{left} {compare_op} ALL{}{right}{}",
if add_parens { "(" } else { "" },
if add_parens { ")" } else { "" },
)
}
Expr::UnaryOp { op, expr } => {
if op == &UnaryOperator::PGPostfixFactorial {
write!(f, "{expr}{op}")
} else if matches!(
op,
UnaryOperator::Not
| UnaryOperator::Hash
| UnaryOperator::AtDashAt
| UnaryOperator::DoubleAt
| UnaryOperator::QuestionDash
| UnaryOperator::QuestionPipe
) {
write!(f, "{op} {expr}")
} else {
write!(f, "{op}{expr}")
}
}
Expr::Convert {
is_try,
expr,
target_before_value,
data_type,
charset,
styles,
} => {
write!(f, "{}CONVERT(", if *is_try { "TRY_" } else { "" })?;
if let Some(data_type) = data_type {
if let Some(charset) = charset {
write!(f, "{expr}, {data_type} CHARACTER SET {charset}")
} else if *target_before_value {
write!(f, "{data_type}, {expr}")
} else {
write!(f, "{expr}, {data_type}")
}
} else if let Some(charset) = charset {
write!(f, "{expr} USING {charset}")
} else {
write!(f, "{expr}") }?;
if !styles.is_empty() {
write!(f, ", {}", display_comma_separated(styles))?;
}
write!(f, ")")
}
Expr::Cast {
kind,
expr,
data_type,
array,
format,
} => match kind {
CastKind::Cast => {
write!(f, "CAST({expr} AS {data_type}")?;
if *array {
write!(f, " ARRAY")?;
}
if let Some(format) = format {
write!(f, " FORMAT {format}")?;
}
write!(f, ")")
}
CastKind::TryCast => {
if let Some(format) = format {
write!(f, "TRY_CAST({expr} AS {data_type} FORMAT {format})")
} else {
write!(f, "TRY_CAST({expr} AS {data_type})")
}
}
CastKind::SafeCast => {
if let Some(format) = format {
write!(f, "SAFE_CAST({expr} AS {data_type} FORMAT {format})")
} else {
write!(f, "SAFE_CAST({expr} AS {data_type})")
}
}
CastKind::DoubleColon => {
write!(f, "{expr}::{data_type}")
}
},
Expr::Extract {
field,
syntax,
expr,
} => match syntax {
ExtractSyntax::From => write!(f, "EXTRACT({field} FROM {expr})"),
ExtractSyntax::Comma => write!(f, "EXTRACT({field}, {expr})"),
},
Expr::Ceil { expr, field } => match field {
CeilFloorKind::DateTimeField(DateTimeField::NoDateTime) => {
write!(f, "CEIL({expr})")
}
CeilFloorKind::DateTimeField(dt_field) => write!(f, "CEIL({expr} TO {dt_field})"),
CeilFloorKind::Scale(s) => write!(f, "CEIL({expr}, {s})"),
},
Expr::Floor { expr, field } => match field {
CeilFloorKind::DateTimeField(DateTimeField::NoDateTime) => {
write!(f, "FLOOR({expr})")
}
CeilFloorKind::DateTimeField(dt_field) => write!(f, "FLOOR({expr} TO {dt_field})"),
CeilFloorKind::Scale(s) => write!(f, "FLOOR({expr}, {s})"),
},
Expr::Position { expr, r#in } => write!(f, "POSITION({expr} IN {in})"),
Expr::Collate { expr, collation } => write!(f, "{expr} COLLATE {collation}"),
Expr::Nested(ast) => write!(f, "({ast})"),
Expr::Value(v) => write!(f, "{v}"),
Expr::Prefixed { prefix, value } => write!(f, "{prefix} {value}"),
Expr::TypedString(ts) => ts.fmt(f),
Expr::Function(fun) => fun.fmt(f),
Expr::Case {
case_token: _,
end_token: _,
operand,
conditions,
else_result,
} => {
f.write_str("CASE")?;
if let Some(operand) = operand {
f.write_str(" ")?;
operand.fmt(f)?;
}
for when in conditions {
SpaceOrNewline.fmt(f)?;
Indent(when).fmt(f)?;
}
if let Some(else_result) = else_result {
SpaceOrNewline.fmt(f)?;
Indent("ELSE").fmt(f)?;
SpaceOrNewline.fmt(f)?;
Indent(Indent(else_result)).fmt(f)?;
}
SpaceOrNewline.fmt(f)?;
f.write_str("END")
}
Expr::Exists { subquery, negated } => write!(
f,
"{}EXISTS ({})",
if *negated { "NOT " } else { "" },
subquery
),
Expr::Subquery(s) => write!(f, "({s})"),
Expr::GroupingSets(sets) => {
write!(f, "GROUPING SETS (")?;
let mut sep = "";
for set in sets {
write!(f, "{sep}")?;
sep = ", ";
write!(f, "({})", display_comma_separated(set))?;
}
write!(f, ")")
}
Expr::Cube(sets) => {
write!(f, "CUBE (")?;
let mut sep = "";
for set in sets {
write!(f, "{sep}")?;
sep = ", ";
if set.len() == 1 {
write!(f, "{}", set[0])?;
} else {
write!(f, "({})", display_comma_separated(set))?;
}
}
write!(f, ")")
}
Expr::Rollup(sets) => {
write!(f, "ROLLUP (")?;
let mut sep = "";
for set in sets {
write!(f, "{sep}")?;
sep = ", ";
if set.len() == 1 {
write!(f, "{}", set[0])?;
} else {
write!(f, "({})", display_comma_separated(set))?;
}
}
write!(f, ")")
}
Expr::Substring {
expr,
substring_from,
substring_for,
special,
shorthand,
} => {
f.write_str("SUBSTR")?;
if !*shorthand {
f.write_str("ING")?;
}
write!(f, "({expr}")?;
if let Some(from_part) = substring_from {
if *special {
write!(f, ", {from_part}")?;
} else {
write!(f, " FROM {from_part}")?;
}
}
if let Some(for_part) = substring_for {
if *special {
write!(f, ", {for_part}")?;
} else {
write!(f, " FOR {for_part}")?;
}
}
write!(f, ")")
}
Expr::Overlay {
expr,
overlay_what,
overlay_from,
overlay_for,
} => {
write!(
f,
"OVERLAY({expr} PLACING {overlay_what} FROM {overlay_from}"
)?;
if let Some(for_part) = overlay_for {
write!(f, " FOR {for_part}")?;
}
write!(f, ")")
}
Expr::IsDistinctFrom(a, b) => write!(f, "{a} IS DISTINCT FROM {b}"),
Expr::IsNotDistinctFrom(a, b) => write!(f, "{a} IS NOT DISTINCT FROM {b}"),
Expr::Trim {
expr,
trim_where,
trim_what,
trim_characters,
} => {
write!(f, "TRIM(")?;
if let Some(ident) = trim_where {
write!(f, "{ident} ")?;
}
if let Some(trim_char) = trim_what {
write!(f, "{trim_char} FROM {expr}")?;
} else {
write!(f, "{expr}")?;
}
if let Some(characters) = trim_characters {
write!(f, ", {}", display_comma_separated(characters))?;
}
write!(f, ")")
}
Expr::Tuple(exprs) => {
write!(f, "({})", display_comma_separated(exprs))
}
Expr::Struct { values, fields } => {
if !fields.is_empty() {
write!(
f,
"STRUCT<{}>({})",
display_comma_separated(fields),
display_comma_separated(values)
)
} else {
write!(f, "STRUCT({})", display_comma_separated(values))
}
}
Expr::Named { expr, name } => {
write!(f, "{expr} AS {name}")
}
Expr::Dictionary(fields) => {
write!(f, "{{{}}}", display_comma_separated(fields))
}
Expr::Map(map) => {
write!(f, "{map}")
}
Expr::Array(set) => {
write!(f, "{set}")
}
Expr::JsonAccess { value, path } => {
write!(f, "{value}{path}")
}
Expr::AtTimeZone {
timestamp,
time_zone,
} => {
write!(f, "{timestamp} AT TIME ZONE {time_zone}")
}
Expr::Interval(interval) => {
write!(f, "{interval}")
}
Expr::MatchAgainst {
columns,
match_value: match_expr,
opt_search_modifier,
} => {
write!(f, "MATCH ({}) AGAINST ", display_comma_separated(columns),)?;
if let Some(search_modifier) = opt_search_modifier {
write!(f, "({match_expr} {search_modifier})")?;
} else {
write!(f, "({match_expr})")?;
}
Ok(())
}
Expr::OuterJoin(expr) => {
write!(f, "{expr} (+)")
}
Expr::Prior(expr) => write!(f, "PRIOR {expr}"),
Expr::Lambda(lambda) => write!(f, "{lambda}"),
Expr::MemberOf(member_of) => write!(f, "{member_of}"),
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum WindowType {
WindowSpec(WindowSpec),
NamedWindow(Ident),
}
impl Display for WindowType {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
WindowType::WindowSpec(spec) => {
f.write_str("(")?;
NewLine.fmt(f)?;
Indent(spec).fmt(f)?;
NewLine.fmt(f)?;
f.write_str(")")
}
WindowType::NamedWindow(name) => name.fmt(f),
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct WindowSpec {
pub window_name: Option<Ident>,
pub partition_by: Vec<Expr>,
pub order_by: Vec<OrderByExpr>,
pub window_frame: Option<WindowFrame>,
}
impl fmt::Display for WindowSpec {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mut is_first = true;
if let Some(window_name) = &self.window_name {
if !is_first {
SpaceOrNewline.fmt(f)?;
}
is_first = false;
write!(f, "{window_name}")?;
}
if !self.partition_by.is_empty() {
if !is_first {
SpaceOrNewline.fmt(f)?;
}
is_first = false;
write!(
f,
"PARTITION BY {}",
display_comma_separated(&self.partition_by)
)?;
}
if !self.order_by.is_empty() {
if !is_first {
SpaceOrNewline.fmt(f)?;
}
is_first = false;
write!(f, "ORDER BY {}", display_comma_separated(&self.order_by))?;
}
if let Some(window_frame) = &self.window_frame {
if !is_first {
SpaceOrNewline.fmt(f)?;
}
if let Some(end_bound) = &window_frame.end_bound {
write!(
f,
"{} BETWEEN {} AND {}",
window_frame.units, window_frame.start_bound, end_bound
)?;
} else {
write!(f, "{} {}", window_frame.units, window_frame.start_bound)?;
}
}
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 WindowFrame {
pub units: WindowFrameUnits,
pub start_bound: WindowFrameBound,
pub end_bound: Option<WindowFrameBound>,
}
impl Default for WindowFrame {
fn default() -> Self {
Self {
units: WindowFrameUnits::Range,
start_bound: WindowFrameBound::Preceding(None),
end_bound: None,
}
}
}
#[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 WindowFrameUnits {
Rows,
Range,
Groups,
}
impl fmt::Display for WindowFrameUnits {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str(match self {
WindowFrameUnits::Rows => "ROWS",
WindowFrameUnits::Range => "RANGE",
WindowFrameUnits::Groups => "GROUPS",
})
}
}
#[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 NullTreatment {
IgnoreNulls,
RespectNulls,
}
impl fmt::Display for NullTreatment {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str(match self {
NullTreatment::IgnoreNulls => "IGNORE NULLS",
NullTreatment::RespectNulls => "RESPECT NULLS",
})
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum WindowFrameBound {
CurrentRow,
Preceding(Option<Box<Expr>>),
Following(Option<Box<Expr>>),
}
impl fmt::Display for WindowFrameBound {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
WindowFrameBound::CurrentRow => f.write_str("CURRENT ROW"),
WindowFrameBound::Preceding(None) => f.write_str("UNBOUNDED PRECEDING"),
WindowFrameBound::Following(None) => f.write_str("UNBOUNDED FOLLOWING"),
WindowFrameBound::Preceding(Some(n)) => write!(f, "{n} PRECEDING"),
WindowFrameBound::Following(Some(n)) => write!(f, "{n} FOLLOWING"),
}
}
}
#[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 AddDropSync {
ADD,
DROP,
SYNC,
}
impl fmt::Display for AddDropSync {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
AddDropSync::SYNC => f.write_str("SYNC PARTITIONS"),
AddDropSync::DROP => f.write_str("DROP PARTITIONS"),
AddDropSync::ADD => f.write_str("ADD PARTITIONS"),
}
}
}
#[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 ShowCreateObject {
Event,
Function,
Procedure,
Table,
Trigger,
View,
}
impl fmt::Display for ShowCreateObject {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
ShowCreateObject::Event => f.write_str("EVENT"),
ShowCreateObject::Function => f.write_str("FUNCTION"),
ShowCreateObject::Procedure => f.write_str("PROCEDURE"),
ShowCreateObject::Table => f.write_str("TABLE"),
ShowCreateObject::Trigger => f.write_str("TRIGGER"),
ShowCreateObject::View => f.write_str("VIEW"),
}
}
}
#[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 CommentObject {
Column,
Table,
Extension,
Schema,
Database,
User,
Role,
}
impl fmt::Display for CommentObject {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
CommentObject::Column => f.write_str("COLUMN"),
CommentObject::Table => f.write_str("TABLE"),
CommentObject::Extension => f.write_str("EXTENSION"),
CommentObject::Schema => f.write_str("SCHEMA"),
CommentObject::Database => f.write_str("DATABASE"),
CommentObject::User => f.write_str("USER"),
CommentObject::Role => f.write_str("ROLE"),
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum Password {
Password(Expr),
NullPassword,
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct CaseStatement {
pub case_token: AttachedToken,
pub match_expr: Option<Expr>,
pub when_blocks: Vec<ConditionalStatementBlock>,
pub else_block: Option<ConditionalStatementBlock>,
pub end_case_token: AttachedToken,
}
impl fmt::Display for CaseStatement {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let CaseStatement {
case_token: _,
match_expr,
when_blocks,
else_block,
end_case_token: AttachedToken(end),
} = self;
write!(f, "CASE")?;
if let Some(expr) = match_expr {
write!(f, " {expr}")?;
}
if !when_blocks.is_empty() {
write!(f, " {}", display_separated(when_blocks, " "))?;
}
if let Some(else_block) = else_block {
write!(f, " {else_block}")?;
}
write!(f, " END")?;
if let Token::Word(w) = &end.token {
if w.keyword == Keyword::CASE {
write!(f, " CASE")?;
}
}
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 IfStatement {
pub if_block: ConditionalStatementBlock,
pub elseif_blocks: Vec<ConditionalStatementBlock>,
pub else_block: Option<ConditionalStatementBlock>,
pub end_token: Option<AttachedToken>,
}
impl fmt::Display for IfStatement {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let IfStatement {
if_block,
elseif_blocks,
else_block,
end_token,
} = self;
write!(f, "{if_block}")?;
for elseif_block in elseif_blocks {
write!(f, " {elseif_block}")?;
}
if let Some(else_block) = else_block {
write!(f, " {else_block}")?;
}
if let Some(AttachedToken(end_token)) = end_token {
write!(f, " END {end_token}")?;
}
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 WhileStatement {
pub while_block: ConditionalStatementBlock,
}
impl fmt::Display for WhileStatement {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let WhileStatement { while_block } = self;
write!(f, "{while_block}")?;
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 ConditionalStatementBlock {
pub start_token: AttachedToken,
pub condition: Option<Expr>,
pub then_token: Option<AttachedToken>,
pub conditional_statements: ConditionalStatements,
}
impl ConditionalStatementBlock {
pub fn statements(&self) -> &Vec<Statement> {
self.conditional_statements.statements()
}
}
impl fmt::Display for ConditionalStatementBlock {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let ConditionalStatementBlock {
start_token: AttachedToken(start_token),
condition,
then_token,
conditional_statements,
} = self;
write!(f, "{start_token}")?;
if let Some(condition) = condition {
write!(f, " {condition}")?;
}
if then_token.is_some() {
write!(f, " THEN")?;
}
if !conditional_statements.statements().is_empty() {
write!(f, " {conditional_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 enum ConditionalStatements {
Sequence {
statements: Vec<Statement>,
},
BeginEnd(BeginEndStatements),
}
impl ConditionalStatements {
pub fn statements(&self) -> &Vec<Statement> {
match self {
ConditionalStatements::Sequence { statements } => statements,
ConditionalStatements::BeginEnd(bes) => &bes.statements,
}
}
}
impl fmt::Display for ConditionalStatements {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
ConditionalStatements::Sequence { statements } => {
if !statements.is_empty() {
format_statement_list(f, statements)?;
}
Ok(())
}
ConditionalStatements::BeginEnd(bes) => write!(f, "{bes}"),
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct BeginEndStatements {
pub begin_token: AttachedToken,
pub statements: Vec<Statement>,
pub end_token: AttachedToken,
}
impl fmt::Display for BeginEndStatements {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let BeginEndStatements {
begin_token: AttachedToken(begin_token),
statements,
end_token: AttachedToken(end_token),
} = self;
if begin_token.token != Token::EOF {
write!(f, "{begin_token} ")?;
}
if !statements.is_empty() {
format_statement_list(f, statements)?;
}
if end_token.token != Token::EOF {
write!(f, " {end_token}")?;
}
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 RaiseStatement {
pub value: Option<RaiseStatementValue>,
}
impl fmt::Display for RaiseStatement {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let RaiseStatement { value } = self;
write!(f, "RAISE")?;
if let Some(value) = value {
write!(f, " {value}")?;
}
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 RaiseStatementValue {
UsingMessage(Expr),
Expr(Expr),
}
impl fmt::Display for RaiseStatementValue {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
RaiseStatementValue::Expr(expr) => write!(f, "{expr}"),
RaiseStatementValue::UsingMessage(expr) => write!(f, "USING MESSAGE = {expr}"),
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum DeclareAssignment {
Expr(Box<Expr>),
Default(Box<Expr>),
DuckAssignment(Box<Expr>),
For(Box<Expr>),
MsSqlAssignment(Box<Expr>),
}
impl fmt::Display for DeclareAssignment {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
DeclareAssignment::Expr(expr) => {
write!(f, "{expr}")
}
DeclareAssignment::Default(expr) => {
write!(f, "DEFAULT {expr}")
}
DeclareAssignment::DuckAssignment(expr) => {
write!(f, ":= {expr}")
}
DeclareAssignment::MsSqlAssignment(expr) => {
write!(f, "= {expr}")
}
DeclareAssignment::For(expr) => {
write!(f, "FOR {expr}")
}
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum DeclareType {
Cursor,
ResultSet,
Exception,
}
impl fmt::Display for DeclareType {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
DeclareType::Cursor => {
write!(f, "CURSOR")
}
DeclareType::ResultSet => {
write!(f, "RESULTSET")
}
DeclareType::Exception => {
write!(f, "EXCEPTION")
}
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct Declare {
pub names: Vec<Ident>,
pub data_type: Option<DataType>,
pub assignment: Option<DeclareAssignment>,
pub declare_type: Option<DeclareType>,
pub binary: Option<bool>,
pub sensitive: Option<bool>,
pub scroll: Option<bool>,
pub hold: Option<bool>,
pub for_query: Option<Box<Query>>,
}
impl fmt::Display for Declare {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let Declare {
names,
data_type,
assignment,
declare_type,
binary,
sensitive,
scroll,
hold,
for_query,
} = self;
write!(f, "{}", display_comma_separated(names))?;
if let Some(true) = binary {
write!(f, " BINARY")?;
}
if let Some(sensitive) = sensitive {
if *sensitive {
write!(f, " INSENSITIVE")?;
} else {
write!(f, " ASENSITIVE")?;
}
}
if let Some(scroll) = scroll {
if *scroll {
write!(f, " SCROLL")?;
} else {
write!(f, " NO SCROLL")?;
}
}
if let Some(declare_type) = declare_type {
write!(f, " {declare_type}")?;
}
if let Some(hold) = hold {
if *hold {
write!(f, " WITH HOLD")?;
} else {
write!(f, " WITHOUT HOLD")?;
}
}
if let Some(query) = for_query {
write!(f, " FOR {query}")?;
}
if let Some(data_type) = data_type {
write!(f, " {data_type}")?;
}
if let Some(expr) = assignment {
write!(f, " {expr}")?;
}
Ok(())
}
}
#[derive(Debug, Default, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum CreateTableOptions {
#[default]
None,
With(Vec<SqlOption>),
Options(Vec<SqlOption>),
Plain(Vec<SqlOption>),
TableProperties(Vec<SqlOption>),
}
impl fmt::Display for CreateTableOptions {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
CreateTableOptions::With(with_options) => {
write!(f, "WITH ({})", display_comma_separated(with_options))
}
CreateTableOptions::Options(options) => {
write!(f, "OPTIONS({})", display_comma_separated(options))
}
CreateTableOptions::TableProperties(options) => {
write!(f, "TBLPROPERTIES ({})", display_comma_separated(options))
}
CreateTableOptions::Plain(options) => {
write!(f, "{}", display_separated(options, " "))
}
CreateTableOptions::None => 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 FromTable {
WithFromKeyword(Vec<TableWithJoins>),
WithoutKeyword(Vec<TableWithJoins>),
}
impl Display for FromTable {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
FromTable::WithFromKeyword(tables) => {
write!(f, "FROM {}", display_comma_separated(tables))
}
FromTable::WithoutKeyword(tables) => {
write!(f, "{}", display_comma_separated(tables))
}
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum Set {
SingleAssignment {
scope: Option<ContextModifier>,
hivevar: bool,
variable: ObjectName,
values: Vec<Expr>,
},
ParenthesizedAssignments {
variables: Vec<ObjectName>,
values: Vec<Expr>,
},
MultipleAssignments {
assignments: Vec<SetAssignment>,
},
SetSessionAuthorization(SetSessionAuthorizationParam),
SetSessionParam(SetSessionParamKind),
SetRole {
context_modifier: Option<ContextModifier>,
role_name: Option<Ident>,
},
SetTimeZone {
local: bool,
value: Expr,
},
SetNames {
charset_name: Ident,
collation_name: Option<String>,
},
SetNamesDefault {},
SetTransaction {
modes: Vec<TransactionMode>,
snapshot: Option<Value>,
session: bool,
},
}
impl Display for Set {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::ParenthesizedAssignments { variables, values } => write!(
f,
"SET ({}) = ({})",
display_comma_separated(variables),
display_comma_separated(values)
),
Self::MultipleAssignments { assignments } => {
write!(f, "SET {}", display_comma_separated(assignments))
}
Self::SetRole {
context_modifier,
role_name,
} => {
let role_name = role_name.clone().unwrap_or_else(|| Ident::new("NONE"));
write!(
f,
"SET {modifier}ROLE {role_name}",
modifier = context_modifier.map(|m| format!("{m}")).unwrap_or_default()
)
}
Self::SetSessionAuthorization(kind) => write!(f, "SET SESSION AUTHORIZATION {kind}"),
Self::SetSessionParam(kind) => write!(f, "SET {kind}"),
Self::SetTransaction {
modes,
snapshot,
session,
} => {
if *session {
write!(f, "SET SESSION CHARACTERISTICS AS TRANSACTION")?;
} else {
write!(f, "SET TRANSACTION")?;
}
if !modes.is_empty() {
write!(f, " {}", display_comma_separated(modes))?;
}
if let Some(snapshot_id) = snapshot {
write!(f, " SNAPSHOT {snapshot_id}")?;
}
Ok(())
}
Self::SetTimeZone { local, value } => {
f.write_str("SET ")?;
if *local {
f.write_str("LOCAL ")?;
}
write!(f, "TIME ZONE {value}")
}
Self::SetNames {
charset_name,
collation_name,
} => {
write!(f, "SET NAMES {charset_name}")?;
if let Some(collation) = collation_name {
f.write_str(" COLLATE ")?;
f.write_str(collation)?;
};
Ok(())
}
Self::SetNamesDefault {} => {
f.write_str("SET NAMES DEFAULT")?;
Ok(())
}
Set::SingleAssignment {
scope,
hivevar,
variable,
values,
} => {
write!(
f,
"SET {}{}{} = {}",
scope.map(|s| format!("{s}")).unwrap_or_default(),
if *hivevar { "HIVEVAR:" } else { "" },
variable,
display_comma_separated(values)
)
}
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct ExceptionWhen {
pub idents: Vec<Ident>,
pub statements: Vec<Statement>,
}
impl Display for ExceptionWhen {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"WHEN {idents} THEN",
idents = display_separated(&self.idents, " OR ")
)?;
if !self.statements.is_empty() {
write!(f, " ")?;
format_statement_list(f, &self.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 Analyze {
#[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
pub table_name: Option<ObjectName>,
pub partitions: Option<Vec<Expr>>,
pub for_columns: bool,
pub columns: Vec<Ident>,
pub cache_metadata: bool,
pub noscan: bool,
pub compute_statistics: bool,
pub has_table_keyword: bool,
}
impl fmt::Display for Analyze {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "ANALYZE")?;
if let Some(ref table_name) = self.table_name {
if self.has_table_keyword {
write!(f, " TABLE")?;
}
write!(f, " {table_name}")?;
}
if !self.for_columns && !self.columns.is_empty() {
write!(f, " ({})", display_comma_separated(&self.columns))?;
}
if let Some(ref parts) = self.partitions {
if !parts.is_empty() {
write!(f, " PARTITION ({})", display_comma_separated(parts))?;
}
}
if self.compute_statistics {
write!(f, " COMPUTE STATISTICS")?;
}
if self.noscan {
write!(f, " NOSCAN")?;
}
if self.cache_metadata {
write!(f, " CACHE METADATA")?;
}
if self.for_columns {
write!(f, " FOR COLUMNS")?;
if !self.columns.is_empty() {
write!(f, " {}", display_comma_separated(&self.columns))?;
}
}
Ok(())
}
}
#[allow(clippy::large_enum_variant)]
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(
feature = "visitor",
derive(Visit, VisitMut),
visit(with = "visit_statement")
)]
pub enum Statement {
Analyze(Analyze),
Set(Set),
Truncate(Truncate),
Msck(Msck),
Query(Box<Query>),
Insert(Insert),
Install {
extension_name: Ident,
},
Load {
extension_name: Ident,
},
Directory {
overwrite: bool,
local: bool,
path: String,
file_format: Option<FileFormat>,
source: Box<Query>,
},
Case(CaseStatement),
If(IfStatement),
While(WhileStatement),
Raise(RaiseStatement),
Call(Function),
Copy {
source: CopySource,
to: bool,
target: CopyTarget,
options: Vec<CopyOption>,
legacy_options: Vec<CopyLegacyOption>,
values: Vec<Option<String>>,
},
CopyIntoSnowflake {
kind: CopyIntoSnowflakeKind,
into: ObjectName,
into_columns: Option<Vec<Ident>>,
from_obj: Option<ObjectName>,
from_obj_alias: Option<Ident>,
stage_params: StageParamsObject,
from_transformations: Option<Vec<StageLoadSelectItemKind>>,
from_query: Option<Box<Query>>,
files: Option<Vec<String>>,
pattern: Option<String>,
file_format: KeyValueOptions,
copy_options: KeyValueOptions,
validation_mode: Option<String>,
partition: Option<Box<Expr>>,
},
Open(OpenStatement),
Close {
cursor: CloseCursor,
},
Update(Update),
Delete(Delete),
CreateView(CreateView),
CreateTable(CreateTable),
CreateVirtualTable {
#[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
name: ObjectName,
if_not_exists: bool,
module_name: Ident,
module_args: Vec<Ident>,
},
CreateIndex(CreateIndex),
CreateRole(CreateRole),
CreateSecret {
or_replace: bool,
temporary: Option<bool>,
if_not_exists: bool,
name: Option<Ident>,
storage_specifier: Option<Ident>,
secret_type: Ident,
options: Vec<SecretOption>,
},
CreateServer(CreateServerStatement),
CreatePolicy(CreatePolicy),
CreateConnector(CreateConnector),
CreateOperator(CreateOperator),
CreateOperatorFamily(CreateOperatorFamily),
CreateOperatorClass(CreateOperatorClass),
AlterTable(AlterTable),
AlterSchema(AlterSchema),
AlterIndex {
name: ObjectName,
operation: AlterIndexOperation,
},
AlterView {
#[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
name: ObjectName,
columns: Vec<Ident>,
query: Box<Query>,
with_options: Vec<SqlOption>,
},
AlterType(AlterType),
AlterOperator(AlterOperator),
AlterOperatorFamily(AlterOperatorFamily),
AlterOperatorClass(AlterOperatorClass),
AlterRole {
name: Ident,
operation: AlterRoleOperation,
},
AlterPolicy(AlterPolicy),
AlterConnector {
name: Ident,
properties: Option<Vec<SqlOption>>,
url: Option<String>,
owner: Option<ddl::AlterConnectorOwner>,
},
AlterSession {
set: bool,
session_params: KeyValueOptions,
},
AttachDatabase {
schema_name: Ident,
database_file_name: Expr,
database: bool,
},
AttachDuckDBDatabase {
if_not_exists: bool,
database: bool,
database_path: Ident,
database_alias: Option<Ident>,
attach_options: Vec<AttachDuckDBDatabaseOption>,
},
DetachDuckDBDatabase {
if_exists: bool,
database: bool,
database_alias: Ident,
},
Drop {
object_type: ObjectType,
if_exists: bool,
names: Vec<ObjectName>,
cascade: bool,
restrict: bool,
purge: bool,
temporary: bool,
table: Option<ObjectName>,
},
DropFunction(DropFunction),
DropDomain(DropDomain),
DropProcedure {
if_exists: bool,
proc_desc: Vec<FunctionDesc>,
drop_behavior: Option<DropBehavior>,
},
DropSecret {
if_exists: bool,
temporary: Option<bool>,
name: Ident,
storage_specifier: Option<Ident>,
},
DropPolicy(DropPolicy),
DropConnector {
if_exists: bool,
name: Ident,
},
Declare {
stmts: Vec<Declare>,
},
CreateExtension(CreateExtension),
DropExtension(DropExtension),
DropOperator(DropOperator),
DropOperatorFamily(DropOperatorFamily),
DropOperatorClass(DropOperatorClass),
Fetch {
name: Ident,
direction: FetchDirection,
position: FetchPosition,
into: Option<ObjectName>,
},
Flush {
object_type: FlushType,
location: Option<FlushLocation>,
channel: Option<String>,
read_lock: bool,
export: bool,
tables: Vec<ObjectName>,
},
Discard {
object_type: DiscardObject,
},
ShowFunctions {
filter: Option<ShowStatementFilter>,
},
ShowVariable {
variable: Vec<Ident>,
},
ShowStatus {
filter: Option<ShowStatementFilter>,
global: bool,
session: bool,
},
ShowVariables {
filter: Option<ShowStatementFilter>,
global: bool,
session: bool,
},
ShowCreate {
obj_type: ShowCreateObject,
obj_name: ObjectName,
},
ShowColumns {
extended: bool,
full: bool,
show_options: ShowStatementOptions,
},
ShowDatabases {
terse: bool,
history: bool,
show_options: ShowStatementOptions,
},
ShowSchemas {
terse: bool,
history: bool,
show_options: ShowStatementOptions,
},
ShowCharset(ShowCharset),
ShowObjects(ShowObjects),
ShowTables {
terse: bool,
history: bool,
extended: bool,
full: bool,
external: bool,
show_options: ShowStatementOptions,
},
ShowViews {
terse: bool,
materialized: bool,
show_options: ShowStatementOptions,
},
ShowCollation {
filter: Option<ShowStatementFilter>,
},
Use(Use),
StartTransaction {
modes: Vec<TransactionMode>,
begin: bool,
transaction: Option<BeginTransactionKind>,
modifier: Option<TransactionModifier>,
statements: Vec<Statement>,
exception: Option<Vec<ExceptionWhen>>,
has_end_keyword: bool,
},
Comment {
object_type: CommentObject,
object_name: ObjectName,
comment: Option<String>,
if_exists: bool,
},
Commit {
chain: bool,
end: bool,
modifier: Option<TransactionModifier>,
},
Rollback {
chain: bool,
savepoint: Option<Ident>,
},
CreateSchema {
schema_name: SchemaName,
if_not_exists: bool,
with: Option<Vec<SqlOption>>,
options: Option<Vec<SqlOption>>,
default_collate_spec: Option<Expr>,
clone: Option<ObjectName>,
},
CreateDatabase {
db_name: ObjectName,
if_not_exists: bool,
location: Option<String>,
managed_location: Option<String>,
or_replace: bool,
transient: bool,
clone: Option<ObjectName>,
data_retention_time_in_days: Option<u64>,
max_data_extension_time_in_days: Option<u64>,
external_volume: Option<String>,
catalog: Option<String>,
replace_invalid_characters: Option<bool>,
default_ddl_collation: Option<String>,
storage_serialization_policy: Option<StorageSerializationPolicy>,
comment: Option<String>,
default_charset: Option<String>,
default_collation: Option<String>,
catalog_sync: Option<String>,
catalog_sync_namespace_mode: Option<CatalogSyncNamespaceMode>,
catalog_sync_namespace_flatten_delimiter: Option<String>,
with_tags: Option<Vec<Tag>>,
with_contacts: Option<Vec<ContactEntry>>,
},
CreateFunction(CreateFunction),
CreateTrigger(CreateTrigger),
DropTrigger(DropTrigger),
CreateProcedure {
or_alter: bool,
name: ObjectName,
params: Option<Vec<ProcedureParam>>,
language: Option<Ident>,
body: ConditionalStatements,
},
CreateMacro {
or_replace: bool,
temporary: bool,
name: ObjectName,
args: Option<Vec<MacroArg>>,
definition: MacroDefinition,
},
CreateStage {
or_replace: bool,
temporary: bool,
if_not_exists: bool,
name: ObjectName,
stage_params: StageParamsObject,
directory_table_params: KeyValueOptions,
file_format: KeyValueOptions,
copy_options: KeyValueOptions,
comment: Option<String>,
},
Assert {
condition: Expr,
message: Option<Expr>,
},
Grant(Grant),
Deny(DenyStatement),
Revoke(Revoke),
Deallocate {
name: Ident,
prepare: bool,
},
Execute {
name: Option<ObjectName>,
parameters: Vec<Expr>,
has_parentheses: bool,
immediate: bool,
into: Vec<Ident>,
using: Vec<ExprWithAlias>,
output: bool,
default: bool,
},
Prepare {
name: Ident,
data_types: Vec<DataType>,
statement: Box<Statement>,
},
Kill {
modifier: Option<KillType>,
id: u64,
},
ExplainTable {
describe_alias: DescribeAlias,
hive_format: Option<HiveDescribeFormat>,
has_table_keyword: bool,
#[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
table_name: ObjectName,
},
Explain {
describe_alias: DescribeAlias,
analyze: bool,
verbose: bool,
query_plan: bool,
estimate: bool,
statement: Box<Statement>,
format: Option<AnalyzeFormatKind>,
options: Option<Vec<UtilityOption>>,
},
Savepoint {
name: Ident,
},
ReleaseSavepoint {
name: Ident,
},
Merge(Merge),
Cache {
table_flag: Option<ObjectName>,
#[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
table_name: ObjectName,
has_as: bool,
options: Vec<SqlOption>,
query: Option<Box<Query>>,
},
UNCache {
#[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
table_name: ObjectName,
if_exists: bool,
},
CreateSequence {
temporary: bool,
if_not_exists: bool,
name: ObjectName,
data_type: Option<DataType>,
sequence_options: Vec<SequenceOptions>,
owned_by: Option<ObjectName>,
},
CreateDomain(CreateDomain),
CreateType {
name: ObjectName,
representation: Option<UserDefinedTypeRepresentation>,
},
Pragma {
name: ObjectName,
value: Option<Value>,
is_eq: bool,
},
LockTables {
tables: Vec<LockTable>,
},
UnlockTables,
Unload {
query: Option<Box<Query>>,
query_text: Option<String>,
to: Ident,
auth: Option<IamRoleKind>,
with: Vec<SqlOption>,
options: Vec<CopyLegacyOption>,
},
OptimizeTable {
name: ObjectName,
on_cluster: Option<Ident>,
partition: Option<Partition>,
include_final: bool,
deduplicate: Option<Deduplicate>,
},
LISTEN {
channel: Ident,
},
UNLISTEN {
channel: Ident,
},
NOTIFY {
channel: Ident,
payload: Option<String>,
},
LoadData {
local: bool,
inpath: String,
overwrite: bool,
table_name: ObjectName,
partitioned: Option<Vec<Expr>>,
table_format: Option<HiveLoadDataFormat>,
},
RenameTable(Vec<RenameTable>),
List(FileStagingCommand),
Remove(FileStagingCommand),
RaisError {
message: Box<Expr>,
severity: Box<Expr>,
state: Box<Expr>,
arguments: Vec<Expr>,
options: Vec<RaisErrorOption>,
},
Print(PrintStatement),
Return(ReturnStatement),
ExportData(ExportData),
CreateUser(CreateUser),
AlterUser(AlterUser),
Vacuum(VacuumStatement),
Reset(ResetStatement),
}
impl From<Analyze> for Statement {
fn from(analyze: Analyze) -> Self {
Statement::Analyze(analyze)
}
}
impl From<ddl::Truncate> for Statement {
fn from(truncate: ddl::Truncate) -> Self {
Statement::Truncate(truncate)
}
}
impl From<ddl::Msck> for Statement {
fn from(msck: ddl::Msck) -> Self {
Statement::Msck(msck)
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum CurrentGrantsKind {
CopyCurrentGrants,
RevokeCurrentGrants,
}
impl fmt::Display for CurrentGrantsKind {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
CurrentGrantsKind::CopyCurrentGrants => write!(f, "COPY CURRENT GRANTS"),
CurrentGrantsKind::RevokeCurrentGrants => write!(f, "REVOKE CURRENT GRANTS"),
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum RaisErrorOption {
Log,
NoWait,
SetError,
}
impl fmt::Display for RaisErrorOption {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
RaisErrorOption::Log => write!(f, "LOG"),
RaisErrorOption::NoWait => write!(f, "NOWAIT"),
RaisErrorOption::SetError => write!(f, "SETERROR"),
}
}
}
impl fmt::Display for Statement {
#[allow(clippy::cognitive_complexity)]
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Statement::Flush {
object_type,
location,
channel,
read_lock,
export,
tables,
} => {
write!(f, "FLUSH")?;
if let Some(location) = location {
f.write_str(" ")?;
location.fmt(f)?;
}
write!(f, " {object_type}")?;
if let Some(channel) = channel {
write!(f, " FOR CHANNEL {channel}")?;
}
write!(
f,
"{tables}{read}{export}",
tables = if !tables.is_empty() {
format!(" {}", display_comma_separated(tables))
} else {
String::new()
},
export = if *export { " FOR EXPORT" } else { "" },
read = if *read_lock { " WITH READ LOCK" } else { "" }
)
}
Statement::Kill { modifier, id } => {
write!(f, "KILL ")?;
if let Some(m) = modifier {
write!(f, "{m} ")?;
}
write!(f, "{id}")
}
Statement::ExplainTable {
describe_alias,
hive_format,
has_table_keyword,
table_name,
} => {
write!(f, "{describe_alias} ")?;
if let Some(format) = hive_format {
write!(f, "{format} ")?;
}
if *has_table_keyword {
write!(f, "TABLE ")?;
}
write!(f, "{table_name}")
}
Statement::Explain {
describe_alias,
verbose,
analyze,
query_plan,
estimate,
statement,
format,
options,
} => {
write!(f, "{describe_alias} ")?;
if *query_plan {
write!(f, "QUERY PLAN ")?;
}
if *analyze {
write!(f, "ANALYZE ")?;
}
if *estimate {
write!(f, "ESTIMATE ")?;
}
if *verbose {
write!(f, "VERBOSE ")?;
}
if let Some(format) = format {
write!(f, "{format} ")?;
}
if let Some(options) = options {
write!(f, "({}) ", display_comma_separated(options))?;
}
write!(f, "{statement}")
}
Statement::Query(s) => s.fmt(f),
Statement::Declare { stmts } => {
write!(f, "DECLARE ")?;
write!(f, "{}", display_separated(stmts, "; "))
}
Statement::Fetch {
name,
direction,
position,
into,
} => {
write!(f, "FETCH {direction} {position} {name}")?;
if let Some(into) = into {
write!(f, " INTO {into}")?;
}
Ok(())
}
Statement::Directory {
overwrite,
local,
path,
file_format,
source,
} => {
write!(
f,
"INSERT{overwrite}{local} DIRECTORY '{path}'",
overwrite = if *overwrite { " OVERWRITE" } else { "" },
local = if *local { " LOCAL" } else { "" },
path = path
)?;
if let Some(ref ff) = file_format {
write!(f, " STORED AS {ff}")?
}
write!(f, " {source}")
}
Statement::Msck(msck) => msck.fmt(f),
Statement::Truncate(truncate) => truncate.fmt(f),
Statement::Case(stmt) => {
write!(f, "{stmt}")
}
Statement::If(stmt) => {
write!(f, "{stmt}")
}
Statement::While(stmt) => {
write!(f, "{stmt}")
}
Statement::Raise(stmt) => {
write!(f, "{stmt}")
}
Statement::AttachDatabase {
schema_name,
database_file_name,
database,
} => {
let keyword = if *database { "DATABASE " } else { "" };
write!(f, "ATTACH {keyword}{database_file_name} AS {schema_name}")
}
Statement::AttachDuckDBDatabase {
if_not_exists,
database,
database_path,
database_alias,
attach_options,
} => {
write!(
f,
"ATTACH{database}{if_not_exists} {database_path}",
database = if *database { " DATABASE" } else { "" },
if_not_exists = if *if_not_exists { " IF NOT EXISTS" } else { "" },
)?;
if let Some(alias) = database_alias {
write!(f, " AS {alias}")?;
}
if !attach_options.is_empty() {
write!(f, " ({})", display_comma_separated(attach_options))?;
}
Ok(())
}
Statement::DetachDuckDBDatabase {
if_exists,
database,
database_alias,
} => {
write!(
f,
"DETACH{database}{if_exists} {database_alias}",
database = if *database { " DATABASE" } else { "" },
if_exists = if *if_exists { " IF EXISTS" } else { "" },
)?;
Ok(())
}
Statement::Analyze(analyze) => analyze.fmt(f),
Statement::Insert(insert) => insert.fmt(f),
Statement::Install {
extension_name: name,
} => write!(f, "INSTALL {name}"),
Statement::Load {
extension_name: name,
} => write!(f, "LOAD {name}"),
Statement::Call(function) => write!(f, "CALL {function}"),
Statement::Copy {
source,
to,
target,
options,
legacy_options,
values,
} => {
write!(f, "COPY")?;
match source {
CopySource::Query(query) => write!(f, " ({query})")?,
CopySource::Table {
table_name,
columns,
} => {
write!(f, " {table_name}")?;
if !columns.is_empty() {
write!(f, " ({})", display_comma_separated(columns))?;
}
}
}
write!(f, " {} {}", if *to { "TO" } else { "FROM" }, target)?;
if !options.is_empty() {
write!(f, " ({})", display_comma_separated(options))?;
}
if !legacy_options.is_empty() {
write!(f, " {}", display_separated(legacy_options, " "))?;
}
if !values.is_empty() {
writeln!(f, ";")?;
let mut delim = "";
for v in values {
write!(f, "{delim}")?;
delim = "\t";
if let Some(v) = v {
write!(f, "{v}")?;
} else {
write!(f, "\\N")?;
}
}
write!(f, "\n\\.")?;
}
Ok(())
}
Statement::Update(update) => update.fmt(f),
Statement::Delete(delete) => delete.fmt(f),
Statement::Open(open) => open.fmt(f),
Statement::Close { cursor } => {
write!(f, "CLOSE {cursor}")?;
Ok(())
}
Statement::CreateDatabase {
db_name,
if_not_exists,
location,
managed_location,
or_replace,
transient,
clone,
data_retention_time_in_days,
max_data_extension_time_in_days,
external_volume,
catalog,
replace_invalid_characters,
default_ddl_collation,
storage_serialization_policy,
comment,
default_charset,
default_collation,
catalog_sync,
catalog_sync_namespace_mode,
catalog_sync_namespace_flatten_delimiter,
with_tags,
with_contacts,
} => {
write!(
f,
"CREATE {or_replace}{transient}DATABASE {if_not_exists}{name}",
or_replace = if *or_replace { "OR REPLACE " } else { "" },
transient = if *transient { "TRANSIENT " } else { "" },
if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" },
name = db_name,
)?;
if let Some(l) = location {
write!(f, " LOCATION '{l}'")?;
}
if let Some(ml) = managed_location {
write!(f, " MANAGEDLOCATION '{ml}'")?;
}
if let Some(clone) = clone {
write!(f, " CLONE {clone}")?;
}
if let Some(value) = data_retention_time_in_days {
write!(f, " DATA_RETENTION_TIME_IN_DAYS = {value}")?;
}
if let Some(value) = max_data_extension_time_in_days {
write!(f, " MAX_DATA_EXTENSION_TIME_IN_DAYS = {value}")?;
}
if let Some(vol) = external_volume {
write!(f, " EXTERNAL_VOLUME = '{vol}'")?;
}
if let Some(cat) = catalog {
write!(f, " CATALOG = '{cat}'")?;
}
if let Some(true) = replace_invalid_characters {
write!(f, " REPLACE_INVALID_CHARACTERS = TRUE")?;
} else if let Some(false) = replace_invalid_characters {
write!(f, " REPLACE_INVALID_CHARACTERS = FALSE")?;
}
if let Some(collation) = default_ddl_collation {
write!(f, " DEFAULT_DDL_COLLATION = '{collation}'")?;
}
if let Some(policy) = storage_serialization_policy {
write!(f, " STORAGE_SERIALIZATION_POLICY = {policy}")?;
}
if let Some(comment) = comment {
write!(f, " COMMENT = '{comment}'")?;
}
if let Some(charset) = default_charset {
write!(f, " DEFAULT CHARACTER SET {charset}")?;
}
if let Some(collation) = default_collation {
write!(f, " DEFAULT COLLATE {collation}")?;
}
if let Some(sync) = catalog_sync {
write!(f, " CATALOG_SYNC = '{sync}'")?;
}
if let Some(mode) = catalog_sync_namespace_mode {
write!(f, " CATALOG_SYNC_NAMESPACE_MODE = {mode}")?;
}
if let Some(delim) = catalog_sync_namespace_flatten_delimiter {
write!(f, " CATALOG_SYNC_NAMESPACE_FLATTEN_DELIMITER = '{delim}'")?;
}
if let Some(tags) = with_tags {
write!(f, " WITH TAG ({})", display_comma_separated(tags))?;
}
if let Some(contacts) = with_contacts {
write!(f, " WITH CONTACT ({})", display_comma_separated(contacts))?;
}
Ok(())
}
Statement::CreateFunction(create_function) => create_function.fmt(f),
Statement::CreateDomain(create_domain) => create_domain.fmt(f),
Statement::CreateTrigger(create_trigger) => create_trigger.fmt(f),
Statement::DropTrigger(drop_trigger) => drop_trigger.fmt(f),
Statement::CreateProcedure {
name,
or_alter,
params,
language,
body,
} => {
write!(
f,
"CREATE {or_alter}PROCEDURE {name}",
or_alter = if *or_alter { "OR ALTER " } else { "" },
name = name
)?;
if let Some(p) = params {
if !p.is_empty() {
write!(f, " ({})", display_comma_separated(p))?;
}
}
if let Some(language) = language {
write!(f, " LANGUAGE {language}")?;
}
write!(f, " AS {body}")
}
Statement::CreateMacro {
or_replace,
temporary,
name,
args,
definition,
} => {
write!(
f,
"CREATE {or_replace}{temp}MACRO {name}",
temp = if *temporary { "TEMPORARY " } else { "" },
or_replace = if *or_replace { "OR REPLACE " } else { "" },
)?;
if let Some(args) = args {
write!(f, "({})", display_comma_separated(args))?;
}
match definition {
MacroDefinition::Expr(expr) => write!(f, " AS {expr}")?,
MacroDefinition::Table(query) => write!(f, " AS TABLE {query}")?,
}
Ok(())
}
Statement::CreateView(create_view) => create_view.fmt(f),
Statement::CreateTable(create_table) => create_table.fmt(f),
Statement::LoadData {
local,
inpath,
overwrite,
table_name,
partitioned,
table_format,
} => {
write!(
f,
"LOAD DATA {local}INPATH '{inpath}' {overwrite}INTO TABLE {table_name}",
local = if *local { "LOCAL " } else { "" },
inpath = inpath,
overwrite = if *overwrite { "OVERWRITE " } else { "" },
table_name = table_name,
)?;
if let Some(ref parts) = &partitioned {
if !parts.is_empty() {
write!(f, " PARTITION ({})", display_comma_separated(parts))?;
}
}
if let Some(HiveLoadDataFormat {
serde,
input_format,
}) = &table_format
{
write!(f, " INPUTFORMAT {input_format} SERDE {serde}")?;
}
Ok(())
}
Statement::CreateVirtualTable {
name,
if_not_exists,
module_name,
module_args,
} => {
write!(
f,
"CREATE VIRTUAL TABLE {if_not_exists}{name} USING {module_name}",
if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" },
name = name,
module_name = module_name
)?;
if !module_args.is_empty() {
write!(f, " ({})", display_comma_separated(module_args))?;
}
Ok(())
}
Statement::CreateIndex(create_index) => create_index.fmt(f),
Statement::CreateExtension(create_extension) => write!(f, "{create_extension}"),
Statement::DropExtension(drop_extension) => write!(f, "{drop_extension}"),
Statement::DropOperator(drop_operator) => write!(f, "{drop_operator}"),
Statement::DropOperatorFamily(drop_operator_family) => {
write!(f, "{drop_operator_family}")
}
Statement::DropOperatorClass(drop_operator_class) => {
write!(f, "{drop_operator_class}")
}
Statement::CreateRole(create_role) => write!(f, "{create_role}"),
Statement::CreateSecret {
or_replace,
temporary,
if_not_exists,
name,
storage_specifier,
secret_type,
options,
} => {
write!(
f,
"CREATE {or_replace}",
or_replace = if *or_replace { "OR REPLACE " } else { "" },
)?;
if let Some(t) = temporary {
write!(f, "{}", if *t { "TEMPORARY " } else { "PERSISTENT " })?;
}
write!(
f,
"SECRET {if_not_exists}",
if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" },
)?;
if let Some(n) = name {
write!(f, "{n} ")?;
};
if let Some(s) = storage_specifier {
write!(f, "IN {s} ")?;
}
write!(f, "( TYPE {secret_type}",)?;
if !options.is_empty() {
write!(f, ", {o}", o = display_comma_separated(options))?;
}
write!(f, " )")?;
Ok(())
}
Statement::CreateServer(stmt) => {
write!(f, "{stmt}")
}
Statement::CreatePolicy(policy) => write!(f, "{policy}"),
Statement::CreateConnector(create_connector) => create_connector.fmt(f),
Statement::CreateOperator(create_operator) => create_operator.fmt(f),
Statement::CreateOperatorFamily(create_operator_family) => {
create_operator_family.fmt(f)
}
Statement::CreateOperatorClass(create_operator_class) => create_operator_class.fmt(f),
Statement::AlterTable(alter_table) => write!(f, "{alter_table}"),
Statement::AlterIndex { name, operation } => {
write!(f, "ALTER INDEX {name} {operation}")
}
Statement::AlterView {
name,
columns,
query,
with_options,
} => {
write!(f, "ALTER VIEW {name}")?;
if !with_options.is_empty() {
write!(f, " WITH ({})", display_comma_separated(with_options))?;
}
if !columns.is_empty() {
write!(f, " ({})", display_comma_separated(columns))?;
}
write!(f, " AS {query}")
}
Statement::AlterType(AlterType { name, operation }) => {
write!(f, "ALTER TYPE {name} {operation}")
}
Statement::AlterOperator(alter_operator) => write!(f, "{alter_operator}"),
Statement::AlterOperatorFamily(alter_operator_family) => {
write!(f, "{alter_operator_family}")
}
Statement::AlterOperatorClass(alter_operator_class) => {
write!(f, "{alter_operator_class}")
}
Statement::AlterRole { name, operation } => {
write!(f, "ALTER ROLE {name} {operation}")
}
Statement::AlterPolicy(alter_policy) => write!(f, "{alter_policy}"),
Statement::AlterConnector {
name,
properties,
url,
owner,
} => {
write!(f, "ALTER CONNECTOR {name}")?;
if let Some(properties) = properties {
write!(
f,
" SET DCPROPERTIES({})",
display_comma_separated(properties)
)?;
}
if let Some(url) = url {
write!(f, " SET URL '{url}'")?;
}
if let Some(owner) = owner {
write!(f, " SET OWNER {owner}")?;
}
Ok(())
}
Statement::AlterSession {
set,
session_params,
} => {
write!(
f,
"ALTER SESSION {set}",
set = if *set { "SET" } else { "UNSET" }
)?;
if !session_params.options.is_empty() {
if *set {
write!(f, " {session_params}")?;
} else {
let options = session_params
.options
.iter()
.map(|p| p.option_name.clone())
.collect::<Vec<_>>();
write!(f, " {}", display_separated(&options, ", "))?;
}
}
Ok(())
}
Statement::Drop {
object_type,
if_exists,
names,
cascade,
restrict,
purge,
temporary,
table,
} => {
write!(
f,
"DROP {}{}{} {}{}{}{}",
if *temporary { "TEMPORARY " } else { "" },
object_type,
if *if_exists { " IF EXISTS" } else { "" },
display_comma_separated(names),
if *cascade { " CASCADE" } else { "" },
if *restrict { " RESTRICT" } else { "" },
if *purge { " PURGE" } else { "" },
)?;
if let Some(table_name) = table.as_ref() {
write!(f, " ON {table_name}")?;
};
Ok(())
}
Statement::DropFunction(drop_function) => write!(f, "{drop_function}"),
Statement::DropDomain(DropDomain {
if_exists,
name,
drop_behavior,
}) => {
write!(
f,
"DROP DOMAIN{} {name}",
if *if_exists { " IF EXISTS" } else { "" },
)?;
if let Some(op) = drop_behavior {
write!(f, " {op}")?;
}
Ok(())
}
Statement::DropProcedure {
if_exists,
proc_desc,
drop_behavior,
} => {
write!(
f,
"DROP PROCEDURE{} {}",
if *if_exists { " IF EXISTS" } else { "" },
display_comma_separated(proc_desc),
)?;
if let Some(op) = drop_behavior {
write!(f, " {op}")?;
}
Ok(())
}
Statement::DropSecret {
if_exists,
temporary,
name,
storage_specifier,
} => {
write!(f, "DROP ")?;
if let Some(t) = temporary {
write!(f, "{}", if *t { "TEMPORARY " } else { "PERSISTENT " })?;
}
write!(
f,
"SECRET {if_exists}{name}",
if_exists = if *if_exists { "IF EXISTS " } else { "" },
)?;
if let Some(s) = storage_specifier {
write!(f, " FROM {s}")?;
}
Ok(())
}
Statement::DropPolicy(policy) => write!(f, "{policy}"),
Statement::DropConnector { if_exists, name } => {
write!(
f,
"DROP CONNECTOR {if_exists}{name}",
if_exists = if *if_exists { "IF EXISTS " } else { "" }
)?;
Ok(())
}
Statement::Discard { object_type } => {
write!(f, "DISCARD {object_type}")?;
Ok(())
}
Self::Set(set) => write!(f, "{set}"),
Statement::ShowVariable { variable } => {
write!(f, "SHOW")?;
if !variable.is_empty() {
write!(f, " {}", display_separated(variable, " "))?;
}
Ok(())
}
Statement::ShowStatus {
filter,
global,
session,
} => {
write!(f, "SHOW")?;
if *global {
write!(f, " GLOBAL")?;
}
if *session {
write!(f, " SESSION")?;
}
write!(f, " STATUS")?;
if filter.is_some() {
write!(f, " {}", filter.as_ref().unwrap())?;
}
Ok(())
}
Statement::ShowVariables {
filter,
global,
session,
} => {
write!(f, "SHOW")?;
if *global {
write!(f, " GLOBAL")?;
}
if *session {
write!(f, " SESSION")?;
}
write!(f, " VARIABLES")?;
if filter.is_some() {
write!(f, " {}", filter.as_ref().unwrap())?;
}
Ok(())
}
Statement::ShowCreate { obj_type, obj_name } => {
write!(f, "SHOW CREATE {obj_type} {obj_name}",)?;
Ok(())
}
Statement::ShowColumns {
extended,
full,
show_options,
} => {
write!(
f,
"SHOW {extended}{full}COLUMNS{show_options}",
extended = if *extended { "EXTENDED " } else { "" },
full = if *full { "FULL " } else { "" },
)?;
Ok(())
}
Statement::ShowDatabases {
terse,
history,
show_options,
} => {
write!(
f,
"SHOW {terse}DATABASES{history}{show_options}",
terse = if *terse { "TERSE " } else { "" },
history = if *history { " HISTORY" } else { "" },
)?;
Ok(())
}
Statement::ShowSchemas {
terse,
history,
show_options,
} => {
write!(
f,
"SHOW {terse}SCHEMAS{history}{show_options}",
terse = if *terse { "TERSE " } else { "" },
history = if *history { " HISTORY" } else { "" },
)?;
Ok(())
}
Statement::ShowObjects(ShowObjects {
terse,
show_options,
}) => {
write!(
f,
"SHOW {terse}OBJECTS{show_options}",
terse = if *terse { "TERSE " } else { "" },
)?;
Ok(())
}
Statement::ShowTables {
terse,
history,
extended,
full,
external,
show_options,
} => {
write!(
f,
"SHOW {terse}{extended}{full}{external}TABLES{history}{show_options}",
terse = if *terse { "TERSE " } else { "" },
extended = if *extended { "EXTENDED " } else { "" },
full = if *full { "FULL " } else { "" },
external = if *external { "EXTERNAL " } else { "" },
history = if *history { " HISTORY" } else { "" },
)?;
Ok(())
}
Statement::ShowViews {
terse,
materialized,
show_options,
} => {
write!(
f,
"SHOW {terse}{materialized}VIEWS{show_options}",
terse = if *terse { "TERSE " } else { "" },
materialized = if *materialized { "MATERIALIZED " } else { "" }
)?;
Ok(())
}
Statement::ShowFunctions { filter } => {
write!(f, "SHOW FUNCTIONS")?;
if let Some(filter) = filter {
write!(f, " {filter}")?;
}
Ok(())
}
Statement::Use(use_expr) => use_expr.fmt(f),
Statement::ShowCollation { filter } => {
write!(f, "SHOW COLLATION")?;
if let Some(filter) = filter {
write!(f, " {filter}")?;
}
Ok(())
}
Statement::ShowCharset(show_stm) => show_stm.fmt(f),
Statement::StartTransaction {
modes,
begin: syntax_begin,
transaction,
modifier,
statements,
exception,
has_end_keyword,
} => {
if *syntax_begin {
if let Some(modifier) = *modifier {
write!(f, "BEGIN {modifier}")?;
} else {
write!(f, "BEGIN")?;
}
} else {
write!(f, "START")?;
}
if let Some(transaction) = transaction {
write!(f, " {transaction}")?;
}
if !modes.is_empty() {
write!(f, " {}", display_comma_separated(modes))?;
}
if !statements.is_empty() {
write!(f, " ")?;
format_statement_list(f, statements)?;
}
if let Some(exception_when) = exception {
write!(f, " EXCEPTION")?;
for when in exception_when {
write!(f, " {when}")?;
}
}
if *has_end_keyword {
write!(f, " END")?;
}
Ok(())
}
Statement::Commit {
chain,
end: end_syntax,
modifier,
} => {
if *end_syntax {
write!(f, "END")?;
if let Some(modifier) = *modifier {
write!(f, " {modifier}")?;
}
if *chain {
write!(f, " AND CHAIN")?;
}
} else {
write!(f, "COMMIT{}", if *chain { " AND CHAIN" } else { "" })?;
}
Ok(())
}
Statement::Rollback { chain, savepoint } => {
write!(f, "ROLLBACK")?;
if *chain {
write!(f, " AND CHAIN")?;
}
if let Some(savepoint) = savepoint {
write!(f, " TO SAVEPOINT {savepoint}")?;
}
Ok(())
}
Statement::CreateSchema {
schema_name,
if_not_exists,
with,
options,
default_collate_spec,
clone,
} => {
write!(
f,
"CREATE SCHEMA {if_not_exists}{name}",
if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" },
name = schema_name
)?;
if let Some(collate) = default_collate_spec {
write!(f, " DEFAULT COLLATE {collate}")?;
}
if let Some(with) = with {
write!(f, " WITH ({})", display_comma_separated(with))?;
}
if let Some(options) = options {
write!(f, " OPTIONS({})", display_comma_separated(options))?;
}
if let Some(clone) = clone {
write!(f, " CLONE {clone}")?;
}
Ok(())
}
Statement::Assert { condition, message } => {
write!(f, "ASSERT {condition}")?;
if let Some(m) = message {
write!(f, " AS {m}")?;
}
Ok(())
}
Statement::Grant(grant) => write!(f, "{grant}"),
Statement::Deny(s) => write!(f, "{s}"),
Statement::Revoke(revoke) => write!(f, "{revoke}"),
Statement::Deallocate { name, prepare } => write!(
f,
"DEALLOCATE {prepare}{name}",
prepare = if *prepare { "PREPARE " } else { "" },
name = name,
),
Statement::Execute {
name,
parameters,
has_parentheses,
immediate,
into,
using,
output,
default,
} => {
let (open, close) = if *has_parentheses {
("(", ")")
} else {
(if parameters.is_empty() { "" } else { " " }, "")
};
write!(f, "EXECUTE")?;
if *immediate {
write!(f, " IMMEDIATE")?;
}
if let Some(name) = name {
write!(f, " {name}")?;
}
write!(f, "{open}{}{close}", display_comma_separated(parameters),)?;
if !into.is_empty() {
write!(f, " INTO {}", display_comma_separated(into))?;
}
if !using.is_empty() {
write!(f, " USING {}", display_comma_separated(using))?;
};
if *output {
write!(f, " OUTPUT")?;
}
if *default {
write!(f, " DEFAULT")?;
}
Ok(())
}
Statement::Prepare {
name,
data_types,
statement,
} => {
write!(f, "PREPARE {name} ")?;
if !data_types.is_empty() {
write!(f, "({}) ", display_comma_separated(data_types))?;
}
write!(f, "AS {statement}")
}
Statement::Comment {
object_type,
object_name,
comment,
if_exists,
} => {
write!(f, "COMMENT ")?;
if *if_exists {
write!(f, "IF EXISTS ")?
};
write!(f, "ON {object_type} {object_name} IS ")?;
if let Some(c) = comment {
write!(f, "'{c}'")
} else {
write!(f, "NULL")
}
}
Statement::Savepoint { name } => {
write!(f, "SAVEPOINT ")?;
write!(f, "{name}")
}
Statement::ReleaseSavepoint { name } => {
write!(f, "RELEASE SAVEPOINT {name}")
}
Statement::Merge(merge) => merge.fmt(f),
Statement::Cache {
table_name,
table_flag,
has_as,
options,
query,
} => {
if let Some(table_flag) = table_flag {
write!(f, "CACHE {table_flag} TABLE {table_name}")?;
} else {
write!(f, "CACHE TABLE {table_name}")?;
}
if !options.is_empty() {
write!(f, " OPTIONS({})", display_comma_separated(options))?;
}
match (*has_as, query) {
(true, Some(query)) => write!(f, " AS {query}"),
(true, None) => f.write_str(" AS"),
(false, Some(query)) => write!(f, " {query}"),
(false, None) => Ok(()),
}
}
Statement::UNCache {
table_name,
if_exists,
} => {
if *if_exists {
write!(f, "UNCACHE TABLE IF EXISTS {table_name}")
} else {
write!(f, "UNCACHE TABLE {table_name}")
}
}
Statement::CreateSequence {
temporary,
if_not_exists,
name,
data_type,
sequence_options,
owned_by,
} => {
let as_type: String = if let Some(dt) = data_type.as_ref() {
[" AS ", &dt.to_string()].concat()
} else {
"".to_string()
};
write!(
f,
"CREATE {temporary}SEQUENCE {if_not_exists}{name}{as_type}",
if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" },
temporary = if *temporary { "TEMPORARY " } else { "" },
name = name,
as_type = as_type
)?;
for sequence_option in sequence_options {
write!(f, "{sequence_option}")?;
}
if let Some(ob) = owned_by.as_ref() {
write!(f, " OWNED BY {ob}")?;
}
write!(f, "")
}
Statement::CreateStage {
or_replace,
temporary,
if_not_exists,
name,
stage_params,
directory_table_params,
file_format,
copy_options,
comment,
..
} => {
write!(
f,
"CREATE {or_replace}{temp}STAGE {if_not_exists}{name}{stage_params}",
temp = if *temporary { "TEMPORARY " } else { "" },
or_replace = if *or_replace { "OR REPLACE " } else { "" },
if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" },
)?;
if !directory_table_params.options.is_empty() {
write!(f, " DIRECTORY=({directory_table_params})")?;
}
if !file_format.options.is_empty() {
write!(f, " FILE_FORMAT=({file_format})")?;
}
if !copy_options.options.is_empty() {
write!(f, " COPY_OPTIONS=({copy_options})")?;
}
if comment.is_some() {
write!(f, " COMMENT='{}'", comment.as_ref().unwrap())?;
}
Ok(())
}
Statement::CopyIntoSnowflake {
kind,
into,
into_columns,
from_obj,
from_obj_alias,
stage_params,
from_transformations,
from_query,
files,
pattern,
file_format,
copy_options,
validation_mode,
partition,
} => {
write!(f, "COPY INTO {into}")?;
if let Some(into_columns) = into_columns {
write!(f, " ({})", display_comma_separated(into_columns))?;
}
if let Some(from_transformations) = from_transformations {
if let Some(from_stage) = from_obj {
write!(
f,
" FROM (SELECT {} FROM {}{}",
display_separated(from_transformations, ", "),
from_stage,
stage_params
)?;
}
if let Some(from_obj_alias) = from_obj_alias {
write!(f, " AS {from_obj_alias}")?;
}
write!(f, ")")?;
} else if let Some(from_obj) = from_obj {
write!(f, " FROM {from_obj}{stage_params}")?;
if let Some(from_obj_alias) = from_obj_alias {
write!(f, " AS {from_obj_alias}")?;
}
} else if let Some(from_query) = from_query {
write!(f, " FROM ({from_query})")?;
}
if let Some(files) = files {
write!(f, " FILES = ('{}')", display_separated(files, "', '"))?;
}
if let Some(pattern) = pattern {
write!(f, " PATTERN = '{pattern}'")?;
}
if let Some(partition) = partition {
write!(f, " PARTITION BY {partition}")?;
}
if !file_format.options.is_empty() {
write!(f, " FILE_FORMAT=({file_format})")?;
}
if !copy_options.options.is_empty() {
match kind {
CopyIntoSnowflakeKind::Table => {
write!(f, " COPY_OPTIONS=({copy_options})")?
}
CopyIntoSnowflakeKind::Location => write!(f, " {copy_options}")?,
}
}
if let Some(validation_mode) = validation_mode {
write!(f, " VALIDATION_MODE = {validation_mode}")?;
}
Ok(())
}
Statement::CreateType {
name,
representation,
} => {
write!(f, "CREATE TYPE {name}")?;
if let Some(repr) = representation {
write!(f, " {repr}")?;
}
Ok(())
}
Statement::Pragma { name, value, is_eq } => {
write!(f, "PRAGMA {name}")?;
if value.is_some() {
let val = value.as_ref().unwrap();
if *is_eq {
write!(f, " = {val}")?;
} else {
write!(f, "({val})")?;
}
}
Ok(())
}
Statement::LockTables { tables } => {
write!(f, "LOCK TABLES {}", display_comma_separated(tables))
}
Statement::UnlockTables => {
write!(f, "UNLOCK TABLES")
}
Statement::Unload {
query,
query_text,
to,
auth,
with,
options,
} => {
write!(f, "UNLOAD(")?;
if let Some(query) = query {
write!(f, "{query}")?;
}
if let Some(query_text) = query_text {
write!(f, "'{query_text}'")?;
}
write!(f, ") TO {to}")?;
if let Some(auth) = auth {
write!(f, " IAM_ROLE {auth}")?;
}
if !with.is_empty() {
write!(f, " WITH ({})", display_comma_separated(with))?;
}
if !options.is_empty() {
write!(f, " {}", display_separated(options, " "))?;
}
Ok(())
}
Statement::OptimizeTable {
name,
on_cluster,
partition,
include_final,
deduplicate,
} => {
write!(f, "OPTIMIZE TABLE {name}")?;
if let Some(on_cluster) = on_cluster {
write!(f, " ON CLUSTER {on_cluster}")?;
}
if let Some(partition) = partition {
write!(f, " {partition}")?;
}
if *include_final {
write!(f, " FINAL")?;
}
if let Some(deduplicate) = deduplicate {
write!(f, " {deduplicate}")?;
}
Ok(())
}
Statement::LISTEN { channel } => {
write!(f, "LISTEN {channel}")?;
Ok(())
}
Statement::UNLISTEN { channel } => {
write!(f, "UNLISTEN {channel}")?;
Ok(())
}
Statement::NOTIFY { channel, payload } => {
write!(f, "NOTIFY {channel}")?;
if let Some(payload) = payload {
write!(f, ", '{payload}'")?;
}
Ok(())
}
Statement::RenameTable(rename_tables) => {
write!(f, "RENAME TABLE {}", display_comma_separated(rename_tables))
}
Statement::RaisError {
message,
severity,
state,
arguments,
options,
} => {
write!(f, "RAISERROR({message}, {severity}, {state}")?;
if !arguments.is_empty() {
write!(f, ", {}", display_comma_separated(arguments))?;
}
write!(f, ")")?;
if !options.is_empty() {
write!(f, " WITH {}", display_comma_separated(options))?;
}
Ok(())
}
Statement::Print(s) => write!(f, "{s}"),
Statement::Return(r) => write!(f, "{r}"),
Statement::List(command) => write!(f, "LIST {command}"),
Statement::Remove(command) => write!(f, "REMOVE {command}"),
Statement::ExportData(e) => write!(f, "{e}"),
Statement::CreateUser(s) => write!(f, "{s}"),
Statement::AlterSchema(s) => write!(f, "{s}"),
Statement::Vacuum(s) => write!(f, "{s}"),
Statement::AlterUser(s) => write!(f, "{s}"),
Statement::Reset(s) => write!(f, "{s}"),
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum SequenceOptions {
IncrementBy(Expr, bool),
MinValue(Option<Expr>),
MaxValue(Option<Expr>),
StartWith(Expr, bool),
Cache(Expr),
Cycle(bool),
}
impl fmt::Display for SequenceOptions {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
SequenceOptions::IncrementBy(increment, by) => {
write!(
f,
" INCREMENT{by} {increment}",
by = if *by { " BY" } else { "" },
increment = increment
)
}
SequenceOptions::MinValue(Some(expr)) => {
write!(f, " MINVALUE {expr}")
}
SequenceOptions::MinValue(None) => {
write!(f, " NO MINVALUE")
}
SequenceOptions::MaxValue(Some(expr)) => {
write!(f, " MAXVALUE {expr}")
}
SequenceOptions::MaxValue(None) => {
write!(f, " NO MAXVALUE")
}
SequenceOptions::StartWith(start, with) => {
write!(
f,
" START{with} {start}",
with = if *with { " WITH" } else { "" },
start = start
)
}
SequenceOptions::Cache(cache) => {
write!(f, " CACHE {}", *cache)
}
SequenceOptions::Cycle(no) => {
write!(f, " {}CYCLE", if *no { "NO " } else { "" })
}
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct SetAssignment {
pub scope: Option<ContextModifier>,
pub name: ObjectName,
pub value: Expr,
}
impl fmt::Display for SetAssignment {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"{}{} = {}",
self.scope.map(|s| format!("{s}")).unwrap_or_default(),
self.name,
self.value
)
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct TruncateTableTarget {
#[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
pub name: ObjectName,
pub only: bool,
pub has_asterisk: bool,
}
impl fmt::Display for TruncateTableTarget {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if self.only {
write!(f, "ONLY ")?;
};
write!(f, "{}", self.name)?;
if self.has_asterisk {
write!(f, " *")?;
};
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 TruncateIdentityOption {
Restart,
Continue,
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum CascadeOption {
Cascade,
Restrict,
}
impl Display for CascadeOption {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
CascadeOption::Cascade => write!(f, "CASCADE"),
CascadeOption::Restrict => write!(f, "RESTRICT"),
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum BeginTransactionKind {
Transaction,
Work,
}
impl Display for BeginTransactionKind {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
BeginTransactionKind::Transaction => write!(f, "TRANSACTION"),
BeginTransactionKind::Work => write!(f, "WORK"),
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum MinMaxValue {
Empty,
None,
Some(Expr),
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
#[non_exhaustive]
pub enum OnInsert {
DuplicateKeyUpdate(Vec<Assignment>),
OnConflict(OnConflict),
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct InsertAliases {
pub row_alias: ObjectName,
pub col_aliases: 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 OnConflict {
pub conflict_target: Option<ConflictTarget>,
pub action: OnConflictAction,
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum ConflictTarget {
Columns(Vec<Ident>),
OnConstraint(ObjectName),
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum OnConflictAction {
DoNothing,
DoUpdate(DoUpdate),
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct DoUpdate {
pub assignments: Vec<Assignment>,
pub selection: Option<Expr>,
}
impl fmt::Display for OnInsert {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::DuplicateKeyUpdate(expr) => write!(
f,
" ON DUPLICATE KEY UPDATE {}",
display_comma_separated(expr)
),
Self::OnConflict(o) => write!(f, "{o}"),
}
}
}
impl fmt::Display for OnConflict {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, " ON CONFLICT")?;
if let Some(target) = &self.conflict_target {
write!(f, "{target}")?;
}
write!(f, " {}", self.action)
}
}
impl fmt::Display for ConflictTarget {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
ConflictTarget::Columns(cols) => write!(f, "({})", display_comma_separated(cols)),
ConflictTarget::OnConstraint(name) => write!(f, " ON CONSTRAINT {name}"),
}
}
}
impl fmt::Display for OnConflictAction {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::DoNothing => write!(f, "DO NOTHING"),
Self::DoUpdate(do_update) => {
write!(f, "DO UPDATE")?;
if !do_update.assignments.is_empty() {
write!(
f,
" SET {}",
display_comma_separated(&do_update.assignments)
)?;
}
if let Some(selection) = &do_update.selection {
write!(f, " WHERE {selection}")?;
}
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 Privileges {
All {
with_privileges_keyword: bool,
},
Actions(Vec<Action>),
}
impl fmt::Display for Privileges {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Privileges::All {
with_privileges_keyword,
} => {
write!(
f,
"ALL{}",
if *with_privileges_keyword {
" PRIVILEGES"
} else {
""
}
)
}
Privileges::Actions(actions) => {
write!(f, "{}", display_comma_separated(actions))
}
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum FetchDirection {
Count {
limit: Value,
},
Next,
Prior,
First,
Last,
Absolute {
limit: Value,
},
Relative {
limit: Value,
},
All,
Forward {
limit: Option<Value>,
},
ForwardAll,
Backward {
limit: Option<Value>,
},
BackwardAll,
}
impl fmt::Display for FetchDirection {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
FetchDirection::Count { limit } => f.write_str(&limit.to_string())?,
FetchDirection::Next => f.write_str("NEXT")?,
FetchDirection::Prior => f.write_str("PRIOR")?,
FetchDirection::First => f.write_str("FIRST")?,
FetchDirection::Last => f.write_str("LAST")?,
FetchDirection::Absolute { limit } => {
f.write_str("ABSOLUTE ")?;
f.write_str(&limit.to_string())?;
}
FetchDirection::Relative { limit } => {
f.write_str("RELATIVE ")?;
f.write_str(&limit.to_string())?;
}
FetchDirection::All => f.write_str("ALL")?,
FetchDirection::Forward { limit } => {
f.write_str("FORWARD")?;
if let Some(l) = limit {
f.write_str(" ")?;
f.write_str(&l.to_string())?;
}
}
FetchDirection::ForwardAll => f.write_str("FORWARD ALL")?,
FetchDirection::Backward { limit } => {
f.write_str("BACKWARD")?;
if let Some(l) = limit {
f.write_str(" ")?;
f.write_str(&l.to_string())?;
}
}
FetchDirection::BackwardAll => f.write_str("BACKWARD ALL")?,
};
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 FetchPosition {
From,
In,
}
impl fmt::Display for FetchPosition {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
FetchPosition::From => f.write_str("FROM")?,
FetchPosition::In => f.write_str("IN")?,
};
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 Action {
AddSearchOptimization,
Apply {
apply_type: ActionApplyType,
},
ApplyBudget,
AttachListing,
AttachPolicy,
Audit,
BindServiceEndpoint,
Connect,
Create {
obj_type: Option<ActionCreateObjectType>,
},
DatabaseRole {
role: ObjectName,
},
Delete,
Drop,
EvolveSchema,
Exec {
obj_type: Option<ActionExecuteObjectType>,
},
Execute {
obj_type: Option<ActionExecuteObjectType>,
},
Failover,
ImportedPrivileges,
ImportShare,
Insert {
columns: Option<Vec<Ident>>,
},
Manage {
manage_type: ActionManageType,
},
ManageReleases,
ManageVersions,
Modify {
modify_type: Option<ActionModifyType>,
},
Monitor {
monitor_type: Option<ActionMonitorType>,
},
Operate,
OverrideShareRestrictions,
Ownership,
PurchaseDataExchangeListing,
Read,
ReadSession,
References {
columns: Option<Vec<Ident>>,
},
Replicate,
ResolveAll,
Role {
role: ObjectName,
},
Select {
columns: Option<Vec<Ident>>,
},
Temporary,
Trigger,
Truncate,
Update {
columns: Option<Vec<Ident>>,
},
Usage,
}
impl fmt::Display for Action {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Action::AddSearchOptimization => f.write_str("ADD SEARCH OPTIMIZATION")?,
Action::Apply { apply_type } => write!(f, "APPLY {apply_type}")?,
Action::ApplyBudget => f.write_str("APPLYBUDGET")?,
Action::AttachListing => f.write_str("ATTACH LISTING")?,
Action::AttachPolicy => f.write_str("ATTACH POLICY")?,
Action::Audit => f.write_str("AUDIT")?,
Action::BindServiceEndpoint => f.write_str("BIND SERVICE ENDPOINT")?,
Action::Connect => f.write_str("CONNECT")?,
Action::Create { obj_type } => {
f.write_str("CREATE")?;
if let Some(obj_type) = obj_type {
write!(f, " {obj_type}")?
}
}
Action::DatabaseRole { role } => write!(f, "DATABASE ROLE {role}")?,
Action::Delete => f.write_str("DELETE")?,
Action::Drop => f.write_str("DROP")?,
Action::EvolveSchema => f.write_str("EVOLVE SCHEMA")?,
Action::Exec { obj_type } => {
f.write_str("EXEC")?;
if let Some(obj_type) = obj_type {
write!(f, " {obj_type}")?
}
}
Action::Execute { obj_type } => {
f.write_str("EXECUTE")?;
if let Some(obj_type) = obj_type {
write!(f, " {obj_type}")?
}
}
Action::Failover => f.write_str("FAILOVER")?,
Action::ImportedPrivileges => f.write_str("IMPORTED PRIVILEGES")?,
Action::ImportShare => f.write_str("IMPORT SHARE")?,
Action::Insert { .. } => f.write_str("INSERT")?,
Action::Manage { manage_type } => write!(f, "MANAGE {manage_type}")?,
Action::ManageReleases => f.write_str("MANAGE RELEASES")?,
Action::ManageVersions => f.write_str("MANAGE VERSIONS")?,
Action::Modify { modify_type } => {
write!(f, "MODIFY")?;
if let Some(modify_type) = modify_type {
write!(f, " {modify_type}")?;
}
}
Action::Monitor { monitor_type } => {
write!(f, "MONITOR")?;
if let Some(monitor_type) = monitor_type {
write!(f, " {monitor_type}")?
}
}
Action::Operate => f.write_str("OPERATE")?,
Action::OverrideShareRestrictions => f.write_str("OVERRIDE SHARE RESTRICTIONS")?,
Action::Ownership => f.write_str("OWNERSHIP")?,
Action::PurchaseDataExchangeListing => f.write_str("PURCHASE DATA EXCHANGE LISTING")?,
Action::Read => f.write_str("READ")?,
Action::ReadSession => f.write_str("READ SESSION")?,
Action::References { .. } => f.write_str("REFERENCES")?,
Action::Replicate => f.write_str("REPLICATE")?,
Action::ResolveAll => f.write_str("RESOLVE ALL")?,
Action::Role { role } => write!(f, "ROLE {role}")?,
Action::Select { .. } => f.write_str("SELECT")?,
Action::Temporary => f.write_str("TEMPORARY")?,
Action::Trigger => f.write_str("TRIGGER")?,
Action::Truncate => f.write_str("TRUNCATE")?,
Action::Update { .. } => f.write_str("UPDATE")?,
Action::Usage => f.write_str("USAGE")?,
};
match self {
Action::Insert { columns }
| Action::References { columns }
| Action::Select { columns }
| Action::Update { columns } => {
if let Some(columns) = columns {
write!(f, " ({})", display_comma_separated(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 enum ActionCreateObjectType {
Account,
Application,
ApplicationPackage,
ComputePool,
DataExchangeListing,
Database,
ExternalVolume,
FailoverGroup,
Integration,
NetworkPolicy,
OrganiationListing,
ReplicationGroup,
Role,
Schema,
Share,
User,
Warehouse,
}
impl fmt::Display for ActionCreateObjectType {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
ActionCreateObjectType::Account => write!(f, "ACCOUNT"),
ActionCreateObjectType::Application => write!(f, "APPLICATION"),
ActionCreateObjectType::ApplicationPackage => write!(f, "APPLICATION PACKAGE"),
ActionCreateObjectType::ComputePool => write!(f, "COMPUTE POOL"),
ActionCreateObjectType::DataExchangeListing => write!(f, "DATA EXCHANGE LISTING"),
ActionCreateObjectType::Database => write!(f, "DATABASE"),
ActionCreateObjectType::ExternalVolume => write!(f, "EXTERNAL VOLUME"),
ActionCreateObjectType::FailoverGroup => write!(f, "FAILOVER GROUP"),
ActionCreateObjectType::Integration => write!(f, "INTEGRATION"),
ActionCreateObjectType::NetworkPolicy => write!(f, "NETWORK POLICY"),
ActionCreateObjectType::OrganiationListing => write!(f, "ORGANIZATION LISTING"),
ActionCreateObjectType::ReplicationGroup => write!(f, "REPLICATION GROUP"),
ActionCreateObjectType::Role => write!(f, "ROLE"),
ActionCreateObjectType::Schema => write!(f, "SCHEMA"),
ActionCreateObjectType::Share => write!(f, "SHARE"),
ActionCreateObjectType::User => write!(f, "USER"),
ActionCreateObjectType::Warehouse => write!(f, "WAREHOUSE"),
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum ActionApplyType {
AggregationPolicy,
AuthenticationPolicy,
JoinPolicy,
MaskingPolicy,
PackagesPolicy,
PasswordPolicy,
ProjectionPolicy,
RowAccessPolicy,
SessionPolicy,
Tag,
}
impl fmt::Display for ActionApplyType {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
ActionApplyType::AggregationPolicy => write!(f, "AGGREGATION POLICY"),
ActionApplyType::AuthenticationPolicy => write!(f, "AUTHENTICATION POLICY"),
ActionApplyType::JoinPolicy => write!(f, "JOIN POLICY"),
ActionApplyType::MaskingPolicy => write!(f, "MASKING POLICY"),
ActionApplyType::PackagesPolicy => write!(f, "PACKAGES POLICY"),
ActionApplyType::PasswordPolicy => write!(f, "PASSWORD POLICY"),
ActionApplyType::ProjectionPolicy => write!(f, "PROJECTION POLICY"),
ActionApplyType::RowAccessPolicy => write!(f, "ROW ACCESS POLICY"),
ActionApplyType::SessionPolicy => write!(f, "SESSION POLICY"),
ActionApplyType::Tag => write!(f, "TAG"),
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum ActionExecuteObjectType {
Alert,
DataMetricFunction,
ManagedAlert,
ManagedTask,
Task,
}
impl fmt::Display for ActionExecuteObjectType {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
ActionExecuteObjectType::Alert => write!(f, "ALERT"),
ActionExecuteObjectType::DataMetricFunction => write!(f, "DATA METRIC FUNCTION"),
ActionExecuteObjectType::ManagedAlert => write!(f, "MANAGED ALERT"),
ActionExecuteObjectType::ManagedTask => write!(f, "MANAGED TASK"),
ActionExecuteObjectType::Task => write!(f, "TASK"),
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum ActionManageType {
AccountSupportCases,
EventSharing,
Grants,
ListingAutoFulfillment,
OrganizationSupportCases,
UserSupportCases,
Warehouses,
}
impl fmt::Display for ActionManageType {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
ActionManageType::AccountSupportCases => write!(f, "ACCOUNT SUPPORT CASES"),
ActionManageType::EventSharing => write!(f, "EVENT SHARING"),
ActionManageType::Grants => write!(f, "GRANTS"),
ActionManageType::ListingAutoFulfillment => write!(f, "LISTING AUTO FULFILLMENT"),
ActionManageType::OrganizationSupportCases => write!(f, "ORGANIZATION SUPPORT CASES"),
ActionManageType::UserSupportCases => write!(f, "USER SUPPORT CASES"),
ActionManageType::Warehouses => write!(f, "WAREHOUSES"),
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum ActionModifyType {
LogLevel,
TraceLevel,
SessionLogLevel,
SessionTraceLevel,
}
impl fmt::Display for ActionModifyType {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
ActionModifyType::LogLevel => write!(f, "LOG LEVEL"),
ActionModifyType::TraceLevel => write!(f, "TRACE LEVEL"),
ActionModifyType::SessionLogLevel => write!(f, "SESSION LOG LEVEL"),
ActionModifyType::SessionTraceLevel => write!(f, "SESSION TRACE LEVEL"),
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum ActionMonitorType {
Execution,
Security,
Usage,
}
impl fmt::Display for ActionMonitorType {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
ActionMonitorType::Execution => write!(f, "EXECUTION"),
ActionMonitorType::Security => write!(f, "SECURITY"),
ActionMonitorType::Usage => write!(f, "USAGE"),
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct Grantee {
pub grantee_type: GranteesType,
pub name: Option<GranteeName>,
}
impl fmt::Display for Grantee {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self.grantee_type {
GranteesType::Role => {
write!(f, "ROLE ")?;
}
GranteesType::Share => {
write!(f, "SHARE ")?;
}
GranteesType::User => {
write!(f, "USER ")?;
}
GranteesType::Group => {
write!(f, "GROUP ")?;
}
GranteesType::Public => {
write!(f, "PUBLIC ")?;
}
GranteesType::DatabaseRole => {
write!(f, "DATABASE ROLE ")?;
}
GranteesType::Application => {
write!(f, "APPLICATION ")?;
}
GranteesType::ApplicationRole => {
write!(f, "APPLICATION ROLE ")?;
}
GranteesType::None => (),
}
if let Some(ref name) = self.name {
name.fmt(f)?;
}
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 GranteesType {
Role,
Share,
User,
Group,
Public,
DatabaseRole,
Application,
ApplicationRole,
None,
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum GranteeName {
ObjectName(ObjectName),
UserHost {
user: Ident,
host: Ident,
},
}
impl fmt::Display for GranteeName {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
GranteeName::ObjectName(name) => name.fmt(f),
GranteeName::UserHost { user, host } => {
write!(f, "{user}@{host}")
}
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum GrantObjects {
AllSequencesInSchema {
schemas: Vec<ObjectName>,
},
AllTablesInSchema {
schemas: Vec<ObjectName>,
},
AllViewsInSchema {
schemas: Vec<ObjectName>,
},
AllMaterializedViewsInSchema {
schemas: Vec<ObjectName>,
},
AllExternalTablesInSchema {
schemas: Vec<ObjectName>,
},
AllFunctionsInSchema {
schemas: Vec<ObjectName>,
},
FutureSchemasInDatabase {
databases: Vec<ObjectName>,
},
FutureTablesInSchema {
schemas: Vec<ObjectName>,
},
FutureViewsInSchema {
schemas: Vec<ObjectName>,
},
FutureExternalTablesInSchema {
schemas: Vec<ObjectName>,
},
FutureMaterializedViewsInSchema {
schemas: Vec<ObjectName>,
},
FutureSequencesInSchema {
schemas: Vec<ObjectName>,
},
Databases(Vec<ObjectName>),
Schemas(Vec<ObjectName>),
Sequences(Vec<ObjectName>),
Tables(Vec<ObjectName>),
Views(Vec<ObjectName>),
Warehouses(Vec<ObjectName>),
Integrations(Vec<ObjectName>),
ResourceMonitors(Vec<ObjectName>),
Users(Vec<ObjectName>),
ComputePools(Vec<ObjectName>),
Connections(Vec<ObjectName>),
FailoverGroup(Vec<ObjectName>),
ReplicationGroup(Vec<ObjectName>),
ExternalVolumes(Vec<ObjectName>),
Procedure {
name: ObjectName,
arg_types: Vec<DataType>,
},
Function {
name: ObjectName,
arg_types: Vec<DataType>,
},
}
impl fmt::Display for GrantObjects {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
GrantObjects::Sequences(sequences) => {
write!(f, "SEQUENCE {}", display_comma_separated(sequences))
}
GrantObjects::Databases(databases) => {
write!(f, "DATABASE {}", display_comma_separated(databases))
}
GrantObjects::Schemas(schemas) => {
write!(f, "SCHEMA {}", display_comma_separated(schemas))
}
GrantObjects::Tables(tables) => {
write!(f, "{}", display_comma_separated(tables))
}
GrantObjects::Views(views) => {
write!(f, "VIEW {}", display_comma_separated(views))
}
GrantObjects::Warehouses(warehouses) => {
write!(f, "WAREHOUSE {}", display_comma_separated(warehouses))
}
GrantObjects::Integrations(integrations) => {
write!(f, "INTEGRATION {}", display_comma_separated(integrations))
}
GrantObjects::AllSequencesInSchema { schemas } => {
write!(
f,
"ALL SEQUENCES IN SCHEMA {}",
display_comma_separated(schemas)
)
}
GrantObjects::AllTablesInSchema { schemas } => {
write!(
f,
"ALL TABLES IN SCHEMA {}",
display_comma_separated(schemas)
)
}
GrantObjects::AllExternalTablesInSchema { schemas } => {
write!(
f,
"ALL EXTERNAL TABLES IN SCHEMA {}",
display_comma_separated(schemas)
)
}
GrantObjects::AllViewsInSchema { schemas } => {
write!(
f,
"ALL VIEWS IN SCHEMA {}",
display_comma_separated(schemas)
)
}
GrantObjects::AllMaterializedViewsInSchema { schemas } => {
write!(
f,
"ALL MATERIALIZED VIEWS IN SCHEMA {}",
display_comma_separated(schemas)
)
}
GrantObjects::AllFunctionsInSchema { schemas } => {
write!(
f,
"ALL FUNCTIONS IN SCHEMA {}",
display_comma_separated(schemas)
)
}
GrantObjects::FutureSchemasInDatabase { databases } => {
write!(
f,
"FUTURE SCHEMAS IN DATABASE {}",
display_comma_separated(databases)
)
}
GrantObjects::FutureTablesInSchema { schemas } => {
write!(
f,
"FUTURE TABLES IN SCHEMA {}",
display_comma_separated(schemas)
)
}
GrantObjects::FutureExternalTablesInSchema { schemas } => {
write!(
f,
"FUTURE EXTERNAL TABLES IN SCHEMA {}",
display_comma_separated(schemas)
)
}
GrantObjects::FutureViewsInSchema { schemas } => {
write!(
f,
"FUTURE VIEWS IN SCHEMA {}",
display_comma_separated(schemas)
)
}
GrantObjects::FutureMaterializedViewsInSchema { schemas } => {
write!(
f,
"FUTURE MATERIALIZED VIEWS IN SCHEMA {}",
display_comma_separated(schemas)
)
}
GrantObjects::FutureSequencesInSchema { schemas } => {
write!(
f,
"FUTURE SEQUENCES IN SCHEMA {}",
display_comma_separated(schemas)
)
}
GrantObjects::ResourceMonitors(objects) => {
write!(f, "RESOURCE MONITOR {}", display_comma_separated(objects))
}
GrantObjects::Users(objects) => {
write!(f, "USER {}", display_comma_separated(objects))
}
GrantObjects::ComputePools(objects) => {
write!(f, "COMPUTE POOL {}", display_comma_separated(objects))
}
GrantObjects::Connections(objects) => {
write!(f, "CONNECTION {}", display_comma_separated(objects))
}
GrantObjects::FailoverGroup(objects) => {
write!(f, "FAILOVER GROUP {}", display_comma_separated(objects))
}
GrantObjects::ReplicationGroup(objects) => {
write!(f, "REPLICATION GROUP {}", display_comma_separated(objects))
}
GrantObjects::ExternalVolumes(objects) => {
write!(f, "EXTERNAL VOLUME {}", display_comma_separated(objects))
}
GrantObjects::Procedure { name, arg_types } => {
write!(f, "PROCEDURE {name}")?;
if !arg_types.is_empty() {
write!(f, "({})", display_comma_separated(arg_types))?;
}
Ok(())
}
GrantObjects::Function { name, arg_types } => {
write!(f, "FUNCTION {name}")?;
if !arg_types.is_empty() {
write!(f, "({})", display_comma_separated(arg_types))?;
}
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 DenyStatement {
pub privileges: Privileges,
pub objects: GrantObjects,
pub grantees: Vec<Grantee>,
pub granted_by: Option<Ident>,
pub cascade: Option<CascadeOption>,
}
impl fmt::Display for DenyStatement {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "DENY {}", self.privileges)?;
write!(f, " ON {}", self.objects)?;
if !self.grantees.is_empty() {
write!(f, " TO {}", display_comma_separated(&self.grantees))?;
}
if let Some(cascade) = &self.cascade {
write!(f, " {cascade}")?;
}
if let Some(granted_by) = &self.granted_by {
write!(f, " AS {granted_by}")?;
}
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 Assignment {
pub target: AssignmentTarget,
pub value: Expr,
}
impl fmt::Display for Assignment {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{} = {}", self.target, self.value)
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum AssignmentTarget {
ColumnName(ObjectName),
Tuple(Vec<ObjectName>),
}
impl fmt::Display for AssignmentTarget {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
AssignmentTarget::ColumnName(column) => write!(f, "{column}"),
AssignmentTarget::Tuple(columns) => write!(f, "({})", display_comma_separated(columns)),
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum FunctionArgExpr {
Expr(Expr),
QualifiedWildcard(ObjectName),
Wildcard,
}
impl From<Expr> for FunctionArgExpr {
fn from(wildcard_expr: Expr) -> Self {
match wildcard_expr {
Expr::QualifiedWildcard(prefix, _) => Self::QualifiedWildcard(prefix),
Expr::Wildcard(_) => Self::Wildcard,
expr => Self::Expr(expr),
}
}
}
impl fmt::Display for FunctionArgExpr {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
FunctionArgExpr::Expr(expr) => write!(f, "{expr}"),
FunctionArgExpr::QualifiedWildcard(prefix) => write!(f, "{prefix}.*"),
FunctionArgExpr::Wildcard => f.write_str("*"),
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum FunctionArgOperator {
Equals,
RightArrow,
Assignment,
Colon,
Value,
}
impl fmt::Display for FunctionArgOperator {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
FunctionArgOperator::Equals => f.write_str("="),
FunctionArgOperator::RightArrow => f.write_str("=>"),
FunctionArgOperator::Assignment => f.write_str(":="),
FunctionArgOperator::Colon => f.write_str(":"),
FunctionArgOperator::Value => f.write_str("VALUE"),
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum FunctionArg {
Named {
name: Ident,
arg: FunctionArgExpr,
operator: FunctionArgOperator,
},
ExprNamed {
name: Expr,
arg: FunctionArgExpr,
operator: FunctionArgOperator,
},
Unnamed(FunctionArgExpr),
}
impl fmt::Display for FunctionArg {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
FunctionArg::Named {
name,
arg,
operator,
} => write!(f, "{name} {operator} {arg}"),
FunctionArg::ExprNamed {
name,
arg,
operator,
} => write!(f, "{name} {operator} {arg}"),
FunctionArg::Unnamed(unnamed_arg) => write!(f, "{unnamed_arg}"),
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum CloseCursor {
All,
Specific {
name: Ident,
},
}
impl fmt::Display for CloseCursor {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
CloseCursor::All => write!(f, "ALL"),
CloseCursor::Specific { 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 struct DropDomain {
pub if_exists: bool,
pub name: ObjectName,
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 TypedString {
pub data_type: DataType,
pub value: ValueWithSpan,
pub uses_odbc_syntax: bool,
}
impl fmt::Display for TypedString {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let data_type = &self.data_type;
let value = &self.value;
match self.uses_odbc_syntax {
false => {
write!(f, "{data_type}")?;
write!(f, " {value}")
}
true => {
let prefix = match data_type {
DataType::Date => "d",
DataType::Time(..) => "t",
DataType::Timestamp(..) => "ts",
_ => "?",
};
write!(f, "{{{prefix} {value}}}")
}
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct Function {
pub name: ObjectName,
pub uses_odbc_syntax: bool,
pub parameters: FunctionArguments,
pub args: FunctionArguments,
pub filter: Option<Box<Expr>>,
pub null_treatment: Option<NullTreatment>,
pub over: Option<WindowType>,
pub within_group: Vec<OrderByExpr>,
}
impl fmt::Display for Function {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if self.uses_odbc_syntax {
write!(f, "{{fn ")?;
}
write!(f, "{}{}{}", self.name, self.parameters, self.args)?;
if !self.within_group.is_empty() {
write!(
f,
" WITHIN GROUP (ORDER BY {})",
display_comma_separated(&self.within_group)
)?;
}
if let Some(filter_cond) = &self.filter {
write!(f, " FILTER (WHERE {filter_cond})")?;
}
if let Some(null_treatment) = &self.null_treatment {
write!(f, " {null_treatment}")?;
}
if let Some(o) = &self.over {
f.write_str(" OVER ")?;
o.fmt(f)?;
}
if self.uses_odbc_syntax {
write!(f, "}}")?;
}
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 FunctionArguments {
None,
Subquery(Box<Query>),
List(FunctionArgumentList),
}
impl fmt::Display for FunctionArguments {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
FunctionArguments::None => Ok(()),
FunctionArguments::Subquery(query) => write!(f, "({query})"),
FunctionArguments::List(args) => write!(f, "({args})"),
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct FunctionArgumentList {
pub duplicate_treatment: Option<DuplicateTreatment>,
pub args: Vec<FunctionArg>,
pub clauses: Vec<FunctionArgumentClause>,
}
impl fmt::Display for FunctionArgumentList {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if let Some(duplicate_treatment) = self.duplicate_treatment {
write!(f, "{duplicate_treatment} ")?;
}
write!(f, "{}", display_comma_separated(&self.args))?;
if !self.clauses.is_empty() {
if !self.args.is_empty() {
write!(f, " ")?;
}
write!(f, "{}", display_separated(&self.clauses, " "))?;
}
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 FunctionArgumentClause {
IgnoreOrRespectNulls(NullTreatment),
OrderBy(Vec<OrderByExpr>),
Limit(Expr),
OnOverflow(ListAggOnOverflow),
Having(HavingBound),
Separator(Value),
JsonNullClause(JsonNullClause),
JsonReturningClause(JsonReturningClause),
}
impl fmt::Display for FunctionArgumentClause {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
FunctionArgumentClause::IgnoreOrRespectNulls(null_treatment) => {
write!(f, "{null_treatment}")
}
FunctionArgumentClause::OrderBy(order_by) => {
write!(f, "ORDER BY {}", display_comma_separated(order_by))
}
FunctionArgumentClause::Limit(limit) => write!(f, "LIMIT {limit}"),
FunctionArgumentClause::OnOverflow(on_overflow) => write!(f, "{on_overflow}"),
FunctionArgumentClause::Having(bound) => write!(f, "{bound}"),
FunctionArgumentClause::Separator(sep) => write!(f, "SEPARATOR {sep}"),
FunctionArgumentClause::JsonNullClause(null_clause) => write!(f, "{null_clause}"),
FunctionArgumentClause::JsonReturningClause(returning_clause) => {
write!(f, "{returning_clause}")
}
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct Method {
pub expr: Box<Expr>,
pub method_chain: Vec<Function>,
}
impl fmt::Display for Method {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"{}.{}",
self.expr,
display_separated(&self.method_chain, ".")
)
}
}
#[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 DuplicateTreatment {
Distinct,
All,
}
impl fmt::Display for DuplicateTreatment {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
DuplicateTreatment::Distinct => write!(f, "DISTINCT"),
DuplicateTreatment::All => write!(f, "ALL"),
}
}
}
#[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 AnalyzeFormatKind {
Keyword(AnalyzeFormat),
Assignment(AnalyzeFormat),
}
impl fmt::Display for AnalyzeFormatKind {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
AnalyzeFormatKind::Keyword(format) => write!(f, "FORMAT {format}"),
AnalyzeFormatKind::Assignment(format) => write!(f, "FORMAT={format}"),
}
}
}
#[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 AnalyzeFormat {
TEXT,
GRAPHVIZ,
JSON,
TRADITIONAL,
TREE,
}
impl fmt::Display for AnalyzeFormat {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_str(match self {
AnalyzeFormat::TEXT => "TEXT",
AnalyzeFormat::GRAPHVIZ => "GRAPHVIZ",
AnalyzeFormat::JSON => "JSON",
AnalyzeFormat::TRADITIONAL => "TRADITIONAL",
AnalyzeFormat::TREE => "TREE",
})
}
}
#[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 FileFormat {
TEXTFILE,
SEQUENCEFILE,
ORC,
PARQUET,
AVRO,
RCFILE,
JSONFILE,
}
impl fmt::Display for FileFormat {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use self::FileFormat::*;
f.write_str(match self {
TEXTFILE => "TEXTFILE",
SEQUENCEFILE => "SEQUENCEFILE",
ORC => "ORC",
PARQUET => "PARQUET",
AVRO => "AVRO",
RCFILE => "RCFILE",
JSONFILE => "JSONFILE",
})
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum ListAggOnOverflow {
Error,
Truncate {
filler: Option<Box<Expr>>,
with_count: bool,
},
}
impl fmt::Display for ListAggOnOverflow {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "ON OVERFLOW")?;
match self {
ListAggOnOverflow::Error => write!(f, " ERROR"),
ListAggOnOverflow::Truncate { filler, with_count } => {
write!(f, " TRUNCATE")?;
if let Some(filler) = filler {
write!(f, " {filler}")?;
}
if *with_count {
write!(f, " WITH")?;
} else {
write!(f, " WITHOUT")?;
}
write!(f, " COUNT")
}
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct HavingBound(pub HavingBoundKind, pub Expr);
impl fmt::Display for HavingBound {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "HAVING {} {}", self.0, self.1)
}
}
#[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 HavingBoundKind {
Min,
Max,
}
impl fmt::Display for HavingBoundKind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
HavingBoundKind::Min => write!(f, "MIN"),
HavingBoundKind::Max => write!(f, "MAX"),
}
}
}
#[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 ObjectType {
Table,
View,
MaterializedView,
Index,
Schema,
Database,
Role,
Sequence,
Stage,
Type,
User,
Stream,
}
impl fmt::Display for ObjectType {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str(match self {
ObjectType::Table => "TABLE",
ObjectType::View => "VIEW",
ObjectType::MaterializedView => "MATERIALIZED VIEW",
ObjectType::Index => "INDEX",
ObjectType::Schema => "SCHEMA",
ObjectType::Database => "DATABASE",
ObjectType::Role => "ROLE",
ObjectType::Sequence => "SEQUENCE",
ObjectType::Stage => "STAGE",
ObjectType::Type => "TYPE",
ObjectType::User => "USER",
ObjectType::Stream => "STREAM",
})
}
}
#[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 KillType {
Connection,
Query,
Mutation,
}
impl fmt::Display for KillType {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str(match self {
KillType::Connection => "CONNECTION",
KillType::Query => "QUERY",
KillType::Mutation => "MUTATION",
})
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum HiveDistributionStyle {
PARTITIONED {
columns: Vec<ColumnDef>,
},
SKEWED {
columns: Vec<ColumnDef>,
on: Vec<ColumnDef>,
stored_as_directories: bool,
},
NONE,
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum HiveRowFormat {
SERDE {
class: String,
},
DELIMITED {
delimiters: Vec<HiveRowDelimiter>,
},
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct HiveLoadDataFormat {
pub serde: Expr,
pub input_format: 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 HiveRowDelimiter {
pub delimiter: HiveDelimiter,
pub char: Ident,
}
impl fmt::Display for HiveRowDelimiter {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{} ", self.delimiter)?;
write!(f, "{}", self.char)
}
}
#[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 HiveDelimiter {
FieldsTerminatedBy,
FieldsEscapedBy,
CollectionItemsTerminatedBy,
MapKeysTerminatedBy,
LinesTerminatedBy,
NullDefinedAs,
}
impl fmt::Display for HiveDelimiter {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
use HiveDelimiter::*;
f.write_str(match self {
FieldsTerminatedBy => "FIELDS TERMINATED BY",
FieldsEscapedBy => "ESCAPED BY",
CollectionItemsTerminatedBy => "COLLECTION ITEMS TERMINATED BY",
MapKeysTerminatedBy => "MAP KEYS TERMINATED BY",
LinesTerminatedBy => "LINES TERMINATED BY",
NullDefinedAs => "NULL DEFINED AS",
})
}
}
#[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 HiveDescribeFormat {
Extended,
Formatted,
}
impl fmt::Display for HiveDescribeFormat {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
use HiveDescribeFormat::*;
f.write_str(match self {
Extended => "EXTENDED",
Formatted => "FORMATTED",
})
}
}
#[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 DescribeAlias {
Describe,
Explain,
Desc,
}
impl fmt::Display for DescribeAlias {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
use DescribeAlias::*;
f.write_str(match self {
Describe => "DESCRIBE",
Explain => "EXPLAIN",
Desc => "DESC",
})
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
#[allow(clippy::large_enum_variant)]
pub enum HiveIOFormat {
IOF {
input_format: Expr,
output_format: Expr,
},
FileFormat {
format: FileFormat,
},
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Default)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct HiveFormat {
pub row_format: Option<HiveRowFormat>,
pub serde_properties: Option<Vec<SqlOption>>,
pub storage: Option<HiveIOFormat>,
pub location: Option<String>,
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct ClusteredIndex {
pub name: Ident,
pub asc: Option<bool>,
}
impl fmt::Display for ClusteredIndex {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.name)?;
match self.asc {
Some(true) => write!(f, " ASC"),
Some(false) => write!(f, " DESC"),
_ => 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 TableOptionsClustered {
ColumnstoreIndex,
ColumnstoreIndexOrder(Vec<Ident>),
Index(Vec<ClusteredIndex>),
}
impl fmt::Display for TableOptionsClustered {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
TableOptionsClustered::ColumnstoreIndex => {
write!(f, "CLUSTERED COLUMNSTORE INDEX")
}
TableOptionsClustered::ColumnstoreIndexOrder(values) => {
write!(
f,
"CLUSTERED COLUMNSTORE INDEX ORDER ({})",
display_comma_separated(values)
)
}
TableOptionsClustered::Index(values) => {
write!(f, "CLUSTERED INDEX ({})", display_comma_separated(values))
}
}
}
}
#[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 PartitionRangeDirection {
Left,
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 SqlOption {
Clustered(TableOptionsClustered),
Ident(Ident),
KeyValue {
key: Ident,
value: Expr,
},
Partition {
column_name: Ident,
range_direction: Option<PartitionRangeDirection>,
for_values: Vec<Expr>,
},
Comment(CommentDef),
TableSpace(TablespaceOption),
NamedParenthesizedList(NamedParenthesizedList),
}
impl fmt::Display for SqlOption {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
SqlOption::Clustered(c) => write!(f, "{c}"),
SqlOption::Ident(ident) => {
write!(f, "{ident}")
}
SqlOption::KeyValue { key: name, value } => {
write!(f, "{name} = {value}")
}
SqlOption::Partition {
column_name,
range_direction,
for_values,
} => {
let direction = match range_direction {
Some(PartitionRangeDirection::Left) => " LEFT",
Some(PartitionRangeDirection::Right) => " RIGHT",
None => "",
};
write!(
f,
"PARTITION ({} RANGE{} FOR VALUES ({}))",
column_name,
direction,
display_comma_separated(for_values)
)
}
SqlOption::TableSpace(tablespace_option) => {
write!(f, "TABLESPACE {}", tablespace_option.name)?;
match tablespace_option.storage {
Some(StorageType::Disk) => write!(f, " STORAGE DISK"),
Some(StorageType::Memory) => write!(f, " STORAGE MEMORY"),
None => Ok(()),
}
}
SqlOption::Comment(comment) => match comment {
CommentDef::WithEq(comment) => {
write!(f, "COMMENT = '{comment}'")
}
CommentDef::WithoutEq(comment) => {
write!(f, "COMMENT '{comment}'")
}
},
SqlOption::NamedParenthesizedList(value) => {
write!(f, "{} = ", value.key)?;
if let Some(key) = &value.name {
write!(f, "{key}")?;
}
if !value.values.is_empty() {
write!(f, "({})", display_comma_separated(&value.values))?
}
Ok(())
}
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum StorageType {
Disk,
Memory,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct TablespaceOption {
pub name: String,
pub storage: Option<StorageType>,
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct SecretOption {
pub key: Ident,
pub value: Ident,
}
impl fmt::Display for SecretOption {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{} {}", self.key, self.value)
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct CreateServerStatement {
pub name: ObjectName,
pub if_not_exists: bool,
pub server_type: Option<Ident>,
pub version: Option<Ident>,
pub foreign_data_wrapper: ObjectName,
pub options: Option<Vec<CreateServerOption>>,
}
impl fmt::Display for CreateServerStatement {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let CreateServerStatement {
name,
if_not_exists,
server_type,
version,
foreign_data_wrapper,
options,
} = self;
write!(
f,
"CREATE SERVER {if_not_exists}{name} ",
if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" },
)?;
if let Some(st) = server_type {
write!(f, "TYPE {st} ")?;
}
if let Some(v) = version {
write!(f, "VERSION {v} ")?;
}
write!(f, "FOREIGN DATA WRAPPER {foreign_data_wrapper}")?;
if let Some(o) = options {
write!(f, " OPTIONS ({o})", o = display_comma_separated(o))?;
}
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 CreateServerOption {
pub key: Ident,
pub value: Ident,
}
impl fmt::Display for CreateServerOption {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{} {}", self.key, self.value)
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum AttachDuckDBDatabaseOption {
ReadOnly(Option<bool>),
Type(Ident),
}
impl fmt::Display for AttachDuckDBDatabaseOption {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
AttachDuckDBDatabaseOption::ReadOnly(Some(true)) => write!(f, "READ_ONLY true"),
AttachDuckDBDatabaseOption::ReadOnly(Some(false)) => write!(f, "READ_ONLY false"),
AttachDuckDBDatabaseOption::ReadOnly(None) => write!(f, "READ_ONLY"),
AttachDuckDBDatabaseOption::Type(t) => write!(f, "TYPE {t}"),
}
}
}
#[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 TransactionMode {
AccessMode(TransactionAccessMode),
IsolationLevel(TransactionIsolationLevel),
}
impl fmt::Display for TransactionMode {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use TransactionMode::*;
match self {
AccessMode(access_mode) => write!(f, "{access_mode}"),
IsolationLevel(iso_level) => write!(f, "ISOLATION LEVEL {iso_level}"),
}
}
}
#[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 TransactionAccessMode {
ReadOnly,
ReadWrite,
}
impl fmt::Display for TransactionAccessMode {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use TransactionAccessMode::*;
f.write_str(match self {
ReadOnly => "READ ONLY",
ReadWrite => "READ WRITE",
})
}
}
#[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 TransactionIsolationLevel {
ReadUncommitted,
ReadCommitted,
RepeatableRead,
Serializable,
Snapshot,
}
impl fmt::Display for TransactionIsolationLevel {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use TransactionIsolationLevel::*;
f.write_str(match self {
ReadUncommitted => "READ UNCOMMITTED",
ReadCommitted => "READ COMMITTED",
RepeatableRead => "REPEATABLE READ",
Serializable => "SERIALIZABLE",
Snapshot => "SNAPSHOT",
})
}
}
#[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 TransactionModifier {
Deferred,
Immediate,
Exclusive,
Try,
Catch,
}
impl fmt::Display for TransactionModifier {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use TransactionModifier::*;
f.write_str(match self {
Deferred => "DEFERRED",
Immediate => "IMMEDIATE",
Exclusive => "EXCLUSIVE",
Try => "TRY",
Catch => "CATCH",
})
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum ShowStatementFilter {
Like(String),
ILike(String),
Where(Expr),
NoKeyword(String),
}
impl fmt::Display for ShowStatementFilter {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use ShowStatementFilter::*;
match self {
Like(pattern) => write!(f, "LIKE '{}'", value::escape_single_quote_string(pattern)),
ILike(pattern) => write!(f, "ILIKE {}", value::escape_single_quote_string(pattern)),
Where(expr) => write!(f, "WHERE {expr}"),
NoKeyword(pattern) => write!(f, "'{}'", value::escape_single_quote_string(pattern)),
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum ShowStatementInClause {
IN,
FROM,
}
impl fmt::Display for ShowStatementInClause {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use ShowStatementInClause::*;
match self {
FROM => write!(f, "FROM"),
IN => write!(f, "IN"),
}
}
}
#[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 SqliteOnConflict {
Rollback,
Abort,
Fail,
Ignore,
Replace,
}
impl fmt::Display for SqliteOnConflict {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use SqliteOnConflict::*;
match self {
Rollback => write!(f, "OR ROLLBACK"),
Abort => write!(f, "OR ABORT"),
Fail => write!(f, "OR FAIL"),
Ignore => write!(f, "OR IGNORE"),
Replace => write!(f, "OR REPLACE"),
}
}
}
#[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 MysqlInsertPriority {
LowPriority,
Delayed,
HighPriority,
}
impl fmt::Display for crate::ast::MysqlInsertPriority {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use MysqlInsertPriority::*;
match self {
LowPriority => write!(f, "LOW_PRIORITY"),
Delayed => write!(f, "DELAYED"),
HighPriority => write!(f, "HIGH_PRIORITY"),
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum CopySource {
Table {
table_name: ObjectName,
columns: Vec<Ident>,
},
Query(Box<Query>),
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum CopyTarget {
Stdin,
Stdout,
File {
filename: String,
},
Program {
command: String,
},
}
impl fmt::Display for CopyTarget {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use CopyTarget::*;
match self {
Stdin => write!(f, "STDIN"),
Stdout => write!(f, "STDOUT"),
File { filename } => write!(f, "'{}'", value::escape_single_quote_string(filename)),
Program { command } => write!(
f,
"PROGRAM '{}'",
value::escape_single_quote_string(command)
),
}
}
}
#[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 OnCommit {
DeleteRows,
PreserveRows,
Drop,
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum CopyOption {
Format(Ident),
Freeze(bool),
Delimiter(char),
Null(String),
Header(bool),
Quote(char),
Escape(char),
ForceQuote(Vec<Ident>),
ForceNotNull(Vec<Ident>),
ForceNull(Vec<Ident>),
Encoding(String),
}
impl fmt::Display for CopyOption {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use CopyOption::*;
match self {
Format(name) => write!(f, "FORMAT {name}"),
Freeze(true) => write!(f, "FREEZE"),
Freeze(false) => write!(f, "FREEZE FALSE"),
Delimiter(char) => write!(f, "DELIMITER '{char}'"),
Null(string) => write!(f, "NULL '{}'", value::escape_single_quote_string(string)),
Header(true) => write!(f, "HEADER"),
Header(false) => write!(f, "HEADER FALSE"),
Quote(char) => write!(f, "QUOTE '{char}'"),
Escape(char) => write!(f, "ESCAPE '{char}'"),
ForceQuote(columns) => write!(f, "FORCE_QUOTE ({})", display_comma_separated(columns)),
ForceNotNull(columns) => {
write!(f, "FORCE_NOT_NULL ({})", display_comma_separated(columns))
}
ForceNull(columns) => write!(f, "FORCE_NULL ({})", display_comma_separated(columns)),
Encoding(name) => write!(f, "ENCODING '{}'", value::escape_single_quote_string(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 CopyLegacyOption {
AcceptAnyDate,
AcceptInvChars(Option<String>),
AddQuotes,
AllowOverwrite,
Binary,
BlankAsNull,
Bzip2,
CleanPath,
CompUpdate {
preset: bool,
enabled: Option<bool>,
},
Csv(Vec<CopyLegacyCsvOption>),
DateFormat(Option<String>),
Delimiter(char),
EmptyAsNull,
Encrypted {
auto: bool,
},
Escape,
Extension(String),
FixedWidth(String),
Gzip,
Header,
IamRole(IamRoleKind),
IgnoreHeader(u64),
Json(Option<String>),
Manifest {
verbose: bool,
},
MaxFileSize(FileSize),
Null(String),
Parallel(Option<bool>),
Parquet,
PartitionBy(UnloadPartitionBy),
Region(String),
RemoveQuotes,
RowGroupSize(FileSize),
StatUpdate(Option<bool>),
TimeFormat(Option<String>),
TruncateColumns,
Zstd,
}
impl fmt::Display for CopyLegacyOption {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use CopyLegacyOption::*;
match self {
AcceptAnyDate => write!(f, "ACCEPTANYDATE"),
AcceptInvChars(ch) => {
write!(f, "ACCEPTINVCHARS")?;
if let Some(ch) = ch {
write!(f, " '{}'", value::escape_single_quote_string(ch))?;
}
Ok(())
}
AddQuotes => write!(f, "ADDQUOTES"),
AllowOverwrite => write!(f, "ALLOWOVERWRITE"),
Binary => write!(f, "BINARY"),
BlankAsNull => write!(f, "BLANKSASNULL"),
Bzip2 => write!(f, "BZIP2"),
CleanPath => write!(f, "CLEANPATH"),
CompUpdate { preset, enabled } => {
write!(f, "COMPUPDATE")?;
if *preset {
write!(f, " PRESET")?;
} else if let Some(enabled) = enabled {
write!(
f,
"{}",
match enabled {
true => " TRUE",
false => " FALSE",
}
)?;
}
Ok(())
}
Csv(opts) => {
write!(f, "CSV")?;
if !opts.is_empty() {
write!(f, " {}", display_separated(opts, " "))?;
}
Ok(())
}
DateFormat(fmt) => {
write!(f, "DATEFORMAT")?;
if let Some(fmt) = fmt {
write!(f, " '{}'", value::escape_single_quote_string(fmt))?;
}
Ok(())
}
Delimiter(char) => write!(f, "DELIMITER '{char}'"),
EmptyAsNull => write!(f, "EMPTYASNULL"),
Encrypted { auto } => write!(f, "ENCRYPTED{}", if *auto { " AUTO" } else { "" }),
Escape => write!(f, "ESCAPE"),
Extension(ext) => write!(f, "EXTENSION '{}'", value::escape_single_quote_string(ext)),
FixedWidth(spec) => write!(
f,
"FIXEDWIDTH '{}'",
value::escape_single_quote_string(spec)
),
Gzip => write!(f, "GZIP"),
Header => write!(f, "HEADER"),
IamRole(role) => write!(f, "IAM_ROLE {role}"),
IgnoreHeader(num_rows) => write!(f, "IGNOREHEADER {num_rows}"),
Json(opt) => {
write!(f, "JSON")?;
if let Some(opt) = opt {
write!(f, " AS '{}'", value::escape_single_quote_string(opt))?;
}
Ok(())
}
Manifest { verbose } => write!(f, "MANIFEST{}", if *verbose { " VERBOSE" } else { "" }),
MaxFileSize(file_size) => write!(f, "MAXFILESIZE {file_size}"),
Null(string) => write!(f, "NULL '{}'", value::escape_single_quote_string(string)),
Parallel(enabled) => {
write!(
f,
"PARALLEL{}",
match enabled {
Some(true) => " TRUE",
Some(false) => " FALSE",
_ => "",
}
)
}
Parquet => write!(f, "PARQUET"),
PartitionBy(p) => write!(f, "{p}"),
Region(region) => write!(f, "REGION '{}'", value::escape_single_quote_string(region)),
RemoveQuotes => write!(f, "REMOVEQUOTES"),
RowGroupSize(file_size) => write!(f, "ROWGROUPSIZE {file_size}"),
StatUpdate(enabled) => {
write!(
f,
"STATUPDATE{}",
match enabled {
Some(true) => " TRUE",
Some(false) => " FALSE",
_ => "",
}
)
}
TimeFormat(fmt) => {
write!(f, "TIMEFORMAT")?;
if let Some(fmt) = fmt {
write!(f, " '{}'", value::escape_single_quote_string(fmt))?;
}
Ok(())
}
TruncateColumns => write!(f, "TRUNCATECOLUMNS"),
Zstd => write!(f, "ZSTD"),
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct FileSize {
pub size: Value,
pub unit: Option<FileSizeUnit>,
}
impl fmt::Display for FileSize {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.size)?;
if let Some(unit) = &self.unit {
write!(f, " {unit}")?;
}
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 FileSizeUnit {
MB,
GB,
}
impl fmt::Display for FileSizeUnit {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
FileSizeUnit::MB => write!(f, "MB"),
FileSizeUnit::GB => write!(f, "GB"),
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct UnloadPartitionBy {
pub columns: Vec<Ident>,
pub include: bool,
}
impl fmt::Display for UnloadPartitionBy {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"PARTITION BY ({}){}",
display_comma_separated(&self.columns),
if self.include { " INCLUDE" } else { "" }
)
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum IamRoleKind {
Default,
Arn(String),
}
impl fmt::Display for IamRoleKind {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
IamRoleKind::Default => write!(f, "DEFAULT"),
IamRoleKind::Arn(arn) => write!(f, "'{arn}'"),
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum CopyLegacyCsvOption {
Header,
Quote(char),
Escape(char),
ForceQuote(Vec<Ident>),
ForceNotNull(Vec<Ident>),
}
impl fmt::Display for CopyLegacyCsvOption {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use CopyLegacyCsvOption::*;
match self {
Header => write!(f, "HEADER"),
Quote(char) => write!(f, "QUOTE '{char}'"),
Escape(char) => write!(f, "ESCAPE '{char}'"),
ForceQuote(columns) => write!(f, "FORCE QUOTE {}", display_comma_separated(columns)),
ForceNotNull(columns) => {
write!(f, "FORCE NOT NULL {}", display_comma_separated(columns))
}
}
}
}
#[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 DiscardObject {
ALL,
PLANS,
SEQUENCES,
TEMP,
}
impl fmt::Display for DiscardObject {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
DiscardObject::ALL => f.write_str("ALL"),
DiscardObject::PLANS => f.write_str("PLANS"),
DiscardObject::SEQUENCES => f.write_str("SEQUENCES"),
DiscardObject::TEMP => f.write_str("TEMP"),
}
}
}
#[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 FlushType {
BinaryLogs,
EngineLogs,
ErrorLogs,
GeneralLogs,
Hosts,
Logs,
Privileges,
OptimizerCosts,
RelayLogs,
SlowLogs,
Status,
UserResources,
Tables,
}
impl fmt::Display for FlushType {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
FlushType::BinaryLogs => f.write_str("BINARY LOGS"),
FlushType::EngineLogs => f.write_str("ENGINE LOGS"),
FlushType::ErrorLogs => f.write_str("ERROR LOGS"),
FlushType::GeneralLogs => f.write_str("GENERAL LOGS"),
FlushType::Hosts => f.write_str("HOSTS"),
FlushType::Logs => f.write_str("LOGS"),
FlushType::Privileges => f.write_str("PRIVILEGES"),
FlushType::OptimizerCosts => f.write_str("OPTIMIZER_COSTS"),
FlushType::RelayLogs => f.write_str("RELAY LOGS"),
FlushType::SlowLogs => f.write_str("SLOW LOGS"),
FlushType::Status => f.write_str("STATUS"),
FlushType::UserResources => f.write_str("USER_RESOURCES"),
FlushType::Tables => f.write_str("TABLES"),
}
}
}
#[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 FlushLocation {
NoWriteToBinlog,
Local,
}
impl fmt::Display for FlushLocation {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
FlushLocation::NoWriteToBinlog => f.write_str("NO_WRITE_TO_BINLOG"),
FlushLocation::Local => f.write_str("LOCAL"),
}
}
}
#[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 ContextModifier {
Local,
Session,
Global,
}
impl fmt::Display for ContextModifier {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::Local => {
write!(f, "LOCAL ")
}
Self::Session => {
write!(f, "SESSION ")
}
Self::Global => {
write!(f, "GLOBAL ")
}
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum DropFunctionOption {
Restrict,
Cascade,
}
impl fmt::Display for DropFunctionOption {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
DropFunctionOption::Restrict => write!(f, "RESTRICT "),
DropFunctionOption::Cascade => write!(f, "CASCADE "),
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct FunctionDesc {
pub name: ObjectName,
pub args: Option<Vec<OperateFunctionArg>>,
}
impl fmt::Display for FunctionDesc {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.name)?;
if let Some(args) = &self.args {
write!(f, "({})", display_comma_separated(args))?;
}
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 OperateFunctionArg {
pub mode: Option<ArgMode>,
pub name: Option<Ident>,
pub data_type: DataType,
pub default_expr: Option<Expr>,
}
impl OperateFunctionArg {
pub fn unnamed(data_type: DataType) -> Self {
Self {
mode: None,
name: None,
data_type,
default_expr: None,
}
}
pub fn with_name(name: &str, data_type: DataType) -> Self {
Self {
mode: None,
name: Some(name.into()),
data_type,
default_expr: None,
}
}
}
impl fmt::Display for OperateFunctionArg {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if let Some(mode) = &self.mode {
write!(f, "{mode} ")?;
}
if let Some(name) = &self.name {
write!(f, "{name} ")?;
}
write!(f, "{}", self.data_type)?;
if let Some(default_expr) = &self.default_expr {
write!(f, " = {default_expr}")?;
}
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 ArgMode {
In,
Out,
InOut,
}
impl fmt::Display for ArgMode {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
ArgMode::In => write!(f, "IN"),
ArgMode::Out => write!(f, "OUT"),
ArgMode::InOut => write!(f, "INOUT"),
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum FunctionBehavior {
Immutable,
Stable,
Volatile,
}
impl fmt::Display for FunctionBehavior {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
FunctionBehavior::Immutable => write!(f, "IMMUTABLE"),
FunctionBehavior::Stable => write!(f, "STABLE"),
FunctionBehavior::Volatile => write!(f, "VOLATILE"),
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum FunctionSecurity {
Definer,
Invoker,
}
impl fmt::Display for FunctionSecurity {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
FunctionSecurity::Definer => write!(f, "SECURITY DEFINER"),
FunctionSecurity::Invoker => write!(f, "SECURITY INVOKER"),
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum FunctionSetValue {
Values(Vec<Expr>),
FromCurrent,
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct FunctionDefinitionSetParam {
pub name: Ident,
pub value: FunctionSetValue,
}
impl fmt::Display for FunctionDefinitionSetParam {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "SET {} ", self.name)?;
match &self.value {
FunctionSetValue::Values(values) => {
write!(f, "= {}", display_comma_separated(values))
}
FunctionSetValue::FromCurrent => write!(f, "FROM CURRENT"),
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum FunctionCalledOnNull {
CalledOnNullInput,
ReturnsNullOnNullInput,
Strict,
}
impl fmt::Display for FunctionCalledOnNull {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
FunctionCalledOnNull::CalledOnNullInput => write!(f, "CALLED ON NULL INPUT"),
FunctionCalledOnNull::ReturnsNullOnNullInput => write!(f, "RETURNS NULL ON NULL INPUT"),
FunctionCalledOnNull::Strict => write!(f, "STRICT"),
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum FunctionParallel {
Unsafe,
Restricted,
Safe,
}
impl fmt::Display for FunctionParallel {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
FunctionParallel::Unsafe => write!(f, "PARALLEL UNSAFE"),
FunctionParallel::Restricted => write!(f, "PARALLEL RESTRICTED"),
FunctionParallel::Safe => write!(f, "PARALLEL SAFE"),
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum FunctionDeterminismSpecifier {
Deterministic,
NotDeterministic,
}
impl fmt::Display for FunctionDeterminismSpecifier {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
FunctionDeterminismSpecifier::Deterministic => {
write!(f, "DETERMINISTIC")
}
FunctionDeterminismSpecifier::NotDeterministic => {
write!(f, "NOT DETERMINISTIC")
}
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum CreateFunctionBody {
AsBeforeOptions {
body: Expr,
link_symbol: Option<Expr>,
},
AsAfterOptions(Expr),
AsBeginEnd(BeginEndStatements),
Return(Expr),
AsReturnExpr(Expr),
AsReturnSelect(Select),
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum CreateFunctionUsing {
Jar(String),
File(String),
Archive(String),
}
impl fmt::Display for CreateFunctionUsing {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "USING ")?;
match self {
CreateFunctionUsing::Jar(uri) => write!(f, "JAR '{uri}'"),
CreateFunctionUsing::File(uri) => write!(f, "FILE '{uri}'"),
CreateFunctionUsing::Archive(uri) => write!(f, "ARCHIVE '{uri}'"),
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct MacroArg {
pub name: Ident,
pub default_expr: Option<Expr>,
}
impl MacroArg {
pub fn new(name: &str) -> Self {
Self {
name: name.into(),
default_expr: None,
}
}
}
impl fmt::Display for MacroArg {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.name)?;
if let Some(default_expr) = &self.default_expr {
write!(f, " := {default_expr}")?;
}
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 MacroDefinition {
Expr(Expr),
Table(Box<Query>),
}
impl fmt::Display for MacroDefinition {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
MacroDefinition::Expr(expr) => write!(f, "{expr}")?,
MacroDefinition::Table(query) => write!(f, "{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 SchemaName {
Simple(ObjectName),
UnnamedAuthorization(Ident),
NamedAuthorization(ObjectName, Ident),
}
impl fmt::Display for SchemaName {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
SchemaName::Simple(name) => {
write!(f, "{name}")
}
SchemaName::UnnamedAuthorization(authorization) => {
write!(f, "AUTHORIZATION {authorization}")
}
SchemaName::NamedAuthorization(name, authorization) => {
write!(f, "{name} AUTHORIZATION {authorization}")
}
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum SearchModifier {
InNaturalLanguageMode,
InNaturalLanguageModeWithQueryExpansion,
InBooleanMode,
WithQueryExpansion,
}
impl fmt::Display for SearchModifier {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::InNaturalLanguageMode => {
write!(f, "IN NATURAL LANGUAGE MODE")?;
}
Self::InNaturalLanguageModeWithQueryExpansion => {
write!(f, "IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION")?;
}
Self::InBooleanMode => {
write!(f, "IN BOOLEAN MODE")?;
}
Self::WithQueryExpansion => {
write!(f, "WITH QUERY EXPANSION")?;
}
}
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 LockTable {
pub table: Ident,
pub alias: Option<Ident>,
pub lock_type: LockTableType,
}
impl fmt::Display for LockTable {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let Self {
table: tbl_name,
alias,
lock_type,
} = self;
write!(f, "{tbl_name} ")?;
if let Some(alias) = alias {
write!(f, "AS {alias} ")?;
}
write!(f, "{lock_type}")?;
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 LockTableType {
Read {
local: bool,
},
Write {
low_priority: bool,
},
}
impl fmt::Display for LockTableType {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Read { local } => {
write!(f, "READ")?;
if *local {
write!(f, " LOCAL")?;
}
}
Self::Write { low_priority } => {
if *low_priority {
write!(f, "LOW_PRIORITY ")?;
}
write!(f, "WRITE")?;
}
}
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 HiveSetLocation {
pub has_set: bool,
pub location: Ident,
}
impl fmt::Display for HiveSetLocation {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if self.has_set {
write!(f, "SET ")?;
}
write!(f, "LOCATION {}", self.location)
}
}
#[allow(clippy::large_enum_variant)]
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum MySQLColumnPosition {
First,
After(Ident),
}
impl Display for MySQLColumnPosition {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
MySQLColumnPosition::First => write!(f, "FIRST"),
MySQLColumnPosition::After(ident) => {
let column_name = &ident.value;
write!(f, "AFTER {column_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 CreateViewAlgorithm {
Undefined,
Merge,
TempTable,
}
impl Display for CreateViewAlgorithm {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
CreateViewAlgorithm::Undefined => write!(f, "UNDEFINED"),
CreateViewAlgorithm::Merge => write!(f, "MERGE"),
CreateViewAlgorithm::TempTable => write!(f, "TEMPTABLE"),
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum CreateViewSecurity {
Definer,
Invoker,
}
impl Display for CreateViewSecurity {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
CreateViewSecurity::Definer => write!(f, "DEFINER"),
CreateViewSecurity::Invoker => write!(f, "INVOKER"),
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct CreateViewParams {
pub algorithm: Option<CreateViewAlgorithm>,
pub definer: Option<GranteeName>,
pub security: Option<CreateViewSecurity>,
}
impl Display for CreateViewParams {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let CreateViewParams {
algorithm,
definer,
security,
} = self;
if let Some(algorithm) = algorithm {
write!(f, "ALGORITHM = {algorithm} ")?;
}
if let Some(definers) = definer {
write!(f, "DEFINER = {definers} ")?;
}
if let Some(security) = security {
write!(f, "SQL SECURITY {security} ")?;
}
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 NamedParenthesizedList {
pub key: Ident,
pub name: Option<Ident>,
pub values: 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 RowAccessPolicy {
pub policy: ObjectName,
pub on: Vec<Ident>,
}
impl RowAccessPolicy {
pub fn new(policy: ObjectName, on: Vec<Ident>) -> Self {
Self { policy, on }
}
}
impl Display for RowAccessPolicy {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"WITH ROW ACCESS POLICY {} ON ({})",
self.policy,
display_comma_separated(self.on.as_slice())
)
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct Tag {
pub key: ObjectName,
pub value: String,
}
impl Tag {
pub fn new(key: ObjectName, value: String) -> Self {
Self { key, value }
}
}
impl Display for Tag {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}='{}'", self.key, self.value)
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct ContactEntry {
pub purpose: String,
pub contact: String,
}
impl Display for ContactEntry {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{} = {}", self.purpose, self.contact)
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum CommentDef {
WithEq(String),
WithoutEq(String),
}
impl Display for CommentDef {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
CommentDef::WithEq(comment) | CommentDef::WithoutEq(comment) => write!(f, "{comment}"),
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum WrappedCollection<T> {
NoWrapping(T),
Parentheses(T),
}
impl<T> Display for WrappedCollection<Vec<T>>
where
T: Display,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
WrappedCollection::NoWrapping(inner) => {
write!(f, "{}", display_comma_separated(inner.as_slice()))
}
WrappedCollection::Parentheses(inner) => {
write!(f, "({})", display_comma_separated(inner.as_slice()))
}
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct UtilityOption {
pub name: Ident,
pub arg: Option<Expr>,
}
impl Display for UtilityOption {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if let Some(ref arg) = self.arg {
write!(f, "{} {}", self.name, arg)
} else {
write!(f, "{}", self.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 ShowStatementOptions {
pub show_in: Option<ShowStatementIn>,
pub starts_with: Option<Value>,
pub limit: Option<Expr>,
pub limit_from: Option<Value>,
pub filter_position: Option<ShowStatementFilterPosition>,
}
impl Display for ShowStatementOptions {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let (like_in_infix, like_in_suffix) = match &self.filter_position {
Some(ShowStatementFilterPosition::Infix(filter)) => {
(format!(" {filter}"), "".to_string())
}
Some(ShowStatementFilterPosition::Suffix(filter)) => {
("".to_string(), format!(" {filter}"))
}
None => ("".to_string(), "".to_string()),
};
write!(
f,
"{like_in_infix}{show_in}{starts_with}{limit}{from}{like_in_suffix}",
show_in = match &self.show_in {
Some(i) => format!(" {i}"),
None => String::new(),
},
starts_with = match &self.starts_with {
Some(s) => format!(" STARTS WITH {s}"),
None => String::new(),
},
limit = match &self.limit {
Some(l) => format!(" LIMIT {l}"),
None => String::new(),
},
from = match &self.limit_from {
Some(f) => format!(" FROM {f}"),
None => String::new(),
}
)?;
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 ShowStatementFilterPosition {
Infix(ShowStatementFilter), Suffix(ShowStatementFilter), }
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum ShowStatementInParentType {
Account,
Database,
Schema,
Table,
View,
}
impl fmt::Display for ShowStatementInParentType {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
ShowStatementInParentType::Account => write!(f, "ACCOUNT"),
ShowStatementInParentType::Database => write!(f, "DATABASE"),
ShowStatementInParentType::Schema => write!(f, "SCHEMA"),
ShowStatementInParentType::Table => write!(f, "TABLE"),
ShowStatementInParentType::View => write!(f, "VIEW"),
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct ShowStatementIn {
pub clause: ShowStatementInClause,
pub parent_type: Option<ShowStatementInParentType>,
#[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
pub parent_name: Option<ObjectName>,
}
impl fmt::Display for ShowStatementIn {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.clause)?;
if let Some(parent_type) = &self.parent_type {
write!(f, " {parent_type}")?;
}
if let Some(parent_name) = &self.parent_name {
write!(f, " {parent_name}")?;
}
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 ShowCharset {
pub is_shorthand: bool,
pub filter: Option<ShowStatementFilter>,
}
impl fmt::Display for ShowCharset {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "SHOW")?;
if self.is_shorthand {
write!(f, " CHARSET")?;
} else {
write!(f, " CHARACTER SET")?;
}
if let Some(filter) = &self.filter {
write!(f, " {filter}")?;
}
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 ShowObjects {
pub terse: bool,
pub show_options: ShowStatementOptions,
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum JsonNullClause {
NullOnNull,
AbsentOnNull,
}
impl Display for JsonNullClause {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
JsonNullClause::NullOnNull => write!(f, "NULL ON NULL"),
JsonNullClause::AbsentOnNull => write!(f, "ABSENT ON NULL"),
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct JsonReturningClause {
pub data_type: DataType,
}
impl Display for JsonReturningClause {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "RETURNING {}", 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 RenameTable {
pub old_name: ObjectName,
pub new_name: ObjectName,
}
impl fmt::Display for RenameTable {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{} TO {}", self.old_name, self.new_name)?;
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 TableObject {
TableName(#[cfg_attr(feature = "visitor", visit(with = "visit_relation"))] ObjectName),
TableFunction(Function),
}
impl fmt::Display for TableObject {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::TableName(table_name) => write!(f, "{table_name}"),
Self::TableFunction(func) => write!(f, "FUNCTION {func}"),
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct SetSessionAuthorizationParam {
pub scope: ContextModifier,
pub kind: SetSessionAuthorizationParamKind,
}
impl fmt::Display for SetSessionAuthorizationParam {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.kind)
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum SetSessionAuthorizationParamKind {
Default,
User(Ident),
}
impl fmt::Display for SetSessionAuthorizationParamKind {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
SetSessionAuthorizationParamKind::Default => write!(f, "DEFAULT"),
SetSessionAuthorizationParamKind::User(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 SetSessionParamKind {
Generic(SetSessionParamGeneric),
IdentityInsert(SetSessionParamIdentityInsert),
Offsets(SetSessionParamOffsets),
Statistics(SetSessionParamStatistics),
}
impl fmt::Display for SetSessionParamKind {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
SetSessionParamKind::Generic(x) => write!(f, "{x}"),
SetSessionParamKind::IdentityInsert(x) => write!(f, "{x}"),
SetSessionParamKind::Offsets(x) => write!(f, "{x}"),
SetSessionParamKind::Statistics(x) => write!(f, "{x}"),
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct SetSessionParamGeneric {
pub names: Vec<String>,
pub value: String,
}
impl fmt::Display for SetSessionParamGeneric {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{} {}", display_comma_separated(&self.names), self.value)
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct SetSessionParamIdentityInsert {
pub obj: ObjectName,
pub value: SessionParamValue,
}
impl fmt::Display for SetSessionParamIdentityInsert {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "IDENTITY_INSERT {} {}", self.obj, self.value)
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct SetSessionParamOffsets {
pub keywords: Vec<String>,
pub value: SessionParamValue,
}
impl fmt::Display for SetSessionParamOffsets {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"OFFSETS {} {}",
display_comma_separated(&self.keywords),
self.value
)
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct SetSessionParamStatistics {
pub topic: SessionParamStatsTopic,
pub value: SessionParamValue,
}
impl fmt::Display for SetSessionParamStatistics {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "STATISTICS {} {}", self.topic, self.value)
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum SessionParamStatsTopic {
IO,
Profile,
Time,
Xml,
}
impl fmt::Display for SessionParamStatsTopic {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
SessionParamStatsTopic::IO => write!(f, "IO"),
SessionParamStatsTopic::Profile => write!(f, "PROFILE"),
SessionParamStatsTopic::Time => write!(f, "TIME"),
SessionParamStatsTopic::Xml => write!(f, "XML"),
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum SessionParamValue {
On,
Off,
}
impl fmt::Display for SessionParamValue {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
SessionParamValue::On => write!(f, "ON"),
SessionParamValue::Off => write!(f, "OFF"),
}
}
}
#[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 StorageSerializationPolicy {
Compatible,
Optimized,
}
impl Display for StorageSerializationPolicy {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
StorageSerializationPolicy::Compatible => write!(f, "COMPATIBLE"),
StorageSerializationPolicy::Optimized => write!(f, "OPTIMIZED"),
}
}
}
#[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 CatalogSyncNamespaceMode {
Nest,
Flatten,
}
impl Display for CatalogSyncNamespaceMode {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
CatalogSyncNamespaceMode::Nest => write!(f, "NEST"),
CatalogSyncNamespaceMode::Flatten => write!(f, "FLATTEN"),
}
}
}
#[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 CopyIntoSnowflakeKind {
Table,
Location,
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct PrintStatement {
pub message: Box<Expr>,
}
impl fmt::Display for PrintStatement {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "PRINT {}", self.message)
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct ReturnStatement {
pub value: Option<ReturnStatementValue>,
}
impl fmt::Display for ReturnStatement {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match &self.value {
Some(ReturnStatementValue::Expr(expr)) => write!(f, "RETURN {expr}"),
None => write!(f, "RETURN"),
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum ReturnStatementValue {
Expr(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 OpenStatement {
pub cursor_name: Ident,
}
impl fmt::Display for OpenStatement {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "OPEN {}", self.cursor_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 NullInclusion {
IncludeNulls,
ExcludeNulls,
}
impl fmt::Display for NullInclusion {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
NullInclusion::IncludeNulls => write!(f, "INCLUDE NULLS"),
NullInclusion::ExcludeNulls => write!(f, "EXCLUDE NULLS"),
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct MemberOf {
pub value: Box<Expr>,
pub array: Box<Expr>,
}
impl fmt::Display for MemberOf {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{} MEMBER OF({})", self.value, self.array)
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct ExportData {
pub options: Vec<SqlOption>,
pub query: Box<Query>,
pub connection: Option<ObjectName>,
}
impl fmt::Display for ExportData {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if let Some(connection) = &self.connection {
write!(
f,
"EXPORT DATA WITH CONNECTION {connection} OPTIONS({}) AS {}",
display_comma_separated(&self.options),
self.query
)
} else {
write!(
f,
"EXPORT DATA OPTIONS({}) AS {}",
display_comma_separated(&self.options),
self.query
)
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct CreateUser {
pub or_replace: bool,
pub if_not_exists: bool,
pub name: Ident,
pub options: KeyValueOptions,
pub with_tags: bool,
pub tags: KeyValueOptions,
}
impl fmt::Display for CreateUser {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "CREATE")?;
if self.or_replace {
write!(f, " OR REPLACE")?;
}
write!(f, " USER")?;
if self.if_not_exists {
write!(f, " IF NOT EXISTS")?;
}
write!(f, " {}", self.name)?;
if !self.options.options.is_empty() {
write!(f, " {}", self.options)?;
}
if !self.tags.options.is_empty() {
if self.with_tags {
write!(f, " WITH")?;
}
write!(f, " TAG ({})", 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 struct AlterUser {
pub if_exists: bool,
pub name: Ident,
pub rename_to: Option<Ident>,
pub reset_password: bool,
pub abort_all_queries: bool,
pub add_role_delegation: Option<AlterUserAddRoleDelegation>,
pub remove_role_delegation: Option<AlterUserRemoveRoleDelegation>,
pub enroll_mfa: bool,
pub set_default_mfa_method: Option<MfaMethodKind>,
pub remove_mfa_method: Option<MfaMethodKind>,
pub modify_mfa_method: Option<AlterUserModifyMfaMethod>,
pub add_mfa_method_otp: Option<AlterUserAddMfaMethodOtp>,
pub set_policy: Option<AlterUserSetPolicy>,
pub unset_policy: Option<UserPolicyKind>,
pub set_tag: KeyValueOptions,
pub unset_tag: Vec<String>,
pub set_props: KeyValueOptions,
pub unset_props: Vec<String>,
pub password: Option<AlterUserPassword>,
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct AlterUserAddRoleDelegation {
pub role: Ident,
pub integration: 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 AlterUserRemoveRoleDelegation {
pub role: Option<Ident>,
pub integration: 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 AlterUserAddMfaMethodOtp {
pub count: Option<Value>,
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct AlterUserModifyMfaMethod {
pub method: MfaMethodKind,
pub comment: String,
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum MfaMethodKind {
PassKey,
Totp,
Duo,
}
impl fmt::Display for MfaMethodKind {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
MfaMethodKind::PassKey => write!(f, "PASSKEY"),
MfaMethodKind::Totp => write!(f, "TOTP"),
MfaMethodKind::Duo => write!(f, "DUO"),
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct AlterUserSetPolicy {
pub policy_kind: UserPolicyKind,
pub policy: 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 UserPolicyKind {
Authentication,
Password,
Session,
}
impl fmt::Display for UserPolicyKind {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
UserPolicyKind::Authentication => write!(f, "AUTHENTICATION"),
UserPolicyKind::Password => write!(f, "PASSWORD"),
UserPolicyKind::Session => write!(f, "SESSION"),
}
}
}
impl fmt::Display for AlterUser {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "ALTER")?;
write!(f, " USER")?;
if self.if_exists {
write!(f, " IF EXISTS")?;
}
write!(f, " {}", self.name)?;
if let Some(new_name) = &self.rename_to {
write!(f, " RENAME TO {new_name}")?;
}
if self.reset_password {
write!(f, " RESET PASSWORD")?;
}
if self.abort_all_queries {
write!(f, " ABORT ALL QUERIES")?;
}
if let Some(role_delegation) = &self.add_role_delegation {
let role = &role_delegation.role;
let integration = &role_delegation.integration;
write!(
f,
" ADD DELEGATED AUTHORIZATION OF ROLE {role} TO SECURITY INTEGRATION {integration}"
)?;
}
if let Some(role_delegation) = &self.remove_role_delegation {
write!(f, " REMOVE DELEGATED")?;
match &role_delegation.role {
Some(role) => write!(f, " AUTHORIZATION OF ROLE {role}")?,
None => write!(f, " AUTHORIZATIONS")?,
}
let integration = &role_delegation.integration;
write!(f, " FROM SECURITY INTEGRATION {integration}")?;
}
if self.enroll_mfa {
write!(f, " ENROLL MFA")?;
}
if let Some(method) = &self.set_default_mfa_method {
write!(f, " SET DEFAULT_MFA_METHOD {method}")?
}
if let Some(method) = &self.remove_mfa_method {
write!(f, " REMOVE MFA METHOD {method}")?;
}
if let Some(modify) = &self.modify_mfa_method {
let method = &modify.method;
let comment = &modify.comment;
write!(
f,
" MODIFY MFA METHOD {method} SET COMMENT '{}'",
value::escape_single_quote_string(comment)
)?;
}
if let Some(add_mfa_method_otp) = &self.add_mfa_method_otp {
write!(f, " ADD MFA METHOD OTP")?;
if let Some(count) = &add_mfa_method_otp.count {
write!(f, " COUNT = {count}")?;
}
}
if let Some(policy) = &self.set_policy {
let policy_kind = &policy.policy_kind;
let name = &policy.policy;
write!(f, " SET {policy_kind} POLICY {name}")?;
}
if let Some(policy_kind) = &self.unset_policy {
write!(f, " UNSET {policy_kind} POLICY")?;
}
if !self.set_tag.options.is_empty() {
write!(f, " SET TAG {}", self.set_tag)?;
}
if !self.unset_tag.is_empty() {
write!(f, " UNSET TAG {}", display_comma_separated(&self.unset_tag))?;
}
let has_props = !self.set_props.options.is_empty();
if has_props {
write!(f, " SET")?;
write!(f, " {}", &self.set_props)?;
}
if !self.unset_props.is_empty() {
write!(f, " UNSET {}", display_comma_separated(&self.unset_props))?;
}
if let Some(password) = &self.password {
write!(f, " {}", password)?;
}
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 AlterUserPassword {
pub encrypted: bool,
pub password: Option<String>,
}
impl Display for AlterUserPassword {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if self.encrypted {
write!(f, "ENCRYPTED ")?;
}
write!(f, "PASSWORD")?;
match &self.password {
None => write!(f, " NULL")?,
Some(password) => write!(f, " '{}'", value::escape_single_quote_string(password))?,
}
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 CreateTableLikeKind {
Parenthesized(CreateTableLike),
Plain(CreateTableLike),
}
#[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 CreateTableLikeDefaults {
Including,
Excluding,
}
impl fmt::Display for CreateTableLikeDefaults {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
CreateTableLikeDefaults::Including => write!(f, "INCLUDING DEFAULTS"),
CreateTableLikeDefaults::Excluding => write!(f, "EXCLUDING DEFAULTS"),
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct CreateTableLike {
pub name: ObjectName,
pub defaults: Option<CreateTableLikeDefaults>,
}
impl fmt::Display for CreateTableLike {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "LIKE {}", self.name)?;
if let Some(defaults) = &self.defaults {
write!(f, " {defaults}")?;
}
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 RefreshModeKind {
Auto,
Full,
Incremental,
}
impl fmt::Display for RefreshModeKind {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
RefreshModeKind::Auto => write!(f, "AUTO"),
RefreshModeKind::Full => write!(f, "FULL"),
RefreshModeKind::Incremental => write!(f, "INCREMENTAL"),
}
}
}
#[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 InitializeKind {
OnCreate,
OnSchedule,
}
impl fmt::Display for InitializeKind {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
InitializeKind::OnCreate => write!(f, "ON_CREATE"),
InitializeKind::OnSchedule => write!(f, "ON_SCHEDULE"),
}
}
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct VacuumStatement {
pub full: bool,
pub sort_only: bool,
pub delete_only: bool,
pub reindex: bool,
pub recluster: bool,
pub table_name: Option<ObjectName>,
pub threshold: Option<Value>,
pub boost: bool,
}
impl fmt::Display for VacuumStatement {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"VACUUM{}{}{}{}{}",
if self.full { " FULL" } else { "" },
if self.sort_only { " SORT ONLY" } else { "" },
if self.delete_only { " DELETE ONLY" } else { "" },
if self.reindex { " REINDEX" } else { "" },
if self.recluster { " RECLUSTER" } else { "" },
)?;
if let Some(table_name) = &self.table_name {
write!(f, " {table_name}")?;
}
if let Some(threshold) = &self.threshold {
write!(f, " TO {threshold} PERCENT")?;
}
if self.boost {
write!(f, " BOOST")?;
}
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 Reset {
ALL,
ConfigurationParameter(ObjectName),
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct ResetStatement {
pub reset: Reset,
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct OptimizerHint {
pub text: String,
pub style: OptimizerHintStyle,
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum OptimizerHintStyle {
SingleLine {
prefix: String,
},
MultiLine,
}
impl fmt::Display for OptimizerHint {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match &self.style {
OptimizerHintStyle::SingleLine { prefix } => {
f.write_str(prefix)?;
f.write_str("+")?;
f.write_str(&self.text)
}
OptimizerHintStyle::MultiLine => {
f.write_str("/*+")?;
f.write_str(&self.text)?;
f.write_str("*/")
}
}
}
}
impl fmt::Display for ResetStatement {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match &self.reset {
Reset::ALL => write!(f, "RESET ALL"),
Reset::ConfigurationParameter(param) => write!(f, "RESET {}", param),
}
}
}
impl From<Set> for Statement {
fn from(s: Set) -> Self {
Self::Set(s)
}
}
impl From<Query> for Statement {
fn from(q: Query) -> Self {
Box::new(q).into()
}
}
impl From<Box<Query>> for Statement {
fn from(q: Box<Query>) -> Self {
Self::Query(q)
}
}
impl From<Insert> for Statement {
fn from(i: Insert) -> Self {
Self::Insert(i)
}
}
impl From<Update> for Statement {
fn from(u: Update) -> Self {
Self::Update(u)
}
}
impl From<CreateView> for Statement {
fn from(cv: CreateView) -> Self {
Self::CreateView(cv)
}
}
impl From<CreateRole> for Statement {
fn from(cr: CreateRole) -> Self {
Self::CreateRole(cr)
}
}
impl From<AlterTable> for Statement {
fn from(at: AlterTable) -> Self {
Self::AlterTable(at)
}
}
impl From<DropFunction> for Statement {
fn from(df: DropFunction) -> Self {
Self::DropFunction(df)
}
}
impl From<CreateExtension> for Statement {
fn from(ce: CreateExtension) -> Self {
Self::CreateExtension(ce)
}
}
impl From<DropExtension> for Statement {
fn from(de: DropExtension) -> Self {
Self::DropExtension(de)
}
}
impl From<CaseStatement> for Statement {
fn from(c: CaseStatement) -> Self {
Self::Case(c)
}
}
impl From<IfStatement> for Statement {
fn from(i: IfStatement) -> Self {
Self::If(i)
}
}
impl From<WhileStatement> for Statement {
fn from(w: WhileStatement) -> Self {
Self::While(w)
}
}
impl From<RaiseStatement> for Statement {
fn from(r: RaiseStatement) -> Self {
Self::Raise(r)
}
}
impl From<Function> for Statement {
fn from(f: Function) -> Self {
Self::Call(f)
}
}
impl From<OpenStatement> for Statement {
fn from(o: OpenStatement) -> Self {
Self::Open(o)
}
}
impl From<Delete> for Statement {
fn from(d: Delete) -> Self {
Self::Delete(d)
}
}
impl From<CreateTable> for Statement {
fn from(c: CreateTable) -> Self {
Self::CreateTable(c)
}
}
impl From<CreateIndex> for Statement {
fn from(c: CreateIndex) -> Self {
Self::CreateIndex(c)
}
}
impl From<CreateServerStatement> for Statement {
fn from(c: CreateServerStatement) -> Self {
Self::CreateServer(c)
}
}
impl From<CreateConnector> for Statement {
fn from(c: CreateConnector) -> Self {
Self::CreateConnector(c)
}
}
impl From<CreateOperator> for Statement {
fn from(c: CreateOperator) -> Self {
Self::CreateOperator(c)
}
}
impl From<CreateOperatorFamily> for Statement {
fn from(c: CreateOperatorFamily) -> Self {
Self::CreateOperatorFamily(c)
}
}
impl From<CreateOperatorClass> for Statement {
fn from(c: CreateOperatorClass) -> Self {
Self::CreateOperatorClass(c)
}
}
impl From<AlterSchema> for Statement {
fn from(a: AlterSchema) -> Self {
Self::AlterSchema(a)
}
}
impl From<AlterType> for Statement {
fn from(a: AlterType) -> Self {
Self::AlterType(a)
}
}
impl From<AlterOperator> for Statement {
fn from(a: AlterOperator) -> Self {
Self::AlterOperator(a)
}
}
impl From<AlterOperatorFamily> for Statement {
fn from(a: AlterOperatorFamily) -> Self {
Self::AlterOperatorFamily(a)
}
}
impl From<AlterOperatorClass> for Statement {
fn from(a: AlterOperatorClass) -> Self {
Self::AlterOperatorClass(a)
}
}
impl From<Merge> for Statement {
fn from(m: Merge) -> Self {
Self::Merge(m)
}
}
impl From<AlterUser> for Statement {
fn from(a: AlterUser) -> Self {
Self::AlterUser(a)
}
}
impl From<DropDomain> for Statement {
fn from(d: DropDomain) -> Self {
Self::DropDomain(d)
}
}
impl From<ShowCharset> for Statement {
fn from(s: ShowCharset) -> Self {
Self::ShowCharset(s)
}
}
impl From<ShowObjects> for Statement {
fn from(s: ShowObjects) -> Self {
Self::ShowObjects(s)
}
}
impl From<Use> for Statement {
fn from(u: Use) -> Self {
Self::Use(u)
}
}
impl From<CreateFunction> for Statement {
fn from(c: CreateFunction) -> Self {
Self::CreateFunction(c)
}
}
impl From<CreateTrigger> for Statement {
fn from(c: CreateTrigger) -> Self {
Self::CreateTrigger(c)
}
}
impl From<DropTrigger> for Statement {
fn from(d: DropTrigger) -> Self {
Self::DropTrigger(d)
}
}
impl From<DropOperator> for Statement {
fn from(d: DropOperator) -> Self {
Self::DropOperator(d)
}
}
impl From<DropOperatorFamily> for Statement {
fn from(d: DropOperatorFamily) -> Self {
Self::DropOperatorFamily(d)
}
}
impl From<DropOperatorClass> for Statement {
fn from(d: DropOperatorClass) -> Self {
Self::DropOperatorClass(d)
}
}
impl From<DenyStatement> for Statement {
fn from(d: DenyStatement) -> Self {
Self::Deny(d)
}
}
impl From<CreateDomain> for Statement {
fn from(c: CreateDomain) -> Self {
Self::CreateDomain(c)
}
}
impl From<RenameTable> for Statement {
fn from(r: RenameTable) -> Self {
vec![r].into()
}
}
impl From<Vec<RenameTable>> for Statement {
fn from(r: Vec<RenameTable>) -> Self {
Self::RenameTable(r)
}
}
impl From<PrintStatement> for Statement {
fn from(p: PrintStatement) -> Self {
Self::Print(p)
}
}
impl From<ReturnStatement> for Statement {
fn from(r: ReturnStatement) -> Self {
Self::Return(r)
}
}
impl From<ExportData> for Statement {
fn from(e: ExportData) -> Self {
Self::ExportData(e)
}
}
impl From<CreateUser> for Statement {
fn from(c: CreateUser) -> Self {
Self::CreateUser(c)
}
}
impl From<VacuumStatement> for Statement {
fn from(v: VacuumStatement) -> Self {
Self::Vacuum(v)
}
}
impl From<ResetStatement> for Statement {
fn from(r: ResetStatement) -> Self {
Self::Reset(r)
}
}
#[cfg(test)]
mod tests {
use crate::tokenizer::Location;
use super::*;
#[test]
fn test_window_frame_default() {
let window_frame = WindowFrame::default();
assert_eq!(WindowFrameBound::Preceding(None), window_frame.start_bound);
}
#[test]
fn test_grouping_sets_display() {
let grouping_sets = Expr::GroupingSets(vec![
vec![Expr::Identifier(Ident::new("a"))],
vec![Expr::Identifier(Ident::new("b"))],
]);
assert_eq!("GROUPING SETS ((a), (b))", format!("{grouping_sets}"));
let grouping_sets = Expr::GroupingSets(vec![vec![
Expr::Identifier(Ident::new("a")),
Expr::Identifier(Ident::new("b")),
]]);
assert_eq!("GROUPING SETS ((a, b))", format!("{grouping_sets}"));
let grouping_sets = Expr::GroupingSets(vec![
vec![
Expr::Identifier(Ident::new("a")),
Expr::Identifier(Ident::new("b")),
],
vec![
Expr::Identifier(Ident::new("c")),
Expr::Identifier(Ident::new("d")),
],
]);
assert_eq!("GROUPING SETS ((a, b), (c, d))", format!("{grouping_sets}"));
}
#[test]
fn test_rollup_display() {
let rollup = Expr::Rollup(vec![vec![Expr::Identifier(Ident::new("a"))]]);
assert_eq!("ROLLUP (a)", format!("{rollup}"));
let rollup = Expr::Rollup(vec![vec![
Expr::Identifier(Ident::new("a")),
Expr::Identifier(Ident::new("b")),
]]);
assert_eq!("ROLLUP ((a, b))", format!("{rollup}"));
let rollup = Expr::Rollup(vec![
vec![Expr::Identifier(Ident::new("a"))],
vec![Expr::Identifier(Ident::new("b"))],
]);
assert_eq!("ROLLUP (a, b)", format!("{rollup}"));
let rollup = Expr::Rollup(vec![
vec![Expr::Identifier(Ident::new("a"))],
vec![
Expr::Identifier(Ident::new("b")),
Expr::Identifier(Ident::new("c")),
],
vec![Expr::Identifier(Ident::new("d"))],
]);
assert_eq!("ROLLUP (a, (b, c), d)", format!("{rollup}"));
}
#[test]
fn test_cube_display() {
let cube = Expr::Cube(vec![vec![Expr::Identifier(Ident::new("a"))]]);
assert_eq!("CUBE (a)", format!("{cube}"));
let cube = Expr::Cube(vec![vec![
Expr::Identifier(Ident::new("a")),
Expr::Identifier(Ident::new("b")),
]]);
assert_eq!("CUBE ((a, b))", format!("{cube}"));
let cube = Expr::Cube(vec![
vec![Expr::Identifier(Ident::new("a"))],
vec![Expr::Identifier(Ident::new("b"))],
]);
assert_eq!("CUBE (a, b)", format!("{cube}"));
let cube = Expr::Cube(vec![
vec![Expr::Identifier(Ident::new("a"))],
vec![
Expr::Identifier(Ident::new("b")),
Expr::Identifier(Ident::new("c")),
],
vec![Expr::Identifier(Ident::new("d"))],
]);
assert_eq!("CUBE (a, (b, c), d)", format!("{cube}"));
}
#[test]
fn test_interval_display() {
let interval = Expr::Interval(Interval {
value: Box::new(Expr::Value(
Value::SingleQuotedString(String::from("123:45.67")).with_empty_span(),
)),
leading_field: Some(DateTimeField::Minute),
leading_precision: Some(10),
last_field: Some(DateTimeField::Second),
fractional_seconds_precision: Some(9),
});
assert_eq!(
"INTERVAL '123:45.67' MINUTE (10) TO SECOND (9)",
format!("{interval}"),
);
let interval = Expr::Interval(Interval {
value: Box::new(Expr::Value(
Value::SingleQuotedString(String::from("5")).with_empty_span(),
)),
leading_field: Some(DateTimeField::Second),
leading_precision: Some(1),
last_field: None,
fractional_seconds_precision: Some(3),
});
assert_eq!("INTERVAL '5' SECOND (1, 3)", format!("{interval}"));
}
#[test]
fn test_one_or_many_with_parens_deref() {
use core::ops::Index;
let one = OneOrManyWithParens::One("a");
assert_eq!(one.deref(), &["a"]);
assert_eq!(<OneOrManyWithParens<_> as Deref>::deref(&one), &["a"]);
assert_eq!(one[0], "a");
assert_eq!(one.index(0), &"a");
assert_eq!(
<<OneOrManyWithParens<_> as Deref>::Target as Index<usize>>::index(&one, 0),
&"a"
);
assert_eq!(one.len(), 1);
assert_eq!(<OneOrManyWithParens<_> as Deref>::Target::len(&one), 1);
let many1 = OneOrManyWithParens::Many(vec!["b"]);
assert_eq!(many1.deref(), &["b"]);
assert_eq!(<OneOrManyWithParens<_> as Deref>::deref(&many1), &["b"]);
assert_eq!(many1[0], "b");
assert_eq!(many1.index(0), &"b");
assert_eq!(
<<OneOrManyWithParens<_> as Deref>::Target as Index<usize>>::index(&many1, 0),
&"b"
);
assert_eq!(many1.len(), 1);
assert_eq!(<OneOrManyWithParens<_> as Deref>::Target::len(&many1), 1);
let many2 = OneOrManyWithParens::Many(vec!["c", "d"]);
assert_eq!(many2.deref(), &["c", "d"]);
assert_eq!(
<OneOrManyWithParens<_> as Deref>::deref(&many2),
&["c", "d"]
);
assert_eq!(many2[0], "c");
assert_eq!(many2.index(0), &"c");
assert_eq!(
<<OneOrManyWithParens<_> as Deref>::Target as Index<usize>>::index(&many2, 0),
&"c"
);
assert_eq!(many2[1], "d");
assert_eq!(many2.index(1), &"d");
assert_eq!(
<<OneOrManyWithParens<_> as Deref>::Target as Index<usize>>::index(&many2, 1),
&"d"
);
assert_eq!(many2.len(), 2);
assert_eq!(<OneOrManyWithParens<_> as Deref>::Target::len(&many2), 2);
}
#[test]
fn test_one_or_many_with_parens_as_ref() {
let one = OneOrManyWithParens::One("a");
assert_eq!(one.as_ref(), &["a"]);
assert_eq!(<OneOrManyWithParens<_> as AsRef<_>>::as_ref(&one), &["a"]);
let many1 = OneOrManyWithParens::Many(vec!["b"]);
assert_eq!(many1.as_ref(), &["b"]);
assert_eq!(<OneOrManyWithParens<_> as AsRef<_>>::as_ref(&many1), &["b"]);
let many2 = OneOrManyWithParens::Many(vec!["c", "d"]);
assert_eq!(many2.as_ref(), &["c", "d"]);
assert_eq!(
<OneOrManyWithParens<_> as AsRef<_>>::as_ref(&many2),
&["c", "d"]
);
}
#[test]
fn test_one_or_many_with_parens_ref_into_iter() {
let one = OneOrManyWithParens::One("a");
assert_eq!(Vec::from_iter(&one), vec![&"a"]);
let many1 = OneOrManyWithParens::Many(vec!["b"]);
assert_eq!(Vec::from_iter(&many1), vec![&"b"]);
let many2 = OneOrManyWithParens::Many(vec!["c", "d"]);
assert_eq!(Vec::from_iter(&many2), vec![&"c", &"d"]);
}
#[test]
fn test_one_or_many_with_parens_value_into_iter() {
use core::iter::once;
fn test_steps<I>(ours: OneOrManyWithParens<usize>, inner: I, n: usize)
where
I: IntoIterator<Item = usize, IntoIter: DoubleEndedIterator + Clone> + Clone,
{
fn checks<I>(ours: OneOrManyWithParensIntoIter<usize>, inner: I)
where
I: Iterator<Item = usize> + Clone + DoubleEndedIterator,
{
assert_eq!(ours.size_hint(), inner.size_hint());
assert_eq!(ours.clone().count(), inner.clone().count());
assert_eq!(
ours.clone().fold(1, |a, v| a + v),
inner.clone().fold(1, |a, v| a + v)
);
assert_eq!(Vec::from_iter(ours.clone()), Vec::from_iter(inner.clone()));
assert_eq!(
Vec::from_iter(ours.clone().rev()),
Vec::from_iter(inner.clone().rev())
);
}
let mut ours_next = ours.clone().into_iter();
let mut inner_next = inner.clone().into_iter();
for _ in 0..n {
checks(ours_next.clone(), inner_next.clone());
assert_eq!(ours_next.next(), inner_next.next());
}
let mut ours_next_back = ours.clone().into_iter();
let mut inner_next_back = inner.clone().into_iter();
for _ in 0..n {
checks(ours_next_back.clone(), inner_next_back.clone());
assert_eq!(ours_next_back.next_back(), inner_next_back.next_back());
}
let mut ours_mixed = ours.clone().into_iter();
let mut inner_mixed = inner.clone().into_iter();
for i in 0..n {
checks(ours_mixed.clone(), inner_mixed.clone());
if i % 2 == 0 {
assert_eq!(ours_mixed.next_back(), inner_mixed.next_back());
} else {
assert_eq!(ours_mixed.next(), inner_mixed.next());
}
}
let mut ours_mixed2 = ours.into_iter();
let mut inner_mixed2 = inner.into_iter();
for i in 0..n {
checks(ours_mixed2.clone(), inner_mixed2.clone());
if i % 2 == 0 {
assert_eq!(ours_mixed2.next(), inner_mixed2.next());
} else {
assert_eq!(ours_mixed2.next_back(), inner_mixed2.next_back());
}
}
}
test_steps(OneOrManyWithParens::One(1), once(1), 3);
test_steps(OneOrManyWithParens::Many(vec![2]), vec![2], 3);
test_steps(OneOrManyWithParens::Many(vec![3, 4]), vec![3, 4], 4);
}
#[test]
fn test_ident_ord() {
let mut a = Ident::with_span(Span::new(Location::new(1, 1), Location::new(1, 1)), "a");
let mut b = Ident::with_span(Span::new(Location::new(2, 2), Location::new(2, 2)), "b");
assert!(a < b);
std::mem::swap(&mut a.span, &mut b.span);
assert!(a < b);
}
}