This is an automated email from the ASF dual-hosted git repository.
menghaoranss 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 7076a80677c Use database default schema in MySQL prepare executor
(#39596)
7076a80677c is described below
commit 7076a80677c2379d94da941a3ba5baae9d00d509
Author: Haoran Meng <[email protected]>
AuthorDate: Tue Aug 25 11:23:06 2026 +0800
Use database default schema in MySQL prepare executor (#39596)
---
.../prepare/MySQLComStmtPrepareExecutor.java | 3 +-
.../prepare/MySQLComStmtPrepareExecutorTest.java | 45 ++++++++++++++++++++++
2 files changed, 46 insertions(+), 2 deletions(-)
diff --git
a/proxy/frontend/dialect/mysql/src/main/java/org/apache/shardingsphere/proxy/frontend/mysql/command/query/binary/prepare/MySQLComStmtPrepareExecutor.java
b/proxy/frontend/dialect/mysql/src/main/java/org/apache/shardingsphere/proxy/frontend/mysql/command/query/binary/prepare/MySQLComStmtPrepareExecutor.java
index 1a7408ea58f..d6af2412ee3 100644
---
a/proxy/frontend/dialect/mysql/src/main/java/org/apache/shardingsphere/proxy/frontend/mysql/command/query/binary/prepare/MySQLComStmtPrepareExecutor.java
+++
b/proxy/frontend/dialect/mysql/src/main/java/org/apache/shardingsphere/proxy/frontend/mysql/command/query/binary/prepare/MySQLComStmtPrepareExecutor.java
@@ -19,7 +19,6 @@ package
org.apache.shardingsphere.proxy.frontend.mysql.command.query.binary.prep
import lombok.RequiredArgsConstructor;
import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
-import
org.apache.shardingsphere.database.connector.core.type.DatabaseTypeRegistry;
import
org.apache.shardingsphere.database.exception.mysql.exception.TooManyPlaceholdersException;
import
org.apache.shardingsphere.database.exception.mysql.exception.UnsupportedPreparedStatementException;
import
org.apache.shardingsphere.database.protocol.mysql.constant.MySQLBinaryColumnType;
@@ -228,7 +227,7 @@ public final class MySQLComStmtPrepareExecutor implements
CommandExecutor {
String databaseName =
sqlStatementContext.getTablesContext().getDatabaseName().orElseGet(connectionSession::getCurrentDatabaseName);
ShardingSphereDatabase database =
ProxyContext.getInstance().getContextManager().getMetaDataContexts().getMetaData().getDatabase(databaseName);
return
sqlStatementContext.getTablesContext().getSchemaName().map(database::getSchema)
- .orElseGet(() -> database.getSchema(new
DatabaseTypeRegistry(sqlStatementContext.getSqlStatement().getDatabaseType()).getDefaultSchemaName(database.getName())));
+ .orElseGet(() -> database.findDefaultSchema().orElse(null));
}
private int calculateColumnDefinitionFlag(final ShardingSphereColumn
column) {
diff --git
a/proxy/frontend/dialect/mysql/src/test/java/org/apache/shardingsphere/proxy/frontend/mysql/command/query/binary/prepare/MySQLComStmtPrepareExecutorTest.java
b/proxy/frontend/dialect/mysql/src/test/java/org/apache/shardingsphere/proxy/frontend/mysql/command/query/binary/prepare/MySQLComStmtPrepareExecutorTest.java
index ca7e3767b63..a2ef80203c3 100644
---
a/proxy/frontend/dialect/mysql/src/test/java/org/apache/shardingsphere/proxy/frontend/mysql/command/query/binary/prepare/MySQLComStmtPrepareExecutorTest.java
+++
b/proxy/frontend/dialect/mysql/src/test/java/org/apache/shardingsphere/proxy/frontend/mysql/command/query/binary/prepare/MySQLComStmtPrepareExecutorTest.java
@@ -34,10 +34,12 @@ import
org.apache.shardingsphere.database.protocol.mysql.packet.command.query.bi
import
org.apache.shardingsphere.database.protocol.mysql.packet.generic.MySQLEofPacket;
import
org.apache.shardingsphere.database.protocol.mysql.payload.MySQLPacketPayload;
import org.apache.shardingsphere.database.protocol.packet.DatabasePacket;
+import
org.apache.shardingsphere.infra.binder.context.segment.table.TablesContext;
import
org.apache.shardingsphere.infra.binder.context.statement.type.dml.InsertStatementContext;
import
org.apache.shardingsphere.infra.binder.context.statement.type.dml.SelectStatementContext;
import
org.apache.shardingsphere.infra.binder.context.statement.type.dml.UpdateStatementContext;
import
org.apache.shardingsphere.infra.binder.context.statement.type.dml.DeleteStatementContext;
+import org.apache.shardingsphere.infra.binder.engine.SQLBindEngine;
import org.apache.shardingsphere.infra.hint.HintValueContext;
import
org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
import
org.apache.shardingsphere.infra.metadata.database.resource.ResourceMetaData;
@@ -67,6 +69,7 @@ import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Answers;
import org.mockito.Mock;
+import org.mockito.MockedConstruction;
import org.mockito.junit.jupiter.MockitoSettings;
import org.mockito.quality.Strictness;
@@ -77,6 +80,7 @@ import java.sql.Types;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
+import java.util.Optional;
import java.util.Properties;
import static org.hamcrest.Matchers.is;
@@ -88,6 +92,7 @@ import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.mockConstruction;
import static org.mockito.Mockito.when;
@ExtendWith(AutoMockExtension.class)
@@ -341,6 +346,46 @@ class MySQLComStmtPrepareExecutorTest {
MySQLStatementIdGenerator.getInstance().unregisterConnection(1);
}
+ @Test
+ void assertPrepareUpdateStatementWithDatabaseDefaultSchema() {
+ String sql = "UPDATE user SET age = ?";
+ when(packet.getSQL()).thenReturn(sql);
+ when(packet.getHintValueContext()).thenReturn(new HintValueContext());
+ int connectionId = 6;
+ when(connectionSession.getConnectionId()).thenReturn(connectionId);
+ when(connectionSession.getCurrentDatabaseName()).thenReturn("foo_db");
+ ContextManager contextManager = mockContextManager();
+ ShardingSphereSchema defaultSchema =
createDatabase().getSchema("foo_db");
+ ShardingSphereDatabase database = mock(ShardingSphereDatabase.class);
+ when(database.getName()).thenReturn("foo_db");
+
when(database.findDefaultSchema()).thenReturn(Optional.of(defaultSchema));
+
when(contextManager.getMetaDataContexts().getMetaData().getDatabase("foo_db")).thenReturn(database);
+
when(ProxyContext.getInstance().getContextManager()).thenReturn(contextManager);
+ UpdateStatement sqlStatement = (UpdateStatement)
contextManager.getMetaDataContexts().getMetaData().getGlobalRuleMetaData().getSingleRule(SQLParserRule.class)
+ .getSQLParserEngine(databaseType).parse(sql, true);
+ UpdateStatementContext sqlStatementContext =
mock(UpdateStatementContext.class, RETURNS_DEEP_STUBS);
+ when(sqlStatementContext.getSqlStatement()).thenReturn(sqlStatement);
+ TablesContext tablesContext = mock(TablesContext.class);
+
when(tablesContext.getDatabaseName()).thenReturn(Optional.of("foo_db"));
+ when(tablesContext.getSchemaName()).thenReturn(Optional.empty());
+
when(tablesContext.getTableNames()).thenReturn(Collections.singleton("user"));
+ when(sqlStatementContext.getTablesContext()).thenReturn(tablesContext);
+
MySQLStatementIdGenerator.getInstance().registerConnection(connectionId);
+ try (
+ MockedConstruction<SQLBindEngine> ignored =
mockConstruction(SQLBindEngine.class,
+ (mock, context) ->
when(mock.bind(any(UpdateStatement.class))).thenReturn(sqlStatementContext))) {
+ Iterator<DatabasePacket> actualIterator = new
MySQLComStmtPrepareExecutor(packet, connectionSession).execute().iterator();
+ assertThat(actualIterator.next(),
isA(MySQLComStmtPrepareOKPacket.class));
+ assertThat(actualIterator.next(),
isA(MySQLColumnDefinition41Packet.class));
+ assertThat(actualIterator.next(), isA(MySQLEofPacket.class));
+ assertFalse(actualIterator.hasNext());
+ MySQLServerPreparedStatement actualPreparedStatement =
connectionSession.getServerPreparedStatementRegistry().getPreparedStatement(1);
+ assertThat(actualPreparedStatement.getParameterColumnTypes(),
is(Collections.singletonList(MySQLBinaryColumnType.SHORT)));
+ } finally {
+
MySQLStatementIdGenerator.getInstance().unregisterConnection(connectionId);
+ }
+ }
+
@Test
void assertPrepareDeleteStatement() {
String sql = "DELETE FROM user WHERE name = ?";