Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Support Array conversion to ResultSet #326

Merged
merged 6 commits into from Feb 8, 2021
Merged

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.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

feat: support converting arrays to ResultSet
3 participants