@@ -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,63 @@ trait RelParser {
7681 }
7782 }
7883
84+ /// Parse a function call
85+ fn parse_func_call ( name : SqlIdent , args : Vec < FunctionArg > ) -> SqlParseResult < SqlFuncCall > {
86+ if args. is_empty ( ) {
87+ return Err ( SqlUnsupported :: TableFunctionNoParams ( name. 0 . into ( ) ) . into ( ) ) ;
88+ }
89+ let 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 { name, args } )
100+ }
101+
79102 /// Parse a table reference in a FROM clause
80- fn parse_relvar ( expr : TableFactor ) -> SqlParseResult < ( SqlIdent , SqlIdent ) > {
103+ fn parse_relvar ( expr : TableFactor ) -> SqlParseResult < SqlFromSource > {
81104 match expr {
82105 // Relvar no alias
83106 TableFactor :: Table {
84107 name,
85108 alias : None ,
86- args : None ,
109+ args,
87110 with_hints,
88111 version : None ,
89112 partitions,
90113 } if with_hints. is_empty ( ) && partitions. is_empty ( ) => {
91114 let name = parse_ident ( name) ?;
92115 let alias = name. clone ( ) ;
93- Ok ( ( name, alias) )
116+
117+ if let Some ( args) = args {
118+ Ok ( SqlFromSource :: FuncCall ( Self :: parse_func_call ( name, args) ?, alias) )
119+ } else {
120+ Ok ( SqlFromSource :: Expr ( name, alias) )
121+ }
94122 }
95123 // Relvar with alias
96124 TableFactor :: Table {
97125 name,
98126 alias : Some ( TableAlias { name : alias, columns } ) ,
99- args : None ,
127+ args,
100128 with_hints,
101129 version : None ,
102130 partitions,
103131 } if with_hints. is_empty ( ) && partitions. is_empty ( ) && columns. is_empty ( ) => {
104- Ok ( ( parse_ident ( name) ?, alias. into ( ) ) )
132+ let args = args. filter ( |v| !v. is_empty ( ) ) ;
133+ if let Some ( args) = args {
134+ Ok ( SqlFromSource :: FuncCall (
135+ Self :: parse_func_call ( parse_ident ( name) ?, args) ?,
136+ alias. into ( ) ,
137+ ) )
138+ } else {
139+ Ok ( SqlFromSource :: Expr ( parse_ident ( name) ?, alias. into ( ) ) )
140+ }
105141 }
106142 _ => Err ( SqlUnsupported :: From ( expr) . into ( ) ) ,
107143 }
0 commit comments