Skip to content

Commit 156b465

Browse files
authored
GH-797: [JDBC] Fix PreparedStatement#execute for DML/DDL (#811)
## What's Changed Instead of always obtaining a result set for queries issued via PreparedStatement.execute(), we now inspect the dataset_schema returned in ActionCreatePreparedStatementResult. If the schema has no fields, we retrieve the update count instead. This aligns the return value with the expectations of the JDBC API. For such cases, the Arrow Flight SQL path now uses CommandPreparedStatementUpdate instead of CommandPreparedStatementQuery. This change mirrors the existing approach in Statement.execute() and Statement.executeUpdate(). ### Are these changes tested? Yes Closes #797.
1 parent 52f7a86 commit 156b465

File tree

2 files changed

+36
-3
lines changed

2 files changed

+36
-3
lines changed

flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/ArrowFlightMetaImpl.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,14 +62,17 @@ static Signature newSignature(final String sql, Schema resultSetSchema, Schema p
6262
parameterSchema == null
6363
? new ArrayList<>()
6464
: ConvertUtils.convertArrowFieldsToAvaticaParameters(parameterSchema.getFields());
65-
65+
StatementType statementType =
66+
resultSetSchema == null || resultSetSchema.getFields().isEmpty()
67+
? StatementType.IS_DML
68+
: StatementType.SELECT;
6669
return new Signature(
6770
columnMetaData,
6871
sql,
6972
parameters,
7073
Collections.emptyMap(),
7174
null, // unnecessary, as SQL requests use ArrowFlightJdbcCursor
72-
StatementType.SELECT);
75+
statementType);
7376
}
7477

7578
@Override
@@ -105,7 +108,8 @@ public ExecuteResult execute(
105108
preparedStatement, ((ArrowFlightConnection) connection).getBufferAllocator())
106109
.bind(typedValues);
107110

108-
if (statementHandle.signature == null) {
111+
if (statementHandle.signature == null
112+
|| statementHandle.signature.statementType == StatementType.IS_DML) {
109113
// Update query
110114
long updatedCount = preparedStatement.executeUpdate();
111115
return new ExecuteResult(

flight/flight-sql-jdbc-core/src/test/java/org/apache/arrow/driver/jdbc/ArrowFlightPreparedStatementTest.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
import static org.hamcrest.MatcherAssert.assertThat;
2121
import static org.junit.jupiter.api.Assertions.assertAll;
2222
import static org.junit.jupiter.api.Assertions.assertEquals;
23+
import static org.junit.jupiter.api.Assertions.assertFalse;
24+
import static org.junit.jupiter.api.Assertions.assertTrue;
2325

2426
import java.nio.charset.StandardCharsets;
2527
import java.sql.Connection;
@@ -83,6 +85,19 @@ public void testSimpleQueryNoParameterBinding() throws SQLException {
8385
}
8486
}
8587

88+
@Test
89+
public void testSimpleQueryNoParameterBindingWithExecute() throws SQLException {
90+
final String query = CoreMockedSqlProducers.LEGACY_REGULAR_SQL_CMD;
91+
try (final PreparedStatement preparedStatement = connection.prepareStatement(query)) {
92+
boolean isResultSet = preparedStatement.execute();
93+
assertTrue(isResultSet);
94+
final ResultSet resultSet = preparedStatement.getResultSet();
95+
CoreMockedSqlProducers.assertLegacyRegularSqlResultSet(resultSet);
96+
assertFalse(preparedStatement.getMoreResults());
97+
assertEquals(-1, preparedStatement.getUpdateCount());
98+
}
99+
}
100+
86101
@Test
87102
public void testQueryWithParameterBinding() throws SQLException {
88103
final String query = "Fake query with parameters";
@@ -174,6 +189,20 @@ public void testUpdateQuery() throws SQLException {
174189
}
175190
}
176191

192+
@Test
193+
public void testUpdateQueryWithExecute() throws SQLException {
194+
String query = "Fake update with execute";
195+
PRODUCER.addUpdateQuery(query, /*updatedRows*/ 42);
196+
try (final PreparedStatement stmt = connection.prepareStatement(query)) {
197+
boolean isResultSet = stmt.execute();
198+
assertFalse(isResultSet);
199+
int updated = stmt.getUpdateCount();
200+
assertEquals(42, updated);
201+
assertFalse(stmt.getMoreResults());
202+
assertEquals(-1, stmt.getUpdateCount());
203+
}
204+
}
205+
177206
@Test
178207
public void testUpdateQueryWithParameters() throws SQLException {
179208
String query = "Fake update with parameters";

0 commit comments

Comments
 (0)