|
26 | 26 | import static org.junit.jupiter.api.Assertions.assertSame; |
27 | 27 | import static org.junit.jupiter.api.Assertions.assertThrows; |
28 | 28 | import static org.junit.jupiter.api.Assertions.assertTrue; |
| 29 | +import static org.mockito.Mockito.doThrow; |
| 30 | +import static org.mockito.Mockito.mock; |
29 | 31 |
|
30 | 32 | import java.nio.charset.StandardCharsets; |
31 | 33 | import java.sql.Connection; |
|
52 | 54 | import org.apache.arrow.vector.types.pojo.FieldType; |
53 | 55 | import org.apache.arrow.vector.types.pojo.Schema; |
54 | 56 | import org.apache.arrow.vector.util.Text; |
| 57 | +import org.apache.calcite.avatica.AvaticaResultSet; |
| 58 | +import org.apache.calcite.avatica.AvaticaStatement; |
55 | 59 | import org.junit.jupiter.api.AfterAll; |
56 | 60 | import org.junit.jupiter.api.BeforeAll; |
57 | 61 | import org.junit.jupiter.api.BeforeEach; |
@@ -177,6 +181,82 @@ public void testPrepareFailureIsReportedAsSQLException() { |
177 | 181 | assertThat(exception.getCause(), instanceOf(FlightRuntimeException.class)); |
178 | 182 | } |
179 | 183 |
|
| 184 | + @Test |
| 185 | + public void testNullQueryIsReportedAsSQLException() { |
| 186 | + final SQLException exception = |
| 187 | + assertThrows(SQLException.class, () -> connection.prepareStatement(null)); |
| 188 | + |
| 189 | + assertThat(exception.getCause(), instanceOf(NullPointerException.class)); |
| 190 | + } |
| 191 | + |
| 192 | + @Test |
| 193 | + public void testCloseReleasesPreparedResourcesWhenResultSetCloseFails() throws Exception { |
| 194 | + try (final ArrowFlightConnection localConnection = |
| 195 | + (ArrowFlightConnection) FLIGHT_SERVER_TEST_EXTENSION.getConnection(false)) { |
| 196 | + final ArrowFlightPreparedStatement preparedStatement = |
| 197 | + (ArrowFlightPreparedStatement) |
| 198 | + localConnection.prepareStatement(CoreMockedSqlProducers.LEGACY_REGULAR_SQL_CMD); |
| 199 | + final AvaticaResultSet resultSet = mock(AvaticaResultSet.class); |
| 200 | + final RuntimeException resultSetCloseFailure = |
| 201 | + new RuntimeException("Result set close failed"); |
| 202 | + doThrow(resultSetCloseFailure).when(resultSet).close(); |
| 203 | + final java.lang.reflect.Field openResultSetField = |
| 204 | + AvaticaStatement.class.getDeclaredField("openResultSet"); |
| 205 | + openResultSetField.setAccessible(true); |
| 206 | + openResultSetField.set(preparedStatement, resultSet); |
| 207 | + |
| 208 | + final SQLException exception = assertThrows(SQLException.class, preparedStatement::close); |
| 209 | + |
| 210 | + assertSame(resultSetCloseFailure, exception.getCause()); |
| 211 | + assertTrue(preparedStatement.isClosed()); |
| 212 | + assertEquals( |
| 213 | + 1, |
| 214 | + PRODUCER |
| 215 | + .getActionTypeCounter() |
| 216 | + .getOrDefault(FlightSqlUtils.FLIGHT_SQL_CLOSE_PREPARED_STATEMENT.getType(), 0)); |
| 217 | + } |
| 218 | + } |
| 219 | + |
| 220 | + @Test |
| 221 | + public void testMetaRejectsForeignStatementHandle() throws SQLException { |
| 222 | + try (final ArrowFlightConnection firstConnection = |
| 223 | + (ArrowFlightConnection) FLIGHT_SERVER_TEST_EXTENSION.getConnection(false); |
| 224 | + final ArrowFlightConnection secondConnection = |
| 225 | + (ArrowFlightConnection) FLIGHT_SERVER_TEST_EXTENSION.getConnection(false); |
| 226 | + final PreparedStatement firstStatement = |
| 227 | + firstConnection.prepareStatement(CoreMockedSqlProducers.LEGACY_REGULAR_SQL_CMD); |
| 228 | + final PreparedStatement secondStatement = |
| 229 | + secondConnection.prepareStatement( |
| 230 | + CoreMockedSqlProducers.UUID_PREPARED_SELECT_SQL_CMD)) { |
| 231 | + final ArrowFlightPreparedStatement firstPreparedStatement = |
| 232 | + (ArrowFlightPreparedStatement) firstStatement; |
| 233 | + final ArrowFlightPreparedStatement secondPreparedStatement = |
| 234 | + (ArrowFlightPreparedStatement) secondStatement; |
| 235 | + assertEquals(firstPreparedStatement.handle.id, secondPreparedStatement.handle.id); |
| 236 | + |
| 237 | + assertThrows( |
| 238 | + IllegalArgumentException.class, |
| 239 | + () -> firstConnection.getMeta().closeStatement(secondPreparedStatement.handle)); |
| 240 | + assertFalse(firstPreparedStatement.isClosed()); |
| 241 | + } |
| 242 | + } |
| 243 | + |
| 244 | + @Test |
| 245 | + public void testMetaRejectsForeignConnectionHandle() throws SQLException { |
| 246 | + try (final ArrowFlightConnection firstConnection = |
| 247 | + (ArrowFlightConnection) FLIGHT_SERVER_TEST_EXTENSION.getConnection(false); |
| 248 | + final ArrowFlightConnection secondConnection = |
| 249 | + (ArrowFlightConnection) FLIGHT_SERVER_TEST_EXTENSION.getConnection(false)) { |
| 250 | + assertThrows( |
| 251 | + IllegalArgumentException.class, |
| 252 | + () -> |
| 253 | + firstConnection |
| 254 | + .getMeta() |
| 255 | + .prepare( |
| 256 | + secondConnection.handle, CoreMockedSqlProducers.LEGACY_REGULAR_SQL_CMD, -1)); |
| 257 | + } |
| 258 | + } |
| 259 | + |
180 | 260 | @Test |
181 | 261 | public void testQueryWithParameterBinding() throws SQLException { |
182 | 262 | final String query = "Fake query with parameters"; |
|
0 commit comments