You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@ignite.apache.org by "xtern (via GitHub)" <gi...@apache.org> on 2025/11/13 12:00:50 UTC
[PR] IGNITE-26314 Jdbc. Use new ResultSet implementation in JdbcDatabaseMetadata. [ignite-3]
xtern opened a new pull request, #6965:
URL: https://github.com/apache/ignite-3/pull/6965
https://issues.apache.org/jira/browse/IGNITE-26314
--
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: notifications-unsubscribe@ignite.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] IGNITE-26314 Jdbc. Migrate JdbcDatabaseMetadata to use the new ResultSet implementation [ignite-3]
Posted by "xtern (via GitHub)" <gi...@apache.org>.
xtern merged PR #6965:
URL: https://github.com/apache/ignite-3/pull/6965
--
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: notifications-unsubscribe@ignite.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] IGNITE-26314 Jdbc. Migrate JdbcDatabaseMetadata to use the new ResultSet implementation [ignite-3]
Posted by "Copilot (via GitHub)" <gi...@apache.org>.
Copilot commented on code in PR #6965:
URL: https://github.com/apache/ignite-3/pull/6965#discussion_r2523453377
##########
modules/jdbc/src/main/java/org/apache/ignite/internal/jdbc/JdbcDatabaseMetadata.java:
##########
@@ -1354,23 +1362,23 @@ public ResultSet getIndexInfo(String catalog, String schema, String tbl, boolean
boolean approximate) throws SQLException {
ensureNotClosed();
- final List<JdbcColumnMeta> meta = asList(
- new JdbcColumnMeta("TABLE_CAT", ColumnType.STRING),
- new JdbcColumnMeta("TABLE_SCHEM", ColumnType.STRING),
- new JdbcColumnMeta("TABLE_NAME", ColumnType.STRING),
- new JdbcColumnMeta("NON_UNIQUE", ColumnType.BOOLEAN),
- new JdbcColumnMeta("INDEX_QUALIFIER", ColumnType.STRING),
- new JdbcColumnMeta("INDEX_NAME", ColumnType.STRING),
- new JdbcColumnMeta("TYPE", ColumnType.INT16),
- new JdbcColumnMeta("ORDINAL_POSITION", ColumnType.INT16),
- new JdbcColumnMeta("COLUMN_NAME", ColumnType.STRING),
- new JdbcColumnMeta("ASC_OR_DESC", ColumnType.STRING),
- new JdbcColumnMeta("CARDINALITY", ColumnType.INT32),
- new JdbcColumnMeta("PAGES", ColumnType.INT32),
- new JdbcColumnMeta("FILTER_CONDITION", ColumnType.STRING));
+ List<ColumnMetadata> meta = asList(
+ columnMeta("TABLE_CAT", ColumnType.STRING),
+ columnMeta("TABLE_SCHEM", ColumnType.STRING),
+ columnMeta("TABLE_NAME", ColumnType.STRING),
+ columnMeta("NON_UNIQUE", ColumnType.BOOLEAN),
+ columnMeta("INDEX_QUALIFIER", ColumnType.STRING),
+ columnMeta("INDEX_NAME", ColumnType.STRING),
+ columnMeta("TYPE", ColumnType.INT16),
+ columnMeta("ORDINAL_POSITION", ColumnType.INT16),
+ columnMeta("COLUMN_NAME", ColumnType.STRING),
+ columnMeta("ASC_OR_DESC", ColumnType.STRING),
+ columnMeta("CARDINALITY", ColumnType.INT32),
+ columnMeta("PAGES", ColumnType.INT32),
+ columnMeta("FILTER_CONDITION", ColumnType.STRING));
if (!isValidCatalog(catalog)) {
- return new JdbcResultSet(Collections.emptyList(), meta);
+ return createObjectListResultSet(Collections.emptyList(), meta);
Review Comment:
[nitpick] The `createObjectListResultSet` method is called with `Collections.emptyList()` when the metadata is already known to be empty. This is inconsistent with other usages where an empty metadata list is created using the single-argument overload (e.g., lines 906, 950, 1035, 1144). For consistency, consider using `createObjectListResultSet(meta)` instead of `createObjectListResultSet(Collections.emptyList(), meta)`.
```suggestion
return createObjectListResultSet(meta);
```
##########
modules/jdbc/src/main/java/org/apache/ignite/internal/jdbc/JdbcDatabaseMetataUtils.java:
##########
@@ -0,0 +1,343 @@
+/*
+ * 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.ignite.internal.jdbc;
+
+import java.math.BigDecimal;
+import java.sql.ResultSet;
+import java.time.Instant;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.ZoneId;
+import java.util.EnumSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.UUID;
+import org.apache.ignite.internal.jdbc2.ClientSyncResultSet;
+import org.apache.ignite.internal.jdbc2.JdbcResultSet;
+import org.apache.ignite.internal.sql.ResultSetMetadataImpl;
+import org.apache.ignite.internal.util.IgniteUtils;
+import org.apache.ignite.internal.util.TransformingIterator;
+import org.apache.ignite.sql.ColumnMetadata;
+import org.apache.ignite.sql.ColumnType;
+import org.apache.ignite.sql.NoRowSetExpectedException;
+import org.apache.ignite.sql.ResultSetMetadata;
+import org.apache.ignite.sql.SqlRow;
+import org.apache.ignite.table.Tuple;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Helper methods for creating a {@link ResultSet} using a list of objects.
+ */
+class JdbcDatabaseMetataUtils {
Review Comment:
The class name has a typo: "Metata" should be "Metadata". This affects the class name `JdbcDatabaseMetataUtils` which should be `JdbcDatabaseMetadataUtils`.
```suggestion
class JdbcDatabaseMetadataUtils {
```
##########
modules/jdbc/src/main/java/org/apache/ignite/internal/jdbc2/JdbcStatement2.java:
##########
@@ -510,12 +510,24 @@ public int getFetchDirection() throws SQLException {
return FETCH_FORWARD;
}
- /** {@inheritDoc} */
+ /**
+ * Gives the JDBC driver a hint as to the number of rows that should
+ * be fetched from the database.
+ *
+ * <p>Note: the current implementation does not provide any means to change the number
+ * of rows after the statement has executed. Thus, changing this value after the statement
+ * has executed will not apply to the previously retrieved ResultSet.
+ *
+ * @param fetchSize the number of rows to fetch
+ * @exception SQLException if the condition {@code rows >= 0} is not satisfied.
Review Comment:
The javadoc has an issue: the `@exception` tag should use `fetchSize < 0` instead of `rows >= 0` to match the actual validation in the code. The current documentation states the condition as `rows >= 0` which is confusing since the parameter is named `fetchSize`, and the validation checks if `fetchSize < 0`.
```suggestion
* @exception SQLException if {@code fetchSize < 0}.
```
##########
modules/jdbc/src/main/java/org/apache/ignite/internal/jdbc/JdbcDatabaseMetadata.java:
##########
@@ -24,6 +24,7 @@
import static java.sql.RowIdLifetime.ROWID_UNSUPPORTED;
import static java.util.Arrays.asList;
import static java.util.Collections.singletonList;
+import static org.apache.ignite.internal.jdbc.JdbcDatabaseMetataUtils.createObjectListResultSet;
Review Comment:
The import statement contains a typo in the class name: "JdbcDatabaseMetataUtils" should be "JdbcDatabaseMetadataUtils".
```suggestion
import static org.apache.ignite.internal.jdbc.JdbcDatabaseMetadataUtils.createObjectListResultSet;
```
##########
modules/jdbc/src/main/java/org/apache/ignite/internal/jdbc/JdbcDatabaseMetataUtils.java:
##########
@@ -0,0 +1,343 @@
+/*
+ * 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.ignite.internal.jdbc;
+
+import java.math.BigDecimal;
+import java.sql.ResultSet;
+import java.time.Instant;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.ZoneId;
+import java.util.EnumSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.UUID;
+import org.apache.ignite.internal.jdbc2.ClientSyncResultSet;
+import org.apache.ignite.internal.jdbc2.JdbcResultSet;
+import org.apache.ignite.internal.sql.ResultSetMetadataImpl;
+import org.apache.ignite.internal.util.IgniteUtils;
+import org.apache.ignite.internal.util.TransformingIterator;
+import org.apache.ignite.sql.ColumnMetadata;
+import org.apache.ignite.sql.ColumnType;
+import org.apache.ignite.sql.NoRowSetExpectedException;
+import org.apache.ignite.sql.ResultSetMetadata;
+import org.apache.ignite.sql.SqlRow;
+import org.apache.ignite.table.Tuple;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Helper methods for creating a {@link ResultSet} using a list of objects.
+ */
+class JdbcDatabaseMetataUtils {
+ /** List of support metadata column types. */
Review Comment:
The comment on line 49 has a typo: "support" should be "supported".
```suggestion
/** List of supported metadata column types. */
```
##########
modules/jdbc/src/main/java/org/apache/ignite/internal/jdbc/JdbcDatabaseMetadata.java:
##########
@@ -813,22 +815,28 @@ public boolean dataDefinitionIgnoredInTransactions() {
return false;
}
+ private static ColumnMetadata columnMeta(String name, ColumnType type) {
+ return new ColumnMetadataImpl(name, type, -1, -1, true, null);
+ }
+
+
+
Review Comment:
[nitpick] There are extra blank lines added here (lines 822-823). While not a functional issue, this creates unnecessary whitespace that could be removed for consistency.
```suggestion
```
##########
modules/jdbc/src/main/java/org/apache/ignite/internal/jdbc/JdbcDatabaseMetadata.java:
##########
@@ -1777,14 +1785,14 @@ public static List<Object> columnRow(JdbcColumnMeta colMeta, int pos) {
row.add(CATALOG_NAME); // 1. TABLE_CAT
row.add(colMeta.schemaName()); // 2. TABLE_SCHEM
row.add(colMeta.tableName()); // 3. TABLE_NAME
- row.add(colMeta.columnLabel()); // 4. COLUMN_NAME
- row.add(colMeta.dataType()); // 5. DATA_TYPE
+ row.add(colMeta.columnLabel()); // 4. COLUMN_NAME
+ row.add((short) colMeta.dataType()); // 5. DATA_TYPE
row.add(colMeta.dataTypeName()); // 6. TYPE_NAME
row.add(colMeta.precision() == -1 ? null : colMeta.precision()); // 7. COLUMN_SIZE
row.add((Integer) null); // 8. BUFFER_LENGTH
row.add(colMeta.scale() == -1 ? null : colMeta.scale()); // 9. DECIMAL_DIGITS
row.add(10); // 10. NUM_PREC_RADIX
- row.add(colMeta.isNullable() ? columnNullable : columnNoNulls); // 11. NULLABLE
+ row.add(colMeta.isNullable() ? (short) columnNullable : (short) columnNoNulls); // 11. NULLABLE
row.add((String) null); // 12. REMARKS
row.add(colMeta.defaultValue()); // 13. COLUMN_DEF
row.add(colMeta.dataType()); // 14. SQL_DATA_TYPE
Review Comment:
Inconsistent data type casting. Line 1789 casts `colMeta.dataType()` to `short`, but line 1798 uses `colMeta.dataType()` without casting for the `SQL_DATA_TYPE` field. Since these are both representing SQL data type integers, they should use consistent types. According to JDBC specification, both DATA_TYPE and SQL_DATA_TYPE should be INT32/int type.
--
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: notifications-unsubscribe@ignite.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] IGNITE-26314 Jdbc. Migrate JdbcDatabaseMetadata to use the new ResultSet implementation [ignite-3]
Posted by "lowka (via GitHub)" <gi...@apache.org>.
lowka commented on code in PR #6965:
URL: https://github.com/apache/ignite-3/pull/6965#discussion_r2527826976
##########
modules/jdbc/src/main/java/org/apache/ignite/internal/jdbc/JdbcDatabaseMetadata.java:
##########
@@ -986,45 +994,45 @@ public ResultSet getCatalogs() throws SQLException {
public ResultSet getTableTypes() throws SQLException {
ensureNotClosed();
- return new JdbcResultSet(
+ return createObjectListResultSet(
asList(List.of(TYPE_TABLE, TYPE_VIEW)),
Review Comment:
There is a bug here - it returns a row with a single column [TYPE_TABLE, TYPE_VIEW)] instead of two rows [TYPE_TABLE], [TYPE_VIEW]
--
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: notifications-unsubscribe@ignite.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] IGNITE-26314 Jdbc. Migrate JdbcDatabaseMetadata to use the new ResultSet implementation [ignite-3]
Posted by "Copilot (via GitHub)" <gi...@apache.org>.
Copilot commented on code in PR #6965:
URL: https://github.com/apache/ignite-3/pull/6965#discussion_r2523722832
##########
modules/jdbc/src/main/java/org/apache/ignite/internal/jdbc/JdbcDatabaseMetadataUtils.java:
##########
@@ -0,0 +1,337 @@
+/*
+ * 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.ignite.internal.jdbc;
+
+import java.math.BigDecimal;
+import java.sql.ResultSet;
+import java.time.Instant;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.util.EnumSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.UUID;
+import org.apache.ignite.internal.jdbc2.ClientSyncResultSet;
+import org.apache.ignite.internal.jdbc2.JdbcResultSet;
+import org.apache.ignite.internal.sql.ResultSetMetadataImpl;
+import org.apache.ignite.internal.util.IgniteUtils;
+import org.apache.ignite.internal.util.TransformingIterator;
+import org.apache.ignite.sql.ColumnMetadata;
+import org.apache.ignite.sql.ColumnType;
+import org.apache.ignite.sql.ResultSetMetadata;
+import org.apache.ignite.sql.SqlRow;
+import org.apache.ignite.table.Tuple;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Helper methods for creating a {@link ResultSet} using a list of objects.
+ */
+class JdbcDatabaseMetadataUtils {
+ /** List of supported metadata column types. */
+ private static final EnumSet<ColumnType> SUPPORTED_TYPES = EnumSet.of(
+ ColumnType.NULL,
+ ColumnType.BOOLEAN,
+ ColumnType.INT8,
+ ColumnType.INT16,
+ ColumnType.INT32,
+ ColumnType.INT64,
+ ColumnType.STRING
+ );
+
+ /** Creates an empty {@link ResultSet} using the provided metadata. */
+ static ResultSet createObjectListResultSet(List<ColumnMetadata> columnsMeta) {
+ return createObjectListResultSet(List.of(), columnsMeta);
+ }
+
+ /** Creates a {@link ResultSet} using the provided list of objects and metadata. */
+ static ResultSet createObjectListResultSet(List<List<Object>> rows, List<ColumnMetadata> columnsMeta) {
+ ResultSetMetadata meta = new ResultSetMetadataImpl(columnsMeta);
+
+ if (IgniteUtils.assertionsEnabled()) {
+ for (ColumnMetadata columnMeta : meta.columns()) {
+ assert SUPPORTED_TYPES.contains(columnMeta.type()) : "Unsupported column type: " + columnMeta.type();
+ }
+ }
+
+ TransformingIterator<List<Object>, SqlRow> transformer =
+ new TransformingIterator<>(rows.iterator(), ObjectListToSqlRowAdapter::new);
+
+ return new JdbcResultSet(
+ new IteratorBasedClientSyncResultSet(transformer, meta),
+ null,
+ null,
+ false,
+ 0
+ );
Review Comment:
Passing `null` for both `statement` and `zoneIdSupplier` parameters can cause `NullPointerException` in the JdbcResultSet methods:
1. `isClosed()` calls `statement.isClosed()` without null check (JdbcResultSet line 1899)
2. `instantWithLocalTimeZone()` calls `zoneIdSupplier.get()` without null check (JdbcResultSet line 2258)
While timestamp types aren't in SUPPORTED_TYPES, the statement issue will definitely cause problems. Consider passing non-null values or ensuring JdbcResultSet handles null parameters properly.
##########
modules/jdbc/src/main/java/org/apache/ignite/internal/jdbc2/JdbcResultSet.java:
##########
@@ -105,7 +105,8 @@ public class JdbcResultSet implements ResultSet {
/**
* Constructor.
*/
- JdbcResultSet(
+ // TODO https://issues.apache.org/jira/browse/IGNITE-26145 Remove "public" modifier
+ public JdbcResultSet(
Review Comment:
Making this constructor public allows it to be called with `null` for the `statement` parameter (as done in `JdbcDatabaseMetadataUtils`). However, this can cause a `NullPointerException` in `isClosed()` method (line 1899), which calls `statement.isClosed()` without null-checking. Consider either:
1. Documenting that statement can be null and fixing usages accordingly
2. Adding validation to prevent null statement parameter
3. Keeping the constructor package-private and finding an alternative approach
##########
modules/jdbc/src/main/java/org/apache/ignite/internal/jdbc/JdbcDatabaseMetadataUtils.java:
##########
@@ -0,0 +1,337 @@
+/*
+ * 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.ignite.internal.jdbc;
+
+import java.math.BigDecimal;
+import java.sql.ResultSet;
+import java.time.Instant;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.util.EnumSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.UUID;
+import org.apache.ignite.internal.jdbc2.ClientSyncResultSet;
+import org.apache.ignite.internal.jdbc2.JdbcResultSet;
+import org.apache.ignite.internal.sql.ResultSetMetadataImpl;
+import org.apache.ignite.internal.util.IgniteUtils;
+import org.apache.ignite.internal.util.TransformingIterator;
+import org.apache.ignite.sql.ColumnMetadata;
+import org.apache.ignite.sql.ColumnType;
+import org.apache.ignite.sql.ResultSetMetadata;
+import org.apache.ignite.sql.SqlRow;
+import org.apache.ignite.table.Tuple;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Helper methods for creating a {@link ResultSet} using a list of objects.
+ */
+class JdbcDatabaseMetadataUtils {
+ /** List of supported metadata column types. */
+ private static final EnumSet<ColumnType> SUPPORTED_TYPES = EnumSet.of(
+ ColumnType.NULL,
+ ColumnType.BOOLEAN,
+ ColumnType.INT8,
+ ColumnType.INT16,
+ ColumnType.INT32,
+ ColumnType.INT64,
+ ColumnType.STRING
+ );
+
+ /** Creates an empty {@link ResultSet} using the provided metadata. */
+ static ResultSet createObjectListResultSet(List<ColumnMetadata> columnsMeta) {
+ return createObjectListResultSet(List.of(), columnsMeta);
+ }
+
+ /** Creates a {@link ResultSet} using the provided list of objects and metadata. */
+ static ResultSet createObjectListResultSet(List<List<Object>> rows, List<ColumnMetadata> columnsMeta) {
+ ResultSetMetadata meta = new ResultSetMetadataImpl(columnsMeta);
+
+ if (IgniteUtils.assertionsEnabled()) {
+ for (ColumnMetadata columnMeta : meta.columns()) {
+ assert SUPPORTED_TYPES.contains(columnMeta.type()) : "Unsupported column type: " + columnMeta.type();
+ }
+ }
+
+ TransformingIterator<List<Object>, SqlRow> transformer =
+ new TransformingIterator<>(rows.iterator(), ObjectListToSqlRowAdapter::new);
+
+ return new JdbcResultSet(
+ new IteratorBasedClientSyncResultSet(transformer, meta),
+ null,
+ null,
+ false,
+ 0
+ );
+ }
+
+ private static class IteratorBasedClientSyncResultSet implements ClientSyncResultSet {
+ private final ResultSetMetadata metadata;
+ private final Iterator<SqlRow> rowsIterator;
+
+ IteratorBasedClientSyncResultSet(Iterator<SqlRow> rowsIterator, ResultSetMetadata metadata) {
+ this.rowsIterator = rowsIterator;
+ this.metadata = metadata;
+ }
+
+ @Override
+ public ResultSetMetadata metadata() {
+ return metadata;
+ }
+
+ @Override
+ public boolean hasRowSet() {
+ return true;
+ }
+
+ @Override
+ public long affectedRows() {
+ return -1;
+ }
+
+ @Override
+ public boolean wasApplied() {
+ return false;
+ }
+
+ @Override
+ public boolean hasNextResultSet() {
+ return false;
+ }
+
+ @Override
+ public ClientSyncResultSet nextResultSet() {
+ throw new NoSuchElementException("Query has no more results");
+ }
+
+ @Override
+ public void close() {
+ // No-op.
+ }
+
+ @Override
+ public boolean hasNext() {
+ return rowsIterator.hasNext();
+ }
+
+ @Override
+ public SqlRow next() {
+ return rowsIterator.next();
+ }
+ }
+
+ private static class ObjectListToSqlRowAdapter implements SqlRow {
+ private final List<Object> row;
+
+ ObjectListToSqlRowAdapter(List<Object> row) {
+ this.row = row;
+ }
+
+ @Override
Review Comment:
This unchecked cast could cause `ClassCastException` at runtime if the stored object type doesn't match the requested type T. Consider adding a `@SuppressWarnings("unchecked")` annotation to acknowledge this is intentional, since the caller is responsible for requesting the correct type based on metadata.
```suggestion
@Override
@SuppressWarnings("unchecked")
```
--
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: notifications-unsubscribe@ignite.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] IGNITE-26314 Jdbc. Migrate JdbcDatabaseMetadata to use the new ResultSet implementation [ignite-3]
Posted by "Copilot (via GitHub)" <gi...@apache.org>.
Copilot commented on code in PR #6965:
URL: https://github.com/apache/ignite-3/pull/6965#discussion_r2526500062
##########
modules/jdbc/src/main/java/org/apache/ignite/internal/jdbc/JdbcUtils.java:
##########
@@ -0,0 +1,336 @@
+/*
+ * 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.ignite.internal.jdbc;
+
+import java.math.BigDecimal;
+import java.sql.ResultSet;
+import java.time.Instant;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.ZoneId;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.UUID;
+import java.util.function.Supplier;
+import org.apache.ignite.internal.jdbc2.ClientSyncResultSet;
+import org.apache.ignite.internal.jdbc2.JdbcResultSet;
+import org.apache.ignite.internal.sql.ResultSetMetadataImpl;
+import org.apache.ignite.internal.util.TransformingIterator;
+import org.apache.ignite.sql.ColumnMetadata;
+import org.apache.ignite.sql.ResultSetMetadata;
+import org.apache.ignite.sql.SqlRow;
+import org.apache.ignite.table.Tuple;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Helper methods for creating a {@link ResultSet} using a list of objects.
+ */
+public class JdbcUtils {
+ /** System time zone supplier. */
+ private static final Supplier<ZoneId> defaultZoneSupplier = ZoneId::systemDefault;
+
+ /** Creates an empty {@link ResultSet} using the provided metadata. */
+ static ResultSet createObjectListResultSet(List<ColumnMetadata> columnsMeta) {
+ return createObjectListResultSet(List.of(), columnsMeta, defaultZoneSupplier);
+ }
+
+ /** Creates a {@link ResultSet} using the provided list of objects and metadata. */
+ public static ResultSet createObjectListResultSet(
+ List<List<Object>> rows,
+ List<ColumnMetadata> columnsMeta,
+ Supplier<ZoneId> timeZoneSupplier
+ ) {
+ return createObjectListResultSet(rows, columnsMeta, timeZoneSupplier, 0);
+ }
+
+ /** Creates a {@link ResultSet} using the provided list of objects and metadata. */
+ public static ResultSet createObjectListResultSet(
+ List<List<Object>> rows,
+ List<ColumnMetadata> columnsMeta,
+ Supplier<ZoneId> timeZoneSupplier,
+ int maxRows
+ ) {
+ ResultSetMetadata meta = new ResultSetMetadataImpl(columnsMeta);
+
+ TransformingIterator<List<Object>, SqlRow> transformer =
+ new TransformingIterator<>(rows.iterator(), ObjectListToSqlRowAdapter::new);
+
+ return new JdbcResultSet(
+ new IteratorBasedClientSyncResultSet(transformer, meta),
+ null,
+ timeZoneSupplier,
+ false,
+ maxRows
+ );
+ }
+
+ private static class IteratorBasedClientSyncResultSet implements ClientSyncResultSet {
+ private final ResultSetMetadata metadata;
+ private final Iterator<SqlRow> rowsIterator;
+
+ IteratorBasedClientSyncResultSet(Iterator<SqlRow> rowsIterator, ResultSetMetadata metadata) {
+ this.rowsIterator = rowsIterator;
+ this.metadata = metadata;
+ }
+
+ @Override
+ public ResultSetMetadata metadata() {
+ return metadata;
+ }
+
+ @Override
+ public boolean hasRowSet() {
+ return true;
+ }
+
+ @Override
+ public long affectedRows() {
+ return -1;
+ }
+
+ @Override
+ public boolean wasApplied() {
+ return false;
+ }
+
+ @Override
+ public boolean hasNextResultSet() {
+ return false;
+ }
+
+ @Override
+ public ClientSyncResultSet nextResultSet() {
+ throw new NoSuchElementException("Query has no more results");
+ }
+
+ @Override
+ public void close() {
+ // No-op.
+ }
+
+ @Override
+ public boolean hasNext() {
+ return rowsIterator.hasNext();
+ }
+
+ @Override
+ public SqlRow next() {
+ return rowsIterator.next();
+ }
+ }
+
+ private static class ObjectListToSqlRowAdapter implements SqlRow {
+ private final List<Object> row;
+
+ ObjectListToSqlRowAdapter(List<Object> row) {
+ this.row = row;
+ }
+
+ @Override
+ public <T> @Nullable T value(int columnIndex) {
+ return (T) row.get(columnIndex);
+ }
Review Comment:
The ObjectListToSqlRowAdapter class is missing the required iterator() method implementation. SqlRow extends Tuple which extends Iterable<Object>, requiring an iterator() method. Add: @Override public Iterator<Object> iterator() { return row.iterator(); }
--
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: notifications-unsubscribe@ignite.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] IGNITE-26314 Jdbc. Migrate JdbcDatabaseMetadata to use the new ResultSet implementation [ignite-3]
Posted by "Copilot (via GitHub)" <gi...@apache.org>.
Copilot commented on code in PR #6965:
URL: https://github.com/apache/ignite-3/pull/6965#discussion_r2523638567
##########
modules/jdbc/src/main/java/org/apache/ignite/internal/jdbc/JdbcDatabaseMetadataUtils.java:
##########
@@ -0,0 +1,342 @@
+/*
+ * 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.ignite.internal.jdbc;
+
+import java.math.BigDecimal;
+import java.sql.ResultSet;
+import java.time.Instant;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.util.EnumSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.UUID;
+import org.apache.ignite.internal.jdbc2.ClientSyncResultSet;
+import org.apache.ignite.internal.jdbc2.JdbcResultSet;
+import org.apache.ignite.internal.sql.ResultSetMetadataImpl;
+import org.apache.ignite.internal.util.IgniteUtils;
+import org.apache.ignite.internal.util.TransformingIterator;
+import org.apache.ignite.sql.ColumnMetadata;
+import org.apache.ignite.sql.ColumnType;
+import org.apache.ignite.sql.NoRowSetExpectedException;
+import org.apache.ignite.sql.ResultSetMetadata;
+import org.apache.ignite.sql.SqlRow;
+import org.apache.ignite.table.Tuple;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Helper methods for creating a {@link ResultSet} using a list of objects.
+ */
+class JdbcDatabaseMetadataUtils {
+ /** List of supported metadata column types. */
+ private static final EnumSet<ColumnType> SUPPORTED_TYPES = EnumSet.of(
+ ColumnType.NULL,
+ ColumnType.BOOLEAN,
+ ColumnType.INT8,
+ ColumnType.INT16,
+ ColumnType.INT32,
+ ColumnType.INT64,
+ ColumnType.STRING
+ );
+
+ /** Creates an empty {@link ResultSet} using the provided metadata. */
+ static ResultSet createObjectListResultSet(List<ColumnMetadata> columnsMeta) {
+ return createObjectListResultSet(List.of(), columnsMeta);
+ }
+
+ /** Creates a {@link ResultSet} using the provided list of objects and metadata. */
+ static ResultSet createObjectListResultSet(List<List<Object>> rows, List<ColumnMetadata> columnsMeta) {
+ ResultSetMetadata meta = new ResultSetMetadataImpl(columnsMeta);
+
+ if (IgniteUtils.assertionsEnabled()) {
+ for (ColumnMetadata columnMeta : meta.columns()) {
+ assert SUPPORTED_TYPES.contains(columnMeta.type()) : "Unsupported column type: " + columnMeta.type();
+ }
+ }
+
+ TransformingIterator<List<Object>, SqlRow> transformer =
+ new TransformingIterator<>(rows.iterator(), ObjectListToSqlRowAdapter::new);
+
+ return new JdbcResultSet(
+ new IteratorBasedClientSyncResultSet(transformer, meta),
+ null,
+ null,
+ false,
+ 0
+ );
+ }
+
+ private static class IteratorBasedClientSyncResultSet implements ClientSyncResultSet {
+ private final ResultSetMetadata metadata;
+ private final Iterator<SqlRow> rowsIterator;
+
+ IteratorBasedClientSyncResultSet(Iterator<SqlRow> rowsIterator, ResultSetMetadata metadata) {
+ this.rowsIterator = rowsIterator;
+ this.metadata = metadata;
+ }
+
+ @Override
+ public ResultSetMetadata metadata() {
+ return metadata;
+ }
+
+ @Override
+ public boolean hasRowSet() {
+ return true;
+ }
+
+ @Override
+ public long affectedRows() {
+ return -1;
+ }
+
+ @Override
+ public boolean wasApplied() {
+ return false;
+ }
+
+ @Override
+ public boolean hasNextResultSet() {
+ return false;
+ }
+
+ @Override
+ public ClientSyncResultSet nextResultSet() {
+ throw new NoSuchElementException("Query has no more results");
+ }
+
+ @Override
+ public void close() {
+ // No-op.
+ }
+
+ @Override
+ public boolean hasNext() {
+ return rowsIterator.hasNext();
+ }
+
+ @Override
+ public SqlRow next() {
+ if (!rowsIterator.hasNext()) {
+ throw new NoRowSetExpectedException();
Review Comment:
Incorrect exception type: `NoRowSetExpectedException` should be thrown when a query doesn't return a row set (e.g., DML/DDL queries), not when an iterator runs out of elements. Since `hasRowSet()` returns `true`, this implementation should throw `NoSuchElementException` when the iterator is exhausted, consistent with the `Iterator` contract. Alternatively, remove the check entirely and let the underlying `rowsIterator.next()` throw `NoSuchElementException`.
```suggestion
throw new NoSuchElementException();
```
##########
modules/jdbc/src/main/java/org/apache/ignite/internal/jdbc/JdbcDatabaseMetadataUtils.java:
##########
@@ -0,0 +1,342 @@
+/*
+ * 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.ignite.internal.jdbc;
+
+import java.math.BigDecimal;
+import java.sql.ResultSet;
+import java.time.Instant;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.util.EnumSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.UUID;
+import org.apache.ignite.internal.jdbc2.ClientSyncResultSet;
+import org.apache.ignite.internal.jdbc2.JdbcResultSet;
+import org.apache.ignite.internal.sql.ResultSetMetadataImpl;
+import org.apache.ignite.internal.util.IgniteUtils;
+import org.apache.ignite.internal.util.TransformingIterator;
+import org.apache.ignite.sql.ColumnMetadata;
+import org.apache.ignite.sql.ColumnType;
+import org.apache.ignite.sql.NoRowSetExpectedException;
+import org.apache.ignite.sql.ResultSetMetadata;
+import org.apache.ignite.sql.SqlRow;
+import org.apache.ignite.table.Tuple;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Helper methods for creating a {@link ResultSet} using a list of objects.
+ */
+class JdbcDatabaseMetadataUtils {
+ /** List of supported metadata column types. */
+ private static final EnumSet<ColumnType> SUPPORTED_TYPES = EnumSet.of(
+ ColumnType.NULL,
+ ColumnType.BOOLEAN,
+ ColumnType.INT8,
+ ColumnType.INT16,
+ ColumnType.INT32,
+ ColumnType.INT64,
+ ColumnType.STRING
+ );
+
+ /** Creates an empty {@link ResultSet} using the provided metadata. */
+ static ResultSet createObjectListResultSet(List<ColumnMetadata> columnsMeta) {
+ return createObjectListResultSet(List.of(), columnsMeta);
+ }
+
+ /** Creates a {@link ResultSet} using the provided list of objects and metadata. */
+ static ResultSet createObjectListResultSet(List<List<Object>> rows, List<ColumnMetadata> columnsMeta) {
+ ResultSetMetadata meta = new ResultSetMetadataImpl(columnsMeta);
+
+ if (IgniteUtils.assertionsEnabled()) {
+ for (ColumnMetadata columnMeta : meta.columns()) {
+ assert SUPPORTED_TYPES.contains(columnMeta.type()) : "Unsupported column type: " + columnMeta.type();
+ }
+ }
+
+ TransformingIterator<List<Object>, SqlRow> transformer =
+ new TransformingIterator<>(rows.iterator(), ObjectListToSqlRowAdapter::new);
+
+ return new JdbcResultSet(
+ new IteratorBasedClientSyncResultSet(transformer, meta),
+ null,
+ null,
+ false,
+ 0
+ );
+ }
+
+ private static class IteratorBasedClientSyncResultSet implements ClientSyncResultSet {
+ private final ResultSetMetadata metadata;
+ private final Iterator<SqlRow> rowsIterator;
+
+ IteratorBasedClientSyncResultSet(Iterator<SqlRow> rowsIterator, ResultSetMetadata metadata) {
+ this.rowsIterator = rowsIterator;
+ this.metadata = metadata;
+ }
+
+ @Override
+ public ResultSetMetadata metadata() {
+ return metadata;
+ }
+
+ @Override
+ public boolean hasRowSet() {
+ return true;
+ }
+
+ @Override
+ public long affectedRows() {
+ return -1;
+ }
+
+ @Override
+ public boolean wasApplied() {
+ return false;
+ }
+
+ @Override
+ public boolean hasNextResultSet() {
+ return false;
+ }
+
+ @Override
+ public ClientSyncResultSet nextResultSet() {
+ throw new NoSuchElementException("Query has no more results");
+ }
+
+ @Override
+ public void close() {
+ // No-op.
+ }
+
+ @Override
+ public boolean hasNext() {
+ return rowsIterator.hasNext();
+ }
+
+ @Override
+ public SqlRow next() {
+ if (!rowsIterator.hasNext()) {
+ throw new NoRowSetExpectedException();
+ }
+
+ return rowsIterator.next();
+ }
+ }
+
+ private static class ObjectListToSqlRowAdapter implements SqlRow {
+ private final List<Object> row;
+
+ ObjectListToSqlRowAdapter(List<Object> row) {
+ this.row = row;
+ }
+
+ @Override
+ public <T> @Nullable T value(int columnIndex) {
+ return (T) row.get(columnIndex);
+ }
+
+ @Override
+ public <T> @Nullable T value(String columnName) throws IllegalArgumentException {
+ throw new UnsupportedOperationException("This method should not be called.");
+ }
+
+ @Override
+ public ResultSetMetadata metadata() {
+ throw new UnsupportedOperationException("This method should not be called.");
+ }
+
+ @Override
+ public int columnCount() {
+ throw new UnsupportedOperationException("This method should not be called.");
+ }
+
+ @Override
+ public String columnName(int columnIndex) {
+ throw new UnsupportedOperationException("This method should not be called.");
+ }
+
+ @Override
+ public int columnIndex(String columnName) {
+ throw new UnsupportedOperationException("This method should not be called.");
+ }
+
+ @Override
+ public <T> @Nullable T valueOrDefault(String columnName, @Nullable T defaultValue) {
+ throw new UnsupportedOperationException("This method should not be called.");
+ }
+
+ @Override
+ public Tuple set(String columnName, @Nullable Object value) {
+ throw new UnsupportedOperationException("This method should not be called.");
+ }
+
+ @Override
+ public boolean booleanValue(String columnName) {
+ throw new UnsupportedOperationException("This method should not be called.");
+ }
+
+ @Override
+ public boolean booleanValue(int columnIndex) {
+ throw new UnsupportedOperationException("This method should not be called.");
+ }
+
+ @Override
+ public byte byteValue(String columnName) {
+ throw new UnsupportedOperationException("This method should not be called.");
+ }
+
+ @Override
+ public byte byteValue(int columnIndex) {
+ throw new UnsupportedOperationException("This method should not be called.");
+ }
+
+ @Override
+ public short shortValue(String columnName) {
+ throw new UnsupportedOperationException("This method should not be called.");
+ }
+
+ @Override
+ public short shortValue(int columnIndex) {
+ throw new UnsupportedOperationException("This method should not be called.");
+ }
+
+ @Override
+ public int intValue(String columnName) {
+ throw new UnsupportedOperationException("This method should not be called.");
+ }
+
+ @Override
+ public int intValue(int columnIndex) {
+ throw new UnsupportedOperationException("This method should not be called.");
+ }
+
+ @Override
+ public long longValue(String columnName) {
+ throw new UnsupportedOperationException("This method should not be called.");
+ }
+
+ @Override
+ public long longValue(int columnIndex) {
+ throw new UnsupportedOperationException("This method should not be called.");
+ }
+
+ @Override
+ public float floatValue(String columnName) {
+ throw new UnsupportedOperationException("This method should not be called.");
+ }
+
+ @Override
+ public float floatValue(int columnIndex) {
+ throw new UnsupportedOperationException("This method should not be called.");
+ }
+
+ @Override
+ public double doubleValue(String columnName) {
+ throw new UnsupportedOperationException("This method should not be called.");
+ }
+
+ @Override
+ public double doubleValue(int columnIndex) {
+ throw new UnsupportedOperationException("This method should not be called.");
+ }
+
+ @Override
+ public BigDecimal decimalValue(String columnName) {
+ throw new UnsupportedOperationException("This method should not be called.");
+ }
+
+ @Override
+ public BigDecimal decimalValue(int columnIndex) {
+ throw new UnsupportedOperationException("This method should not be called.");
+ }
+
+ @Override
+ public String stringValue(String columnName) {
+ throw new UnsupportedOperationException("This method should not be called.");
+ }
+
+ @Override
+ public String stringValue(int columnIndex) {
+ throw new UnsupportedOperationException("This method should not be called.");
+ }
+
+ @Override
+ public byte[] bytesValue(String columnName) {
+ throw new UnsupportedOperationException("This method should not be called.");
+ }
+
+ @Override
+ public byte[] bytesValue(int columnIndex) {
+ throw new UnsupportedOperationException("This method should not be called.");
+ }
+
+ @Override
+ public UUID uuidValue(String columnName) {
+ throw new UnsupportedOperationException("This method should not be called.");
+ }
+
+ @Override
+ public UUID uuidValue(int columnIndex) {
+ throw new UnsupportedOperationException("This method should not be called.");
+ }
+
+ @Override
+ public LocalDate dateValue(String columnName) {
+ throw new UnsupportedOperationException("This method should not be called.");
+ }
+
+ @Override
+ public LocalDate dateValue(int columnIndex) {
+ throw new UnsupportedOperationException("This method should not be called.");
+ }
+
+ @Override
+ public LocalTime timeValue(String columnName) {
+ throw new UnsupportedOperationException("This method should not be called.");
+ }
+
+ @Override
+ public LocalTime timeValue(int columnIndex) {
+ throw new UnsupportedOperationException("This method should not be called.");
+ }
+
+ @Override
+ public LocalDateTime datetimeValue(String columnName) {
+ throw new UnsupportedOperationException("This method should not be called.");
+ }
+
+ @Override
+ public LocalDateTime datetimeValue(int columnIndex) {
+ throw new UnsupportedOperationException("This method should not be called.");
+ }
+
+ @Override
+ public Instant timestampValue(String columnName) {
+ throw new UnsupportedOperationException("This method should not be called.");
+ }
+
+ @Override
+ public Instant timestampValue(int columnIndex) {
+ throw new UnsupportedOperationException("This method should not be called.");
Review Comment:
All UnsupportedOperationException messages in this class use the generic "This method should not be called." Consider making these messages more specific by including the method name to aid debugging, e.g., "value(String columnName) should not be called on ObjectListToSqlRowAdapter."
```suggestion
throw new UnsupportedOperationException("timeValue(String columnName) should not be called on ObjectListToSqlRowAdapter.");
}
@Override
public LocalTime timeValue(int columnIndex) {
throw new UnsupportedOperationException("timeValue(int columnIndex) should not be called on ObjectListToSqlRowAdapter.");
}
@Override
public LocalDateTime datetimeValue(String columnName) {
throw new UnsupportedOperationException("datetimeValue(String columnName) should not be called on ObjectListToSqlRowAdapter.");
}
@Override
public LocalDateTime datetimeValue(int columnIndex) {
throw new UnsupportedOperationException("datetimeValue(int columnIndex) should not be called on ObjectListToSqlRowAdapter.");
}
@Override
public Instant timestampValue(String columnName) {
throw new UnsupportedOperationException("timestampValue(String columnName) should not be called on ObjectListToSqlRowAdapter.");
}
@Override
public Instant timestampValue(int columnIndex) {
throw new UnsupportedOperationException("timestampValue(int columnIndex) should not be called on ObjectListToSqlRowAdapter.");
```
--
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: notifications-unsubscribe@ignite.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org