Merge 'Fix INSERT UNION ALL' from Duy Dang

Close #3849
Close #3855

Reviewed-by: Jussi Saurio <jussi.saurio@gmail.com>

Closes #3877
This commit is contained in:
Pekka Enberg
2025-11-01 11:12:38 +02:00
committed by GitHub
3 changed files with 83 additions and 46 deletions

View File

@@ -927,43 +927,48 @@ fn bind_insert(
.collect();
}
InsertBody::Select(select, upsert_opt) => {
match &mut select.body.select {
// TODO see how to avoid clone
OneSelect::Values(values_expr) if values_expr.len() <= 1 => {
if values_expr.is_empty() {
crate::bail_parse_error!("no values to insert");
}
for expr in values_expr.iter_mut().flat_map(|v| v.iter_mut()) {
match expr.as_mut() {
Expr::Id(name) => {
if name.quoted_with('"') {
*expr = Expr::Literal(ast::Literal::String(name.as_literal()))
.into();
} else {
// an INSERT INTO ... VALUES (...) cannot reference columns
crate::bail_parse_error!("no such column: {name}");
}
}
Expr::Qualified(first_name, second_name) => {
// an INSERT INTO ... VALUES (...) cannot reference columns
crate::bail_parse_error!(
"no such column: {first_name}.{second_name}"
);
}
_ => {}
if select.body.compounds.is_empty() {
match &mut select.body.select {
// TODO see how to avoid clone
OneSelect::Values(values_expr) if values_expr.len() <= 1 => {
if values_expr.is_empty() {
crate::bail_parse_error!("no values to insert");
}
bind_and_rewrite_expr(
expr,
None,
None,
connection,
&mut program.param_ctx,
BindingBehavior::ResultColumnsNotAllowed,
)?;
for expr in values_expr.iter_mut().flat_map(|v| v.iter_mut()) {
match expr.as_mut() {
Expr::Id(name) => {
if name.quoted_with('"') {
*expr =
Expr::Literal(ast::Literal::String(name.as_literal()))
.into();
} else {
// an INSERT INTO ... VALUES (...) cannot reference columns
crate::bail_parse_error!("no such column: {name}");
}
}
Expr::Qualified(first_name, second_name) => {
// an INSERT INTO ... VALUES (...) cannot reference columns
crate::bail_parse_error!(
"no such column: {first_name}.{second_name}"
);
}
_ => {}
}
bind_and_rewrite_expr(
expr,
None,
None,
connection,
&mut program.param_ctx,
BindingBehavior::ResultColumnsNotAllowed,
)?;
}
values = values_expr.pop().unwrap_or_else(Vec::new);
}
values = values_expr.pop().unwrap_or_else(Vec::new);
_ => inserting_multiple_rows = true,
}
_ => inserting_multiple_rows = true,
} else {
inserting_multiple_rows = true;
}
upsert = upsert_opt.take();
}
@@ -1056,8 +1061,10 @@ fn init_source_emission<'a>(
) -> Result<ProgramBuilder> {
let (num_values, cursor_id) = match body {
InsertBody::Select(select, _) => {
// Simple Common case of INSERT INTO <table> VALUES (...)
if matches!(&select.body.select, OneSelect::Values(values) if values.len() <= 1) {
// Simple common case of INSERT INTO <table> VALUES (...) without compounds.
if select.body.compounds.is_empty()
&& matches!(&select.body.select, OneSelect::Values(values) if values.len() <= 1)
{
(
values.len(),
program.alloc_cursor_id(CursorType::BTreeTable(ctx.table.clone())),