@@ -470,7 +470,7 @@ impl<'a> Parser<'a> {
470470 Keyword :: ANALYZE => Ok ( self . parse_analyze ( ) ?) ,
471471 Keyword :: SELECT | Keyword :: WITH | Keyword :: VALUES => {
472472 self . prev_token ( ) ;
473- Ok ( Statement :: Query ( Box :: new ( self . parse_query ( ) ?) ) )
473+ Ok ( Statement :: Query ( self . parse_boxed_query ( ) ?) )
474474 }
475475 Keyword :: TRUNCATE => Ok ( self . parse_truncate ( ) ?) ,
476476 Keyword :: ATTACH => Ok ( self . parse_attach_database ( ) ?) ,
@@ -530,7 +530,7 @@ impl<'a> Parser<'a> {
530530 } ,
531531 Token :: LParen => {
532532 self . prev_token ( ) ;
533- Ok ( Statement :: Query ( Box :: new ( self . parse_query ( ) ?) ) )
533+ Ok ( Statement :: Query ( self . parse_boxed_query ( ) ?) )
534534 }
535535 _ => self . expected ( "an SQL statement" , next_token) ,
536536 }
@@ -1084,7 +1084,7 @@ impl<'a> Parser<'a> {
10841084 let expr =
10851085 if self . parse_keyword ( Keyword :: SELECT ) || self . parse_keyword ( Keyword :: WITH ) {
10861086 self . prev_token ( ) ;
1087- Expr :: Subquery ( Box :: new ( self . parse_query ( ) ?) )
1087+ Expr :: Subquery ( self . parse_boxed_query ( ) ?)
10881088 } else {
10891089 let exprs = self . parse_comma_separated ( Parser :: parse_expr) ?;
10901090 match exprs. len ( ) {
@@ -1465,7 +1465,7 @@ impl<'a> Parser<'a> {
14651465 self . expect_token ( & Token :: LParen ) ?;
14661466 let exists_node = Expr :: Exists {
14671467 negated,
1468- subquery : Box :: new ( self . parse_query ( ) ?) ,
1468+ subquery : self . parse_boxed_query ( ) ?,
14691469 } ;
14701470 self . expect_token ( & Token :: RParen ) ?;
14711471 Ok ( exists_node)
@@ -1654,9 +1654,9 @@ impl<'a> Parser<'a> {
16541654
16551655 // Parses an array constructed from a subquery
16561656 pub fn parse_array_subquery ( & mut self ) -> Result < Expr , ParserError > {
1657- let query = self . parse_query ( ) ?;
1657+ let query = self . parse_boxed_query ( ) ?;
16581658 self . expect_token ( & Token :: RParen ) ?;
1659- Ok ( Expr :: ArraySubquery ( Box :: new ( query) ) )
1659+ Ok ( Expr :: ArraySubquery ( query) )
16601660 }
16611661
16621662 /// Parse a SQL LISTAGG expression, e.g. `LISTAGG(...) WITHIN GROUP (ORDER BY ...)`.
@@ -2554,7 +2554,7 @@ impl<'a> Parser<'a> {
25542554 self . prev_token ( ) ;
25552555 Expr :: InSubquery {
25562556 expr : Box :: new ( expr) ,
2557- subquery : Box :: new ( self . parse_query ( ) ?) ,
2557+ subquery : self . parse_boxed_query ( ) ?,
25582558 negated,
25592559 }
25602560 } else {
@@ -3637,7 +3637,7 @@ impl<'a> Parser<'a> {
36373637 }
36383638
36393639 self . expect_keyword ( Keyword :: AS ) ?;
3640- let query = Box :: new ( self . parse_query ( ) ?) ;
3640+ let query = self . parse_boxed_query ( ) ?;
36413641 // Optional `WITH [ CASCADED | LOCAL ] CHECK OPTION` is widely supported here.
36423642
36433643 let with_no_schema_binding = dialect_of ! ( self is RedshiftSqlDialect | GenericDialect )
@@ -4032,7 +4032,7 @@ impl<'a> Parser<'a> {
40324032
40334033 self . expect_keyword ( Keyword :: FOR ) ?;
40344034
4035- let query = Some ( Box :: new ( self . parse_query ( ) ?) ) ;
4035+ let query = Some ( self . parse_boxed_query ( ) ?) ;
40364036
40374037 Ok ( Statement :: Declare {
40384038 stmts : vec ! [ Declare {
@@ -4126,7 +4126,7 @@ impl<'a> Parser<'a> {
41264126 match self . peek_token ( ) . token {
41274127 Token :: Word ( w) if w. keyword == Keyword :: SELECT => (
41284128 Some ( DeclareType :: Cursor ) ,
4129- Some ( Box :: new ( self . parse_query ( ) ?) ) ,
4129+ Some ( self . parse_boxed_query ( ) ?) ,
41304130 None ,
41314131 None ,
41324132 ) ,
@@ -4650,7 +4650,7 @@ impl<'a> Parser<'a> {
46504650
46514651 // Parse optional `AS ( query )`
46524652 let query = if self . parse_keyword ( Keyword :: AS ) {
4653- Some ( Box :: new ( self . parse_query ( ) ?) )
4653+ Some ( self . parse_boxed_query ( ) ?)
46544654 } else {
46554655 None
46564656 } ;
@@ -5646,7 +5646,7 @@ impl<'a> Parser<'a> {
56465646 let with_options = self . parse_options ( Keyword :: WITH ) ?;
56475647
56485648 self . expect_keyword ( Keyword :: AS ) ?;
5649- let query = Box :: new ( self . parse_query ( ) ?) ;
5649+ let query = self . parse_boxed_query ( ) ?;
56505650
56515651 Ok ( Statement :: AlterView {
56525652 name,
@@ -5686,7 +5686,7 @@ impl<'a> Parser<'a> {
56865686 pub fn parse_copy ( & mut self ) -> Result < Statement , ParserError > {
56875687 let source;
56885688 if self . consume_token ( & Token :: LParen ) {
5689- source = CopySource :: Query ( Box :: new ( self . parse_query ( ) ?) ) ;
5689+ source = CopySource :: Query ( self . parse_boxed_query ( ) ?) ;
56905690 self . expect_token ( & Token :: RParen ) ?;
56915691 } else {
56925692 let table_name = self . parse_object_name ( false ) ?;
@@ -6910,6 +6910,15 @@ impl<'a> Parser<'a> {
69106910 }
69116911 }
69126912
6913+ /// Call's [`Self::parse_query`] returning a `Box`'ed result.
6914+ ///
6915+ /// This function can be used to reduce the stack size required in debug
6916+ /// builds. Instead of `sizeof(Query)` only a pointer (`Box<Query>`)
6917+ /// is used.
6918+ fn parse_boxed_query ( & mut self ) -> Result < Box < Query > , ParserError > {
6919+ self . parse_query ( ) . map ( Box :: new)
6920+ }
6921+
69136922 /// Parse a query expression, i.e. a `SELECT` statement optionally
69146923 /// preceded with some `WITH` CTE declarations and optionally followed
69156924 /// by `ORDER BY`. Unlike some other parse_... methods, this one doesn't
@@ -6924,13 +6933,10 @@ impl<'a> Parser<'a> {
69246933 } else {
69256934 None
69266935 } ;
6927-
69286936 if self . parse_keyword ( Keyword :: INSERT ) {
6929- let insert = self . parse_insert ( ) ?;
6930-
69316937 Ok ( Query {
69326938 with,
6933- body : Box :: new ( SetExpr :: Insert ( insert ) ) ,
6939+ body : self . parse_insert_setexpr_boxed ( ) ? ,
69346940 limit : None ,
69356941 limit_by : vec ! [ ] ,
69366942 order_by : vec ! [ ] ,
@@ -6940,10 +6946,9 @@ impl<'a> Parser<'a> {
69406946 for_clause : None ,
69416947 } )
69426948 } else if self . parse_keyword ( Keyword :: UPDATE ) {
6943- let update = self . parse_update ( ) ?;
69446949 Ok ( Query {
69456950 with,
6946- body : Box :: new ( SetExpr :: Update ( update ) ) ,
6951+ body : self . parse_update_setexpr_boxed ( ) ? ,
69476952 limit : None ,
69486953 limit_by : vec ! [ ] ,
69496954 order_by : vec ! [ ] ,
@@ -6953,7 +6958,7 @@ impl<'a> Parser<'a> {
69536958 for_clause : None ,
69546959 } )
69556960 } else {
6956- let body = Box :: new ( self . parse_query_body ( 0 ) ?) ;
6961+ let body = self . parse_boxed_query_body ( 0 ) ?;
69576962
69586963 let order_by = if self . parse_keywords ( & [ Keyword :: ORDER , Keyword :: BY ] ) {
69596964 self . parse_comma_separated ( Parser :: parse_order_by_expr) ?
@@ -7143,7 +7148,7 @@ impl<'a> Parser<'a> {
71437148 }
71447149 }
71457150 self . expect_token ( & Token :: LParen ) ?;
7146- let query = Box :: new ( self . parse_query ( ) ?) ;
7151+ let query = self . parse_boxed_query ( ) ?;
71477152 self . expect_token ( & Token :: RParen ) ?;
71487153 let alias = TableAlias {
71497154 name,
@@ -7167,7 +7172,7 @@ impl<'a> Parser<'a> {
71677172 }
71687173 }
71697174 self . expect_token ( & Token :: LParen ) ?;
7170- let query = Box :: new ( self . parse_query ( ) ?) ;
7175+ let query = self . parse_boxed_query ( ) ?;
71717176 self . expect_token ( & Token :: RParen ) ?;
71727177 let alias = TableAlias { name, columns } ;
71737178 Cte {
@@ -7183,6 +7188,15 @@ impl<'a> Parser<'a> {
71837188 Ok ( cte)
71847189 }
71857190
7191+ /// Call's [`Self::parse_query_body`] returning a `Box`'ed result.
7192+ ///
7193+ /// This function can be used to reduce the stack size required in debug
7194+ /// builds. Instead of `sizeof(QueryBody)` only a pointer (`Box<QueryBody>`)
7195+ /// is used.
7196+ fn parse_boxed_query_body ( & mut self , precedence : u8 ) -> Result < Box < SetExpr > , ParserError > {
7197+ self . parse_query_body ( precedence) . map ( Box :: new)
7198+ }
7199+
71867200 /// Parse a "query body", which is an expression with roughly the
71877201 /// following grammar:
71887202 /// ```sql
@@ -7191,16 +7205,19 @@ impl<'a> Parser<'a> {
71917205 /// subquery ::= query_body [ order_by_limit ]
71927206 /// set_operation ::= query_body { 'UNION' | 'EXCEPT' | 'INTERSECT' } [ 'ALL' ] query_body
71937207 /// ```
7208+ ///
7209+ /// If you need `Box<SetExpr>` then maybe there is sense to use `parse_boxed_query_body`
7210+ /// due to prevent stack overflow in debug building(to reserve less memory on stack).
71947211 pub fn parse_query_body ( & mut self , precedence : u8 ) -> Result < SetExpr , ParserError > {
71957212 // We parse the expression using a Pratt parser, as in `parse_expr()`.
71967213 // Start by parsing a restricted SELECT or a `(subquery)`:
71977214 let mut expr = if self . parse_keyword ( Keyword :: SELECT ) {
7198- SetExpr :: Select ( Box :: new ( self . parse_select ( ) ? ) )
7215+ SetExpr :: Select ( self . parse_select ( ) . map ( Box :: new ) ? )
71997216 } else if self . consume_token ( & Token :: LParen ) {
72007217 // CTEs are not allowed here, but the parser currently accepts them
7201- let subquery = self . parse_query ( ) ?;
7218+ let subquery = self . parse_boxed_query ( ) ?;
72027219 self . expect_token ( & Token :: RParen ) ?;
7203- SetExpr :: Query ( Box :: new ( subquery) )
7220+ SetExpr :: Query ( subquery)
72047221 } else if self . parse_keyword ( Keyword :: VALUES ) {
72057222 let is_mysql = dialect_of ! ( self is MySqlDialect ) ;
72067223 SetExpr :: Values ( self . parse_values ( is_mysql) ?)
@@ -7233,7 +7250,7 @@ impl<'a> Parser<'a> {
72337250 left : Box :: new ( expr) ,
72347251 op : op. unwrap ( ) ,
72357252 set_quantifier,
7236- right : Box :: new ( self . parse_query_body ( next_precedence) ?) ,
7253+ right : self . parse_boxed_query_body ( next_precedence) ?,
72377254 } ;
72387255 }
72397256
@@ -8147,7 +8164,7 @@ impl<'a> Parser<'a> {
81478164 & mut self ,
81488165 lateral : IsLateral ,
81498166 ) -> Result < TableFactor , ParserError > {
8150- let subquery = Box :: new ( self . parse_query ( ) ?) ;
8167+ let subquery = self . parse_boxed_query ( ) ?;
81518168 self . expect_token ( & Token :: RParen ) ?;
81528169 let alias = self . parse_optional_table_alias ( keywords:: RESERVED_FOR_TABLE_ALIAS ) ?;
81538170 Ok ( TableFactor :: Derived {
@@ -8395,6 +8412,13 @@ impl<'a> Parser<'a> {
83958412 Ok ( insert. clone ( ) )
83968413 }
83978414
8415+ /// Parse an INSERT statement, returning a `Box`ed SetExpr
8416+ ///
8417+ /// This is used to reduce the size of the stack frames in debug builds
8418+ fn parse_insert_setexpr_boxed ( & mut self ) -> Result < Box < SetExpr > , ParserError > {
8419+ Ok ( Box :: new ( SetExpr :: Insert ( self . parse_insert ( ) ?) ) )
8420+ }
8421+
83988422 /// Parse an INSERT statement
83998423 pub fn parse_insert ( & mut self ) -> Result < Statement , ParserError > {
84008424 let or = if !dialect_of ! ( self is SQLiteDialect ) {
@@ -8445,7 +8469,7 @@ impl<'a> Parser<'a> {
84458469 } else {
84468470 None
84478471 } ;
8448- let source = Box :: new ( self . parse_query ( ) ?) ;
8472+ let source = self . parse_boxed_query ( ) ?;
84498473 Ok ( Statement :: Directory {
84508474 local,
84518475 path,
@@ -8478,7 +8502,7 @@ impl<'a> Parser<'a> {
84788502 // Hive allows you to specify columns after partitions as well if you want.
84798503 let after_columns = self . parse_parenthesized_column_list ( Optional , false ) ?;
84808504
8481- let source = Some ( Box :: new ( self . parse_query ( ) ?) ) ;
8505+ let source = Some ( self . parse_boxed_query ( ) ?) ;
84828506
84838507 ( columns, partitioned, after_columns, source)
84848508 } ;
@@ -8581,6 +8605,13 @@ impl<'a> Parser<'a> {
85818605 }
85828606 }
85838607
8608+ /// Parse an UPDATE statement, returning a `Box`ed SetExpr
8609+ ///
8610+ /// This is used to reduce the size of the stack frames in debug builds
8611+ fn parse_update_setexpr_boxed ( & mut self ) -> Result < Box < SetExpr > , ParserError > {
8612+ Ok ( Box :: new ( SetExpr :: Update ( self . parse_update ( ) ?) ) )
8613+ }
8614+
85848615 pub fn parse_update ( & mut self ) -> Result < Statement , ParserError > {
85858616 let table = self . parse_table_and_joins ( ) ?;
85868617 self . expect_keyword ( Keyword :: SET ) ?;
@@ -8686,11 +8717,11 @@ impl<'a> Parser<'a> {
86868717 . is_some ( )
86878718 {
86888719 self . prev_token ( ) ;
8689- let subquery = self . parse_query ( ) ?;
8720+ let subquery = self . parse_boxed_query ( ) ?;
86908721 self . expect_token ( & Token :: RParen ) ?;
86918722 return Ok ( (
86928723 vec ! [ FunctionArg :: Unnamed ( FunctionArgExpr :: from( Expr :: Subquery (
8693- Box :: new ( subquery) ,
8724+ subquery,
86948725 ) ) ) ] ,
86958726 vec ! [ ] ,
86968727 ) ) ;
@@ -9204,7 +9235,7 @@ impl<'a> Parser<'a> {
92049235
92059236 pub fn parse_unload ( & mut self ) -> Result < Statement , ParserError > {
92069237 self . expect_token ( & Token :: LParen ) ?;
9207- let query = self . parse_query ( ) ?;
9238+ let query = self . parse_boxed_query ( ) ?;
92089239 self . expect_token ( & Token :: RParen ) ?;
92099240
92109241 self . expect_keyword ( Keyword :: TO ) ?;
@@ -9213,7 +9244,7 @@ impl<'a> Parser<'a> {
92139244 let with_options = self . parse_options ( Keyword :: WITH ) ?;
92149245
92159246 Ok ( Statement :: Unload {
9216- query : Box :: new ( query ) ,
9247+ query,
92179248 to,
92189249 with : with_options,
92199250 } )
0 commit comments