This is an automated email from the ASF dual-hosted git repository.
terrymanu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shardingsphere.git
The following commit(s) were added to refs/heads/master by this push:
new 0ab7543beaa Fix firebird blob registry actual table name (#40099)
0ab7543beaa is described below
commit 0ab7543beaa5c9ee4b30c56a54703cee5f485f3b
Author: Maxim Igoshin <[email protected]>
AuthorDate: Thu Oct 15 18:05:29 2026 +0300
Fix firebird blob registry actual table name (#40099)
* Key Firebird BLOB column registry by actual table name
Tables whose names differ only by trailing digits shared one registry
entry, so BLOB columns of one table were described with the sub type of another
or lost. Store BLOB columns by the actual table name loaded from the database
and look up the actual table of a logic table through the data node rule
attributes.
* Mark Firebird actual table name lookup as high frequency invocation
Name the described column packet in the sharding table test
actualColumnPacket.
* Trigger CI
---
.../metadata/data/FirebirdBlobInfoRegistry.java | 17 ++++-------------
.../metadata/data/FirebirdBlobInfoRegistryTest.java | 9 ++++++++-
.../FirebirdPrepareStatementCommandExecutor.java | 19 +++++++++++++++++--
.../FirebirdPrepareStatementCommandExecutorTest.java | 20 ++++++++++++++++++++
4 files changed, 49 insertions(+), 16 deletions(-)
diff --git
a/database/connector/dialect/firebird/src/main/java/org/apache/shardingsphere/database/connector/firebird/metadata/data/FirebirdBlobInfoRegistry.java
b/database/connector/dialect/firebird/src/main/java/org/apache/shardingsphere/database/connector/firebird/metadata/data/FirebirdBlobInfoRegistry.java
index 13987445e04..53a6384f31a 100644
---
a/database/connector/dialect/firebird/src/main/java/org/apache/shardingsphere/database/connector/firebird/metadata/data/FirebirdBlobInfoRegistry.java
+++
b/database/connector/dialect/firebird/src/main/java/org/apache/shardingsphere/database/connector/firebird/metadata/data/FirebirdBlobInfoRegistry.java
@@ -40,7 +40,7 @@ public final class FirebirdBlobInfoRegistry {
* Refresh blob column metadata for a table.
*
* @param schemaName schema name
- * @param tableName table name
+ * @param tableName actual table name
* @param blobColumns blob column name to subtype mapping
*/
public static void refreshTable(final String schemaName, final String
tableName, final Map<String, Integer> blobColumns) {
@@ -69,7 +69,7 @@ public final class FirebirdBlobInfoRegistry {
* Determine whether column is a Firebird blob column.
*
* @param schemaName schema name
- * @param tableName table name
+ * @param tableName actual table name
* @param columnName column name
* @return whether column is a blob column
*/
@@ -85,7 +85,7 @@ public final class FirebirdBlobInfoRegistry {
* Find blob subtype for a column.
*
* @param schemaName schema name
- * @param tableName table name
+ * @param tableName actual table name
* @param columnName column name
* @return blob subtype if present
*/
@@ -103,16 +103,7 @@ public final class FirebirdBlobInfoRegistry {
private static String buildTableKey(final String schemaName, final String
tableName) {
String schemaKey = null == schemaName ? "" : toKey(schemaName);
- String logicTable = trimToLogicTableName(tableName);
- return schemaKey + "." + toKey(logicTable);
- }
-
- private static String trimToLogicTableName(final String tableName) {
- int end = tableName.length() - 1;
- while (end >= 0 && !Character.isLetter(tableName.charAt(end))) {
- end--;
- }
- return end < 0 ? tableName : tableName.substring(0, end + 1);
+ return schemaKey + "." + toKey(tableName);
}
private static String toKey(final String value) {
diff --git
a/database/connector/dialect/firebird/src/test/java/org/apache/shardingsphere/database/connector/firebird/metadata/data/FirebirdBlobInfoRegistryTest.java
b/database/connector/dialect/firebird/src/test/java/org/apache/shardingsphere/database/connector/firebird/metadata/data/FirebirdBlobInfoRegistryTest.java
index 2d2d493122c..01cc62e291b 100644
---
a/database/connector/dialect/firebird/src/test/java/org/apache/shardingsphere/database/connector/firebird/metadata/data/FirebirdBlobInfoRegistryTest.java
+++
b/database/connector/dialect/firebird/src/test/java/org/apache/shardingsphere/database/connector/firebird/metadata/data/FirebirdBlobInfoRegistryTest.java
@@ -69,11 +69,18 @@ class FirebirdBlobInfoRegistryTest {
assertThat(blobColumns.get("SENTINEL").get("EXISTING_COL"), is(9));
}
+ @Test
+ void assertRefreshTableWhenOtherTableDiffersOnlyBySuffix() {
+ FirebirdBlobInfoRegistry.refreshTable("schema_a", "t1",
Collections.singletonMap("blob_col", 1));
+ FirebirdBlobInfoRegistry.refreshTable("schema_a", "t2",
Collections.emptyMap());
+ assertTrue(FirebirdBlobInfoRegistry.isBlobColumn("schema_a", "t1",
"blob_col"));
+ }
+
@Test
void assertRefreshTable() {
Map<String, Integer> newColumns = createColumnsWithMixedNames();
FirebirdBlobInfoRegistry.refreshTable(null, "table_1", newColumns);
- Map<String, Integer> actual = blobColumns.get(".TABLE");
+ Map<String, Integer> actual = blobColumns.get(".TABLE_1");
assertTrue(actual.containsKey("BLOB_COL"));
assertThat(actual.get("BLOB_COL"), is(2));
assertThat(actual.size(), is(1));
diff --git
a/proxy/frontend/dialect/firebird/src/main/java/org/apache/shardingsphere/proxy/frontend/firebird/command/query/statement/prepare/FirebirdPrepareStatementCommandExecutor.java
b/proxy/frontend/dialect/firebird/src/main/java/org/apache/shardingsphere/proxy/frontend/firebird/command/query/statement/prepare/FirebirdPrepareStatementCommandExecutor.java
index e06ad8a3cb0..697066b8e60 100644
---
a/proxy/frontend/dialect/firebird/src/main/java/org/apache/shardingsphere/proxy/frontend/firebird/command/query/statement/prepare/FirebirdPrepareStatementCommandExecutor.java
+++
b/proxy/frontend/dialect/firebird/src/main/java/org/apache/shardingsphere/proxy/frontend/firebird/command/query/statement/prepare/FirebirdPrepareStatementCommandExecutor.java
@@ -30,6 +30,7 @@ import
org.apache.shardingsphere.database.protocol.firebird.packet.command.query
import
org.apache.shardingsphere.database.protocol.firebird.packet.command.query.statement.prepare.FirebirdReturnColumnPacket;
import
org.apache.shardingsphere.database.protocol.firebird.packet.generic.FirebirdGenericResponsePacket;
import org.apache.shardingsphere.database.protocol.packet.DatabasePacket;
+import org.apache.shardingsphere.infra.annotation.HighFrequencyInvocation;
import
org.apache.shardingsphere.infra.binder.context.available.WhereContextAvailable;
import
org.apache.shardingsphere.infra.binder.context.segment.insert.values.InsertValueContext;
import
org.apache.shardingsphere.infra.binder.context.segment.select.projection.Projection;
@@ -51,6 +52,7 @@ import
org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
import
org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereColumn;
import
org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereSchema;
import
org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereTable;
+import
org.apache.shardingsphere.infra.rule.attribute.datanode.DataNodeRuleAttribute;
import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
import org.apache.shardingsphere.mode.metadata.MetaDataContexts;
import org.apache.shardingsphere.parser.rule.SQLParserRule;
@@ -95,6 +97,7 @@ import java.util.Collections;
import java.util.LinkedList;
import java.util.Locale;
import java.util.Map;
+import java.util.Optional;
import java.util.OptionalInt;
/**
@@ -489,17 +492,29 @@ public final class
FirebirdPrepareStatementCommandExecutor implements CommandExe
if (null == table || null == column) {
return false;
}
- if
(FirebirdBlobInfoRegistry.isBlobColumn(connectionSession.getCurrentDatabaseName(),
table.getName(), column.getName())) {
+ if (null != table.getName() &&
FirebirdBlobInfoRegistry.isBlobColumn(connectionSession.getCurrentDatabaseName(),
getActualTableName(table.getName()), column.getName())) {
return true;
}
return Types.BLOB == column.getDataType();
}
+ @HighFrequencyInvocation
+ private String getActualTableName(final String logicTableName) {
+ ShardingSphereDatabase database =
ProxyContext.getInstance().getContextManager().getMetaDataContexts().getMetaData().getDatabase(connectionSession.getCurrentDatabaseName());
+ for (DataNodeRuleAttribute each :
database.getRuleMetaData().getAttributes(DataNodeRuleAttribute.class)) {
+ Optional<String> actualTableName =
each.findFirstActualTable(logicTableName);
+ if (actualTableName.isPresent()) {
+ return actualTableName.get();
+ }
+ }
+ return logicTableName;
+ }
+
private Integer resolveBlobSubtype(final ShardingSphereTable table, final
ShardingSphereColumn column, final boolean blobColumn) {
if (!blobColumn) {
return null;
}
- OptionalInt subtype =
FirebirdBlobInfoRegistry.findBlobSubtype(connectionSession.getCurrentDatabaseName(),
table.getName(), column.getName());
+ OptionalInt subtype =
FirebirdBlobInfoRegistry.findBlobSubtype(connectionSession.getCurrentDatabaseName(),
getActualTableName(table.getName()), column.getName());
return subtype.isPresent() ? subtype.getAsInt() : null;
}
diff --git
a/proxy/frontend/dialect/firebird/src/test/java/org/apache/shardingsphere/proxy/frontend/firebird/command/query/statement/prepare/FirebirdPrepareStatementCommandExecutorTest.java
b/proxy/frontend/dialect/firebird/src/test/java/org/apache/shardingsphere/proxy/frontend/firebird/command/query/statement/prepare/FirebirdPrepareStatementCommandExecutorTest.java
index f1145d48038..45829f65c58 100644
---
a/proxy/frontend/dialect/firebird/src/test/java/org/apache/shardingsphere/proxy/frontend/firebird/command/query/statement/prepare/FirebirdPrepareStatementCommandExecutorTest.java
+++
b/proxy/frontend/dialect/firebird/src/test/java/org/apache/shardingsphere/proxy/frontend/firebird/command/query/statement/prepare/FirebirdPrepareStatementCommandExecutorTest.java
@@ -41,6 +41,9 @@ import
org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSp
import
org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereTable;
import
org.apache.shardingsphere.infra.metadata.statistics.ShardingSphereStatistics;
import org.apache.shardingsphere.infra.metadata.user.Grantee;
+import org.apache.shardingsphere.infra.rule.ShardingSphereRule;
+import org.apache.shardingsphere.infra.rule.attribute.RuleAttributes;
+import
org.apache.shardingsphere.infra.rule.attribute.datanode.DataNodeRuleAttribute;
import org.apache.shardingsphere.infra.session.connection.ConnectionContext;
import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
import org.apache.shardingsphere.mode.metadata.MetaDataContexts;
@@ -133,6 +136,7 @@ class FirebirdPrepareStatementCommandExecutorTest {
FirebirdFetchStatementCache.getInstance().unregisterStatement(CONNECTION_ID, 1);
FirebirdFetchStatementCache.getInstance().unregisterConnection(CONNECTION_ID);
FirebirdBlobInfoRegistry.refreshTable("foo_db", "foo_tbl",
Collections.emptyMap());
+ FirebirdBlobInfoRegistry.refreshTable("foo_db", "foo_tbl_0",
Collections.emptyMap());
}
private MetaDataContexts createMetaDataContexts() {
@@ -217,6 +221,22 @@ class FirebirdPrepareStatementCommandExecutorTest {
verify(payload).writeInt4LE(7);
}
+ @Test
+ void assertDescribeBlobColumnOfShardingTable() throws Exception {
+ DataNodeRuleAttribute dataNodeRuleAttribute =
mock(DataNodeRuleAttribute.class);
+
when(dataNodeRuleAttribute.findFirstActualTable("foo_tbl")).thenReturn(Optional.of("foo_tbl_0"));
+ ShardingSphereRule rule = mock(ShardingSphereRule.class);
+ when(rule.getAttributes()).thenReturn(new
RuleAttributes(dataNodeRuleAttribute));
+ ShardingSphereDatabase database =
ProxyContext.getInstance().getContextManager().getMetaDataContexts().getMetaData().getDatabase("foo_db");
+ doReturn(new
RuleMetaData(Collections.singleton(rule))).when(database).getRuleMetaData();
+ FirebirdBlobInfoRegistry.refreshTable("foo_db", "foo_tbl_0",
Collections.singletonMap("id", 7));
+ FirebirdReturnColumnPacket actualColumnPacket =
describeSingleColumn("SELECT id FROM foo_tbl");
+ FirebirdPacketPayload payload = mock(FirebirdPacketPayload.class,
RETURNS_DEEP_STUBS);
+ actualColumnPacket.write(payload);
+ verify(payload).writeInt4LE(FirebirdBinaryColumnType.BLOB.getValue() +
1);
+ verify(payload).writeInt4LE(7);
+ }
+
@Test
void
assertDescribeBlobTypeColumnWithoutRegistryEntryReturnsBlobTypeAndDefaultSubtype()
throws Exception {
FirebirdReturnColumnPacket columnPacket = describeSingleColumn("SELECT
content FROM foo_tbl");