Skip to content

Commit 04cd108

Browse files
committed
feat: define opt_replace for wildcard replace
1 parent 571e326 commit 04cd108

File tree

3 files changed

+71
-1
lines changed

3 files changed

+71
-1
lines changed

src/ast/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ pub use self::operator::{BinaryOperator, UnaryOperator};
3636
pub use self::query::{
3737
Cte, ExceptSelectItem, ExcludeSelectItem, Fetch, IdentWithAlias, Join, JoinConstraint,
3838
JoinOperator, LateralView, LockClause, LockType, NonBlock, Offset, OffsetRows, OrderByExpr,
39-
Query, RenameSelectItem, Select, SelectInto, SelectItem, SetExpr, SetOperator, SetQuantifier,
39+
Query, RenameSelectItem, ReplaceSelectItem, Select, SelectInto, SelectItem, SetExpr, SetOperator, SetQuantifier,
4040
Table, TableAlias, TableFactor, TableWithJoins, Top, Values, WildcardAdditionalOptions, With,
4141
};
4242
pub use self::value::{

src/ast/query.rs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,8 @@ pub struct WildcardAdditionalOptions {
394394
pub opt_except: Option<ExceptSelectItem>,
395395
/// `[RENAME ...]`.
396396
pub opt_rename: Option<RenameSelectItem>,
397+
/// `[REPLACE]`
398+
pub opt_replace:Option<ReplaceSelectItem>
397399
}
398400

399401
impl fmt::Display for WildcardAdditionalOptions {
@@ -526,6 +528,46 @@ impl fmt::Display for ExceptSelectItem {
526528
}
527529
}
528530

531+
/// Bigquery `REPLACE` information.
532+
///
533+
/// # Syntax
534+
/// ```plaintext
535+
/// REPLACE <new_expr> AS <col_name>
536+
/// ```
537+
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
538+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
539+
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
540+
pub enum ReplaceSelectItem {
541+
/// Single column name with alias without parenthesis.
542+
///
543+
/// # Syntax
544+
/// ```plaintext
545+
/// <col_name> AS <col_alias>
546+
/// ```
547+
Single(IdentWithAlias),
548+
/// Multiple column names with aliases inside parenthesis.
549+
/// # Syntax
550+
/// ```plaintext
551+
/// (<col_name> AS <col_alias>, <col_name> AS <col_alias>, ...)
552+
/// ```
553+
Multiple(Vec<IdentWithAlias>),
554+
}
555+
556+
impl fmt::Display for ReplaceSelectItem {
557+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
558+
write!(f, "REPLACE")?;
559+
match self {
560+
Self::Single(column) => {
561+
write!(f, " {column}")?;
562+
}
563+
Self::Multiple(columns) => {
564+
write!(f, " ({})", display_comma_separated(columns))?;
565+
}
566+
}
567+
Ok(())
568+
}
569+
}
570+
529571
impl fmt::Display for SelectItem {
530572
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
531573
match &self {

src/parser.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6164,10 +6164,17 @@ impl<'a> Parser<'a> {
61646164
None
61656165
};
61666166

6167+
let opt_replace = if dialect_of!(self is GenericDialect | BigQueryDialect){
6168+
self.parse_optional_select_item_replace()?
6169+
}else {
6170+
None
6171+
};
6172+
61676173
Ok(WildcardAdditionalOptions {
61686174
opt_exclude,
61696175
opt_except,
61706176
opt_rename,
6177+
opt_replace
61716178
})
61726179
}
61736180

@@ -6241,6 +6248,27 @@ impl<'a> Parser<'a> {
62416248
Ok(opt_rename)
62426249
}
62436250

6251+
/// Parse a [`Replace](RepalceSelectItem) information for wildcard select items.
6252+
pub fn parse_optional_select_item_replace(
6253+
&mut self,
6254+
) -> Result<Option<ReplaceSelectItem>, ParserError> {
6255+
let opt_replace = if self.parse_keyword(Keyword::REPLACE) {
6256+
if self.consume_token(&Token::LParen) {
6257+
let idents =
6258+
self.parse_comma_separated(|parser| parser.parse_identifier_with_alias())?;
6259+
self.expect_token(&Token::RParen)?;
6260+
Some(ReplaceSelectItem::Multiple(idents))
6261+
} else {
6262+
let ident = self.parse_identifier_with_alias()?;
6263+
Some(ReplaceSelectItem::Single(ident))
6264+
}
6265+
} else {
6266+
None
6267+
};
6268+
6269+
Ok(opt_replace)
6270+
}
6271+
62446272
/// Parse an expression, optionally followed by ASC or DESC (used in ORDER BY)
62456273
pub fn parse_order_by_expr(&mut self) -> Result<OrderByExpr, ParserError> {
62466274
let expr = self.parse_expr()?;

0 commit comments

Comments
 (0)