Copilot commented on code in PR #37778: URL: https://github.com/apache/shardingsphere/pull/37778#discussion_r2706708997
########## jdbc/src/main/java/org/apache/shardingsphere/driver/executor/engine/distsql/DriverDistSQLExecutor.java: ########## @@ -0,0 +1,120 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.shardingsphere.driver.executor.engine.distsql; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import org.apache.shardingsphere.distsql.handler.engine.DistSQLConnectionContext; +import org.apache.shardingsphere.distsql.handler.engine.query.DistSQLQueryExecuteEngine; +import org.apache.shardingsphere.distsql.handler.engine.update.DistSQLUpdateExecuteEngine; +import org.apache.shardingsphere.distsql.statement.DistSQLStatement; +import org.apache.shardingsphere.distsql.statement.type.ral.queryable.QueryableRALStatement; +import org.apache.shardingsphere.distsql.statement.type.rql.RQLStatement; +import org.apache.shardingsphere.distsql.statement.type.rul.RULStatement; +import org.apache.shardingsphere.driver.jdbc.core.connection.ShardingSphereConnection; +import org.apache.shardingsphere.infra.session.query.QueryContext; +import org.apache.shardingsphere.mode.manager.ContextManager; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; + +/** + * Driver DistSQL executor. + */ +@RequiredArgsConstructor +public final class DriverDistSQLExecutor { + + private final ShardingSphereConnection connection; + + /** + * Execute DistSQL query. + * + * @param sqlStatement DistSQL statement + * @param queryContext query context + * @param statement statement + * @return result set + * @throws SQLException SQL exception + */ + public ResultSet executeQuery(final DistSQLStatement sqlStatement, final QueryContext queryContext, final Statement statement) throws SQLException { + ContextManager contextManager = connection.getContextManager(); + DistSQLConnectionContext distsqlConnectionContext = createDistSQLConnectionContext(queryContext); + DistSQLQueryExecuteEngine engine = new DistSQLQueryExecuteEngine(sqlStatement, connection.getCurrentDatabaseName(), contextManager, distsqlConnectionContext); + engine.executeQuery(); + return new DistSQLResultSet(engine.getColumnNames(), engine.getRows(), statement); + } + + /** + * Execute DistSQL update. + * + * @param sqlStatement DistSQL statement + * @param queryContext query context + * @return update count + * @throws SQLException SQL exception + */ + public int executeUpdate(final DistSQLStatement sqlStatement, final QueryContext queryContext) throws SQLException { + ContextManager contextManager = connection.getContextManager(); + DistSQLConnectionContext distsqlConnectionContext = createDistSQLConnectionContext(queryContext); + DistSQLUpdateExecuteEngine engine = new DistSQLUpdateExecuteEngine(sqlStatement, connection.getCurrentDatabaseName(), contextManager, distsqlConnectionContext); + engine.executeUpdate(); + return 0; + } + + /** + * Execute DistSQL. + * + * @param sqlStatement DistSQL statement + * @param queryContext query context + * @param statement statement + * @return execute result + * @throws SQLException SQL exception + */ + public ExecuteResult execute(final DistSQLStatement sqlStatement, final QueryContext queryContext, final Statement statement) throws SQLException { + if (isQueryStatement(sqlStatement)) { + ResultSet resultSet = executeQuery(sqlStatement, queryContext, statement); + return new ExecuteResult(true, resultSet, 0); + } + int updateCount = executeUpdate(sqlStatement, queryContext); + return new ExecuteResult(false, null, updateCount); + } + + private boolean isQueryStatement(final DistSQLStatement sqlStatement) { + return sqlStatement instanceof RQLStatement || sqlStatement instanceof RULStatement + || sqlStatement instanceof QueryableRALStatement; + } + + private DistSQLConnectionContext createDistSQLConnectionContext(final QueryContext queryContext) { + return new DistSQLConnectionContext(queryContext, 1, + connection.getContextManager().getMetaDataContexts().getMetaData().getDatabase(connection.getCurrentDatabaseName()).getProtocolType(), + connection.getDatabaseConnectionManager(), null); + } + + /** + * Execute result. + */ + @Getter + @RequiredArgsConstructor + public static final class ExecuteResult { + + private final boolean hasResultSet; + + private final ResultSet resultSet; + + private final int updateCount; + } +} Review Comment: The new DriverDistSQLExecutor class lacks unit tests. While there is an integration test in ShardingTest, unit tests should be added to verify the executor's behavior in isolation, including edge cases like handling different types of DistSQL statements and error conditions. ########## jdbc/src/main/java/org/apache/shardingsphere/driver/jdbc/core/statement/DistSQLStatementContext.java: ########## @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.shardingsphere.driver.jdbc.core.statement; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import org.apache.shardingsphere.distsql.statement.DistSQLStatement; +import org.apache.shardingsphere.infra.binder.context.segment.table.TablesContext; +import org.apache.shardingsphere.infra.binder.context.statement.SQLStatementContext; + +import java.util.Collections; + +/** + * SQL statement context for DistSQL. + */ +@RequiredArgsConstructor +@Getter +public final class DistSQLStatementContext implements SQLStatementContext { + + private final DistSQLStatement sqlStatement; + + @Override + public TablesContext getTablesContext() { + return new TablesContext(Collections.emptyList()); + } +} Review Comment: This class is an exact duplicate of org.apache.shardingsphere.proxy.backend.distsql.DistSQLStatementContext. While the PR description mentions this is intentional due to infrastructure constraints, this represents significant code duplication that could lead to maintenance issues. Consider creating a shared module for common infrastructure between JDBC and Proxy, or documenting why these must remain separate to help future maintainers understand the architectural decision. ########## jdbc/src/main/java/org/apache/shardingsphere/driver/executor/engine/distsql/DistSQLResultSet.java: ########## @@ -0,0 +1,265 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.shardingsphere.driver.executor.engine.distsql; + +import com.google.common.base.Preconditions; +import org.apache.shardingsphere.driver.jdbc.unsupported.AbstractUnsupportedGeneratedKeysResultSet; +import org.apache.shardingsphere.infra.merge.result.impl.local.LocalDataQueryResultRow; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.nio.charset.StandardCharsets; +import java.sql.ResultSetMetaData; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +/** + * DistSQL result set. + */ +public final class DistSQLResultSet extends AbstractUnsupportedGeneratedKeysResultSet { + + private final List<String> columnNames; + + private final Iterator<LocalDataQueryResultRow> rows; + + private final Statement statement; + + private LocalDataQueryResultRow currentRow; + + private boolean closed; + + public DistSQLResultSet(final Collection<String> columnNames, final Collection<LocalDataQueryResultRow> rows, final Statement statement) { + this.columnNames = new ArrayList<>(columnNames); + this.rows = rows.iterator(); + this.statement = statement; + } + + @Override + public boolean isClosed() { + return closed; + } + + @Override + public boolean next() { + if (closed || !rows.hasNext()) { + currentRow = null; + return false; + } + currentRow = rows.next(); + return true; + } + + @Override + public void close() { + closed = true; + } + + @Override + public ResultSetMetaData getMetaData() { + checkState(); + return new DistSQLResultSetMetaData(columnNames); + } + + @Override + public boolean wasNull() { + checkState(); + return false; + } + + @Override + public String getString(final int columnIndex) { + checkStateForGetData(); + Object value = currentRow.getCell(columnIndex); + return null == value ? null : value.toString(); + } + + @Override + public String getString(final String columnLabel) { + return getString(findColumn(columnLabel)); + } + + @Override + public String getNString(final int columnIndex) { + return getString(columnIndex); + } + + @Override + public String getNString(final String columnLabel) { + return getString(columnLabel); + } + + @Override + public byte getByte(final int columnIndex) { + checkStateForGetData(); + String value = getString(columnIndex); + return null == value ? 0 : Byte.parseByte(value); + } + + @Override + public byte getByte(final String columnLabel) { + return getByte(findColumn(columnLabel)); + } + + @Override + public short getShort(final int columnIndex) { + checkStateForGetData(); + String value = getString(columnIndex); + return null == value ? 0 : Short.parseShort(value); + } + + @Override + public short getShort(final String columnLabel) { + return getShort(findColumn(columnLabel)); + } + + @Override + public int getInt(final int columnIndex) { + checkStateForGetData(); + String value = getString(columnIndex); + return null == value ? 0 : Integer.parseInt(value); + } + + @Override + public int getInt(final String columnLabel) { + return getInt(findColumn(columnLabel)); + } + + @Override + public long getLong(final int columnIndex) { + checkStateForGetData(); + String value = getString(columnIndex); + return null == value ? 0L : Long.parseLong(value); Review Comment: Potential uncaught 'java.lang.NumberFormatException'. ```suggestion if (null == value) { return 0L; } try { return Long.parseLong(value); } catch (NumberFormatException ex) { return 0L; } ``` ########## jdbc/src/main/java/org/apache/shardingsphere/driver/executor/engine/distsql/DistSQLResultSet.java: ########## @@ -0,0 +1,265 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.shardingsphere.driver.executor.engine.distsql; + +import com.google.common.base.Preconditions; +import org.apache.shardingsphere.driver.jdbc.unsupported.AbstractUnsupportedGeneratedKeysResultSet; +import org.apache.shardingsphere.infra.merge.result.impl.local.LocalDataQueryResultRow; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.nio.charset.StandardCharsets; +import java.sql.ResultSetMetaData; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +/** + * DistSQL result set. + */ +public final class DistSQLResultSet extends AbstractUnsupportedGeneratedKeysResultSet { + + private final List<String> columnNames; + + private final Iterator<LocalDataQueryResultRow> rows; + + private final Statement statement; + + private LocalDataQueryResultRow currentRow; + + private boolean closed; + + public DistSQLResultSet(final Collection<String> columnNames, final Collection<LocalDataQueryResultRow> rows, final Statement statement) { + this.columnNames = new ArrayList<>(columnNames); + this.rows = rows.iterator(); + this.statement = statement; + } + + @Override + public boolean isClosed() { + return closed; + } + + @Override + public boolean next() { + if (closed || !rows.hasNext()) { + currentRow = null; + return false; + } + currentRow = rows.next(); + return true; + } + + @Override + public void close() { + closed = true; + } + + @Override + public ResultSetMetaData getMetaData() { + checkState(); + return new DistSQLResultSetMetaData(columnNames); + } + + @Override + public boolean wasNull() { + checkState(); + return false; + } + + @Override + public String getString(final int columnIndex) { + checkStateForGetData(); + Object value = currentRow.getCell(columnIndex); + return null == value ? null : value.toString(); + } + + @Override + public String getString(final String columnLabel) { + return getString(findColumn(columnLabel)); + } + + @Override + public String getNString(final int columnIndex) { + return getString(columnIndex); + } + + @Override + public String getNString(final String columnLabel) { + return getString(columnLabel); + } + + @Override + public byte getByte(final int columnIndex) { + checkStateForGetData(); + String value = getString(columnIndex); + return null == value ? 0 : Byte.parseByte(value); Review Comment: Potential uncaught 'java.lang.NumberFormatException'. ########## jdbc/src/main/java/org/apache/shardingsphere/driver/executor/engine/distsql/DistSQLResultSet.java: ########## @@ -0,0 +1,265 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.shardingsphere.driver.executor.engine.distsql; + +import com.google.common.base.Preconditions; +import org.apache.shardingsphere.driver.jdbc.unsupported.AbstractUnsupportedGeneratedKeysResultSet; +import org.apache.shardingsphere.infra.merge.result.impl.local.LocalDataQueryResultRow; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.nio.charset.StandardCharsets; +import java.sql.ResultSetMetaData; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +/** + * DistSQL result set. + */ +public final class DistSQLResultSet extends AbstractUnsupportedGeneratedKeysResultSet { + + private final List<String> columnNames; + + private final Iterator<LocalDataQueryResultRow> rows; + + private final Statement statement; + + private LocalDataQueryResultRow currentRow; + + private boolean closed; + + public DistSQLResultSet(final Collection<String> columnNames, final Collection<LocalDataQueryResultRow> rows, final Statement statement) { + this.columnNames = new ArrayList<>(columnNames); + this.rows = rows.iterator(); + this.statement = statement; + } + + @Override + public boolean isClosed() { + return closed; + } + + @Override + public boolean next() { + if (closed || !rows.hasNext()) { + currentRow = null; + return false; + } + currentRow = rows.next(); + return true; + } + + @Override + public void close() { + closed = true; + } + + @Override + public ResultSetMetaData getMetaData() { + checkState(); + return new DistSQLResultSetMetaData(columnNames); + } + + @Override + public boolean wasNull() { + checkState(); + return false; + } + + @Override + public String getString(final int columnIndex) { + checkStateForGetData(); + Object value = currentRow.getCell(columnIndex); + return null == value ? null : value.toString(); + } + + @Override + public String getString(final String columnLabel) { + return getString(findColumn(columnLabel)); + } + + @Override + public String getNString(final int columnIndex) { + return getString(columnIndex); + } + + @Override + public String getNString(final String columnLabel) { + return getString(columnLabel); + } + + @Override + public byte getByte(final int columnIndex) { + checkStateForGetData(); + String value = getString(columnIndex); + return null == value ? 0 : Byte.parseByte(value); + } + + @Override + public byte getByte(final String columnLabel) { + return getByte(findColumn(columnLabel)); + } + + @Override + public short getShort(final int columnIndex) { + checkStateForGetData(); + String value = getString(columnIndex); + return null == value ? 0 : Short.parseShort(value); Review Comment: Potential uncaught 'java.lang.NumberFormatException'. ########## jdbc/src/main/java/org/apache/shardingsphere/driver/executor/engine/distsql/DistSQLResultSet.java: ########## @@ -0,0 +1,265 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.shardingsphere.driver.executor.engine.distsql; + +import com.google.common.base.Preconditions; +import org.apache.shardingsphere.driver.jdbc.unsupported.AbstractUnsupportedGeneratedKeysResultSet; +import org.apache.shardingsphere.infra.merge.result.impl.local.LocalDataQueryResultRow; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.nio.charset.StandardCharsets; +import java.sql.ResultSetMetaData; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +/** + * DistSQL result set. + */ +public final class DistSQLResultSet extends AbstractUnsupportedGeneratedKeysResultSet { + + private final List<String> columnNames; + + private final Iterator<LocalDataQueryResultRow> rows; + + private final Statement statement; + + private LocalDataQueryResultRow currentRow; + + private boolean closed; + + public DistSQLResultSet(final Collection<String> columnNames, final Collection<LocalDataQueryResultRow> rows, final Statement statement) { + this.columnNames = new ArrayList<>(columnNames); + this.rows = rows.iterator(); + this.statement = statement; + } + + @Override + public boolean isClosed() { + return closed; + } + + @Override + public boolean next() { + if (closed || !rows.hasNext()) { + currentRow = null; + return false; + } + currentRow = rows.next(); + return true; + } + + @Override + public void close() { + closed = true; + } + + @Override + public ResultSetMetaData getMetaData() { + checkState(); + return new DistSQLResultSetMetaData(columnNames); + } + + @Override + public boolean wasNull() { + checkState(); + return false; Review Comment: The wasNull method always returns false, which may not correctly reflect whether the last column read was SQL NULL. According to JDBC specifications, wasNull should return true if the last column value read was SQL NULL. Consider tracking the last read value to properly implement this method. ########## docs/document/content/user-manual/shardingsphere-jdbc/distsql/_index.en.md: ########## @@ -0,0 +1,121 @@ ++++ +title = "DistSQL" +weight = 6 +chapter = true ++++ + +# Background Information + +Currently, DistSQL can be executed via ShardingSphere JDBC DataSource to dynamically modify ShardingSphere configuration. + +# Configuration Example + +## Prerequisites + +Include the following dependencies in your business project: + +```xml +<dependency> + <groupId>org.apache.shardingsphere</groupId> + <artifactId>shardingsphere-jdbc</artifactId> + <version>${shardingsphere.version}</version> +</dependency> +<dependency> + <groupId>org.apache.shardingsphere</groupId> + <artifactId>shardingsphere-jdbc-dialect-mysql</artifactId> + <version>${shardingsphere.version}</version> +</dependency> +<dependency> + <groupId>org.apache.shardingsphere</groupId> + <artifactId>shardingsphere-infra-data-source-pool-hikari</artifactId> + <version>${shardingsphere.version}</version> +</dependency> +<dependency> + <groupId>org.apache.shardingsphere</groupId> + <artifactId>shardingsphere-infra-url-classpath</artifactId> + <version>${shardingsphere.version}</version> +</dependency> +<dependency> + <groupId>org.apache.shardingsphere</groupId> + <artifactId>shardingsphere-standalone-mode-repository-memory</artifactId> + <version>${shardingsphere.version}</version> +</dependency> +<dependency> + <groupId>org.apache.shardingsphere</groupId> + <artifactId>shardingsphere-sharding-core</artifactId> + <version>${shardingsphere.version}</version> +</dependency> +<dependency> + <groupId>org.apache.shardingsphere</groupId> + <artifactId>shardingsphere-authority-simple</artifactId> + <version>${shardingsphere.version}</version> +</dependency> +<dependency> + <groupId>com.h2database</groupId> + <artifactId>h2</artifactId> + <version>2.2.224</version> +</dependency> +``` + +Write the ShardingSphere data source configuration file `demo.yaml` on the classpath of your business project. + +```yaml +props: + sql-show: false +``` + +## 享受集成 Review Comment: The section header contains Chinese text "享受集成" instead of English text. This should be translated to English, such as "Integration" or "Enjoy the Integration". ```suggestion ## Enjoy the Integration ``` ########## jdbc/src/main/java/org/apache/shardingsphere/driver/executor/engine/distsql/DistSQLResultSet.java: ########## @@ -0,0 +1,265 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.shardingsphere.driver.executor.engine.distsql; + +import com.google.common.base.Preconditions; +import org.apache.shardingsphere.driver.jdbc.unsupported.AbstractUnsupportedGeneratedKeysResultSet; +import org.apache.shardingsphere.infra.merge.result.impl.local.LocalDataQueryResultRow; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.nio.charset.StandardCharsets; +import java.sql.ResultSetMetaData; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +/** + * DistSQL result set. + */ +public final class DistSQLResultSet extends AbstractUnsupportedGeneratedKeysResultSet { + + private final List<String> columnNames; + + private final Iterator<LocalDataQueryResultRow> rows; + + private final Statement statement; + + private LocalDataQueryResultRow currentRow; + + private boolean closed; + + public DistSQLResultSet(final Collection<String> columnNames, final Collection<LocalDataQueryResultRow> rows, final Statement statement) { + this.columnNames = new ArrayList<>(columnNames); + this.rows = rows.iterator(); + this.statement = statement; + } + + @Override + public boolean isClosed() { + return closed; + } + + @Override + public boolean next() { + if (closed || !rows.hasNext()) { + currentRow = null; + return false; + } + currentRow = rows.next(); + return true; + } + + @Override + public void close() { + closed = true; + } + + @Override + public ResultSetMetaData getMetaData() { + checkState(); + return new DistSQLResultSetMetaData(columnNames); + } + + @Override + public boolean wasNull() { + checkState(); + return false; + } + + @Override + public String getString(final int columnIndex) { + checkStateForGetData(); + Object value = currentRow.getCell(columnIndex); + return null == value ? null : value.toString(); + } + + @Override + public String getString(final String columnLabel) { + return getString(findColumn(columnLabel)); + } + + @Override + public String getNString(final int columnIndex) { + return getString(columnIndex); + } + + @Override + public String getNString(final String columnLabel) { + return getString(columnLabel); + } + + @Override + public byte getByte(final int columnIndex) { + checkStateForGetData(); + String value = getString(columnIndex); + return null == value ? 0 : Byte.parseByte(value); + } + + @Override + public byte getByte(final String columnLabel) { + return getByte(findColumn(columnLabel)); + } + + @Override + public short getShort(final int columnIndex) { + checkStateForGetData(); + String value = getString(columnIndex); + return null == value ? 0 : Short.parseShort(value); + } + + @Override + public short getShort(final String columnLabel) { + return getShort(findColumn(columnLabel)); + } + + @Override + public int getInt(final int columnIndex) { + checkStateForGetData(); + String value = getString(columnIndex); + return null == value ? 0 : Integer.parseInt(value); Review Comment: Potential uncaught 'java.lang.NumberFormatException'. ########## jdbc/src/main/java/org/apache/shardingsphere/driver/executor/engine/distsql/DistSQLResultSetMetaData.java: ########## @@ -0,0 +1,166 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.shardingsphere.driver.executor.engine.distsql; + +import com.google.common.base.Preconditions; +import org.apache.shardingsphere.driver.jdbc.adapter.WrapperAdapter; + +import java.sql.ResultSetMetaData; +import java.sql.Types; +import java.util.List; + +/** + * Result set meta data for DistSQL. + */ +public final class DistSQLResultSetMetaData extends WrapperAdapter implements ResultSetMetaData { + + private final List<String> columnNames; + + public DistSQLResultSetMetaData(final List<String> columnNames) { + this.columnNames = columnNames; + } + + @Override + public int getColumnCount() { + return columnNames.size(); + } + + @Override + public boolean isAutoIncrement(final int column) { + checkColumnIndex(column); + return false; + } + + @Override + public boolean isCaseSensitive(final int column) { + checkColumnIndex(column); + return true; + } + + @Override + public boolean isSearchable(final int column) { + checkColumnIndex(column); + return false; + } + + @Override + public boolean isCurrency(final int column) { + checkColumnIndex(column); + return false; + } + + @Override + public int isNullable(final int column) { + checkColumnIndex(column); + return columnNullable; + } + + @Override + public boolean isSigned(final int column) { + checkColumnIndex(column); + return false; + } + + @Override + public int getColumnDisplaySize(final int column) { + checkColumnIndex(column); + return 255; + } + + @Override + public String getColumnLabel(final int column) { + checkColumnIndex(column); + return columnNames.get(column - 1); + } + + @Override + public String getColumnName(final int column) { + checkColumnIndex(column); + return columnNames.get(column - 1); + } + + @Override + public String getSchemaName(final int column) { + checkColumnIndex(column); + return ""; + } + + @Override + public int getPrecision(final int column) { + checkColumnIndex(column); + return 0; + } + + @Override + public int getScale(final int column) { + checkColumnIndex(column); + return 0; + } + + @Override + public String getTableName(final int column) { + checkColumnIndex(column); + return ""; + } + + @Override + public String getCatalogName(final int column) { + checkColumnIndex(column); + return ""; + } + + @Override + public int getColumnType(final int column) { + checkColumnIndex(column); + return Types.CHAR; + } + + @Override + public String getColumnTypeName(final int column) { + checkColumnIndex(column); + return "CHAR"; + } + + @Override + public boolean isReadOnly(final int column) { + checkColumnIndex(column); + return true; + } + + @Override + public boolean isWritable(final int column) { + checkColumnIndex(column); + return false; + } + + @Override + public boolean isDefinitelyWritable(final int column) { + checkColumnIndex(column); + return false; + } + + @Override + public String getColumnClassName(final int column) { + checkColumnIndex(column); + return String.class.getName(); + } + + private void checkColumnIndex(final int column) { + Preconditions.checkArgument(column >= 1 && column <= columnNames.size(), "Column index %s is out of range [1, %s]", column, columnNames.size()); + } +} Review Comment: The new DistSQLResultSetMetaData class lacks unit tests. Consider adding unit tests to verify the metadata's behavior, including column count, column names, types, and all the metadata accessor methods. ########## jdbc/src/main/java/org/apache/shardingsphere/driver/executor/engine/distsql/DistSQLResultSet.java: ########## @@ -0,0 +1,265 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.shardingsphere.driver.executor.engine.distsql; + +import com.google.common.base.Preconditions; +import org.apache.shardingsphere.driver.jdbc.unsupported.AbstractUnsupportedGeneratedKeysResultSet; +import org.apache.shardingsphere.infra.merge.result.impl.local.LocalDataQueryResultRow; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.nio.charset.StandardCharsets; +import java.sql.ResultSetMetaData; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +/** + * DistSQL result set. + */ +public final class DistSQLResultSet extends AbstractUnsupportedGeneratedKeysResultSet { + + private final List<String> columnNames; + + private final Iterator<LocalDataQueryResultRow> rows; + + private final Statement statement; + + private LocalDataQueryResultRow currentRow; + + private boolean closed; + + public DistSQLResultSet(final Collection<String> columnNames, final Collection<LocalDataQueryResultRow> rows, final Statement statement) { + this.columnNames = new ArrayList<>(columnNames); + this.rows = rows.iterator(); + this.statement = statement; + } + + @Override + public boolean isClosed() { + return closed; + } + + @Override + public boolean next() { + if (closed || !rows.hasNext()) { + currentRow = null; + return false; + } + currentRow = rows.next(); + return true; + } + + @Override + public void close() { + closed = true; + } + + @Override + public ResultSetMetaData getMetaData() { + checkState(); + return new DistSQLResultSetMetaData(columnNames); + } + + @Override + public boolean wasNull() { + checkState(); + return false; + } + + @Override + public String getString(final int columnIndex) { + checkStateForGetData(); + Object value = currentRow.getCell(columnIndex); + return null == value ? null : value.toString(); + } + + @Override + public String getString(final String columnLabel) { + return getString(findColumn(columnLabel)); + } + + @Override + public String getNString(final int columnIndex) { + return getString(columnIndex); + } + + @Override + public String getNString(final String columnLabel) { + return getString(columnLabel); + } + + @Override + public byte getByte(final int columnIndex) { + checkStateForGetData(); + String value = getString(columnIndex); + return null == value ? 0 : Byte.parseByte(value); + } + + @Override + public byte getByte(final String columnLabel) { + return getByte(findColumn(columnLabel)); + } + + @Override + public short getShort(final int columnIndex) { + checkStateForGetData(); + String value = getString(columnIndex); + return null == value ? 0 : Short.parseShort(value); + } + + @Override + public short getShort(final String columnLabel) { + return getShort(findColumn(columnLabel)); + } + + @Override + public int getInt(final int columnIndex) { + checkStateForGetData(); + String value = getString(columnIndex); + return null == value ? 0 : Integer.parseInt(value); + } + + @Override + public int getInt(final String columnLabel) { + return getInt(findColumn(columnLabel)); + } + + @Override + public long getLong(final int columnIndex) { + checkStateForGetData(); + String value = getString(columnIndex); + return null == value ? 0L : Long.parseLong(value); + } + + @Override + public long getLong(final String columnLabel) { + return getLong(findColumn(columnLabel)); + } + + @Override + public float getFloat(final int columnIndex) { + checkStateForGetData(); + String value = getString(columnIndex); + return null == value ? 0F : Float.parseFloat(value); + } + + @Override + public float getFloat(final String columnLabel) { + return getFloat(findColumn(columnLabel)); + } + + @Override + public double getDouble(final int columnIndex) { + checkStateForGetData(); + String value = getString(columnIndex); + return null == value ? 0D : Double.parseDouble(value); + } + + @Override + public double getDouble(final String columnLabel) { + return getDouble(findColumn(columnLabel)); + } + + @Override + public BigDecimal getBigDecimal(final int columnIndex, final int scale) { + checkStateForGetData(); + String value = getString(columnIndex); + return null == value ? null : new BigDecimal(value).setScale(scale, RoundingMode.HALF_UP); + } + + @Override + public BigDecimal getBigDecimal(final String columnLabel, final int scale) { + return getBigDecimal(findColumn(columnLabel), scale); + } + + @Override + public BigDecimal getBigDecimal(final int columnIndex) { + checkStateForGetData(); + String value = getString(columnIndex); + return null == value ? null : new BigDecimal(value); + } + + @Override + public BigDecimal getBigDecimal(final String columnLabel) { + return getBigDecimal(findColumn(columnLabel)); + } + + @Override + public byte[] getBytes(final int columnIndex) { + checkStateForGetData(); + String value = getString(columnIndex); + return null == value ? null : value.getBytes(StandardCharsets.UTF_8); + } + + @Override + public byte[] getBytes(final String columnLabel) { + return getBytes(findColumn(columnLabel)); + } + + @Override + public Object getObject(final int columnIndex) { + checkStateForGetData(); + return currentRow.getCell(columnIndex); + } + + @Override + public Object getObject(final String columnLabel) { + return getObject(findColumn(columnLabel)); + } + + @Override + public int findColumn(final String columnLabel) { + checkState(); + for (int i = 0; i < columnNames.size(); i++) { + if (columnNames.get(i).equalsIgnoreCase(columnLabel)) { + return i + 1; + } + } + throw new IllegalArgumentException("Column '" + columnLabel + "' not found"); + } + + @Override + public int getType() { + checkState(); + return TYPE_FORWARD_ONLY; + } + + @Override + public int getConcurrency() { + checkState(); + return CONCUR_READ_ONLY; + } + + @Override + public Statement getStatement() { + checkState(); + return statement; + } + + private void checkStateForGetData() { + checkState(); + Preconditions.checkNotNull(currentRow, "ResultSet should call next or has no more data."); + } + + private void checkState() { + Preconditions.checkState(!closed, "ResultSet has closed."); + } +} Review Comment: The new DistSQLResultSet class lacks unit tests. Consider adding unit tests to verify the ResultSet's behavior, including data retrieval methods, metadata access, navigation methods, and boundary conditions. ########## test/native/src/test/resources/test-native/ps1/config-rdctl.ps1: ########## @@ -19,6 +19,7 @@ # This file is only used in the PowerShell 7 of ShardingSphere in GitHub Actions environment and should not be executed manually in a development environment. # Background information can be found at https://github.com/apache/shardingsphere/pull/35905 . +[Environment]::SetEnvironmentVariable('DOCKER_API_VERSION','1.44','Machine') Review Comment: This change sets the DOCKER_API_VERSION environment variable, which appears unrelated to the PR's main purpose of adding DistSQL support for JDBC. This change should be explained in the PR description or moved to a separate PR focused on Docker/test infrastructure changes. ```suggestion # Ensure Docker tooling uses a compatible API version within this CI job only. [Environment]::SetEnvironmentVariable('DOCKER_API_VERSION','1.44','Process') ``` ########## jdbc/src/main/java/org/apache/shardingsphere/driver/jdbc/core/statement/DistSQLStatementContext.java: ########## @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.shardingsphere.driver.jdbc.core.statement; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import org.apache.shardingsphere.distsql.statement.DistSQLStatement; +import org.apache.shardingsphere.infra.binder.context.segment.table.TablesContext; +import org.apache.shardingsphere.infra.binder.context.statement.SQLStatementContext; + +import java.util.Collections; + +/** + * SQL statement context for DistSQL. + */ +@RequiredArgsConstructor +@Getter +public final class DistSQLStatementContext implements SQLStatementContext { + + private final DistSQLStatement sqlStatement; + + @Override + public TablesContext getTablesContext() { + return new TablesContext(Collections.emptyList()); + } +} Review Comment: The new DistSQLStatementContext class lacks unit tests. While a similar test exists for the Proxy version (DistSQLStatementContextTest), consider adding equivalent tests for the JDBC version to ensure consistency and proper behavior. ########## jdbc/src/main/java/org/apache/shardingsphere/driver/executor/engine/distsql/DistSQLResultSet.java: ########## @@ -0,0 +1,265 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.shardingsphere.driver.executor.engine.distsql; + +import com.google.common.base.Preconditions; +import org.apache.shardingsphere.driver.jdbc.unsupported.AbstractUnsupportedGeneratedKeysResultSet; +import org.apache.shardingsphere.infra.merge.result.impl.local.LocalDataQueryResultRow; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.nio.charset.StandardCharsets; +import java.sql.ResultSetMetaData; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +/** + * DistSQL result set. + */ +public final class DistSQLResultSet extends AbstractUnsupportedGeneratedKeysResultSet { + + private final List<String> columnNames; + + private final Iterator<LocalDataQueryResultRow> rows; + + private final Statement statement; + + private LocalDataQueryResultRow currentRow; + + private boolean closed; + + public DistSQLResultSet(final Collection<String> columnNames, final Collection<LocalDataQueryResultRow> rows, final Statement statement) { + this.columnNames = new ArrayList<>(columnNames); + this.rows = rows.iterator(); + this.statement = statement; + } + + @Override + public boolean isClosed() { + return closed; + } + + @Override + public boolean next() { + if (closed || !rows.hasNext()) { + currentRow = null; + return false; + } + currentRow = rows.next(); + return true; + } + + @Override + public void close() { + closed = true; + } + + @Override + public ResultSetMetaData getMetaData() { + checkState(); + return new DistSQLResultSetMetaData(columnNames); + } + + @Override + public boolean wasNull() { + checkState(); + return false; + } + + @Override + public String getString(final int columnIndex) { + checkStateForGetData(); + Object value = currentRow.getCell(columnIndex); + return null == value ? null : value.toString(); + } + + @Override + public String getString(final String columnLabel) { + return getString(findColumn(columnLabel)); + } + + @Override + public String getNString(final int columnIndex) { + return getString(columnIndex); + } + + @Override + public String getNString(final String columnLabel) { + return getString(columnLabel); + } + + @Override + public byte getByte(final int columnIndex) { + checkStateForGetData(); + String value = getString(columnIndex); + return null == value ? 0 : Byte.parseByte(value); + } + + @Override + public byte getByte(final String columnLabel) { + return getByte(findColumn(columnLabel)); + } + + @Override + public short getShort(final int columnIndex) { + checkStateForGetData(); + String value = getString(columnIndex); + return null == value ? 0 : Short.parseShort(value); + } + + @Override + public short getShort(final String columnLabel) { + return getShort(findColumn(columnLabel)); + } + + @Override + public int getInt(final int columnIndex) { + checkStateForGetData(); + String value = getString(columnIndex); + return null == value ? 0 : Integer.parseInt(value); + } + + @Override + public int getInt(final String columnLabel) { + return getInt(findColumn(columnLabel)); + } + + @Override + public long getLong(final int columnIndex) { + checkStateForGetData(); + String value = getString(columnIndex); + return null == value ? 0L : Long.parseLong(value); + } + + @Override + public long getLong(final String columnLabel) { + return getLong(findColumn(columnLabel)); + } + + @Override + public float getFloat(final int columnIndex) { + checkStateForGetData(); + String value = getString(columnIndex); + return null == value ? 0F : Float.parseFloat(value); Review Comment: Potential uncaught 'java.lang.NumberFormatException'. ########## jdbc/src/main/java/org/apache/shardingsphere/driver/executor/engine/distsql/DistSQLResultSet.java: ########## @@ -0,0 +1,265 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.shardingsphere.driver.executor.engine.distsql; + +import com.google.common.base.Preconditions; +import org.apache.shardingsphere.driver.jdbc.unsupported.AbstractUnsupportedGeneratedKeysResultSet; +import org.apache.shardingsphere.infra.merge.result.impl.local.LocalDataQueryResultRow; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.nio.charset.StandardCharsets; +import java.sql.ResultSetMetaData; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +/** + * DistSQL result set. + */ +public final class DistSQLResultSet extends AbstractUnsupportedGeneratedKeysResultSet { + + private final List<String> columnNames; + + private final Iterator<LocalDataQueryResultRow> rows; + + private final Statement statement; + + private LocalDataQueryResultRow currentRow; + + private boolean closed; + + public DistSQLResultSet(final Collection<String> columnNames, final Collection<LocalDataQueryResultRow> rows, final Statement statement) { + this.columnNames = new ArrayList<>(columnNames); + this.rows = rows.iterator(); + this.statement = statement; + } + + @Override + public boolean isClosed() { + return closed; + } + + @Override + public boolean next() { + if (closed || !rows.hasNext()) { + currentRow = null; + return false; + } + currentRow = rows.next(); + return true; + } + + @Override + public void close() { + closed = true; + } + + @Override + public ResultSetMetaData getMetaData() { + checkState(); + return new DistSQLResultSetMetaData(columnNames); + } + + @Override + public boolean wasNull() { + checkState(); + return false; + } + + @Override + public String getString(final int columnIndex) { + checkStateForGetData(); + Object value = currentRow.getCell(columnIndex); + return null == value ? null : value.toString(); + } + + @Override + public String getString(final String columnLabel) { + return getString(findColumn(columnLabel)); + } + + @Override + public String getNString(final int columnIndex) { + return getString(columnIndex); + } + + @Override + public String getNString(final String columnLabel) { + return getString(columnLabel); + } + + @Override + public byte getByte(final int columnIndex) { + checkStateForGetData(); + String value = getString(columnIndex); + return null == value ? 0 : Byte.parseByte(value); + } + + @Override + public byte getByte(final String columnLabel) { + return getByte(findColumn(columnLabel)); + } + + @Override + public short getShort(final int columnIndex) { + checkStateForGetData(); + String value = getString(columnIndex); + return null == value ? 0 : Short.parseShort(value); + } + + @Override + public short getShort(final String columnLabel) { + return getShort(findColumn(columnLabel)); + } + + @Override + public int getInt(final int columnIndex) { + checkStateForGetData(); + String value = getString(columnIndex); + return null == value ? 0 : Integer.parseInt(value); + } + + @Override + public int getInt(final String columnLabel) { + return getInt(findColumn(columnLabel)); + } + + @Override + public long getLong(final int columnIndex) { + checkStateForGetData(); + String value = getString(columnIndex); + return null == value ? 0L : Long.parseLong(value); + } + + @Override + public long getLong(final String columnLabel) { + return getLong(findColumn(columnLabel)); + } + + @Override + public float getFloat(final int columnIndex) { + checkStateForGetData(); + String value = getString(columnIndex); + return null == value ? 0F : Float.parseFloat(value); + } + + @Override + public float getFloat(final String columnLabel) { + return getFloat(findColumn(columnLabel)); + } + + @Override + public double getDouble(final int columnIndex) { + checkStateForGetData(); + String value = getString(columnIndex); + return null == value ? 0D : Double.parseDouble(value); Review Comment: Potential uncaught 'java.lang.NumberFormatException'. ########## jdbc/src/main/java/org/apache/shardingsphere/driver/jdbc/core/statement/DistSQLStatementContext.java: ########## @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.shardingsphere.driver.jdbc.core.statement; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import org.apache.shardingsphere.distsql.statement.DistSQLStatement; +import org.apache.shardingsphere.infra.binder.context.segment.table.TablesContext; +import org.apache.shardingsphere.infra.binder.context.statement.SQLStatementContext; + +import java.util.Collections; + +/** + * SQL statement context for DistSQL. + */ +@RequiredArgsConstructor +@Getter +public final class DistSQLStatementContext implements SQLStatementContext { + + private final DistSQLStatement sqlStatement; + + @Override Review Comment: This method overrides [SQLStatementContext.getSqlStatement](1); it is advisable to add an Override annotation. ```suggestion public final class DistSQLStatementContext implements SQLStatementContext { private final DistSQLStatement sqlStatement; @Override public DistSQLStatement getSqlStatement() { return sqlStatement; } @Override ``` -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
