This is an automated email from the ASF dual-hosted git repository. shengkai pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/flink.git
The following commit(s) were added to refs/heads/master by this push: new 82fcdfe5634 [FLINK-33928][table-planner] Should not throw exception while creating view with specify field names (#24096) 82fcdfe5634 is described below commit 82fcdfe5634fb82d3ab4a183818d852119dc68a9 Author: yunhong <337361...@qq.com> AuthorDate: Fri Jan 19 11:16:25 2024 +0800 [FLINK-33928][table-planner] Should not throw exception while creating view with specify field names (#24096) Co-authored-by: zhengyunhong.zyh <zhengyunhong....@alibaba-inc.com> --- .../operations/converters/SqlNodeConvertUtils.java | 23 ++++++++++++++++------ .../operations/SqlDdlToOperationConverterTest.java | 13 ++++++++++++ 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/flink-table/flink-table-planner/src/main/java/org/apache/flink/table/planner/operations/converters/SqlNodeConvertUtils.java b/flink-table/flink-table-planner/src/main/java/org/apache/flink/table/planner/operations/converters/SqlNodeConvertUtils.java index 43e3937392e..991bbf744b5 100644 --- a/flink-table/flink-table-planner/src/main/java/org/apache/flink/table/planner/operations/converters/SqlNodeConvertUtils.java +++ b/flink-table/flink-table-planner/src/main/java/org/apache/flink/table/planner/operations/converters/SqlNodeConvertUtils.java @@ -81,7 +81,7 @@ class SqlNodeConvertUtils { // index to identify the duplicate names. SqlValidatorNamespace validatedNamespace = context.getSqlValidator().getNamespace(validateQuery); - validateDuplicatedColumnNames(query, validatedNamespace); + validateDuplicatedColumnNames(query, viewFields, validatedNamespace); // The LATERAL operator was eliminated during sql validation, thus the unparsed SQL // does not contain LATERAL which is problematic, @@ -142,12 +142,23 @@ class SqlNodeConvertUtils { } private static void validateDuplicatedColumnNames( - SqlNode query, SqlValidatorNamespace namespace) { + SqlNode query, List<SqlNode> viewFields, SqlValidatorNamespace namespace) { + + // If view fields is not empty, means the view column list is specified by user use syntax + // 'CREATE VIEW viewName(x,x,x) AS SELECT x,x,x FROM table'. For this syntax, we need + // validate whether the column name in the view column list is unique. + List<String> columnNameList; + if (!viewFields.isEmpty()) { + columnNameList = + viewFields.stream().map(SqlNode::toString).collect(Collectors.toList()); + } else { + Objects.requireNonNull(namespace); + columnNameList = namespace.getType().getFieldNames(); + } + Map<String, Integer> nameToPos = new HashMap<>(); - for (int i = 0; - i < Objects.requireNonNull(namespace).getType().getFieldList().size(); - i++) { - String columnName = namespace.getType().getFieldList().get(i).getName(); + for (int i = 0; i < columnNameList.size(); i++) { + String columnName = columnNameList.get(i); if (nameToPos.containsKey(columnName)) { SqlSelect select = extractSelect(query); // Can not get the origin schema. diff --git a/flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/operations/SqlDdlToOperationConverterTest.java b/flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/operations/SqlDdlToOperationConverterTest.java index 1de2d72583a..c88140e5780 100644 --- a/flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/operations/SqlDdlToOperationConverterTest.java +++ b/flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/operations/SqlDdlToOperationConverterTest.java @@ -2229,6 +2229,19 @@ public class SqlDdlToOperationConverterTest extends SqlNodeToOperationConversion catalogManager.createTable( catalogTable, ObjectIdentifier.of("builtin", "default", "id_table"), false); + Operation operation = + parse("CREATE VIEW id_view(a, b) AS SELECT id, uid AS id FROM id_table"); + assertThat(operation).isInstanceOf(CreateViewOperation.class); + + assertThatThrownBy( + () -> + parse( + "CREATE VIEW id_view(a, a) AS SELECT id, uid AS id FROM id_table")) + .satisfies( + FlinkAssertions.anyCauseMatches( + SqlValidateException.class, + "A column with the same name `a` has been defined at line 1, column 37.")); + assertThatThrownBy( () -> parse("CREATE VIEW id_view AS\nSELECT id, uid AS id FROM id_table")) .satisfies(