Skip to content

Commit 82bebb5

Browse files
committed
[CALCITE-6781] The isUpdateCapable method of calcite.avatica will incorrectly traverse the returned result value
1 parent 8f2b775 commit 82bebb5

2 files changed

Lines changed: 58 additions & 11 deletions

File tree

core/src/main/java/org/apache/calcite/avatica/AvaticaConnection.java

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -614,18 +614,19 @@ private void isUpdateCapable(final AvaticaStatement statement)
614614
return;
615615
}
616616
if (signature.statementType.canUpdate() && statement.updateCount == -1) {
617-
statement.openResultSet.next();
618-
Object obj = statement.openResultSet.getObject(ROWCOUNT_COLUMN_NAME);
619-
if (obj instanceof Number) {
620-
statement.updateCount = ((Number) obj).intValue();
621-
} else if (obj instanceof List) {
622-
@SuppressWarnings("unchecked")
623-
final List<Number> numbers = (List<Number>) obj;
624-
statement.updateCount = numbers.get(0).intValue();
625-
} else {
626-
throw HELPER.createException("Not a valid return result.");
617+
if (statement.openResultSet.next()) {
618+
Object obj = statement.openResultSet.getObject(ROWCOUNT_COLUMN_NAME);
619+
if (obj instanceof Number) {
620+
statement.updateCount = ((Number) obj).intValue();
621+
} else if (obj instanceof List) {
622+
@SuppressWarnings("unchecked")
623+
final List<Number> numbers = (List<Number>) obj;
624+
statement.updateCount = numbers.get(0).intValue();
625+
} else {
626+
throw HELPER.createException("Not a valid return result.");
627+
}
628+
statement.openResultSet = null;
627629
}
628-
statement.openResultSet = null;
629630
}
630631
}
631632

core/src/test/java/org/apache/calcite/avatica/AvaticaConnectionTest.java

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,10 @@
2020
import org.junit.Test;
2121
import org.mockito.Mockito;
2222

23+
import java.lang.reflect.InvocationTargetException;
24+
import java.lang.reflect.Method;
2325
import java.sql.SQLException;
26+
import java.util.Collections;
2427
import java.util.Properties;
2528

2629
/**
@@ -71,6 +74,49 @@ public void testNumExecuteRetries() {
7174
Assert.assertEquals(10, connection.getNumStatementRetries(props));
7275
}
7376

77+
/** Test case for
78+
* <a href="https://issues.apache.org/jira/browse/CALCITE-6781">[CALCITE-6781]
79+
* The isUpdateCapable method of calcite.avatica will incorrectly traverse
80+
* the returned result value</a>.
81+
*/
82+
@Test
83+
public void testIsUpdateCapableSkipsRowCountWhenResultSetHasNoRows() throws Exception {
84+
AvaticaConnection connection = Mockito.mock(
85+
AvaticaConnection.class, Mockito.CALLS_REAL_METHODS);
86+
AvaticaStatement statement = Mockito.mock(AvaticaStatement.class);
87+
AvaticaResultSet resultSet = Mockito.mock(AvaticaResultSet.class);
88+
89+
Meta.Signature signature = new Meta.Signature(Collections.<ColumnMetaData>emptyList(), null,
90+
Collections.<AvaticaParameter>emptyList(), Collections.<String, Object>emptyMap(), null,
91+
Meta.StatementType.INSERT);
92+
93+
Mockito.when(statement.getSignature()).thenReturn(signature);
94+
Mockito.when(resultSet.next()).thenReturn(false);
95+
statement.updateCount = -1;
96+
statement.openResultSet = resultSet;
97+
98+
invokeIsUpdateCapable(connection, statement);
99+
100+
Assert.assertEquals(-1, statement.updateCount);
101+
Assert.assertSame(resultSet, statement.openResultSet);
102+
Mockito.verify(resultSet, Mockito.never()).getObject(AvaticaConnection.ROWCOUNT_COLUMN_NAME);
103+
}
104+
105+
private static void invokeIsUpdateCapable(
106+
AvaticaConnection connection, AvaticaStatement statement) throws Exception {
107+
Method method = AvaticaConnection.class
108+
.getDeclaredMethod("isUpdateCapable", AvaticaStatement.class);
109+
method.setAccessible(true);
110+
try {
111+
method.invoke(connection, statement);
112+
} catch (InvocationTargetException e) {
113+
if (e.getCause() instanceof SQLException) {
114+
throw (SQLException) e.getCause();
115+
}
116+
throw e;
117+
}
118+
}
119+
74120
}
75121

76122
// End AvaticaConnectionTest.java

0 commit comments

Comments
 (0)