@@ -31,7 +31,7 @@ pub mod statement;
3131pub ( crate ) fn type_select ( input : RelExpr , expr : SqlExpr , vars : & Relvars ) -> TypingResult < RelExpr > {
3232 Ok ( RelExpr :: Select (
3333 Box :: new ( input) ,
34- type_expr ( vars, expr, Some ( & AlgebraicType :: Bool ) , & mut 0 ) ?,
34+ type_expr ( vars, expr, Some ( & AlgebraicType :: Bool ) ) ?,
3535 ) )
3636}
3737
@@ -69,7 +69,7 @@ pub(crate) fn type_proj(input: RelExpr, proj: ast::Project, vars: &Relvars) -> T
6969 return Err ( DuplicateName ( alias. into_string ( ) ) . into ( ) ) ;
7070 }
7171
72- if let Expr :: Field ( p) = type_expr ( vars, expr. into ( ) , None , & mut 0 ) ? {
72+ if let Expr :: Field ( p) = type_expr ( vars, expr. into ( ) , None ) ? {
7373 projections. push ( ( alias, p) ) ;
7474 }
7575 }
@@ -79,13 +79,12 @@ pub(crate) fn type_proj(input: RelExpr, proj: ast::Project, vars: &Relvars) -> T
7979 }
8080}
8181
82- /// Type check and lower a [SqlExpr] into a logical [Expr].
83- pub ( crate ) fn type_expr (
84- vars : & Relvars ,
85- expr : SqlExpr ,
86- expected : Option < & AlgebraicType > ,
87- depth : & mut usize ,
88- ) -> TypingResult < Expr > {
82+ // These types determine the size of each stack frame during type checking.
83+ // Changing their sizes will require updating the recursion limit to avoid stack overflows.
84+ const _: ( ) = assert ! ( size_of:: <TypingResult <Expr >>( ) == 64 ) ;
85+ const _: ( ) = assert ! ( size_of:: <SqlExpr >( ) == 40 ) ;
86+
87+ fn _type_expr ( vars : & Relvars , expr : SqlExpr , expected : Option < & AlgebraicType > , depth : usize ) -> TypingResult < Expr > {
8988 recursion:: guard ( depth, recursion:: MAX_RECURSION_TYP_EXPR , "expr::type_expr" ) ?;
9089
9190 match ( expr, expected) {
@@ -125,21 +124,21 @@ pub(crate) fn type_expr(
125124 } ) )
126125 }
127126 ( SqlExpr :: Log ( a, b, op) , None | Some ( AlgebraicType :: Bool ) ) => {
128- let a = type_expr ( vars, * a, Some ( & AlgebraicType :: Bool ) , depth) ?;
129- let b = type_expr ( vars, * b, Some ( & AlgebraicType :: Bool ) , depth) ?;
127+ let a = _type_expr ( vars, * a, Some ( & AlgebraicType :: Bool ) , depth + 1 ) ?;
128+ let b = _type_expr ( vars, * b, Some ( & AlgebraicType :: Bool ) , depth + 1 ) ?;
130129 Ok ( Expr :: LogOp ( op, Box :: new ( a) , Box :: new ( b) ) )
131130 }
132131 ( SqlExpr :: Bin ( a, b, op) , None | Some ( AlgebraicType :: Bool ) ) if matches ! ( & * a, SqlExpr :: Lit ( _) ) => {
133- let b = type_expr ( vars, * b, None , depth) ?;
134- let a = type_expr ( vars, * a, Some ( b. ty ( ) ) , depth) ?;
132+ let b = _type_expr ( vars, * b, None , depth + 1 ) ?;
133+ let a = _type_expr ( vars, * a, Some ( b. ty ( ) ) , depth + 1 ) ?;
135134 if !op_supports_type ( op, a. ty ( ) ) {
136135 return Err ( InvalidOp :: new ( op, a. ty ( ) ) . into ( ) ) ;
137136 }
138137 Ok ( Expr :: BinOp ( op, Box :: new ( a) , Box :: new ( b) ) )
139138 }
140139 ( SqlExpr :: Bin ( a, b, op) , None | Some ( AlgebraicType :: Bool ) ) => {
141- let a = type_expr ( vars, * a, None , depth) ?;
142- let b = type_expr ( vars, * b, Some ( a. ty ( ) ) , depth) ?;
140+ let a = _type_expr ( vars, * a, None , depth + 1 ) ?;
141+ let b = _type_expr ( vars, * b, Some ( a. ty ( ) ) , depth + 1 ) ?;
143142 if !op_supports_type ( op, a. ty ( ) ) {
144143 return Err ( InvalidOp :: new ( op, a. ty ( ) ) . into ( ) ) ;
145144 }
@@ -152,6 +151,11 @@ pub(crate) fn type_expr(
152151 }
153152}
154153
154+ /// Type check and lower a [SqlExpr] into a logical [Expr].
155+ pub ( crate ) fn type_expr ( vars : & Relvars , expr : SqlExpr , expected : Option < & AlgebraicType > ) -> TypingResult < Expr > {
156+ _type_expr ( vars, expr, expected, 0 )
157+ }
158+
155159/// Is this type compatible with this binary operator?
156160fn op_supports_type ( _op : BinOp , t : & AlgebraicType ) -> bool {
157161 t. is_bool ( )
0 commit comments