Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
182 changes: 182 additions & 0 deletions src/ast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2459,6 +2459,8 @@ pub enum CommentObject {
Schema,
/// A sequence.
Sequence,
/// Statistics object.
Statistics,
/// A table.
Table,
/// A type.
Expand All @@ -2483,6 +2485,7 @@ impl fmt::Display for CommentObject {
CommentObject::Role => f.write_str("ROLE"),
CommentObject::Schema => f.write_str("SCHEMA"),
CommentObject::Sequence => f.write_str("SEQUENCE"),
CommentObject::Statistics => f.write_str("STATISTICS"),
CommentObject::Table => f.write_str("TABLE"),
CommentObject::Type => f.write_str("TYPE"),
CommentObject::User => f.write_str("USER"),
Expand Down Expand Up @@ -3707,6 +3710,11 @@ pub enum Statement {
/// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-createopclass.html)
CreateOperatorClass(CreateOperatorClass),
/// ```sql
/// CREATE STATISTICS
/// ```
/// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-createstatistics.html)
CreateStatistics(CreateStatistics),
/// ```sql
/// ALTER TABLE
/// ```
AlterTable(AlterTable),
Expand Down Expand Up @@ -3759,6 +3767,11 @@ pub enum Statement {
/// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-alteropclass.html)
AlterOperatorClass(AlterOperatorClass),
/// ```sql
/// ALTER STATISTICS
/// ```
/// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-alterstatistics.html)
AlterStatistics(AlterStatistics),
/// ```sql
/// ALTER ROLE
/// ```
AlterRole {
Expand Down Expand Up @@ -5443,6 +5456,7 @@ impl fmt::Display for Statement {
create_operator_family.fmt(f)
}
Statement::CreateOperatorClass(create_operator_class) => create_operator_class.fmt(f),
Statement::CreateStatistics(create_statistics) => create_statistics.fmt(f),
Statement::AlterTable(alter_table) => write!(f, "{alter_table}"),
Statement::AlterIndex { name, operation } => {
write!(f, "ALTER INDEX {name} {operation}")
Expand Down Expand Up @@ -5472,6 +5486,7 @@ impl fmt::Display for Statement {
Statement::AlterOperatorClass(alter_operator_class) => {
write!(f, "{alter_operator_class}")
}
Statement::AlterStatistics(alter_statistics) => write!(f, "{alter_statistics}"),
Statement::AlterRole { name, operation } => {
write!(f, "ALTER ROLE {name} {operation}")
}
Expand Down Expand Up @@ -8246,6 +8261,8 @@ pub enum ObjectType {
Role,
/// A sequence.
Sequence,
/// Statistics object.
Statistics,
/// A stage.
Stage,
/// A type definition.
Expand All @@ -8267,6 +8284,7 @@ impl fmt::Display for ObjectType {
ObjectType::Database => "DATABASE",
ObjectType::Role => "ROLE",
ObjectType::Sequence => "SEQUENCE",
ObjectType::Statistics => "STATISTICS",
ObjectType::Stage => "STAGE",
ObjectType::Type => "TYPE",
ObjectType::User => "USER",
Expand Down Expand Up @@ -8697,6 +8715,158 @@ impl fmt::Display for SecretOption {
}
}

/// Statistics kinds supported by PostgreSQL `CREATE STATISTICS`.
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum StatisticsType {
/// `ndistinct` kind.
Ndistinct,
/// `dependencies` kind.
Dependencies,
/// `mcv` kind.
Mcv,
/// Any other statistics kind identifier accepted by PostgreSQL grammar.
Other(Ident),
}

impl fmt::Display for StatisticsType {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
StatisticsType::Ndistinct => write!(f, "NDISTINCT"),
StatisticsType::Dependencies => write!(f, "DEPENDENCIES"),
StatisticsType::Mcv => write!(f, "MCV"),
StatisticsType::Other(ident) => write!(f, "{ident}"),
}
}
}

/// A `CREATE STATISTICS` statement.
///
/// [PostgreSQL Documentation](https://www.postgresql.org/docs/current/sql-createstatistics.html)
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct CreateStatistics {
/// Whether `IF NOT EXISTS` was specified.
pub if_not_exists: bool,
/// Optional name of the statistics object.
pub name: Option<ObjectName>,
/// Optional list of statistics kinds.
pub statistics_types: Vec<StatisticsType>,
/// Target expressions listed after `ON`.
pub columns: Vec<Expr>,
/// Source relation list after `FROM`.
pub from: Vec<TableWithJoins>,
}

impl fmt::Display for CreateStatistics {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "CREATE STATISTICS")?;
if self.if_not_exists {
write!(f, " IF NOT EXISTS")?;
}
if let Some(name) = &self.name {
write!(f, " {name}")?;
}
if !self.statistics_types.is_empty() {
write!(f, " ({})", display_comma_separated(&self.statistics_types))?;
}
write!(
f,
" ON {} FROM {}",
display_comma_separated(&self.columns),
display_comma_separated(&self.from)
)
}
}

/// Target value for `ALTER STATISTICS ... SET STATISTICS`.
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum AlterStatisticsTarget {
/// Numeric target value.
Value(i64),
/// `DEFAULT` target.
Default,
}

impl fmt::Display for AlterStatisticsTarget {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
AlterStatisticsTarget::Value(value) => write!(f, "{value}"),
AlterStatisticsTarget::Default => write!(f, "DEFAULT"),
}
}
}

/// Operation variants for `ALTER STATISTICS`.
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum AlterStatisticsOperation {
/// `RENAME TO new_name`.
RenameTo {
/// New name of the statistics object.
new_name: ObjectName,
},
/// `OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER }`.
OwnerTo(Owner),
/// `SET SCHEMA new_schema`.
SetSchema {
/// New schema for the statistics object.
schema_name: ObjectName,
},
/// `SET STATISTICS { integer | DEFAULT }`.
SetStatistics {
/// New statistics target value.
target: AlterStatisticsTarget,
},
}

impl fmt::Display for AlterStatisticsOperation {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
AlterStatisticsOperation::RenameTo { new_name } => write!(f, "RENAME TO {new_name}"),
AlterStatisticsOperation::OwnerTo(owner) => write!(f, "OWNER TO {owner}"),
AlterStatisticsOperation::SetSchema { schema_name } => {
write!(f, "SET SCHEMA {schema_name}")
}
AlterStatisticsOperation::SetStatistics { target } => {
write!(f, "SET STATISTICS {target}")
}
}
}
}

