diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/mv/InitMaterializationContextHook.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/mv/InitMaterializationContextHook.java index 049a2a235c934b..ee13628b4d141f 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/mv/InitMaterializationContextHook.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/mv/InitMaterializationContextHook.java @@ -313,7 +313,7 @@ private String assembleCreateMvSqlForDupOrUniqueTable(String baseTableName, Stri StringBuilder createMvSqlBuilder = new StringBuilder(); createMvSqlBuilder.append(String.format("create materialized view %s as select ", mvName)); for (Column col : columns) { - createMvSqlBuilder.append(String.format("%s, ", col.getName())); + createMvSqlBuilder.append(String.format("%s, ", getIdentSql(col.getName()))); } removeLastTwoChars(createMvSqlBuilder); createMvSqlBuilder.append(String.format(" from %s", baseTableName)); @@ -342,13 +342,13 @@ private String assembleCreateMvSqlForAggTable(String baseTableName, String mvNam case BITMAP_UNION: case QUANTILE_UNION: { aggColumnsStringBuilder - .append(String.format("%s(%s), ", aggregateType, col.getName())); + .append(String.format("%s(%s), ", aggregateType, getIdentSql(col.getName()))); break; } case GENERIC: { AggStateType aggStateType = (AggStateType) col.getType(); aggColumnsStringBuilder.append(String.format("%s_union(%s), ", - aggStateType.getFunctionName(), col.getName())); + aggStateType.getFunctionName(), getIdentSql(col.getName()))); break; } default: { @@ -362,7 +362,7 @@ private String assembleCreateMvSqlForAggTable(String baseTableName, String mvNam // use column name for key Preconditions.checkState(col.isKey(), String.format("%s must be key", col.getName())); - keyColumnsStringBuilder.append(String.format("%s, ", col.getName())); + keyColumnsStringBuilder.append(String.format("%s, ", getIdentSql(col.getName()))); } } Preconditions.checkState(keyColumnsStringBuilder.length() > 0, @@ -382,7 +382,7 @@ private String assembleCreateMvSqlForAggTable(String baseTableName, String mvNam String.format(" from %s group by %s", baseTableName, keyColumnsStringBuilder)); } else { for (Column col : columns) { - createMvSqlBuilder.append(String.format("%s, ", col.getName())); + createMvSqlBuilder.append(String.format("%s, ", getIdentSql(col.getName()))); } removeLastTwoChars(createMvSqlBuilder); createMvSqlBuilder.append(String.format(" from %s", baseTableName)); @@ -396,4 +396,18 @@ private void removeLastTwoChars(StringBuilder stringBuilder) { stringBuilder.delete(stringBuilder.length() - 2, stringBuilder.length()); } } + + private static String getIdentSql(String ident) { + StringBuilder sb = new StringBuilder(); + sb.append('`'); + for (char ch : ident.toCharArray()) { + if (ch == '`') { + sb.append("``"); + } else { + sb.append(ch); + } + } + sb.append('`'); + return sb.toString(); + } } diff --git a/regression-test/suites/mv_p0/test_mv_with_keyword/test_mv_with_keyword.groovy b/regression-test/suites/mv_p0/test_mv_with_keyword/test_mv_with_keyword.groovy new file mode 100644 index 00000000000000..fa937ceb3b4d43 --- /dev/null +++ b/regression-test/suites/mv_p0/test_mv_with_keyword/test_mv_with_keyword.groovy @@ -0,0 +1,67 @@ +// 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. + +import org.codehaus.groovy.runtime.IOGroovyMethods + +suite ("test_mv_with_keyword") { + + multi_sql """ + drop table if exists t1_dup; + create table t1_dup ( + `install` int, + ```install``` int, + c1 int + ) + duplicate key(`install`) + distributed BY hash(`install`) buckets 1 + rollup (r1(```install```, `install`)) + properties("replication_num" = "1"); + insert into t1_dup values(1,1,1), (2,2,2); + + drop table if exists t1_agg; + create table t1_agg ( + `install` int, + ```install``` int, + `kill` int sum + ) + aggregate key(`install`, ```install```) + distributed BY hash(`install`) buckets 1 + rollup (r1(```install```, `kill`)) + properties("replication_num" = "1"); + insert into t1_agg values(1,1,1), (2,2,2); + """ + createMV("create materialized view mv1 as select ```install``` as `select` from t1_dup where ```install``` > 0;") + createMV("create materialized view mv2 as select `install` as ```select``` from t1_dup where `install` > 0;") + createMV("create materialized view mv1 as select ```install``` as `select` from t1_agg group by ```install```;") + createMV("create materialized view mv2 as select `install` as ```select```, sum(`kill`) as ```kill``` from t1_agg group by `install`;") + explain { + sql("select ```install``` as `select` from t1_dup where ```install``` > 0;") + contains "(mv1)" + } + explain { + sql("select `install` as ```select``` from t1_dup where `install` > 0;") + contains "(mv2)" + } + explain { + sql("select ```install``` as `select` from t1_agg group by ```install```;") + contains "(mv1)" + } + explain { + sql("select `install` as ```select```, sum(`kill`) as ```kill``` from t1_agg group by `install`;") + contains "(mv2)" + } +} \ No newline at end of file