snowflakedb/snowflake-jdbc

The `errorCode` and `errorMessage` fields of `QueryStatus` enum are not thread-safe

Closed this issue · 8 comments

arouel commented
  1. What version of JDBC driver are you using?

3.13.30

  1. What operating system and processor architecture are you using?

Any OS

  1. What version of Java are you using?

Java 17

  1. What did you do?

Running many Snowflake queries concurrently.

  1. What did you expect to see?

When multiple queries fail at the same time, the errorCode and errorMessage of the QueryStatus should contain the correct error as seen in the query history, but may contain another error code and error message from a different query that failed at the same time.

  1. Can you set logging to DEBUG and collect the logs?

No

  1. What is your Snowflake account identifier, if any? (Optional)

Thanks for reporting it @arouel , PR is being reviewed internally.
CC: @sfc-gh-igarish, since I see you already are looking at it.

Added comments to the PR. Still in review.

Ask PR filer to answer the questions in the PR.

@sfc-gh-pfus Could you please check the PR and finish merging it? Josh Zana from apps team need this merge to the code line. If you are buys we can assign to other teammates.

@sfc-gh-jzana The filer doesn't give the test case to repro and then test after the fix. Can we get it? Are we sharing connection between threads?

@sfc-gh-igarish It shouldn't matter whether the connection is shared across threads., Doesn't even require multiple threads for that matter. This is because each enum value of QueryStatus is a singleton, but it tries to temporarily store per-request code and message on the singleton instance.

The test case would look something like this psuedocode:

// start two async queries
queryId1 = executeQuery(<some query that will produce an error>)
queryId2 = executeQuery(<a different query that will produce a different error>)

// Get status on each one once they are both done
queryStatus1 = getQueryStatus(queryId1)
queryStatus2 = getQueryStatus(queryId2)

You would expect that after this, queryStatus1 would have the error message appropriate to queryId1

With the current code, it will not, because the second call will overwrite the error message on the singleton instance of QueryStatus.FAILED_WITH_ERROR

The PR was merged and should be the part of the January release.

Fix is part of snowflake-jdbc in version 3.14.5