* Problem: Inconsistent behavior occurs when executing partial column update `UPDATE` statements and `INSERT` statements on merge-on-write tables with the Nereids optimizer enabled. The number of columns passed to BE differs; `UPDATE` operations incorrectly pass all columns, while `INSERT` operations correctly pass only the updated columns. Reason: The Nereids optimizer does not handle partial column update `UPDATE` statements properly. The processing logic for `UPDATE` statements rewrites them as equivalent `INSERT` statements, which are then processed according to the logic of `INSERT` statements. For example, assuming a MoW table structure with columns k1, k2, v1, v2, the correct rewrite should be: * `UPDATE` table t1 set v1 = v1 + 1 where k1 = 1 and k2 = 2 * => * `INSERT` into table (v1) select v1 + 1 from table t1 where k1 = 1 and k2 = 2 However, the actual rewriting process does not consider the logic for partial column updates, leading to all columns being included in the `INSERT` statement, i.e., the result is: * `INSERT` into table (k1, k2, v1, v2) select k1, k2, v1 + 1, v2 from table t1 where k1 = 1 and k2 = 2 This results in `UPDATE` operations incorrectly passing all columns to BE. Solution: Having analyzed the cause, the solution is straightforward: when rewriting partial column update `UPDATE` statements to `INSERT` statements, only retain the updated columns and all key columns (as partial column updates must include all key columns). Additionally, this PR includes error injection cases to verify the number of columns passed to BE is correct. * 2 * 3 * 4 * 5
84 lines
2.8 KiB
Groovy
84 lines
2.8 KiB
Groovy
// Licensed to the Apache Software Foundation (ASF) under one
|
|
// or more contributor license agreements. See the NOTICE file
|
|
// distributed with this work for additional information
|
|
// regarding copyright ownership. The ASF licenses this file
|
|
// to you under the Apache License, Version 2.0 (the
|
|
// "License"); you may not use this file except in compliance
|
|
// with the License. You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing,
|
|
// software distributed under the License is distributed on an
|
|
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
// KIND, either express or implied. See the License for the
|
|
// specific language governing permissions and limitations
|
|
// under the License.
|
|
|
|
suite("test_unique_table_update","nonConcurrent") {
|
|
|
|
|
|
def tableName = "test_unique_table_update"
|
|
|
|
sql """ DROP TABLE IF EXISTS ${tableName} """
|
|
|
|
sql """
|
|
CREATE TABLE ${tableName}
|
|
(k bigint, v1 string, v2 string, v3 string, v4 string )
|
|
UNIQUE KEY(k)
|
|
DISTRIBUTED BY HASH (k)
|
|
BUCKETS 32
|
|
PROPERTIES(
|
|
"replication_num" = "1",
|
|
"enable_unique_key_merge_on_write"="true");
|
|
"""
|
|
|
|
sql "insert into ${tableName} values(1,1,1,1,1),(2,2,2,2,2),(3,3,3,3,3);"
|
|
qt_select_1 "select * from ${tableName} order by k;"
|
|
|
|
sql "set enable_nereids_planner=true"
|
|
sql "set enable_fallback_to_original_planner=false"
|
|
|
|
// update key is not allowed
|
|
try {
|
|
sql "update ${tableName} set k=1, v1=1, v2=1 where k=2;"
|
|
assertTrue(false)
|
|
} catch (Exception e) {
|
|
logger.info(e.getMessage())
|
|
assertTrue(e.getMessage().contains("Only value columns of unique table could be updated"))
|
|
} finally {
|
|
qt_select_2 "select * from ${tableName} order by k;"
|
|
}
|
|
|
|
// update value is allowed
|
|
try {
|
|
sql "update ${tableName} set v1=1, v2=1 where k=2;"
|
|
} catch (Exception e) {
|
|
logger.info(e.getMessage())
|
|
assertTrue(false)
|
|
} finally {
|
|
qt_select_3 "select * from ${tableName} order by k;"
|
|
}
|
|
|
|
sql "set enable_nereids_planner=false"
|
|
// update key is not allowed
|
|
try {
|
|
sql "update ${tableName} set k=1, v1=1, v2=1 where k=2;"
|
|
assertTrue(false)
|
|
} catch (Exception e) {
|
|
logger.info(e.getMessage())
|
|
assertTrue(e.getMessage().contains("Only value columns of unique table could be updated"))
|
|
} finally {
|
|
qt_select_4 "select * from ${tableName} order by k;"
|
|
}
|
|
|
|
// update key is allowed
|
|
try {
|
|
sql "update ${tableName} set v1=1, v2=1 where k=2;"
|
|
} catch (Exception e) {
|
|
logger.info(e.getMessage())
|
|
assertTrue(false)
|
|
} finally {
|
|
qt_select_5 "select * from ${tableName} order by k;"
|
|
}
|
|
} |