@@ -81,8 +81,8 @@ impl Default for SelectRestrictions {
8181 }
8282}
8383
84- fn opt_paren_select ( p : & mut Parser < ' _ > ) -> Option < CompletedMarker > {
85- let m = p. start ( ) ;
84+ fn opt_paren_select ( p : & mut Parser < ' _ > , m : Option < Marker > ) -> Option < CompletedMarker > {
85+ let m = m . unwrap_or_else ( || p. start ( ) ) ;
8686 if !p. eat ( L_PAREN ) {
8787 m. abandon ( p) ;
8888 return None ;
@@ -98,7 +98,7 @@ fn opt_paren_select(p: &mut Parser<'_>) -> Option<CompletedMarker> {
9898 {
9999 break ;
100100 }
101- if opt_paren_select ( p) . is_none ( ) {
101+ if opt_paren_select ( p, None ) . is_none ( ) {
102102 break ;
103103 }
104104 if !p. at ( R_PAREN ) {
@@ -234,16 +234,14 @@ const EXTRACT_ARG_FIRST_: TokenSet =
234234
235235// IDENT | YEAR_P | MONTH_P | DAY_P | HOUR_P | MINUTE_P | SECOND_P | Sconst
236236const EXTRACT_ARG_FIRST : TokenSet = IDENTS . union ( EXTRACT_ARG_FIRST_ ) ;
237- fn extract_arg ( p : & mut Parser < ' _ > ) -> bool {
237+ fn extract_arg ( p : & mut Parser < ' _ > ) {
238238 if p. at_ts ( EXTRACT_ARG_FIRST ) {
239239 p. bump_any ( ) ;
240- true
241240 } else {
242241 p. error ( format ! (
243242 "expected ident, year, month, day, hour, minute, second, or string, got {:?}" ,
244243 p. current( )
245244 ) ) ;
246- false
247245 }
248246}
249247
@@ -2559,7 +2557,7 @@ fn compound_select(p: &mut Parser<'_>, cm: CompletedMarker) -> CompletedMarker {
25592557 p. eat ( DISTINCT_KW ) ;
25602558 }
25612559 if p. at ( L_PAREN ) {
2562- opt_paren_select ( p) ;
2560+ opt_paren_select ( p, None ) ;
25632561 } else {
25642562 if p. at_ts ( SELECT_FIRST ) {
25652563 select (
@@ -3161,7 +3159,7 @@ fn xml_namespace_element(p: &mut Parser<'_>) {
31613159fn paren_data_source ( p : & mut Parser < ' _ > ) -> Option < CompletedMarker > {
31623160 assert ! ( p. at( L_PAREN ) ) ;
31633161 if p. at ( L_PAREN ) && p. nth_at_ts ( 1 , SELECT_FIRST ) {
3164- return opt_paren_select ( p) ;
3162+ return opt_paren_select ( p, None ) ;
31653163 }
31663164 let m = p. start ( ) ;
31673165 p. bump ( L_PAREN ) ;
@@ -3417,7 +3415,7 @@ fn opt_sequence_options(p: &mut Parser<'_>) -> bool {
34173415
34183416enum ColumnDefKind {
34193417 Name ,
3420- Ref ,
3418+ NameRef ,
34213419 WithData ,
34223420}
34233421
@@ -3469,7 +3467,7 @@ fn column(p: &mut Parser<'_>, kind: &ColumnDefKind) -> CompletedMarker {
34693467 p. eat ( PERIOD_KW ) ;
34703468 match kind {
34713469 ColumnDefKind :: Name => name ( p) ,
3472- ColumnDefKind :: Ref => {
3470+ ColumnDefKind :: NameRef => {
34733471 // supports parsing things like:
34743472 // INSERT INTO tictactoe (game, board[1:3][1:3])
34753473 name_ref ( p) . map ( |lhs| postfix_expr ( p, lhs, true ) ) ;
@@ -3489,7 +3487,7 @@ fn column(p: &mut Parser<'_>, kind: &ColumnDefKind) -> CompletedMarker {
34893487
34903488// [ ( column_name [, ... ] ) ]
34913489fn opt_column_list ( p : & mut Parser < ' _ > ) -> bool {
3492- opt_column_list_with ( p, ColumnDefKind :: Ref )
3490+ opt_column_list_with ( p, ColumnDefKind :: NameRef )
34933491}
34943492
34953493fn column_list ( p : & mut Parser < ' _ > ) {
@@ -5608,7 +5606,7 @@ fn stmt(p: &mut Parser, r: &StmtRestrictions) -> Option<CompletedMarker> {
56085606 ( INSERT_KW , _) => Some ( insert ( p, None ) ) ,
56095607 ( L_PAREN , _) if p. nth_at_ts ( 1 , SELECT_FIRST ) || p. at ( L_PAREN ) => {
56105608 // can have select nested in parens, i.e., ((select 1));
5611- opt_paren_select ( p)
5609+ opt_paren_select ( p, None )
56125610 }
56135611 ( LISTEN_KW , _) => Some ( listen ( p) ) ,
56145612 ( LOAD_KW , _) => Some ( load ( p) ) ,
@@ -12009,7 +12007,7 @@ fn create_schema(p: &mut Parser<'_>) -> CompletedMarker {
1200912007fn query ( p : & mut Parser < ' _ > ) {
1201012008 // TODO: this needs to be more general
1201112009 if ( !p. at_ts ( SELECT_FIRST ) || select ( p, None , & SelectRestrictions :: default ( ) ) . is_none ( ) )
12012- && opt_paren_select ( p) . is_none ( )
12010+ && opt_paren_select ( p, None ) . is_none ( )
1201312011 {
1201412012 p. error ( "expected select stmt" )
1201512013 }
@@ -12111,55 +12109,82 @@ fn insert(p: &mut Parser<'_>, m: Option<Marker>) -> CompletedMarker {
1211112109// ( column_name [, ...] ) = ( sub-SELECT )
1211212110// } [, ...]
1211312111fn set_clause ( p : & mut Parser < ' _ > ) {
12112+ let m = p. start ( ) ;
1211412113 p. expect ( SET_KW ) ;
12115- // TODO: generalize
12116- while !p. at ( EOF ) {
12117- // ( column_name [, ...] ) = [ ROW ] ( { expression | DEFAULT } [, ...] ) |
12118- // ( column_name [, ...] ) = ( sub-SELECT )
12119- if p. eat ( L_PAREN ) {
12120- while !p. at ( EOF ) {
12121- name_ref ( p) . map ( |lhs| postfix_expr ( p, lhs, true ) ) ;
12122- if !p. eat ( COMMA ) {
12123- break ;
12124- }
12125- }
12126- p. expect ( R_PAREN ) ;
12127- p. expect ( EQ ) ;
12128- // [ ROW ] ( { expression | DEFAULT } [, ...] )
12129- // ( sub-SELECT )
12130- let found_row = p. eat ( ROW_KW ) ;
12131- if p. eat ( L_PAREN ) {
12132- // ( sub-SELECT )
12133- if p. at ( SELECT_KW ) && !found_row {
12134- if select ( p, None , & SelectRestrictions :: default ( ) ) . is_none ( ) {
12135- p. error ( "expected sub-SELECT" ) ;
12136- }
12137- } else {
12138- // ( { expression | DEFAULT } [, ...] )
12139- while !p. at ( EOF ) {
12140- if !p. eat ( DEFAULT_KW ) && expr ( p) . is_none ( ) {
12141- p. error ( "expected expression" ) ;
12142- }
12143- if !p. eat ( COMMA ) {
12144- break ;
12145- }
12146- }
12147- }
12148- p. expect ( R_PAREN ) ;
12114+ set_column_list ( p) ;
12115+ m. complete ( p, SET_CLAUSE ) ;
12116+ }
12117+
12118+ fn set_column_list ( p : & mut Parser < ' _ > ) {
12119+ let m = p. start ( ) ;
12120+ separated (
12121+ p,
12122+ COMMA ,
12123+ || "unexpected comma" . to_string ( ) ,
12124+ SET_COLUMN_FIRST ,
12125+ SET_COLUMN_FOLLOW ,
12126+ |p| opt_set_column ( p) . is_some ( ) ,
12127+ ) ;
12128+ m. complete ( p, SET_COLUMN_LIST ) ;
12129+ }
12130+
12131+ const SET_COLUMN_FIRST : TokenSet = TokenSet :: new ( & [ L_PAREN ] ) . union ( COLUMN_FIRST ) ;
12132+ const SET_COLUMN_FOLLOW : TokenSet = TokenSet :: new ( & [ FROM_KW , WHERE_KW , RETURNING_KW ] ) ;
12133+
12134+ fn opt_set_column ( p : & mut Parser < ' _ > ) -> Option < CompletedMarker > {
12135+ if !p. at_ts ( SET_COLUMN_FIRST ) {
12136+ return None ;
12137+ }
12138+ let m = p. start ( ) ;
12139+ // ( column_name [, ...] ) = [ ROW ] ( { expression | DEFAULT } [, ...] ) |
12140+ // ( column_name [, ...] ) = ( sub-SELECT )
12141+ if p. at ( L_PAREN ) {
12142+ column_list ( p) ;
12143+ p. expect ( EQ ) ;
12144+ set_expr_list_or_paren_select ( p) ;
12145+ } else {
12146+ // column_name = { expression | DEFAULT }
12147+ column ( p, & ColumnDefKind :: NameRef ) ;
12148+ p. expect ( EQ ) ;
12149+ set_expr ( p) ;
12150+ }
12151+ Some ( m. complete ( p, SET_COLUMN ) )
12152+ }
12153+
12154+ // [ ROW ] ( { expression | DEFAULT } [, ...] )
12155+ // ( sub-SELECT )
12156+ fn set_expr_list_or_paren_select ( p : & mut Parser < ' _ > ) {
12157+ let m = p. start ( ) ;
12158+ p. eat ( ROW_KW ) ;
12159+ if p. at ( L_PAREN ) {
12160+ if p. nth_at ( 1 , SELECT_KW ) {
12161+ if opt_paren_select ( p, Some ( m) ) . is_none ( ) {
12162+ p. error ( "expected sub-SELECT" ) ;
1214912163 }
12150- // column_name = { expression | DEFAULT }
1215112164 } else {
12152- name_ref ( p) . map ( |lhs| postfix_expr ( p, lhs, true ) ) ;
12153- p. expect ( EQ ) ;
12154- // { expression | DEFAULT }
12155- if !p. eat ( DEFAULT_KW ) && expr ( p) . is_none ( ) {
12156- p. error ( "expected expression" ) ;
12157- }
12165+ set_expr_list ( p, m) ;
1215812166 }
12167+ }
12168+ }
12169+
12170+ fn set_expr_list ( p : & mut Parser < ' _ > , m : Marker ) {
12171+ assert ! ( p. at( L_PAREN ) ) ;
12172+ p. expect ( L_PAREN ) ;
12173+ // ( { expression | DEFAULT } [, ...] )
12174+ while !p. at ( EOF ) {
12175+ set_expr ( p) ;
1215912176 if !p. eat ( COMMA ) {
1216012177 break ;
1216112178 }
1216212179 }
12180+ p. expect ( R_PAREN ) ;
12181+ m. complete ( p, SET_EXPR_LIST ) ;
12182+ }
12183+
12184+ fn set_expr ( p : & mut Parser < ' _ > ) {
12185+ if !p. eat ( DEFAULT_KW ) && expr ( p) . is_none ( ) {
12186+ p. error ( "expected expression" ) ;
12187+ }
1216312188}
1216412189
1216512190fn opt_as_alias ( p : & mut Parser < ' _ > ) -> Option < CompletedMarker > {
0 commit comments