diff --git a/table/src/main/java/tech/ydb/table/description/TableColumn.java b/table/src/main/java/tech/ydb/table/description/TableColumn.java index 391386f8e..579aaf44c 100644 --- a/table/src/main/java/tech/ydb/table/description/TableColumn.java +++ b/table/src/main/java/tech/ydb/table/description/TableColumn.java @@ -15,10 +15,17 @@ public class TableColumn { @Nullable private final String family; - public TableColumn(String name, Type type, String family) { + private boolean hasDefaultValue; + + public TableColumn(String name, Type type, String family, boolean hasDefaultValue) { this.name = name; this.type = type; this.family = family; + this.hasDefaultValue = hasDefaultValue; + } + + public TableColumn(String name, Type type, String family) { + this(name, type, family, false); } public TableColumn(String name, Type type) { @@ -33,6 +40,10 @@ public Type getType() { return type; } + public boolean hasDefaultValue() { + return hasDefaultValue; + } + @Nullable public String getFamily() { return family; diff --git a/table/src/main/java/tech/ydb/table/description/TableDescription.java b/table/src/main/java/tech/ydb/table/description/TableDescription.java index dbc2a1689..f7dcc522d 100644 --- a/table/src/main/java/tech/ydb/table/description/TableDescription.java +++ b/table/src/main/java/tech/ydb/table/description/TableDescription.java @@ -117,7 +117,7 @@ public List getChangefeeds() { public static class Builder { private StoreType storeType = StoreType.ROW; private List primaryKeys = Collections.emptyList(); - private final LinkedHashMap columns = new LinkedHashMap<>(); + private final Map columns = new LinkedHashMap<>(); private final List indexes = new ArrayList<>(); private final List families = new ArrayList<>(); private final List keyRanges = new ArrayList<>(); @@ -133,12 +133,17 @@ public Builder setStoreType(StoreType storeType) { return this; } + public Builder addColumn(TableColumn column) { + columns.put(column.getName(), column); + return this; + } + public Builder addNonnullColumn(String name, Type type) { return addNonnullColumn(name, type, null); } public Builder addNonnullColumn(String name, Type type, String family) { - columns.put(name, new TypeAndFamily(type, family)); + columns.put(name, new TableColumn(name, type, family)); return this; } @@ -152,7 +157,7 @@ public Builder addNullableColumn(String name, Type type) { } public Builder addNullableColumn(String name, Type type, String family) { - columns.put(name, new TypeAndFamily(OptionalType.of(type), family)); + columns.put(name, new TableColumn(name, OptionalType.of(type), family)); return this; } @@ -279,8 +284,8 @@ private List buildColumns() { int i = 0; TableColumn[] array = new TableColumn[this.columns.size()]; - for (Map.Entry e : this.columns.entrySet()) { - array[i++] = new TableColumn(e.getKey(), e.getValue().type, e.getValue().family); + for (Map.Entry e : this.columns.entrySet()) { + array[i++] = e.getValue(); } return ImmutableList.copyOf(array); @@ -296,16 +301,6 @@ private void checkColumnKnown(String name) { throw new IllegalArgumentException("unknown column name: " + name); } } - - private static class TypeAndFamily { - private final Type type; - private final String family; - - TypeAndFamily(Type type, String family) { - this.type = type; - this.family = family; - } - } } public static class PartitionStats { diff --git a/table/src/main/java/tech/ydb/table/impl/BaseSession.java b/table/src/main/java/tech/ydb/table/impl/BaseSession.java index 37698e2af..ba0833405 100644 --- a/table/src/main/java/tech/ydb/table/impl/BaseSession.java +++ b/table/src/main/java/tech/ydb/table/impl/BaseSession.java @@ -776,7 +776,12 @@ private static Result mapDescribeTable(Result session.executeSchemeQuery("" + + "CREATE TABLE alter_table_test (" + + " id BigSerial NOT NULL," + + " code Text NOT NULL," + + " size Float," + + " created Timestamp," + + " data Text," + + " PRIMARY KEY(id)," + + " INDEX idx1 GLOBAL ON (id, code)," + + " INDEX idx2 GLOBAL ASYNC ON (data) COVER (code)" + + ")" + )).join(); + Assert.assertTrue("Create table with indexes " + createStatus, createStatus.isSuccess()); + + // --------------------- describe table after creating ----------------------------- + Result describeResult = ctx.supplyResult(session ->session.describeTable(tablePath)).join(); + Assert.assertTrue("Describe table with indexes " + describeResult.getStatus(), describeResult.isSuccess()); + + TableDescription description = describeResult.getValue(); + + Assert.assertEquals(TableDescription.StoreType.ROW, description.getStoreType()); + Assert.assertEquals(1, description.getColumnFamilies().size()); + Assert.assertEquals(DEFAULT_FAMILY, description.getColumnFamilies().get(0).getName()); + + Assert.assertEquals(5, description.getColumns().size()); + assertColumn(description.getColumns().get(0), "id", PrimitiveType.Int64, true, true); + assertColumn(description.getColumns().get(1), "code", PrimitiveType.Text, true, false); + assertColumn(description.getColumns().get(2), "size", PrimitiveType.Float); + assertColumn(description.getColumns().get(3), "created", PrimitiveType.Timestamp); + assertColumn(description.getColumns().get(4), "data", PrimitiveType.Text); + + Assert.assertEquals(2, description.getIndexes().size()); + assertIndexSync(description.getIndexes().get(0), "idx1", Arrays.asList("id", "code"), Collections.emptyList()); + assertIndexAsync(description.getIndexes().get(1), "idx2", Arrays.asList("data"), Arrays.asList("code")); + + // --------------------- alter table with changing columns ----------------------------- + + Status alterStatus = ctx.supplyStatus( + session -> session.alterTable(tablePath, new AlterTableSettings() + .addNullableColumn("data2", PrimitiveType.Bytes) + .dropColumn("created")) + ).join(); + Assert.assertTrue("Alter table with column " + alterStatus, alterStatus.isSuccess()); + + // --------------------- describe table after first altering ----------------------------- + describeResult = ctx.supplyResult(session ->session.describeTable(tablePath)).join(); + Assert.assertTrue("Describe table after altering " + describeResult.getStatus(), describeResult.isSuccess()); + + description = describeResult.getValue(); + + Assert.assertEquals(1, description.getColumnFamilies().size()); + Assert.assertEquals(DEFAULT_FAMILY, description.getColumnFamilies().get(0).getName()); + + Assert.assertEquals(5, description.getColumns().size()); + assertColumn(description.getColumns().get(0), "id", PrimitiveType.Int64, true, true); + assertColumn(description.getColumns().get(1), "code", PrimitiveType.Text, true, false); + assertColumn(description.getColumns().get(2), "size", PrimitiveType.Float); + assertColumn(description.getColumns().get(3), "data", PrimitiveType.Text); + assertColumn(description.getColumns().get(4), "data2", PrimitiveType.Bytes); + + Assert.assertEquals(2, description.getIndexes().size()); + assertIndexSync(description.getIndexes().get(0), "idx1", Arrays.asList("id", "code"), Collections.emptyList()); + assertIndexAsync(description.getIndexes().get(1), "idx2", Arrays.asList("data"), Arrays.asList("code")); + + // --------------------- alter table with changing indexes ----------------------------- + alterStatus = ctx.supplyStatus( + session -> session.alterTable(tablePath, new AlterTableSettings() + .dropIndex("idx1")) + ).join(); + Assert.assertTrue("Alter table with indexes " + alterStatus, alterStatus.isSuccess()); + + // --------------------- describe table after first altering ----------------------------- + describeResult = ctx.supplyResult(session ->session.describeTable(tablePath)).join(); + Assert.assertTrue("Describe table after altering " + describeResult.getStatus(), describeResult.isSuccess()); + + description = describeResult.getValue(); + + Assert.assertEquals(1, description.getColumnFamilies().size()); + Assert.assertEquals(DEFAULT_FAMILY, description.getColumnFamilies().get(0).getName()); + + Assert.assertEquals(5, description.getColumns().size()); + assertColumn(description.getColumns().get(0), "id", PrimitiveType.Int64, true, true); + assertColumn(description.getColumns().get(1), "code", PrimitiveType.Text, true, false); + assertColumn(description.getColumns().get(2), "size", PrimitiveType.Float); + assertColumn(description.getColumns().get(3), "data", PrimitiveType.Text); + assertColumn(description.getColumns().get(4), "data2", PrimitiveType.Bytes); Assert.assertEquals(1, description.getIndexes().size()); assertIndexAsync(description.getIndexes().get(0), "idx2", Arrays.asList("data"), Arrays.asList("code")); } private void assertColumn(TableColumn column, String name, Type type) { + assertColumn(column, name, type, false, false); + } + + private void assertColumn(TableColumn column, String name, Type type, boolean isNotNull, boolean hasDefaultValue) { Assert.assertEquals(name, column.getName()); - Assert.assertEquals(type, column.getType()); + Assert.assertEquals(isNotNull ? type : type.makeOptional(), column.getType()); Assert.assertEquals(EMPTY_FAMILY, column.getFamily()); +// Assert.assertEquals(isNotNull, column.isNotNull()); + Assert.assertEquals(hasDefaultValue, column.hasDefaultValue()); } private void assertIndexSync(TableIndex index, String name, List columns, List dataColumns) {