Allow unbound identifiers specifically for INSERT ... ON CONFLICT

the binding for the ON CONFLICT clause is done later.
This commit is contained in:
Jussi Saurio
2025-10-08 08:36:12 +03:00
parent a343dacaaf
commit f5766379ce
2 changed files with 14 additions and 2 deletions

View File

@@ -3272,11 +3272,14 @@ impl ParamState {
/// TryCanonicalColumnsFirst means that canonical columns take precedence over result columns. This is used for e.g. WHERE clauses.
///
/// ResultColumnsNotAllowed means that referring to result columns is not allowed. This is used e.g. for DML statements.
///
/// AllowUnboundIdentifiers means that unbound identifiers are allowed. This is used for INSERT ... ON CONFLICT DO UPDATE SET ... where binding is handled later than this phase.
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum BindingBehavior {
TryResultColumnsFirst,
TryCanonicalColumnsFirst,
ResultColumnsNotAllowed,
AllowUnboundIdentifiers,
}
/// Rewrite ast::Expr in place, binding Column references/rewriting Expr::Id -> Expr::Column
@@ -3329,6 +3332,9 @@ pub fn bind_and_rewrite_expr<'a>(
match expr {
Expr::Id(id) => {
let Some(referenced_tables) = &mut referenced_tables else {
if binding_behavior == BindingBehavior::AllowUnboundIdentifiers {
return Ok(WalkControl::Continue);
}
crate::bail_parse_error!("no such column: {}", id.as_str());
};
let normalized_id = normalize_ident(id.as_str());
@@ -3459,6 +3465,9 @@ pub fn bind_and_rewrite_expr<'a>(
Expr::Qualified(tbl, id) => {
tracing::debug!("bind_and_rewrite_expr({:?}, {:?})", tbl, id);
let Some(referenced_tables) = &mut referenced_tables else {
if binding_behavior == BindingBehavior::AllowUnboundIdentifiers {
return Ok(WalkControl::Continue);
}
crate::bail_parse_error!(
"no such column: {}.{}",
tbl.as_str(),
@@ -3499,6 +3508,9 @@ pub fn bind_and_rewrite_expr<'a>(
}
Expr::DoublyQualified(db_name, tbl_name, col_name) => {
let Some(referenced_tables) = &mut referenced_tables else {
if binding_behavior == BindingBehavior::AllowUnboundIdentifiers {
return Ok(WalkControl::Continue);
}
crate::bail_parse_error!(
"no such column: {}.{}.{}",
db_name.as_str(),

View File

@@ -190,7 +190,7 @@ pub fn translate_insert(
None,
connection,
&mut program.param_ctx,
BindingBehavior::ResultColumnsNotAllowed,
BindingBehavior::AllowUnboundIdentifiers,
)?;
}
if let Some(ref mut where_expr) = where_clause {
@@ -200,7 +200,7 @@ pub fn translate_insert(
None,
connection,
&mut program.param_ctx,
BindingBehavior::ResultColumnsNotAllowed,
BindingBehavior::AllowUnboundIdentifiers,
)?;
}
}