-
Notifications
You must be signed in to change notification settings - Fork 57
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
User Defined Type (UDT) Out Parameters #272
Comments
We introduced with version 0.9 a
The spec contains also a bit of documentation regarding out parameters and type references. The Postgres driver uses this feature to reference UDTs. The type lookup is however vendor-specific and we never really considered a mapping API/registry for types. That could be an inspiration for the next major revision of R2DBC. Let me know whether that helps. |
I like the idea of using io.r2dbc.spi.Type to represent UDTs. As an Oracle specific extension, I'm considering a factory method like this: /**
* Returns a {@code Type} representing a user defined type.
* @param type The base type
* @param name The type name
public Type userDefined(Type type, String name) {
...
} This lets the application code express the same information as JDBC's registerOutParameter method: A base type, and a user defined name. It might be used like this: connection.createStatement("{? = call CREATE_A_PERSON (?)}")
.bind(0, Parameters.out(
OracleR2dbcTypes.userDefined(OracleR2dbcTypes.STRUCT, "UDO_PERSON")))
.bind(1, "YOURE NAME")
.execute(); I'm confused about what is meant by "mapping API/registry". In this case, I'm just considering how application code would express the name of a user defined type. JDBC choose to codify that as a part of its standard, with registerOutParameter accepting a name parameter. If multiple R2DBC drivers need to support named types, then a standard way to do that could be beneficial, as it would allow for code that is portable across drivers. A SPI extension that is specific to Oracle R2DBC is fine for now. But if we end up with multiple drivers exposing different ways to express named types, then a common interface might be a better solution. |
Sorry, I wasn't clear. Something along the lines of |
Thanks, I understand what you mean now, and I like the idea of a type lookup method. |
Good catch, I was too quick capturing my idea. Indeed, |
Are you folks sure this is what should be done here? In JDBC, the |
Perhaps we should use this thread to explore the larger idea of supporting UDTs? I originally just wanted support for the highly specific case of a UDT out parameter bind. But really there's more to this: What Java type is that out parameter mapped to? I think JDBC would answer that question with "java.sql.Struct or the connection type map". And yes, set/getTypeMap should be a purely client side operation; No publisher needed for that. But for this proposed I have to admit that my knowledge on JDBC's support for structured types is weak. I'm planning to dig in to it more in the coming weeks. At the moment, I'm super busy with other projects. I'd like to contribute more once things settle down. |
I definitely think so. This shouldn't be addressed merely in the context of procedure parameters. JDBC has 2 ways of interacting with UDTs:
I personally think that the second approach should not have been added to JDBC. It feels rather weird, has a few important flaws (e.g. I've never had the need for any round-trip inducing A bit of additional background on UDTs: While ojdbc implemented JDBC completely in this area and probably also designed these ORDBMS features both in JDBC and in the SQL standard, PostgreSQL has a more elegant view on the topic. In PostgreSQL, table row types are also "UDTs", so for example, you can write things like: SELECT actor FROM actor;
SELECT ROW(id, first_name, last_name)::actor FROM actor; In both cases, you'll get a nested record / UDT style data structure of type SELECT ROW(id, first_name, last_name) FROM actor; Now, the UDT is only structurally typed, not nominally typed. Informix also works more or less this way, and I think it would make sense for Oracle Database to also add these features to consolidate and follow the SQL standard more closely (though I don't think it will be a priority any time soon). So, a UDT is just a nominally typed ROW, very similar to |
I've decided to add support for UDTs in the Oracle driver. If anyone is curious about that, they can see the changes here: Thank you @mp911de and @lukaseder for the discussion on this thread. I found it to be very helpful when making some decisions for the Oracle driver. |
Thanks for the ping. I have a TODO to look into these integrations sometime soon, as a customer is interested. |
Good to hear. Feedback from library authors such as your selves is truly invaluable. I did my best to get the API right for Oracle, but please let me know if you think there's anything we do better. |
JDBC has registerOutParameter methods on CallableStatement which accept a type name:
https://docs.oracle.com/javase/8/docs/api/java/sql/CallableStatement.html#registerOutParameter-int-java.sql.SQLType-java.lang.String-
Is there any interest in the R2DBC SPI also having a way to do this?
This problem can already be solved by driver-specific extensions to the SPI. For instance, I've drafted a solution for Oracle R2DBC here:
oracle/oracle-r2dbc#83 (comment)
Just wanted to check in with the broader R2DBC community before I go off and implement this. Should we have a standard way to do this? Or, is it fine for each driver to have its own unique API?
The text was updated successfully, but these errors were encountered: