From 7ec53c2b79b02d9efc1cf83ce33aeea23757c776 Mon Sep 17 00:00:00 2001 From: Zhengqiang Duan Date: Wed, 13 Dec 2023 15:00:55 +0800 Subject: [PATCH] Add column type assert in BaseDQLE2EIT (#29390) * Add column type assert in BaseDQLE2EIT * skip proxy adapter column type assert * skip proxy adapter column type assert --- .../generic/SubstitutableColumnNameToken.java | 28 +++++-------- .../engine/type/dql/AdditionalDQLE2EIT.java | 38 +++++++++--------- .../e2e/engine/type/dql/BaseDQLE2EIT.java | 10 +++-- .../e2e/engine/type/dql/GeneralDQLE2EIT.java | 40 +++++++++---------- 4 files changed, 57 insertions(+), 59 deletions(-) diff --git a/infra/rewrite/src/main/java/org/apache/shardingsphere/infra/rewrite/sql/token/pojo/generic/SubstitutableColumnNameToken.java b/infra/rewrite/src/main/java/org/apache/shardingsphere/infra/rewrite/sql/token/pojo/generic/SubstitutableColumnNameToken.java index 0a5764ca6049b..d7d8d18fab52c 100644 --- a/infra/rewrite/src/main/java/org/apache/shardingsphere/infra/rewrite/sql/token/pojo/generic/SubstitutableColumnNameToken.java +++ b/infra/rewrite/src/main/java/org/apache/shardingsphere/infra/rewrite/sql/token/pojo/generic/SubstitutableColumnNameToken.java @@ -19,22 +19,21 @@ import lombok.EqualsAndHashCode; import lombok.Getter; +import org.apache.commons.collections4.map.CaseInsensitiveMap; import org.apache.shardingsphere.infra.binder.context.segment.select.projection.Projection; import org.apache.shardingsphere.infra.binder.context.segment.select.projection.impl.ColumnProjection; +import org.apache.shardingsphere.infra.database.core.metadata.database.enums.QuoteCharacter; import org.apache.shardingsphere.infra.rewrite.sql.token.pojo.RouteUnitAware; import org.apache.shardingsphere.infra.rewrite.sql.token.pojo.SQLToken; import org.apache.shardingsphere.infra.rewrite.sql.token.pojo.Substitutable; import org.apache.shardingsphere.infra.route.context.RouteMapper; import org.apache.shardingsphere.infra.route.context.RouteUnit; -import org.apache.shardingsphere.infra.database.core.metadata.database.enums.QuoteCharacter; import org.apache.shardingsphere.sql.parser.sql.common.value.identifier.IdentifierValue; import java.util.Collection; import java.util.Collections; import java.util.HashMap; -import java.util.LinkedHashMap; import java.util.Map; -import java.util.Optional; /** * Substitutable column name token. @@ -61,14 +60,6 @@ public SubstitutableColumnNameToken(final int startIndex, final int stopIndex, f this.projections = projections; } - public SubstitutableColumnNameToken(final int startIndex, final int stopIndex, final Collection projections, final boolean lastColumn) { - super(startIndex); - this.stopIndex = stopIndex; - this.lastColumn = lastColumn; - this.quoteCharacter = QuoteCharacter.NONE; - this.projections = projections; - } - public SubstitutableColumnNameToken(final int startIndex, final int stopIndex, final Collection projections, final QuoteCharacter quoteCharacter) { super(startIndex); this.stopIndex = stopIndex; @@ -100,7 +91,7 @@ private Map getLogicAndActualTables(final RouteUnit routeUnit) { if (null == routeUnit) { return Collections.emptyMap(); } - Map result = new LinkedHashMap<>(); + Map result = new CaseInsensitiveMap<>(); for (RouteMapper each : routeUnit.getTableMappers()) { result.put(each.getLogicName().toLowerCase(), each.getActualName()); } @@ -112,21 +103,24 @@ private String getColumnExpression(final Projection projection, final Map logicActualTableNames, final StringBuilder builder) { + private void appendColumnProjection(final ColumnProjection columnProjection, final Map logicActualTableNames, final StringBuilder builder) { if (columnProjection.getOwner().isPresent()) { - Optional owner = columnProjection.getOwner(); - String lowerCaseOwner = owner.get().getValue().toLowerCase(); - builder.append(owner.get().getQuoteCharacter().wrap(logicActualTableNames.getOrDefault(lowerCaseOwner, owner.get().getValue()))).append('.'); + IdentifierValue owner = columnProjection.getOwner().get(); + String actualTableOwner = logicActualTableNames.getOrDefault(owner.getValue(), owner.getValue()); + builder.append(getValueWithQuoteCharacters(new IdentifierValue(actualTableOwner, owner.getQuoteCharacter()))).append('.'); } builder.append(columnProjection.getName().getValueWithQuoteCharacters()); if (columnProjection.getAlias().isPresent()) { builder.append(" AS ").append(columnProjection.getAlias().get().getValueWithQuoteCharacters()); } } + + private String getValueWithQuoteCharacters(final IdentifierValue identifierValue) { + return QuoteCharacter.NONE == identifierValue.getQuoteCharacter() ? identifierValue.getValue() : quoteCharacter.wrap(identifierValue.getValue()); + } } diff --git a/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/engine/type/dql/AdditionalDQLE2EIT.java b/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/engine/type/dql/AdditionalDQLE2EIT.java index f8197854eb93a..a3b61f0c17ec3 100644 --- a/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/engine/type/dql/AdditionalDQLE2EIT.java +++ b/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/engine/type/dql/AdditionalDQLE2EIT.java @@ -60,7 +60,7 @@ void assertExecuteQueryWithResultSetTypeAndConcurrency(final AssertionTestParame if (isUseXMLAsExpectedDataset()) { assertExecuteQueryWithXMLExpected(testParam, containerComposer, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY); } else { - assertExecuteQueryWithExpectedDataSource(containerComposer, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY); + assertExecuteQueryWithExpectedDataSource(testParam, containerComposer, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY); } } @@ -81,7 +81,7 @@ void assertExecuteQueryWithResultSetTypeAndConcurrencyAndHoldability(final Asser if (isUseXMLAsExpectedDataset()) { assertExecuteQueryWithXMLExpected(testParam, containerComposer, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.HOLD_CURSORS_OVER_COMMIT); } else { - assertExecuteQueryWithExpectedDataSource(containerComposer, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.HOLD_CURSORS_OVER_COMMIT); + assertExecuteQueryWithExpectedDataSource(testParam, containerComposer, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.HOLD_CURSORS_OVER_COMMIT); } } @@ -102,7 +102,7 @@ void assertExecuteWithResultSetTypeAndConcurrency(final AssertionTestParameter t if (isUseXMLAsExpectedDataset()) { assertExecuteWithXMLExpected(testParam, containerComposer, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY); } else { - assertExecuteWithExpectedDataSource(containerComposer, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY); + assertExecuteWithExpectedDataSource(testParam, containerComposer, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY); } } @@ -123,7 +123,7 @@ void assertExecuteWithResultSetTypeAndConcurrencyAndHoldability(final AssertionT if (isUseXMLAsExpectedDataset()) { assertExecuteWithXMLExpected(testParam, containerComposer, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.HOLD_CURSORS_OVER_COMMIT); } else { - assertExecuteWithExpectedDataSource(containerComposer, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.HOLD_CURSORS_OVER_COMMIT); + assertExecuteWithExpectedDataSource(testParam, containerComposer, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.HOLD_CURSORS_OVER_COMMIT); } } @@ -146,21 +146,21 @@ private void assertExecuteQueryWithXMLExpected(final AssertionTestParameter test } } - private void assertExecuteQueryWithExpectedDataSource(final SingleE2EContainerComposer containerComposer, final int... resultSetTypes) throws SQLException { + private void assertExecuteQueryWithExpectedDataSource(final AssertionTestParameter testParam, final SingleE2EContainerComposer containerComposer, final int... resultSetTypes) throws SQLException { try ( Connection actualConnection = containerComposer.getTargetDataSource().getConnection(); Connection expectedConnection = getExpectedDataSource().getConnection()) { if (SQLExecuteType.Literal == containerComposer.getSqlExecuteType()) { - assertExecuteQueryForStatementWithResultSetTypes(containerComposer, actualConnection, expectedConnection, resultSetTypes); + assertExecuteQueryForStatementWithResultSetTypes(containerComposer, actualConnection, expectedConnection, testParam, resultSetTypes); } else { - assertExecuteQueryForPreparedStatementWithResultSetTypes(containerComposer, actualConnection, expectedConnection, resultSetTypes); + assertExecuteQueryForPreparedStatementWithResultSetTypes(containerComposer, actualConnection, expectedConnection, testParam, resultSetTypes); } } } private void assertExecuteQueryForStatementWithResultSetTypes(final SingleE2EContainerComposer containerComposer, final Connection actualConnection, final Connection expectedConnection, - final int... resultSetTypes) throws SQLException { + final AssertionTestParameter testParam, final int... resultSetTypes) throws SQLException { try ( Statement actualStatement = 2 == resultSetTypes.length ? actualConnection.createStatement(resultSetTypes[0], resultSetTypes[1]) : actualConnection.createStatement(resultSetTypes[0], resultSetTypes[1], resultSetTypes[2]); @@ -168,12 +168,12 @@ private void assertExecuteQueryForStatementWithResultSetTypes(final SingleE2ECon Statement expectedStatement = 2 == resultSetTypes.length ? expectedConnection.createStatement(resultSetTypes[0], resultSetTypes[1]) : expectedConnection.createStatement(resultSetTypes[0], resultSetTypes[1], resultSetTypes[2]); ResultSet expectedResultSet = expectedStatement.executeQuery(containerComposer.getSQL())) { - assertResultSet(actualResultSet, expectedResultSet); + assertResultSet(actualResultSet, expectedResultSet, testParam); } } private void assertExecuteQueryForPreparedStatementWithResultSetTypes(final SingleE2EContainerComposer containerComposer, final Connection actualConnection, final Connection expectedConnection, - final int... resultSetTypes) throws SQLException { + final AssertionTestParameter testParam, final int... resultSetTypes) throws SQLException { try ( PreparedStatement actualPreparedStatement = 2 == resultSetTypes.length ? actualConnection.prepareStatement(containerComposer.getSQL(), resultSetTypes[0], resultSetTypes[1]) : actualConnection.prepareStatement(containerComposer.getSQL(), resultSetTypes[0], resultSetTypes[1], resultSetTypes[2]); @@ -186,7 +186,7 @@ private void assertExecuteQueryForPreparedStatementWithResultSetTypes(final Sing try ( ResultSet actualResultSet = actualPreparedStatement.executeQuery(); ResultSet expectedResultSet = expectedPreparedStatement.executeQuery()) { - assertResultSet(actualResultSet, expectedResultSet); + assertResultSet(actualResultSet, expectedResultSet, testParam); } } } @@ -207,20 +207,20 @@ private void assertExecuteWithXMLExpected(final AssertionTestParameter testParam } } - private void assertExecuteWithExpectedDataSource(final SingleE2EContainerComposer containerComposer, final int... resultSetTypes) throws SQLException { + private void assertExecuteWithExpectedDataSource(final AssertionTestParameter testParam, final SingleE2EContainerComposer containerComposer, final int... resultSetTypes) throws SQLException { try ( Connection actualConnection = containerComposer.getTargetDataSource().getConnection(); Connection expectedConnection = getExpectedDataSource().getConnection()) { if (SQLExecuteType.Literal == containerComposer.getSqlExecuteType()) { - assertExecuteForStatementWithResultSetTypes(containerComposer, actualConnection, expectedConnection, resultSetTypes); + assertExecuteForStatementWithResultSetTypes(containerComposer, actualConnection, expectedConnection, testParam, resultSetTypes); } else { - assertExecuteForPreparedStatementWithResultSetTypes(containerComposer, actualConnection, expectedConnection, resultSetTypes); + assertExecuteForPreparedStatementWithResultSetTypes(containerComposer, actualConnection, expectedConnection, testParam, resultSetTypes); } } } - private void assertExecuteForStatementWithResultSetTypes(final SingleE2EContainerComposer containerComposer, - final Connection actualConnection, final Connection expectedConnection, final int... resultSetTypes) throws SQLException { + private void assertExecuteForStatementWithResultSetTypes(final SingleE2EContainerComposer containerComposer, final Connection actualConnection, final Connection expectedConnection, + final AssertionTestParameter testParam, final int... resultSetTypes) throws SQLException { try ( Statement actualStatement = 2 == resultSetTypes.length ? actualConnection.createStatement(resultSetTypes[0], resultSetTypes[1]) : actualConnection.createStatement(resultSetTypes[0], resultSetTypes[1], resultSetTypes[2]); @@ -230,13 +230,13 @@ private void assertExecuteForStatementWithResultSetTypes(final SingleE2EContaine try ( ResultSet actualResultSet = actualStatement.getResultSet(); ResultSet expectedResultSet = expectedStatement.getResultSet()) { - assertResultSet(actualResultSet, expectedResultSet); + assertResultSet(actualResultSet, expectedResultSet, testParam); } } } private void assertExecuteForPreparedStatementWithResultSetTypes(final SingleE2EContainerComposer containerComposer, final Connection actualConnection, final Connection expectedConnection, - final int... resultSetTypes) throws SQLException { + final AssertionTestParameter testParam, final int... resultSetTypes) throws SQLException { try ( PreparedStatement actualPreparedStatement = 2 == resultSetTypes.length ? actualConnection.prepareStatement(containerComposer.getSQL(), resultSetTypes[0], resultSetTypes[1]) : actualConnection.prepareStatement(containerComposer.getSQL(), resultSetTypes[0], resultSetTypes[1], resultSetTypes[2]); @@ -250,7 +250,7 @@ private void assertExecuteForPreparedStatementWithResultSetTypes(final SingleE2E try ( ResultSet actualResultSet = actualPreparedStatement.getResultSet(); ResultSet expectedResultSet = expectedPreparedStatement.getResultSet()) { - assertResultSet(actualResultSet, expectedResultSet); + assertResultSet(actualResultSet, expectedResultSet, testParam); } } } diff --git a/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/engine/type/dql/BaseDQLE2EIT.java b/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/engine/type/dql/BaseDQLE2EIT.java index 21ea979539d28..d027e461379fe 100644 --- a/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/engine/type/dql/BaseDQLE2EIT.java +++ b/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/engine/type/dql/BaseDQLE2EIT.java @@ -91,8 +91,8 @@ private void fillDataOnlyOnce(final AssertionTestParameter testParam, final Sing } } - protected final void assertResultSet(final ResultSet actualResultSet, final ResultSet expectedResultSet) throws SQLException { - assertMetaData(actualResultSet.getMetaData(), expectedResultSet.getMetaData()); + protected final void assertResultSet(final ResultSet actualResultSet, final ResultSet expectedResultSet, final AssertionTestParameter testParam) throws SQLException { + assertMetaData(actualResultSet.getMetaData(), expectedResultSet.getMetaData(), testParam); assertRows(actualResultSet, expectedResultSet); } @@ -117,11 +117,15 @@ private Collection getNotAssertionColumns(final SingleE2EContainerCompos return result; } - private void assertMetaData(final ResultSetMetaData actualResultSetMetaData, final ResultSetMetaData expectedResultSetMetaData) throws SQLException { + private void assertMetaData(final ResultSetMetaData actualResultSetMetaData, final ResultSetMetaData expectedResultSetMetaData, final AssertionTestParameter testParam) throws SQLException { assertThat(actualResultSetMetaData.getColumnCount(), is(expectedResultSetMetaData.getColumnCount())); for (int i = 0; i < actualResultSetMetaData.getColumnCount(); i++) { assertThat(actualResultSetMetaData.getColumnLabel(i + 1), is(expectedResultSetMetaData.getColumnLabel(i + 1))); assertThat(actualResultSetMetaData.getColumnName(i + 1), is(expectedResultSetMetaData.getColumnName(i + 1))); + if ("jdbc".equals(testParam.getAdapter()) && "Cluster".equals(testParam.getMode())) { + // FIXME correct columnType with proxy adapter + assertThat(actualResultSetMetaData.getColumnType(i + 1), is(expectedResultSetMetaData.getColumnType(i + 1))); + } } } diff --git a/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/engine/type/dql/GeneralDQLE2EIT.java b/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/engine/type/dql/GeneralDQLE2EIT.java index 6eae6bee1a4a5..e7108b3244353 100644 --- a/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/engine/type/dql/GeneralDQLE2EIT.java +++ b/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/engine/type/dql/GeneralDQLE2EIT.java @@ -55,7 +55,7 @@ void assertExecuteQuery(final AssertionTestParameter testParam) throws SQLExcept if (isUseXMLAsExpectedDataset()) { assertExecuteQueryWithXmlExpected(testParam, containerComposer); } else { - assertExecuteQueryWithExpectedDataSource(containerComposer); + assertExecuteQueryWithExpectedDataSource(testParam, containerComposer); } } @@ -72,31 +72,31 @@ private void assertExecuteQueryWithXmlExpected(final AssertionTestParameter test } } - private void assertExecuteQueryWithExpectedDataSource(final SingleE2EContainerComposer containerComposer) throws SQLException { + private void assertExecuteQueryWithExpectedDataSource(final AssertionTestParameter testParam, final SingleE2EContainerComposer containerComposer) throws SQLException { try ( Connection actualConnection = containerComposer.getTargetDataSource().getConnection(); Connection expectedConnection = getExpectedDataSource().getConnection()) { if (SQLExecuteType.Literal == containerComposer.getSqlExecuteType()) { - assertExecuteQueryForStatement(containerComposer, actualConnection, expectedConnection); + assertExecuteQueryForStatement(containerComposer, actualConnection, expectedConnection, testParam); } else { - assertExecuteQueryForPreparedStatement(containerComposer, actualConnection, expectedConnection); + assertExecuteQueryForPreparedStatement(containerComposer, actualConnection, expectedConnection, testParam); } } } - private void assertExecuteQueryForStatement(final SingleE2EContainerComposer containerComposer, - final Connection actualConnection, final Connection expectedConnection) throws SQLException { + private void assertExecuteQueryForStatement(final SingleE2EContainerComposer containerComposer, final Connection actualConnection, final Connection expectedConnection, + final AssertionTestParameter testParam) throws SQLException { try ( Statement actualStatement = actualConnection.createStatement(); ResultSet actualResultSet = actualStatement.executeQuery(containerComposer.getSQL()); Statement expectedStatement = expectedConnection.createStatement(); ResultSet expectedResultSet = expectedStatement.executeQuery(containerComposer.getSQL())) { - assertResultSet(actualResultSet, expectedResultSet); + assertResultSet(actualResultSet, expectedResultSet, testParam); } } - private void assertExecuteQueryForPreparedStatement(final SingleE2EContainerComposer containerComposer, - final Connection actualConnection, final Connection expectedConnection) throws SQLException { + private void assertExecuteQueryForPreparedStatement(final SingleE2EContainerComposer containerComposer, final Connection actualConnection, final Connection expectedConnection, + final AssertionTestParameter testParam) throws SQLException { try ( PreparedStatement actualPreparedStatement = actualConnection.prepareStatement(containerComposer.getSQL()); PreparedStatement expectedPreparedStatement = expectedConnection.prepareStatement(containerComposer.getSQL())) { @@ -107,7 +107,7 @@ private void assertExecuteQueryForPreparedStatement(final SingleE2EContainerComp try ( ResultSet actualResultSet = actualPreparedStatement.executeQuery(); ResultSet expectedResultSet = expectedPreparedStatement.executeQuery()) { - assertResultSet(actualResultSet, expectedResultSet); + assertResultSet(actualResultSet, expectedResultSet, testParam); } } } @@ -125,7 +125,7 @@ void assertExecute(final AssertionTestParameter testParam) throws SQLException, if (isUseXMLAsExpectedDataset()) { assertExecuteWithXmlExpected(testParam, containerComposer); } else { - assertExecuteWithExpectedDataSource(containerComposer); + assertExecuteWithExpectedDataSource(testParam, containerComposer); } } @@ -143,20 +143,20 @@ private void assertExecuteWithXmlExpected(final AssertionTestParameter testParam } } - private void assertExecuteWithExpectedDataSource(final SingleE2EContainerComposer containerComposer) throws SQLException { + private void assertExecuteWithExpectedDataSource(final AssertionTestParameter testParam, final SingleE2EContainerComposer containerComposer) throws SQLException { try ( Connection actualConnection = containerComposer.getTargetDataSource().getConnection(); Connection expectedConnection = getExpectedDataSource().getConnection()) { if (SQLExecuteType.Literal == containerComposer.getSqlExecuteType()) { - assertExecuteForStatement(containerComposer, actualConnection, expectedConnection); + assertExecuteForStatement(containerComposer, actualConnection, expectedConnection, testParam); } else { - assertExecuteForPreparedStatement(containerComposer, actualConnection, expectedConnection); + assertExecuteForPreparedStatement(containerComposer, actualConnection, expectedConnection, testParam); } } } - private void assertExecuteForStatement(final SingleE2EContainerComposer containerComposer, - final Connection actualConnection, final Connection expectedConnection) throws SQLException { + private void assertExecuteForStatement(final SingleE2EContainerComposer containerComposer, final Connection actualConnection, final Connection expectedConnection, + final AssertionTestParameter testParam) throws SQLException { try ( Statement actualStatement = actualConnection.createStatement(); Statement expectedStatement = expectedConnection.createStatement()) { @@ -164,13 +164,13 @@ private void assertExecuteForStatement(final SingleE2EContainerComposer containe try ( ResultSet actualResultSet = actualStatement.getResultSet(); ResultSet expectedResultSet = expectedStatement.getResultSet()) { - assertResultSet(actualResultSet, expectedResultSet); + assertResultSet(actualResultSet, expectedResultSet, testParam); } } } - private void assertExecuteForPreparedStatement(final SingleE2EContainerComposer containerComposer, - final Connection actualConnection, final Connection expectedConnection) throws SQLException { + private void assertExecuteForPreparedStatement(final SingleE2EContainerComposer containerComposer, final Connection actualConnection, final Connection expectedConnection, + final AssertionTestParameter testParam) throws SQLException { try ( PreparedStatement actualPreparedStatement = actualConnection.prepareStatement(containerComposer.getSQL()); PreparedStatement expectedPreparedStatement = expectedConnection.prepareStatement(containerComposer.getSQL())) { @@ -182,7 +182,7 @@ private void assertExecuteForPreparedStatement(final SingleE2EContainerComposer try ( ResultSet actualResultSet = actualPreparedStatement.getResultSet(); ResultSet expectedResultSet = expectedPreparedStatement.getResultSet()) { - assertResultSet(actualResultSet, expectedResultSet); + assertResultSet(actualResultSet, expectedResultSet, testParam); } } }