-
Notifications
You must be signed in to change notification settings - Fork 43
Support for sending type name with Out Parameters. #83
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
Comments
This is a great thing to point out! There is currently no way to bind user defined types (UDT)s. I think we should first check with the R2DBC SPI project: Should the SPI be enhanced to support UDTs? I'll post an issue on there soon, and we can see where it goes. It might be the case that UDT support is only valuable for Oracle. In this case, rather than enhance the SPI, Oracle R2DBC should can just extend it. Here's a very rough draft of how we might do that: class OracleR2dbcTypes {
...
public static final Type STRUCT = ...;
/**
* 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 extension would allow us to write code like this: connection.createStatement("{? = call CREATE_A_PERSON (?)}")
.bind(0, Parameters.out(
OracleR2dbcTypes.userDefined(OracleR2dbcTypes.STRUCT, "UDO_PERSON")))
.bind(1, "YOURE NAME")
.execute(); @nirmalhk7 and anyone who's interested: Does this seem like a good solution? |
If we do it this way, wont we have to make changes in the I was thinking more along these lines:
We can set appropriate getters to get the parameter, and we wont need to change |
Thinking about this a bit more. I'm not seeing the need to change the Parameters SPI. I'll flesh out the solution more, please let me know what I'm missing. The userDefined factory returns an instance of a particular class: public class UserDefinedType implements Type {
private final Type baseType;
private final String name;
private UserDefinedType(Type baseType, String name) {
this.baseType = baseType;
this.name = name;
}
public Type baseType() {
return baseType;
}
@Override
public String getName() {
return name;
}
@Override
public Class<?> getJavaType() {
// TODO: Map baseType to a Java type
}
} An instance of UserDefinedType can be passed to Parameters.out(Type), because UserDefinedType is a subclass of the Type interface. When Oracle R2DBC goes to bind the parameter: if (parameter.getType() instanceof UserDefinedType) {
UserDefinedType userDefinedType = (UserDefineType)parameter.getType();
SQLType sqlType = toJdbctype(userDefinedType.baseType());
statement.registerOutParameter(index, sqlType, userDefinedType.getName());
} I think this works, but maybe your way is better? If I understand it, OracleWrapper is like this: public class OracleWrapper {
private final Parameter.Out parameter;
private final String name;
... constructor + getters ...
} And then the binder code, like what I have above, would be checking I still think I like UserDefinedType better. As a subclass of Type, an instance of this class could be returned by ReadableMetaData.getType(). That seems like something we need to do if we want to support UDTs. |
Hi, I'd like to take this up. I think I have a solution ready that fits your description @Michael-A-McMahon. I'll create an MR shortly. |
That's awesome @nirmalhk7 ! Thank you!!! |
As asked here: https://stackoverflow.com/questions/73061887/how-to-specify-parameter-type-in-r2dbc-when-using-stored-procedures
Parameters.out
seems to call JDBCsregisterOutputParameters
within it, but it seems to pass only the binding index and the type (I want to pass the type name too).The text was updated successfully, but these errors were encountered: