@@ -2399,14 +2399,64 @@ pub enum Statement {
2399
2399
/// Supported variants:
2400
2400
/// 1. [Hive](https://cwiki.apache.org/confluence/display/hive/languagemanual+ddl#LanguageManualDDL-Create/Drop/ReloadFunction)
2401
2401
/// 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)
2402
2403
CreateFunction {
2403
2404
or_replace : bool ,
2404
2405
temporary : bool ,
2406
+ if_not_exists : bool ,
2405
2407
name : ObjectName ,
2406
2408
args : Option < Vec < OperateFunctionArg > > ,
2407
2409
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 > ,
2410
2460
} ,
2411
2461
/// ```sql
2412
2462
/// CREATE PROCEDURE
@@ -3097,24 +3147,70 @@ impl fmt::Display for Statement {
3097
3147
Statement :: CreateFunction {
3098
3148
or_replace,
3099
3149
temporary,
3150
+ if_not_exists,
3100
3151
name,
3101
3152
args,
3102
3153
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,
3104
3163
} => {
3105
3164
write ! (
3106
3165
f,
3107
- "CREATE {or_replace}{temp}FUNCTION {name}" ,
3166
+ "CREATE {or_replace}{temp}FUNCTION {if_not_exists}{ name}" ,
3108
3167
temp = if * temporary { "TEMPORARY " } else { "" } ,
3109
3168
or_replace = if * or_replace { "OR REPLACE " } else { "" } ,
3169
+ if_not_exists = if * if_not_exists { "IF NOT EXISTS " } else { "" } ,
3110
3170
) ?;
3111
3171
if let Some ( args) = args {
3112
3172
write ! ( f, "({})" , display_comma_separated( args) ) ?;
3113
3173
}
3114
3174
if let Some ( return_type) = return_type {
3115
3175
write ! ( f, " RETURNS {return_type}" ) ?;
3116
3176
}
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
+ }
3118
3214
Ok ( ( ) )
3119
3215
}
3120
3216
Statement :: CreateProcedure {
@@ -6041,75 +6137,74 @@ impl fmt::Display for FunctionParallel {
6041
6137
}
6042
6138
}
6043
6139
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
6044
6143
#[ derive( Debug , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
6045
6144
#[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
6046
6145
#[ 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 ,
6050
6149
}
6051
6150
6052
- impl fmt:: Display for FunctionDefinition {
6151
+ impl fmt:: Display for FunctionDeterminismSpecifier {
6053
6152
fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
6054
6153
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
+ }
6057
6160
}
6058
- Ok ( ( ) )
6059
6161
}
6060
6162
}
6061
6163
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.
6063
6166
///
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 ) ]
6067
6170
#[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
6068
6171
#[ 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.
6079
6175
///
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 ) ,
6113
6208
}
6114
6209
6115
6210
#[ derive( Debug , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
0 commit comments