From 6baa2442c33779e85ad6319c24bbfb8ff8e14807 Mon Sep 17 00:00:00 2001 From: Liang Zhang Date: Sun, 24 Nov 2024 19:22:08 +0800 Subject: [PATCH] Add ShardingSphereMetaDataIdentifier and try to use in ShardingSphereTable.columns (#33776) * Add ShardingSphereMetaDataIdentifier and try to use in ShardingSphereTable.columns * Add ShardingSphereMetaDataIdentifier and try to use in ShardingSphereTable.columns --- .../schema/model/ShardingSphereTable.java | 21 ++--- ...abaseDialectMetaDataIdentifierHandler.java | 35 +++++++++ .../ShardingSphereMetaDataIdentifier.java | 78 +++++++++++++++++++ .../enumerable/EnumerableScanExecutor.java | 2 +- .../EnumerableScanExecutorTest.java | 2 +- .../prepare/MySQLComStmtPrepareExecutor.java | 2 +- 6 files changed, 128 insertions(+), 12 deletions(-) create mode 100644 infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/identifier/DatabaseDialectMetaDataIdentifierHandler.java create mode 100644 infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/identifier/ShardingSphereMetaDataIdentifier.java diff --git a/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/database/schema/model/ShardingSphereTable.java b/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/database/schema/model/ShardingSphereTable.java index b87cf50b9c699..d94284e7e4492 100644 --- a/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/database/schema/model/ShardingSphereTable.java +++ b/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/database/schema/model/ShardingSphereTable.java @@ -18,10 +18,12 @@ package org.apache.shardingsphere.infra.metadata.database.schema.model; import com.cedarsoftware.util.CaseInsensitiveMap; +import lombok.AccessLevel; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.ToString; import org.apache.shardingsphere.infra.database.core.metadata.database.enums.TableType; +import org.apache.shardingsphere.infra.metadata.identifier.ShardingSphereMetaDataIdentifier; import java.util.ArrayList; import java.util.Collection; @@ -39,7 +41,8 @@ public final class ShardingSphereTable { private final String name; - private final Map columns; + @Getter(AccessLevel.NONE) + private final Map columns; private final Map indexes; @@ -77,11 +80,11 @@ public ShardingSphereTable(final String name, final Collection createColumns(final Collection columns) { - Map result = new CaseInsensitiveMap<>(columns.size(), 1F); + private Map createColumns(final Collection columns) { + Map result = new CaseInsensitiveMap<>(columns.size(), 1F); int index = 0; for (ShardingSphereColumn each : columns) { - result.put(each.getName(), each); + result.put(new ShardingSphereMetaDataIdentifier(each.getName()), each); columnNames.add(each.getName()); if (each.isPrimaryKey()) { primaryKeyColumns.add(each.getName()); @@ -116,7 +119,7 @@ private Map createConstraints(final Collection * @param column column meta data */ public void putColumn(final ShardingSphereColumn column) { - columns.put(column.getName(), column); + columns.put(new ShardingSphereMetaDataIdentifier(column.getName()), column); } /** @@ -126,13 +129,13 @@ public void putColumn(final ShardingSphereColumn column) { * @return column meta data */ public ShardingSphereColumn getColumn(final String columnName) { - return columns.get(columnName); + return columns.get(new ShardingSphereMetaDataIdentifier(columnName)); } /** - * Get column meta data collection. + * Get column meta data list. * - * @return column meta data collection + * @return column meta data list */ public Collection getColumnValues() { return columns.values(); @@ -145,7 +148,7 @@ public Collection getColumnValues() { * @return whether contains column or not */ public boolean containsColumn(final String columnName) { - return null != columnName && columns.containsKey(columnName); + return null != columnName && columns.containsKey(new ShardingSphereMetaDataIdentifier(columnName)); } /** diff --git a/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/identifier/DatabaseDialectMetaDataIdentifierHandler.java b/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/identifier/DatabaseDialectMetaDataIdentifierHandler.java new file mode 100644 index 0000000000000..e0cbec7703c14 --- /dev/null +++ b/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/identifier/DatabaseDialectMetaDataIdentifierHandler.java @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.shardingsphere.infra.metadata.identifier; + +import org.apache.shardingsphere.infra.database.core.spi.DatabaseTypedSPI; +import org.apache.shardingsphere.infra.spi.annotation.SingletonSPI; + +/** + * Database dialect meta data identifier handler. + */ +@SingletonSPI +public interface DatabaseDialectMetaDataIdentifierHandler extends DatabaseTypedSPI { + + /** + * Whether identifier is case-sensitive. + * + * @return is case-sensitive or insensitive + */ + boolean isCaseSensitive(); +} diff --git a/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/identifier/ShardingSphereMetaDataIdentifier.java b/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/identifier/ShardingSphereMetaDataIdentifier.java new file mode 100644 index 0000000000000..be7be0d442ffe --- /dev/null +++ b/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/identifier/ShardingSphereMetaDataIdentifier.java @@ -0,0 +1,78 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.shardingsphere.infra.metadata.identifier; + +import com.cedarsoftware.util.CaseInsensitiveMap.CaseInsensitiveString; +import org.apache.shardingsphere.infra.database.core.metadata.database.enums.QuoteCharacter; +import org.apache.shardingsphere.infra.database.core.spi.DatabaseTypedSPILoader; +import org.apache.shardingsphere.infra.database.core.type.DatabaseType; +import org.apache.shardingsphere.sql.parser.statement.core.value.identifier.IdentifierValue; + +/** + * ShardingSphere meta data identifier. + */ +public final class ShardingSphereMetaDataIdentifier { + + private final boolean isCaseSensitive; + + private final CaseInsensitiveString value; + + public ShardingSphereMetaDataIdentifier(final String value) { + isCaseSensitive = false; + this.value = new CaseInsensitiveString(value); + } + + public ShardingSphereMetaDataIdentifier(final String value, final DatabaseType databaseType) { + isCaseSensitive = DatabaseTypedSPILoader.findService(DatabaseDialectMetaDataIdentifierHandler.class, databaseType) + .map(DatabaseDialectMetaDataIdentifierHandler::isCaseSensitive).orElse(false); + this.value = new CaseInsensitiveString(value); + } + + public ShardingSphereMetaDataIdentifier(final IdentifierValue value) { + isCaseSensitive = QuoteCharacter.NONE != value.getQuoteCharacter(); + this.value = new CaseInsensitiveString(value.getValue()); + } + + public ShardingSphereMetaDataIdentifier(final IdentifierValue value, final DatabaseType databaseType) { + isCaseSensitive = QuoteCharacter.NONE != value.getQuoteCharacter() + && DatabaseTypedSPILoader.findService(DatabaseDialectMetaDataIdentifierHandler.class, databaseType).map(DatabaseDialectMetaDataIdentifierHandler::isCaseSensitive).orElse(false); + this.value = new CaseInsensitiveString(value.getValue()); + } + + /** + * Get identifier value. + * + * @return identifier value + */ + public String getValue() { + return value.toString(); + } + + @Override + public boolean equals(final Object obj) { + if (!(obj instanceof ShardingSphereMetaDataIdentifier)) { + return false; + } + return isCaseSensitive ? value.toString().equals(((ShardingSphereMetaDataIdentifier) obj).value.toString()) : value.equals(((ShardingSphereMetaDataIdentifier) obj).value); + } + + @Override + public int hashCode() { + return isCaseSensitive ? value.toString().hashCode() : value.hashCode(); + } +} diff --git a/kernel/sql-federation/executor/src/main/java/org/apache/shardingsphere/sqlfederation/executor/enumerable/EnumerableScanExecutor.java b/kernel/sql-federation/executor/src/main/java/org/apache/shardingsphere/sqlfederation/executor/enumerable/EnumerableScanExecutor.java index 3be60e46f33dd..bac006825289c 100644 --- a/kernel/sql-federation/executor/src/main/java/org/apache/shardingsphere/sqlfederation/executor/enumerable/EnumerableScanExecutor.java +++ b/kernel/sql-federation/executor/src/main/java/org/apache/shardingsphere/sqlfederation/executor/enumerable/EnumerableScanExecutor.java @@ -168,7 +168,7 @@ private Enumerable createMemoryEnumerator(final ShardingSphereTableData @Override public Enumerator enumerator() { - return new MemoryRowEnumerator(tableData.getRows(), table.getColumns().values(), databaseType); + return new MemoryRowEnumerator(tableData.getRows(), table.getColumnValues(), databaseType); } }; } diff --git a/kernel/sql-federation/executor/src/test/java/org/apache/shardingsphere/sqlfederation/executor/enumerable/EnumerableScanExecutorTest.java b/kernel/sql-federation/executor/src/test/java/org/apache/shardingsphere/sqlfederation/executor/enumerable/EnumerableScanExecutorTest.java index bfad36bc30c36..4843954603f1b 100644 --- a/kernel/sql-federation/executor/src/test/java/org/apache/shardingsphere/sqlfederation/executor/enumerable/EnumerableScanExecutorTest.java +++ b/kernel/sql-federation/executor/src/test/java/org/apache/shardingsphere/sqlfederation/executor/enumerable/EnumerableScanExecutorTest.java @@ -63,7 +63,7 @@ void assertExecuteWithStatistics() { when(schemaData.getTable("test")).thenReturn(tableData); ShardingSphereTable table = mock(ShardingSphereTable.class, RETURNS_DEEP_STUBS); when(table.getName()).thenReturn("test"); - when(table.getColumns().values()).thenReturn(Collections.singleton(new ShardingSphereColumn("id", Types.INTEGER, true, false, false, false, true, false))); + when(table.getColumnValues()).thenReturn(Collections.singleton(new ShardingSphereColumn("id", Types.INTEGER, true, false, false, false, true, false))); Enumerable enumerable = new EnumerableScanExecutor(null, null, null, optimizerContext, executorContext, null, null, statistics) .execute(table, mock(ScanExecutorContext.class)); try (Enumerator actual = enumerable.enumerator()) { diff --git a/proxy/frontend/type/mysql/src/main/java/org/apache/shardingsphere/proxy/frontend/mysql/command/query/binary/prepare/MySQLComStmtPrepareExecutor.java b/proxy/frontend/type/mysql/src/main/java/org/apache/shardingsphere/proxy/frontend/mysql/command/query/binary/prepare/MySQLComStmtPrepareExecutor.java index bf2de9b4b6aca..545c7a9f128c6 100644 --- a/proxy/frontend/type/mysql/src/main/java/org/apache/shardingsphere/proxy/frontend/mysql/command/query/binary/prepare/MySQLComStmtPrepareExecutor.java +++ b/proxy/frontend/type/mysql/src/main/java/org/apache/shardingsphere/proxy/frontend/mysql/command/query/binary/prepare/MySQLComStmtPrepareExecutor.java @@ -155,7 +155,7 @@ private Collection createProjectionColumnDefinition41Packets(final // TODO Calculate column definition flag for other projection types if (each instanceof ColumnProjection) { result.add(Optional.ofNullable(schema.getTable(((ColumnProjection) each).getOriginalTable().getValue())) - .map(table -> table.getColumns().get(((ColumnProjection) each).getOriginalColumn().getValue())) + .map(table -> table.getColumn(((ColumnProjection) each).getOriginalColumn().getValue())) .map(column -> createMySQLColumnDefinition41Packet(characterSet, calculateColumnDefinitionFlag(column), MySQLBinaryColumnType.valueOfJDBCType(column.getDataType()))) .orElseGet(() -> createMySQLColumnDefinition41Packet(characterSet, 0, MySQLBinaryColumnType.VAR_STRING))); } else {