Skip to content

feat(sql-udf): introduce udf_binding_flag #14782

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jan 25, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions src/frontend/src/binder/expr/column.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,18 @@ impl Binder {
// to the name of the defined sql udf parameters stored in `udf_context`.
// 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 Ok(expr.clone());
if self.udf_binding_flag {
if let Some(expr) = self.udf_context.get_expr(&column_name) {
return Ok(expr.clone());
} else {
// The reason that we directly return error here,
// is because during a valid sql udf binding,
// there will not exist any column identifiers
return Err(ErrorCode::BindError(format!(
"failed to find named parameter {column_name}"
))
.into());
}
}

match self
Expand Down
3 changes: 3 additions & 0 deletions src/frontend/src/binder/expr/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,10 @@ impl Binder {
}

if let Ok(expr) = UdfContext::extract_udf_expression(ast) {
self.set_udf_binding_flag();
let bind_result = self.bind_expr(expr);
self.unset_udf_binding_flag();

// Restore context information for subsequent binding
self.udf_context.update_context(stashed_udf_context);
return bind_result;
Expand Down
14 changes: 13 additions & 1 deletion src/frontend/src/binder/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,9 +122,12 @@ pub struct Binder {

/// The sql udf context that will be used during binding phase
udf_context: UdfContext,

/// Udf binding flag, used to distinguish between
/// columns and named parameters during sql udf binding
udf_binding_flag: bool,
}

#[derive(Clone, Debug, Default)]
pub struct UdfContext {
/// 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
Expand Down Expand Up @@ -340,6 +343,7 @@ impl Binder {
included_relations: HashSet::new(),
param_types: ParameterTypes::new(param_types),
udf_context: UdfContext::new(),
udf_binding_flag: false,
}
}

Expand Down Expand Up @@ -489,6 +493,14 @@ impl Binder {
pub fn udf_context_mut(&mut self) -> &mut UdfContext {
&mut self.udf_context
}

pub fn set_udf_binding_flag(&mut self) {
self.udf_binding_flag = true;
}

pub fn unset_udf_binding_flag(&mut self) {
self.udf_binding_flag = false;
}
}

/// The column name stored in [`BindContext`] for a column without an alias.
Expand Down