@@ -2814,9 +2814,19 @@ impl<'a> Parser<'a> {
28142814 pub fn parse_select_item ( & mut self ) -> Result < SelectItem , ParserError > {
28152815 let expr = self . parse_expr ( ) ?;
28162816 if let Expr :: Wildcard = expr {
2817- Ok ( SelectItem :: Wildcard )
2817+ let ( except, replace) = self . parse_wildcard_modifiers ( ) ?;
2818+ Ok ( SelectItem :: Wildcard {
2819+ prefix : None ,
2820+ except,
2821+ replace,
2822+ } )
28182823 } else if let Expr :: QualifiedWildcard ( prefix) = expr {
2819- Ok ( SelectItem :: QualifiedWildcard ( ObjectName ( prefix) ) )
2824+ let ( except, replace) = self . parse_wildcard_modifiers ( ) ?;
2825+ Ok ( SelectItem :: Wildcard {
2826+ prefix : Some ( ObjectName ( prefix) ) ,
2827+ except,
2828+ replace,
2829+ } )
28202830 } else {
28212831 // `expr` is a regular SQL expression and can be followed by an alias
28222832 if let Some ( alias) = self . parse_optional_alias ( keywords:: RESERVED_FOR_COLUMN_ALIAS ) ? {
@@ -2827,6 +2837,40 @@ impl<'a> Parser<'a> {
28272837 }
28282838 }
28292839
2840+ /// Parse a comma-delimited list of projections after REPLACE
2841+ /// https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax#select_replace
2842+ pub fn parse_replace_item ( & mut self ) -> Result < ( Expr , Ident ) , ParserError > {
2843+ let expr = self . parse_expr ( ) ?;
2844+ // `expr` is a regular SQL expression and can be followed by an alias
2845+ if let Some ( alias) = self . parse_optional_alias ( keywords:: RESERVED_FOR_COLUMN_ALIAS ) ? {
2846+ Ok ( ( expr, alias) )
2847+ } else {
2848+ parser_err ! ( self , "REPLACE expression must have alias" )
2849+ }
2850+ }
2851+
2852+ pub fn parse_wildcard_modifiers (
2853+ & mut self ,
2854+ ) -> Result < ( Vec < Ident > , Vec < ( Expr , Ident ) > ) , ParserError > {
2855+ let except = if self . parse_keyword ( Keyword :: EXCEPT ) {
2856+ self . expect_token ( & Token :: LParen ) ?;
2857+ let aliases = self . parse_comma_separated ( Parser :: parse_identifier) ?;
2858+ self . expect_token ( & Token :: RParen ) ?;
2859+ aliases
2860+ } else {
2861+ vec ! [ ]
2862+ } ;
2863+ let replace = if self . parse_keyword ( Keyword :: EXCEPT ) {
2864+ self . expect_token ( & Token :: LParen ) ?;
2865+ let replace = self . parse_comma_separated ( Parser :: parse_replace_item) ?;
2866+ self . expect_token ( & Token :: RParen ) ?;
2867+ replace
2868+ } else {
2869+ vec ! [ ]
2870+ } ;
2871+ Ok ( ( except, replace) )
2872+ }
2873+
28302874 /// Parse an expression, optionally followed by ASC or DESC (used in ORDER BY)
28312875 pub fn parse_order_by_expr ( & mut self ) -> Result < OrderByExpr , ParserError > {
28322876 let expr = self . parse_expr ( ) ?;
0 commit comments