@@ -2454,14 +2454,64 @@ pub enum Statement {
24542454 /// Supported variants:
24552455 /// 1. [Hive](https://cwiki.apache.org/confluence/display/hive/languagemanual+ddl#LanguageManualDDL-Create/Drop/ReloadFunction)
24562456 /// 2. [Postgres](https://www.postgresql.org/docs/15/sql-createfunction.html)
2457+ /// 3. [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#create_function_statement)
24572458 CreateFunction {
24582459 or_replace : bool ,
24592460 temporary : bool ,
2461+ if_not_exists : bool ,
24602462 name : ObjectName ,
24612463 args : Option < Vec < OperateFunctionArg > > ,
24622464 return_type : Option < DataType > ,
2463- /// Optional parameters.
2464- params : CreateFunctionBody ,
2465+ /// The expression that defines the function.
2466+ ///
2467+ /// Examples:
2468+ /// ```sql
2469+ /// AS ((SELECT 1))
2470+ /// AS "console.log();"
2471+ /// ```
2472+ function_body : Option < CreateFunctionBody > ,
2473+ /// Behavior attribute for the function
2474+ ///
2475+ /// IMMUTABLE | STABLE | VOLATILE
2476+ ///
2477+ /// [Postgres](https://www.postgresql.org/docs/current/sql-createfunction.html)
2478+ behavior : Option < FunctionBehavior > ,
2479+ /// CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT
2480+ ///
2481+ /// [Postgres](https://www.postgresql.org/docs/current/sql-createfunction.html)
2482+ called_on_null : Option < FunctionCalledOnNull > ,
2483+ /// PARALLEL { UNSAFE | RESTRICTED | SAFE }
2484+ ///
2485+ /// [Postgres](https://www.postgresql.org/docs/current/sql-createfunction.html)
2486+ parallel : Option < FunctionParallel > ,
2487+ /// USING ... (Hive only)
2488+ using : Option < CreateFunctionUsing > ,
2489+ /// Language used in a UDF definition.
2490+ ///
2491+ /// Example:
2492+ /// ```sql
2493+ /// CREATE FUNCTION foo() LANGUAGE js AS "console.log();"
2494+ /// ```
2495+ /// [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#create_a_javascript_udf)
2496+ language : Option < Ident > ,
2497+ /// Determinism keyword used for non-sql UDF definitions.
2498+ ///
2499+ /// [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#syntax_11)
2500+ determinism_specifier : Option < FunctionDeterminismSpecifier > ,
2501+ /// List of options for creating the function.
2502+ ///
2503+ /// [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#syntax_11)
2504+ options : Option < Vec < SqlOption > > ,
2505+ /// Connection resource for a remote function.
2506+ ///
2507+ /// Example:
2508+ /// ```sql
2509+ /// CREATE FUNCTION foo()
2510+ /// RETURNS FLOAT64
2511+ /// REMOTE WITH CONNECTION us.myconnection
2512+ /// ```
2513+ /// [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#create_a_remote_function)
2514+ remote_connection : Option < ObjectName > ,
24652515 } ,
24662516 /// ```sql
24672517 /// CREATE PROCEDURE
@@ -3152,24 +3202,70 @@ impl fmt::Display for Statement {
31523202 Statement :: CreateFunction {
31533203 or_replace,
31543204 temporary,
3205+ if_not_exists,
31553206 name,
31563207 args,
31573208 return_type,
3158- params,
3209+ function_body,
3210+ language,
3211+ behavior,
3212+ called_on_null,
3213+ parallel,
3214+ using,
3215+ determinism_specifier,
3216+ options,
3217+ remote_connection,
31593218 } => {
31603219 write ! (
31613220 f,
3162- "CREATE {or_replace}{temp}FUNCTION {name}" ,
3221+ "CREATE {or_replace}{temp}FUNCTION {if_not_exists}{ name}" ,
31633222 temp = if * temporary { "TEMPORARY " } else { "" } ,
31643223 or_replace = if * or_replace { "OR REPLACE " } else { "" } ,
3224+ if_not_exists = if * if_not_exists { "IF NOT EXISTS " } else { "" } ,
31653225 ) ?;
31663226 if let Some ( args) = args {
31673227 write ! ( f, "({})" , display_comma_separated( args) ) ?;
31683228 }
31693229 if let Some ( return_type) = return_type {
31703230 write ! ( f, " RETURNS {return_type}" ) ?;
31713231 }
3172- write ! ( f, "{params}" ) ?;
3232+ if let Some ( determinism_specifier) = determinism_specifier {
3233+ write ! ( f, " {determinism_specifier}" ) ?;
3234+ }
3235+ if let Some ( language) = language {
3236+ write ! ( f, " LANGUAGE {language}" ) ?;
3237+ }
3238+ if let Some ( behavior) = behavior {
3239+ write ! ( f, " {behavior}" ) ?;
3240+ }
3241+ if let Some ( called_on_null) = called_on_null {
3242+ write ! ( f, " {called_on_null}" ) ?;
3243+ }
3244+ if let Some ( parallel) = parallel {
3245+ write ! ( f, " {parallel}" ) ?;
3246+ }
3247+ if let Some ( remote_connection) = remote_connection {
3248+ write ! ( f, " REMOTE WITH CONNECTION {remote_connection}" ) ?;
3249+ }
3250+ if let Some ( CreateFunctionBody :: AsBeforeOptions ( function_body) ) = function_body {
3251+ write ! ( f, " AS {function_body}" ) ?;
3252+ }
3253+ if let Some ( CreateFunctionBody :: Return ( function_body) ) = function_body {
3254+ write ! ( f, " RETURN {function_body}" ) ?;
3255+ }
3256+ if let Some ( using) = using {
3257+ write ! ( f, " {using}" ) ?;
3258+ }
3259+ if let Some ( options) = options {
3260+ write ! (
3261+ f,
3262+ " OPTIONS({})" ,
3263+ display_comma_separated( options. as_slice( ) )
3264+ ) ?;
3265+ }
3266+ if let Some ( CreateFunctionBody :: AsAfterOptions ( function_body) ) = function_body {
3267+ write ! ( f, " AS {function_body}" ) ?;
3268+ }
31733269 Ok ( ( ) )
31743270 }
31753271 Statement :: CreateProcedure {
@@ -6143,75 +6239,74 @@ impl fmt::Display for FunctionParallel {
61436239 }
61446240}
61456241
6242+ /// [BigQuery] Determinism specifier used in a UDF definition.
6243+ ///
6244+ /// [BigQuery]: https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#syntax_11
61466245#[ derive( Debug , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
61476246#[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
61486247#[ cfg_attr( feature = "visitor" , derive( Visit , VisitMut ) ) ]
6149- pub enum FunctionDefinition {
6150- SingleQuotedDef ( String ) ,
6151- DoubleDollarDef ( String ) ,
6248+ pub enum FunctionDeterminismSpecifier {
6249+ Deterministic ,
6250+ NotDeterministic ,
61526251}
61536252
6154- impl fmt:: Display for FunctionDefinition {
6253+ impl fmt:: Display for FunctionDeterminismSpecifier {
61556254 fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
61566255 match self {
6157- FunctionDefinition :: SingleQuotedDef ( s) => write ! ( f, "'{s}'" ) ?,
6158- FunctionDefinition :: DoubleDollarDef ( s) => write ! ( f, "$${s}$$" ) ?,
6256+ FunctionDeterminismSpecifier :: Deterministic => {
6257+ write ! ( f, "DETERMINISTIC" )
6258+ }
6259+ FunctionDeterminismSpecifier :: NotDeterministic => {
6260+ write ! ( f, "NOT DETERMINISTIC" )
6261+ }
61596262 }
6160- Ok ( ( ) )
61616263 }
61626264}
61636265
6164- /// Postgres specific feature.
6266+ /// Represent the expression body of a `CREATE FUNCTION` statement as well as
6267+ /// where within the statement, the body shows up.
61656268///
6166- /// See [Postgres docs]( https://www.postgresql.org/ docs/15/ sql-createfunction.html)
6167- /// for more details
6168- #[ derive( Debug , Default , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
6269+ /// [BigQuery]: https://cloud.google.com/bigquery/ docs/reference/standard- sql/data-definition-language#syntax_11
6270+ /// [Postgres]: https://www.postgresql.org/docs/15/sql-createfunction.html
6271+ #[ derive( Debug , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
61696272#[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
61706273#[ cfg_attr( feature = "visitor" , derive( Visit , VisitMut ) ) ]
6171- pub struct CreateFunctionBody {
6172- /// LANGUAGE lang_name
6173- pub language : Option < Ident > ,
6174- /// IMMUTABLE | STABLE | VOLATILE
6175- pub behavior : Option < FunctionBehavior > ,
6176- /// CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT
6177- pub called_on_null : Option < FunctionCalledOnNull > ,
6178- /// PARALLEL { UNSAFE | RESTRICTED | SAFE }
6179- pub parallel : Option < FunctionParallel > ,
6180- /// AS 'definition'
6274+ pub enum CreateFunctionBody {
6275+ /// A function body expression using the 'AS' keyword and shows up
6276+ /// before any `OPTIONS` clause.
61816277 ///
6182- /// Note that Hive's `AS class_name` is also parsed here.
6183- pub as_ : Option < FunctionDefinition > ,
6184- /// RETURN expression
6185- pub return_ : Option < Expr > ,
6186- /// USING ... (Hive only)
6187- pub using : Option < CreateFunctionUsing > ,
6188- }
6189-
6190- impl fmt:: Display for CreateFunctionBody {
6191- fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
6192- if let Some ( language) = & self . language {
6193- write ! ( f, " LANGUAGE {language}" ) ?;
6194- }
6195- if let Some ( behavior) = & self . behavior {
6196- write ! ( f, " {behavior}" ) ?;
6197- }
6198- if let Some ( called_on_null) = & self . called_on_null {
6199- write ! ( f, " {called_on_null}" ) ?;
6200- }
6201- if let Some ( parallel) = & self . parallel {
6202- write ! ( f, " {parallel}" ) ?;
6203- }
6204- if let Some ( definition) = & self . as_ {
6205- write ! ( f, " AS {definition}" ) ?;
6206- }
6207- if let Some ( expr) = & self . return_ {
6208- write ! ( f, " RETURN {expr}" ) ?;
6209- }
6210- if let Some ( using) = & self . using {
6211- write ! ( f, " {using}" ) ?;
6212- }
6213- Ok ( ( ) )
6214- }
6278+ /// Example:
6279+ /// ```sql
6280+ /// CREATE FUNCTION myfunc(x FLOAT64, y FLOAT64) RETURNS FLOAT64
6281+ /// AS (x * y)
6282+ /// OPTIONS(description="desc");
6283+ /// ```
6284+ ///
6285+ /// [BigQuery]: https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#syntax_11
6286+ AsBeforeOptions ( Expr ) ,
6287+ /// A function body expression using the 'AS' keyword and shows up
6288+ /// after any `OPTIONS` clause.
6289+ ///
6290+ /// Example:
6291+ /// ```sql
6292+ /// CREATE FUNCTION myfunc(x FLOAT64, y FLOAT64) RETURNS FLOAT64
6293+ /// OPTIONS(description="desc")
6294+ /// AS (x * y);
6295+ /// ```
6296+ ///
6297+ /// [BigQuery]: https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#syntax_11
6298+ AsAfterOptions ( Expr ) ,
6299+ /// Function body expression using the 'RETURN' keyword.
6300+ ///
6301+ /// Example:
6302+ /// ```sql
6303+ /// CREATE FUNCTION myfunc(a INTEGER, IN b INTEGER = 1) RETURNS INTEGER
6304+ /// LANGUAGE SQL
6305+ /// RETURN a + b;
6306+ /// ```
6307+ ///
6308+ /// [Postgres]: https://www.postgresql.org/docs/current/sql-createfunction.html
6309+ Return ( Expr ) ,
62156310}
62166311
62176312#[ derive( Debug , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
0 commit comments