fmguerreiro commented on code in PR #2316:
URL:
https://github.com/apache/datafusion-sqlparser-rs/pull/2316#discussion_r4333891187
##########
src/parser/mod.rs:
##########
@@ -7499,6 +7492,226 @@ impl<'a> Parser<'a> {
})
}
+ /// Parse a [Statement::CreateAggregate]
+ ///
+ /// [PostgreSQL
Documentation](https://www.postgresql.org/docs/current/sql-createaggregate.html)
+ pub fn parse_create_aggregate(
+ &mut self,
+ or_replace: bool,
+ ) -> Result<CreateAggregate, ParserError> {
+ let name = self.parse_object_name(false)?;
+
+ // The legacy and modern forms (see [`CreateAggregateArgs::Legacy`])
differ
+ // only in whether a second parenthesized list follows the first, so
look
+ // that far ahead before committing to either branch.
+ let args = if self.peek_create_aggregate_arg_list()? {
+ self.parse_create_aggregate_args()?
+ } else {
+ CreateAggregateArgs::Legacy
+ };
+ self.expect_token(&Token::LParen)?;
+
+ let mut seen: Vec<Keyword> = Vec::new();
+ let options = self.parse_comma_separated(|parser| {
+ let start = parser.peek_token_ref().span.start;
+ let keyword = parser.parse_create_aggregate_option_key()?;
+ if seen.contains(&keyword) {
+ return parser_err!(
+ format!("Duplicate CREATE AGGREGATE option: {keyword:?}"),
+ start
+ );
+ }
+ seen.push(keyword);
+ parser.parse_create_aggregate_option(keyword)
+ })?;
+ self.expect_token(&Token::RParen)?;
+
+ Ok(CreateAggregate {
+ or_replace,
+ name,
+ args,
+ options,
+ })
+ }
+
+ /// Parse the argument list of a `CREATE AGGREGATE`: `(*)` or `(arg [,
...])`.
+ fn parse_create_aggregate_args(&mut self) -> Result<CreateAggregateArgs,
ParserError> {
+ self.expect_token(&Token::LParen)?;
+ let args = if self.consume_token(&Token::Mul) {
+ CreateAggregateArgs::Star
+ } else {
+
CreateAggregateArgs::List(self.parse_comma_separated(Parser::parse_function_arg)?)
+ };
Review Comment:
fixed in ea2bfe88.
##########
src/parser/mod.rs:
##########
Review Comment:
fixed in ea2bfe88.
##########
src/ast/ddl.rs:
##########
@@ -6078,3 +6078,168 @@ impl Spanned for CreateForeignTable {
)
}
}
+
+/// CREATE AGGREGATE statement.
+/// See <https://www.postgresql.org/docs/current/sql-createaggregate.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 CreateAggregate {
+ /// True if `OR REPLACE` was specified.
+ pub or_replace: bool,
+ /// The aggregate name (can be schema-qualified).
+ pub name: ObjectName,
+ /// The argument list preceding the options list.
+ pub args: CreateAggregateArgs,
+ /// The options listed inside the required parentheses after the argument
+ /// list (e.g. `SFUNC`, `STYPE`, `FINALFUNC`, `PARALLEL`, …).
+ pub options: Vec<CreateAggregateOption>,
+}
+
+impl fmt::Display for CreateAggregate {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(f, "CREATE")?;
+ if self.or_replace {
+ write!(f, " OR REPLACE")?;
+ }
+ write!(f, " AGGREGATE {}", self.name)?;
+ match &self.args {
+ CreateAggregateArgs::Legacy => {}
+ CreateAggregateArgs::Star => write!(f, " (*)")?,
+ CreateAggregateArgs::List(args) => write!(f, " ({})",
display_comma_separated(args))?,
+ }
+ write!(f, " ({})", display_comma_separated(&self.options))
+ }
+}
+
+/// The argument list of a [`CreateAggregate`] statement.
+#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
+#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
+#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
+pub enum CreateAggregateArgs {
+ /// No argument-list parentheses: the historical form that packs
everything,
+ /// usually including a `BASETYPE` option, into a single list.
+ Legacy,
+ /// The wildcard form `(*)`, used by zero-argument aggregates such as
+ /// `count(*)`.
+ Star,
+ /// An explicit argument list: `(NUMERIC)`,
+ /// `(input INT, VARIADIC tail TEXT)`.
+ List(Vec<OperateFunctionArg>),
Review Comment:
fixed in ea2bfe88.
##########
src/ast/ddl.rs:
##########
@@ -6078,3 +6078,168 @@ impl Spanned for CreateForeignTable {
)
}
}
+
+/// CREATE AGGREGATE statement.
+/// See <https://www.postgresql.org/docs/current/sql-createaggregate.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 CreateAggregate {
+ /// True if `OR REPLACE` was specified.
+ pub or_replace: bool,
+ /// The aggregate name (can be schema-qualified).
+ pub name: ObjectName,
+ /// The argument list preceding the options list.
+ pub args: CreateAggregateArgs,
+ /// The options listed inside the required parentheses after the argument
+ /// list (e.g. `SFUNC`, `STYPE`, `FINALFUNC`, `PARALLEL`, …).
+ pub options: Vec<CreateAggregateOption>,
+}
+
+impl fmt::Display for CreateAggregate {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(f, "CREATE")?;
+ if self.or_replace {
+ write!(f, " OR REPLACE")?;
+ }
+ write!(f, " AGGREGATE {}", self.name)?;
+ match &self.args {
+ CreateAggregateArgs::Legacy => {}
+ CreateAggregateArgs::Star => write!(f, " (*)")?,
+ CreateAggregateArgs::List(args) => write!(f, " ({})",
display_comma_separated(args))?,
Review Comment:
fixed in ea2bfe88.
##########
src/ast/spans.rs:
##########
@@ -2532,6 +2533,65 @@ impl Spanned for AlterTable {
}
}
+impl Spanned for CreateAggregate {
+ fn span(&self) -> Span {
+ union_spans(
+ core::iter::once(self.name.span())
+ .chain(core::iter::once(self.args.span()))
+ .chain(self.options.iter().map(|option| option.span())),
+ )
+ }
+}
+
+impl Spanned for CreateAggregateArgs {
+ fn span(&self) -> Span {
+ match self {
+ CreateAggregateArgs::Legacy | CreateAggregateArgs::Star =>
Span::empty(),
+ CreateAggregateArgs::List(args) =>
union_spans(args.iter().map(|arg| arg.span())),
Review Comment:
fixed in ea2bfe88.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]