This is an automated email from the ASF dual-hosted git repository.
jshao pushed a commit to branch branch-1.1
in repository https://gitbox.apache.org/repos/asf/gravitino.git
The following commit(s) were added to refs/heads/branch-1.1 by this push:
new f153e6d055 [#10034] fix(core): Fix loading table problem due to
incorrect SQL sentence in fetch column infos (#10062)(cherry-pick) (#10079)
f153e6d055 is described below
commit f153e6d055f3068de134e5f357f235d9d5e26033
Author: Qi Yu <[email protected]>
AuthorDate: Mon Mar 2 11:26:56 2026 +0800
[#10034] fix(core): Fix loading table problem due to incorrect SQL sentence
in fetch column infos (#10062)(cherry-pick) (#10079)
### What changes were proposed in this pull request?
This pull request introduces improvements to logging for column updates,
refines the SQL query for selecting columns to prefer non-deleted
records, and adds a new test to verify this behavior. The most important
changes are grouped below by theme.
### Why are the changes needed?
It's a bug.
Fix: #10034
### Does this PR introduce _any_ user-facing change?
N/A.
### How was this patch tested?
Newly added UT and test locally.
---
.github/workflows/build.yml | 2 +-
.../catalog/TableOperationDispatcher.java | 54 ++++++++++++++++--
.../provider/base/TableColumnBaseSQLProvider.java | 5 +-
.../service/TestTableColumnMetaService.java | 64 ++++++++++++++++++++++
4 files changed, 118 insertions(+), 7 deletions(-)
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 3da6d54a18..8936a8e1c8 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -110,7 +110,7 @@ jobs:
strategy:
matrix:
java-version: [ 17 ]
- timeout-minutes: 60
+ timeout-minutes: 90
needs: changes
if: needs.changes.outputs.source_changes == 'true'
# Steps represent a sequence of tasks that will be executed as part of the
job
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 7446135834..57499b6f6d 100644
---
a/core/src/main/java/org/apache/gravitino/catalog/TableOperationDispatcher.java
+++
b/core/src/main/java/org/apache/gravitino/catalog/TableOperationDispatcher.java
@@ -671,6 +671,48 @@ public class TableOperationDispatcher extends
OperationDispatcher implements Tab
&& Objects.equal(left.defaultValue(), right.defaultValue());
}
+ private String columnDifferenceContent(
+ Column catalogColumn, int catalogPosition, ColumnEntity entityColumn) {
+ List<String> differences = Lists.newArrayList();
+ if (!Objects.equal(catalogColumn.name(), entityColumn.name())) {
+ differences.add(
+ String.format("name[catalog=%s, store=%s]", catalogColumn.name(),
entityColumn.name()));
+ }
+ if (catalogPosition != entityColumn.position()) {
+ differences.add(
+ String.format(
+ "position[catalog=%s, store=%s]", catalogPosition,
entityColumn.position()));
+ }
+ if (!Objects.equal(catalogColumn.dataType(), entityColumn.dataType())) {
+ differences.add(
+ String.format(
+ "type[catalog=%s, store=%s]", catalogColumn.dataType(),
entityColumn.dataType()));
+ }
+ if (!Objects.equal(catalogColumn.comment(), entityColumn.comment())) {
+ differences.add(
+ String.format(
+ "comment[catalog=%s, store=%s]", catalogColumn.comment(),
entityColumn.comment()));
+ }
+ if (catalogColumn.nullable() != entityColumn.nullable()) {
+ differences.add(
+ String.format(
+ "nullable[catalog=%s, store=%s]", catalogColumn.nullable(),
entityColumn.nullable()));
+ }
+ if (catalogColumn.autoIncrement() != entityColumn.autoIncrement()) {
+ differences.add(
+ String.format(
+ "autoIncrement[catalog=%s, store=%s]",
+ catalogColumn.autoIncrement(), entityColumn.autoIncrement()));
+ }
+ if (!Objects.equal(catalogColumn.defaultValue(),
entityColumn.defaultValue())) {
+ differences.add(
+ String.format(
+ "defaultValue[catalog=%s, store=%s]",
+ catalogColumn.defaultValue(), entityColumn.defaultValue()));
+ }
+ return String.join(", ", differences);
+ }
+
private Pair<Boolean, List<ColumnEntity>> updateColumnsIfNecessary(
Table tableFromCatalog, TableEntity tableFromGravitino) {
if (tableFromCatalog == null || tableFromGravitino == null) {
@@ -705,11 +747,12 @@ public class TableOperationDispatcher extends
OperationDispatcher implements Tab
columnsNeedsUpdate = true;
} else if (!isSameColumn(columnPair.getRight(), columnPair.getLeft(),
entry.getValue())) {
- // If the column need to be updated, we create a new ColumnEntity with
the same id
+ // Add debug log to print the difference between the two columns
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());
+ + "from the one in the table entity, it will be updated,
differences: {}",
+ entry.getKey(),
+ columnDifferenceContent(columnPair.getRight(),
columnPair.getLeft(), entry.getValue()));
Column column = columnPair.getRight();
ColumnEntity updatedColumnEntity =
@@ -744,9 +787,10 @@ public class TableOperationDispatcher extends
OperationDispatcher implements Tab
for (Map.Entry<String, Pair<Integer, 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 "
+ "Column {} of table: {} is found in the table from underlying
source but not in the table "
+ "entity, it will be added to the table entity",
- entry.getKey());
+ entry.getKey(),
+ tableFromGravitino.id());
ColumnEntity newColumnEntity =
ColumnEntity.toColumnEntity(
entry.getValue().getRight(),
diff --git
a/core/src/main/java/org/apache/gravitino/storage/relational/mapper/provider/base/TableColumnBaseSQLProvider.java
b/core/src/main/java/org/apache/gravitino/storage/relational/mapper/provider/base/TableColumnBaseSQLProvider.java
index f42cee072f..98ac81ecbf 100644
---
a/core/src/main/java/org/apache/gravitino/storage/relational/mapper/provider/base/TableColumnBaseSQLProvider.java
+++
b/core/src/main/java/org/apache/gravitino/storage/relational/mapper/provider/base/TableColumnBaseSQLProvider.java
@@ -123,7 +123,10 @@ public class TableColumnBaseSQLProvider {
+ " FROM "
+ TableColumnMapper.COLUMN_TABLE_NAME
+ " WHERE table_id = #{tableId} AND column_name = #{columnName} AND
deleted_at = 0"
- + " ORDER BY table_version DESC LIMIT 1";
+ // Update a column will generate two records with the same version,
one with op_type = 2
+ // (update) and another with op_type = 3 (delete). We should not
return NULL if both records
+ // exist with the same version, otherwise the caller will think the
column does not exist.
+ + " ORDER BY table_version DESC, column_op_type ASC, id DESC LIMIT 1";
}
public String selectColumnPOById(@Param("columnId") Long columnId) {
diff --git
a/core/src/test/java/org/apache/gravitino/storage/relational/service/TestTableColumnMetaService.java
b/core/src/test/java/org/apache/gravitino/storage/relational/service/TestTableColumnMetaService.java
index 528db047e5..057a12ac16 100644
---
a/core/src/test/java/org/apache/gravitino/storage/relational/service/TestTableColumnMetaService.java
+++
b/core/src/test/java/org/apache/gravitino/storage/relational/service/TestTableColumnMetaService.java
@@ -529,6 +529,70 @@ public class TestTableColumnMetaService extends
TestJDBCBackend {
() ->
TableColumnMetaService.getInstance().getColumnPOById(updatedColumn.id()));
}
+ @TestTemplate
+ public void testGetColumnIdByNamePrefersNonDeletedRecordInSameVersion()
throws IOException {
+ String catalogName = "catalog1";
+ String schemaName = "schema1";
+ createParentEntities(METALAKE_NAME, catalogName, schemaName, AUDIT_INFO);
+
+ ColumnEntity oldColumn =
+ ColumnEntity.builder()
+ .withId(RandomIdGenerator.INSTANCE.nextId())
+ .withName("column1")
+ .withPosition(0)
+ .withComment("comment1")
+ .withDataType(Types.IntegerType.get())
+ .withNullable(true)
+ .withAutoIncrement(false)
+ .withDefaultValue(Literals.integerLiteral(1))
+ .withAuditInfo(AUDIT_INFO)
+ .build();
+
+ TableEntity createdTable =
+ TableEntity.builder()
+ .withId(RandomIdGenerator.INSTANCE.nextId())
+ .withName("table_same_name")
+ .withNamespace(Namespace.of(METALAKE_NAME, catalogName,
schemaName))
+ .withColumns(Lists.newArrayList(oldColumn))
+ .withAuditInfo(AUDIT_INFO)
+ .build();
+ TableMetaService.getInstance().insertTable(createdTable, false);
+
+ TableEntity retrievedTable =
+
TableMetaService.getInstance().getTableByIdentifier(createdTable.nameIdentifier());
+
+ // Replace the column with a new column id but the same name in one table
update.
+ ColumnEntity newColumn =
+ ColumnEntity.builder()
+ .withId(RandomIdGenerator.INSTANCE.nextId())
+ .withName("column1")
+ .withPosition(0)
+ .withComment("comment1_new")
+ .withDataType(Types.LongType.get())
+ .withNullable(true)
+ .withAutoIncrement(false)
+ .withDefaultValue(Literals.longLiteral(2L))
+ .withAuditInfo(AUDIT_INFO)
+ .build();
+
+ TableEntity updatedTable =
+ TableEntity.builder()
+ .withId(retrievedTable.id())
+ .withName(retrievedTable.name())
+ .withNamespace(retrievedTable.namespace())
+ .withColumns(Lists.newArrayList(newColumn))
+ .withAuditInfo(retrievedTable.auditInfo())
+ .build();
+
+ TableMetaService.getInstance()
+ .updateTable(retrievedTable.nameIdentifier(), old -> updatedTable);
+
+ Long selectedColumnId =
+ TableColumnMetaService.getInstance()
+ .getColumnIdByTableIdAndName(retrievedTable.id(),
newColumn.name());
+ Assertions.assertEquals(newColumn.id(), selectedColumnId);
+ }
+
private void compareTwoColumns(
List<ColumnEntity> expectedColumns, List<ColumnEntity> actualColumns) {
Assertions.assertEquals(expectedColumns.size(), actualColumns.size());