@@ -6,7 +6,8 @@ use sqlparser::ast::{
66} ;
77
88use crate :: ast:: {
9- BinOp , LogOp , Parameter , Project , ProjectElem , ProjectExpr , SqlExpr , SqlFrom , SqlIdent , SqlJoin , SqlLiteral ,
9+ BinOp , LogOp , Parameter , Project , ProjectElem , ProjectExpr , SqlExpr , SqlFrom , SqlFromSource , SqlFuncCall , SqlIdent ,
10+ SqlJoin , SqlLiteral ,
1011} ;
1112
1213pub mod errors;
@@ -34,11 +35,15 @@ trait RelParser {
3435 return Err ( SqlUnsupported :: ImplicitJoins . into ( ) ) ;
3536 }
3637 let TableWithJoins { relation, joins } = tables. swap_remove ( 0 ) ;
37- let ( name, alias) = Self :: parse_relvar ( relation) ?;
38- if joins. is_empty ( ) {
39- return Ok ( SqlFrom :: Expr ( name, alias) ) ;
38+ match Self :: parse_relvar ( relation) ? {
39+ SqlFromSource :: Expr ( name, alias) => {
40+ if joins. is_empty ( ) {
41+ return Ok ( SqlFrom :: Expr ( name, alias) ) ;
42+ }
43+ Ok ( SqlFrom :: Join ( name, alias, Self :: parse_joins ( joins) ?) )
44+ }
45+ SqlFromSource :: FuncCall ( func_call, alias) => Ok ( SqlFrom :: FuncCall ( func_call, alias) ) ,
4046 }
41- Ok ( SqlFrom :: Join ( name, alias, Self :: parse_joins ( joins) ?) )
4247 }
4348
4449 /// Parse a sequence of JOIN clauses
@@ -48,10 +53,11 @@ trait RelParser {
4853
4954 /// Parse a single JOIN clause
5055 fn parse_join ( join : Join ) -> SqlParseResult < SqlJoin > {
51- let ( var, alias) = Self :: parse_relvar ( join. relation ) ?;
56+ let from = Self :: parse_relvar ( join. relation ) ?;
57+
5258 match join. join_operator {
53- JoinOperator :: CrossJoin => Ok ( SqlJoin { var , alias , on : None } ) ,
54- JoinOperator :: Inner ( JoinConstraint :: None ) => Ok ( SqlJoin { var , alias , on : None } ) ,
59+ JoinOperator :: CrossJoin => Ok ( SqlJoin { from , on : None } ) ,
60+ JoinOperator :: Inner ( JoinConstraint :: None ) => Ok ( SqlJoin { from , on : None } ) ,
5561 JoinOperator :: Inner ( JoinConstraint :: On ( Expr :: BinaryOp {
5662 left,
5763 op : BinaryOperator :: Eq ,
@@ -60,8 +66,7 @@ trait RelParser {
6066 && matches ! ( * right, Expr :: Identifier ( ..) | Expr :: CompoundIdentifier ( ..) ) =>
6167 {
6268 Ok ( SqlJoin {
63- var,
64- alias,
69+ from,
6570 on : Some ( parse_expr (
6671 Expr :: BinaryOp {
6772 left,
@@ -76,32 +81,66 @@ trait RelParser {
7681 }
7782 }
7883
84+ /// Parse a function call
85+ fn parse_func_call ( func_name : SqlIdent , args : Vec < FunctionArg > ) -> SqlParseResult < SqlFuncCall > {
86+ if args. is_empty ( ) {
87+ return Err ( SqlUnsupported :: TableFunctionNoParams ( func_name. 0 . into ( ) ) . into ( ) ) ;
88+ }
89+ let func_args = args
90+ . into_iter ( )
91+ . map ( |arg| match arg. clone ( ) {
92+ FunctionArg :: Unnamed ( FunctionArgExpr :: Expr ( expr) ) => match parse_expr ( expr, 0 ) {
93+ Ok ( SqlExpr :: Lit ( lit) ) => Ok ( lit) ,
94+ _ => Err ( SqlUnsupported :: FuncArg ( arg) . into ( ) ) ,
95+ } ,
96+ _ => Err ( SqlUnsupported :: FuncArg ( arg. clone ( ) ) . into ( ) ) ,
97+ } )
98+ . collect :: < SqlParseResult < _ > > ( ) ?;
99+ Ok ( SqlFuncCall {
100+ name : func_name,
101+ args : func_args,
102+ } )
103+ }
104+
79105 /// Parse a table reference in a FROM clause
80- fn parse_relvar ( expr : TableFactor ) -> SqlParseResult < ( SqlIdent , SqlIdent ) > {
106+ fn parse_relvar ( expr : TableFactor ) -> SqlParseResult < SqlFromSource > {
81107 match expr {
82108 // Relvar no alias
83109 TableFactor :: Table {
84110 name,
85111 alias : None ,
86- args : None ,
112+ args,
87113 with_hints,
88114 version : None ,
89115 partitions,
90116 } if with_hints. is_empty ( ) && partitions. is_empty ( ) => {
91117 let name = parse_ident ( name) ?;
92118 let alias = name. clone ( ) ;
93- Ok ( ( name, alias) )
119+
120+ if let Some ( args) = args {
121+ Ok ( SqlFromSource :: FuncCall ( Self :: parse_func_call ( name, args) ?, alias) )
122+ } else {
123+ Ok ( SqlFromSource :: Expr ( name, alias) )
124+ }
94125 }
95126 // Relvar with alias
96127 TableFactor :: Table {
97128 name,
98129 alias : Some ( TableAlias { name : alias, columns } ) ,
99- args : None ,
130+ args,
100131 with_hints,
101132 version : None ,
102133 partitions,
103134 } if with_hints. is_empty ( ) && partitions. is_empty ( ) && columns. is_empty ( ) => {
104- Ok ( ( parse_ident ( name) ?, alias. into ( ) ) )
135+ let args = args. filter ( |v| !v. is_empty ( ) ) ;
136+ if let Some ( args) = args {
137+ Ok ( SqlFromSource :: FuncCall (
138+ Self :: parse_func_call ( parse_ident ( name) ?, args) ?,
139+ alias. into ( ) ,
140+ ) )
141+ } else {
142+ Ok ( SqlFromSource :: Expr ( parse_ident ( name) ?, alias. into ( ) ) )
143+ }
105144 }
106145 _ => Err ( SqlUnsupported :: From ( expr) . into ( ) ) ,
107146 }
0 commit comments