From fbe0a414989941ae93fb402e06a7e827132e8858 Mon Sep 17 00:00:00 2001 From: Michael Xu Date: Fri, 12 Jan 2024 14:37:34 -0500 Subject: [PATCH 1/7] fix(sql-udf): correctly binding arguments for inner calling sql udfs --- e2e_test/udf/sql_udf.slt | 35 +++++++++++++ src/frontend/src/binder/expr/column.rs | 2 +- src/frontend/src/binder/expr/function.rs | 66 +++++++++++++++--------- src/frontend/src/binder/expr/mod.rs | 2 +- src/frontend/src/binder/mod.rs | 15 ++++-- 5 files changed, 90 insertions(+), 30 deletions(-) diff --git a/e2e_test/udf/sql_udf.slt b/e2e_test/udf/sql_udf.slt index 02fc23b2d7f02..717a1cf23a829 100644 --- a/e2e_test/udf/sql_udf.slt +++ b/e2e_test/udf/sql_udf.slt @@ -64,6 +64,19 @@ select fib(100); statement error function fib calling stack depth limit exceeded create materialized view foo_mv as select fib(100); +statement ok +create function regexp_replace_wrapper(varchar) returns varchar language sql as $$select regexp_replace($1, 'baz(...)', '这是🥵', 'ic')$$; + +statement ok +create function print(INT) returns int language sql as 'select $1'; + +# Adjust the input value of the calling function (i.e., `print` here) with the actual input parameter +statement ok +create function print_add_one(INT) returns int language sql as 'select print($1 + 1)'; + +statement ok +create function print_add_two(INT) returns int language sql as 'select print($1 + $1)'; + # Call the defined sql udf query I select add(1, -1); @@ -100,6 +113,11 @@ select call_regexp_replace(); ---- 💩💩💩💩💩foo🤔️bar亲爱的😭这是🥵爱情❤️‍🔥 +query T +select regexp_replace_wrapper('💩💩💩💩💩foo🤔️bar亲爱的😭baz这不是爱情❤️‍🔥'); +---- +💩💩💩💩💩foo🤔️bar亲爱的😭这是🥵爱情❤️‍🔥 + query T select foo(114514); ---- @@ -118,6 +136,11 @@ select add_sub_wrapper(1, 1); ---- 114514 +query III +select print_add_one(1), print_add_one(114513), print_add_two(2); +---- +2 114514 4 + # Create a mock table statement ok create table t1 (c1 INT, c2 INT); @@ -251,6 +274,18 @@ drop function add_sub_types; statement ok drop function fib; +statement ok +drop function print; + +statement ok +drop function print_add_one; + +statement ok +drop function print_add_two; + +statement ok +drop function regexp_replace_wrapper; + # Drop the mock table statement ok drop table t1; diff --git a/src/frontend/src/binder/expr/column.rs b/src/frontend/src/binder/expr/column.rs index cac4f7eccd62e..139b9e065303c 100644 --- a/src/frontend/src/binder/expr/column.rs +++ b/src/frontend/src/binder/expr/column.rs @@ -46,7 +46,7 @@ impl Binder { // If so, we will treat this bind as an special bind, the actual expression // stored in `udf_context` will then be bound instead of binding the non-existing column. if let Some(expr) = self.udf_context.get_expr(&column_name) { - return self.bind_expr(expr.clone()); + return Ok(expr.clone()); } match self diff --git a/src/frontend/src/binder/expr/function.rs b/src/frontend/src/binder/expr/function.rs index de4f0f4aa6331..6aeea9949fb12 100644 --- a/src/frontend/src/binder/expr/function.rs +++ b/src/frontend/src/binder/expr/function.rs @@ -258,31 +258,47 @@ impl Binder { // We can safely unwrap here let ast = parse_result.unwrap(); - let mut clean_flag = true; - - // We need to check if the `udf_context` is empty first, consider the following example: - // - create function add(INT, INT) returns int language sql as 'select $1 + $2'; - // - create function add_wrapper(INT, INT) returns int language sql as 'select add($1, $2)'; - // - select add_wrapper(1, 1); - // When binding `add($1, $2)` in `add_wrapper`, the input args are [$1, $2] instead of - // the original [1, 1], thus we need to check `udf_context` to see if the input - // args already exist in the context. If so, we do NOT need to create the context again. - // Otherwise the current `udf_context` will be corrupted. + let mut clean_flag = false; + + // We need to check if the `udf_context` is empty first, + // If so, we will clear the `udf_context` after binding. + // Since this is the root (top-most) binding for sql udf. + // Otherwise we need to restore the context later, or the + // original `udf_context` will be corrupted. if self.udf_context.is_empty() { - // The actual inline logic for sql udf - if let Ok(context) = create_udf_context(&args, &Arc::clone(func)) { - self.udf_context.update_context(context); - } else { - return Err(ErrorCode::InvalidInputSyntax( - "failed to create the `udf_context`, please recheck your function definition and syntax".to_string() - ) - .into()); + clean_flag = true; + } + + // Stash the current `udf_context` + let stashed_udf_context = self.udf_context.get_context(); + + // The actual inline logic for sql udf + // Note that we will always create new udf context for each sql udf + if let Ok(context) = create_udf_context(&args, &Arc::clone(func)) { + let mut udf_context = HashMap::new(); + for (c, e) in context { + // Note that we need to bind the args before actual delve in the function body + // This will update the context in the subsequent inner calling function + // e.g., + // - create function print(INT) returns int language sql as 'select $1'; + // - create function print_add_one(INT) returns int language sql as 'select print($1 + 1)'; + // - select print_add_one(1); # The result should be 2 instead of 1. + // Without the pre-binding here, the ($1 + 1) will not be correctly populated, + // causing the result to always be 1. + let Ok(e) = self.bind_expr(e) else { + return Err(ErrorCode::BindError(format!( + "failed to bind the argument, please recheck the syntax" + )) + .into()); + }; + udf_context.insert(c, e); } + self.udf_context.update_context(udf_context); } else { - // If the `udf_context` is not empty, this means the current binding - // function is not the root binding sql udf, thus we should NOT - // clean the context after binding. - clean_flag = false; + return Err(ErrorCode::InvalidInputSyntax( + "failed to create the `udf_context`, please recheck your function definition and syntax".to_string() + ) + .into()); } // Check for potential recursive calling @@ -299,10 +315,14 @@ impl Binder { if let Ok(expr) = extract_udf_expression(ast) { let bind_result = self.bind_expr(expr); - // Clean the `udf_context` & `udf_recursive_context` after inlining, + // Clean the `udf_context` after inlining, // which makes sure the subsequent binding will not be affected if clean_flag { self.udf_context.clear(); + } else { + // Restore context information for subsequent binding + // Since this is not the root binding sql udf + self.udf_context.update_context(stashed_udf_context); } return bind_result; } else { diff --git a/src/frontend/src/binder/expr/mod.rs b/src/frontend/src/binder/expr/mod.rs index 1b3dcd5dd051c..fedf2aacdd9cd 100644 --- a/src/frontend/src/binder/expr/mod.rs +++ b/src/frontend/src/binder/expr/mod.rs @@ -383,7 +383,7 @@ impl Binder { // parameters will be parsed and treated as `Parameter`. // For detailed explanation, consider checking `bind_column`. if let Some(expr) = self.udf_context.get_expr(&format!("${index}")) { - return self.bind_expr(expr.clone()); + return Ok(expr.clone()); } Ok(Parameter::new(index, self.param_types.clone()).into()) diff --git a/src/frontend/src/binder/mod.rs b/src/frontend/src/binder/mod.rs index 51b53d23a2e3f..6b3830ea2ce09 100644 --- a/src/frontend/src/binder/mod.rs +++ b/src/frontend/src/binder/mod.rs @@ -21,7 +21,7 @@ use risingwave_common::error::Result; use risingwave_common::session_config::{ConfigMap, SearchPath}; use risingwave_common::types::DataType; use risingwave_common::util::iter_util::ZipEqDebug; -use risingwave_sqlparser::ast::{Expr as AstExpr, Statement}; +use risingwave_sqlparser::ast::Statement; mod bind_context; mod bind_param; @@ -59,6 +59,7 @@ pub use values::BoundValues; use crate::catalog::catalog_service::CatalogReadGuard; use crate::catalog::schema_catalog::SchemaCatalog; use crate::catalog::{CatalogResult, TableId, ViewId}; +use crate::expr::ExprImpl; use crate::session::{AuthContext, SessionImpl}; pub type ShareId = usize; @@ -122,9 +123,9 @@ pub struct Binder { #[derive(Clone, Debug, Default)] pub struct UdfContext { - /// The mapping from `sql udf parameters` to `ast expressions` + /// The mapping from `sql udf parameters` to a bound `ExprImpl` generated from `ast expressions` /// Note: The expressions are constructed during runtime, correspond to the actual users' input - udf_param_context: HashMap, + udf_param_context: HashMap, /// The global counter that records the calling stack depth /// of the current binding sql udf chain @@ -151,7 +152,7 @@ impl UdfContext { self.udf_param_context.is_empty() } - pub fn update_context(&mut self, context: HashMap) { + pub fn update_context(&mut self, context: HashMap) { self.udf_param_context = context; } @@ -160,9 +161,13 @@ impl UdfContext { self.udf_param_context.clear(); } - pub fn get_expr(&self, name: &str) -> Option<&AstExpr> { + pub fn get_expr(&self, name: &str) -> Option<&ExprImpl> { self.udf_param_context.get(name) } + + pub fn get_context(&self) -> HashMap { + self.udf_param_context.clone() + } } /// `ParameterTypes` is used to record the types of the parameters during binding. It works From 8ce02de445300d9512def729e341040defdab8fe Mon Sep 17 00:00:00 2001 From: Michael Xu Date: Fri, 12 Jan 2024 16:37:09 -0500 Subject: [PATCH 2/7] feat(sql-udf): add semantic check when creating sql udf --- e2e_test/udf/sql_udf.slt | 48 ++++++----- src/frontend/src/binder/mod.rs | 4 + .../src/handler/create_sql_function.rs | 80 ++++++++++++++++++- 3 files changed, 109 insertions(+), 23 deletions(-) diff --git a/e2e_test/udf/sql_udf.slt b/e2e_test/udf/sql_udf.slt index 717a1cf23a829..4b4d1f1c39f7d 100644 --- a/e2e_test/udf/sql_udf.slt +++ b/e2e_test/udf/sql_udf.slt @@ -28,12 +28,12 @@ create function add_return(INT, INT) returns int language sql return $1 + $2; statement ok create function add_return_binding() returns int language sql return add_return(1, 1) + add_return(1, 1); -# Recursive definition can be accepted, but will be eventually rejected during runtime -statement ok +# Recursive definition can NOT be accepted at present due to semantic check +statement error failed to conduct semantic check, please see if you are calling non-existence functions create function recursive(INT, INT) returns int language sql as 'select recursive($1, $2) + recursive($1, $2)'; # Complex but error-prone definition, recursive & normal sql udfs interleaving -statement ok +statement error failed to conduct semantic check, please see if you are calling non-existence functions create function recursive_non_recursive(INT, INT) returns int language sql as 'select recursive($1, $2) + sub($1, $2)'; # Recursive corner case @@ -46,7 +46,7 @@ create function add_sub_wrapper(INT, INT) returns int language sql as 'select ad # Create a valid recursive function # Please note we do NOT support actual running the recursive sql udf at present -statement ok +statement error failed to conduct semantic check, please see if you are calling non-existence functions create function fib(INT) returns int language sql as 'select case when $1 = 0 then 0 @@ -57,12 +57,12 @@ create function fib(INT) returns int end;'; # The execution will eventually exceed the pre-defined max stack depth -statement error function fib calling stack depth limit exceeded -select fib(100); +# statement error function fib calling stack depth limit exceeded +# select fib(100); # Currently create a materialized view with a recursive sql udf will be rejected -statement error function fib calling stack depth limit exceeded -create materialized view foo_mv as select fib(100); +# statement error function fib calling stack depth limit exceeded +# create materialized view foo_mv as select fib(100); statement ok create function regexp_replace_wrapper(varchar) returns varchar language sql as $$select regexp_replace($1, 'baz(...)', '这是🥵', 'ic')$$; @@ -77,6 +77,10 @@ create function print_add_one(INT) returns int language sql as 'select print($1 statement ok create function print_add_two(INT) returns int language sql as 'select print($1 + $1)'; +# Calling a non-existence function +statement error failed to conduct semantic check, please see if you are calling non-existence functions +create function non_exist(INT) returns int language sql as 'select yo(114514)'; + # Call the defined sql udf query I select add(1, -1); @@ -124,12 +128,12 @@ select foo(114514); foo(INT) # Rejected deep calling stack -statement error function recursive calling stack depth limit exceeded -select recursive(1, 1); +# statement error function recursive calling stack depth limit exceeded +# select recursive(1, 1); # Same as above -statement error function recursive calling stack depth limit exceeded -select recursive_non_recursive(1, 1); +# statement error function recursive calling stack depth limit exceeded +# select recursive_non_recursive(1, 1); query I select add_sub_wrapper(1, 1); @@ -168,12 +172,12 @@ select c1, c2, add_return(c1, c2) from t1 order by c1 asc; 5 5 10 # Recursive sql udf with normal table -statement error function fib calling stack depth limit exceeded -select fib(c1) from t1; +# statement error function fib calling stack depth limit exceeded +# select fib(c1) from t1; # Recursive sql udf with materialized view -statement error function fib calling stack depth limit exceeded -create materialized view bar_mv as select fib(c1) from t1; +# statement error function fib calling stack depth limit exceeded +# create materialized view bar_mv as select fib(c1) from t1; # Invalid function body syntax statement error Expected an expression:, found: EOF at the end @@ -259,20 +263,20 @@ drop function call_regexp_replace; statement ok drop function add_sub_wrapper; -statement ok -drop function recursive; +# statement ok +# drop function recursive; statement ok drop function foo; -statement ok -drop function recursive_non_recursive; +# statement ok +# drop function recursive_non_recursive; statement ok drop function add_sub_types; -statement ok -drop function fib; +# statement ok +# drop function fib; statement ok drop function print; diff --git a/src/frontend/src/binder/mod.rs b/src/frontend/src/binder/mod.rs index 6b3830ea2ce09..317f67acddd85 100644 --- a/src/frontend/src/binder/mod.rs +++ b/src/frontend/src/binder/mod.rs @@ -415,6 +415,10 @@ impl Binder { pub fn set_clause(&mut self, clause: Option) { self.context.clause = clause; } + + pub fn get_udf_context(&mut self) -> &mut UdfContext { + &mut self.udf_context + } } /// The column name stored in [`BindContext`] for a column without an alias. diff --git a/src/frontend/src/handler/create_sql_function.rs b/src/frontend/src/handler/create_sql_function.rs index bbe504d779bfd..2469ea63cd428 100644 --- a/src/frontend/src/handler/create_sql_function.rs +++ b/src/frontend/src/handler/create_sql_function.rs @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +use std::collections::HashMap; + use itertools::Itertools; use pgwire::pg_response::StatementType; use risingwave_common::catalog::FunctionId; @@ -25,8 +27,59 @@ use risingwave_sqlparser::parser::{Parser, ParserError}; use super::*; use crate::catalog::CatalogError; +use crate::expr::{ExprImpl, Literal}; use crate::{bind_data_type, Binder}; +/// Create a mock `udf_context`, which is used for semantic check +fn create_mock_udf_context(arg_types: Vec) -> HashMap { + (1..=arg_types.len()) + .map(|i| { + let mock_expr = ExprImpl::Literal(Box::new(Literal::new(None, arg_types[i - 1].clone()))); + (format!("${i}"), mock_expr.clone()) + }) + .collect() +} + +fn extract_udf_expression(ast: Vec) -> Result { + if ast.len() != 1 { + return Err(ErrorCode::InvalidInputSyntax( + "the query for sql udf should contain only one statement".to_string(), + ) + .into()); + } + + // Extract the expression out + let Statement::Query(query) = ast[0].clone() else { + return Err(ErrorCode::InvalidInputSyntax( + "invalid function definition, please recheck the syntax".to_string(), + ) + .into()); + }; + + let SetExpr::Select(select) = query.body else { + return Err(ErrorCode::InvalidInputSyntax( + "missing `select` body for sql udf expression, please recheck the syntax".to_string(), + ) + .into()); + }; + + if select.projection.len() != 1 { + return Err(ErrorCode::InvalidInputSyntax( + "`projection` should contain only one `SelectItem`".to_string(), + ) + .into()); + } + + let SelectItem::UnnamedExpr(expr) = select.projection[0].clone() else { + return Err(ErrorCode::InvalidInputSyntax( + "expect `UnnamedExpr` for `projection`".to_string(), + ) + .into()); + }; + + Ok(expr) +} + pub async fn handle_create_sql_function( handler_args: HandlerArgs, or_replace: bool, @@ -45,7 +98,8 @@ pub async fn handle_create_sql_function( } let language = "sql".to_string(); - // Just a basic sanity check for language + + // Just a basic sanity check for `language` if !matches!(params.language, Some(lang) if lang.real_value().to_lowercase() == "sql") { return Err(ErrorCode::InvalidParameterValue( "`language` for sql udf must be `sql`".to_string(), @@ -147,6 +201,30 @@ pub async fn handle_create_sql_function( return Err(ErrorCode::InvalidInputSyntax(err).into()); } else { debug_assert!(parse_result.is_ok()); + + // Conduct semantic check (e.g., see if the inner calling functions exist, etc.) + let ast = parse_result.unwrap(); + let mut binder = Binder::new_for_system(&session); + + binder + .get_udf_context() + .update_context(create_mock_udf_context(arg_types.clone())); + + if let Ok(expr) = extract_udf_expression(ast) { + if let Err(e) = binder.bind_expr(expr) { + return Err(ErrorCode::InvalidInputSyntax( + format!("failed to conduct semantic check, please see if you are calling non-existence functions.\nDetailed error: {}", e.to_string()) + ) + .into()); + } + } else { + return Err(ErrorCode::InvalidInputSyntax( + "failed to parse the input query and extract the udf expression, + please recheck the syntax" + .to_string(), + ) + .into()); + } } // Create the actual function, will be stored in function catalog From 829e0deeb58313c1dc5dcedfa75e35eedbd1624d Mon Sep 17 00:00:00 2001 From: Michael Xu Date: Fri, 12 Jan 2024 16:41:41 -0500 Subject: [PATCH 3/7] fix check --- src/frontend/src/binder/expr/function.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/frontend/src/binder/expr/function.rs b/src/frontend/src/binder/expr/function.rs index 6aeea9949fb12..1de98cea6febc 100644 --- a/src/frontend/src/binder/expr/function.rs +++ b/src/frontend/src/binder/expr/function.rs @@ -286,9 +286,10 @@ impl Binder { // Without the pre-binding here, the ($1 + 1) will not be correctly populated, // causing the result to always be 1. let Ok(e) = self.bind_expr(e) else { - return Err(ErrorCode::BindError(format!( + return Err(ErrorCode::BindError( "failed to bind the argument, please recheck the syntax" - )) + .to_string(), + ) .into()); }; udf_context.insert(c, e); From 4cdb0c0d743e37e331d9b7dd9b37587573de3377 Mon Sep 17 00:00:00 2001 From: Michael Xu Date: Wed, 17 Jan 2024 09:43:08 -0500 Subject: [PATCH 4/7] restore code --- src/frontend/src/binder/expr/function.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/frontend/src/binder/expr/function.rs b/src/frontend/src/binder/expr/function.rs index 054a7b00567b1..c0ffc86cd5ebe 100644 --- a/src/frontend/src/binder/expr/function.rs +++ b/src/frontend/src/binder/expr/function.rs @@ -272,6 +272,25 @@ impl Binder { "failed to create the `udf_context`, please recheck your function definition and syntax".to_string() ) .into()); + }; + + let mut udf_context = HashMap::new(); + for (c, e) in context { + // Note that we need to bind the args before actual delve in the function body + // This will update the context in the subsequent inner calling function + // e.g., + // - create function print(INT) returns int language sql as 'select $1'; + // - create function print_add_one(INT) returns int language sql as 'select print($1 + 1)'; + // - select print_add_one(1); # The result should be 2 instead of 1. + // Without the pre-binding here, the ($1 + 1) will not be correctly populated, + // causing the result to always be 1. + let Ok(e) = self.bind_expr(e) else { + return Err(ErrorCode::BindError( + "failed to bind the argument, please recheck the syntax".to_string(), + ) + .into()); + }; + udf_context.insert(c, e); } self.udf_context.update_context(udf_context); From 07b2bb034f63b7b7d6558d1282b8ce23cdeac7c9 Mon Sep 17 00:00:00 2001 From: Michael Xu Date: Wed, 17 Jan 2024 09:47:06 -0500 Subject: [PATCH 5/7] fix check --- src/frontend/src/handler/create_sql_function.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/frontend/src/handler/create_sql_function.rs b/src/frontend/src/handler/create_sql_function.rs index 2469ea63cd428..8124a7e5e6e53 100644 --- a/src/frontend/src/handler/create_sql_function.rs +++ b/src/frontend/src/handler/create_sql_function.rs @@ -34,10 +34,11 @@ use crate::{bind_data_type, Binder}; fn create_mock_udf_context(arg_types: Vec) -> HashMap { (1..=arg_types.len()) .map(|i| { - let mock_expr = ExprImpl::Literal(Box::new(Literal::new(None, arg_types[i - 1].clone()))); + let mock_expr = + ExprImpl::Literal(Box::new(Literal::new(None, arg_types[i - 1].clone()))); (format!("${i}"), mock_expr.clone()) - }) - .collect() + }) + .collect() } fn extract_udf_expression(ast: Vec) -> Result { From f8c2a1679823f706f39038d6c21ab50777cfcfe1 Mon Sep 17 00:00:00 2001 From: Michael Xu Date: Wed, 17 Jan 2024 10:14:26 -0500 Subject: [PATCH 6/7] tiny update --- e2e_test/udf/sql_udf.slt | 25 ------------------- .../src/handler/create_sql_function.rs | 4 +-- 2 files changed, 2 insertions(+), 27 deletions(-) diff --git a/e2e_test/udf/sql_udf.slt b/e2e_test/udf/sql_udf.slt index d8c3762504deb..4b4d1f1c39f7d 100644 --- a/e2e_test/udf/sql_udf.slt +++ b/e2e_test/udf/sql_udf.slt @@ -81,19 +81,6 @@ create function print_add_two(INT) returns int language sql as 'select print($1 statement error failed to conduct semantic check, please see if you are calling non-existence functions create function non_exist(INT) returns int language sql as 'select yo(114514)'; -statement ok -create function regexp_replace_wrapper(varchar) returns varchar language sql as $$select regexp_replace($1, 'baz(...)', '这是🥵', 'ic')$$; - -statement ok -create function print(INT) returns int language sql as 'select $1'; - -# Adjust the input value of the calling function (i.e., `print` here) with the actual input parameter -statement ok -create function print_add_one(INT) returns int language sql as 'select print($1 + 1)'; - -statement ok -create function print_add_two(INT) returns int language sql as 'select print($1 + $1)'; - # Call the defined sql udf query I select add(1, -1); @@ -303,18 +290,6 @@ drop function print_add_two; statement ok drop function regexp_replace_wrapper; -statement ok -drop function print; - -statement ok -drop function print_add_one; - -statement ok -drop function print_add_two; - -statement ok -drop function regexp_replace_wrapper; - # Drop the mock table statement ok drop table t1; diff --git a/src/frontend/src/handler/create_sql_function.rs b/src/frontend/src/handler/create_sql_function.rs index 8124a7e5e6e53..05bb39bfe35b0 100644 --- a/src/frontend/src/handler/create_sql_function.rs +++ b/src/frontend/src/handler/create_sql_function.rs @@ -205,7 +205,7 @@ pub async fn handle_create_sql_function( // Conduct semantic check (e.g., see if the inner calling functions exist, etc.) let ast = parse_result.unwrap(); - let mut binder = Binder::new_for_system(&session); + let mut binder = Binder::new_for_system(session); binder .get_udf_context() @@ -214,7 +214,7 @@ pub async fn handle_create_sql_function( if let Ok(expr) = extract_udf_expression(ast) { if let Err(e) = binder.bind_expr(expr) { return Err(ErrorCode::InvalidInputSyntax( - format!("failed to conduct semantic check, please see if you are calling non-existence functions.\nDetailed error: {}", e.to_string()) + format!("failed to conduct semantic check, please see if you are calling non-existence functions.\nDetailed error: {e}") ) .into()); } From 50e01a0900a77263a3bc7aa764b44aa839055c56 Mon Sep 17 00:00:00 2001 From: Michael Xu Date: Mon, 22 Jan 2024 10:12:33 -0500 Subject: [PATCH 7/7] change function name --- src/frontend/src/binder/mod.rs | 2 +- src/frontend/src/handler/create_sql_function.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/frontend/src/binder/mod.rs b/src/frontend/src/binder/mod.rs index 6c5347b38a902..bf090a87a7514 100644 --- a/src/frontend/src/binder/mod.rs +++ b/src/frontend/src/binder/mod.rs @@ -416,7 +416,7 @@ impl Binder { self.context.clause = clause; } - pub fn get_udf_context(&mut self) -> &mut UdfContext { + pub fn udf_context_mut(&mut self) -> &mut UdfContext { &mut self.udf_context } } diff --git a/src/frontend/src/handler/create_sql_function.rs b/src/frontend/src/handler/create_sql_function.rs index 05bb39bfe35b0..21798b17b2ac5 100644 --- a/src/frontend/src/handler/create_sql_function.rs +++ b/src/frontend/src/handler/create_sql_function.rs @@ -208,7 +208,7 @@ pub async fn handle_create_sql_function( let mut binder = Binder::new_for_system(session); binder - .get_udf_context() + .udf_context_mut() .update_context(create_mock_udf_context(arg_types.clone())); if let Ok(expr) = extract_udf_expression(ast) {