This is an automated email from the ASF dual-hosted git repository.
mchades pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/gravitino.git
The following commit(s) were added to refs/heads/main by this push:
new 075a851b4 [#5086] core(feat): Add logic to support manipulating
columns in TableOperationDispatcher (#5127)
075a851b4 is described below
commit 075a851b488061f7464f2695458b6240d92f087e
Author: Jerry Shao <[email protected]>
AuthorDate: Thu Oct 17 14:27:06 2024 +0800
[#5086] core(feat): Add logic to support manipulating columns in
TableOperationDispatcher (#5127)
### What changes were proposed in this pull request?
Add core logic to support manipulating columns in table create/load/load
operations.
### Why are the changes needed?
With this PR, we can manage the columns during the table operations.
Fix: #5086
### Does this PR introduce _any_ user-facing change?
No.
### How was this patch tested?
Add new UTs to cover the new changes.
---
.../jdbc/operation/JdbcTableOperations.java | 13 +-
.../operation/PostgreSqlTableOperations.java | 11 +
.../gravitino/catalog/EntityCombinedTable.java | 8 +
.../catalog/TableOperationDispatcher.java | 236 +++++++++--
.../org/apache/gravitino/meta/ColumnEntity.java | 13 +
.../test/java/org/apache/gravitino/TestColumn.java | 1 +
.../catalog/TestTableNormalizeDispatcher.java | 9 +-
.../catalog/TestTableOperationDispatcher.java | 464 +++++++++++++++++++++
.../gravitino/connector/TestCatalogOperations.java | 137 +++++-
scripts/h2/schema-0.7.0-h2.sql | 4 +-
scripts/h2/upgrade-0.6.0-to-0.7.0-h2.sql | 4 +-
scripts/mysql/schema-0.7.0-mysql.sql | 4 +-
scripts/mysql/upgrade-0.6.0-to-0.7.0-mysql.sql | 4 +-
scripts/postgresql/schema-0.7.0-postgresql.sql | 4 +-
14 files changed, 870 insertions(+), 42 deletions(-)
diff --git
a/catalogs/catalog-jdbc-common/src/main/java/org/apache/gravitino/catalog/jdbc/operation/JdbcTableOperations.java
b/catalogs/catalog-jdbc-common/src/main/java/org/apache/gravitino/catalog/jdbc/operation/JdbcTableOperations.java
index e65926fd0..e9b6bf6ab 100644
---
a/catalogs/catalog-jdbc-common/src/main/java/org/apache/gravitino/catalog/jdbc/operation/JdbcTableOperations.java
+++
b/catalogs/catalog-jdbc-common/src/main/java/org/apache/gravitino/catalog/jdbc/operation/JdbcTableOperations.java
@@ -168,6 +168,15 @@ public abstract class JdbcTableOperations implements
TableOperation {
return builder;
}
+ protected JdbcColumn.Builder getColumnBuilder(
+ ResultSet columnsResult, String databaseName, String tableName) throws
SQLException {
+ JdbcColumn.Builder builder = null;
+ if (Objects.equals(columnsResult.getString("TABLE_NAME"), tableName)) {
+ builder = getBasicJdbcColumnInfo(columnsResult);
+ }
+ return builder;
+ }
+
@Override
public JdbcTable load(String databaseName, String tableName) throws
NoSuchTableException {
// We should handle case sensitivity and wild card issue in some catalog
tables, take MySQL
@@ -188,8 +197,8 @@ public abstract class JdbcTableOperations implements
TableOperation {
ResultSet columns = getColumns(connection, databaseName, tableName);
while (columns.next()) {
// TODO(yunqing): check schema and catalog also
- if (Objects.equals(columns.getString("TABLE_NAME"), tableName)) {
- JdbcColumn.Builder columnBuilder = getBasicJdbcColumnInfo(columns);
+ JdbcColumn.Builder columnBuilder = getColumnBuilder(columns,
databaseName, tableName);
+ if (columnBuilder != null) {
boolean autoIncrement = getAutoIncrementInfo(columns);
columnBuilder.withAutoIncrement(autoIncrement);
jdbcColumns.add(columnBuilder.build());
diff --git
a/catalogs/catalog-jdbc-postgresql/src/main/java/org/apache/gravitino/catalog/postgresql/operation/PostgreSqlTableOperations.java
b/catalogs/catalog-jdbc-postgresql/src/main/java/org/apache/gravitino/catalog/postgresql/operation/PostgreSqlTableOperations.java
index 639544105..775687abd 100644
---
a/catalogs/catalog-jdbc-postgresql/src/main/java/org/apache/gravitino/catalog/postgresql/operation/PostgreSqlTableOperations.java
+++
b/catalogs/catalog-jdbc-postgresql/src/main/java/org/apache/gravitino/catalog/postgresql/operation/PostgreSqlTableOperations.java
@@ -108,6 +108,17 @@ public class PostgreSqlTableOperations extends
JdbcTableOperations {
return builder;
}
+ @Override
+ protected JdbcColumn.Builder getColumnBuilder(
+ ResultSet columnsResult, String databaseName, String tableName) throws
SQLException {
+ JdbcColumn.Builder builder = null;
+ if (Objects.equals(columnsResult.getString("TABLE_NAME"), tableName)
+ && Objects.equals(columnsResult.getString("TABLE_SCHEM"),
databaseName)) {
+ builder = getBasicJdbcColumnInfo(columnsResult);
+ }
+ return builder;
+ }
+
@Override
protected String generateCreateTableSql(
String tableName,
diff --git
a/core/src/main/java/org/apache/gravitino/catalog/EntityCombinedTable.java
b/core/src/main/java/org/apache/gravitino/catalog/EntityCombinedTable.java
index 460835f51..4b0da1568 100644
--- a/core/src/main/java/org/apache/gravitino/catalog/EntityCombinedTable.java
+++ b/core/src/main/java/org/apache/gravitino/catalog/EntityCombinedTable.java
@@ -128,6 +128,14 @@ public final class EntityCombinedTable implements Table {
return imported;
}
+ public Table tableFromCatalog() {
+ return table;
+ }
+
+ public TableEntity tableFromGravitino() {
+ return tableEntity;
+ }
+
@Override
public Audit auditInfo() {
AuditInfo mergedAudit =
diff --git
a/core/src/main/java/org/apache/gravitino/catalog/TableOperationDispatcher.java
b/core/src/main/java/org/apache/gravitino/catalog/TableOperationDispatcher.java
index 4472859d9..b54f06887 100644
---
a/core/src/main/java/org/apache/gravitino/catalog/TableOperationDispatcher.java
+++
b/core/src/main/java/org/apache/gravitino/catalog/TableOperationDispatcher.java
@@ -24,9 +24,16 @@ import static
org.apache.gravitino.catalog.PropertiesMetadataHelpers.validatePro
import static
org.apache.gravitino.rel.expressions.transforms.Transforms.EMPTY_TRANSFORM;
import static
org.apache.gravitino.utils.NameIdentifierUtil.getCatalogIdentifier;
+import com.google.common.base.Objects;
+import com.google.common.collect.Lists;
import java.time.Instant;
import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
import java.util.Map;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import org.apache.commons.lang3.tuple.Pair;
import org.apache.gravitino.EntityStore;
import org.apache.gravitino.GravitinoEnv;
import org.apache.gravitino.NameIdentifier;
@@ -41,6 +48,7 @@ import
org.apache.gravitino.exceptions.TableAlreadyExistsException;
import org.apache.gravitino.lock.LockType;
import org.apache.gravitino.lock.TreeLockUtils;
import org.apache.gravitino.meta.AuditInfo;
+import org.apache.gravitino.meta.ColumnEntity;
import org.apache.gravitino.meta.TableEntity;
import org.apache.gravitino.rel.Column;
import org.apache.gravitino.rel.Table;
@@ -97,26 +105,31 @@ public class TableOperationDispatcher extends
OperationDispatcher implements Tab
*/
@Override
public Table loadTable(NameIdentifier ident) throws NoSuchTableException {
- EntityCombinedTable table =
+ EntityCombinedTable entityCombinedTable =
TreeLockUtils.doWithTreeLock(ident, LockType.READ, () ->
internalLoadTable(ident));
- if (!table.imported()) {
+ if (!entityCombinedTable.imported()) {
// Load the schema to make sure the schema is imported.
SchemaDispatcher schemaDispatcher =
GravitinoEnv.getInstance().schemaDispatcher();
NameIdentifier schemaIdent =
NameIdentifier.of(ident.namespace().levels());
schemaDispatcher.loadSchema(schemaIdent);
// Import the table.
- TreeLockUtils.doWithTreeLock(
- schemaIdent,
- LockType.WRITE,
- () -> {
- importTable(ident);
- return null;
- });
+ entityCombinedTable =
+ TreeLockUtils.doWithTreeLock(schemaIdent, LockType.WRITE, () ->
importTable(ident));
}
- return table;
+ // Update the column entities in Gravitino store if the columns are
different from the ones
+ // fetching from the underlying source.
+ TableEntity updatedEntity = updateColumnsIfNecessaryWhenLoad(ident,
entityCombinedTable);
+
+ return EntityCombinedTable.of(entityCombinedTable.tableFromCatalog(),
updatedEntity)
+ .withHiddenPropertiesSet(
+ getHiddenPropertyNames(
+ getCatalogIdentifier(ident),
+ HasPropertyMetadata::tablePropertiesMetadata,
+ entityCombinedTable.tableFromCatalog().properties()))
+ .withImported(entityCombinedTable.imported());
}
/**
@@ -215,11 +228,15 @@ public class TableOperationDispatcher extends
OperationDispatcher implements Tab
.map(c -> ((TableChange.RenameTable)
c).getNewName())
.reduce((c1, c2) -> c2)
.orElse(tableEntity.name());
+ // Update the columns
+ Pair<Boolean, List<ColumnEntity>> columnsUpdateResult =
+ updateColumnsIfNecessary(alteredTable, tableEntity);
return TableEntity.builder()
.withId(tableEntity.id())
.withName(newName)
.withNamespace(ident.namespace())
+ .withColumns(columnsUpdateResult.getRight())
.withAuditInfo(
AuditInfo.builder()
.withCreator(tableEntity.auditInfo().creator())
@@ -328,11 +345,11 @@ public class TableOperationDispatcher extends
OperationDispatcher implements Tab
: droppedFromCatalog;
}
- private void importTable(NameIdentifier identifier) {
+ private EntityCombinedTable importTable(NameIdentifier identifier) {
EntityCombinedTable table = internalLoadTable(identifier);
if (table.imported()) {
- return;
+ return table;
}
StringIdentifier stringId = null;
@@ -348,8 +365,8 @@ public class TableOperationDispatcher extends
OperationDispatcher implements Tab
// of external system to correct it.
LOG.warn(
"The Table uid {} existed but still need to be imported, this could
be happened "
- + "when Table is renamed by external systems not controlled by
Gravitino. In this case, "
- + "we need to overwrite the stored entity to keep the
consistency.",
+ + "when Table is renamed by external systems not controlled by
Gravitino. In this "
+ + "case, we need to overwrite the stored entity to keep the
consistency.",
stringId);
uid = stringId.id();
} else {
@@ -357,18 +374,22 @@ public class TableOperationDispatcher extends
OperationDispatcher implements Tab
uid = idGenerator.nextId();
}
+ AuditInfo audit =
+ AuditInfo.builder()
+ .withCreator(table.auditInfo().creator())
+ .withCreateTime(table.auditInfo().createTime())
+ .withLastModifier(table.auditInfo().lastModifier())
+ .withLastModifiedTime(table.auditInfo().lastModifiedTime())
+ .build();
+ List<ColumnEntity> columnEntityList =
+ toColumnEntities(table.tableFromCatalog().columns(), audit);
TableEntity tableEntity =
TableEntity.builder()
.withId(uid)
.withName(identifier.name())
.withNamespace(identifier.namespace())
- .withAuditInfo(
- AuditInfo.builder()
- .withCreator(table.auditInfo().creator())
- .withCreateTime(table.auditInfo().createTime())
- .withLastModifier(table.auditInfo().lastModifier())
- .withLastModifiedTime(table.auditInfo().lastModifiedTime())
- .build())
+ .withColumns(columnEntityList)
+ .withAuditInfo(audit)
.build();
try {
store.put(tableEntity, true);
@@ -376,6 +397,13 @@ public class TableOperationDispatcher extends
OperationDispatcher implements Tab
LOG.error(FormattedErrorMessages.STORE_OP_FAILURE, "put", identifier, e);
throw new RuntimeException("Fail to import the table entity to the
store.", e);
}
+
+ return EntityCombinedTable.of(table.tableFromCatalog(), tableEntity)
+ .withHiddenPropertiesSet(
+ getHiddenPropertyNames(
+ getCatalogIdentifier(identifier),
+ HasPropertyMetadata::tablePropertiesMetadata,
+ table.tableFromCatalog().properties()));
}
private EntityCombinedTable internalLoadTable(NameIdentifier ident) {
@@ -465,16 +493,23 @@ public class TableOperationDispatcher extends
OperationDispatcher implements Tab
NoSuchSchemaException.class,
TableAlreadyExistsException.class);
+ AuditInfo audit =
+ AuditInfo.builder()
+ .withCreator(PrincipalUtils.getCurrentPrincipal().getName())
+ .withCreateTime(Instant.now())
+ .build();
+ List<ColumnEntity> columnEntityList =
+ Arrays.stream(columns)
+ .map(c -> ColumnEntity.toColumnEntity(c, idGenerator.nextId(),
audit))
+ .collect(Collectors.toList());
+
TableEntity tableEntity =
TableEntity.builder()
.withId(uid)
.withName(ident.name())
.withNamespace(ident.namespace())
- .withAuditInfo(
- AuditInfo.builder()
-
.withCreator(PrincipalUtils.getCurrentPrincipal().getName())
- .withCreateTime(Instant.now())
- .build())
+ .withColumns(columnEntityList)
+ .withAuditInfo(audit)
.build();
try {
@@ -492,4 +527,153 @@ public class TableOperationDispatcher extends
OperationDispatcher implements Tab
getHiddenPropertyNames(
catalogIdent, HasPropertyMetadata::tablePropertiesMetadata,
table.properties()));
}
+
+ private List<ColumnEntity> toColumnEntities(Column[] columns, AuditInfo
audit) {
+ return columns == null
+ ? Collections.emptyList()
+ : Arrays.stream(columns)
+ .map(c -> ColumnEntity.toColumnEntity(c, idGenerator.nextId(),
audit))
+ .collect(Collectors.toList());
+ }
+
+ private boolean isSameColumn(Column left, ColumnEntity right) {
+ return Objects.equal(left.name(), right.name())
+ && Objects.equal(left.dataType(), right.dataType())
+ && Objects.equal(left.comment(), right.comment())
+ && left.nullable() == right.nullable()
+ && left.autoIncrement() == right.autoIncrement()
+ && Objects.equal(left.defaultValue(), right.defaultValue());
+ }
+
+ private Pair<Boolean, List<ColumnEntity>> updateColumnsIfNecessary(
+ Table tableFromCatalog, TableEntity tableFromGravitino) {
+ if (tableFromCatalog == null || tableFromGravitino == null) {
+ LOG.warn(
+ "Cannot update columns for table when altering because table or
table entity is "
+ + "null");
+ return Pair.of(false, Collections.emptyList());
+ }
+
+ Map<String, Column> columnsFromCatalogTable =
+ tableFromCatalog.columns() == null
+ ? Collections.emptyMap()
+ : Arrays.stream(tableFromCatalog.columns())
+ .collect(Collectors.toMap(Column::name, Function.identity()));
+ Map<String, ColumnEntity> columnsFromTableEntity =
+ tableFromGravitino.columns() == null
+ ? Collections.emptyMap()
+ : tableFromGravitino.columns().stream()
+ .collect(Collectors.toMap(ColumnEntity::name,
Function.identity()));
+
+ // Check if columns need to be updated in Gravitino store
+ List<ColumnEntity> columnsToInsert = Lists.newArrayList();
+ boolean columnsNeedsUpdate = false;
+ for (Map.Entry<String, ColumnEntity> entry :
columnsFromTableEntity.entrySet()) {
+ Column column = columnsFromCatalogTable.get(entry.getKey());
+ if (column == null) {
+ LOG.debug(
+ "Column {} is not found in the table from underlying source, it
will be removed"
+ + " from the table entity",
+ entry.getKey());
+ columnsNeedsUpdate = true;
+
+ } else if (!isSameColumn(column, entry.getValue())) {
+ // If the column need to be updated, we create a new ColumnEntity with
the same id
+ LOG.debug(
+ "Column {} is found in the table from underlying source, but it is
different "
+ + "from the one in the table entity, it will be updated",
+ entry.getKey());
+
+ ColumnEntity updatedColumnEntity =
+ ColumnEntity.builder()
+ .withId(entry.getValue().id())
+ .withName(column.name())
+ .withDataType(column.dataType())
+ .withComment(column.comment())
+ .withNullable(column.nullable())
+ .withAutoIncrement(column.autoIncrement())
+ .withDefaultValue(column.defaultValue())
+ .withAuditInfo(
+ AuditInfo.builder()
+ .withCreator(entry.getValue().auditInfo().creator())
+
.withCreateTime(entry.getValue().auditInfo().createTime())
+
.withLastModifier(PrincipalUtils.getCurrentPrincipal().getName())
+ .withLastModifiedTime(Instant.now())
+ .build())
+ .build();
+
+ columnsNeedsUpdate = true;
+ columnsToInsert.add(updatedColumnEntity);
+
+ } else {
+ // If the column is the same, we keep the original ColumnEntity
+ columnsToInsert.add(entry.getValue());
+ }
+ }
+
+ // Check if there are new columns in the table from the underlying source
+ for (Map.Entry<String, Column> entry : columnsFromCatalogTable.entrySet())
{
+ if (!columnsFromTableEntity.containsKey(entry.getKey())) {
+ LOG.debug(
+ "Column {} is found in the table from underlying source but not in
the table "
+ + "entity, it will be added to the table entity",
+ entry.getKey());
+ ColumnEntity newColumnEntity =
+ ColumnEntity.toColumnEntity(
+ entry.getValue(),
+ idGenerator.nextId(),
+ AuditInfo.builder()
+
.withCreator(PrincipalUtils.getCurrentPrincipal().getName())
+ .withCreateTime(Instant.now())
+ .build());
+
+ columnsNeedsUpdate = true;
+ columnsToInsert.add(newColumnEntity);
+ }
+ }
+
+ return Pair.of(columnsNeedsUpdate, columnsToInsert);
+ }
+
+ private TableEntity updateColumnsIfNecessaryWhenLoad(
+ NameIdentifier tableIdent, EntityCombinedTable combinedTable) {
+ Pair<Boolean, List<ColumnEntity>> columnsUpdateResult =
+ updateColumnsIfNecessary(
+ combinedTable.tableFromCatalog(),
combinedTable.tableFromGravitino());
+
+ // No need to update the columns
+ if (!columnsUpdateResult.getLeft()) {
+ return combinedTable.tableFromGravitino();
+ }
+
+ // Update the columns in the Gravitino store
+ return TreeLockUtils.doWithTreeLock(
+ tableIdent,
+ LockType.WRITE,
+ () ->
+ operateOnEntity(
+ tableIdent,
+ id ->
+ store.update(
+ id,
+ TableEntity.class,
+ TABLE,
+ entity ->
+ TableEntity.builder()
+ .withId(entity.id())
+ .withName(entity.name())
+ .withNamespace(entity.namespace())
+ .withColumns(columnsUpdateResult.getRight())
+ .withAuditInfo(
+ AuditInfo.builder()
+
.withCreator(entity.auditInfo().creator())
+
.withCreateTime(entity.auditInfo().createTime())
+ .withLastModifier(
+
PrincipalUtils.getCurrentPrincipal().getName())
+ .withLastModifiedTime(Instant.now())
+ .build())
+ .build()),
+ "UPDATE",
+ combinedTable.tableFromGravitino().id()));
+ }
}
diff --git a/core/src/main/java/org/apache/gravitino/meta/ColumnEntity.java
b/core/src/main/java/org/apache/gravitino/meta/ColumnEntity.java
index 5b89bfce5..379044260 100644
--- a/core/src/main/java/org/apache/gravitino/meta/ColumnEntity.java
+++ b/core/src/main/java/org/apache/gravitino/meta/ColumnEntity.java
@@ -150,6 +150,19 @@ public class ColumnEntity implements Entity, Auditable {
return new Builder();
}
+ public static ColumnEntity toColumnEntity(Column column, long uid, AuditInfo
audit) {
+ return builder()
+ .withId(uid)
+ .withName(column.name())
+ .withComment(column.comment())
+ .withDataType(column.dataType())
+ .withNullable(column.nullable())
+ .withAutoIncrement(column.autoIncrement())
+ .withDefaultValue(column.defaultValue())
+ .withAuditInfo(audit)
+ .build();
+ }
+
public static class Builder {
private final ColumnEntity columnEntity;
diff --git a/core/src/test/java/org/apache/gravitino/TestColumn.java
b/core/src/test/java/org/apache/gravitino/TestColumn.java
index 93af75c05..7085da6d3 100644
--- a/core/src/test/java/org/apache/gravitino/TestColumn.java
+++ b/core/src/test/java/org/apache/gravitino/TestColumn.java
@@ -40,6 +40,7 @@ public class TestColumn extends BaseColumn {
column.comment = comment;
column.dataType = dataType;
column.nullable = nullable;
+ column.autoIncrement = autoIncrement;
column.defaultValue = defaultValue;
return column;
diff --git
a/core/src/test/java/org/apache/gravitino/catalog/TestTableNormalizeDispatcher.java
b/core/src/test/java/org/apache/gravitino/catalog/TestTableNormalizeDispatcher.java
index 2c8938edc..c45f5cab2 100644
---
a/core/src/test/java/org/apache/gravitino/catalog/TestTableNormalizeDispatcher.java
+++
b/core/src/test/java/org/apache/gravitino/catalog/TestTableNormalizeDispatcher.java
@@ -22,6 +22,8 @@ import com.google.common.collect.ImmutableMap;
import java.io.IOException;
import java.util.Arrays;
import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
import org.apache.gravitino.MetadataObjects;
import org.apache.gravitino.NameIdentifier;
import org.apache.gravitino.Namespace;
@@ -178,8 +180,11 @@ public class TestTableNormalizeDispatcher extends
TestOperationDispatcher {
private void assertTableCaseInsensitive(
NameIdentifier tableIdent, Column[] expectedColumns, Table table) {
Assertions.assertEquals(tableIdent.name().toLowerCase(), table.name());
- Assertions.assertEquals(expectedColumns[0].name().toLowerCase(),
table.columns()[0].name());
- Assertions.assertEquals(expectedColumns[1].name().toLowerCase(),
table.columns()[1].name());
+ Set<String> expectedColumnNames =
+ Arrays.stream(expectedColumns).map(c ->
c.name().toLowerCase()).collect(Collectors.toSet());
+ Set<String> actualColumnNames =
+
Arrays.stream(table.columns()).map(Column::name).collect(Collectors.toSet());
+ Assertions.assertEquals(expectedColumnNames, actualColumnNames);
Assertions.assertEquals(
expectedColumns[0].name().toLowerCase(),
table.partitioning()[0].references()[0].fieldName()[0]);
diff --git
a/core/src/test/java/org/apache/gravitino/catalog/TestTableOperationDispatcher.java
b/core/src/test/java/org/apache/gravitino/catalog/TestTableOperationDispatcher.java
index 1dd31fd33..f31b95e1e 100644
---
a/core/src/test/java/org/apache/gravitino/catalog/TestTableOperationDispatcher.java
+++
b/core/src/test/java/org/apache/gravitino/catalog/TestTableOperationDispatcher.java
@@ -38,8 +38,11 @@ import java.time.Instant;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import java.util.Optional;
+import java.util.function.Function;
+import java.util.stream.Collectors;
import org.apache.commons.lang3.reflect.FieldUtils;
import org.apache.gravitino.Config;
import org.apache.gravitino.GravitinoEnv;
@@ -52,10 +55,12 @@ import org.apache.gravitino.connector.TestCatalogOperations;
import org.apache.gravitino.exceptions.NoSuchEntityException;
import org.apache.gravitino.lock.LockManager;
import org.apache.gravitino.meta.AuditInfo;
+import org.apache.gravitino.meta.ColumnEntity;
import org.apache.gravitino.meta.TableEntity;
import org.apache.gravitino.rel.Column;
import org.apache.gravitino.rel.Table;
import org.apache.gravitino.rel.TableChange;
+import org.apache.gravitino.rel.expressions.literals.Literals;
import org.apache.gravitino.rel.expressions.transforms.Transform;
import org.apache.gravitino.rel.types.Types;
import org.junit.jupiter.api.Assertions;
@@ -345,4 +350,463 @@ public class TestTableOperationDispatcher extends
TestOperationDispatcher {
Assertions.assertTrue(entityStore.exists(NameIdentifier.of(tableNs.levels()),
SCHEMA));
Assertions.assertTrue(entityStore.exists(tableIdent, TABLE));
}
+
+ @Test
+ public void testCreateAndLoadTableWithColumn() throws IOException {
+ Namespace tableNs = Namespace.of(metalake, catalog, "schema91");
+ Map<String, String> props = ImmutableMap.of("k1", "v1", "k2", "v2");
+
schemaOperationDispatcher.createSchema(NameIdentifier.of(tableNs.levels()),
"comment", props);
+
+ NameIdentifier tableIdent = NameIdentifier.of(tableNs, "table41");
+ Column[] columns =
+ new Column[] {
+ TestColumn.builder()
+ .withName("col1")
+ .withType(Types.StringType.get())
+ .withComment("comment1")
+ .withNullable(true)
+ .withAutoIncrement(true)
+ .withDefaultValue(Literals.stringLiteral("1"))
+ .build(),
+ TestColumn.builder()
+ .withName("col2")
+ .withType(Types.StringType.get())
+ .withComment("comment2")
+ .withNullable(false)
+ .withAutoIncrement(false)
+ .withDefaultValue(Literals.stringLiteral("2"))
+ .build()
+ };
+
+ Table table1 =
+ tableOperationDispatcher.createTable(
+ tableIdent, columns, "comment", props, new Transform[0]);
+
+ Table loadedTable1 = tableOperationDispatcher.loadTable(tableIdent);
+ Assertions.assertEquals(table1.name(), loadedTable1.name());
+ Assertions.assertEquals(table1.comment(), loadedTable1.comment());
+ testProperties(table1.properties(), loadedTable1.properties());
+ testColumns(columns, loadedTable1.columns());
+
+ // The columns from table and table entity should be the same after
creating.
+ TableEntity tableEntity = entityStore.get(tableIdent, TABLE,
TableEntity.class);
+ Assertions.assertNotNull(tableEntity);
+ Assertions.assertEquals("table41", tableEntity.name());
+ testColumnAndColumnEntities(columns, tableEntity.columns());
+
+ // Test if the column from table is not matched with the column from table
entity
+ TestCatalog testCatalog =
+ (TestCatalog) catalogManager.loadCatalog(NameIdentifier.of(metalake,
catalog));
+ TestCatalogOperations testCatalogOperations = (TestCatalogOperations)
testCatalog.ops();
+
+ // 1. Update the existing column
+ Table alteredTable2 =
+ testCatalogOperations.alterTable(
+ tableIdent, TableChange.renameColumn(new String[] {"col1"},
"col3"));
+ Table loadedTable2 = tableOperationDispatcher.loadTable(tableIdent);
+ testColumns(alteredTable2.columns(), loadedTable2.columns());
+
+ // columns in table entity should be updated to match the columns in table
+ TableEntity tableEntity2 = entityStore.get(tableIdent, TABLE,
TableEntity.class);
+ testColumnAndColumnEntities(alteredTable2.columns(),
tableEntity2.columns());
+
+ // 2. Add a new column
+ Table alteredTable3 =
+ testCatalogOperations.alterTable(
+ tableIdent,
+ TableChange.addColumn(
+ new String[] {"col4"},
+ Types.StringType.get(),
+ "comment4",
+ TableChange.ColumnPosition.first(),
+ true,
+ true,
+ Literals.stringLiteral("4")));
+
+ Table loadedTable3 = tableOperationDispatcher.loadTable(tableIdent);
+ testColumns(alteredTable3.columns(), loadedTable3.columns());
+
+ TableEntity tableEntity3 = entityStore.get(tableIdent, TABLE,
TableEntity.class);
+ testColumnAndColumnEntities(alteredTable3.columns(),
tableEntity3.columns());
+
+ // 3. Drop a column
+ Table alteredTable4 =
+ testCatalogOperations.alterTable(
+ tableIdent, TableChange.deleteColumn(new String[] {"col2"}, true));
+ Table loadedTable4 = tableOperationDispatcher.loadTable(tableIdent);
+ testColumns(alteredTable4.columns(), loadedTable4.columns());
+
+ TableEntity tableEntity4 = entityStore.get(tableIdent, TABLE,
TableEntity.class);
+ testColumnAndColumnEntities(alteredTable4.columns(),
tableEntity4.columns());
+
+ // No column for the table
+ Table alteredTable5 =
+ testCatalogOperations.alterTable(
+ tableIdent,
+ TableChange.deleteColumn(new String[] {"col3"}, true),
+ TableChange.deleteColumn(new String[] {"col4"}, true));
+ Table loadedTable5 = tableOperationDispatcher.loadTable(tableIdent);
+ Assertions.assertEquals(0, alteredTable5.columns().length);
+ Assertions.assertEquals(0, loadedTable5.columns().length);
+
+ TableEntity tableEntity5 = entityStore.get(tableIdent, TABLE,
TableEntity.class);
+ Assertions.assertEquals(0, tableEntity5.columns().size());
+
+ // Re-add columns to the table
+ Table alteredTable6 =
+ testCatalogOperations.alterTable(
+ tableIdent,
+ TableChange.addColumn(
+ new String[] {"col5"},
+ Types.StringType.get(),
+ "comment5",
+ TableChange.ColumnPosition.first(),
+ true,
+ true,
+ Literals.stringLiteral("5")),
+ TableChange.addColumn(
+ new String[] {"col6"},
+ Types.StringType.get(),
+ "comment6",
+ TableChange.ColumnPosition.first(),
+ false,
+ false,
+ Literals.stringLiteral("2")));
+ Table loadedTable6 = tableOperationDispatcher.loadTable(tableIdent);
+ testColumns(alteredTable6.columns(), loadedTable6.columns());
+
+ TableEntity tableEntity6 = entityStore.get(tableIdent, TABLE,
TableEntity.class);
+ testColumnAndColumnEntities(alteredTable6.columns(),
tableEntity6.columns());
+ }
+
+ @Test
+ public void testCreateAndAlterTableWithColumn() throws IOException {
+ Namespace tableNs = Namespace.of(metalake, catalog, "schema101");
+ Map<String, String> props = ImmutableMap.of("k1", "v1", "k2", "v2");
+
schemaOperationDispatcher.createSchema(NameIdentifier.of(tableNs.levels()),
"comment", props);
+
+ NameIdentifier tableIdent = NameIdentifier.of(tableNs, "table51");
+ Column[] columns =
+ new Column[] {
+ TestColumn.builder()
+ .withName("col1")
+ .withType(Types.StringType.get())
+ .withComment("comment1")
+ .withNullable(true)
+ .withAutoIncrement(true)
+ .withDefaultValue(Literals.stringLiteral("1"))
+ .build(),
+ TestColumn.builder()
+ .withName("col2")
+ .withType(Types.StringType.get())
+ .withComment("comment2")
+ .withNullable(false)
+ .withAutoIncrement(false)
+ .withDefaultValue(Literals.stringLiteral("2"))
+ .build()
+ };
+
+ Table table1 =
+ tableOperationDispatcher.createTable(
+ tableIdent, columns, "comment", props, new Transform[0]);
+ testColumns(columns, table1.columns());
+
+ // 1. Rename the column
+ Table alteredTable1 =
+ tableOperationDispatcher.alterTable(
+ tableIdent, TableChange.renameColumn(new String[] {"col1"},
"col3"));
+ Column[] expectedColumns =
+ new Column[] {
+ TestColumn.builder()
+ .withName("col3")
+ .withType(Types.StringType.get())
+ .withComment("comment1")
+ .withNullable(true)
+ .withAutoIncrement(true)
+ .withDefaultValue(Literals.stringLiteral("1"))
+ .build(),
+ TestColumn.builder()
+ .withName("col2")
+ .withType(Types.StringType.get())
+ .withComment("comment2")
+ .withNullable(false)
+ .withAutoIncrement(false)
+ .withDefaultValue(Literals.stringLiteral("2"))
+ .build()
+ };
+ testColumns(expectedColumns, alteredTable1.columns());
+
+ TableEntity tableEntity1 = entityStore.get(tableIdent, TABLE,
TableEntity.class);
+ testColumnAndColumnEntities(expectedColumns, tableEntity1.columns());
+
+ // 2. Add a new column
+ Table alteredTable2 =
+ tableOperationDispatcher.alterTable(
+ tableIdent,
+ TableChange.addColumn(
+ new String[] {"col4"},
+ Types.StringType.get(),
+ "comment4",
+ TableChange.ColumnPosition.first(),
+ true,
+ true,
+ Literals.stringLiteral("4")));
+ Column[] expectedColumns2 =
+ new Column[] {
+ TestColumn.builder()
+ .withName("col4")
+ .withType(Types.StringType.get())
+ .withComment("comment4")
+ .withNullable(true)
+ .withAutoIncrement(true)
+ .withDefaultValue(Literals.stringLiteral("4"))
+ .build(),
+ TestColumn.builder()
+ .withName("col3")
+ .withType(Types.StringType.get())
+ .withComment("comment1")
+ .withNullable(true)
+ .withAutoIncrement(true)
+ .withDefaultValue(Literals.stringLiteral("1"))
+ .build(),
+ TestColumn.builder()
+ .withName("col2")
+ .withType(Types.StringType.get())
+ .withComment("comment2")
+ .withNullable(false)
+ .withAutoIncrement(false)
+ .withDefaultValue(Literals.stringLiteral("2"))
+ .build()
+ };
+
+ testColumns(expectedColumns2, alteredTable2.columns());
+
+ TableEntity tableEntity2 = entityStore.get(tableIdent, TABLE,
TableEntity.class);
+ testColumnAndColumnEntities(expectedColumns2, tableEntity2.columns());
+
+ // 3. Drop a column
+ Table alteredTable3 =
+ tableOperationDispatcher.alterTable(
+ tableIdent,
+ TableChange.deleteColumn(new String[] {"col2"}, true),
+ TableChange.deleteColumn(new String[] {"col3"}, true));
+ Column[] expectedColumns3 =
+ new Column[] {
+ TestColumn.builder()
+ .withName("col4")
+ .withType(Types.StringType.get())
+ .withComment("comment4")
+ .withNullable(true)
+ .withAutoIncrement(true)
+ .withDefaultValue(Literals.stringLiteral("4"))
+ .build()
+ };
+ testColumns(expectedColumns3, alteredTable3.columns());
+
+ TableEntity tableEntity3 = entityStore.get(tableIdent, TABLE,
TableEntity.class);
+ testColumnAndColumnEntities(expectedColumns3, tableEntity3.columns());
+
+ // 4. Update column default value
+ Table alteredTable4 =
+ tableOperationDispatcher.alterTable(
+ tableIdent,
+ TableChange.updateColumnDefaultValue(
+ new String[] {"col4"}, Literals.stringLiteral("5")));
+
+ Column[] expectedColumns4 =
+ new Column[] {
+ TestColumn.builder()
+ .withName("col4")
+ .withType(Types.StringType.get())
+ .withComment("comment4")
+ .withNullable(true)
+ .withAutoIncrement(true)
+ .withDefaultValue(Literals.stringLiteral("5"))
+ .build()
+ };
+ testColumns(expectedColumns4, alteredTable4.columns());
+
+ TableEntity tableEntity4 = entityStore.get(tableIdent, TABLE,
TableEntity.class);
+ testColumnAndColumnEntities(expectedColumns4, tableEntity4.columns());
+
+ // 5. Update column type
+ Table alteredTable5 =
+ tableOperationDispatcher.alterTable(
+ tableIdent,
+ TableChange.updateColumnType(new String[] {"col4"},
Types.IntegerType.get()));
+
+ Column[] expectedColumns5 =
+ new Column[] {
+ TestColumn.builder()
+ .withName("col4")
+ .withType(Types.IntegerType.get())
+ .withComment("comment4")
+ .withNullable(true)
+ .withAutoIncrement(true)
+ .withDefaultValue(Literals.stringLiteral("5"))
+ .build()
+ };
+
+ testColumns(expectedColumns5, alteredTable5.columns());
+
+ TableEntity tableEntity5 = entityStore.get(tableIdent, TABLE,
TableEntity.class);
+ testColumnAndColumnEntities(expectedColumns5, tableEntity5.columns());
+
+ // 6. Update column comment
+ Table alteredTable6 =
+ tableOperationDispatcher.alterTable(
+ tableIdent, TableChange.updateColumnComment(new String[] {"col4"},
"new comment"));
+
+ Column[] expectedColumns6 =
+ new Column[] {
+ TestColumn.builder()
+ .withName("col4")
+ .withType(Types.IntegerType.get())
+ .withComment("new comment")
+ .withNullable(true)
+ .withAutoIncrement(true)
+ .withDefaultValue(Literals.stringLiteral("5"))
+ .build()
+ };
+
+ testColumns(expectedColumns6, alteredTable6.columns());
+
+ TableEntity tableEntity6 = entityStore.get(tableIdent, TABLE,
TableEntity.class);
+ testColumnAndColumnEntities(expectedColumns6, tableEntity6.columns());
+
+ // 7. Update column nullable
+ Table alteredTable7 =
+ tableOperationDispatcher.alterTable(
+ tableIdent, TableChange.updateColumnNullability(new String[]
{"col4"}, false));
+
+ Column[] expectedColumns7 =
+ new Column[] {
+ TestColumn.builder()
+ .withName("col4")
+ .withType(Types.IntegerType.get())
+ .withComment("new comment")
+ .withNullable(false)
+ .withAutoIncrement(true)
+ .withDefaultValue(Literals.stringLiteral("5"))
+ .build()
+ };
+
+ testColumns(expectedColumns7, alteredTable7.columns());
+
+ TableEntity tableEntity7 = entityStore.get(tableIdent, TABLE,
TableEntity.class);
+ testColumnAndColumnEntities(expectedColumns7, tableEntity7.columns());
+
+ // 8. Update column auto increment
+ Table alteredTable8 =
+ tableOperationDispatcher.alterTable(
+ tableIdent, TableChange.updateColumnAutoIncrement(new String[]
{"col4"}, false));
+
+ Column[] expectedColumns8 =
+ new Column[] {
+ TestColumn.builder()
+ .withName("col4")
+ .withType(Types.IntegerType.get())
+ .withComment("new comment")
+ .withNullable(false)
+ .withAutoIncrement(false)
+ .withDefaultValue(Literals.stringLiteral("5"))
+ .build()
+ };
+
+ testColumns(expectedColumns8, alteredTable8.columns());
+
+ TableEntity tableEntity8 = entityStore.get(tableIdent, TABLE,
TableEntity.class);
+ testColumnAndColumnEntities(expectedColumns8, tableEntity8.columns());
+ }
+
+ @Test
+ public void testCreateAndDropTableWithColumn() throws IOException {
+ Namespace tableNs = Namespace.of(metalake, catalog, "schema111");
+ Map<String, String> props = ImmutableMap.of("k1", "v1", "k2", "v2");
+
schemaOperationDispatcher.createSchema(NameIdentifier.of(tableNs.levels()),
"comment", props);
+
+ NameIdentifier tableIdent = NameIdentifier.of(tableNs, "table61");
+ Column[] columns =
+ new Column[] {
+ TestColumn.builder()
+ .withName("col1")
+ .withType(Types.StringType.get())
+ .withComment("comment1")
+ .withNullable(true)
+ .withAutoIncrement(true)
+ .withDefaultValue(Literals.stringLiteral("1"))
+ .build(),
+ TestColumn.builder()
+ .withName("col2")
+ .withType(Types.StringType.get())
+ .withComment("comment2")
+ .withNullable(false)
+ .withAutoIncrement(false)
+ .withDefaultValue(Literals.stringLiteral("2"))
+ .build()
+ };
+
+ Table table1 =
+ tableOperationDispatcher.createTable(
+ tableIdent, columns, "comment", props, new Transform[0]);
+ testColumns(columns, table1.columns());
+
+ // Delete table
+ boolean dropped = tableOperationDispatcher.dropTable(tableIdent);
+ Assertions.assertTrue(dropped);
+ Assertions.assertFalse(entityStore.exists(tableIdent, TABLE));
+ }
+
+ private static void testColumns(Column[] expectedColumns, Column[]
actualColumns) {
+ Map<String, Column> expectedColumnMap =
+ expectedColumns == null
+ ? Collections.emptyMap()
+ : Arrays.stream(expectedColumns)
+ .collect(Collectors.toMap(c -> c.name().toLowerCase(),
Function.identity()));
+ Map<String, Column> actualColumnMap =
+ actualColumns == null
+ ? Collections.emptyMap()
+ : Arrays.stream(actualColumns)
+ .collect(Collectors.toMap(Column::name, Function.identity()));
+
+ Assertions.assertEquals(expectedColumnMap.size(), actualColumnMap.size());
+ expectedColumnMap.forEach(
+ (name, expectedColumn) -> {
+ Column actualColumn = actualColumnMap.get(name);
+ Assertions.assertNotNull(actualColumn);
+ Assertions.assertEquals(expectedColumn.name().toLowerCase(),
actualColumn.name());
+ Assertions.assertEquals(expectedColumn.dataType(),
actualColumn.dataType());
+ Assertions.assertEquals(expectedColumn.comment(),
actualColumn.comment());
+ Assertions.assertEquals(expectedColumn.nullable(),
actualColumn.nullable());
+ Assertions.assertEquals(expectedColumn.autoIncrement(),
actualColumn.autoIncrement());
+ Assertions.assertEquals(expectedColumn.defaultValue(),
actualColumn.defaultValue());
+ });
+ }
+
+ private static void testColumnAndColumnEntities(
+ Column[] expectedColumns, List<ColumnEntity> ColumnEntities) {
+ Map<String, Column> expectedColumnMap =
+ expectedColumns == null
+ ? Collections.emptyMap()
+ : Arrays.stream(expectedColumns)
+ .collect(Collectors.toMap(Column::name, Function.identity()));
+ Map<String, ColumnEntity> actualColumnMap =
+ ColumnEntities == null
+ ? Collections.emptyMap()
+ : ColumnEntities.stream()
+ .collect(Collectors.toMap(ColumnEntity::name,
Function.identity()));
+
+ Assertions.assertEquals(expectedColumnMap.size(), actualColumnMap.size());
+ expectedColumnMap.forEach(
+ (name, expectedColumn) -> {
+ ColumnEntity actualColumn = actualColumnMap.get(name);
+ Assertions.assertNotNull(actualColumn);
+ Assertions.assertEquals(expectedColumn.name(), actualColumn.name());
+ Assertions.assertEquals(expectedColumn.dataType(),
actualColumn.dataType());
+ Assertions.assertEquals(expectedColumn.comment(),
actualColumn.comment());
+ Assertions.assertEquals(expectedColumn.nullable(),
actualColumn.nullable());
+ Assertions.assertEquals(expectedColumn.autoIncrement(),
actualColumn.autoIncrement());
+ Assertions.assertEquals(expectedColumn.defaultValue(),
actualColumn.defaultValue());
+ });
+ }
}
diff --git
a/core/src/test/java/org/apache/gravitino/connector/TestCatalogOperations.java
b/core/src/test/java/org/apache/gravitino/connector/TestCatalogOperations.java
index d6bbd81c3..13c465205 100644
---
a/core/src/test/java/org/apache/gravitino/connector/TestCatalogOperations.java
+++
b/core/src/test/java/org/apache/gravitino/connector/TestCatalogOperations.java
@@ -23,14 +23,18 @@ import com.google.common.collect.Maps;
import java.io.File;
import java.io.IOException;
import java.time.Instant;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
+import java.util.function.Function;
+import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils;
import org.apache.gravitino.Catalog;
import org.apache.gravitino.NameIdentifier;
import org.apache.gravitino.Namespace;
import org.apache.gravitino.Schema;
import org.apache.gravitino.SchemaChange;
+import org.apache.gravitino.TestColumn;
import org.apache.gravitino.TestFileset;
import org.apache.gravitino.TestSchema;
import org.apache.gravitino.TestTable;
@@ -198,17 +202,24 @@ public class TestCatalogOperations
throw new TableAlreadyExistsException("Table %s already exists",
ident);
}
} else {
- throw new IllegalArgumentException("Unsupported table change: " +
change);
+ // do nothing
}
}
+ TableChange.ColumnChange[] columnChanges =
+ Arrays.stream(changes)
+ .filter(change -> change instanceof TableChange.ColumnChange)
+ .map(change -> (TableChange.ColumnChange) change)
+ .toArray(TableChange.ColumnChange[]::new);
+ Column[] newColumns = updateColumns(table.columns(), columnChanges);
+
TestTable updatedTable =
TestTable.builder()
.withName(newIdent.name())
.withComment(table.comment())
.withProperties(new HashMap<>(newProps))
.withAuditInfo(updatedAuditInfo)
- .withColumns(table.columns())
+ .withColumns(newColumns)
.withPartitioning(table.partitioning())
.withDistribution(table.distribution())
.withSortOrders(table.sortOrder())
@@ -634,4 +645,126 @@ public class TestCatalogOperations
return false;
}
}
+
+ private Column[] updateColumns(Column[] columns, TableChange.ColumnChange[]
columnChanges) {
+ Map<String, Column> columnMap =
+ Arrays.stream(columns).collect(Collectors.toMap(Column::name,
Function.identity()));
+
+ for (TableChange.ColumnChange columnChange : columnChanges) {
+ if (columnChange instanceof TableChange.AddColumn) {
+ TableChange.AddColumn addColumn = (TableChange.AddColumn) columnChange;
+ TestColumn column =
+ TestColumn.builder()
+ .withName(String.join(".", addColumn.fieldName()))
+ .withComment(addColumn.getComment())
+ .withType(addColumn.getDataType())
+ .withNullable(addColumn.isNullable())
+ .withAutoIncrement(addColumn.isAutoIncrement())
+ .withDefaultValue(addColumn.getDefaultValue())
+ .build();
+ columnMap.put(column.name(), column);
+
+ } else if (columnChange instanceof TableChange.DeleteColumn) {
+ columnMap.remove(String.join(".", columnChange.fieldName()));
+
+ } else if (columnChange instanceof TableChange.RenameColumn) {
+ String oldName = String.join(".", columnChange.fieldName());
+ String newName = ((TableChange.RenameColumn)
columnChange).getNewName();
+ Column column = columnMap.remove(oldName);
+ TestColumn newColumn =
+ TestColumn.builder()
+ .withName(newName)
+ .withComment(column.comment())
+ .withType(column.dataType())
+ .withNullable(column.nullable())
+ .withAutoIncrement(column.autoIncrement())
+ .withDefaultValue(column.defaultValue())
+ .build();
+ columnMap.put(newName, newColumn);
+
+ } else if (columnChange instanceof TableChange.UpdateColumnDefaultValue)
{
+ String columnName = String.join(".", columnChange.fieldName());
+ TableChange.UpdateColumnDefaultValue updateColumnDefaultValue =
+ (TableChange.UpdateColumnDefaultValue) columnChange;
+ Column oldColumn = columnMap.get(columnName);
+ TestColumn newColumn =
+ TestColumn.builder()
+ .withName(columnName)
+ .withComment(oldColumn.comment())
+ .withType(oldColumn.dataType())
+ .withNullable(oldColumn.nullable())
+ .withAutoIncrement(oldColumn.autoIncrement())
+
.withDefaultValue(updateColumnDefaultValue.getNewDefaultValue())
+ .build();
+ columnMap.put(columnName, newColumn);
+
+ } else if (columnChange instanceof TableChange.UpdateColumnType) {
+ String columnName = String.join(".", columnChange.fieldName());
+ TableChange.UpdateColumnType updateColumnType =
(TableChange.UpdateColumnType) columnChange;
+ Column oldColumn = columnMap.get(columnName);
+ TestColumn newColumn =
+ TestColumn.builder()
+ .withName(columnName)
+ .withComment(oldColumn.comment())
+ .withType(updateColumnType.getNewDataType())
+ .withNullable(oldColumn.nullable())
+ .withAutoIncrement(oldColumn.autoIncrement())
+ .withDefaultValue(oldColumn.defaultValue())
+ .build();
+ columnMap.put(columnName, newColumn);
+
+ } else if (columnChange instanceof TableChange.UpdateColumnComment) {
+ String columnName = String.join(".", columnChange.fieldName());
+ TableChange.UpdateColumnComment updateColumnComment =
+ (TableChange.UpdateColumnComment) columnChange;
+ Column oldColumn = columnMap.get(columnName);
+ TestColumn newColumn =
+ TestColumn.builder()
+ .withName(columnName)
+ .withComment(updateColumnComment.getNewComment())
+ .withType(oldColumn.dataType())
+ .withNullable(oldColumn.nullable())
+ .withAutoIncrement(oldColumn.autoIncrement())
+ .withDefaultValue(oldColumn.defaultValue())
+ .build();
+ columnMap.put(columnName, newColumn);
+
+ } else if (columnChange instanceof TableChange.UpdateColumnNullability) {
+ String columnName = String.join(".", columnChange.fieldName());
+ TableChange.UpdateColumnNullability updateColumnNullable =
+ (TableChange.UpdateColumnNullability) columnChange;
+ Column oldColumn = columnMap.get(columnName);
+ TestColumn newColumn =
+ TestColumn.builder()
+ .withName(columnName)
+ .withComment(oldColumn.comment())
+ .withType(oldColumn.dataType())
+ .withNullable(updateColumnNullable.nullable())
+ .withAutoIncrement(oldColumn.autoIncrement())
+ .withDefaultValue(oldColumn.defaultValue())
+ .build();
+ columnMap.put(columnName, newColumn);
+
+ } else if (columnChange instanceof
TableChange.UpdateColumnAutoIncrement) {
+ String columnName = String.join(".", columnChange.fieldName());
+ TableChange.UpdateColumnAutoIncrement updateColumnAutoIncrement =
+ (TableChange.UpdateColumnAutoIncrement) columnChange;
+ Column oldColumn = columnMap.get(columnName);
+ TestColumn newColumn =
+ TestColumn.builder()
+ .withName(columnName)
+ .withComment(oldColumn.comment())
+ .withType(oldColumn.dataType())
+ .withNullable(oldColumn.nullable())
+ .withAutoIncrement(updateColumnAutoIncrement.isAutoIncrement())
+ .withDefaultValue(oldColumn.defaultValue())
+ .build();
+ columnMap.put(columnName, newColumn);
+
+ } else {
+ // do nothing
+ }
+ }
+ return columnMap.values().toArray(new Column[0]);
+ }
}
diff --git a/scripts/h2/schema-0.7.0-h2.sql b/scripts/h2/schema-0.7.0-h2.sql
index 8a76f1e6a..bada37abc 100644
--- a/scripts/h2/schema-0.7.0-h2.sql
+++ b/scripts/h2/schema-0.7.0-h2.sql
@@ -93,11 +93,11 @@ CREATE TABLE IF NOT EXISTS `table_column_version_info` (
`table_version` INT UNSIGNED NOT NULL COMMENT 'table version',
`column_id` BIGINT(20) UNSIGNED NOT NULL COMMENT 'column id',
`column_name` VARCHAR(128) NOT NULL COMMENT 'column name',
- `column_type` VARCHAR(128) NOT NULL COMMENT 'column type',
+ `column_type` TEXT NOT NULL COMMENT 'column type',
`column_comment` VARCHAR(256) DEFAULT '' COMMENT 'column comment',
`column_nullable` TINYINT(1) NOT NULL DEFAULT 1 COMMENT 'column nullable,
0 is not nullable, 1 is nullable',
`column_auto_increment` TINYINT(1) NOT NULL DEFAULT 0 COMMENT 'column auto
increment, 0 is not auto increment, 1 is auto increment',
- `column_default_value` VARCHAR(256) DEFAULT NULL COMMENT 'column default
value',
+ `column_default_value` TEXT DEFAULT NULL COMMENT 'column default value',
`column_op_type` TINYINT(1) NOT NULL COMMENT 'column operation type, 1 is
create, 2 is update, 3 is delete',
`deleted_at` BIGINT(20) UNSIGNED NOT NULL DEFAULT 0 COMMENT 'column
deleted at',
`audit_info` MEDIUMTEXT NOT NULL COMMENT 'column audit info',
diff --git a/scripts/h2/upgrade-0.6.0-to-0.7.0-h2.sql
b/scripts/h2/upgrade-0.6.0-to-0.7.0-h2.sql
index fba1075f5..cdf1bbdc4 100644
--- a/scripts/h2/upgrade-0.6.0-to-0.7.0-h2.sql
+++ b/scripts/h2/upgrade-0.6.0-to-0.7.0-h2.sql
@@ -25,11 +25,11 @@ CREATE TABLE IF NOT EXISTS `table_column_version_info` (
`table_version` INT UNSIGNED NOT NULL COMMENT 'table version',
`column_id` BIGINT(20) UNSIGNED NOT NULL COMMENT 'column id',
`column_name` VARCHAR(128) NOT NULL COMMENT 'column name',
- `column_type` VARCHAR(128) NOT NULL COMMENT 'column type',
+ `column_type` TEXT NOT NULL COMMENT 'column type',
`column_comment` VARCHAR(256) DEFAULT '' COMMENT 'column comment',
`column_nullable` TINYINT(1) NOT NULL DEFAULT 1 COMMENT 'column nullable,
0 is not nullable, 1 is nullable',
`column_auto_increment` TINYINT(1) NOT NULL DEFAULT 0 COMMENT 'column auto
increment, 0 is not auto increment, 1 is auto increment',
- `column_default_value` VARCHAR(256) DEFAULT NULL COMMENT 'column default
value',
+ `column_default_value` TEXT DEFAULT NULL COMMENT 'column default value',
`column_op_type` TINYINT(1) NOT NULL COMMENT 'column operation type, 1 is
create, 2 is update, 3 is delete',
`deleted_at` BIGINT(20) UNSIGNED NOT NULL DEFAULT 0 COMMENT 'column
deleted at',
`audit_info` MEDIUMTEXT NOT NULL COMMENT 'column audit info',
diff --git a/scripts/mysql/schema-0.7.0-mysql.sql
b/scripts/mysql/schema-0.7.0-mysql.sql
index 858d47d49..13f46debc 100644
--- a/scripts/mysql/schema-0.7.0-mysql.sql
+++ b/scripts/mysql/schema-0.7.0-mysql.sql
@@ -88,11 +88,11 @@ CREATE TABLE IF NOT EXISTS `table_column_version_info` (
`table_version` INT UNSIGNED NOT NULL COMMENT 'table version',
`column_id` BIGINT(20) UNSIGNED NOT NULL COMMENT 'column id',
`column_name` VARCHAR(128) NOT NULL COMMENT 'column name',
- `column_type` VARCHAR(128) NOT NULL COMMENT 'column type',
+ `column_type` TEXT NOT NULL COMMENT 'column type',
`column_comment` VARCHAR(256) DEFAULT '' COMMENT 'column comment',
`column_nullable` TINYINT(1) NOT NULL DEFAULT 1 COMMENT 'column nullable,
0 is not nullable, 1 is nullable',
`column_auto_increment` TINYINT(1) NOT NULL DEFAULT 0 COMMENT 'column auto
increment, 0 is not auto increment, 1 is auto increment',
- `column_default_value` VARCHAR(256) DEFAULT NULL COMMENT 'column default
value',
+ `column_default_value` TEXT DEFAULT NULL COMMENT 'column default value',
`column_op_type` TINYINT(1) NOT NULL COMMENT 'column operation type, 1 is
create, 2 is update, 3 is delete',
`deleted_at` BIGINT(20) UNSIGNED NOT NULL DEFAULT 0 COMMENT 'column
deleted at',
`audit_info` MEDIUMTEXT NOT NULL COMMENT 'column audit info',
diff --git a/scripts/mysql/upgrade-0.6.0-to-0.7.0-mysql.sql
b/scripts/mysql/upgrade-0.6.0-to-0.7.0-mysql.sql
index 007fc0a8d..0afe56078 100644
--- a/scripts/mysql/upgrade-0.6.0-to-0.7.0-mysql.sql
+++ b/scripts/mysql/upgrade-0.6.0-to-0.7.0-mysql.sql
@@ -25,11 +25,11 @@ CREATE TABLE IF NOT EXISTS `table_column_version_info` (
`table_version` INT UNSIGNED NOT NULL COMMENT 'table version',
`column_id` BIGINT(20) UNSIGNED NOT NULL COMMENT 'column id',
`column_name` VARCHAR(128) NOT NULL COMMENT 'column name',
- `column_type` VARCHAR(128) NOT NULL COMMENT 'column type',
+ `column_type` TEXT NOT NULL COMMENT 'column type',
`column_comment` VARCHAR(256) DEFAULT '' COMMENT 'column comment',
`column_nullable` TINYINT(1) NOT NULL DEFAULT 1 COMMENT 'column nullable,
0 is not nullable, 1 is nullable',
`column_auto_increment` TINYINT(1) NOT NULL DEFAULT 0 COMMENT 'column auto
increment, 0 is not auto increment, 1 is auto increment',
- `column_default_value` VARCHAR(256) DEFAULT NULL COMMENT 'column default
value',
+ `column_default_value` TEXT DEFAULT NULL COMMENT 'column default value',
`column_op_type` TINYINT(1) NOT NULL COMMENT 'column operation type, 1 is
create, 2 is update, 3 is delete',
`deleted_at` BIGINT(20) UNSIGNED NOT NULL DEFAULT 0 COMMENT 'column
deleted at',
`audit_info` MEDIUMTEXT NOT NULL COMMENT 'column audit info',
diff --git a/scripts/postgresql/schema-0.7.0-postgresql.sql
b/scripts/postgresql/schema-0.7.0-postgresql.sql
index e2ad46cf5..d377c57b5 100644
--- a/scripts/postgresql/schema-0.7.0-postgresql.sql
+++ b/scripts/postgresql/schema-0.7.0-postgresql.sql
@@ -149,11 +149,11 @@ CREATE TABLE IF NOT EXISTS table_column_version_info (
table_version INT NOT NULL,
column_id BIGINT NOT NULL,
column_name VARCHAR(128) NOT NULL,
- column_type VARCHAR(128) NOT NULL,
+ column_type TEXT NOT NULL,
column_comment VARCHAR(256) DEFAULT '',
column_nullable SMALLINT NOT NULL DEFAULT 1,
column_auto_increment SMALLINT NOT NULL DEFAULT 0,
- column_default_value VARCHAR(256) DEFAULT NULL,
+ column_default_value TEXT DEFAULT NULL,
column_op_type SMALLINT NOT NULL,
deleted_at BIGINT NOT NULL DEFAULT 0,
audit_info TEXT NOT NULL,