@@ -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,20 @@ 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) => {
46+ if !joins. is_empty ( ) {
47+ return Err ( SqlUnsupported :: FunctionJoin . into ( ) ) ;
48+ }
49+ Ok ( SqlFrom :: FuncCall ( func_call, alias) )
50+ }
4051 }
41- Ok ( SqlFrom :: Join ( name, alias, Self :: parse_joins ( joins) ?) )
4252 }
4353
4454 /// Parse a sequence of JOIN clauses
@@ -48,7 +58,12 @@ trait RelParser {
4858
4959 /// Parse a single JOIN clause
5060 fn parse_join ( join : Join ) -> SqlParseResult < SqlJoin > {
51- let ( var, alias) = Self :: parse_relvar ( join. relation ) ?;
61+ let ( var, alias) = if let SqlFromSource :: Expr ( var, alias) = Self :: parse_relvar ( join. relation ) ? {
62+ ( var, alias)
63+ } else {
64+ return Err ( SqlUnsupported :: FunctionJoin . into ( ) ) ;
65+ } ;
66+
5267 match join. join_operator {
5368 JoinOperator :: CrossJoin => Ok ( SqlJoin { var, alias, on : None } ) ,
5469 JoinOperator :: Inner ( JoinConstraint :: None ) => Ok ( SqlJoin { var, alias, on : None } ) ,
@@ -76,32 +91,63 @@ trait RelParser {
7691 }
7792 }
7893
94+ fn parse_func_call ( func_name : SqlIdent , args : Vec < FunctionArg > ) -> SqlParseResult < SqlFuncCall > {
95+ let func_args = args
96+ . into_iter ( )
97+ . map ( |arg| match arg. clone ( ) {
98+ FunctionArg :: Unnamed ( FunctionArgExpr :: Expr ( expr) ) => match parse_expr ( expr, 0 ) {
99+ Ok ( SqlExpr :: Lit ( lit) ) => Ok ( lit) ,
100+ _ => Err ( SqlUnsupported :: FuncArg ( arg) . into ( ) ) ,
101+ } ,
102+ _ => Err ( SqlUnsupported :: FuncArg ( arg. clone ( ) ) . into ( ) ) ,
103+ } )
104+ . collect :: < SqlParseResult < _ > > ( ) ?;
105+ Ok ( SqlFuncCall {
106+ name : func_name,
107+ args : func_args,
108+ } )
109+ }
110+
79111 /// Parse a table reference in a FROM clause
80- fn parse_relvar ( expr : TableFactor ) -> SqlParseResult < ( SqlIdent , SqlIdent ) > {
112+ fn parse_relvar ( expr : TableFactor ) -> SqlParseResult < SqlFromSource > {
81113 match expr {
82114 // Relvar no alias
83115 TableFactor :: Table {
84116 name,
85117 alias : None ,
86- args : None ,
118+ args,
87119 with_hints,
88120 version : None ,
89121 partitions,
90122 } if with_hints. is_empty ( ) && partitions. is_empty ( ) => {
91123 let name = parse_ident ( name) ?;
92124 let alias = name. clone ( ) ;
93- Ok ( ( name, alias) )
125+ if let Some ( args) = args {
126+ Ok ( SqlFromSource :: FuncCall (
127+ Self :: parse_func_call ( name, args) ?,
128+ alias. into ( ) ,
129+ ) )
130+ } else {
131+ Ok ( SqlFromSource :: Expr ( name, alias) )
132+ }
94133 }
95134 // Relvar with alias
96135 TableFactor :: Table {
97136 name,
98137 alias : Some ( TableAlias { name : alias, columns } ) ,
99- args : None ,
138+ args,
100139 with_hints,
101140 version : None ,
102141 partitions,
103142 } if with_hints. is_empty ( ) && partitions. is_empty ( ) && columns. is_empty ( ) => {
104- Ok ( ( parse_ident ( name) ?, alias. into ( ) ) )
143+ if let Some ( args) = args {
144+ Ok ( SqlFromSource :: FuncCall (
145+ Self :: parse_func_call ( parse_ident ( name) ?, args) ?,
146+ alias. into ( ) ,
147+ ) )
148+ } else {
149+ Ok ( SqlFromSource :: Expr ( parse_ident ( name) ?, alias. into ( ) ) )
150+ }
105151 }
106152 _ => Err ( SqlUnsupported :: From ( expr) . into ( ) ) ,
107153 }
0 commit comments