[jOOQ/jOOQ#9973] Remove internal AbstractFunction

This commit is contained in:
Lukas Eder 2020-03-18 14:26:22 +01:00
parent f3ff999494
commit 1eb32ec08d
15 changed files with 244 additions and 328 deletions

View File

@ -1,76 +0,0 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Other licenses:
* -----------------------------------------------------------------------------
* Commercial licenses for this work are available. These replace the above
* ASL 2.0 and offer limited warranties, support, maintenance, and commercial
* database integrations.
*
* For more information, please visit: http://www.jooq.org/licenses
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
package org.jooq.impl;
import org.jooq.Configuration;
import org.jooq.Context;
import org.jooq.DataType;
import org.jooq.Field;
import org.jooq.QueryPart;
/**
* A base class for all built-in functions that have vendor-specific behaviour
*
* @author Lukas Eder
*/
abstract class AbstractFunction<T> extends AbstractField<T> {
/**
* Generated UID
*/
private static final long serialVersionUID = 8771262868110746571L;
private final Field<?>[] arguments;
AbstractFunction(String name, DataType<T> type, Field<?>... arguments) {
super(DSL.name(name), type);
this.arguments = arguments;
}
@Override
public final void accept(Context<?> ctx) {
ctx.visit(getFunction0(ctx.configuration()));
}
final Field<?>[] getArguments() {
return arguments;
}
abstract QueryPart getFunction0(Configuration configuration);
}

View File

@ -13790,7 +13790,7 @@ public class DSL {
*/
@Support({ CUBRID, FIREBIRD, H2, HSQLDB, MARIADB, MYSQL, POSTGRES, SQLITE })
public static Field<String> replace(Field<String> field, Field<String> search) {
return new Replace(nullSafe(field), nullSafe(search));
return new Replace(nullSafe(field), nullSafe(search), null);
}
/**

View File

@ -38,15 +38,16 @@
package org.jooq.impl;
import static org.jooq.impl.DSL.function;
import static org.jooq.impl.Names.N_DECODE;
import org.jooq.CaseConditionStep;
import org.jooq.Configuration;
import org.jooq.Context;
import org.jooq.Field;
/**
* @author Lukas Eder
*/
final class Decode<T, Z> extends AbstractFunction<Z> {
final class Decode<T, Z> extends AbstractField<Z> {
/**
* Generated UID
@ -59,7 +60,7 @@ final class Decode<T, Z> extends AbstractFunction<Z> {
private final Field<?>[] more;
public Decode(Field<T> field, Field<T> search, Field<Z> result, Field<?>[] more) {
super("decode", result.getDataType(), Tools.combine(field, search, result, more));
super(N_DECODE, result.getDataType());
this.field = field;
this.search = search;
@ -69,8 +70,10 @@ final class Decode<T, Z> extends AbstractFunction<Z> {
@SuppressWarnings("unchecked")
@Override
final Field<Z> getFunction0(Configuration configuration) {
switch (configuration.family()) {
public final void accept(Context<?> ctx) {
switch (ctx.family()) {
@ -87,17 +90,22 @@ final class Decode<T, Z> extends AbstractFunction<Z> {
.choose()
.when(field.isNotDistinctFrom(search), result);
for (int i = 0; i < more.length; i += 2)
for (int i = 0; i < more.length; i += 2) {
// search/result pair
if (i + 1 < more.length)
if (i + 1 < more.length) {
when = when.when(field.isNotDistinctFrom((Field<T>) more[i]), (Field<Z>) more[i + 1]);
}
// trailing default value
else
return when.otherwise((Field<Z>) more[i]);
else {
ctx.visit(when.otherwise((Field<Z>) more[i]));
return;
}
}
return when;
ctx.visit(when);
return;
}
}
}

View File

@ -40,16 +40,16 @@ package org.jooq.impl;
import static org.jooq.impl.DSL.function;
import static org.jooq.impl.DSL.inline;
import static org.jooq.impl.DSL.one;
import static org.jooq.impl.Names.N_E;
import java.math.BigDecimal;
import org.jooq.Configuration;
import org.jooq.Field;
import org.jooq.Context;
/**
* @author Lukas Eder
*/
final class Euler extends AbstractFunction<BigDecimal> {
final class Euler extends AbstractField<BigDecimal> {
/**
* Generated UID
@ -57,12 +57,12 @@ final class Euler extends AbstractFunction<BigDecimal> {
private static final long serialVersionUID = -420788300355442056L;
Euler() {
super("e", SQLDataType.NUMERIC);
super(N_E, SQLDataType.NUMERIC);
}
@Override
final Field<BigDecimal> getFunction0(Configuration configuration) {
switch (configuration.family()) {
public final void accept(Context<?> ctx) {
switch (ctx.family()) {
@ -90,14 +90,17 @@ final class Euler extends AbstractFunction<BigDecimal> {
case MARIADB:
case MYSQL:
case POSTGRES:
return DSL.exp(one());
ctx.visit(DSL.exp(one()));
return;
case SQLITE:
return inline(Math.E, BigDecimal.class);
ctx.visit(inline(Math.E, BigDecimal.class));
return;
// The Euler number doesn't seem to exist in any dialect...
default:
return function("e", getDataType());
ctx.visit(function("e", getDataType()));
return;
}
}
}

View File

@ -38,17 +38,18 @@
package org.jooq.impl;
import static org.jooq.impl.DSL.function;
import static org.jooq.impl.Names.N_EXP;
import static org.jooq.impl.SQLDataType.NUMERIC;
import java.math.BigDecimal;
import org.jooq.Configuration;
import org.jooq.Context;
import org.jooq.Field;
/**
* @author Lukas Eder
*/
final class Exp extends AbstractFunction<BigDecimal> {
final class Exp extends AbstractField<BigDecimal> {
/**
* Generated UID
@ -58,14 +59,16 @@ final class Exp extends AbstractFunction<BigDecimal> {
private final Field<? extends Number> argument;
Exp(Field<? extends Number> argument) {
super("exp", NUMERIC, argument);
super(N_EXP, NUMERIC);
this.argument = argument;
}
@Override
final Field<BigDecimal> getFunction0(Configuration configuration) {
switch (configuration.family()) {
public final void accept(Context<?> ctx) {
switch (ctx.family()) {
@ -76,7 +79,8 @@ final class Exp extends AbstractFunction<BigDecimal> {
default:
return function("exp", NUMERIC, argument);
ctx.visit(function("exp", NUMERIC, argument));
return;
}
}
}

View File

@ -38,35 +38,40 @@
package org.jooq.impl;
import static org.jooq.impl.DSL.function;
import static org.jooq.impl.Names.N_GREATEST;
import org.jooq.Configuration;
import org.jooq.Context;
import org.jooq.DataType;
import org.jooq.Field;
/**
* @author Lukas Eder
*/
final class Greatest<T> extends AbstractFunction<T> {
final class Greatest<T> extends AbstractField<T> {
/**
* Generated UID
*/
private static final long serialVersionUID = -7273879239726265322L;
private final Field<?>[] args;
Greatest(DataType<T> type, Field<?>... arguments) {
super("greatest", type, arguments);
Greatest(DataType<T> type, Field<?>... args) {
super(N_GREATEST, type);
this.args = args;
}
@SuppressWarnings("unchecked")
@Override
final Field<T> getFunction0(Configuration configuration) {
public final void accept(Context<?> ctx) {
// In any dialect, a single argument is always the greatest
if (getArguments().length == 1) {
return (Field<T>) getArguments()[0];
if (args.length == 1) {
ctx.visit(args[0]);
return;
}
switch (configuration.family()) {
switch (ctx.family()) {
// This implementation has O(2^n) complexity. Better implementations
// are very welcome
// [#1049] TODO Fix this!
@ -80,32 +85,37 @@ final class Greatest<T> extends AbstractFunction<T> {
case DERBY: {
Field<T> first = (Field<T>) getArguments()[0];
Field<T> other = (Field<T>) getArguments()[1];
Field<T> first = (Field<T>) args[0];
Field<T> other = (Field<T>) args[1];
if (getArguments().length > 2) {
Field<?>[] remaining = new Field[getArguments().length - 2];
System.arraycopy(getArguments(), 2, remaining, 0, remaining.length);
if (args.length > 2) {
Field<?>[] remaining = new Field[args.length - 2];
System.arraycopy(args, 2, remaining, 0, remaining.length);
return DSL
.when(first.greaterThan(other), DSL.greatest(first, remaining))
.otherwise(DSL.greatest(other, remaining));
ctx.visit(DSL
.when(first.gt(other), DSL.greatest(first, remaining))
.otherwise(DSL.greatest(other, remaining)));
}
else {
return DSL
.when(first.greaterThan(other), first)
.otherwise(other);
ctx.visit(DSL
.when(first.gt(other), first)
.otherwise(other));
}
return;
}
case FIREBIRD:
return function("maxvalue", getDataType(), getArguments());
ctx.visit(function("maxvalue", getDataType(), args));
return;
case SQLITE:
return function("max", getDataType(), getArguments());
ctx.visit(function("max", getDataType(), args));
return;
default:
return function("greatest", getDataType(), getArguments());
ctx.visit(function("greatest", getDataType(), args));
return;
}
}
}

View File

@ -39,31 +39,23 @@ package org.jooq.impl;
// ...
import static org.jooq.impl.DSL.inline;
import static org.jooq.impl.Names.N_GROUP_CONCAT;
import java.util.Arrays;
import java.util.Collection;
import org.jooq.AggregateFilterStep;
import org.jooq.AggregateFunction;
import org.jooq.Condition;
import org.jooq.Configuration;
import org.jooq.Context;
import org.jooq.Field;
import org.jooq.GroupConcatOrderByStep;
import org.jooq.GroupConcatSeparatorStep;
import org.jooq.Name;
import org.jooq.OrderField;
// ...
import org.jooq.QueryPart;
import org.jooq.SQL;
import org.jooq.WindowDefinition;
import org.jooq.WindowFinalStep;
import org.jooq.WindowPartitionByStep;
import org.jooq.WindowSpecification;
/**
* @author Lukas Eder
*/
final class GroupConcat extends AbstractFunction<String> implements GroupConcatOrderByStep {
final class GroupConcat
extends AbstractAggregateFunction<String>
implements GroupConcatOrderByStep {
/**
* Generated UID
@ -71,7 +63,6 @@ final class GroupConcat extends AbstractFunction<String> implements GroupConcatO
private static final long serialVersionUID = -6884415527559632960L;
private final Field<?> field;
private final boolean distinct;
private final SortFieldList orderBy;
private String separator;
@ -80,15 +71,14 @@ final class GroupConcat extends AbstractFunction<String> implements GroupConcatO
}
GroupConcat(Field<?> field, boolean distinct) {
super("group_concat", SQLDataType.VARCHAR);
super(distinct, N_GROUP_CONCAT, SQLDataType.VARCHAR, field);
this.field = field;
this.distinct = distinct;
this.orderBy = new SortFieldList();
}
@Override
final Field<String> getFunction0(Configuration configuration) {
public final void accept(Context<?> ctx) {
ListAgg result;
if (separator == null)
@ -103,106 +93,9 @@ final class GroupConcat extends AbstractFunction<String> implements GroupConcatO
if (orderBy.isEmpty())
return result;
ctx.visit(result);
else
return result.withinGroupOrderBy(orderBy);
}
@Override
public final AggregateFilterStep<String> filterWhere(Condition condition) {
throw new UnsupportedOperationException("FILTER() not supported on GROUP_CONCAT aggregate function");
}
@Override
public final AggregateFilterStep<String> filterWhere(Condition... conditions) {
throw new UnsupportedOperationException("FILTER() not supported on GROUP_CONCAT aggregate function");
}
@Override
public final AggregateFilterStep<String> filterWhere(Collection<? extends Condition> conditions) {
throw new UnsupportedOperationException("FILTER() not supported on GROUP_CONCAT aggregate function");
}
@Override
public final AggregateFilterStep<String> filterWhere(Field<Boolean> c) {
throw new UnsupportedOperationException("FILTER() not supported on GROUP_CONCAT aggregate function");
}
@Override
public final AggregateFilterStep<String> filterWhere(Boolean c) {
throw new UnsupportedOperationException("FILTER() not supported on GROUP_CONCAT aggregate function");
}
@Override
public final AggregateFilterStep<String> filterWhere(SQL sql) {
throw new UnsupportedOperationException("FILTER() not supported on GROUP_CONCAT aggregate function");
}
@Override
public final AggregateFilterStep<String> filterWhere(String sql) {
throw new UnsupportedOperationException("FILTER() not supported on GROUP_CONCAT aggregate function");
}
@Override
public final AggregateFilterStep<String> filterWhere(String sql, Object... bindings) {
throw new UnsupportedOperationException("FILTER() not supported on GROUP_CONCAT aggregate function");
}
@Override
public final AggregateFilterStep<String> filterWhere(String sql, QueryPart... parts) {
throw new UnsupportedOperationException("FILTER() not supported on GROUP_CONCAT aggregate function");
}
@Override
public final WindowPartitionByStep<String> over() {
throw new UnsupportedOperationException("OVER() not supported on GROUP_CONCAT aggregate function");
}
@Override
public final WindowFinalStep<String> over(WindowSpecification specification) {
throw new UnsupportedOperationException("OVER() not supported on GROUP_CONCAT aggregate function");
}
@Override
public final WindowFinalStep<String> over(WindowDefinition definition) {
throw new UnsupportedOperationException("OVER() not supported on GROUP_CONCAT aggregate function");
}
@Override
public final WindowFinalStep<String> over(Name name) {
throw new UnsupportedOperationException("OVER() not supported on GROUP_CONCAT aggregate function");
}
@Override
public final WindowFinalStep<String> over(String name) {
throw new UnsupportedOperationException("OVER() not supported on GROUP_CONCAT aggregate function");
ctx.visit(result.withinGroupOrderBy(orderBy));
}
@Override
@ -212,12 +105,12 @@ final class GroupConcat extends AbstractFunction<String> implements GroupConcatO
}
@Override
public final GroupConcatSeparatorStep orderBy(OrderField<?>... fields) {
public final GroupConcat orderBy(OrderField<?>... fields) {
return orderBy(Arrays.asList(fields));
}
@Override
public final GroupConcatSeparatorStep orderBy(Collection<? extends OrderField<?>> fields) {
public final GroupConcat orderBy(Collection<? extends OrderField<?>> fields) {
orderBy.addAll(Tools.sortFields(fields));
return this;
}

View File

@ -38,35 +38,40 @@
package org.jooq.impl;
import static org.jooq.impl.DSL.function;
import static org.jooq.impl.Names.N_LEAST;
import org.jooq.Configuration;
import org.jooq.Context;
import org.jooq.DataType;
import org.jooq.Field;
/**
* @author Lukas Eder
*/
final class Least<T> extends AbstractFunction<T> {
final class Least<T> extends AbstractField<T> {
/**
* Generated UID
*/
private static final long serialVersionUID = -7273879239726265322L;
private final Field<?>[] args;
Least(DataType<T> type, Field<?>... arguments) {
super("least", type, arguments);
Least(DataType<T> type, Field<?>... args) {
super(N_LEAST, type);
this.args = args;
}
@SuppressWarnings("unchecked")
@Override
final Field<T> getFunction0(Configuration configuration) {
public final void accept(Context<?> ctx) {
// In any dialect, a single argument is always the least
if (getArguments().length == 1) {
return (Field<T>) getArguments()[0];
if (args.length == 1) {
ctx.visit(args[0]);
return;
}
switch (configuration.family()) {
switch (ctx.family()) {
// This implementation has O(2^n) complexity. Better implementations
// are very welcome
@ -79,32 +84,37 @@ final class Least<T> extends AbstractFunction<T> {
case DERBY: {
Field<T> first = (Field<T>) getArguments()[0];
Field<T> other = (Field<T>) getArguments()[1];
Field<T> first = (Field<T>) args[0];
Field<T> other = (Field<T>) args[1];
if (getArguments().length > 2) {
Field<?>[] remaining = new Field<?>[getArguments().length - 2];
System.arraycopy(getArguments(), 2, remaining, 0, remaining.length);
if (args.length > 2) {
Field<?>[] remaining = new Field<?>[args.length - 2];
System.arraycopy(args, 2, remaining, 0, remaining.length);
return DSL
.when(first.lessThan(other), DSL.least(first, remaining))
.otherwise(DSL.least(other, remaining));
ctx.visit(DSL
.when(first.lt(other), DSL.least(first, remaining))
.otherwise(DSL.least(other, remaining)));
}
else {
return DSL
.when(first.lessThan(other), first)
.otherwise(other);
ctx.visit(DSL
.when(first.lt(other), first)
.otherwise(other));
}
return;
}
case FIREBIRD:
return function("minvalue", getDataType(), getArguments());
ctx.visit(function("minvalue", getDataType(), args));
return;
case SQLITE:
return function("min", getDataType(), getArguments());
ctx.visit(function("min", getDataType(), args));
return;
default:
return function("least", getDataType(), getArguments());
ctx.visit(function("least", getDataType(), args));
return;
}
}
}

View File

@ -38,17 +38,18 @@
package org.jooq.impl;
import static org.jooq.impl.DSL.function;
import static org.jooq.impl.Names.N_LN;
import static org.jooq.impl.SQLDataType.NUMERIC;
import java.math.BigDecimal;
import org.jooq.Configuration;
import org.jooq.Context;
import org.jooq.Field;
/**
* @author Lukas Eder
*/
final class Ln extends AbstractFunction<BigDecimal> {
final class Ln extends AbstractField<BigDecimal> {
/**
* Generated UID
@ -63,16 +64,20 @@ final class Ln extends AbstractFunction<BigDecimal> {
}
Ln(Field<? extends Number> argument, Field<? extends Number> base) {
super("ln", SQLDataType.NUMERIC, argument);
super(N_LN, SQLDataType.NUMERIC);
this.argument = argument;
this.base = base;
}
@Override
final Field<BigDecimal> getFunction0(Configuration configuration) {
public final void accept(Context<?> ctx) {
if (base == null) {
switch (configuration.family()) {
switch (ctx.family()) {
@ -92,11 +97,13 @@ final class Ln extends AbstractFunction<BigDecimal> {
default:
return function("ln", SQLDataType.NUMERIC, argument);
ctx.visit(function("ln", SQLDataType.NUMERIC, argument));
return;
}
}
else {
switch (configuration.family()) {
switch (ctx.family()) {
@ -119,10 +126,12 @@ final class Ln extends AbstractFunction<BigDecimal> {
case DERBY:
case HSQLDB:
return DSL.ln(argument).div(DSL.ln(base));
ctx.visit(DSL.ln(argument).div(DSL.ln(base)));
return;
default:
return function("log", SQLDataType.NUMERIC, base, argument);
ctx.visit(function("log", SQLDataType.NUMERIC, base, argument));
return;
}
}
}

View File

@ -74,13 +74,17 @@ final class Names {
static final Name N_CURRVAL = DSL.unquotedName("currval");
static final Name N_DATEADD = DSL.unquotedName("dateadd");
static final Name N_DATEDIFF = DSL.unquotedName("datediff");
static final Name N_DECODE = DSL.unquotedName("decode");
static final Name N_DEGREES = DSL.unquotedName("degrees");
static final Name N_DUAL = DSL.unquotedName("dual");
static final Name N_E = DSL.unquotedName("e");
static final Name N_EXP = DSL.unquotedName("exp");
static final Name N_EXTRACT = DSL.unquotedName("extract");
static final Name N_FLASHBACK = DSL.unquotedName("flashback");
static final Name N_FLOOR = DSL.unquotedName("floor");
static final Name N_FUNCTION = DSL.unquotedName("function");
static final Name N_GENERATE_SERIES = DSL.unquotedName("generate_series");
static final Name N_GREATEST = DSL.unquotedName("greatest");
static final Name N_GROUP_CONCAT = DSL.unquotedName("group_concat");
static final Name N_IIF = DSL.unquotedName("iif");
static final Name N_JOIN = DSL.unquotedName("join");
@ -94,9 +98,11 @@ final class Names {
static final Name N_JSONB_OBJECT = DSL.unquotedName("jsonb_object");
static final Name N_JSONB_OBJECTAGG = DSL.unquotedName("jsonb_objectagg");
static final Name N_JSONB_OBJECT_AGG = DSL.unquotedName("jsonb_object_agg");
static final Name N_LEAST = DSL.unquotedName("least");
static final Name N_LEFT = DSL.unquotedName("left");
static final Name N_LIST = DSL.unquotedName("list");
static final Name N_LISTAGG = DSL.unquotedName("listagg");
static final Name N_LN = DSL.unquotedName("ln");
static final Name N_LOWER = DSL.unquotedName("lower");
static final Name N_LPAD = DSL.unquotedName("lpad");
static final Name N_LTRIM = DSL.unquotedName("ltrim");
@ -111,15 +117,19 @@ final class Names {
static final Name N_NVL = DSL.unquotedName("nvl");
static final Name N_NVL2 = DSL.unquotedName("nvl2");
static final Name N_OVERLAY = DSL.unquotedName("overlay");
static final Name N_PI = DSL.unquotedName("pi");
static final Name N_PIVOT = DSL.unquotedName("pivot");
static final Name N_POSITION = DSL.unquotedName("position");
static final Name N_POWER = DSL.unquotedName("power");
static final Name N_PRIOR = DSL.unquotedName("prior");
static final Name N_PRODUCT = DSL.unquotedName("product");
static final Name N_RADIANS = DSL.unquotedName("radians");
static final Name N_RANDOM = DSL.unquotedName("rand");
static final Name N_REPLACE = DSL.unquotedName("replace");
static final Name N_REVERSE = DSL.unquotedName("reverse");
static final Name N_RIGHT = DSL.unquotedName("right");
static final Name N_ROLLUP = DSL.unquotedName("rollup");
static final Name N_ROUND = DSL.unquotedName("round");
static final Name N_ROW = DSL.unquotedName("row");
static final Name N_ROWNUM = DSL.unquotedName("rownum");
static final Name N_ROW_NUMBER = DSL.unquotedName("row_number");
@ -138,6 +148,7 @@ final class Names {
static final Name N_T = DSL.unquotedName("t");
static final Name N_TANH = DSL.unquotedName("tanh");
static final Name N_TIMESTAMPDIFF = DSL.unquotedName("timestampdiff");
static final Name N_TRANSLATE = DSL.unquotedName("translate");
static final Name N_TRIM = DSL.unquotedName("trim");
static final Name N_TRUNC = DSL.unquotedName("trunc");
static final Name N_UPPER = DSL.unquotedName("upper");

View File

@ -41,16 +41,16 @@ import static org.jooq.impl.DSL.function;
import static org.jooq.impl.DSL.inline;
import static org.jooq.impl.DSL.one;
import static org.jooq.impl.DSL.two;
import static org.jooq.impl.Names.N_PI;
import java.math.BigDecimal;
import org.jooq.Configuration;
import org.jooq.Field;
import org.jooq.Context;
/**
* @author Lukas Eder
*/
final class Pi extends AbstractFunction<BigDecimal> {
final class Pi extends AbstractField<BigDecimal> {
/**
* Generated UID
@ -58,12 +58,13 @@ final class Pi extends AbstractFunction<BigDecimal> {
private static final long serialVersionUID = -420788300355442056L;
Pi() {
super("pi", SQLDataType.NUMERIC);
super(N_PI, SQLDataType.NUMERIC);
}
@Override
final Field<BigDecimal> getFunction0(Configuration configuration) {
switch (configuration.family()) {
public final void accept(Context<?> ctx) {
switch (ctx.family()) {
@ -75,10 +76,12 @@ final class Pi extends AbstractFunction<BigDecimal> {
case SQLITE:
return inline(Math.PI, BigDecimal.class);
ctx.visit(inline(Math.PI, BigDecimal.class));
return;
default:
return function("pi", getDataType());
ctx.visit(function("pi", getDataType()));
return;
}
}
}

View File

@ -40,17 +40,18 @@ package org.jooq.impl;
import static org.jooq.impl.DSL.function;
import static org.jooq.impl.DSL.inline;
import static org.jooq.impl.DSL.pi;
import static org.jooq.impl.Names.N_RADIANS;
import static org.jooq.impl.Tools.castIfNeeded;
import java.math.BigDecimal;
import org.jooq.Configuration;
import org.jooq.Context;
import org.jooq.Field;
/**
* @author Lukas Eder
*/
final class Radians extends AbstractFunction<BigDecimal> {
final class Radians extends AbstractField<BigDecimal> {
/**
* Generated UID
@ -60,14 +61,14 @@ final class Radians extends AbstractFunction<BigDecimal> {
private final Field<?> argument;
Radians(Field<?> argument) {
super("radians", SQLDataType.NUMERIC, argument);
super(N_RADIANS, SQLDataType.NUMERIC);
this.argument = argument;
}
@Override
final Field<BigDecimal> getFunction0(Configuration configuration) {
switch (configuration.family()) {
public final void accept(Context<?> ctx) {
switch (ctx.family()) {
@ -76,10 +77,12 @@ final class Radians extends AbstractFunction<BigDecimal> {
case FIREBIRD:
case SQLITE:
return castIfNeeded(argument, BigDecimal.class).mul(pi()).div(inline(180));
ctx.visit(castIfNeeded(argument, BigDecimal.class).mul(pi()).div(inline(180)));
return;
default:
return function("radians", SQLDataType.NUMERIC, argument);
ctx.visit(function("radians", SQLDataType.NUMERIC, argument));
return;
}
}
}

View File

@ -39,31 +39,42 @@ package org.jooq.impl;
import static org.jooq.impl.DSL.function;
import static org.jooq.impl.DSL.val;
import static org.jooq.impl.Names.N_REPLACE;
import static org.jooq.impl.SQLDataType.VARCHAR;
import org.jooq.Configuration;
import org.jooq.Context;
import org.jooq.Field;
/**
* @author Lukas Eder
*/
final class Replace extends AbstractFunction<String> {
final class Replace extends AbstractField<String> {
/**
* Generated UID
*/
private static final long serialVersionUID = -7273879239726265322L;
private final Field<?> field;
private final Field<?> search;
private final Field<?> replace;
Replace(Field<?>... arguments) {
super("replace", SQLDataType.VARCHAR, arguments);
Replace(Field<?> field, Field<?> search, Field<?> replace) {
super(N_REPLACE, SQLDataType.VARCHAR);
this.field = field;
this.search = search;
this.replace = replace;
}
@Override
final Field<String> getFunction0(Configuration configuration) {
Field<?>[] args = getArguments();
public final void accept(Context<?> ctx) {
// [#861] Most dialects don't ship with a two-argument replace function:
switch (configuration.family()) {
switch (ctx.family()) {
@ -97,13 +108,20 @@ final class Replace extends AbstractFunction<String> {
case MYSQL:
case POSTGRES:
case SQLITE:
if (args.length == 2)
return function("replace", VARCHAR, args[0], args[1], val(""));
if (replace == null)
ctx.visit(function("replace", VARCHAR, field, search, val("")));
else
return function("replace", VARCHAR, args);
ctx.visit(function("replace", VARCHAR, field, search, replace));
return;
default:
return function("replace", VARCHAR, args);
if (replace == null)
ctx.visit(function("replace", VARCHAR, field, search));
else
ctx.visit(function("replace", VARCHAR, field, search, replace));
return;
}
}
}

View File

@ -39,19 +39,20 @@ package org.jooq.impl;
import static org.jooq.impl.DSL.function;
import static org.jooq.impl.DSL.inline;
import static org.jooq.impl.Names.N_ROUND;
import static org.jooq.impl.SQLDataType.NUMERIC;
import static org.jooq.impl.Tools.castIfNeeded;
import java.math.BigDecimal;
import org.jooq.Configuration;
import org.jooq.Context;
import org.jooq.Field;
import org.jooq.Param;
/**
* @author Lukas Eder
*/
final class Round<T extends Number> extends AbstractFunction<T> {
final class Round<T extends Number> extends AbstractField<T> {
/**
* Generated UID
@ -66,7 +67,7 @@ final class Round<T extends Number> extends AbstractFunction<T> {
}
Round(Field<T> argument, Field<Integer> decimals) {
super("round", argument.getDataType(), argument);
super(N_ROUND, argument.getDataType());
this.argument = argument;
this.decimals = decimals;
@ -74,26 +75,30 @@ final class Round<T extends Number> extends AbstractFunction<T> {
@SuppressWarnings("unchecked")
@Override
final Field<T> getFunction0(Configuration configuration) {
switch (configuration.family()) {
public final void accept(Context<?> ctx) {
switch (ctx.family()) {
// evaluate "round" if unavailable
case DERBY: {
if (decimals == null) {
return DSL
ctx.visit(DSL
.when(argument.sub(DSL.floor(argument))
.lessThan((T) Double.valueOf(0.5)), DSL.floor(argument))
.otherwise(DSL.ceil(argument));
.otherwise(DSL.ceil(argument)));
return;
}
else if (decimals instanceof Param) {
Integer decimalsValue = ((Param<Integer>) decimals).getValue();
Field<BigDecimal> factor = DSL.val(BigDecimal.ONE.movePointRight(decimalsValue));
Field<T> mul = argument.mul(factor);
return DSL
ctx.visit(DSL
.when(mul.sub(DSL.floor(mul))
.lessThan((T) Double.valueOf(0.5)), DSL.floor(mul).div(factor))
.otherwise(DSL.ceil(mul).div(factor));
.otherwise(DSL.ceil(mul).div(factor)));
return;
}
// fall-through
}
@ -121,21 +126,25 @@ final class Round<T extends Number> extends AbstractFunction<T> {
// There's no function round(double precision, integer) in Postgres
case POSTGRES: {
if (decimals == null)
return function("round", getDataType(), argument);
else
return function("round", getDataType(), castIfNeeded(argument, BigDecimal.class), decimals);
}
// This is the optimal implementation by most RDBMS
default: {
// There's no function round(double precision, integer) in Postgres
case POSTGRES:
if (decimals == null)
return function("round", getDataType(), argument);
ctx.visit(function("round", getDataType(), argument));
else
return function("round", getDataType(), argument, decimals);
}
ctx.visit(function("round", getDataType(), castIfNeeded(argument, BigDecimal.class), decimals));
return;
default:
if (decimals == null)
ctx.visit(function("round", getDataType(), argument));
else
ctx.visit(function("round", getDataType(), argument, decimals));
return;
}
}
}

View File

@ -38,28 +38,38 @@
package org.jooq.impl;
import static org.jooq.impl.DSL.function;
import static org.jooq.impl.Names.N_TRANSLATE;
import org.jooq.Configuration;
import org.jooq.Context;
import org.jooq.Field;
import org.jooq.QueryPart;
/**
* @author Lukas Eder
*/
final class Translate extends AbstractFunction<String> {
final class Translate extends AbstractField<String> {
/**
* Generated UID
*/
private static final long serialVersionUID = 6776882414592454999L;
private static final long serialVersionUID = 6776882414592454999L;
private final Field<String> text;
private final Field<String> from;
private final Field<String> to;
Translate(Field<String> text, Field<String> from, Field<String> to) {
super("translate", text.getDataType(), text, from, to);
super(N_TRANSLATE, text.getDataType());
this.text = text;
this.from = from;
this.to = to;
}
@Override
final QueryPart getFunction0(Configuration configuration) {
switch (configuration.family()) {
public final void accept(Context<?> ctx) {
switch (ctx.family()) {
@ -69,7 +79,8 @@ final class Translate extends AbstractFunction<String> {
default:
return function("translate", getDataType(), getArguments());
ctx.visit(function("translate", getDataType(), text, from, to));
return;
}
}
}