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

ppa pushed a commit to branch jdbc_over_thin_sql
in repository https://gitbox.apache.org/repos/asf/ignite-3.git


The following commit(s) were added to refs/heads/jdbc_over_thin_sql by this 
push:
     new 8548260b703 IGNITE-26190 Sql. Jdbc. PreparedStatement.executeBatch 
using the thin client SQL API (#6823)
8548260b703 is described below

commit 8548260b70373f4d80d79082042252765e0aafb0
Author: Pavel Pereslegin <[email protected]>
AuthorDate: Tue Oct 21 13:25:00 2025 +0300

    IGNITE-26190 Sql. Jdbc. PreparedStatement.executeBatch using the thin 
client SQL API (#6823)
---
 .../apache/ignite/jdbc/ItJdbcBatchSelfTest.java    | 35 ++++++++---
 .../ignite/jdbc/ItJdbcConnectionSelfTest.java      | 11 ++++
 .../ignite/jdbc/ItJdbcStatementCancelSelfTest.java |  1 -
 .../apache/ignite/jdbc/ItJdbcTransactionTest.java  |  1 -
 .../ignite/internal/jdbc2/JdbcConnection2.java     | 10 +---
 .../internal/jdbc2/JdbcPreparedStatement2.java     | 68 +++++++++++++++++++++-
 .../ignite/internal/jdbc2/JdbcStatement2.java      | 58 ++++++++++--------
 .../org/apache/ignite/data/SpringDataJdbcTest.java |  2 -
 8 files changed, 139 insertions(+), 47 deletions(-)

diff --git 
a/modules/jdbc/src/integrationTest/java/org/apache/ignite/jdbc/ItJdbcBatchSelfTest.java
 
b/modules/jdbc/src/integrationTest/java/org/apache/ignite/jdbc/ItJdbcBatchSelfTest.java
index b650c4b76d8..43d1e520fa5 100644
--- 
a/modules/jdbc/src/integrationTest/java/org/apache/ignite/jdbc/ItJdbcBatchSelfTest.java
+++ 
b/modules/jdbc/src/integrationTest/java/org/apache/ignite/jdbc/ItJdbcBatchSelfTest.java
@@ -44,18 +44,20 @@ import java.util.Arrays;
 import java.util.List;
 import java.util.UUID;
 import java.util.concurrent.ThreadLocalRandom;
+import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
 import org.apache.ignite.internal.TestWrappers;
 import org.apache.ignite.internal.app.IgniteImpl;
-import org.apache.ignite.internal.jdbc.JdbcPreparedStatement;
 import org.apache.ignite.internal.jdbc.JdbcStatement;
 import org.apache.ignite.internal.jdbc.proto.IgniteQueryErrorCode;
 import org.apache.ignite.internal.jdbc.proto.SqlStateCode;
+import org.apache.ignite.internal.jdbc2.JdbcPreparedStatement2;
 import org.apache.ignite.internal.sql.engine.QueryCancelledException;
 import org.apache.ignite.internal.sql.engine.SqlQueryProcessor;
 import org.apache.ignite.internal.sql.engine.exec.fsm.QueryInfo;
 import org.apache.ignite.internal.sql.engine.util.SqlTestUtils;
 import org.apache.ignite.internal.tx.TxManager;
+import org.awaitility.Awaitility;
 import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeAll;
@@ -69,8 +71,6 @@ import org.junit.jupiter.params.provider.MethodSource;
 /**
  * Statement test.
  */
-// TODO https://issues.apache.org/jira/browse/IGNITE-26190
-@Disabled("https://issues.apache.org/jira/browse/IGNITE-26143";)
 public class ItJdbcBatchSelfTest extends AbstractJdbcSelfTest {
     /** SQL CREATE TABLE query. */
     private static final String SQL_CREATE = "CREATE TABLE Person(id INT 
PRIMARY KEY, firstName VARCHAR, lastName VARCHAR, age INT)";
@@ -88,6 +88,9 @@ public class ItJdbcBatchSelfTest extends AbstractJdbcSelfTest 
{
     /** Prepared statement. */
     private PreparedStatement pstmt;
 
+    /** The number of open thin client resources before the test started. */
+    private int resourcesBefore;
+
     @BeforeAll
     public static void beforeAll() throws Exception {
         try (Statement statement = conn.createStatement()) {
@@ -113,6 +116,8 @@ public class ItJdbcBatchSelfTest extends 
AbstractJdbcSelfTest {
         try (Statement statement = conn.createStatement()) {
             statement.executeUpdate(SQL_DELETE);
         }
+
+        resourcesBefore = openResources();
     }
 
     /** {@inheritDoc} */
@@ -131,9 +136,14 @@ public class ItJdbcBatchSelfTest extends 
AbstractJdbcSelfTest {
                 .getSum();
 
         assertEquals(0, countOfPendingTransactions);
+
+        Awaitility.await().timeout(5, TimeUnit.SECONDS).untilAsserted(() -> {
+            assertThat(openResources() - resourcesBefore, is(0));
+        });
     }
 
     @Test
+    @Disabled("https://issues.apache.org/jira/browse/IGNITE-26143";)
     public void testBatch() throws SQLException {
         final int batchSize = 10;
 
@@ -152,6 +162,7 @@ public class ItJdbcBatchSelfTest extends 
AbstractJdbcSelfTest {
     }
 
     @Test
+    @Disabled("https://issues.apache.org/jira/browse/IGNITE-26143";)
     public void testBatchWithDdl() throws SQLException {
         stmt.addBatch("CREATE TABLE t1(ID INT PRIMARY KEY)");
         stmt.addBatch("CREATE TABLE t2(ID INT PRIMARY KEY)");
@@ -168,6 +179,7 @@ public class ItJdbcBatchSelfTest extends 
AbstractJdbcSelfTest {
     }
 
     @Test
+    @Disabled("https://issues.apache.org/jira/browse/IGNITE-26143";)
     public void testBatchWithKill() throws SQLException {
         try (Statement targetQueryStatement = conn.createStatement()) {
             try (ResultSet rs = targetQueryStatement.executeQuery("SELECT x 
FROM system_range(0, 100000);")) {
@@ -197,6 +209,7 @@ public class ItJdbcBatchSelfTest extends 
AbstractJdbcSelfTest {
     }
 
     @Test
+    @Disabled("https://issues.apache.org/jira/browse/IGNITE-26143";)
     public void testMultipleStatementForBatchIsNotAllowed() throws 
SQLException {
         String insertStmt = "insert into Person (id, firstName, lastName, age) 
values";
         String ins1 = insertStmt + valuesRow(1);
@@ -211,6 +224,7 @@ public class ItJdbcBatchSelfTest extends 
AbstractJdbcSelfTest {
     }
 
     @Test
+    @Disabled("https://issues.apache.org/jira/browse/IGNITE-26143";)
     public void testBatchOnClosedStatement() throws SQLException {
         Statement stmt2 = conn.createStatement();
         PreparedStatement pstmt2 = conn.prepareStatement("");
@@ -280,6 +294,7 @@ public class ItJdbcBatchSelfTest extends 
AbstractJdbcSelfTest {
 
     @ParameterizedTest(name = "{0}")
     @MethodSource("forbiddenStatements")
+    @Disabled("https://issues.apache.org/jira/browse/IGNITE-26143";)
     public void testForbiddenQueryTypes(String sql, String expectedError) 
throws SQLException {
         stmt.addBatch(sql);
 
@@ -291,6 +306,7 @@ public class ItJdbcBatchSelfTest extends 
AbstractJdbcSelfTest {
     }
 
     @Test
+    @Disabled("https://issues.apache.org/jira/browse/IGNITE-26143";)
     public void testBatchException() throws Exception {
         final int successUpdates = 5;
 
@@ -322,6 +338,7 @@ public class ItJdbcBatchSelfTest extends 
AbstractJdbcSelfTest {
     }
 
     @Test
+    @Disabled("https://issues.apache.org/jira/browse/IGNITE-26143";)
     public void testBatchParseException() throws Exception {
         final int successUpdates = 5;
 
@@ -354,6 +371,7 @@ public class ItJdbcBatchSelfTest extends 
AbstractJdbcSelfTest {
     }
 
     @Test
+    @Disabled("https://issues.apache.org/jira/browse/IGNITE-26143";)
     public void testBatchMerge() throws SQLException {
         final int batchSize = 5;
 
@@ -397,6 +415,7 @@ public class ItJdbcBatchSelfTest extends 
AbstractJdbcSelfTest {
     }
 
     @Test
+    @Disabled("https://issues.apache.org/jira/browse/IGNITE-26143";)
     public void testBatchKeyDuplicatesException() throws Exception {
         final int successUpdates = 5;
 
@@ -433,6 +452,7 @@ public class ItJdbcBatchSelfTest extends 
AbstractJdbcSelfTest {
     }
 
     @Test
+    @Disabled("https://issues.apache.org/jira/browse/IGNITE-26143";)
     public void testHeterogeneousBatch() throws SQLException {
         stmt.addBatch("insert into Person (id, firstName, lastName, age) 
values (0, 'Name0', 'Lastname0', 10)");
         stmt.addBatch("insert into Person (id, firstName, lastName, age) "
@@ -447,6 +467,7 @@ public class ItJdbcBatchSelfTest extends 
AbstractJdbcSelfTest {
     }
 
     @Test
+    @Disabled("https://issues.apache.org/jira/browse/IGNITE-26143";)
     public void testHeterogeneousBatchException() throws Exception {
         stmt.addBatch("insert into Person (id, firstName, lastName, age) 
values (0, 'Name0', 'Lastname0', 10)");
         stmt.addBatch("insert into Person (id, firstName, lastName, age) "
@@ -467,6 +488,7 @@ public class ItJdbcBatchSelfTest extends 
AbstractJdbcSelfTest {
     }
 
     @Test
+    @Disabled("https://issues.apache.org/jira/browse/IGNITE-26143";)
     public void testBatchClear() throws SQLException {
         final int batchSize = 7;
 
@@ -603,10 +625,8 @@ public class ItJdbcBatchSelfTest extends 
AbstractJdbcSelfTest {
      * @throws SQLException If failed.
      */
     private void populateTable(int size) throws SQLException {
-        stmt.addBatch("insert into Person (id, firstName, lastName, age) 
values "
+        stmt.executeUpdate("insert into Person (id, firstName, lastName, age) 
values "
                 + generateValues(0, size));
-
-        stmt.executeBatch();
     }
 
     @Test
@@ -774,7 +794,7 @@ public class ItJdbcBatchSelfTest extends 
AbstractJdbcSelfTest {
                 + "SELECT * FROM TABLE(SYSTEM_RANGE(50, 100)))";
         pstmt = conn.prepareStatement(updateStmt);
 
-        JdbcPreparedStatement igniteStmt = 
pstmt.unwrap(JdbcPreparedStatement.class);
+        JdbcPreparedStatement2 igniteStmt = 
pstmt.unwrap(JdbcPreparedStatement2.class);
 
         {
             // Disable timeout
@@ -821,6 +841,7 @@ public class ItJdbcBatchSelfTest extends 
AbstractJdbcSelfTest {
     }
 
     @Test
+    @Disabled("https://issues.apache.org/jira/browse/IGNITE-26143";)
     public void testBatchTimeout() throws SQLException {
         JdbcStatement igniteStmt = stmt.unwrap(JdbcStatement.class);
 
diff --git 
a/modules/jdbc/src/integrationTest/java/org/apache/ignite/jdbc/ItJdbcConnectionSelfTest.java
 
b/modules/jdbc/src/integrationTest/java/org/apache/ignite/jdbc/ItJdbcConnectionSelfTest.java
index 79076ce270a..29985e08dc4 100644
--- 
a/modules/jdbc/src/integrationTest/java/org/apache/ignite/jdbc/ItJdbcConnectionSelfTest.java
+++ 
b/modules/jdbc/src/integrationTest/java/org/apache/ignite/jdbc/ItJdbcConnectionSelfTest.java
@@ -518,6 +518,12 @@ public class ItJdbcConnectionSelfTest extends 
AbstractJdbcSelfTest {
                     conn::commit
             );
 
+            conn.setAutoCommit(false);
+            assertFalse(conn.getAutoCommit());
+
+            // No exception is expected.
+            conn.commit();
+
             conn.close();
 
             // Exception when called on closed connection
@@ -534,6 +540,11 @@ public class ItJdbcConnectionSelfTest extends 
AbstractJdbcSelfTest {
                     conn::rollback
             );
 
+            conn.setAutoCommit(false);
+
+            // No exception is expected.
+            conn.rollback();
+
             conn.close();
 
             // Exception when called on closed connection
diff --git 
a/modules/jdbc/src/integrationTest/java/org/apache/ignite/jdbc/ItJdbcStatementCancelSelfTest.java
 
b/modules/jdbc/src/integrationTest/java/org/apache/ignite/jdbc/ItJdbcStatementCancelSelfTest.java
index 80150ff660f..936625b3a04 100644
--- 
a/modules/jdbc/src/integrationTest/java/org/apache/ignite/jdbc/ItJdbcStatementCancelSelfTest.java
+++ 
b/modules/jdbc/src/integrationTest/java/org/apache/ignite/jdbc/ItJdbcStatementCancelSelfTest.java
@@ -212,7 +212,6 @@ public class ItJdbcStatementCancelSelfTest extends 
AbstractJdbcSelfTest {
     }
 
     @Test
-    @Disabled("https://issues.apache.org/jira/browse/IGNITE-26190";)
     void cancellationOfPreparedBatch() throws Exception {
         stmt.executeUpdate("CREATE TABLE dummy (id INT PRIMARY KEY, val INT)");
         try (PreparedStatement ps = conn.prepareStatement("INSERT INTO dummy 
SELECT x, x FROM system_range(?, ?)")) {
diff --git 
a/modules/jdbc/src/integrationTest/java/org/apache/ignite/jdbc/ItJdbcTransactionTest.java
 
b/modules/jdbc/src/integrationTest/java/org/apache/ignite/jdbc/ItJdbcTransactionTest.java
index 0924c40d690..f055b8ec040 100644
--- 
a/modules/jdbc/src/integrationTest/java/org/apache/ignite/jdbc/ItJdbcTransactionTest.java
+++ 
b/modules/jdbc/src/integrationTest/java/org/apache/ignite/jdbc/ItJdbcTransactionTest.java
@@ -211,7 +211,6 @@ public class ItJdbcTransactionTest extends 
AbstractJdbcSelfTest {
      * @throws Exception If failed.
      */
     @Test
-    @Disabled("https://issues.apache.org/jira/browse/IGNITE-26190";)
     public void testBatchPrepared() throws Exception {
         checkRollbackAndCommit((conn, start, cnt) -> {
             try (PreparedStatement pstmt = 
conn.prepareStatement(SQL_INSERT_PREPARED)) {
diff --git 
a/modules/jdbc/src/main/java/org/apache/ignite/internal/jdbc2/JdbcConnection2.java
 
b/modules/jdbc/src/main/java/org/apache/ignite/internal/jdbc2/JdbcConnection2.java
index fddc15cf342..1c0b3bc4741 100644
--- 
a/modules/jdbc/src/main/java/org/apache/ignite/internal/jdbc2/JdbcConnection2.java
+++ 
b/modules/jdbc/src/main/java/org/apache/ignite/internal/jdbc2/JdbcConnection2.java
@@ -101,12 +101,6 @@ public class JdbcConnection2 implements Connection {
     private static final String INVALID_TRANSACTION_ISOLATION_LEVEL =
             "Invalid transaction isolation level.";
 
-    private static final String NO_TRANSACTION_TO_COMMIT =
-            "No transaction to commit.";
-
-    private static final String NO_TRANSACTION_TO_ROLLBACK =
-            "No transaction to rollback.";
-
     private static final String SHARDING_KEYS_ARE_NOT_SUPPORTED =
             "Sharding keys are not supported.";
 
@@ -279,7 +273,7 @@ public class JdbcConnection2 implements Connection {
     private void commitTx() throws SQLException {
         Transaction tx = transaction;
         if (tx == null) {
-            throw new SQLException(NO_TRANSACTION_TO_COMMIT);
+            return;
         }
 
         // Null out the transaction first.
@@ -295,7 +289,7 @@ public class JdbcConnection2 implements Connection {
     private void rollbackTx() throws SQLException {
         Transaction tx = transaction;
         if (tx == null) {
-            throw new SQLException(NO_TRANSACTION_TO_ROLLBACK);
+            return;
         }
 
         // Null out the transaction first.
diff --git 
a/modules/jdbc/src/main/java/org/apache/ignite/internal/jdbc2/JdbcPreparedStatement2.java
 
b/modules/jdbc/src/main/java/org/apache/ignite/internal/jdbc2/JdbcPreparedStatement2.java
index 4e74ebd579f..3e6148a5957 100644
--- 
a/modules/jdbc/src/main/java/org/apache/ignite/internal/jdbc2/JdbcPreparedStatement2.java
+++ 
b/modules/jdbc/src/main/java/org/apache/ignite/internal/jdbc2/JdbcPreparedStatement2.java
@@ -17,11 +17,14 @@
 
 package org.apache.ignite.internal.jdbc2;
 
+import static org.apache.ignite.internal.util.ArrayUtils.INT_EMPTY_ARRAY;
+
 import java.io.InputStream;
 import java.io.Reader;
 import java.math.BigDecimal;
 import java.net.URL;
 import java.sql.Array;
+import java.sql.BatchUpdateException;
 import java.sql.Blob;
 import java.sql.Clob;
 import java.sql.Connection;
@@ -52,8 +55,17 @@ import java.util.List;
 import java.util.Objects;
 import java.util.Set;
 import java.util.UUID;
+import org.apache.ignite.internal.client.sql.ClientSql;
+import org.apache.ignite.internal.jdbc.proto.IgniteQueryErrorCode;
 import org.apache.ignite.internal.jdbc.proto.SqlStateCode;
+import org.apache.ignite.internal.lang.IgniteExceptionMapperUtil;
+import org.apache.ignite.internal.util.CollectionUtils;
+import org.apache.ignite.lang.CancelHandle;
+import org.apache.ignite.sql.BatchedArguments;
 import org.apache.ignite.sql.IgniteSql;
+import org.apache.ignite.sql.SqlBatchException;
+import org.apache.ignite.sql.Statement;
+import org.apache.ignite.tx.Transaction;
 import org.jetbrains.annotations.Nullable;
 
 /**
@@ -102,6 +114,9 @@ public class JdbcPreparedStatement2 extends JdbcStatement2 
implements PreparedSt
 
     private List<Object> currentArguments = List.of();
 
+    /** Batched query arguments. */
+    private @Nullable BatchedArguments batchedArgs;
+
     JdbcPreparedStatement2(
             Connection connection,
             IgniteSql igniteSql,
@@ -140,7 +155,35 @@ public class JdbcPreparedStatement2 extends JdbcStatement2 
implements PreparedSt
     public int[] executeBatch() throws SQLException {
         ensureNotClosed();
 
-        throw new UnsupportedOperationException("Batch operation");
+        if (CollectionUtils.nullOrEmpty(batchedArgs)) {
+            return INT_EMPTY_ARRAY;
+        }
+
+        JdbcConnection2 conn = connection.unwrap(JdbcConnection2.class);
+        Transaction tx = conn.startTransactionIfNoAutoCommit();
+
+        // Cancel handle is not reusable, we should create a new one for each 
execution.
+        CancelHandle handle = CancelHandle.create();
+        cancelHandle = handle;
+
+        Statement igniteStmt = createIgniteStatement(sql);
+        ClientSql clientSql = (ClientSql) igniteSql;
+
+        try {
+            long[] longUpdateCounters = clientSql.executeBatch(tx, 
handle.token(), igniteStmt, batchedArgs);
+
+            return longsArrayToIntsArrayUnsafe(longUpdateCounters);
+        } catch (SqlBatchException e) {
+            throw new BatchUpdateException(e.getMessage(),
+                    IgniteQueryErrorCode.codeToSqlState(e.errorCode()),
+                    IgniteQueryErrorCode.UNKNOWN,
+                    longsArrayToIntsArrayUnsafe(e.updateCounters()));
+        } catch (Exception e) {
+            Throwable cause = 
IgniteExceptionMapperUtil.mapToPublicException(e);
+            throw new SQLException(cause.getMessage(), cause);
+        } finally {
+            batchedArgs = null;
+        }
     }
 
     /** {@inheritDoc} */
@@ -226,7 +269,16 @@ public class JdbcPreparedStatement2 extends JdbcStatement2 
implements PreparedSt
     public void addBatch() throws SQLException {
         ensureNotClosed();
 
-        throw new UnsupportedOperationException("Batch operation");
+        if (currentArguments.isEmpty()) {
+            return;
+        }
+
+        if (batchedArgs == null) {
+            batchedArgs = BatchedArguments.create();
+        }
+
+        batchedArgs.add(currentArguments.toArray());
+        currentArguments = List.of();
     }
 
     /** {@inheritDoc} */
@@ -241,7 +293,7 @@ public class JdbcPreparedStatement2 extends JdbcStatement2 
implements PreparedSt
     public void clearBatch() throws SQLException {
         ensureNotClosed();
 
-        throw new UnsupportedOperationException("Batch operation");
+        batchedArgs = null;
     }
 
     /** {@inheritDoc} */
@@ -827,4 +879,14 @@ public class JdbcPreparedStatement2 extends JdbcStatement2 
implements PreparedSt
             throw new 
SQLFeatureNotSupportedException(SQL_SPECIFIC_TYPES_ARE_NOT_SUPPORTED);
         }
     }
+
+    private static int[] longsArrayToIntsArrayUnsafe(long[] longs) {
+        int[] ints = new int[longs.length];
+
+        for (int i = 0; i < longs.length; i++) {
+            ints[i] = (int) longs[i];
+        }
+
+        return ints;
+    }
 }
diff --git 
a/modules/jdbc/src/main/java/org/apache/ignite/internal/jdbc2/JdbcStatement2.java
 
b/modules/jdbc/src/main/java/org/apache/ignite/internal/jdbc2/JdbcStatement2.java
index be61cee9d73..ea7656ba575 100644
--- 
a/modules/jdbc/src/main/java/org/apache/ignite/internal/jdbc2/JdbcStatement2.java
+++ 
b/modules/jdbc/src/main/java/org/apache/ignite/internal/jdbc2/JdbcStatement2.java
@@ -46,6 +46,7 @@ import org.apache.ignite.sql.async.AsyncResultSet;
 import org.apache.ignite.table.mapper.Mapper;
 import org.apache.ignite.tx.Transaction;
 import org.jetbrains.annotations.Nullable;
+import org.jetbrains.annotations.TestOnly;
 
 /**
  * {@link Statement} implementation backed by the thin client.
@@ -83,9 +84,9 @@ public class JdbcStatement2 implements Statement {
     private static final String ONLY_FORWARD_DIRECTION_IS_SUPPORTED =
             "Only forward direction is supported.";
 
-    private final IgniteSql igniteSql;
+    final Connection connection;
 
-    private final Connection connection;
+    final IgniteSql igniteSql;
 
     private final String schemaName;
 
@@ -93,7 +94,7 @@ public class JdbcStatement2 implements Statement {
 
     private volatile @Nullable JdbcResultSet resultSet;
 
-    private int queryTimeoutSeconds;
+    private long queryTimeoutMillis;
 
     private int pageSize;
 
@@ -103,7 +104,7 @@ public class JdbcStatement2 implements Statement {
 
     private boolean closeOnCompletion;
 
-    private volatile @Nullable CancelHandle cancelHandle;
+    volatile @Nullable CancelHandle cancelHandle;
 
     JdbcStatement2(
             Connection connection,
@@ -166,25 +167,7 @@ public class JdbcStatement2 implements Statement {
             throw new UnsupportedOperationException("Multi-statements are not 
supported yet.");
         }
 
-        StatementBuilder stmtBuilder = igniteSql.statementBuilder()
-                .query(sql)
-                .defaultSchema(schemaName);
-
-        if (queryTimeoutSeconds > 0) {
-            stmtBuilder.queryTimeout(queryTimeoutSeconds, TimeUnit.SECONDS);
-        }
-
-        if (getFetchSize() > 0) {
-            stmtBuilder.pageSize(getFetchSize());
-        }
-
-        JdbcConnection2 conn = connection.unwrap(JdbcConnection2.class);
-        ZoneId zoneId = conn.properties().getConnectionTimeZone();
-
-        org.apache.ignite.sql.Statement igniteStmt = stmtBuilder
-                .timeZoneId(zoneId)
-                .build();
-
+        org.apache.ignite.sql.Statement igniteStmt = 
createIgniteStatement(sql);
         ClientSql clientSql = (ClientSql) igniteSql;
 
         // Cancel handle is not reusable, we should create a new one for each 
execution.
@@ -323,7 +306,7 @@ public class JdbcStatement2 implements Statement {
     public int getQueryTimeout() throws SQLException {
         ensureNotClosed();
 
-        return queryTimeoutSeconds;
+        return (int) TimeUnit.MILLISECONDS.toSeconds(queryTimeoutMillis);
     }
 
     /** {@inheritDoc} */
@@ -335,7 +318,7 @@ public class JdbcStatement2 implements Statement {
             throw new SQLException("Invalid timeout value.");
         }
 
-        this.queryTimeoutSeconds = timeout;
+        this.queryTimeoutMillis = TimeUnit.SECONDS.toMillis(timeout);
     }
 
     /** {@inheritDoc} */
@@ -670,6 +653,12 @@ public class JdbcStatement2 implements Statement {
         return iface != null && iface.isAssignableFrom(JdbcStatement2.class);
     }
 
+    /** Sets timeout in milliseconds. */
+    @TestOnly
+    public void timeout(long timeoutMillis) {
+        this.queryTimeoutMillis = timeoutMillis;
+    }
+
     protected boolean isQuery() {
         // This method is called after statement is executed, so the reference 
points to a correct result set.
         // The statement is not expected to be used from multiple threads, so 
this reference points to a correct result set.
@@ -680,6 +669,25 @@ public class JdbcStatement2 implements Statement {
         return rs.isQuery();
     }
 
+    org.apache.ignite.sql.Statement createIgniteStatement(String sql) throws 
SQLException {
+        StatementBuilder builder = igniteSql.statementBuilder()
+                .query(sql)
+                .defaultSchema(schemaName);
+
+        if (queryTimeoutMillis > 0) {
+            builder.queryTimeout(queryTimeoutMillis, TimeUnit.MILLISECONDS);
+        }
+
+        if (getFetchSize() > 0) {
+            builder.pageSize(getFetchSize());
+        }
+
+        JdbcConnection2 conn = connection.unwrap(JdbcConnection2.class);
+        ZoneId zoneId = conn.properties().getConnectionTimeZone();
+
+        return builder.timeZoneId(zoneId).build();
+    }
+
     void ensureNotClosed() throws SQLException {
         if (isClosed()) {
             throw new SQLException(STATEMENT_IS_CLOSED);
diff --git 
a/modules/spring/spring-data-ignite/src/test/java/org/apache/ignite/data/SpringDataJdbcTest.java
 
b/modules/spring/spring-data-ignite/src/test/java/org/apache/ignite/data/SpringDataJdbcTest.java
index c3d621a9091..33ae5acec66 100644
--- 
a/modules/spring/spring-data-ignite/src/test/java/org/apache/ignite/data/SpringDataJdbcTest.java
+++ 
b/modules/spring/spring-data-ignite/src/test/java/org/apache/ignite/data/SpringDataJdbcTest.java
@@ -40,7 +40,6 @@ import org.apache.ignite.internal.testframework.WorkDirectory;
 import org.apache.ignite.internal.testframework.WorkDirectoryExtension;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Disabled;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.TestInfo;
 import org.junit.jupiter.api.extension.ExtendWith;
@@ -71,7 +70,6 @@ import org.springframework.data.util.Streamable;
  */
 @SpringBootTest(classes = TestApplication.class)
 @ExtendWith(WorkDirectoryExtension.class)
-@Disabled("https://issues.apache.org/jira/browse/IGNITE-26190";)
 public class SpringDataJdbcTest extends BaseIgniteAbstractTest {
 
     @WorkDirectory

Reply via email to