Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion table/src/main/java/tech/ydb/table/description/TableColumn.java
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -33,6 +40,10 @@ public Type getType() {
return type;
}

public boolean hasDefaultValue() {
return hasDefaultValue;
}

@Nullable
public String getFamily() {
return family;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ public List<ChangefeedDescription> getChangefeeds() {
public static class Builder {
private StoreType storeType = StoreType.ROW;
private List<String> primaryKeys = Collections.emptyList();
private final LinkedHashMap<String, TypeAndFamily> columns = new LinkedHashMap<>();
private final Map<String, TableColumn> columns = new LinkedHashMap<>();
private final List<TableIndex> indexes = new ArrayList<>();
private final List<ColumnFamily> families = new ArrayList<>();
private final List<KeyRange> keyRanges = new ArrayList<>();
Expand All @@ -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;
}

Expand All @@ -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;
}

Expand Down Expand Up @@ -279,8 +284,8 @@ private List<TableColumn> buildColumns() {

int i = 0;
TableColumn[] array = new TableColumn[this.columns.size()];
for (Map.Entry<String, Builder.TypeAndFamily> e : this.columns.entrySet()) {
array[i++] = new TableColumn(e.getKey(), e.getValue().type, e.getValue().family);
for (Map.Entry<String, TableColumn> e : this.columns.entrySet()) {
array[i++] = e.getValue();
}

return ImmutableList.copyOf(array);
Expand All @@ -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 {
Expand Down
7 changes: 6 additions & 1 deletion table/src/main/java/tech/ydb/table/impl/BaseSession.java
Original file line number Diff line number Diff line change
Expand Up @@ -776,7 +776,12 @@ private static Result<TableDescription> mapDescribeTable(Result<YdbTable.Describ

for (int i = 0; i < desc.getColumnsCount(); i++) {
YdbTable.ColumnMeta column = desc.getColumns(i);
description.addNonnullColumn(column.getName(), ProtoType.fromPb(column.getType()), column.getFamily());
description.addColumn(new TableColumn(
column.getName(),
ProtoType.fromPb(column.getType()),
column.getFamily(),
column.hasFromLiteral() || column.hasFromSequence()
));
}
description.setPrimaryKeys(desc.getPrimaryKeyList());
for (int i = 0; i < desc.getIndexesCount(); i++) {
Expand Down
132 changes: 116 additions & 16 deletions table/src/test/java/tech/ydb/table/integration/AlterTableTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,11 @@ public void alterTableTest() {
Assert.assertEquals(DEFAULT_FAMILY, description.getColumnFamilies().get(0).getName());

Assert.assertEquals(5, description.getColumns().size());
assertColumn(description.getColumns().get(0), "id", PrimitiveType.Uint64);
assertColumn(description.getColumns().get(1), "code", PrimitiveType.Text.makeOptional());
assertColumn(description.getColumns().get(2), "size", PrimitiveType.Float.makeOptional());
assertColumn(description.getColumns().get(3), "created", PrimitiveType.Timestamp.makeOptional());
assertColumn(description.getColumns().get(4), "data", PrimitiveType.Text.makeOptional());
assertColumn(description.getColumns().get(0), "id", PrimitiveType.Uint64, true, false);
assertColumn(description.getColumns().get(1), "code", PrimitiveType.Text);
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());
Expand All @@ -108,11 +108,11 @@ public void alterTableTest() {
Assert.assertEquals(DEFAULT_FAMILY, description.getColumnFamilies().get(0).getName());

Assert.assertEquals(5, description.getColumns().size());
assertColumn(description.getColumns().get(0), "id", PrimitiveType.Uint64);
assertColumn(description.getColumns().get(1), "code", PrimitiveType.Text.makeOptional());
assertColumn(description.getColumns().get(2), "size", PrimitiveType.Float.makeOptional());
assertColumn(description.getColumns().get(3), "data", PrimitiveType.Text.makeOptional());
assertColumn(description.getColumns().get(4), "data2", PrimitiveType.Bytes.makeOptional());
assertColumn(description.getColumns().get(0), "id", PrimitiveType.Uint64, true, false);
assertColumn(description.getColumns().get(1), "code", PrimitiveType.Text);
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());
Expand All @@ -135,20 +135,120 @@ public void alterTableTest() {
Assert.assertEquals(DEFAULT_FAMILY, description.getColumnFamilies().get(0).getName());

Assert.assertEquals(5, description.getColumns().size());
assertColumn(description.getColumns().get(0), "id", PrimitiveType.Uint64);
assertColumn(description.getColumns().get(1), "code", PrimitiveType.Text.makeOptional());
assertColumn(description.getColumns().get(2), "size", PrimitiveType.Float.makeOptional());
assertColumn(description.getColumns().get(3), "data", PrimitiveType.Text.makeOptional());
assertColumn(description.getColumns().get(4), "data2", PrimitiveType.Bytes.makeOptional());
assertColumn(description.getColumns().get(0), "id", PrimitiveType.Uint64, true, false);
assertColumn(description.getColumns().get(1), "code", PrimitiveType.Text);
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"));
}

@Test
public void alterTableWithSerialTest() {
// --------------------- craete table -----------------------------
Status createStatus = ctx.supplyStatus(session -> 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<TableDescription> 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<String> columns, List<String> dataColumns) {
Expand Down