diff --git a/jOOQ/src/main/java/org/jooq/impl/AbstractRoutine.java b/jOOQ/src/main/java/org/jooq/impl/AbstractRoutine.java index 4f5dbe94db..a22a4a4ea4 100644 --- a/jOOQ/src/main/java/org/jooq/impl/AbstractRoutine.java +++ b/jOOQ/src/main/java/org/jooq/impl/AbstractRoutine.java @@ -125,13 +125,14 @@ public abstract class AbstractRoutine extends AbstractQueryPart implements Ro private Parameter returnParameter; private ResultsImpl results; private boolean overloaded; - private boolean hasDefaultedParameters; private boolean hasUnnamedParameters; + + // ------------------------------------------------------------------------ // Call-data attributes (call-specific) // ------------------------------------------------------------------------ @@ -143,7 +144,7 @@ public abstract class AbstractRoutine extends AbstractQueryPart implements Ro private Configuration configuration; private final Map, Object> outValues; - private final Map, Integer> parameterIndexes; + private final Map, Integer> resultIndexes; // ------------------------------------------------------------------------ // Constructors @@ -188,7 +189,7 @@ public abstract class AbstractRoutine extends AbstractQueryPart implements Ro @SuppressWarnings({ "unchecked", "rawtypes" }) protected AbstractRoutine(String name, Schema schema, Package pkg, DataType type, Converter converter, Binding binding) { - this.parameterIndexes = new HashMap, Integer>(); + this.resultIndexes = new HashMap, Integer>(); this.schema = schema; this.pkg = pkg; @@ -496,56 +497,101 @@ public abstract class AbstractRoutine extends AbstractQueryPart implements Ro } final void bind0(BindContext context) { + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + for (Parameter parameter : getParameters()) { // [#1183] [#3533] Skip defaulted parameters - if (getInParameters().contains(parameter) && inValuesDefaulted.contains(parameter)) { + if (getInParameters().contains(parameter) && inValuesDefaulted.contains(parameter)) continue; - } - int index = context.peekIndex(); - parameterIndexes.put(parameter, index); + bind1(context, parameter, getInValues().get(parameter) != null, resultParameter(parameter)); + } + } - if (getInValues().get(parameter) != null) { - context.visit(getInValues().get(parameter)); + private final void bind1(BindContext context, Parameter parameter, boolean bindAsIn, boolean bindAsOut) { + int index = context.peekIndex(); - // [#391] This happens when null literals are used as IN/OUT - // parameters. They're not bound as in value, but they need to - // be registered as OUT parameter - if (index == context.peekIndex() && getOutParameters().contains(parameter)) { - context.nextIndex(); - } - } + if (bindAsOut) + resultIndexes.put(parameter, index); - // Skip one index for OUT parameters - else { + if (bindAsIn) { + context.visit(getInValues().get(parameter)); + + // [#391] This happens when null literals are used as IN/OUT + // parameters. They're not bound as in value, but they need to + // be registered as OUT parameter + if (index == context.peekIndex() && bindAsOut) context.nextIndex(); - } + } + + // Skip one index for OUT parameters + else { + context.nextIndex(); } } final void toSQL0(RenderContext context) { + toSQLDeclare(context); toSQLBegin(context); - if (getReturnParameter() != null) { + if (getReturnParameter() != null) toSQLAssign(context); - } toSQLCall(context); context.sql('('); String separator = ""; - for (Parameter parameter : getParameters()) { + List> parameters = getParameters(); + for (int i = 0; i < parameters.size(); i++) { + Parameter parameter = parameters.get(i); // The return value has already been written - if (parameter.equals(getReturnParameter())) { + if (parameter.equals(getReturnParameter())) continue; - } // OUT and IN OUT parameters are always written as a '?' bind variable - else if (getOutParameters().contains(parameter)) { + if (getOutParameters().contains(parameter)) { context.sql(separator); - toSQLOutParam(context, parameter); + toSQLOutParam(context, parameter, i); } // [#1183] [#3533] Omit defaulted parameters @@ -556,7 +602,7 @@ public abstract class AbstractRoutine extends AbstractQueryPart implements Ro // IN parameters are rendered normally else { context.sql(separator); - toSQLInParam(context, parameter, getInValues().get(parameter)); + toSQLInParam(context, parameter, i, getInValues().get(parameter)); } separator = ", "; @@ -576,9 +622,52 @@ public abstract class AbstractRoutine extends AbstractQueryPart implements Ro + + + + + + + + + + + { context.sql(" }"); } + } + + private final void toSQLDeclare(RenderContext context) { + + + + + + + + + + + + + + + + + + + + + + + + + + + + + } private final void toSQLBegin(RenderContext context) { @@ -602,6 +691,9 @@ public abstract class AbstractRoutine extends AbstractQueryPart implements Ro + + + { context.sql("? = "); } @@ -620,7 +712,10 @@ public abstract class AbstractRoutine extends AbstractQueryPart implements Ro toSQLQualifiedName(context); } - private final void toSQLOutParam(RenderContext context, Parameter parameter) { + private final void toSQLOutParam(RenderContext context, Parameter parameter, int index) { + + + @@ -631,7 +726,10 @@ public abstract class AbstractRoutine extends AbstractQueryPart implements Ro context.sql('?'); } - private final void toSQLInParam(RenderContext context, Parameter parameter, Field value) { + private final void toSQLInParam(RenderContext context, Parameter parameter, int index, Field value) { + + + @@ -669,13 +767,9 @@ public abstract class AbstractRoutine extends AbstractQueryPart implements Ro } private final void fetchOutParameters(ExecuteContext ctx) throws SQLException { - for (Parameter parameter : getParameters()) { - if (parameter.equals(getReturnParameter()) || - getOutParameters().contains(parameter)) { - + for (Parameter parameter : getParameters()) + if (resultParameter(parameter)) fetchOutParameter(ctx, parameter); - } - } } private final void fetchOutParameter(ExecuteContext ctx, Parameter parameter) throws SQLException { @@ -683,7 +777,7 @@ public abstract class AbstractRoutine extends AbstractQueryPart implements Ro ctx.configuration(), ctx.data(), (CallableStatement) ctx.statement(), - parameterIndexes.get(parameter) + resultIndexes.get(parameter) ); parameter.getBinding().get(out); @@ -697,17 +791,13 @@ public abstract class AbstractRoutine extends AbstractQueryPart implements Ro // Register all out / inout parameters according to their position // Note that some RDBMS do not support binding by name very well - for (Parameter parameter : getParameters()) { - if (parameter.equals(getReturnParameter()) || - getOutParameters().contains(parameter)) { - + for (Parameter parameter : getParameters()) + if (resultParameter(parameter)) registerOutParameter(c, data, statement, parameter); - } - } } private final void registerOutParameter(Configuration c, Map data, CallableStatement statement, Parameter parameter) throws SQLException { - parameter.getBinding().register(new DefaultBindingRegisterContext(c, data, statement, parameterIndexes.get(parameter))); + parameter.getBinding().register(new DefaultBindingRegisterContext(c, data, statement, resultIndexes.get(parameter))); } // ------------------------------------------------------------------------ @@ -716,9 +806,8 @@ public abstract class AbstractRoutine extends AbstractQueryPart implements Ro @Override public final T getReturnValue() { - if (returnParameter != null) { + if (returnParameter != null) return getValue(returnParameter); - } return null; } @@ -800,9 +889,18 @@ public abstract class AbstractRoutine extends AbstractQueryPart implements Ro - private final boolean hasDefaultedParameters() { - return hasDefaultedParameters && !inValuesDefaulted.isEmpty(); - } + + + + + + + + + + + + private final boolean hasUnnamedParameters() { return hasUnnamedParameters; @@ -810,8 +908,16 @@ public abstract class AbstractRoutine extends AbstractQueryPart implements Ro private final void addParameter(Parameter parameter) { allParameters.add(parameter); - hasDefaultedParameters |= parameter.isDefaulted(); hasUnnamedParameters |= parameter.isUnnamed(); + + + + + + } + + private final boolean resultParameter(Parameter parameter) { + return parameter.equals(getReturnParameter()) || getOutParameters().contains(parameter); } protected final void addInParameter(Parameter parameter) { diff --git a/jOOQ/src/main/java/org/jooq/impl/DefaultBinding.java b/jOOQ/src/main/java/org/jooq/impl/DefaultBinding.java index bb63ddbffc..ae289e48c8 100644 --- a/jOOQ/src/main/java/org/jooq/impl/DefaultBinding.java +++ b/jOOQ/src/main/java/org/jooq/impl/DefaultBinding.java @@ -780,7 +780,13 @@ public class DefaultBinding implements Binding { Configuration configuration = ctx.configuration(); int sqlType = DefaultDataType.getDataType(ctx.dialect(), type).getSQLType(); - switch (configuration.dialect().family()) { + switch (configuration.family()) { + + + + + + @@ -919,6 +925,8 @@ public class DefaultBinding implements Binding { + + ctx.statement().setBoolean(ctx.index(), (Boolean) value); } else if (actualType == BigDecimal.class) {