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 1e890783241 Align generated query rows with metadata (#38826)
1e890783241 is described below
commit 1e890783241fe4de1b781d3feb945b687d526205
Author: Liang Zhang <[email protected]>
AuthorDate: Sat Jun 6 17:36:21 2026 +0800
Align generated query rows with metadata (#38826)
Ensure generated admin query results build metadata and row data from the
same ordered column labels, filling missing row cells instead of exposing
shorter rows. Reject unsupported MySQL no-FROM sane result projections rather
than silently dropping them, and replace the reflective connector symptom test
with producer-side regression coverage.
---
.../admin/executor/DatabaseMetaDataExecutor.java | 20 ++++--
.../StandardDatabaseProxyConnectorTest.java | 59 ---------------
.../executor/DatabaseMetaDataExecutorTest.java | 84 +++++++++++++++++-----
.../sane/MySQLDialectSaneQueryResultEngine.java | 19 ++---
.../MySQLDialectSaneQueryResultEngineTest.java | 13 +++-
...LSelectWithoutFromAdminExecutorFactoryTest.java | 15 +++-
6 files changed, 115 insertions(+), 95 deletions(-)
diff --git
a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/admin/executor/DatabaseMetaDataExecutor.java
b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/admin/executor/DatabaseMetaDataExecutor.java
index 3baae3fad10..2d3766bbacb 100644
---
a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/admin/executor/DatabaseMetaDataExecutor.java
+++
b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/admin/executor/DatabaseMetaDataExecutor.java
@@ -139,17 +139,25 @@ public class DatabaseMetaDataExecutor implements
DatabaseAdminQueryExecutor {
}
private RawQueryResultMetaData createQueryResultMetaData() {
- if (rows.isEmpty() && !labels.isEmpty()) {
- List<RawQueryResultColumnMetaData> columns =
labels.stream().map(each -> new RawQueryResultColumnMetaData("", each, each,
Types.VARCHAR, "VARCHAR", 20, 0)).collect(Collectors.toList());
- return new RawQueryResultMetaData(columns);
- }
- List<RawQueryResultColumnMetaData> columns =
rows.stream().flatMap(each ->
each.keySet().stream()).collect(Collectors.toCollection(LinkedHashSet::new))
+ Collection<String> columnLabels = rows.isEmpty() && !labels.isEmpty()
+ ? labels
+ : rows.stream().flatMap(each ->
each.keySet().stream()).collect(Collectors.toCollection(LinkedHashSet::new));
+ List<RawQueryResultColumnMetaData> columns = columnLabels
.stream().map(each -> new RawQueryResultColumnMetaData("",
each, each, Types.VARCHAR, "VARCHAR", 20, 0)).collect(Collectors.toList());
return new RawQueryResultMetaData(columns);
}
private MergedResult createMergedResult() {
- List<MemoryQueryResultDataRow> resultDataRows = rows.stream().map(each
-> new MemoryQueryResultDataRow(new
LinkedList<>(each.values()))).collect(Collectors.toList());
+ Collection<String> columnLabels = rows.isEmpty() && !labels.isEmpty()
+ ? labels
+ : rows.stream().flatMap(each ->
each.keySet().stream()).collect(Collectors.toCollection(LinkedHashSet::new));
+ List<MemoryQueryResultDataRow> resultDataRows = rows.stream().map(each
-> {
+ List<Object> rowData = new LinkedList<>();
+ for (String columnLabel : columnLabels) {
+ rowData.add(each.getOrDefault(columnLabel, ""));
+ }
+ return new MemoryQueryResultDataRow(rowData);
+ }).collect(Collectors.toList());
return new TransparentMergedResult(new
RawMemoryQueryResult(queryResultMetaData, resultDataRows));
}
}
diff --git
a/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/connector/StandardDatabaseProxyConnectorTest.java
b/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/connector/StandardDatabaseProxyConnectorTest.java
index bf8de9a48cc..c1151dd71eb 100644
---
a/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/connector/StandardDatabaseProxyConnectorTest.java
+++
b/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/connector/StandardDatabaseProxyConnectorTest.java
@@ -23,7 +23,6 @@ import
org.apache.shardingsphere.database.connector.core.metadata.database.metad
import
org.apache.shardingsphere.database.connector.core.spi.DatabaseTypedSPILoader;
import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
import
org.apache.shardingsphere.database.connector.core.type.DatabaseTypeRegistry;
-import
org.apache.shardingsphere.driver.jdbc.core.resultset.ShardingSphereResultSetMetaData;
import
org.apache.shardingsphere.infra.binder.context.segment.insert.keygen.GeneratedKeyContext;
import
org.apache.shardingsphere.infra.binder.context.segment.select.projection.Projection;
import
org.apache.shardingsphere.infra.binder.context.segment.select.projection.ProjectionsContext;
@@ -45,20 +44,13 @@ import
org.apache.shardingsphere.infra.executor.sql.prepare.driver.jdbc.JDBCDriv
import org.apache.shardingsphere.infra.hint.HintValueContext;
import org.apache.shardingsphere.infra.merge.MergeEngine;
import org.apache.shardingsphere.infra.merge.result.MergedResult;
-import
org.apache.shardingsphere.infra.merge.result.impl.memory.MemoryMergedResult;
-import
org.apache.shardingsphere.infra.merge.result.impl.memory.MemoryQueryResultRow;
import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData;
import
org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
import
org.apache.shardingsphere.infra.metadata.database.resource.ResourceMetaData;
import org.apache.shardingsphere.infra.metadata.database.rule.RuleMetaData;
-import
org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereColumn;
-import
org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereIndex;
-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.metadata.database.schema.util.SystemSchemaUtils;
import
org.apache.shardingsphere.infra.metadata.statistics.ShardingSphereStatistics;
import
org.apache.shardingsphere.infra.metadata.statistics.builder.ShardingSphereStatisticsFactory;
-import org.apache.shardingsphere.infra.rule.ShardingSphereRule;
import
org.apache.shardingsphere.infra.rule.attribute.datanode.DataNodeRuleAttribute;
import org.apache.shardingsphere.infra.session.connection.ConnectionContext;
import
org.apache.shardingsphere.infra.session.connection.cursor.CursorConnectionContext;
@@ -78,7 +70,6 @@ import
org.apache.shardingsphere.proxy.backend.context.BackendExecutorContext;
import org.apache.shardingsphere.proxy.backend.context.ProxyContext;
import org.apache.shardingsphere.proxy.backend.response.header.ResponseHeader;
import
org.apache.shardingsphere.proxy.backend.response.header.query.QueryHeaderBuilder;
-import
org.apache.shardingsphere.proxy.backend.response.header.query.QueryHeaderBuilderEngine;
import
org.apache.shardingsphere.proxy.backend.response.header.query.QueryResponseHeader;
import
org.apache.shardingsphere.proxy.backend.response.header.update.UpdateResponseHeader;
import org.apache.shardingsphere.sharding.rule.ShardingRule;
@@ -109,17 +100,14 @@ import org.mockito.internal.configuration.plugins.Plugins;
import org.mockito.junit.jupiter.MockitoSettings;
import org.mockito.quality.Strictness;
-import java.lang.reflect.Field;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
-import java.sql.Types;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
-import java.util.List;
import java.util.Optional;
import java.util.Properties;
import java.util.stream.Collectors;
@@ -199,37 +187,6 @@ class StandardDatabaseProxyConnectorTest {
return result;
}
- @Test
- void assertBinaryProtocolQueryHeader() throws SQLException,
NoSuchFieldException, IllegalAccessException {
- SQLStatementContext sqlStatementContext =
mock(SQLStatementContext.class, RETURNS_DEEP_STUBS);
-
when(sqlStatementContext.getTablesContext().getDatabaseNames()).thenReturn(Collections.emptyList());
-
when(sqlStatementContext.getSqlStatement().getDatabaseType()).thenReturn(databaseType);
- DatabaseProxyConnector engine =
createDatabaseProxyConnector(JDBCDriverType.PREPARED_STATEMENT,
createQueryContext(sqlStatementContext, mockDatabase()));
- Field queryHeadersField =
StandardDatabaseProxyConnector.class.getDeclaredField("queryHeaders");
- ShardingSphereDatabase database = createDatabaseMetaData();
- try (MockedStatic<DatabaseTypedSPILoader> spiLoader =
mockStatic(DatabaseTypedSPILoader.class)) {
- spiLoader.when(() ->
DatabaseTypedSPILoader.getService(QueryHeaderBuilder.class,
databaseType)).thenReturn(new QueryHeaderBuilderFixture());
- Plugins.getMemberAccessor().set(queryHeadersField, engine,
Collections.singletonList(new
QueryHeaderBuilderEngine(databaseType).build(createResultSetMetaData(),
database, 1)));
- Field mergedResultField =
StandardDatabaseProxyConnector.class.getDeclaredField("mergedResult");
- Plugins.getMemberAccessor().set(mergedResultField, engine, new
MemoryMergedResult<ShardingSphereRule>(null, null, null,
Collections.emptyList()) {
-
- @Override
- protected List<MemoryQueryResultRow> init(final
ShardingSphereRule rule, final ShardingSphereSchema schema,
- final
SQLStatementContext sqlStatementContext, final List<QueryResult> queryResults) {
- return
Collections.singletonList(mock(MemoryQueryResultRow.class));
- }
- });
- Exception ex = null;
- try {
- engine.getRowData();
- } catch (final SQLException | IndexOutOfBoundsException exception)
{
- ex = exception;
- } finally {
- assertFalse(ex instanceof IndexOutOfBoundsException);
- }
- }
- }
-
@Test
void assertExecuteWithFederationMetaDataRefresh() throws SQLException {
SQLStatementContext sqlStatementContext =
createSQLStatementContext(new SQLStatement(databaseType));
@@ -707,22 +664,6 @@ class StandardDatabaseProxyConnectorTest {
return new QueryContext(sqlStatementContext, "schemaName",
Collections.emptyList(), new HintValueContext(), connectionContext, metaData);
}
- private ShardingSphereDatabase createDatabaseMetaData() {
- ShardingSphereDatabase result = mock(ShardingSphereDatabase.class,
RETURNS_DEEP_STUBS);
- ShardingSphereColumn column = new ShardingSphereColumn("order_id",
Types.INTEGER, true, false, false, true, false, false);
-
when(result.getSchema("foo_db").getTable("t_logic_order")).thenReturn(new
ShardingSphereTable(
- "t_logic_order", Collections.singleton(column),
Collections.singleton(new ShardingSphereIndex("order_id",
Collections.emptyList(), false)), Collections.emptyList()));
-
when(result.getRuleMetaData().getRules()).thenReturn(Collections.singleton(mock(ShardingRule.class)));
- return result;
- }
-
- private ShardingSphereResultSetMetaData createResultSetMetaData() throws
SQLException {
- ResultSetMetaData resultSetMetaData = mock(ResultSetMetaData.class);
- when(resultSetMetaData.getColumnLabel(1)).thenReturn("order_id");
- when(resultSetMetaData.getColumnName(1)).thenReturn("order_id");
- return new ShardingSphereResultSetMetaData(resultSetMetaData,
mock(ShardingSphereDatabase.class), null);
- }
-
private ResponseHeader executeWithImplicitCommitCondition(final
SQLStatement sqlStatement, final String transactionType, final boolean
inTransaction,
final int
executionUnitCount) throws SQLException {
when(databaseConnectionManager.getConnectionSession().isAutoCommit()).thenReturn(true);
diff --git
a/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/admin/executor/DatabaseMetaDataExecutorTest.java
b/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/admin/executor/DatabaseMetaDataExecutorTest.java
index df11aa0c95b..d2b8b2e7721 100644
---
a/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/admin/executor/DatabaseMetaDataExecutorTest.java
+++
b/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/admin/executor/DatabaseMetaDataExecutorTest.java
@@ -28,6 +28,7 @@ import
org.apache.shardingsphere.infra.metadata.database.resource.ResourceMetaDa
import org.apache.shardingsphere.infra.metadata.database.rule.RuleMetaData;
import
org.apache.shardingsphere.infra.metadata.database.schema.util.SystemSchemaUtils;
import org.apache.shardingsphere.infra.metadata.user.Grantee;
+import org.apache.shardingsphere.infra.merge.result.MergedResult;
import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
import org.apache.shardingsphere.proxy.backend.session.ConnectionSession;
import org.apache.shardingsphere.test.infra.fixture.jdbc.MockedDataSource;
@@ -36,6 +37,8 @@ import
org.apache.shardingsphere.test.infra.framework.extension.mock.StaticMockS
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
import org.mockito.Answers;
import org.mockito.Mock;
@@ -46,6 +49,7 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
@@ -161,41 +165,89 @@ class DatabaseMetaDataExecutorTest {
assertThat(executor.getQueryResultMetaData().getColumnCount(), is(0));
}
- @Test
- void assertExecuteFillLabelsWhenRowsFilteredOut() throws SQLException {
- Map<String, String> expectedResultSetMap =
Collections.singletonMap("foo_column", "foo_value");
+ @ParameterizedTest(name = "{0}")
+ @ValueSource(strings = {"filtered_rows", "aligned_rows"})
+ void assertExecuteWithPreProcessedRows(final String scenario) throws
SQLException {
+ if ("filtered_rows".equals(scenario)) {
+ Map<String, String> expectedResultSetMap =
Collections.singletonMap("foo_column", "foo_value");
+ ShardingSphereDatabase database = new
ShardingSphereDatabase("auth_db",
+ databaseType, new
ResourceMetaData(Collections.singletonMap("foo_ds", new
MockedDataSource(mockConnection(expectedResultSetMap)))), mock(),
Collections.emptyList(),
+ new ConfigurationProperties(new Properties()));
+ DatabaseMetaDataExecutor executor =
mock(DatabaseMetaDataExecutor.class, withSettings().useConstructor(
+ "SELECT foo_column FROM foo_table",
Collections.emptyList()).defaultAnswer(CALLS_REAL_METHODS));
+ doAnswer(invocation -> {
+ Map<String, Object> rows = invocation.getArgument(1);
+ rows.clear();
+ return null;
+ }).when(executor).preProcess(any(ShardingSphereDatabase.class),
anyMap(), anyMap());
+ executor.execute(connectionSession, mockMetaData(database,
Collections.singleton("auth_db")));
+ assertTrue(executor.getRows().isEmpty());
+ assertThat(executor.getQueryResultMetaData().getColumnCount(),
is(1));
+ assertFalse(executor.getMergedResult().next());
+ return;
+ }
+ Map<String, String> firstResultSetMap = new LinkedHashMap<>(2, 1F);
+ firstResultSetMap.put("foo_column", "foo_value");
+ firstResultSetMap.put("bar_column", "bar_value");
+ Map<String, String> secondResultSetMap = new LinkedHashMap<>(2, 1F);
+ secondResultSetMap.put("foo_column", "second_foo_value");
+ secondResultSetMap.put("bar_column", "second_bar_value");
ShardingSphereDatabase database = new ShardingSphereDatabase("auth_db",
- databaseType, new
ResourceMetaData(Collections.singletonMap("foo_ds", new
MockedDataSource(mockConnection(expectedResultSetMap)))), mock(),
Collections.emptyList(),
- new ConfigurationProperties(new Properties()));
- DatabaseMetaDataExecutor executor =
mock(DatabaseMetaDataExecutor.class, withSettings().useConstructor(
- "SELECT foo_column FROM foo_table",
Collections.emptyList()).defaultAnswer(CALLS_REAL_METHODS));
+ databaseType, new
ResourceMetaData(Collections.singletonMap("foo_ds", new
MockedDataSource(mockConnection(firstResultSetMap, secondResultSetMap)))),
mock(),
+ Collections.emptyList(), new ConfigurationProperties(new
Properties()));
+ DatabaseMetaDataExecutor executor =
+ mock(DatabaseMetaDataExecutor.class,
withSettings().useConstructor("SELECT foo_column, bar_column FROM foo_table",
Collections.emptyList()).defaultAnswer(CALLS_REAL_METHODS));
doAnswer(invocation -> {
Map<String, Object> rows = invocation.getArgument(1);
- rows.clear();
+ if ("foo_value".equals(rows.get("foo_column"))) {
+ rows.remove("bar_column");
+ rows.put("baz_column", "baz_value");
+ }
return null;
}).when(executor).preProcess(any(ShardingSphereDatabase.class),
anyMap(), anyMap());
executor.execute(connectionSession, mockMetaData(database,
Collections.singleton("auth_db")));
- assertTrue(executor.getRows().isEmpty());
- assertThat(executor.getQueryResultMetaData().getColumnCount(), is(1));
- assertFalse(executor.getMergedResult().next());
+ assertThat(executor.getQueryResultMetaData().getColumnCount(), is(3));
+ assertThat(executor.getQueryResultMetaData().getColumnLabel(1),
is("foo_column"));
+ assertThat(executor.getQueryResultMetaData().getColumnLabel(2),
is("baz_column"));
+ assertThat(executor.getQueryResultMetaData().getColumnLabel(3),
is("bar_column"));
+ MergedResult actualMergedResult = executor.getMergedResult();
+ assertTrue(actualMergedResult.next());
+ assertThat(actualMergedResult.getValue(1, String.class),
is("foo_value"));
+ assertThat(actualMergedResult.getValue(2, String.class),
is("baz_value"));
+ assertThat(actualMergedResult.getValue(3, String.class), is(""));
+ assertTrue(actualMergedResult.next());
+ assertThat(actualMergedResult.getValue(1, String.class),
is("second_foo_value"));
+ assertThat(actualMergedResult.getValue(2, String.class), is(""));
+ assertThat(actualMergedResult.getValue(3, String.class),
is("second_bar_value"));
+ assertFalse(actualMergedResult.next());
}
- private Connection mockConnection(final Map<String, String>
expectedResultSetMap) throws SQLException {
+ private Connection mockConnection(final Map<String, String>
expectedResultSetMap, final Map<String, String>...
additionalExpectedResultSetMaps) throws SQLException {
Connection result = mock(Connection.class, RETURNS_DEEP_STUBS);
- ResultSet resultSet = mockResultSet(expectedResultSetMap);
+ ResultSet resultSet = mockResultSet(expectedResultSetMap,
additionalExpectedResultSetMaps);
when(result.prepareStatement(any(String.class)).executeQuery()).thenReturn(resultSet);
return result;
}
- private ResultSet mockResultSet(final Map<String, String>
expectedResultSetMap) throws SQLException {
+ private ResultSet mockResultSet(final Map<String, String>
expectedResultSetMap, final Map<String, String>...
additionalExpectedResultSetMaps) throws SQLException {
ResultSet result = mock(ResultSet.class, RETURNS_DEEP_STUBS);
List<String> keys = new ArrayList<>(expectedResultSetMap.keySet());
for (int i = 0; i < keys.size(); i++) {
when(result.getMetaData().getColumnName(i +
1)).thenReturn(keys.get(i));
when(result.getMetaData().getColumnLabel(i +
1)).thenReturn(keys.get(i));
- when(result.getString(i +
1)).thenReturn(expectedResultSetMap.get(keys.get(i)));
+ List<String> columnValues = new
ArrayList<>(additionalExpectedResultSetMaps.length + 1);
+ columnValues.add(expectedResultSetMap.get(keys.get(i)));
+ for (Map<String, String> each : additionalExpectedResultSetMaps) {
+ columnValues.add(each.get(keys.get(i)));
+ }
+ when(result.getString(i + 1)).thenReturn(columnValues.get(0),
columnValues.subList(1, columnValues.size()).toArray(new String[0]));
+ }
+ List<Boolean> nextResults = new
ArrayList<>(additionalExpectedResultSetMaps.length + 2);
+ for (int i = 0; i < additionalExpectedResultSetMaps.length + 1; i++) {
+ nextResults.add(true);
}
- when(result.next()).thenReturn(true, false);
+ nextResults.add(false);
+ when(result.next()).thenReturn(nextResults.get(0),
nextResults.subList(1, nextResults.size()).toArray(new Boolean[0]));
when(result.getMetaData().getColumnCount()).thenReturn(expectedResultSetMap.size());
return result;
}
diff --git
a/proxy/backend/dialect/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/connector/sane/MySQLDialectSaneQueryResultEngine.java
b/proxy/backend/dialect/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/connector/sane/MySQLDialectSaneQueryResultEngine.java
index 148ac2f4957..93fc676b0e6 100644
---
a/proxy/backend/dialect/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/connector/sane/MySQLDialectSaneQueryResultEngine.java
+++
b/proxy/backend/dialect/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/connector/sane/MySQLDialectSaneQueryResultEngine.java
@@ -72,16 +72,17 @@ public final class MySQLDialectSaneQueryResultEngine
implements DialectSaneQuery
List<RawQueryResultColumnMetaData> queryResultColumnMetaDataList = new
ArrayList<>(sqlStatement.getProjections().getProjections().size());
List<Object> data = new
ArrayList<>(sqlStatement.getProjections().getProjections().size());
for (ProjectionSegment each :
sqlStatement.getProjections().getProjections()) {
- if (each instanceof ExpressionProjectionSegment) {
- ExpressionProjectionSegment expressionProjection =
(ExpressionProjectionSegment) each;
- String text = expressionProjection.getText();
- String alias =
expressionProjection.getAliasName().orElse(expressionProjection.getText());
-
queryResultColumnMetaDataList.add(createRawQueryResultColumnMetaData(text,
alias));
- String value = expressionProjection.getExpr() instanceof
VariableSegment
- ?
MySQLSystemVariable.findSystemVariable(((VariableSegment)
expressionProjection.getExpr()).getVariable()).map(MySQLSystemVariable::getDefaultValue).orElse("1")
- : "1";
- data.add(value);
+ if (!(each instanceof ExpressionProjectionSegment)) {
+ return Optional.empty();
}
+ ExpressionProjectionSegment expressionProjection =
(ExpressionProjectionSegment) each;
+ String text = expressionProjection.getText();
+ String alias =
expressionProjection.getAliasName().orElse(expressionProjection.getText());
+
queryResultColumnMetaDataList.add(createRawQueryResultColumnMetaData(text,
alias));
+ String value = expressionProjection.getExpr() instanceof
VariableSegment
+ ?
MySQLSystemVariable.findSystemVariable(((VariableSegment)
expressionProjection.getExpr()).getVariable()).map(MySQLSystemVariable::getDefaultValue).orElse("1")
+ : "1";
+ data.add(value);
}
return queryResultColumnMetaDataList.isEmpty()
? Optional.empty()
diff --git
a/proxy/backend/dialect/mysql/src/test/java/org/apache/shardingsphere/proxy/backend/mysql/connector/sane/MySQLDialectSaneQueryResultEngineTest.java
b/proxy/backend/dialect/mysql/src/test/java/org/apache/shardingsphere/proxy/backend/mysql/connector/sane/MySQLDialectSaneQueryResultEngineTest.java
index a92c67cef5a..79f6c8371c2 100644
---
a/proxy/backend/dialect/mysql/src/test/java/org/apache/shardingsphere/proxy/backend/mysql/connector/sane/MySQLDialectSaneQueryResultEngineTest.java
+++
b/proxy/backend/dialect/mysql/src/test/java/org/apache/shardingsphere/proxy/backend/mysql/connector/sane/MySQLDialectSaneQueryResultEngineTest.java
@@ -25,6 +25,7 @@ import
org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.dal.VariableSegment;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.ExpressionProjectionSegment;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.ProjectionsSegment;
+import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.ShorthandProjectionSegment;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.SimpleTableSegment;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.TableNameSegment;
import
org.apache.shardingsphere.sql.parser.statement.core.statement.type.dal.SetStatement;
@@ -33,6 +34,8 @@ import
org.apache.shardingsphere.sql.parser.statement.core.statement.type.dml.Se
import
org.apache.shardingsphere.sql.parser.statement.core.value.identifier.IdentifierValue;
import
org.apache.shardingsphere.sql.parser.statement.mysql.dal.show.MySQLShowOtherStatement;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
import java.sql.SQLException;
import java.util.Collections;
@@ -63,11 +66,17 @@ class MySQLDialectSaneQueryResultEngineTest {
assertThat(new
MySQLDialectSaneQueryResultEngine().getSaneQueryResult(selectStatement, new
SQLException("")), is(Optional.empty()));
}
- @Test
- void assertGetSaneQueryResultForSelectStatementWithoutFrom() {
+ @ParameterizedTest(name = "{0}")
+ @ValueSource(strings = {"expression_projections",
"unsupported_projection"})
+ void assertGetSaneQueryResultForSelectStatementWithoutFrom(final String
scenario) {
SelectStatement selectStatement =
SelectStatement.builder().databaseType(databaseType).projections(new
ProjectionsSegment(0, 0)).build();
selectStatement.getProjections().getProjections().add(new
ExpressionProjectionSegment(0, 0, "@@session.transaction_read_only", new
VariableSegment(0, 0, "transaction_read_only")));
selectStatement.getProjections().getProjections().add(new
ExpressionProjectionSegment(0, 0, "unknown_variable"));
+ if ("unsupported_projection".equals(scenario)) {
+ selectStatement.getProjections().getProjections().add(new
ShorthandProjectionSegment(0, 0));
+ assertThat(new
MySQLDialectSaneQueryResultEngine().getSaneQueryResult(selectStatement, new
SQLException("")), is(Optional.empty()));
+ return;
+ }
Optional<ExecuteResult> actual = new
MySQLDialectSaneQueryResultEngine().getSaneQueryResult(selectStatement, new
SQLException(""));
assertTrue(actual.isPresent());
assertThat(actual.get(), isA(RawMemoryQueryResult.class));
diff --git
a/proxy/backend/dialect/mysql/src/test/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/factory/withoutfrom/MySQLSelectWithoutFromAdminExecutorFactoryTest.java
b/proxy/backend/dialect/mysql/src/test/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/factory/withoutfrom/MySQLSelectWithoutFromAdminExecutorFactoryTest.java
index 703818b54f2..232ab0bb988 100644
---
a/proxy/backend/dialect/mysql/src/test/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/factory/withoutfrom/MySQLSelectWithoutFromAdminExecutorFactoryTest.java
+++
b/proxy/backend/dialect/mysql/src/test/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/factory/withoutfrom/MySQLSelectWithoutFromAdminExecutorFactoryTest.java
@@ -35,9 +35,13 @@ import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.Proj
import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.ProjectionsSegment;
import
org.apache.shardingsphere.sql.parser.statement.core.statement.type.dml.SelectStatement;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
import java.util.Arrays;
+import java.util.Collection;
import java.util.Collections;
+import java.util.LinkedList;
import java.util.Optional;
import static org.hamcrest.MatcherAssert.assertThat;
@@ -96,9 +100,14 @@ class MySQLSelectWithoutFromAdminExecutorFactoryTest {
assertThat(actual.get(), isA(ShowCurrentDatabaseExecutor.class));
}
- @Test
- void assertCreateNoResourceExecutorWhenEmptyResource() {
- SelectStatement selectStatement =
createSelectStatement(Collections.singletonList(new
ExpressionProjectionSegment(0, 0, "other()")));
+ @ParameterizedTest(name = "{0}")
+ @ValueSource(ints = {1, 2})
+ void assertCreateNoResourceExecutorWhenEmptyResource(final int
projectionCount) {
+ Collection<ProjectionSegment> projections = new LinkedList<>();
+ for (int i = 0; i < projectionCount; i++) {
+ projections.add(new ExpressionProjectionSegment(0, 0, "col" + i));
+ }
+ SelectStatement selectStatement = createSelectStatement(projections);
ShardingSphereMetaData metaData = mock(ShardingSphereMetaData.class);
when(metaData.getAllDatabases()).thenReturn(Collections.emptyList());
Optional<DatabaseAdminExecutor> actual =
MySQLSelectWithoutFromAdminExecutorFactory.newInstance(