This is an automated email from the ASF dual-hosted git repository.

iamhucong 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 fff1310070b Minor refacor in encrypt rewrite and 
QueryHeaderBuilderEngine (#38978)
fff1310070b is described below

commit fff1310070b6bb2f995917b63e6228dc65f96fc8
Author: Zhengqiang Duan <[email protected]>
AuthorDate: Thu Jul 2 13:59:08 2026 +0800

    Minor refacor in encrypt rewrite and QueryHeaderBuilderEngine (#38978)
---
 .../rewrite/token/EncryptTokenGenerateBuilder.java |  2 +-
 .../insert/EncryptInsertValuesTokenGenerator.java  | 25 ++++++++++-
 .../select/EncryptGroupByItemTokenGenerator.java   | 52 +++++++++++-----------
 .../EncryptInsertValuesTokenGeneratorTest.java     |  6 ++-
 .../connector/StandardDatabaseProxyConnector.java  | 10 ++---
 .../header/query/QueryHeaderBuilderEngine.java     | 35 +++++++++++----
 .../header/query/QueryHeaderBuilderEngineTest.java | 52 +++++++++++++++++++---
 .../prepare/MySQLProjectionMetadataResolver.java   |  4 +-
 .../impl/ShardingSphereProxyEmbeddedContainer.java |  3 +-
 .../storage/type/DockerStorageContainer.java       |  2 +-
 .../storage/type/NativeStorageContainer.java       | 42 +++++++++++++----
 .../test/e2e/sql/it/sql/dql/BaseDQLE2EIT.java      | 17 ++++---
 12 files changed, 185 insertions(+), 65 deletions(-)

diff --git 
a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/EncryptTokenGenerateBuilder.java
 
b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/EncryptTokenGenerateBuilder.java
index f06a46f786a..ef5eb45481e 100644
--- 
a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/EncryptTokenGenerateBuilder.java
+++ 
b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/EncryptTokenGenerateBuilder.java
@@ -72,7 +72,7 @@ public final class EncryptTokenGenerateBuilder implements 
SQLTokenGeneratorBuild
         addSQLTokenGenerator(result, new 
EncryptInsertPredicateColumnTokenGenerator(rule));
         addSQLTokenGenerator(result, new 
EncryptPredicateValueTokenGenerator(rule, database, encryptConditions));
         addSQLTokenGenerator(result, new 
EncryptInsertPredicateValueTokenGenerator(rule, database, encryptConditions));
-        addSQLTokenGenerator(result, new 
EncryptInsertValuesTokenGenerator(rule, database));
+        addSQLTokenGenerator(result, new 
EncryptInsertValuesTokenGenerator(rule, database, sqlRewriteContext));
         addSQLTokenGenerator(result, new 
EncryptInsertDefaultColumnsTokenGenerator(rule));
         addSQLTokenGenerator(result, new 
EncryptInsertCipherNameTokenGenerator(rule));
         addSQLTokenGenerator(result, new 
EncryptInsertDerivedColumnsTokenGenerator(rule));
diff --git 
a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/insert/EncryptInsertValuesTokenGenerator.java
 
b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/insert/EncryptInsertValuesTokenGenerator.java
index c69c0521bd3..ae14e6a125c 100644
--- 
a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/insert/EncryptInsertValuesTokenGenerator.java
+++ 
b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/insert/EncryptInsertValuesTokenGenerator.java
@@ -34,6 +34,7 @@ import 
org.apache.shardingsphere.infra.binder.context.segment.insert.values.Inse
 import 
org.apache.shardingsphere.infra.binder.context.statement.SQLStatementContext;
 import 
org.apache.shardingsphere.infra.binder.context.statement.type.dml.InsertStatementContext;
 import 
org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
+import org.apache.shardingsphere.infra.rewrite.context.SQLRewriteContext;
 import 
org.apache.shardingsphere.infra.rewrite.sql.token.common.generator.OptionalSQLTokenGenerator;
 import 
org.apache.shardingsphere.infra.rewrite.sql.token.common.generator.aware.PreviousSQLTokensAware;
 import 
org.apache.shardingsphere.infra.rewrite.sql.token.common.pojo.Attachable;
@@ -73,6 +74,8 @@ public final class EncryptInsertValuesTokenGenerator 
implements OptionalSQLToken
     
     private final ShardingSphereDatabase database;
     
+    private final SQLRewriteContext sqlRewriteContext;
+    
     private List<SQLToken> previousSQLTokens;
     
     @Override
@@ -199,6 +202,13 @@ public final class EncryptInsertValuesTokenGenerator 
implements OptionalSQLToken
         return Optional.empty();
     }
     
+    private Optional<String> getOriginalSQLExpressionText(final 
ExpressionSegment valueExpression) {
+        if (null == sqlRewriteContext || valueExpression.getStartIndex() < 0 
|| valueExpression.getStopIndex() >= sqlRewriteContext.getSql().length()) {
+            return Optional.empty();
+        }
+        return 
Optional.of(sqlRewriteContext.getSql().substring(valueExpression.getStartIndex(),
 valueExpression.getStopIndex() + 1));
+    }
+    
     private Optional<EncryptInsertColumnToken> addAssistedQueryColumn(final 
String schemaName, final String tableName, final EncryptColumn encryptColumn,
                                                                       final 
ExpressionSegment valueExpression, final int columnIndex, final Object 
originalValue,
                                                                       final 
int parameterIndexCount) {
@@ -248,13 +258,24 @@ public final class EncryptInsertValuesTokenGenerator 
implements OptionalSQLToken
     }
     
     private Optional<String> getTemporalLiteralValue(final ExpressionSegment 
valueExpression) {
-        if (null == valueExpression.getText()) {
+        return 
getTemporalLiteralExpressionText(valueExpression).flatMap(this::getTemporalLiteralValue);
+    }
+    
+    private Optional<String> getTemporalLiteralValue(final String 
expressionText) {
+        if (null == expressionText) {
             return Optional.empty();
         }
-        Matcher matcher = 
TEMPORAL_LITERAL_PATTERN.matcher(valueExpression.getText());
+        Matcher matcher = TEMPORAL_LITERAL_PATTERN.matcher(expressionText);
         return matcher.matches() ? Optional.of(matcher.group(1)) : 
Optional.empty();
     }
     
+    private Optional<String> getTemporalLiteralExpressionText(final 
ExpressionSegment valueExpression) {
+        if (getTemporalLiteralValue(valueExpression.getText()).isPresent()) {
+            return Optional.of(valueExpression.getText());
+        }
+        return getOriginalSQLExpressionText(valueExpression).filter(optional 
-> getTemporalLiteralValue(optional).isPresent());
+    }
+    
     private int getParameterIndexCount(final Collection<ExpressionSegment> 
expressionSegments) {
         int result = 0;
         for (ExpressionSegment each : expressionSegments) {
diff --git 
a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/select/EncryptGroupByItemTokenGenerator.java
 
b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/select/EncryptGroupByItemTokenGenerator.java
index 463c020eadc..04d9de9a354 100644
--- 
a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/select/EncryptGroupByItemTokenGenerator.java
+++ 
b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/select/EncryptGroupByItemTokenGenerator.java
@@ -22,6 +22,7 @@ import lombok.Setter;
 import 
org.apache.shardingsphere.database.connector.core.metadata.database.enums.QuoteCharacter;
 import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
 import 
org.apache.shardingsphere.database.connector.core.type.DatabaseTypeRegistry;
+import org.apache.shardingsphere.encrypt.enums.EncryptDerivedColumnSuffix;
 import org.apache.shardingsphere.encrypt.rule.EncryptRule;
 import org.apache.shardingsphere.encrypt.rule.column.EncryptColumn;
 import org.apache.shardingsphere.encrypt.rule.table.EncryptTable;
@@ -74,19 +75,25 @@ public final class EncryptGroupByItemTokenGenerator 
implements CollectionSQLToke
     
     @Override
     public Collection<SQLToken> generateSQLTokens(final SelectStatementContext 
sqlStatementContext) {
+        return generateGroupBySQLTokens(sqlStatementContext);
+    }
+    
+    private Collection<SQLToken> generateGroupBySQLTokens(final 
SelectStatementContext selectStatementContext) {
         Collection<SQLToken> result = new LinkedList<>();
-        for (GroupByContext each : getGroupByItems(sqlStatementContext)) {
-            for (OrderByItem item : each.getItems()) {
-                if (item.getSegment() instanceof ColumnOrderByItemSegment) {
-                    ColumnSegment columnSegment = ((ColumnOrderByItemSegment) 
item.getSegment()).getColumn();
-                    generateSQLToken(columnSegment, 
sqlStatementContext).ifPresent(result::add);
-                }
+        GroupByContext groupByContext = 
selectStatementContext.getGroupByContext();
+        for (OrderByItem item : groupByContext.getItems()) {
+            if (item.getSegment() instanceof ColumnOrderByItemSegment) {
+                ColumnSegment columnSegment = ((ColumnOrderByItemSegment) 
item.getSegment()).getColumn();
+                generateSQLToken(columnSegment, 
selectStatementContext).ifPresent(result::add);
             }
         }
+        for (SelectStatementContext each : 
selectStatementContext.getSubqueryContexts().values()) {
+            result.addAll(generateGroupBySQLTokens(each));
+        }
         return result;
     }
     
-    private Optional<SubstitutableColumnNameToken> generateSQLToken(final 
ColumnSegment columnSegment, final SelectStatementContext 
selectStatementContext) {
+    private Optional<SQLToken> generateSQLToken(final ColumnSegment 
columnSegment, final SelectStatementContext selectStatementContext) {
         DatabaseType databaseType = 
selectStatementContext.getSqlStatement().getDatabaseType();
         Optional<EncryptTable> encryptTable = 
rule.findEncryptTable(columnSegment.getColumnBoundInfo().getOriginalTable().getValue());
         String columnName = 
columnSegment.getColumnBoundInfo().getOriginalColumn().getValue();
@@ -96,29 +103,24 @@ public final class EncryptGroupByItemTokenGenerator 
implements CollectionSQLToke
         EncryptColumn encryptColumn = 
encryptTable.get().getEncryptColumn(columnName);
         int startIndex = columnSegment.getOwner().isPresent() ? 
columnSegment.getOwner().get().getStopIndex() + 2 : 
columnSegment.getStartIndex();
         int stopIndex = columnSegment.getStopIndex();
-        QuoteCharacter quoteCharacter = getQuoteCharacter(columnSegment, 
databaseType);
+        // SPEX CHANGED: BEGIN
         return Optional.of(encryptColumn.getAssistedQuery()
-                .map(optional -> new SubstitutableColumnNameToken(startIndex, 
stopIndex, createColumnProjections(optional.getName(), quoteCharacter, 
databaseType),
+                .map(optional -> new SubstitutableColumnNameToken(startIndex, 
stopIndex,
+                        createColumnProjections(optional.getName(), 
columnSegment, databaseType, EncryptDerivedColumnSuffix.ASSISTED_QUERY),
                         databaseType))
                 .orElseGet(() -> new SubstitutableColumnNameToken(startIndex, 
stopIndex,
-                        
createColumnProjections(encryptColumn.getCipher().getName(), quoteCharacter, 
databaseType), databaseType)));
-    }
-    
-    private Collection<GroupByContext> getGroupByItems(final 
SelectStatementContext sqlStatementContext) {
-        Collection<GroupByContext> result = new LinkedList<>();
-        result.add(sqlStatementContext.getGroupByContext());
-        for (SelectStatementContext each : 
sqlStatementContext.getSubqueryContexts().values()) {
-            result.addAll(getGroupByItems(each));
-        }
-        return result;
-    }
-    
-    private QuoteCharacter getQuoteCharacter(final ColumnSegment 
columnSegment, final DatabaseType databaseType) {
-        return TableSourceType.PHYSICAL_TABLE == 
columnSegment.getColumnBoundInfo().getTableSourceType() ? new 
DatabaseTypeRegistry(databaseType).getDialectDatabaseMetaData().getQuoteCharacter()
-                : columnSegment.getIdentifier().getQuoteCharacter();
+                        
createColumnProjections(encryptColumn.getCipher().getName(), columnSegment, 
databaseType, EncryptDerivedColumnSuffix.CIPHER), databaseType)));
+        // SPEX CHANGED: END
     }
     
-    private Collection<Projection> createColumnProjections(final String 
columnName, final QuoteCharacter quoteCharacter, final DatabaseType 
databaseType) {
+    private Collection<Projection> createColumnProjections(final String 
actualColumnName, final ColumnSegment columnSegment, final DatabaseType 
databaseType,
+                                                           final 
EncryptDerivedColumnSuffix derivedColumnSuffix) {
+        String columnName = TableSourceType.TEMPORARY_TABLE == 
columnSegment.getColumnBoundInfo().getTableSourceType()
+                ? 
derivedColumnSuffix.getDerivedColumnName(columnSegment.getIdentifier().getValue(),
 databaseType)
+                : actualColumnName;
+        QuoteCharacter quoteCharacter = TableSourceType.TEMPORARY_TABLE == 
columnSegment.getColumnBoundInfo().getTableSourceType()
+                ? columnSegment.getIdentifier().getQuoteCharacter()
+                : new 
DatabaseTypeRegistry(databaseType).getDialectDatabaseMetaData().getQuoteCharacter();
         return Collections.singleton(new ColumnProjection(null, new 
IdentifierValue(columnName, quoteCharacter), null, databaseType));
     }
 }
diff --git 
a/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/insert/EncryptInsertValuesTokenGeneratorTest.java
 
b/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/insert/EncryptInsertValuesTokenGeneratorTest.java
index 15b1b17bef0..d5337330e54 100644
--- 
a/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/insert/EncryptInsertValuesTokenGeneratorTest.java
+++ 
b/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/insert/EncryptInsertValuesTokenGeneratorTest.java
@@ -25,6 +25,7 @@ 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.rewrite.context.SQLRewriteContext;
 import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
 import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.assignment.InsertValuesSegment;
 import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.column.ColumnSegment;
@@ -49,6 +50,7 @@ import static org.hamcrest.Matchers.is;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
 
 class EncryptInsertValuesTokenGeneratorTest {
     
@@ -58,8 +60,10 @@ class EncryptInsertValuesTokenGeneratorTest {
     
     @BeforeEach
     void setup() {
+        SQLRewriteContext sqlRewriteContext = mock(SQLRewriteContext.class);
+        when(sqlRewriteContext.getSql()).thenReturn("");
         generator = new 
EncryptInsertValuesTokenGenerator(EncryptGeneratorFixtureBuilder.createEncryptRule(),
-                new ShardingSphereDatabase("foo_db", mock(), mock(), mock(), 
Collections.emptyList(), new ConfigurationProperties(new Properties())));
+                new ShardingSphereDatabase("foo_db", mock(), mock(), mock(), 
Collections.emptyList(), new ConfigurationProperties(new Properties())), 
sqlRewriteContext);
     }
     
     @Test
diff --git 
a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/connector/StandardDatabaseProxyConnector.java
 
b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/connector/StandardDatabaseProxyConnector.java
index 3076ab1fded..183643fa41d 100644
--- 
a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/connector/StandardDatabaseProxyConnector.java
+++ 
b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/connector/StandardDatabaseProxyConnector.java
@@ -300,9 +300,10 @@ public final class StandardDatabaseProxyConnector 
implements DatabaseProxyConnec
         int columnCount = getColumnCount(sqlStatementContext, 
queryResultSample);
         List<QueryHeader> result = new ArrayList<>(columnCount);
         QueryHeaderBuilderEngine queryHeaderBuilderEngine = new 
QueryHeaderBuilderEngine(database.getProtocolType());
+        Collection<ShardingSphereDatabase> databases = 
queryContext.getMetaData().getAllDatabases();
         ShardingSphereResultSetMetaData resultSetMetaData = new 
ShardingSphereResultSetMetaData(queryResultSample.getMetaData().getResultSetMetaData(),
 database, sqlStatementContext);
         for (int columnIndex = 1; columnIndex <= columnCount; columnIndex++) {
-            result.add(createQueryHeader(queryHeaderBuilderEngine, 
sqlStatementContext, resultSetMetaData, database, columnIndex));
+            result.add(createQueryHeader(queryHeaderBuilderEngine, 
sqlStatementContext, resultSetMetaData, database, databases, columnIndex));
         }
         return result;
     }
@@ -314,10 +315,9 @@ public final class StandardDatabaseProxyConnector 
implements DatabaseProxyConnec
     }
     
     private QueryHeader createQueryHeader(final QueryHeaderBuilderEngine 
queryHeaderBuilderEngine, final SQLStatementContext sqlStatementContext,
-                                          final 
ShardingSphereResultSetMetaData resultSetMetaData, final ShardingSphereDatabase 
database, final int columnIndex) throws SQLException {
-        return containsDerivedProjections
-                ? queryHeaderBuilderEngine.build(((SelectStatementContext) 
sqlStatementContext).getProjectionsContext(), resultSetMetaData, database, 
columnIndex)
-                : queryHeaderBuilderEngine.build(resultSetMetaData, database, 
columnIndex);
+                                          final 
ShardingSphereResultSetMetaData resultSetMetaData, final ShardingSphereDatabase 
database,
+                                          final 
Collection<ShardingSphereDatabase> databases, final int columnIndex) throws 
SQLException {
+        return queryHeaderBuilderEngine.build(sqlStatementContext, 
resultSetMetaData, database, databases, columnIndex);
     }
     
     private MergedResult mergeQuery(final List<QueryResult> queryResults) 
throws SQLException {
diff --git 
a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/response/header/query/QueryHeaderBuilderEngine.java
 
b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/response/header/query/QueryHeaderBuilderEngine.java
index d43c26169b1..dd1ec10889e 100644
--- 
a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/response/header/query/QueryHeaderBuilderEngine.java
+++ 
b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/response/header/query/QueryHeaderBuilderEngine.java
@@ -21,12 +21,14 @@ import 
org.apache.shardingsphere.database.connector.core.spi.DatabaseTypedSPILoa
 import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
 import 
org.apache.shardingsphere.driver.jdbc.core.resultset.ShardingSphereResultSetMetaData;
 import 
org.apache.shardingsphere.infra.binder.context.segment.select.projection.Projection;
-import 
org.apache.shardingsphere.infra.binder.context.segment.select.projection.ProjectionsContext;
+import 
org.apache.shardingsphere.infra.binder.context.statement.SQLStatementContext;
+import 
org.apache.shardingsphere.infra.binder.context.statement.type.dml.SelectStatementContext;
 import org.apache.shardingsphere.infra.exception.ShardingSpherePreconditions;
 import 
org.apache.shardingsphere.infra.exception.kernel.syntax.ColumnIndexOutOfRangeException;
 import 
org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
 
 import java.sql.SQLException;
+import java.util.Collection;
 
 /**
  * Query header builder engine.
@@ -57,17 +59,34 @@ public final class QueryHeaderBuilderEngine {
     /**
      * Build query header builder.
      *
-     * @param projectionsContext projections context
+     * @param sqlStatementContext SQL statement context
      * @param resultSetMetaData result set meta data
-     * @param database database
+     * @param database current database
+     * @param databases available databases
      * @param columnIndex column index
      * @return query header
      * @throws SQLException SQL exception
      */
-    public QueryHeader build(final ProjectionsContext projectionsContext, 
final ShardingSphereResultSetMetaData resultSetMetaData, final 
ShardingSphereDatabase database,
-                             final int columnIndex) throws SQLException {
-        ShardingSpherePreconditions.checkState(columnIndex <= 
projectionsContext.getExpandProjections().size(), () -> new 
ColumnIndexOutOfRangeException(columnIndex));
-        Projection projection = 
projectionsContext.getExpandProjections().get(columnIndex - 1);
-        return queryHeaderBuilder.build(resultSetMetaData, database, 
projection.getColumnName(), projection.getColumnLabel(), columnIndex);
+    public QueryHeader build(final SQLStatementContext sqlStatementContext, 
final ShardingSphereResultSetMetaData resultSetMetaData, final 
ShardingSphereDatabase database,
+                             final Collection<ShardingSphereDatabase> 
databases, final int columnIndex) throws SQLException {
+        Projection projection = findProjection(sqlStatementContext, 
columnIndex);
+        return null == projection
+                ? build(resultSetMetaData, database, columnIndex)
+                : queryHeaderBuilder.build(resultSetMetaData, database, 
projection.getColumnName(), projection.getColumnLabel(), columnIndex);
+    }
+    
+    private Projection findProjection(final SQLStatementContext 
sqlStatementContext, final int columnIndex) {
+        if (!(sqlStatementContext instanceof SelectStatementContext) || 
!((SelectStatementContext) sqlStatementContext).containsDerivedProjections()) {
+            return null;
+        }
+        checkColumnIndex(sqlStatementContext, columnIndex);
+        return ((SelectStatementContext) 
sqlStatementContext).getProjectionsContext().getExpandProjections().get(columnIndex
 - 1);
+    }
+    
+    private void checkColumnIndex(final SQLStatementContext 
sqlStatementContext, final int columnIndex) {
+        if (sqlStatementContext instanceof SelectStatementContext && 
((SelectStatementContext) sqlStatementContext).containsDerivedProjections()) {
+            ShardingSpherePreconditions.checkState(columnIndex <= 
((SelectStatementContext) 
sqlStatementContext).getProjectionsContext().getExpandProjections().size(),
+                    () -> new ColumnIndexOutOfRangeException(columnIndex));
+        }
     }
 }
diff --git 
a/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/response/header/query/QueryHeaderBuilderEngineTest.java
 
b/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/response/header/query/QueryHeaderBuilderEngineTest.java
index bf99744d57d..58b13bbf844 100644
--- 
a/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/response/header/query/QueryHeaderBuilderEngineTest.java
+++ 
b/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/response/header/query/QueryHeaderBuilderEngineTest.java
@@ -22,6 +22,8 @@ import 
org.apache.shardingsphere.database.connector.core.type.DatabaseType;
 import 
org.apache.shardingsphere.driver.jdbc.core.resultset.ShardingSphereResultSetMetaData;
 import 
org.apache.shardingsphere.infra.binder.context.segment.select.projection.Projection;
 import 
org.apache.shardingsphere.infra.binder.context.segment.select.projection.ProjectionsContext;
+import 
org.apache.shardingsphere.infra.binder.context.statement.SQLStatementContext;
+import 
org.apache.shardingsphere.infra.binder.context.statement.type.dml.SelectStatementContext;
 import 
org.apache.shardingsphere.infra.exception.kernel.syntax.ColumnIndexOutOfRangeException;
 import 
org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
 import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
@@ -31,8 +33,8 @@ import org.mockito.MockedStatic;
 import java.sql.SQLException;
 import java.util.Collections;
 
-import static org.hamcrest.Matchers.is;
 import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
 import static org.junit.jupiter.api.Assertions.assertThrows;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.mockStatic;
@@ -59,12 +61,15 @@ class QueryHeaderBuilderEngineTest {
     }
     
     @Test
-    void assertBuildWithProjections() throws SQLException {
+    void assertBuildWithDerivedProjections() throws SQLException {
         Projection projection = mock(Projection.class);
         when(projection.getColumnName()).thenReturn("c1");
         when(projection.getColumnLabel()).thenReturn("l1");
         when(projection.getExpression()).thenReturn("c1");
         ProjectionsContext projectionsContext = new ProjectionsContext(0, 0, 
false, Collections.singleton(projection));
+        SelectStatementContext sqlStatementContext = 
mock(SelectStatementContext.class);
+        
when(sqlStatementContext.containsDerivedProjections()).thenReturn(true);
+        
when(sqlStatementContext.getProjectionsContext()).thenReturn(projectionsContext);
         ShardingSphereResultSetMetaData resultSetMetaData = 
mock(ShardingSphereResultSetMetaData.class);
         ShardingSphereDatabase database = mock(ShardingSphereDatabase.class);
         QueryHeader expectedQueryHeader = mock(QueryHeader.class);
@@ -72,22 +77,59 @@ class QueryHeaderBuilderEngineTest {
             QueryHeaderBuilder queryHeaderBuilder = 
mock(QueryHeaderBuilder.class);
             when(queryHeaderBuilder.build(resultSetMetaData, database, "c1", 
"l1", 1)).thenReturn(expectedQueryHeader);
             spiLoader.when(() -> 
DatabaseTypedSPILoader.getService(QueryHeaderBuilder.class, 
databaseType)).thenReturn(queryHeaderBuilder);
-            QueryHeader actualQueryHeader = new 
QueryHeaderBuilderEngine(databaseType).build(projectionsContext, 
resultSetMetaData, database, 1);
+            QueryHeader actualQueryHeader = new 
QueryHeaderBuilderEngine(databaseType).build(sqlStatementContext, 
resultSetMetaData, database, Collections.singleton(database), 1);
+            assertThat(actualQueryHeader, is(expectedQueryHeader));
+        }
+    }
+    
+    @Test
+    void assertBuildWithDerivedProjectionsColumnIndexOutOfRange() {
+        Projection projection = mock(Projection.class);
+        when(projection.getColumnLabel()).thenReturn("label");
+        when(projection.getColumnName()).thenReturn("column");
+        when(projection.getExpression()).thenReturn("column");
+        ProjectionsContext projectionsContext = new ProjectionsContext(0, 0, 
false, Collections.singleton(projection));
+        SelectStatementContext sqlStatementContext = 
mock(SelectStatementContext.class);
+        
when(sqlStatementContext.containsDerivedProjections()).thenReturn(true);
+        
when(sqlStatementContext.getProjectionsContext()).thenReturn(projectionsContext);
+        try (MockedStatic<DatabaseTypedSPILoader> spiLoader = 
mockStatic(DatabaseTypedSPILoader.class)) {
+            spiLoader.when(() -> 
DatabaseTypedSPILoader.getService(QueryHeaderBuilder.class, 
databaseType)).thenReturn(mock(QueryHeaderBuilder.class));
+            assertThrows(ColumnIndexOutOfRangeException.class,
+                    () -> new 
QueryHeaderBuilderEngine(databaseType).build(sqlStatementContext, 
mock(ShardingSphereResultSetMetaData.class), mock(), 
Collections.singleton(mock()), 2));
+        }
+    }
+    
+    @Test
+    void assertBuildWithSQLStatementContext() throws SQLException {
+        SQLStatementContext sqlStatementContext = 
mock(SQLStatementContext.class);
+        ShardingSphereResultSetMetaData resultSetMetaData = 
mock(ShardingSphereResultSetMetaData.class);
+        when(resultSetMetaData.getColumnName(1)).thenReturn("col_name");
+        when(resultSetMetaData.getColumnLabel(1)).thenReturn("col_label");
+        ShardingSphereDatabase database = mock(ShardingSphereDatabase.class);
+        QueryHeader expectedQueryHeader = mock(QueryHeader.class);
+        try (MockedStatic<DatabaseTypedSPILoader> spiLoader = 
mockStatic(DatabaseTypedSPILoader.class)) {
+            QueryHeaderBuilder queryHeaderBuilder = 
mock(QueryHeaderBuilder.class);
+            when(queryHeaderBuilder.build(resultSetMetaData, database, 
"col_name", "col_label", 1)).thenReturn(expectedQueryHeader);
+            spiLoader.when(() -> 
DatabaseTypedSPILoader.getService(QueryHeaderBuilder.class, 
databaseType)).thenReturn(queryHeaderBuilder);
+            QueryHeader actualQueryHeader = new 
QueryHeaderBuilderEngine(databaseType).build(sqlStatementContext, 
resultSetMetaData, database, Collections.singleton(database), 1);
             assertThat(actualQueryHeader, is(expectedQueryHeader));
         }
     }
     
     @Test
-    void assertBuildWithProjectionsColumnIndexOutOfRange() {
+    void assertBuildWithSQLStatementContextColumnIndexOutOfRange() {
         Projection projection = mock(Projection.class);
         when(projection.getColumnLabel()).thenReturn("label");
         when(projection.getColumnName()).thenReturn("column");
         when(projection.getExpression()).thenReturn("column");
         ProjectionsContext projectionsContext = new ProjectionsContext(0, 0, 
false, Collections.singleton(projection));
+        SelectStatementContext sqlStatementContext = 
mock(SelectStatementContext.class);
+        
when(sqlStatementContext.containsDerivedProjections()).thenReturn(true);
+        
when(sqlStatementContext.getProjectionsContext()).thenReturn(projectionsContext);
         try (MockedStatic<DatabaseTypedSPILoader> spiLoader = 
mockStatic(DatabaseTypedSPILoader.class)) {
             spiLoader.when(() -> 
DatabaseTypedSPILoader.getService(QueryHeaderBuilder.class, 
databaseType)).thenReturn(mock(QueryHeaderBuilder.class));
             assertThrows(ColumnIndexOutOfRangeException.class,
-                    () -> new 
QueryHeaderBuilderEngine(databaseType).build(projectionsContext, 
mock(ShardingSphereResultSetMetaData.class), mock(), 2));
+                    () -> new 
QueryHeaderBuilderEngine(databaseType).build(sqlStatementContext, 
mock(ShardingSphereResultSetMetaData.class), mock(), 
Collections.singleton(mock()), 2));
         }
     }
 }
diff --git 
a/proxy/frontend/dialect/mysql/src/main/java/org/apache/shardingsphere/proxy/frontend/mysql/command/query/binary/prepare/MySQLProjectionMetadataResolver.java
 
b/proxy/frontend/dialect/mysql/src/main/java/org/apache/shardingsphere/proxy/frontend/mysql/command/query/binary/prepare/MySQLProjectionMetadataResolver.java
index 9c6e417c078..ebd0a75fc32 100644
--- 
a/proxy/frontend/dialect/mysql/src/main/java/org/apache/shardingsphere/proxy/frontend/mysql/command/query/binary/prepare/MySQLProjectionMetadataResolver.java
+++ 
b/proxy/frontend/dialect/mysql/src/main/java/org/apache/shardingsphere/proxy/frontend/mysql/command/query/binary/prepare/MySQLProjectionMetadataResolver.java
@@ -40,6 +40,7 @@ import java.sql.Types;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.HashSet;
 
 /**
@@ -77,7 +78,8 @@ public final class MySQLProjectionMetadataResolver {
             QueryHeaderBuilderEngine queryHeaderBuilderEngine = new 
QueryHeaderBuilderEngine(database.getProtocolType());
             Collection<MySQLPacket> result = new 
ArrayList<>(selectStatementContext.getProjectionsContext().getExpandProjections().size());
             for (int columnIndex = 1; columnIndex <= 
selectStatementContext.getProjectionsContext().getExpandProjections().size(); 
columnIndex++) {
-                QueryHeader queryHeader = 
queryHeaderBuilderEngine.build(selectStatementContext.getProjectionsContext(), 
resultSetMetaData, database, columnIndex);
+                QueryHeader queryHeader =
+                        queryHeaderBuilderEngine.build(selectStatementContext, 
resultSetMetaData, database, Collections.singleton(database), columnIndex);
                 result.add(createMySQLColumnDefinition41Packet(queryHeader, 
characterSet));
             }
             return result;
diff --git 
a/test/e2e/env/src/test/java/org/apache/shardingsphere/test/e2e/env/container/adapter/impl/ShardingSphereProxyEmbeddedContainer.java
 
b/test/e2e/env/src/test/java/org/apache/shardingsphere/test/e2e/env/container/adapter/impl/ShardingSphereProxyEmbeddedContainer.java
index a9c9bc6ed31..8e95cc4685d 100644
--- 
a/test/e2e/env/src/test/java/org/apache/shardingsphere/test/e2e/env/container/adapter/impl/ShardingSphereProxyEmbeddedContainer.java
+++ 
b/test/e2e/env/src/test/java/org/apache/shardingsphere/test/e2e/env/container/adapter/impl/ShardingSphereProxyEmbeddedContainer.java
@@ -127,7 +127,8 @@ public final class ShardingSphereProxyEmbeddedContainer 
implements EmbeddedE2ECo
     
     @SneakyThrows({SQLException.class, IOException.class, 
InterruptedException.class})
     private void startProxy() {
-        YamlProxyConfiguration yamlConfig = 
ProxyConfigurationLoader.load(getTempConfigurationDirectory().toString());
+        Path tempConfigurationDirectory = getTempConfigurationDirectory();
+        YamlProxyConfiguration yamlConfig = 
ProxyConfigurationLoader.load(tempConfigurationDirectory.toString());
         new BootstrapInitializer().init(yamlConfig, proxyPort);
         ProxySSLContext.init();
         proxy = new ShardingSphereProxy();
diff --git 
a/test/e2e/env/src/test/java/org/apache/shardingsphere/test/e2e/env/container/storage/type/DockerStorageContainer.java
 
b/test/e2e/env/src/test/java/org/apache/shardingsphere/test/e2e/env/container/storage/type/DockerStorageContainer.java
index f812e679e83..f4a104b205f 100644
--- 
a/test/e2e/env/src/test/java/org/apache/shardingsphere/test/e2e/env/container/storage/type/DockerStorageContainer.java
+++ 
b/test/e2e/env/src/test/java/org/apache/shardingsphere/test/e2e/env/container/storage/type/DockerStorageContainer.java
@@ -165,7 +165,7 @@ public final class DockerStorageContainer extends 
DockerE2EContainer implements
     }
     
     private Map<String, DataSource> createAccessDataSources(final 
Collection<String> databaseNames) {
-        return 
databaseNames.stream().distinct().collect(Collectors.toMap(Function.identity(), 
this::createAccessDataSource));
+        return 
databaseNames.stream().distinct().collect(Collectors.toMap(Function.identity(), 
this::createAccessDataSource, (previous, current) -> previous, 
LinkedHashMap::new));
     }
     
     /**
diff --git 
a/test/e2e/env/src/test/java/org/apache/shardingsphere/test/e2e/env/container/storage/type/NativeStorageContainer.java
 
b/test/e2e/env/src/test/java/org/apache/shardingsphere/test/e2e/env/container/storage/type/NativeStorageContainer.java
index 7cdc7831c5a..9b4653e4aaf 100644
--- 
a/test/e2e/env/src/test/java/org/apache/shardingsphere/test/e2e/env/container/storage/type/NativeStorageContainer.java
+++ 
b/test/e2e/env/src/test/java/org/apache/shardingsphere/test/e2e/env/container/storage/type/NativeStorageContainer.java
@@ -21,7 +21,6 @@ import lombok.Getter;
 import lombok.Setter;
 import 
org.apache.shardingsphere.database.connector.core.spi.DatabaseTypedSPILoader;
 import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
-import 
org.apache.shardingsphere.test.e2e.env.container.constants.StorageContainerConstants;
 import 
org.apache.shardingsphere.test.e2e.env.container.storage.StorageContainer;
 import 
org.apache.shardingsphere.test.e2e.env.container.storage.mount.MountSQLResourceGenerator;
 import 
org.apache.shardingsphere.test.e2e.env.container.storage.option.StorageContainerOption;
@@ -37,6 +36,7 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 
@@ -47,6 +47,8 @@ public final class NativeStorageContainer implements 
StorageContainer {
     
     private static final Collection<String> INITIALIZED_DATABASES = new 
HashSet<>();
     
+    private static final String SQL_RESOURCE_SUFFIX = ".sql";
+    
     private final NativeDatabaseEnvironment env;
     
     @Getter
@@ -89,14 +91,40 @@ public final class NativeStorageContainer implements 
StorageContainer {
     }
     
     private void initDatabase(final String initDatabaseCacheKey) {
-        DataSource dataSource = 
StorageContainerUtils.generateDataSource(option.getConnectOption().getURL(env.getHost(),
 env.getPort(databaseType)),
-                env.getUser(), env.getPassword(), 2);
-        new MountSQLResourceGenerator(option.getType(), 
option.getCreateOption()).generate(0, scenario).keySet().forEach(each -> 
SQLScriptUtils.execute(dataSource, each));
+        DataSource dataSource = createInitDataSource();
+        Map<String, String> mountedResources = generateMountedResources();
+        executeSQLScripts(dataSource, mountedResources.keySet());
         INITIALIZED_DATABASES.add(initDatabaseCacheKey);
     }
     
+    private Map<String, String> generateMountedResources() {
+        return new MountSQLResourceGenerator(option.getType(), 
option.getCreateOption()).generate(getDefaultMajorVersion(), scenario);
+    }
+    
+    private int getDefaultMajorVersion() {
+        List<Integer> supportedMajorVersions = 
option.getCreateOption().getSupportedMajorVersions();
+        return supportedMajorVersions.isEmpty() ? 0 : 
supportedMajorVersions.get(0);
+    }
+    
+    private void executeSQLScripts(final DataSource dataSource, final 
Collection<String> mountedResources) {
+        for (String each : mountedResources) {
+            if (each.endsWith(SQL_RESOURCE_SUFFIX)) {
+                SQLScriptUtils.execute(dataSource, each);
+            }
+        }
+    }
+    
+    private DataSource createInitDataSource() {
+        return 
StorageContainerUtils.generateDataSource(option.getConnectOption().getURL(env.getHost(),
 env.getPort(databaseType)),
+                getInitUser(), env.getPassword(), 2);
+    }
+    
+    private String getInitUser() {
+        return env.getUser();
+    }
+    
     private String getInitDatabaseCacheKey() {
-        return String.join(":", String.valueOf(scenario), 
databaseType.getType(), env.getHost(), 
String.valueOf(env.getPort(databaseType)));
+        return String.join(":", String.valueOf(scenario), 
databaseType.getType(), env.getHost(), 
String.valueOf(env.getPort(databaseType)), 
String.valueOf(getDefaultMajorVersion()));
     }
     
     private Map<String, DataSource> createDataSourceMap(final Type type) {
@@ -104,7 +132,7 @@ public final class NativeStorageContainer implements 
StorageContainer {
     }
     
     private Map<String, DataSource> getDataSourceMap(final Collection<String> 
databaseNames) {
-        Map<String, DataSource> result = new HashMap<>(databaseNames.size(), 
1F);
+        Map<String, DataSource> result = new 
LinkedHashMap<>(databaseNames.size(), 1F);
         for (String each : databaseNames) {
             DataSource dataSource = 
StorageContainerUtils.generateDataSource(option.getConnectOption().getURL(env.getHost(),
 env.getPort(databaseType), each),
                     env.getUser(), env.getPassword(), 2);
@@ -137,8 +165,6 @@ public final class NativeStorageContainer implements 
StorageContainer {
         for (String each : getNetworkAliases()) {
             result.put(each + ":" + getExposedPort(), env.getHost() + ":" + 
env.getPort(databaseType));
         }
-        result.put(StorageContainerConstants.OPERATION_USER, env.getUser());
-        result.put(StorageContainerConstants.OPERATION_PASSWORD, 
env.getPassword());
         return result;
     }
 }
diff --git 
a/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/sql/it/sql/dql/BaseDQLE2EIT.java
 
b/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/sql/it/sql/dql/BaseDQLE2EIT.java
index 3c2e7e7ace6..6177de21254 100644
--- 
a/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/sql/it/sql/dql/BaseDQLE2EIT.java
+++ 
b/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/sql/it/sql/dql/BaseDQLE2EIT.java
@@ -108,11 +108,15 @@ public abstract class BaseDQLE2EIT implements SQLE2EIT {
     }
     
     private DataSource getExpectedDataSource(final AssertionTestParameter 
testParam, final SQLE2EITContext context) {
-        if (null != context.getAssertion().getExpectedDataSourceName() && 1 != 
getEnvironmentEngine().getExpectedDataSourceMap().size()) {
-            return 
getEnvironmentEngine().getExpectedDataSourceMap().get(context.getAssertion().getExpectedDataSourceName());
+        Map<String, DataSource> expectedDataSourceMap = 
getEnvironmentEngine().getExpectedDataSourceMap();
+        if (null != context.getAssertion().getExpectedDataSourceName() && 1 != 
expectedDataSourceMap.size()) {
+            return 
expectedDataSourceMap.get(context.getAssertion().getExpectedDataSourceName());
         }
-        DataSource result = 
getEnvironmentEngine().getExpectedDataSourceMap().get(testParam.getScenario());
-        return null == result ? 
getFirstExpectedDataSource(getEnvironmentEngine().getExpectedDataSourceMap().values())
 : result;
+        DataSource result = expectedDataSourceMap.get(testParam.getScenario());
+        if (null == result) {
+            result = expectedDataSourceMap.get(testParam.getScenario());
+        }
+        return null == result ? 
getFirstExpectedDataSource(expectedDataSourceMap.values()) : result;
     }
     
     private void fillDataOnlyOnce(final AssertionTestParameter testParam) 
throws IOException, JAXBException {
@@ -127,9 +131,8 @@ public abstract class BaseDQLE2EIT implements SQLE2EIT {
             new DataSetEnvironmentManager(
                     new ScenarioDataPath(testParam.getScenario(), 
Type.ACTUAL).getDataSetFile(), getEnvironmentEngine().getActualDataSourceMap(),
                     
testParam.getDatabaseType()).fillData(Collections.emptyList());
-            new DataSetEnvironmentManager(
-                    new ScenarioDataPath(testParam.getScenario(), 
Type.EXPECTED).getDataSetFile(), 
getEnvironmentEngine().getExpectedDataSourceMap(),
-                    
testParam.getDatabaseType()).fillData(Collections.emptyList());
+            new DataSetEnvironmentManager(new 
ScenarioDataPath(testParam.getScenario(), Type.EXPECTED).getDataSetFile(),
+                    getEnvironmentEngine().getExpectedDataSourceMap(), 
testParam.getDatabaseType()).fillData(Collections.emptyList());
             FILLED_SUITES.add(cacheKey);
         }
     }


Reply via email to