diff --git a/jOOQ/src/main/java/org/jooq/impl/AbstractField.java b/jOOQ/src/main/java/org/jooq/impl/AbstractField.java index 44f98eca36..65d3dc8b9c 100644 --- a/jOOQ/src/main/java/org/jooq/impl/AbstractField.java +++ b/jOOQ/src/main/java/org/jooq/impl/AbstractField.java @@ -347,12 +347,8 @@ abstract class AbstractField extends AbstractTypedNamed implements Field add(Field value) { + public final Field add(Field value) { return new Expression<>(ADD, false, this, nullSafe(value, getDataType())); } @@ -371,12 +367,8 @@ abstract class AbstractField extends AbstractTypedNamed implements FieldExpression to generate neater expressions - */ @Override - public Field mul(Field value) { + public final Field mul(Field value) { return new Expression<>(MULTIPLY, false, this, nullSafe(value, getDataType())); } diff --git a/jOOQ/src/main/java/org/jooq/impl/Concat.java b/jOOQ/src/main/java/org/jooq/impl/Concat.java index b2704d5ff7..b978500f50 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Concat.java +++ b/jOOQ/src/main/java/org/jooq/impl/Concat.java @@ -65,7 +65,6 @@ final class Concat extends AbstractField { this.arguments = arguments; } - @SuppressWarnings("unchecked") @Override public final void accept(Context ctx) { @@ -78,10 +77,7 @@ final class Concat extends AbstractField { return; } - Field first = cast[0]; - Field[] others = new Field[cast.length - 1]; - System.arraycopy(cast, 1, others, 0, others.length); - + ExpressionOperator op = CONCAT; switch (ctx.family()) { @@ -91,7 +87,7 @@ final class Concat extends AbstractField { case MARIADB: case MYSQL: ctx.visit(function("concat", SQLDataType.VARCHAR, cast)); - break; + return; @@ -105,9 +101,12 @@ final class Concat extends AbstractField { - default: - ctx.visit(new Expression<>(CONCAT, false, first, others)); - break; } + + Field expression = new Expression<>(op, false, cast[0], cast[1]); + for (int i = 2; i < cast.length; i++) + expression = new Expression<>(op, false, expression, cast[i]); + + ctx.visit(expression); } } diff --git a/jOOQ/src/main/java/org/jooq/impl/CustomField.java b/jOOQ/src/main/java/org/jooq/impl/CustomField.java index 06ac8a3a62..ad4acc68a8 100644 --- a/jOOQ/src/main/java/org/jooq/impl/CustomField.java +++ b/jOOQ/src/main/java/org/jooq/impl/CustomField.java @@ -101,16 +101,6 @@ public abstract class CustomField extends AbstractField { return super.as(alias); } - @Override - public final Field add(Field value) { - return super.add(value); - } - - @Override - public final Field mul(Field value) { - return super.mul(value); - } - @Override public final boolean declaresFields() { return super.declaresFields(); diff --git a/jOOQ/src/main/java/org/jooq/impl/Expression.java b/jOOQ/src/main/java/org/jooq/impl/Expression.java index 3f89a15115..fd3c71bde1 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Expression.java +++ b/jOOQ/src/main/java/org/jooq/impl/Expression.java @@ -98,8 +98,6 @@ import static org.jooq.impl.Names.N_SQL_TSI_MONTH; import static org.jooq.impl.Names.N_SQL_TSI_SECOND; import static org.jooq.impl.Names.N_STRFTIME; import static org.jooq.impl.Names.N_TIMESTAMPADD; -import static org.jooq.impl.QueryPartListView.wrap; -import static org.jooq.impl.Tools.EMPTY_FIELD; import static org.jooq.impl.Tools.castIfNeeded; import java.sql.Timestamp; @@ -126,48 +124,26 @@ final class Expression extends AbstractField { /** * Generated UID */ - private static final long serialVersionUID = -5522799070693019771L; - private static final Set SUPPORT_BIT_AND = SQLDialect.supportedBy(H2, HSQLDB); - private static final Set SUPPORT_BIT_OR_XOR = SQLDialect.supportedBy(H2, HSQLDB); - private static final Set EMULATE_BIT_XOR = SQLDialect.supportedBy(SQLITE); - private static final Set EMULATE_SHR_SHL = SQLDialect.supportedBy(HSQLDB); - private static final Set HASH_OP_FOR_BIT_XOR = SQLDialect.supportedBy(POSTGRES); - private static final Set SUPPORT_YEAR_TO_SECOND = SQLDialect.supportedBy(POSTGRES); + private static final long serialVersionUID = -5522799070693019771L; + private static final Set SUPPORT_BIT_AND = SQLDialect.supportedBy(H2, HSQLDB); + private static final Set SUPPORT_BIT_OR_XOR = SQLDialect.supportedBy(H2, HSQLDB); + private static final Set EMULATE_BIT_XOR = SQLDialect.supportedBy(SQLITE); + private static final Set EMULATE_SHR_SHL = SQLDialect.supportedBy(HSQLDB); + private static final Set HASH_OP_FOR_BIT_XOR = SQLDialect.supportedBy(POSTGRES); + private static final Set SUPPORT_YEAR_TO_SECOND = SQLDialect.supportedBy(POSTGRES); - private final ExpressionOperator operator; - private final boolean internal; - private final Field lhs; - private final QueryPartList> rhs; - private final Field[] arguments; + private final ExpressionOperator operator; + private final boolean internal; + private final Field lhs; + private final Field rhs; - Expression(ExpressionOperator operator, boolean internal, Field lhs, Field... rhs) { + Expression(ExpressionOperator operator, boolean internal, Field lhs, Field rhs) { super(DSL.name(operator.toSQL()), lhs.getDataType()); this.operator = operator; this.internal = internal; this.lhs = lhs; - this.rhs = new QueryPartList<>(rhs); - this.arguments = Tools.combine(lhs, rhs); - } - - @Override - public final Field add(Field value) { - if (operator == ExpressionOperator.ADD && getDataType().isNumeric()) { - rhs.add(value); - return this; - } - - return super.add(value); - } - - @Override - public final Field mul(Field value) { - if (operator == ExpressionOperator.MULTIPLY && getDataType().isNumeric()) { - rhs.add(value); - return this; - } - - return super.mul(value); + this.rhs = rhs; } @SuppressWarnings("unchecked") @@ -192,17 +168,17 @@ final class Expression extends AbstractField { // DB2, H2 and HSQLDB know functions, instead of operators if (BIT_AND == operator && SUPPORT_BIT_AND.contains(ctx.dialect())) - ctx.visit(function("bitand", getDataType(), arguments)); + ctx.visit(function("bitand", getDataType(), lhs, rhs)); else if (BIT_AND == operator && FIREBIRD == family) - ctx.visit(function("bin_and", getDataType(), arguments)); + ctx.visit(function("bin_and", getDataType(), lhs, rhs)); else if (BIT_XOR == operator && SUPPORT_BIT_OR_XOR.contains(ctx.dialect())) - ctx.visit(function("bitxor", getDataType(), arguments)); + ctx.visit(function("bitxor", getDataType(), lhs, rhs)); else if (BIT_XOR == operator && FIREBIRD == family) - ctx.visit(function("bin_xor", getDataType(), arguments)); + ctx.visit(function("bin_xor", getDataType(), lhs, rhs)); else if (BIT_OR == operator && SUPPORT_BIT_OR_XOR.contains(ctx.dialect())) - ctx.visit(function("bitor", getDataType(), arguments)); + ctx.visit(function("bitor", getDataType(), lhs, rhs)); else if (BIT_OR == operator && FIREBIRD == family) - ctx.visit(function("bin_or", getDataType(), arguments)); + ctx.visit(function("bin_or", getDataType(), lhs, rhs)); @@ -218,7 +194,7 @@ final class Expression extends AbstractField { else if (operator == SHL || operator == SHR) { if (family == H2) - ctx.visit(function(SHL == operator ? "lshift" : "rshift", getDataType(), arguments)); + ctx.visit(function(SHL == operator ? "lshift" : "rshift", getDataType(), lhs, rhs)); @@ -227,7 +203,7 @@ final class Expression extends AbstractField { // Some dialects support shifts as functions else if (FIREBIRD == family) - ctx.visit(function(SHL == operator ? "bin_shl" : "bin_shr", getDataType(), arguments)); + ctx.visit(function(SHL == operator ? "bin_shl" : "bin_shr", getDataType(), lhs, rhs)); // Many dialects don't support shifts. Use multiplication/division instead else if (SHL == operator && EMULATE_SHR_SHL.contains(ctx.dialect())) @@ -258,9 +234,9 @@ final class Expression extends AbstractField { // [#585] Date time arithmetic for numeric or interval RHS else if ((ADD == operator || SUBTRACT == operator) && lhs.getDataType().isDateTime() && - (rhs.get(0).getDataType().isNumeric() || - rhs.get(0).getDataType().isInterval())) - ctx.visit(new DateExpression<>(lhs, operator, rhs.get(0))); + (rhs.getDataType().isNumeric() || + rhs.getDataType().isInterval())) + ctx.visit(new DateExpression<>(lhs, operator, rhs)); // --------------------------------------------------------------------- // XXX: Other operators @@ -284,14 +260,6 @@ final class Expression extends AbstractField { - - - - - - - - @@ -314,7 +282,7 @@ final class Expression extends AbstractField { */ @SuppressWarnings("unchecked") private final Field rhsAsNumber() { - return (Field) rhs.get(0); + return (Field) rhs; } // E.g. +2 00:00:00.000000000 @@ -626,7 +594,7 @@ final class Expression extends AbstractField { case HSQLDB: case POSTGRES: default: - ctx.visit(new DefaultExpression<>(lhs, operator, wrap(rhs))); + ctx.visit(new DefaultExpression<>(lhs, operator, rhs)); break; } } @@ -774,7 +742,7 @@ final class Expression extends AbstractField { case H2: default: - ctx.visit(new DefaultExpression<>(lhs, operator, wrap(rhs))); + ctx.visit(new DefaultExpression<>(lhs, operator, rhs)); break; } } @@ -833,13 +801,13 @@ final class Expression extends AbstractField { /** * Generated UID */ - private static final long serialVersionUID = -5105004317793995419L; + private static final long serialVersionUID = -5105004317793995419L; - private final Field lhs; - private final ExpressionOperator operator; - private final QueryPartCollectionView> rhs; + private final Field lhs; + private final ExpressionOperator operator; + private final Field rhs; - DefaultExpression(Field lhs, ExpressionOperator operator, QueryPartCollectionView> rhs) { + DefaultExpression(Field lhs, ExpressionOperator operator, Field rhs) { super(operator.toName(), lhs.getDataType()); this.lhs = lhs; @@ -854,16 +822,13 @@ final class Expression extends AbstractField { if (operator == BIT_XOR && HASH_OP_FOR_BIT_XOR.contains(ctx.dialect())) op = "#"; - ctx.sql('('); - ctx.visit(lhs); - - for (Field field : rhs) - ctx.sql(' ') - .sql(op) - .sql(' ') - .visit(field); - - ctx.sql(')'); + ctx.sql('(') + .visit(lhs) + .sql(' ') + .sql(op) + .sql(' ') + .visit(rhs) + .sql(')'); } } }