@@ -2454,14 +2454,64 @@ pub enum Statement {
2454
2454
/// Supported variants:
2455
2455
/// 1. [Hive](https://cwiki.apache.org/confluence/display/hive/languagemanual+ddl#LanguageManualDDL-Create/Drop/ReloadFunction)
2456
2456
/// 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)
2457
2458
CreateFunction {
2458
2459
or_replace : bool ,
2459
2460
temporary : bool ,
2461
+ if_not_exists : bool ,
2460
2462
name : ObjectName ,
2461
2463
args : Option < Vec < OperateFunctionArg > > ,
2462
2464
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 > ,
2465
2515
} ,
2466
2516
/// ```sql
2467
2517
/// CREATE PROCEDURE
@@ -3152,24 +3202,70 @@ impl fmt::Display for Statement {
3152
3202
Statement :: CreateFunction {
3153
3203
or_replace,
3154
3204
temporary,
3205
+ if_not_exists,
3155
3206
name,
3156
3207
args,
3157
3208
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,
3159
3218
} => {
3160
3219
write ! (
3161
3220
f,
3162
- "CREATE {or_replace}{temp}FUNCTION {name}" ,
3221
+ "CREATE {or_replace}{temp}FUNCTION {if_not_exists}{ name}" ,
3163
3222
temp = if * temporary { "TEMPORARY " } else { "" } ,
3164
3223
or_replace = if * or_replace { "OR REPLACE " } else { "" } ,
3224
+ if_not_exists = if * if_not_exists { "IF NOT EXISTS " } else { "" } ,
3165
3225
) ?;
3166
3226
if let Some ( args) = args {
3167
3227
write ! ( f, "({})" , display_comma_separated( args) ) ?;
3168
3228
}
3169
3229
if let Some ( return_type) = return_type {
3170
3230
write ! ( f, " RETURNS {return_type}" ) ?;
3171
3231
}
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
+ }
3173
3269
Ok ( ( ) )
3174
3270
}
3175
3271
Statement :: CreateProcedure {
@@ -6143,75 +6239,74 @@ impl fmt::Display for FunctionParallel {
6143
6239
}
6144
6240
}
6145
6241
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
6146
6245
#[ derive( Debug , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
6147
6246
#[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
6148
6247
#[ 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 ,
6152
6251
}
6153
6252
6154
- impl fmt:: Display for FunctionDefinition {
6253
+ impl fmt:: Display for FunctionDeterminismSpecifier {
6155
6254
fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
6156
6255
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
+ }
6159
6262
}
6160
- Ok ( ( ) )
6161
6263
}
6162
6264
}
6163
6265
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.
6165
6268
///
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 ) ]
6169
6272
#[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
6170
6273
#[ 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.
6181
6277
///
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 ) ,
6215
6310
}
6216
6311
6217
6312
#[ derive( Debug , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
0 commit comments