[#3533] Avoid using named parameters for Oracle, if not really needed

This commit is contained in:
Lukas Eder 2014-08-12 11:16:57 +02:00
parent 557d35e7cd
commit d1320bf98e
2 changed files with 76 additions and 74 deletions

View File

@ -50,6 +50,8 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeNotNull;
import static org.junit.Assume.assumeTrue;
import java.sql.Date;
import java.util.Arrays;
@ -236,31 +238,27 @@ extends BaseTest<A, AP, B, S, B2S, BS, L, X, DATE, BOOL, D, T, U, UU, I, IPK, T7
}
public void testStoredProcedureWithDefaultParameters() {
if (cRoutines() == null) {
log.info("SKIPPING", "procedure tests with default parameters");
return;
}
assumeNotNull(cRoutines());
Reflect pdefault;
try {
pdefault = Reflect.on(cRoutines().getPackage().getName() + ".routines.PDefault");
if (!pdefault.field("P_IN_NUMBER").call("isDefaulted").<Boolean>get()) {
log.info("SKIPPING", "procedure tests with default parameters");
return;
}
assumeTrue(pdefault.field("P_IN_NUMBER").call("isDefaulted").<Boolean>get());
}
catch (ReflectException e) {
log.info("SKIPPING", "procedure tests with default parameters");
return;
}
// Call with defaulted IN parameters only
Reflect executedWithDefaults = pdefault.create();
executedWithDefaults.call("execute", create().configuration());
assertEquals(0, executedWithDefaults.call("getPOutNumber").<Number>get().intValue());
assertEquals("0", executedWithDefaults.call("getPOutVarchar").get());
assertEquals(Date.valueOf("1981-07-10"), executedWithDefaults.call("getPOutDate").get());
// Call with all values provided
Reflect executedWithoutDefault = pdefault.create();
executedWithoutDefault.call("setPInNumber", 123);
executedWithoutDefault.call("setPInVarchar", "abc");

View File

@ -42,6 +42,7 @@ package org.jooq.impl;
import static org.jooq.Clause.FIELD;
import static org.jooq.Clause.FIELD_FUNCTION;
// ...
import static org.jooq.SQLDialect.POSTGRES;
// ...
import static org.jooq.impl.DSL.function;
@ -113,12 +114,14 @@ public abstract class AbstractRoutine<T> extends AbstractQueryPart implements Ro
private final DataType<T> type;
private Parameter<T> returnParameter;
private boolean overloaded;
private boolean hasDefaultedParameters;
// ------------------------------------------------------------------------
// Call-data attributes (call-specific)
// ------------------------------------------------------------------------
private final Map<Parameter<?>, Field<?>> inValues;
private final Set<Parameter<?>> inValuesDefaulted;
private final Set<Parameter<?>> inValuesNonDefaulted;
private transient Field<T> function;
@ -152,6 +155,7 @@ public abstract class AbstractRoutine<T> extends AbstractQueryPart implements Ro
this.inParameters = new ArrayList<Parameter<?>>();
this.outParameters = new ArrayList<Parameter<?>>();
this.inValues = new HashMap<Parameter<?>, Field<?>>();
this.inValuesDefaulted = new HashSet<Parameter<?>>();
this.inValuesNonDefaulted = new HashSet<Parameter<?>>();
this.results = new HashMap<Parameter<?>, Object>();
this.type = type;
@ -182,9 +186,10 @@ public abstract class AbstractRoutine<T> extends AbstractQueryPart implements Ro
setField(parameter, val(null, parameter.getDataType()));
}
// [#1183] Add the field to the in-values and mark them as non-defaulted
// [#1183] [#3533] Add the field to the in-values and mark them as non-defaulted
else {
inValues.put(parameter, value);
inValuesDefaulted.remove(parameter);
inValuesNonDefaulted.add(parameter);
}
}
@ -352,8 +357,8 @@ public abstract class AbstractRoutine<T> extends AbstractQueryPart implements Ro
final void bind0(BindContext context) {
for (Parameter<?> parameter : getParameters()) {
// [#1183] Skip defaulted parameters
if (getInParameters().contains(parameter) && !inValuesNonDefaulted.contains(parameter)) {
// [#1183] [#3533] Skip defaulted parameters
if (getInParameters().contains(parameter) && inValuesDefaulted.contains(parameter)) {
continue;
}
@ -402,8 +407,8 @@ public abstract class AbstractRoutine<T> extends AbstractQueryPart implements Ro
toSQLOutParam(context, parameter);
}
// [#1183] Omit defaulted parameters
else if (!inValuesNonDefaulted.contains(parameter)) {
// [#1183] [#3533] Omit defaulted parameters
else if (inValuesDefaulted.contains(parameter)) {
continue;
}
@ -428,62 +433,54 @@ public abstract class AbstractRoutine<T> extends AbstractQueryPart implements Ro
}
private final void toSQLEnd(RenderContext context) {
switch (context.configuration().dialect().family()) {
/* [pro] xx
xxxx xxxxxxx
xxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxx
xxxxxx
xx [/pro] */
default:
context.sql(" }");
break;
/* [pro] xx
xx xxxxxxxxxxxxxxxxxxxxxxxxx xx xxxxxxxxxxxxxxxx xx xxxxxxx x
xxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxx
x
xxxx
xx [/pro] */
{
context.sql(" }");
}
}
private final void toSQLBegin(RenderContext context) {
switch (context.configuration().dialect().family()) {
/* [pro] xx
xxxx xxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxx
xxxxxx
xx [/pro] */
default:
context.sql("{ ");
break;
/* [pro] xx
xx xxxxxxxxxxxxxxxxxxxxxxxxx xx xxxxxxxxxxxxxxxx xx xxxxxxx x
xxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxx
x
xxxx
xx [/pro] */
{
context.sql("{ ");
}
}
private final void toSQLAssign(RenderContext context) {
switch (context.configuration().dialect().family()) {
/* [pro] xx
xxxx xxxxxxx
xxxxxxxxxxxxxx xx xxx
xxxxxx
xx [/pro] */
default:
context.sql("? = ");
break;
/* [pro] xx
xx xxxxxxxxxxxxxxxxxxxxxxxxx xx xxxxxxxxxxxxxxxx xx xxxxxxx x
xxxxxxxxxxxxxx xx xxx
x
xxxx
xx [/pro] */
{
context.sql("? = ");
}
}
private final void toSQLCall(RenderContext context) {
switch (context.configuration().dialect().family()) {
/* [pro] xx
xxxx xxxxxxx
xxxxxx
xx [/pro] */
default:
context.sql("call ");
break;
/* [pro] xx
xx xxxxxxxxxxxxxxxxxxxxxxxxx xx xxxxxxxxxxxxxxxx xx xxxxxxx x
x
xxxx
xx [/pro] */
{
context.sql("call ");
}
toSQLQualifiedName(context);
@ -491,11 +488,9 @@ public abstract class AbstractRoutine<T> extends AbstractQueryPart implements Ro
private final void toSQLOutParam(RenderContext context, Parameter<?> parameter) {
/* [pro] xx
xxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx x
xxxx xxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxx xx xxx
xxxxxx
xx xxxxxxxxxxxxxxxxxxxxxxxxx xx xxxxxxxxxxxxxxxx xx xxxxxxx x
xxxxxxxxxxxxxxxxxxxxxxxx
xxxxxx xx xxx
x
xx [/pro] */
@ -504,11 +499,9 @@ public abstract class AbstractRoutine<T> extends AbstractQueryPart implements Ro
private final void toSQLInParam(RenderContext context, Parameter<?> parameter, Field<?> value) {
/* [pro] xx
xxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx x
xxxx xxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxx xx xxx
xxxxxx
xx xxxxxxxxxxxxxxxxxxxxxxxxx xx xxxxxxxxxxxxxxxx xx xxxxxxx x
xxxxxxxxxxxxxxxxxxxxxxxx
xxxxxx xx xxx
x
xx [/pro] */
@ -670,32 +663,43 @@ public abstract class AbstractRoutine<T> extends AbstractQueryPart implements Ro
return overloaded;
}
protected final void addInParameter(Parameter<?> parameter) {
inParameters.add(parameter);
private final boolean hasDefaultedParameters() {
return hasDefaultedParameters && !inValuesDefaulted.isEmpty();
}
private final void addParameter(Parameter<?> parameter) {
allParameters.add(parameter);
hasDefaultedParameters |= parameter.isDefaulted();
}
protected final void addInParameter(Parameter<?> parameter) {
addParameter(parameter);
inParameters.add(parameter);
// IN parameters are initialised with null by default
inValues.put(parameter, val(null, parameter.getDataType()));
// [#1183] non-defaulted parameters are marked as such
if (!parameter.isDefaulted()) {
// [#1183] [#3533] defaulted parameters are marked as such
if (parameter.isDefaulted())
inValuesDefaulted.add(parameter);
else
inValuesNonDefaulted.add(parameter);
}
}
protected final void addInOutParameter(Parameter<?> parameter) {
addInParameter(parameter);
outParameters.add(parameter);
}
protected final void addOutParameter(Parameter<?> parameter) {
addParameter(parameter);
outParameters.add(parameter);
allParameters.add(parameter);
}
protected final void setReturnParameter(Parameter<T> parameter) {
addParameter(parameter);
returnParameter = parameter;
allParameters.add(parameter);
}
public final Field<T> asField() {