Skip to content

Druid improperly closes a JDBC Statement on executeQuery() error #12684

@paul-rogers

Description

@paul-rogers

Affected Version

Latest master version.

Description

According to the JDBC 4.1 Spec, a JDBC Statement is closed when:

An application calls the method Statement.close to indicate that it has finished processing a statement. All Statement objects will be closed when the connection that created them is closed.

This means that, if a statement encounters an exception, we can close the ResultSet associated with a statement, but not the statement itself. Yet, Druid explicitly closes statements on errors. Consider this test in DruidAvaticaHandlerTest:

  @Test
  public void testNotTooManyStatementsWhenTheyThrowErrors() throws Exception
  {
    for (int i = 0; i < 50; i++) {
      Exception thrown = null;
      try {
        client.createStatement().executeQuery("SELECT SUM(nonexistent) FROM druid.foo");
      }
      catch (Exception e) {
        thrown = e;
      }

      Assert.assertNotNull(thrown);
    }
  }

The only way the above could work is if executeQuery() closes the statement, which it should not do. The failure can close the associated ResultSet.

The test should be coded as:

  @Test
  public void testNotTooManyStatementsWhenClosed() throws Exception
  {
    for (int i = 0; i < 50; i++) {
      Exception thrown = null;
      try (Statement statement = client.createStatement()) {
        statement.executeQuery("SELECT SUM(nonexistent) FROM druid.foo");
      }
      catch (Exception e) {
        thrown = e;
      }

      Assert.assertNotNull(thrown);
    }
  }

Solution

This issue is fixed in PR #12636.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions