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

[Java][FlightRPC] FlightSQL error: 'Parameter ordinal out of range' executing a prepared stmt with params #33475

Closed
asfimport opened this issue Nov 10, 2022 · 8 comments · Fixed by #38404

Comments

@asfimport
Copy link

Hey again :)

I'm getting a 'parameter ordinal 1 out of range' error trying to set a parameter on the returned AvaticaPreparedStatement. Repro:

  • Open a FlightSQL JDBC connection

  • conn.prepareStatement with a SQL query containing params (e.g. INSERT INTO users (id, name) VALUES (?, ?))

  • ps.setString(1, "foo") -> above error, thrown from AvaticaPreparedStatement.getParameter(int)

    I had a bit of a dig to try to identify a potential cause:

  • the Meta.Signature passed to the AvaticaPreparedStatement on creation has an empty parameter list - this is what causes the out-of-bounds error.

  • in ArrowFlightMetaImpl.prepare, it calls newSignature, but this only takes the SQL query, and so newSignature creates the signature with the empty list. The call to ArrowFlightSqlClientHandler.prepare happens on the line after - could we pass the param Schema from this result to newSignature?

Let me know if I can help narrow this down further or help with the fix :)

James

Reporter: James Henderson / @jarohen
Assignee: David Li / @lidavidm

PRs and other links:

Note: This issue was originally created as ARROW-18300. Please see the migration documentation for further details.

@asfimport
Copy link
Author

David Li / @lidavidm:
Thanks for the detailed reproduction.

This is going to take me a bit to fix, because it looks like parameters are straight up not implemented (ArrowFlightMetaImpl#execute ignores typedValues). So it'll take me a bit to put this together and ensure it's thoroughly tested.

@asfimport
Copy link
Author

James Henderson / @jarohen:
Thanks - yep, no worries, of course.

FWIW we can't return accurate parameter types at the point of creating a prepared statement - partly because XT is a dynamic database, but also partly because we're not sure it's possible in the general case:

  • For us, we can't accurately type the params in INSERT INTO users (id, name) VALUES (?, ?) because a user is allowed to put any value in those columns - aware we might be the exception to the rule on this one. We currently say that the param Schema has two columns, both of which are 0-leg dense unions, and then refine it when the user binds some parameters, but I'm not sure how viable that workaround might be long-term.
  • More generally, even in statically typed databases, (admittedly quite contrived) queries like SELECT ? FROM foo have untypable params - Postgres, for example, throws an error if you try to get the parameter metadata through JDBC for this one.

@asfimport
Copy link
Author

David Li / @lidavidm:
Yeah, and I think that's not been well-defined in the standard. ADBC, for what it's worth, uses NullType/NA to indicate that the parameter type is not known (though this is somewhat abusing the type system), and the SQLite example implementation of Flight SQL returns a dense union type (that's not really feasible if your type system is extensible like Postgres's, though).

@jduo any thoughts here? We should clarify this in the protocol specification.

@asfimport
Copy link
Author

David Li / @lidavidm:
I put up a draft PR: #14627

It doesn't yet handle the NullType/NA convention proposed above or any types besides String.

@asfimport
Copy link
Author

David Li / @lidavidm:
It looks like I'm not going to get any time to work on this in the near future. Let me know if you want to pick it up.

@avantgardnerio
Copy link

If it helps, I think it wouldn't be too hard to get Apache Ballista to return the correct schema to test against. We could definitely use this feature.

AFAICT, this:

Would need to call this:

And I have some code in a private repo that is providing the schema to be deserialized (DataFusion recently implemented type inference and a method to collect the inferred schema from the parameters)

CC @alamb

@avantgardnerio
Copy link

PTAL at #33961

@lidavidm lidavidm removed their assignment Aug 10, 2023
lidavidm pushed a commit that referenced this issue Nov 4, 2023
…C driver (#38404)

This PR is a combination of #33961 and #14627. The goal is to support parametrized queries through the Arrow Flight SQL JDBC driver.

An Arrow Flight SQL server returns a Schema for the `PreparedStatement` parameters. The driver then converts the `Field` list associated with the Schema into a list of `AvaticaParameter`. When the user sets values for the parameters, Avatica generates a list of `TypedValue`, which we then bind to each parameter vector. This conversion between Arrow and Avatica is handled by implementations of a `AvaticaParameterConverter` interface for each Arrow type. This interface which provides 2 methods:
- createParameter: Create an `AvaticaParameter` from the given Arrow `Field`.
- bindParameter: Cast the given `TypedValue` and bind it to the `FieldVector` at the specified index.

This PR purposely leaves out a few features:
- We currently naively cast the `TypedValue` values assuming users set the type correctly. If this cast fails, we raise an exception letting the user know that the cast is not supported. This could be improved in subsequent PRs to do smarter conversions from other types.
- We currently don't provide conversions for complex types such as List, Map, Struct, Union, Interval, and Duration. The stubs are there so they can be implemented as needed.
- Tests for specific types have not been implemented. I'm not very familiar with a lot of these JDBC types so it's hard to implement rigorous tets.

* Closes: #33475
* Closes: #35536

Authored-by: Diego Fernandez <aiguo.fernandez@gmail.com>
Signed-off-by: David Li <li.davidm96@gmail.com>
@lidavidm lidavidm added this to the 15.0.0 milestone Nov 4, 2023
@lidavidm
Copy link
Member

lidavidm commented Nov 4, 2023

@jarohen in case this interests you, @aiguofer pushed this across the finish line! However it currently depends on the server providing accurate types for the parameters, so there's still more that could be improved

loicalleyne pushed a commit to loicalleyne/arrow that referenced this issue Nov 13, 2023
…in JDBC driver (apache#38404)

This PR is a combination of apache#33961 and apache#14627. The goal is to support parametrized queries through the Arrow Flight SQL JDBC driver.

An Arrow Flight SQL server returns a Schema for the `PreparedStatement` parameters. The driver then converts the `Field` list associated with the Schema into a list of `AvaticaParameter`. When the user sets values for the parameters, Avatica generates a list of `TypedValue`, which we then bind to each parameter vector. This conversion between Arrow and Avatica is handled by implementations of a `AvaticaParameterConverter` interface for each Arrow type. This interface which provides 2 methods:
- createParameter: Create an `AvaticaParameter` from the given Arrow `Field`.
- bindParameter: Cast the given `TypedValue` and bind it to the `FieldVector` at the specified index.

This PR purposely leaves out a few features:
- We currently naively cast the `TypedValue` values assuming users set the type correctly. If this cast fails, we raise an exception letting the user know that the cast is not supported. This could be improved in subsequent PRs to do smarter conversions from other types.
- We currently don't provide conversions for complex types such as List, Map, Struct, Union, Interval, and Duration. The stubs are there so they can be implemented as needed.
- Tests for specific types have not been implemented. I'm not very familiar with a lot of these JDBC types so it's hard to implement rigorous tets.

* Closes: apache#33475
* Closes: apache#35536

Authored-by: Diego Fernandez <aiguo.fernandez@gmail.com>
Signed-off-by: David Li <li.davidm96@gmail.com>
dgreiss pushed a commit to dgreiss/arrow that referenced this issue Feb 19, 2024
…in JDBC driver (apache#38404)

This PR is a combination of apache#33961 and apache#14627. The goal is to support parametrized queries through the Arrow Flight SQL JDBC driver.

An Arrow Flight SQL server returns a Schema for the `PreparedStatement` parameters. The driver then converts the `Field` list associated with the Schema into a list of `AvaticaParameter`. When the user sets values for the parameters, Avatica generates a list of `TypedValue`, which we then bind to each parameter vector. This conversion between Arrow and Avatica is handled by implementations of a `AvaticaParameterConverter` interface for each Arrow type. This interface which provides 2 methods:
- createParameter: Create an `AvaticaParameter` from the given Arrow `Field`.
- bindParameter: Cast the given `TypedValue` and bind it to the `FieldVector` at the specified index.

This PR purposely leaves out a few features:
- We currently naively cast the `TypedValue` values assuming users set the type correctly. If this cast fails, we raise an exception letting the user know that the cast is not supported. This could be improved in subsequent PRs to do smarter conversions from other types.
- We currently don't provide conversions for complex types such as List, Map, Struct, Union, Interval, and Duration. The stubs are there so they can be implemented as needed.
- Tests for specific types have not been implemented. I'm not very familiar with a lot of these JDBC types so it's hard to implement rigorous tets.

* Closes: apache#33475
* Closes: apache#35536

Authored-by: Diego Fernandez <aiguo.fernandez@gmail.com>
Signed-off-by: David Li <li.davidm96@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants