From fe5fb271dcad114fe96c573a51eeb08d769fb15d Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Tue, 21 Jul 2020 16:31:59 +0300 Subject: [PATCH] Fix "There is no supertype" error on ALTER UPDATE #7306 --- src/Interpreters/MutationsInterpreter.cpp | 21 +++++++++++++++---- .../01413_alter_update_supertype.reference | 21 +++++++++++++++++++ .../01413_alter_update_supertype.sql | 13 ++++++++++++ 3 files changed, 51 insertions(+), 4 deletions(-) create mode 100644 tests/queries/0_stateless/01413_alter_update_supertype.reference create mode 100644 tests/queries/0_stateless/01413_alter_update_supertype.sql diff --git a/src/Interpreters/MutationsInterpreter.cpp b/src/Interpreters/MutationsInterpreter.cpp index 6ea656f0056..a3287fb44e5 100644 --- a/src/Interpreters/MutationsInterpreter.cpp +++ b/src/Interpreters/MutationsInterpreter.cpp @@ -367,15 +367,28 @@ ASTPtr MutationsInterpreter::prepare(bool dry_run) affected_materialized.emplace(mat_column); } - /// Just to be sure, that we don't change type - /// after update expression execution. + /// When doing UPDATE column = expression WHERE condition + /// we will replace column to the result of the following expression: + /// + /// CAST(if(condition, CAST(expression, type), column), type) + /// + /// Inner CAST is needed to make 'if' work when branches have no common type, + /// example: type is UInt64, UPDATE x = -1 or UPDATE x = x - 1. + /// + /// Outer CAST is added just in case if we don't trust the returning type of 'if'. + + auto type_literal = std::make_shared(columns_desc.getPhysical(column).type->getName()); + const auto & update_expr = kv.second; auto updated_column = makeASTFunction("CAST", makeASTFunction("if", command.predicate->clone(), - update_expr->clone(), + makeASTFunction("CAST", + update_expr->clone(), + type_literal), std::make_shared(column)), - std::make_shared(columns_desc.getPhysical(column).type->getName())); + type_literal); + stages.back().column_to_updated.emplace(column, updated_column); } diff --git a/tests/queries/0_stateless/01413_alter_update_supertype.reference b/tests/queries/0_stateless/01413_alter_update_supertype.reference new file mode 100644 index 00000000000..6ea44b46479 --- /dev/null +++ b/tests/queries/0_stateless/01413_alter_update_supertype.reference @@ -0,0 +1,21 @@ +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +--- +0 +0 +2 +2 +4 +4 +6 +6 +8 +8 diff --git a/tests/queries/0_stateless/01413_alter_update_supertype.sql b/tests/queries/0_stateless/01413_alter_update_supertype.sql new file mode 100644 index 00000000000..9003d3f34c9 --- /dev/null +++ b/tests/queries/0_stateless/01413_alter_update_supertype.sql @@ -0,0 +1,13 @@ +DROP TABLE IF EXISTS t; +CREATE TABLE t (x UInt64) ENGINE = MergeTree ORDER BY tuple(); +INSERT INTO t SELECT number FROM numbers(10); + +SELECT * FROM t; + +SET mutations_sync = 1; +ALTER TABLE t UPDATE x = x - 1 WHERE x % 2 = 1; + +SELECT '---'; +SELECT * FROM t; + +DROP TABLE t;