org.jooq.impl.AbstractField Maven / Gradle / Ivy
/*
* 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
*
* https://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: https://www.jooq.org/legal/licensing
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
package org.jooq.impl;
import static org.jooq.Clause.FIELD;
import static org.jooq.impl.DSL.inline;
import static org.jooq.impl.ExpressionOperator.ADD;
import static org.jooq.impl.ExpressionOperator.SUBTRACT;
import static org.jooq.impl.Tools.EMPTY_FIELD;
import static org.jooq.impl.Tools.castIfNeeded;
import static org.jooq.impl.Tools.map;
import static org.jooq.impl.Tools.nullSafe;
import static org.jooq.impl.Tools.nullSafeList;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import org.jooq.BetweenAndStep;
import org.jooq.Binding;
import org.jooq.Clause;
import org.jooq.Collation;
import org.jooq.Comment;
import org.jooq.Comparator;
import org.jooq.Condition;
import org.jooq.Context;
import org.jooq.Converter;
import org.jooq.DataType;
import org.jooq.DatePart;
import org.jooq.Field;
import org.jooq.LikeEscapeStep;
import org.jooq.Name;
// ...
import org.jooq.QuantifiedSelect;
import org.jooq.Record;
import org.jooq.Record1;
import org.jooq.Result;
import org.jooq.Select;
import org.jooq.SortField;
import org.jooq.SortOrder;
import org.jooq.WindowIgnoreNullsStep;
import org.jooq.WindowPartitionByStep;
import org.jooq.impl.QOM.Aliasable;
/**
* @author Lukas Eder
*/
abstract class AbstractField
extends
AbstractTypedNamed
implements
Field,
Aliasable>
{
private static final Clause[] CLAUSES = { FIELD };
AbstractField(Name name, DataType type) {
this(name, type, null);
}
AbstractField(Name name, DataType type, Comment comment) {
this(name, type, comment, type.getBinding());
}
@SuppressWarnings("unchecked")
AbstractField(Name name, DataType type, Comment comment, Binding, T> binding) {
super(name, comment, type.asConvertedDataType((Binding) binding));
}
// ------------------------------------------------------------------------
// XXX: API (not implemented)
// ------------------------------------------------------------------------
/**
* [#10179] [#14665] Subclasses may override this method to indicate that
* the condition may produce TRUE
, FALSE
, or
* NULL
.
*/
boolean isNullable() {
return true;
}
@Override
public abstract void accept(Context> ctx);
@Override
public Clause[] clauses(Context> ctx) {
return CLAUSES;
}
/* non-final */ boolean isPossiblyNullable() {
return true;
}
/* non-final */ int projectionSize() {
return 1;
}
/**
* [#7362] Subclasses may override this method to indicate that the
* condition is already parenthesised, or produces syntax that render
* parentheses around this condition unnecessary.
*
* This can help prevent excess parentheses, e.g. when this condition is
* wrapped in {@link QOM.Not}, {@link QOM.BitNot}, or {@link QOM.Neg}
*/
/* non-final */ boolean parenthesised(Context> ctx) {
return false;
}
// ------------------------------------------------------------------------
// [#5518] Record method inversions, e.g. for use as method references
// ------------------------------------------------------------------------
@Override
public final Field field(Record record) {
return record.field(this);
}
@Override
public final T get(Record record) {
return record.get(this);
}
@Override
public final T getValue(Record record) {
return record.getValue(this);
}
@Override
public final T original(Record record) {
return record.original(this);
}
@Override
public final boolean changed(Record record) {
return record.changed(this);
}
@Override
public final void reset(Record record) {
record.reset(this);
}
@Override
public final Record1 from(Record record) {
return record.into(this);
}
// ------------------------------------------------------------------------
// XXX: QOM API
// ------------------------------------------------------------------------
@Override
public /* non-final */ Name $alias() {
return null;
}
@Override
public /* non-final */ Field> $aliased() {
return this;
}
// ------------------------------------------------------------------------
// XXX: API
// ------------------------------------------------------------------------
@Override
public final Field convert(Binding binding) {
return coerce(getDataType().asConvertedDataType(binding));
}
@Override
public final Field convert(Converter converter) {
return coerce(getDataType().asConvertedDataType(converter));
}
@Override
public final Field convert(
Class toType,
Function super T, ? extends U> from,
Function super U, ? extends T> to
) {
return coerce(getDataType().asConvertedDataType(toType, from, to));
}
@Override
public final Field convertFrom(Class toType, Function super T, ? extends U> from) {
return coerce(getDataType().asConvertedDataTypeFrom(toType, from));
}
@Override
public final Field convertFrom(Function super T, ? extends U> from) {
return coerce(getDataType().asConvertedDataTypeFrom(from));
}
@Override
public final Field convertTo(Class toType, Function super U, ? extends T> to) {
return coerce(getDataType().asConvertedDataTypeTo(toType, to));
}
@Override
public final Field convertTo(Function super U, ? extends T> to) {
return coerce(getDataType().asConvertedDataTypeTo(to));
}
@Override
public final Field as(String alias) {
return as(DSL.name(alias));
}
@SuppressWarnings("unchecked")
@Override
public Field as(Name alias) {
return new FieldAlias<>((Field) (this instanceof Condition c ? DSL.field(c) : this), alias);
}
@Override
public final Field as(Field> otherField) {
return as(otherField.getUnqualifiedName());
}
@Override
public final Field as(Function super Field, ? extends String> aliasFunction) {
return as(aliasFunction.apply(this));
}
// ------------------------------------------------------------------------
// XXX: DDL API
// ------------------------------------------------------------------------
@Override
public final Field comment(String comment) {
return comment(DSL.comment(comment));
}
@Override
public final Field comment(Comment comment) {
return DSL.field(getQualifiedName(), getDataType(), comment);
}
// ------------------------------------------------------------------------
// XXX: Type casts
// ------------------------------------------------------------------------
@Override
public final Field cast(Field field) {
return cast(field.getDataType());
}
@Override
public final Field cast(DataType type) {
return new Cast<>(this, type);
}
@Override
public final Field cast(Class type) {
return cast(DefaultDataType.getDataType(null, type));
}
// ------------------------------------------------------------------------
// XXX: Type coercions
// ------------------------------------------------------------------------
@Override
public final Field coerce(Field field) {
return coerce(field.getDataType());
}
@Override
public final Field coerce(DataType type) {
return new Coerce<>(this, type);
}
@Override
public final Field coerce(Class type) {
return coerce(DefaultDataType.getDataType(null, type));
}
// ------------------------------------------------------------------------
// XXX: Conversion of field into a sort field
// ------------------------------------------------------------------------
@Override
public final SortField asc() {
return sort(SortOrder.ASC);
}
@Override
public final SortField desc() {
return sort(SortOrder.DESC);
}
@Override
public final SortField sortDefault() {
return sort(SortOrder.DEFAULT);
}
@Override
public final SortField sort(SortOrder order) {
return this instanceof NoField n ? n : new SortFieldImpl<>(this, order);
}
@Override
public final SortField sortAsc(Collection sortList) {
Map map = new LinkedHashMap<>();
int i = 0;
for (T value : sortList)
map.put(value, i++);
return sort(map);
}
@Override
@SafeVarargs
public final SortField sortAsc(T... sortList) {
return sortAsc(Arrays.asList(sortList));
}
@Override
public final SortField sortDesc(Collection sortList) {
Map map = new LinkedHashMap<>();
int i = sortList.size();
for (T value : sortList)
map.put(value, i--);
return sort(map);
}
@Override
@SafeVarargs
public final SortField sortDesc(T... sortList) {
return sortDesc(Arrays.asList(sortList));
}
@Override
@SuppressWarnings({ "unchecked", "rawtypes" })
public final SortField sort(Map sortMap) {
return sortMap == null || sortMap.isEmpty()
? DSL.noField((Field) this).sortDefault()
: DSL.case_(this).mapValues(sortMap).asc();
}
@Override
public final SortField nullsFirst() {
return sortDefault().nullsFirst();
}
@Override
public final SortField nullsLast() {
return sortDefault().nullsLast();
}
// -------------------------------------------------------------------------
// Generic predicates
// -------------------------------------------------------------------------
@Override
public final Condition eq(T arg2) {
return new Eq<>(this, Tools.field(arg2, this));
}
@Override
public final Condition eq(Select extends Record1> arg2) {
return new Eq<>(this, DSL.field(arg2));
}
@Override
public final Condition eq(Field arg2) {
return new Eq<>(this, nullSafe(arg2, getDataType()));
}
@Override
public final Condition eq(org.jooq.QuantifiedSelect extends Record1> arg2) {
return new EqQuantified<>(this, arg2);
}
@Override
public final Condition equal(T arg2) {
return eq(arg2);
}
@Override
public final Condition equal(Select extends Record1> arg2) {
return eq(arg2);
}
@Override
public final Condition equal(Field arg2) {
return eq(arg2);
}
@Override
public final Condition equal(org.jooq.QuantifiedSelect extends Record1> arg2) {
return eq(arg2);
}
@Override
public final Condition ge(T arg2) {
return new Ge<>(this, Tools.field(arg2, this));
}
@Override
public final Condition ge(Select extends Record1> arg2) {
return new Ge<>(this, DSL.field(arg2));
}
@Override
public final Condition ge(Field arg2) {
return new Ge<>(this, nullSafe(arg2, getDataType()));
}
@Override
public final Condition ge(org.jooq.QuantifiedSelect extends Record1> arg2) {
return new GeQuantified<>(this, arg2);
}
@Override
public final Condition greaterOrEqual(T arg2) {
return ge(arg2);
}
@Override
public final Condition greaterOrEqual(Select extends Record1> arg2) {
return ge(arg2);
}
@Override
public final Condition greaterOrEqual(Field arg2) {
return ge(arg2);
}
@Override
public final Condition greaterOrEqual(org.jooq.QuantifiedSelect extends Record1> arg2) {
return ge(arg2);
}
@Override
public final Condition greaterThan(T arg2) {
return gt(arg2);
}
@Override
public final Condition greaterThan(Select extends Record1> arg2) {
return gt(arg2);
}
@Override
public final Condition greaterThan(Field arg2) {
return gt(arg2);
}
@Override
public final Condition greaterThan(org.jooq.QuantifiedSelect extends Record1> arg2) {
return gt(arg2);
}
@Override
public final Condition gt(T arg2) {
return new Gt<>(this, Tools.field(arg2, this));
}
@Override
public final Condition gt(Select extends Record1> arg2) {
return new Gt<>(this, DSL.field(arg2));
}
@Override
public final Condition gt(Field arg2) {
return new Gt<>(this, nullSafe(arg2, getDataType()));
}
@Override
public final Condition gt(org.jooq.QuantifiedSelect extends Record1> arg2) {
return new GtQuantified<>(this, arg2);
}
@Override
public final Condition in(Select extends Record1> arg2) {
return new In<>(this, arg2);
}
@Override
public final Condition isDistinctFrom(T arg2) {
return new IsDistinctFrom<>(this, Tools.field(arg2, this));
}
@Override
public final Condition isDistinctFrom(Select extends Record1> arg2) {
return new IsDistinctFrom<>(this, DSL.field(arg2));
}
@Override
public final Condition isDistinctFrom(Field arg2) {
return new IsDistinctFrom<>(this, nullSafe(arg2, getDataType()));
}
@Override
public final Condition isNull() {
return new IsNull(this);
}
@Override
public final Condition isNotDistinctFrom(T arg2) {
return new IsNotDistinctFrom<>(this, Tools.field(arg2, this));
}
@Override
public final Condition isNotDistinctFrom(Select extends Record1> arg2) {
return new IsNotDistinctFrom<>(this, DSL.field(arg2));
}
@Override
public final Condition isNotDistinctFrom(Field arg2) {
return new IsNotDistinctFrom<>(this, nullSafe(arg2, getDataType()));
}
@Override
public final Condition isNotNull() {
return new IsNotNull(this);
}
@Override
public final Condition le(T arg2) {
return new Le<>(this, Tools.field(arg2, this));
}
@Override
public final Condition le(Select extends Record1> arg2) {
return new Le<>(this, DSL.field(arg2));
}
@Override
public final Condition le(Field arg2) {
return new Le<>(this, nullSafe(arg2, getDataType()));
}
@Override
public final Condition le(org.jooq.QuantifiedSelect extends Record1> arg2) {
return new LeQuantified<>(this, arg2);
}
@Override
public final Condition lessOrEqual(T arg2) {
return le(arg2);
}
@Override
public final Condition lessOrEqual(Select extends Record1> arg2) {
return le(arg2);
}
@Override
public final Condition lessOrEqual(Field arg2) {
return le(arg2);
}
@Override
public final Condition lessOrEqual(org.jooq.QuantifiedSelect extends Record1> arg2) {
return le(arg2);
}
@Override
public final Condition lessThan(T arg2) {
return lt(arg2);
}
@Override
public final Condition lessThan(Select extends Record1> arg2) {
return lt(arg2);
}
@Override
public final Condition lessThan(Field arg2) {
return lt(arg2);
}
@Override
public final Condition lessThan(org.jooq.QuantifiedSelect extends Record1> arg2) {
return lt(arg2);
}
@Override
public final LikeEscapeStep like(String pattern) {
return new Like(this, Tools.field(pattern));
}
@Override
public final LikeEscapeStep like(Field pattern) {
return new Like(this, nullSafe(pattern, getDataType()));
}
@Override
public final LikeEscapeStep like(org.jooq.QuantifiedSelect extends Record1> pattern) {
return new LikeQuantified(this, pattern);
}
@Override
public final LikeEscapeStep likeIgnoreCase(String pattern) {
return new LikeIgnoreCase(this, Tools.field(pattern));
}
@Override
public final LikeEscapeStep likeIgnoreCase(Field pattern) {
return new LikeIgnoreCase(this, nullSafe(pattern, getDataType()));
}
@Override
public final Condition lt(T arg2) {
return new Lt<>(this, Tools.field(arg2, this));
}
@Override
public final Condition lt(Select extends Record1> arg2) {
return new Lt<>(this, DSL.field(arg2));
}
@Override
public final Condition lt(Field arg2) {
return new Lt<>(this, nullSafe(arg2, getDataType()));
}
@Override
public final Condition lt(org.jooq.QuantifiedSelect extends Record1> arg2) {
return new LtQuantified<>(this, arg2);
}
@Override
public final Condition ne(T arg2) {
return new Ne<>(this, Tools.field(arg2, this));
}
@Override
public final Condition ne(Select extends Record1> arg2) {
return new Ne<>(this, DSL.field(arg2));
}
@Override
public final Condition ne(Field arg2) {
return new Ne<>(this, nullSafe(arg2, getDataType()));
}
@Override
public final Condition ne(org.jooq.QuantifiedSelect extends Record1> arg2) {
return new NeQuantified<>(this, arg2);
}
@Override
public final Condition notEqual(T arg2) {
return ne(arg2);
}
@Override
public final Condition notEqual(Select extends Record1> arg2) {
return ne(arg2);
}
@Override
public final Condition notEqual(Field arg2) {
return ne(arg2);
}
@Override
public final Condition notEqual(org.jooq.QuantifiedSelect extends Record1> arg2) {
return ne(arg2);
}
@Override
public final Condition notIn(Select extends Record1> arg2) {
return new NotIn<>(this, arg2);
}
@Override
public final LikeEscapeStep notLike(String pattern) {
return new NotLike(this, Tools.field(pattern));
}
@Override
public final LikeEscapeStep notLike(Field pattern) {
return new NotLike(this, nullSafe(pattern, getDataType()));
}
@Override
public final LikeEscapeStep notLike(org.jooq.QuantifiedSelect extends Record1> pattern) {
return new NotLikeQuantified(this, pattern);
}
@Override
public final LikeEscapeStep notLikeIgnoreCase(String pattern) {
return new NotLikeIgnoreCase(this, Tools.field(pattern));
}
@Override
public final LikeEscapeStep notLikeIgnoreCase(Field pattern) {
return new NotLikeIgnoreCase(this, nullSafe(pattern, getDataType()));
}
@Override
public final LikeEscapeStep notSimilarTo(String pattern) {
return new NotSimilarTo(this, Tools.field(pattern));
}
@Override
public final LikeEscapeStep notSimilarTo(Field pattern) {
return new NotSimilarTo(this, nullSafe(pattern, getDataType()));
}
@Override
public final LikeEscapeStep notSimilarTo(org.jooq.QuantifiedSelect extends Record1> pattern) {
return new NotSimilarToQuantified(this, pattern);
}
@Override
public final LikeEscapeStep similarTo(String pattern) {
return new SimilarTo(this, Tools.field(pattern));
}
@Override
public final LikeEscapeStep similarTo(Field pattern) {
return new SimilarTo(this, nullSafe(pattern, getDataType()));
}
@Override
public final LikeEscapeStep similarTo(org.jooq.QuantifiedSelect extends Record1> pattern) {
return new SimilarToQuantified(this, pattern);
}
// -------------------------------------------------------------------------
// XML predicates
// -------------------------------------------------------------------------
@Override
public final Condition isDocument() {
return new IsDocument(this);
}
@Override
public final Condition isNotDocument() {
return new IsNotDocument(this);
}
// -------------------------------------------------------------------------
// JSON predicates
// -------------------------------------------------------------------------
@Override
public final Condition isJson() {
return new IsJson(this);
}
@Override
public final Condition isNotJson() {
return new IsNotJson(this);
}
// -------------------------------------------------------------------------
// Numeric functions
// -------------------------------------------------------------------------
@Override
@SuppressWarnings({ "unchecked", "rawtypes" })
public final Field bitAnd(T arg2) {
return DSL.bitAnd((Field) this, (Number) arg2);
}
@Override
@SuppressWarnings({ "unchecked", "rawtypes" })
public final Field bitAnd(Field arg2) {
return DSL.bitAnd((Field) this, (Field) arg2);
}
@Override
@SuppressWarnings({ "unchecked", "rawtypes" })
public final Field bitNand(T arg2) {
return DSL.bitNand((Field) this, (Number) arg2);
}
@Override
@SuppressWarnings({ "unchecked", "rawtypes" })
public final Field bitNand(Field arg2) {
return DSL.bitNand((Field) this, (Field) arg2);
}
@Override
@SuppressWarnings({ "unchecked", "rawtypes" })
public final Field bitNor(T arg2) {
return DSL.bitNor((Field) this, (Number) arg2);
}
@Override
@SuppressWarnings({ "unchecked", "rawtypes" })
public final Field bitNor(Field arg2) {
return DSL.bitNor((Field) this, (Field) arg2);
}
@Override
public final Field bitNot() {
return DSL.bitNot((Field) this);
}
@Override
@SuppressWarnings({ "unchecked", "rawtypes" })
public final Field bitOr(T arg2) {
return DSL.bitOr((Field) this, (Number) arg2);
}
@Override
@SuppressWarnings({ "unchecked", "rawtypes" })
public final Field bitOr(Field arg2) {
return DSL.bitOr((Field) this, (Field) arg2);
}
@Override
@SuppressWarnings({ "unchecked", "rawtypes" })
public final Field bitXNor(T arg2) {
return DSL.bitXNor((Field) this, (Number) arg2);
}
@Override
@SuppressWarnings({ "unchecked", "rawtypes" })
public final Field bitXNor(Field arg2) {
return DSL.bitXNor((Field) this, (Field) arg2);
}
@Override
@SuppressWarnings({ "unchecked", "rawtypes" })
public final Field bitXor(T arg2) {
return DSL.bitXor((Field) this, (Number) arg2);
}
@Override
@SuppressWarnings({ "unchecked", "rawtypes" })
public final Field bitXor(Field arg2) {
return DSL.bitXor((Field) this, (Field) arg2);
}
@Override
@SuppressWarnings({ "unchecked", "rawtypes" })
public final Field mod(Number divisor) {
return new Mod(this, Tools.field(divisor));
}
@Override
@SuppressWarnings({ "unchecked", "rawtypes" })
public final Field mod(Field extends Number> divisor) {
return new Mod(this, nullSafe(divisor, getDataType()));
}
@Override
public final Field modulo(Number divisor) {
return mod(divisor);
}
@Override
public final Field modulo(Field extends Number> divisor) {
return mod(divisor);
}
@Override
public final Field rem(Number divisor) {
return mod(divisor);
}
@Override
public final Field rem(Field extends Number> divisor) {
return mod(divisor);
}
@Override
public final Field power(Number exponent) {
return DSL.power((Field) this, exponent);
}
@Override
public final Field power(Field extends Number> exponent) {
return DSL.power((Field) this, exponent);
}
@Override
public final Field pow(Number exponent) {
return power(exponent);
}
@Override
public final Field pow(Field extends Number> exponent) {
return power(exponent);
}
@Override
@SuppressWarnings({ "unchecked", "rawtypes" })
public final Field shl(Number count) {
return DSL.shl((Field) this, count);
}
@Override
@SuppressWarnings({ "unchecked", "rawtypes" })
public final Field shl(Field extends Number> count) {
return DSL.shl((Field) this, count);
}
@Override
@SuppressWarnings({ "unchecked", "rawtypes" })
public final Field shr(Number count) {
return DSL.shr((Field) this, count);
}
@Override
@SuppressWarnings({ "unchecked", "rawtypes" })
public final Field shr(Field extends Number> count) {
return DSL.shr((Field) this, count);
}
// -------------------------------------------------------------------------
// String functions
// -------------------------------------------------------------------------
@Override
public final Condition contains(T content) {
return new Contains<>(this, Tools.field(content, this));
}
@Override
public final Condition contains(Field content) {
return new Contains<>(this, nullSafe(content, getDataType()));
}
@Override
public final Condition containsIgnoreCase(T content) {
return new ContainsIgnoreCase<>(this, Tools.field(content, this));
}
@Override
public final Condition containsIgnoreCase(Field content) {
return new ContainsIgnoreCase<>(this, nullSafe(content, getDataType()));
}
@Override
public final Condition endsWith(T suffix) {
return new EndsWith<>(this, Tools.field(suffix, this));
}
@Override
public final Condition endsWith(Field suffix) {
return new EndsWith<>(this, nullSafe(suffix, getDataType()));
}
@Override
public final Condition endsWithIgnoreCase(T suffix) {
return new EndsWithIgnoreCase<>(this, Tools.field(suffix, this));
}
@Override
public final Condition endsWithIgnoreCase(Field suffix) {
return new EndsWithIgnoreCase<>(this, nullSafe(suffix, getDataType()));
}
@Override
public final Condition startsWith(T prefix) {
return new StartsWith<>(this, Tools.field(prefix, this));
}
@Override
public final Condition startsWith(Field prefix) {
return new StartsWith<>(this, nullSafe(prefix, getDataType()));
}
@Override
public final Condition startsWithIgnoreCase(T prefix) {
return new StartsWithIgnoreCase<>(this, Tools.field(prefix, this));
}
@Override
public final Condition startsWithIgnoreCase(Field prefix) {
return new StartsWithIgnoreCase<>(this, nullSafe(prefix, getDataType()));
}
// ------------------------------------------------------------------------
// XXX: Arithmetic operations
// ------------------------------------------------------------------------
@Override
public final Field neg() {
return new Neg<>(this, false);
}
@Override
public final Field unaryMinus() {
return neg();
}
@Override
public final Field unaryPlus() {
return this;
}
@Override
public final Field add(Number value) {
return add(Tools.field(value));
}
@SuppressWarnings("unchecked")
@Override
public final Field add(Field> value) {
Field> rhs;
if (getDataType().isDateTime() && ((rhs = nullSafe(value)).getDataType().isNumeric() || rhs.getDataType().isInterval()))
return new Expression<>(ADD, false, this, rhs);
else
return new Add(this, (Field) nullSafe(value, getDataType()));
}
@Override
public final Field sub(Number value) {
return sub(Tools.field(value));
}
@SuppressWarnings("unchecked")
@Override
public final Field sub(Field> value) {
Field> rhs;
if (getDataType().isDateTime() && ((rhs = nullSafe(value)).getDataType().isNumeric() || rhs.getDataType().isInterval()))
return new Expression<>(SUBTRACT, false, this, rhs);
else
return new Sub(this, (Field) nullSafe(value, getDataType()));
}
@Override
public final Field mul(Number value) {
return mul(Tools.field(value));
}
@SuppressWarnings("unchecked")
@Override
public final Field mul(Field extends Number> value) {
return new Mul(this, (Field) (getDataType().isTemporal() || nullSafe(value).getDataType().isTemporal()
? nullSafe(value)
: nullSafe(value, getDataType())
));
}
@Override
public final Field div(Number value) {
return div(Tools.field(value));
}
@SuppressWarnings("unchecked")
@Override
public final Field div(Field extends Number> value) {
return new Div(this, (Field) (getDataType().isTemporal() || nullSafe(value).getDataType().isTemporal()
? nullSafe(value)
: nullSafe(value, getDataType())
));
}
// ------------------------------------------------------------------------
// XXX: Arithmetic operation aliases
// ------------------------------------------------------------------------
@Override
public final Field plus(Number value) {
return add(value);
}
@Override
public final Field plus(Field> value) {
return add(value);
}
@Override
public final Field subtract(Number value) {
return sub(value);
}
@Override
public final Field subtract(Field> value) {
return sub(value);
}
@Override
public final Field minus(Number value) {
return sub(value);
}
@Override
public final Field minus(Field> value) {
return sub(value);
}
@Override
public final Field multiply(Number value) {
return mul(value);
}
@Override
public final Field multiply(Field extends Number> value) {
return mul(value);
}
@Override
public final Field times(Number value) {
return mul(value);
}
@Override
public final Field times(Field extends Number> value) {
return mul(value);
}
@Override
public final Field divide(Number value) {
return div(value);
}
@Override
public final Field divide(Field extends Number> value) {
return div(value);
}
// ------------------------------------------------------------------------
// XXX: Conditions created from this field
// ------------------------------------------------------------------------
/**
* [#11200] Nest these constants to prevent initialisation deadlocks.
*/
private static class BooleanValues {
static final List> TRUE_VALUES = Tools.map(Convert.TRUE_VALUES, v -> DSL.inline(v));
static final List> FALSE_VALUES = Tools.map(Convert.FALSE_VALUES, v -> DSL.inline(v));
}
@SuppressWarnings({ "unchecked" })
@Override
public final Condition isTrue() {
Class> type = getType();
if (type == String.class)
return ((Field) this).in(BooleanValues.TRUE_VALUES);
else if (Number.class.isAssignableFrom(type))
return ((Field) this).equal(inline((Number) getDataType().convert(1)));
else if (Boolean.class.isAssignableFrom(type))
return ((Field) this).equal(inline(true, (DataType) getDataType()));
else
return castIfNeeded(this, String.class).in(BooleanValues.TRUE_VALUES);
}
@SuppressWarnings({ "unchecked" })
@Override
public final Condition isFalse() {
Class> type = getType();
if (type == String.class)
return ((Field) this).in(BooleanValues.FALSE_VALUES);
else if (Number.class.isAssignableFrom(type))
return ((Field) this).equal(inline((Number) getDataType().convert(0)));
else if (Boolean.class.isAssignableFrom(type))
return ((Field) this).equal(inline(false, (DataType) getDataType()));
else
return castIfNeeded(this, String.class).in(BooleanValues.FALSE_VALUES);
}
@Override
public final Condition similarTo(String value, char escape) {
return similarTo(Tools.field(value), escape);
}
@Override
public final Condition similarTo(Field field, char escape) {
return similarTo(field).escape(escape);
}
@Override
public final Condition notSimilarTo(String value, char escape) {
return notSimilarTo(Tools.field(value), escape);
}
@Override
public final Condition notSimilarTo(Field field, char escape) {
return notSimilarTo(field).escape(escape);
}
@Override
public final Condition like(String value, char escape) {
return like(value).escape(escape);
}
@Override
public final Condition like(Field field, char escape) {
return like(field).escape(escape);
}
@Override
public final Condition likeIgnoreCase(String value, char escape) {
return likeIgnoreCase(Tools.field(value), escape);
}
@Override
public final Condition likeIgnoreCase(Field field, char escape) {
return likeIgnoreCase(field).escape(escape);
}
@Override
public final Condition likeRegex(String pattern) {
return likeRegex(Tools.field(pattern));
}
@Override
public final Condition likeRegex(Field pattern) {
return new RegexpLike(this, nullSafe(pattern, getDataType()));
}
@Override
public final Condition notLike(String value, char escape) {
return notLike(Tools.field(value), escape);
}
@Override
public final Condition notLike(Field field, char escape) {
return notLike(field).escape(escape);
}
@Override
public final Condition notLikeIgnoreCase(String value, char escape) {
return notLikeIgnoreCase(Tools.field(value), escape);
}
@Override
public final Condition notLikeIgnoreCase(Field field, char escape) {
return notLikeIgnoreCase(field).escape(escape);
}
@Override
public final Condition notLikeRegex(String pattern) {
return likeRegex(pattern).not();
}
@Override
public final Condition notLikeRegex(Field pattern) {
return likeRegex(pattern).not();
}
@Override
public final Condition notContains(T value) {
return contains(value).not();
}
@Override
public final Condition notContains(Field value) {
return contains(value).not();
}
@Override
public final Condition notContainsIgnoreCase(T value) {
return containsIgnoreCase(value).not();
}
@Override
public final Condition notContainsIgnoreCase(Field value) {
return containsIgnoreCase(value).not();
}
private final boolean isAccidentalSelect(T[] values) {
return (values != null && values.length == 1 && values[0] instanceof Select);
}
private final boolean isAccidentalCollection(T[] values) {
return (values != null && values.length == 1 && values[0] instanceof Collection);
}
@SuppressWarnings("unchecked")
@Override
public final Condition in(T... values) {
// [#3362] Prevent "rogue" API usage when using Field