@@ -4102,6 +4102,101 @@ impl fmt::Display for FunctionReturnType {
41024102 }
41034103}
41044104
4105+ /// A `HEADERS` entry in a Snowflake external function definition.
4106+ #[ derive( Debug , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
4107+ #[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
4108+ #[ cfg_attr( feature = "visitor" , derive( Visit , VisitMut ) ) ]
4109+ pub struct ExternalFunctionHeader {
4110+ /// Header-name string literal.
4111+ pub name : ValueWithSpan ,
4112+ /// Header-value string literal.
4113+ pub value : ValueWithSpan ,
4114+ }
4115+
4116+ impl fmt:: Display for ExternalFunctionHeader {
4117+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
4118+ write ! ( f, "{} = {}" , self . name, self . value)
4119+ }
4120+ }
4121+
4122+ /// Compression mode for a Snowflake external function request.
4123+ #[ derive( Debug , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
4124+ #[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
4125+ #[ cfg_attr( feature = "visitor" , derive( Visit , VisitMut ) ) ]
4126+ pub enum ExternalFunctionCompression {
4127+ /// No compression.
4128+ None ,
4129+ /// Gzip compression.
4130+ Gzip ,
4131+ /// Deflate compression.
4132+ Deflate ,
4133+ /// Compression selected automatically.
4134+ Auto ,
4135+ }
4136+
4137+ impl fmt:: Display for ExternalFunctionCompression {
4138+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
4139+ match self {
4140+ Self :: None => write ! ( f, "NONE" ) ,
4141+ Self :: Gzip => write ! ( f, "GZIP" ) ,
4142+ Self :: Deflate => write ! ( f, "DEFLATE" ) ,
4143+ Self :: Auto => write ! ( f, "AUTO" ) ,
4144+ }
4145+ }
4146+ }
4147+
4148+ /// Snowflake-specific parameters for `CREATE EXTERNAL FUNCTION`.
4149+ #[ derive( Debug , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
4150+ #[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
4151+ #[ cfg_attr( feature = "visitor" , derive( Visit , VisitMut ) ) ]
4152+ pub struct ExternalFunctionParams {
4153+ /// Whether the return type has a `NOT NULL` annotation.
4154+ pub return_not_null : bool ,
4155+ /// API integration used to invoke the remote endpoint.
4156+ pub api_integration : ObjectName ,
4157+ /// Custom HTTP headers.
4158+ pub headers : Option < Vec < ExternalFunctionHeader > > ,
4159+ /// Context function names forwarded as headers.
4160+ pub context_headers : Option < Vec < Ident > > ,
4161+ /// Maximum rows per request batch.
4162+ pub max_batch_rows : Option < u64 > ,
4163+ /// Request compression mode.
4164+ pub compression : Option < ExternalFunctionCompression > ,
4165+ /// Optional request translator function.
4166+ pub request_translator : Option < ObjectName > ,
4167+ /// Optional response translator function.
4168+ pub response_translator : Option < ObjectName > ,
4169+ }
4170+
4171+ impl fmt:: Display for ExternalFunctionParams {
4172+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
4173+ write ! ( f, "API_INTEGRATION = {}" , self . api_integration) ?;
4174+ if let Some ( headers) = & self . headers {
4175+ write ! ( f, " HEADERS = ({})" , display_comma_separated( headers) ) ?;
4176+ }
4177+ if let Some ( context_headers) = & self . context_headers {
4178+ write ! (
4179+ f,
4180+ " CONTEXT_HEADERS = ({})" ,
4181+ display_comma_separated( context_headers)
4182+ ) ?;
4183+ }
4184+ if let Some ( max_batch_rows) = self . max_batch_rows {
4185+ write ! ( f, " MAX_BATCH_ROWS = {max_batch_rows}" ) ?;
4186+ }
4187+ if let Some ( compression) = & self . compression {
4188+ write ! ( f, " COMPRESSION = {compression}" ) ?;
4189+ }
4190+ if let Some ( request_translator) = & self . request_translator {
4191+ write ! ( f, " REQUEST_TRANSLATOR = {request_translator}" ) ?;
4192+ }
4193+ if let Some ( response_translator) = & self . response_translator {
4194+ write ! ( f, " RESPONSE_TRANSLATOR = {response_translator}" ) ?;
4195+ }
4196+ Ok ( ( ) )
4197+ }
4198+ }
4199+
41054200#[ derive( Debug , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
41064201#[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
41074202#[ cfg_attr( feature = "visitor" , derive( Visit , VisitMut ) ) ]
@@ -4185,16 +4280,23 @@ pub struct CreateFunction {
41854280 /// ```
41864281 /// [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#create_a_remote_function)
41874282 pub remote_connection : Option < ObjectName > ,
4283+ /// Snowflake external-function parameters.
4284+ pub external_params : Option < ExternalFunctionParams > ,
41884285}
41894286
41904287impl fmt:: Display for CreateFunction {
41914288 fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
41924289 write ! (
41934290 f,
4194- "CREATE {or_alter}{or_replace}{temp}{secure}{data_metric}FUNCTION {if_not_exists}{name}" ,
4291+ "CREATE {or_alter}{or_replace}{temp}{secure}{external}{ data_metric}FUNCTION {if_not_exists}{name}" ,
41954292 name = self . name,
41964293 temp = if self . temporary { "TEMPORARY " } else { "" } ,
41974294 secure = if self . secure { "SECURE " } else { "" } ,
4295+ external = if self . external_params. is_some( ) {
4296+ "EXTERNAL "
4297+ } else {
4298+ ""
4299+ } ,
41984300 data_metric = if self . data_metric { "DATA METRIC " } else { "" } ,
41994301 or_alter = if self . or_alter { "OR ALTER " } else { "" } ,
42004302 or_replace = if self . or_replace { "OR REPLACE " } else { "" } ,
@@ -4210,6 +4312,32 @@ impl fmt::Display for CreateFunction {
42104312 if let Some ( return_type) = & self . return_type {
42114313 write ! ( f, " RETURNS {return_type}" ) ?;
42124314 }
4315+ if let Some ( external) = & self . external_params {
4316+ if external. return_not_null {
4317+ write ! ( f, " NOT NULL" ) ?;
4318+ }
4319+ if let Some ( called_on_null) = & self . called_on_null {
4320+ write ! ( f, " {called_on_null}" ) ?;
4321+ }
4322+ if let Some ( behavior) = & self . behavior {
4323+ write ! ( f, " {behavior}" ) ?;
4324+ }
4325+ if let Some ( options) = & self . options {
4326+ for option in options {
4327+ write ! ( f, " {option}" ) ?;
4328+ }
4329+ }
4330+ write ! ( f, " {external}" ) ?;
4331+ if let Some ( CreateFunctionBody :: AsBeforeOptions { body, link_symbol } ) =
4332+ & self . function_body
4333+ {
4334+ write ! ( f, " AS {body}" ) ?;
4335+ if let Some ( link_symbol) = link_symbol {
4336+ write ! ( f, ", {link_symbol}" ) ?;
4337+ }
4338+ }
4339+ return Ok ( ( ) ) ;
4340+ }
42134341 if let Some ( determinism_specifier) = & self . determinism_specifier {
42144342 write ! ( f, " {determinism_specifier}" ) ?;
42154343 }
0 commit comments