Search code examples
dockertestngintegration-testingresultsetpresto

Processing Presto ResultSet in Java: 'SQLException: Not on a valid row'


My Presto plugin has two components:

  • An EventListener that logs stats of queries made to Presto
  • Some UDFs for hashing (MD5, SHA1) common datatypes (varchar, long) and returning result as varchar

I've already done:

  • Integration-test (mvn verify) of query-logging component
  • Unit-test of hashing UDFs

In integration test of UDF component, I'm tyring to assert value returned by my UDF by firing a query

Connection connection = DriverManager.getConnection(PRESTO_URL, PRESTO_USER, PRESTO_PASSWORD);
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery("SELECT SHA1(9223372036854775807) AS hash");
assertEquals("458B642B137E2C76E0B746C6FA43E64C3D4C47F1", resultSet.getString("hash"));

This gives following stack-trace (PrestoResultSet.checkValidRow)

NOTE: ExtendedHashFunctionsTestIT.java:39 line is the one containing resultSet.getString(..)

java.sql.SQLException: Not on a valid row
    at com.facebook.presto.jdbc.PrestoResultSet.checkValidRow(PrestoResultSet.java:1658)
    at com.facebook.presto.jdbc.PrestoResultSet.column(PrestoResultSet.java:1690)
    at com.facebook.presto.jdbc.PrestoResultSet.getString(PrestoResultSet.java:370)
    at com.company.plugin.it.udfs.scalar.hash.ExtendedHashFunctionsTestIT.testBody(ExtendedHashFunctionsTestIT.java:39)
    at com.company.plugin.it.AbstractIntegrationTest.test(AbstractIntegrationTest.java:77)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:85)
    at org.testng.internal.Invoker.invokeMethod(Invoker.java:639)
    at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:816)
    at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1124)
    at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:125)
    at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:108)
    at org.testng.TestRunner.privateRun(TestRunner.java:774)
    at org.testng.TestRunner.run(TestRunner.java:624)
    at org.testng.SuiteRunner.runTest(SuiteRunner.java:359)
    at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:354)
    at org.testng.SuiteRunner.privateRun(SuiteRunner.java:312)
    at org.testng.SuiteRunner.run(SuiteRunner.java:261)
    at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
    at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
    at org.testng.TestNG.runSuitesSequentially(TestNG.java:1191)
    at org.testng.TestNG.runSuitesLocally(TestNG.java:1116)
    at org.testng.TestNG.run(TestNG.java:1024)
    at org.apache.maven.surefire.testng.TestNGExecutor.run(TestNGExecutor.java:62)
    at org.apache.maven.surefire.testng.TestNGDirectoryTestSuite.execute(TestNGDirectoryTestSuite.java:141)
    at org.apache.maven.surefire.Surefire.run(Surefire.java:180)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.apache.maven.surefire.booter.SurefireBooter.runSuitesInProcess(SurefireBooter.java:350)
    at org.apache.maven.surefire.booter.SurefireBooter.main(SurefireBooter.java:1021)

I'm perplexed because error occurs only when I try to access ResultSet; commenting out the assertEquals(..) statement lets the test run successfully.

What's even more disturbing is that stack-trace is same for virtually any query:

  • SELECT 'some_string' AS some_alias
  • SHOW SCHEMAS

I'm using Spotify's dockerfile-maven-plugin for the tests. I've put up relevant files in this GitHub Gist

  • ExtendedHashFunctionsTestIT.java (simplified integration-test file)
  • pom.xml
  • Dockerfile

Solution

  • It laments me to think that the mistake that ate up my 2 days was this

    Connection connection = DriverManager.getConnection(PRESTO_URL, PRESTO_USER, PRESTO_PASSWORD);
    Statement statement = connection.createStatement();
    ResultSet resultSet = statement.executeQuery("SELECT SHA1(9223372036854775807) AS hash");
    resultSet.next();
    assertEquals("458B642B137E2C76E0B746C6FA43E64C3D4C47F1", resultSet.getString("hash"));
    

    That 4th line: I had missed resultSet.next() prior to resultSet.getString(..) :-(