@@ -2399,14 +2399,64 @@ pub enum Statement {
23992399 /// Supported variants:
24002400 /// 1. [Hive](https://cwiki.apache.org/confluence/display/hive/languagemanual+ddl#LanguageManualDDL-Create/Drop/ReloadFunction)
24012401 /// 2. [Postgres](https://www.postgresql.org/docs/15/sql-createfunction.html)
2402+ /// 3. [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#create_function_statement)
24022403 CreateFunction {
24032404 or_replace : bool ,
24042405 temporary : bool ,
2406+ if_not_exists : bool ,
24052407 name : ObjectName ,
24062408 args : Option < Vec < OperateFunctionArg > > ,
24072409 return_type : Option < DataType > ,
2408- /// Optional parameters.
2409- params : CreateFunctionBody ,
2410+ /// The expression that defines the function.
2411+ ///
2412+ /// Examples:
2413+ /// ```sql
2414+ /// AS ((SELECT 1))
2415+ /// AS "console.log();"
2416+ /// ```
2417+ function_body : Option < CreateFunctionBody > ,
2418+ /// Behavior attribute for the function
2419+ ///
2420+ /// IMMUTABLE | STABLE | VOLATILE
2421+ ///
2422+ /// [Postgres](https://www.postgresql.org/docs/current/sql-createfunction.html)
2423+ behavior : Option < FunctionBehavior > ,
2424+ /// CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT
2425+ ///
2426+ /// [Postgres](https://www.postgresql.org/docs/current/sql-createfunction.html)
2427+ called_on_null : Option < FunctionCalledOnNull > ,
2428+ /// PARALLEL { UNSAFE | RESTRICTED | SAFE }
2429+ ///
2430+ /// [Postgres](https://www.postgresql.org/docs/current/sql-createfunction.html)
2431+ parallel : Option < FunctionParallel > ,
2432+ /// USING ... (Hive only)
2433+ using : Option < CreateFunctionUsing > ,
2434+ /// Language used in a UDF definition.
2435+ ///
2436+ /// Example:
2437+ /// ```sql
2438+ /// CREATE FUNCTION foo() LANGUAGE js AS "console.log();"
2439+ /// ```
2440+ /// [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#create_a_javascript_udf)
2441+ language : Option < Ident > ,
2442+ /// Determinism keyword used for non-sql UDF definitions.
2443+ ///
2444+ /// [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#syntax_11)
2445+ determinism_specifier : Option < FunctionDeterminismSpecifier > ,
2446+ /// List of options for creating the function.
2447+ ///
2448+ /// [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#syntax_11)
2449+ options : Option < Vec < SqlOption > > ,
2450+ /// Connection resource for a remote function.
2451+ ///
2452+ /// Example:
2453+ /// ```sql
2454+ /// CREATE FUNCTION foo()
2455+ /// RETURNS FLOAT64
2456+ /// REMOTE WITH CONNECTION us.myconnection
2457+ /// ```
2458+ /// [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#create_a_remote_function)
2459+ remote_connection : Option < ObjectName > ,
24102460 } ,
24112461 /// ```sql
24122462 /// CREATE PROCEDURE
@@ -3097,24 +3147,70 @@ impl fmt::Display for Statement {
30973147 Statement :: CreateFunction {
30983148 or_replace,
30993149 temporary,
3150+ if_not_exists,
31003151 name,
31013152 args,
31023153 return_type,
3103- params,
3154+ function_body,
3155+ language,
3156+ behavior,
3157+ called_on_null,
3158+ parallel,
3159+ using,
3160+ determinism_specifier,
3161+ options,
3162+ remote_connection,
31043163 } => {
31053164 write ! (
31063165 f,
3107- "CREATE {or_replace}{temp}FUNCTION {name}" ,
3166+ "CREATE {or_replace}{temp}FUNCTION {if_not_exists}{ name}" ,
31083167 temp = if * temporary { "TEMPORARY " } else { "" } ,
31093168 or_replace = if * or_replace { "OR REPLACE " } else { "" } ,
3169+ if_not_exists = if * if_not_exists { "IF NOT EXISTS " } else { "" } ,
31103170 ) ?;
31113171 if let Some ( args) = args {
31123172 write ! ( f, "({})" , display_comma_separated( args) ) ?;
31133173 }
31143174 if let Some ( return_type) = return_type {
31153175 write ! ( f, " RETURNS {return_type}" ) ?;
31163176 }
3117- write ! ( f, "{params}" ) ?;
3177+ if let Some ( determinism_specifier) = determinism_specifier {
3178+ write ! ( f, " {determinism_specifier}" ) ?;
3179+ }
3180+ if let Some ( language) = language {
3181+ write ! ( f, " LANGUAGE {language}" ) ?;
3182+ }
3183+ if let Some ( behavior) = behavior {
3184+ write ! ( f, " {behavior}" ) ?;
3185+ }
3186+ if let Some ( called_on_null) = called_on_null {
3187+ write ! ( f, " {called_on_null}" ) ?;
3188+ }
3189+ if let Some ( parallel) = parallel {
3190+ write ! ( f, " {parallel}" ) ?;
3191+ }
3192+ if let Some ( remote_connection) = remote_connection {
3193+ write ! ( f, " REMOTE WITH CONNECTION {remote_connection}" ) ?;
3194+ }
3195+ if let Some ( CreateFunctionBody :: AsBeforeOptions ( function_body) ) = function_body {
3196+ write ! ( f, " AS {function_body}" ) ?;
3197+ }
3198+ if let Some ( CreateFunctionBody :: Return ( function_body) ) = function_body {
3199+ write ! ( f, " RETURN {function_body}" ) ?;
3200+ }
3201+ if let Some ( using) = using {
3202+ write ! ( f, " {using}" ) ?;
3203+ }
3204+ if let Some ( options) = options {
3205+ write ! (
3206+ f,
3207+ " OPTIONS({})" ,
3208+ display_comma_separated( options. as_slice( ) )
3209+ ) ?;
3210+ }
3211+ if let Some ( CreateFunctionBody :: AsAfterOptions ( function_body) ) = function_body {
3212+ write ! ( f, " AS {function_body}" ) ?;
3213+ }
31183214 Ok ( ( ) )
31193215 }
31203216 Statement :: CreateProcedure {
@@ -6041,75 +6137,74 @@ impl fmt::Display for FunctionParallel {
60416137 }
60426138}
60436139
6140+ /// [BigQuery] Determinism specifier used in a UDF definition.
6141+ ///
6142+ /// [BigQuery]: https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#syntax_11
60446143#[ derive( Debug , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
60456144#[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
60466145#[ cfg_attr( feature = "visitor" , derive( Visit , VisitMut ) ) ]
6047- pub enum FunctionDefinition {
6048- SingleQuotedDef ( String ) ,
6049- DoubleDollarDef ( String ) ,
6146+ pub enum FunctionDeterminismSpecifier {
6147+ Deterministic ,
6148+ NotDeterministic ,
60506149}
60516150
6052- impl fmt:: Display for FunctionDefinition {
6151+ impl fmt:: Display for FunctionDeterminismSpecifier {
60536152 fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
60546153 match self {
6055- FunctionDefinition :: SingleQuotedDef ( s) => write ! ( f, "'{s}'" ) ?,
6056- FunctionDefinition :: DoubleDollarDef ( s) => write ! ( f, "$${s}$$" ) ?,
6154+ FunctionDeterminismSpecifier :: Deterministic => {
6155+ write ! ( f, "DETERMINISTIC" )
6156+ }
6157+ FunctionDeterminismSpecifier :: NotDeterministic => {
6158+ write ! ( f, "NOT DETERMINISTIC" )
6159+ }
60576160 }
6058- Ok ( ( ) )
60596161 }
60606162}
60616163
6062- /// Postgres specific feature.
6164+ /// Represent the expression body of a `CREATE FUNCTION` statement as well as
6165+ /// where within the statement, the body shows up.
60636166///
6064- /// See [Postgres docs]( https://www.postgresql.org/ docs/15/ sql-createfunction.html)
6065- /// for more details
6066- #[ derive( Debug , Default , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
6167+ /// [BigQuery]: https://cloud.google.com/bigquery/ docs/reference/standard- sql/data-definition-language#syntax_11
6168+ /// [Postgres]: https://www.postgresql.org/docs/15/sql-createfunction.html
6169+ #[ derive( Debug , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
60676170#[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
60686171#[ cfg_attr( feature = "visitor" , derive( Visit , VisitMut ) ) ]
6069- pub struct CreateFunctionBody {
6070- /// LANGUAGE lang_name
6071- pub language : Option < Ident > ,
6072- /// IMMUTABLE | STABLE | VOLATILE
6073- pub behavior : Option < FunctionBehavior > ,
6074- /// CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT
6075- pub called_on_null : Option < FunctionCalledOnNull > ,
6076- /// PARALLEL { UNSAFE | RESTRICTED | SAFE }
6077- pub parallel : Option < FunctionParallel > ,
6078- /// AS 'definition'
6172+ pub enum CreateFunctionBody {
6173+ /// A function body expression using the 'AS' keyword and shows up
6174+ /// before any `OPTIONS` clause.
60796175 ///
6080- /// Note that Hive's `AS class_name` is also parsed here.
6081- pub as_ : Option < FunctionDefinition > ,
6082- /// RETURN expression
6083- pub return_ : Option < Expr > ,
6084- /// USING ... (Hive only)
6085- pub using : Option < CreateFunctionUsing > ,
6086- }
6087-
6088- impl fmt:: Display for CreateFunctionBody {
6089- fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
6090- if let Some ( language) = & self . language {
6091- write ! ( f, " LANGUAGE {language}" ) ?;
6092- }
6093- if let Some ( behavior) = & self . behavior {
6094- write ! ( f, " {behavior}" ) ?;
6095- }
6096- if let Some ( called_on_null) = & self . called_on_null {
6097- write ! ( f, " {called_on_null}" ) ?;
6098- }
6099- if let Some ( parallel) = & self . parallel {
6100- write ! ( f, " {parallel}" ) ?;
6101- }
6102- if let Some ( definition) = & self . as_ {
6103- write ! ( f, " AS {definition}" ) ?;
6104- }
6105- if let Some ( expr) = & self . return_ {
6106- write ! ( f, " RETURN {expr}" ) ?;
6107- }
6108- if let Some ( using) = & self . using {
6109- write ! ( f, " {using}" ) ?;
6110- }
6111- Ok ( ( ) )
6112- }
6176+ /// Example:
6177+ /// ```sql
6178+ /// CREATE FUNCTION myfunc(x FLOAT64, y FLOAT64) RETURNS FLOAT64
6179+ /// AS (x * y)
6180+ /// OPTIONS(description="desc");
6181+ /// ```
6182+ ///
6183+ /// [BigQuery]: https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#syntax_11
6184+ AsBeforeOptions ( Expr ) ,
6185+ /// A function body expression using the 'AS' keyword and shows up
6186+ /// after any `OPTIONS` clause.
6187+ ///
6188+ /// Example:
6189+ /// ```sql
6190+ /// CREATE FUNCTION myfunc(x FLOAT64, y FLOAT64) RETURNS FLOAT64
6191+ /// OPTIONS(description="desc")
6192+ /// AS (x * y);
6193+ /// ```
6194+ ///
6195+ /// [BigQuery]: https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#syntax_11
6196+ AsAfterOptions ( Expr ) ,
6197+ /// Function body expression using the 'RETURN' keyword.
6198+ ///
6199+ /// Example:
6200+ /// ```sql
6201+ /// CREATE FUNCTION myfunc(a INTEGER, IN b INTEGER = 1) RETURNS INTEGER
6202+ /// LANGUAGE SQL
6203+ /// RETURN a + b;
6204+ /// ```
6205+ ///
6206+ /// [Postgres]: https://www.postgresql.org/docs/current/sql-createfunction.html
6207+ Return ( Expr ) ,
61136208}
61146209
61156210#[ derive( Debug , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
0 commit comments