Skip to content

Conversation

@olavloite
Copy link
Collaborator

@olavloite olavloite commented Jan 18, 2021

JDBC arrays have an optional method that allow them to be converted to ResultSets. This method was not implemented for the Cloud Spanner JDBC driver. This would cause DBeaver to not be able to fetch and view the data of NUMERIC columns, as DBeaver would use this method for specifically those columns (other array columns would work). This PR fixes that specific problem and allows other users to use this convenience method for all array types.

Fixes #332

Screenshot from 2021-01-18 12-44-51

JDBC arrays can optionally be converted to ResultSets. This feature was not implemented for the Cloud Spanner JDBC driver. This would cause DBeaver to show an error message instead of the actual data when fetching a NUMERIC array. Other arrays would be fetched correctly by DBeaver, as those array types do not use the conversion to a ResultSet.
@olavloite olavloite requested a review from a team as a code owner January 18, 2021 11:49
@product-auto-label product-auto-label bot added the api: spanner Issues related to the googleapis/java-spanner-jdbc API. label Jan 18, 2021
@google-cla google-cla bot added the cla: yes This human has signed the Contributor License Agreement. label Jan 18, 2021
@codecov
Copy link

codecov bot commented Jan 18, 2021

Codecov Report

Merging #326 (c15ebed) into master (250c4c1) will increase coverage by 0.67%.
The diff coverage is 83.33%.

Impacted file tree graph

@@ Coverage Diff @@ ## master #326 +/- ## ============================================ + Coverage 71.35% 72.02% +0.67%  - Complexity 1114 1131 +17  ============================================ Files 24 24 Lines 3474 3518 +44 Branches 531 537 +6 ============================================ + Hits 2479 2534 +55  + Misses 778 765 -13  - Partials 217 219 +2 
Impacted Files Coverage Δ Complexity Δ
.../java/com/google/cloud/spanner/jdbc/JdbcArray.java 71.81% <83.33%> (+15.75%) 28.00 <14.00> (+15.00)
...a/com/google/cloud/spanner/jdbc/JdbcResultSet.java 75.34% <0.00%> (+0.54%) 190.00% <0.00%> (+2.00%)
...va/com/google/cloud/spanner/jdbc/JdbcDataType.java 75.80% <0.00%> (+17.74%) 4.00% <0.00%> (ø%)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 250c4c1...8a46d00. Read the comment docs.

Copy link

@elharo elharo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds reasonable, but could probably use an issue for tracking and release notes

public ResultSet getResultSet(long index, int count) throws SQLException {
throw new SQLFeatureNotSupportedException(RESULTSET_NOT_SUPPORTED);
public ResultSet getResultSet(long startIndex, int count) throws SQLException {
JdbcPreconditions.checkArgument(
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not just Preconditions and an IllegalArgumentException?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because the JDBC specification requires the driver to throw an instance of SQLException if the input is invalid. This applies to (almost) all methods defined by the JDBC specification, hence the separate JdbcPreconditions helper class.

assertThat(array.getBaseType()).isEqualTo(Types.BOOLEAN);
assertThat(((Boolean[]) array.getArray(1, 1))[0]).isEqualTo(Boolean.TRUE);
try (ResultSet rs = array.getResultSet()) {
assertThat(rs.next()).isTrue();
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not just assertEquals and assertTrue?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This library (and also the Java Spanner client) mostly use Truth for assertions, but some of the older classes use JUnit assertions. To reduce the mixing of the two, I tend to change the older classes to Truth when (larger) changes are made to them.

case TIMESTAMP:
builder = binder.to(JdbcTypeConverter.toGoogleTimestamp((Timestamp) value));
break;
case ARRAY:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we create tests for the ARRAY, STRUCT and default cases?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's not really possible, because it is impossible to create an array with an invalid data type. It will fail already during creation, but I've added a couple of tests to verify that.

Copy link
Contributor

@thiagotnunes thiagotnunes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@thiagotnunes thiagotnunes merged commit 6ea0a26 into master Feb 8, 2021
@thiagotnunes thiagotnunes deleted the array-to-resultset branch February 8, 2021 01:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

api: spanner Issues related to the googleapis/java-spanner-jdbc API. cla: yes This human has signed the Contributor License Agreement.

4 participants