/// An `ALTER STATISTICS` statement.
///
/// [PostgreSQL Documentation](https://www.postgresql.org/docs/current/sql-alterstatistics.html)
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct AlterStatistics {
/// Whether `IF EXISTS` was specified.
pub if_exists: bool,
/// Name of the statistics object.
pub name: ObjectName,
/// Operation to apply.
pub operation: AlterStatisticsOperation,
}

impl fmt::Display for AlterStatistics {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"ALTER STATISTICS {if_exists}{name} {operation}",
if_exists = if self.if_exists { "IF EXISTS " } else { "" },
name = self.name,
operation = self.operation
)
}
}

/// A `CREATE SERVER` statement.
///
/// [PostgreSQL Documentation](https://www.postgresql.org/docs/current/sql-createserver.html)
Expand Down Expand Up @@ -11912,6 +12082,12 @@ impl From<CreateOperatorClass> for Statement {
}
}

impl From<CreateStatistics> for Statement {
fn from(c: CreateStatistics) -> Self {
Self::CreateStatistics(c)
}
}

impl From<AlterSchema> for Statement {
fn from(a: AlterSchema) -> Self {
Self::AlterSchema(a)
Expand Down Expand Up @@ -11942,6 +12118,12 @@ impl From<AlterOperatorClass> for Statement {
}
}

impl From<AlterStatistics> for Statement {
fn from(a: AlterStatistics) -> Self {
Self::AlterStatistics(a)
}
}

impl From<Merge> for Statement {
fn from(m: Merge) -> Self {
Self::Merge(m)
Expand Down
2 changes: 2 additions & 0 deletions src/ast/spans.rs
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,7 @@ impl Spanned for Statement {
create_operator_family.span()
}
Statement::CreateOperatorClass(create_operator_class) => create_operator_class.span(),
Statement::CreateStatistics(..) => Span::empty(),
Statement::AlterTable(alter_table) => alter_table.span(),
Statement::AlterIndex { name, operation } => name.span().union(&operation.span()),
Statement::AlterView {
Expand All @@ -406,6 +407,7 @@ impl Spanned for Statement {
Statement::AlterOperator { .. } => Span::empty(),
Statement::AlterOperatorFamily { .. } => Span::empty(),
Statement::AlterOperatorClass { .. } => Span::empty(),
Statement::AlterStatistics(..) => Span::empty(),
Statement::AlterRole { .. } => Span::empty(),
Statement::AlterSession { .. } => Span::empty(),
Statement::AttachDatabase { .. } => Span::empty(),
Expand Down
Loading