diff --git a/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/databases/DatabaseUtil.java b/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/databases/DatabaseUtil.java index 662d28c2253..2036180c7c8 100644 --- a/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/databases/DatabaseUtil.java +++ b/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/databases/DatabaseUtil.java @@ -79,6 +79,7 @@ public final class DatabaseUtil { } public static void validateColumns(Table table) { + validateColumnNames(table.getColumns()); for (Column c : table.getColumns()) { validateColumnDataTypeDisplay(c); validateColumnDataLength(c); @@ -87,6 +88,16 @@ public final class DatabaseUtil { } } + public static void validateColumnNames(List columns) { + List columnNames = new ArrayList<>(); + for (Column c : columns) { + if (columnNames.contains(c.getName())) { + throw new IllegalArgumentException(String.format("Column name %s is repeated", c.getName())); + } + columnNames.add(c.getName()); + } + } + public static void validateColumnDataTypeDisplay(Column column) { // If dataTypeDisplay is null then set it based on dataType if (column.getDataTypeDisplay() == null) { @@ -143,6 +154,7 @@ public final class DatabaseUtil { "must not be null"); } + validateColumnNames(column.getChildren()); if (!column.getDataTypeDisplay().startsWith("struct<")) { throw new IllegalArgumentException("For column data type struct, dataTypeDisplay must be of type " + "stuct"); diff --git a/catalog-rest-service/src/test/java/org/openmetadata/catalog/resources/databases/TableResourceTest.java b/catalog-rest-service/src/test/java/org/openmetadata/catalog/resources/databases/TableResourceTest.java index 9c6d9275f3e..7985213b716 100644 --- a/catalog-rest-service/src/test/java/org/openmetadata/catalog/resources/databases/TableResourceTest.java +++ b/catalog-rest-service/src/test/java/org/openmetadata/catalog/resources/databases/TableResourceTest.java @@ -200,6 +200,18 @@ public class TableResourceTest extends CatalogApplicationTest { "For column data type array, dataTypeDisplay must be of type array"); } + @Test + public void post_duplicateColumnName_400(TestInfo test) { + // Duplicate column names c1 + String repeatedColumnName = "c1"; + List columns = Arrays.asList(getColumn(repeatedColumnName, ARRAY, "array", null), + getColumn(repeatedColumnName, INT, null)); + CreateTable create = create(test).withColumns(columns); + HttpResponseException exception = assertThrows(HttpResponseException.class, () -> + createTable(create, adminAuthHeaders())); + assertResponse(exception, BAD_REQUEST, String.format("Column name %s is repeated", repeatedColumnName)); + } + @Test public void post_tableAlreadyExists_409_conflict(TestInfo test) throws HttpResponseException { CreateTable create = create(test); @@ -227,9 +239,9 @@ public class TableResourceTest extends CatalogApplicationTest { } private static Column getColumn(String name, ColumnDataType columnDataType, String dataTypeDisplay, TagLabel tag) { - + List tags = tag == null ? new ArrayList<>() : singletonList(tag); return new Column().withName(name).withDataType(columnDataType) - .withDataTypeDisplay(dataTypeDisplay).withTags(singletonList(tag)); + .withDataTypeDisplay(dataTypeDisplay).withTags(tags); } @Test