From c0b5e641f0a569a8551fa2f13e1e51c7daee1fd2 Mon Sep 17 00:00:00 2001 From: Dylan Date: Wed, 13 Nov 2024 10:55:38 +0800 Subject: [PATCH] fix(binder): report error on update query with subquery on the set clause (#19305) --- .../planner_test/tests/testdata/input/update.yaml | 7 +++++++ .../planner_test/tests/testdata/output/update.yaml | 6 ++++++ src/frontend/src/binder/update.rs | 13 +++++++------ 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/frontend/planner_test/tests/testdata/input/update.yaml b/src/frontend/planner_test/tests/testdata/input/update.yaml index 2322f68ad95e0..65c0f47eb4cd4 100644 --- a/src/frontend/planner_test/tests/testdata/input/update.yaml +++ b/src/frontend/planner_test/tests/testdata/input/update.yaml @@ -98,3 +98,10 @@ update t set a = a + 1; expected_outputs: - batch_distributed_plan +- name: update table with subquery in the set clause + sql: | + create table t1 (v1 int primary key, v2 int); + create table t2 (v1 int primary key, v2 int); + update t1 set v1 = (select v1 from t2 where t1.v2 = t2.v2); + expected_outputs: + - binder_error diff --git a/src/frontend/planner_test/tests/testdata/output/update.yaml b/src/frontend/planner_test/tests/testdata/output/update.yaml index 884b091cf8af7..eae928bb858a7 100644 --- a/src/frontend/planner_test/tests/testdata/output/update.yaml +++ b/src/frontend/planner_test/tests/testdata/output/update.yaml @@ -165,3 +165,9 @@ └─BatchUpdate { table: t, exprs: [($0 + 1:Int32), $1, $2] } └─BatchExchange { order: [], dist: HashShard(t.a, t.b, t._row_id) } └─BatchScan { table: t, columns: [t.a, t.b, t._row_id], distribution: UpstreamHashShard(t._row_id) } +- name: update table with subquery in the set clause + sql: | + create table t1 (v1 int primary key, v2 int); + create table t2 (v1 int primary key, v2 int); + update t1 set v1 = (select v1 from t2 where t1.v2 = t2.v2); + binder_error: 'Bind error: subquery on the right side of assignment is unsupported' diff --git a/src/frontend/src/binder/update.rs b/src/frontend/src/binder/update.rs index cbe51f9ec69bd..6775c2173e00b 100644 --- a/src/frontend/src/binder/update.rs +++ b/src/frontend/src/binder/update.rs @@ -17,7 +17,6 @@ use std::collections::{BTreeMap, HashMap}; use fixedbitset::FixedBitSet; use itertools::Itertools; -use risingwave_common::bail_not_implemented; use risingwave_common::catalog::{Schema, TableVersionId}; use risingwave_common::util::iter_util::ZipEqFast; use risingwave_sqlparser::ast::{Assignment, AssignmentValue, Expr, ObjectName, SelectItem}; @@ -129,15 +128,17 @@ impl Binder { for Assignment { id, value } in assignments { // FIXME: Parsing of `id` is not strict. It will even treat `a.b` as `(a, b)`. let assignments = match (id.as_slice(), value) { + // _ = (subquery) + (_ids, AssignmentValue::Expr(Expr::Subquery(_))) => { + return Err(ErrorCode::BindError( + "subquery on the right side of assignment is unsupported".to_owned(), + ) + .into()) + } // col = expr ([id], value) => { vec![(id.clone(), value)] } - - // (col1, col2) = (subquery) - (_ids, AssignmentValue::Expr(Expr::Subquery(_))) => { - bail_not_implemented!("subquery on the right side of multi-assignment"); - } // (col1, col2) = (expr1, expr2) // TODO: support `DEFAULT` in multiple assignments (ids, AssignmentValue::Expr(Expr::Row(values))) if ids.len() == values.len() => id