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

Add support for prepared statements in JDBC #3116

Open
wants to merge 13 commits into
base: main
Choose a base branch
from

Conversation

ohadzeliger
Copy link
Contributor

@ohadzeliger ohadzeliger commented Feb 6, 2025

This PR enables support for prepared statements on the JDBC server.
Specifically, support for PreparedStatement setObject() and setArray().
Also, JDBCRelationalConnection needed support for array creation.
A slew of type conversion utilities were added in support of these features.
In general, we have 3 models that we are dealing with:

  • Java (including primitives, [], null)
  • JDBC (including primitive, Array, Struct, NULL)
  • Protobuf

And because of the way the API is structured, we may need to perform conversions between all 3. Specifically, we support the following:

  • Java and SQL primitives are treated the same way
  • Java arrays are only supported in Connection.createArrayOf, where the type of array elements is also provided
  • SQL Array and Struct are assumed in all cases of nesting. That is, an array of elements would be assumed to have SQL Array if there is any nested array. The reasoning is that we would need the additional type information in these cases
    Some cleanup and restructuring of that code may be warranted, in addition to null, error and edge case testing.

The protobuf for the Array definition was changed in order to support the extra type information.
The change was made to be backwards compatible at the protobuf level but the old server (before this change) cannot handle arrays in parameters. In order to facilitate multi-version testing against the older servers we may be able to cherry-pick these commits to the server's branch.

@ohadzeliger ohadzeliger changed the title Initial implementation of prepared statement support in JDBC Add support for prepared statements in JDBC Feb 6, 2025
@ohadzeliger ohadzeliger marked this pull request as ready for review February 7, 2025 14:11
case Types.DOUBLE:
return column.getDouble();
default:
// TODO: NULL?
Copy link
Collaborator

Choose a reason for hiding this comment

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

"enum" is also missing from this, but enum support in general is awaiting: #3074

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Is #3074 going to be merged in soon? If so, I can add support here after it was merged.

Copy link
Collaborator

Choose a reason for hiding this comment

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

#3074 merged, but I don't know that we need to add support here, now.

Comment on lines +35 to +37
* TODO: We can't use the other implementation of array in {@link RelationalArrayFacade} as it makes several assumptions
* that would be incompatible with the need to transfer an array across the wire (e.g. the type of element is missing,
* {@link RelationalArrayFacade#getArray()} returns a type other than a Java array).
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why create a new implementation rather than changing RelationalArrayFacade? It seems like the two are trying to accomplish the same thing.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I wanted to reduce risk: RelationalArrayFacade is used in many places and reimplementing it as part of this PR would require many changes (potentially).

Copy link
Collaborator

Choose a reason for hiding this comment

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

I'm still not sure I follow, I'll reach out offline.

@@ -49,7 +49,10 @@ message Struct {

// Relational Array.
message Array {
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think by making this a backward compatible change, and if the elementType is set (non-zero), the client will just get the type from the columns.
I think this shouldn't be much work, and would allow us to keep the mixed-mode testing for returning arrays.

Copy link
Contributor Author

@ohadzeliger ohadzeliger Feb 11, 2025

Choose a reason for hiding this comment

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

Making the changes allows arrays.yamsql to run, however prepared.yamsql still fails: The server-side code to deserialize (FRL.java:254) cannot handle an ARRAY type required by the tests.
We may cherry pick this PR to the earlier branch if we want to allow these tests to run against older seervers

return fromArray(column.getArray());
case Types.BIGINT:
checkColumnType(columnType, column.hasLong());
Copy link
Collaborator

Choose a reason for hiding this comment

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

Does this work correctly if the column has the default value for the desired item, i.e. 0 for a long, or an int, or an empty string?

case Types.DOUBLE:
return column.getDouble();
default:
// TODO: NULL?
Copy link
Collaborator

Choose a reason for hiding this comment

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

#3074 merged, but I don't know that we need to add support here, now.

@@ -58,6 +58,7 @@ test_block:
-
# correlation are allowed in from-subquery.
- query: select x, sq.idr, sq.nr from a, (select * from r where r.idr = a.x) sq;
- supported_version: !current_version # changes in Proto definition for arrays
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can this be removed?

Comment on lines +35 to +37
* TODO: We can't use the other implementation of array in {@link RelationalArrayFacade} as it makes several assumptions
* that would be incompatible with the need to transfer an array across the wire (e.g. the type of element is missing,
* {@link RelationalArrayFacade#getArray()} returns a type other than a Java array).
Copy link
Collaborator

Choose a reason for hiding this comment

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

I'm still not sure I follow, I'll reach out offline.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants