[jOOQ/jOOQ#12425] Move SHL, SHR to API generator

This includes:
- [jOOQ/jOOQ#12427] Extract bitwise operations into their own classes
This commit is contained in:
Lukas Eder 2021-09-14 15:47:21 +02:00
parent cc8970fd86
commit 7c1b93fe35
6 changed files with 438 additions and 156 deletions

View File

@ -16281,6 +16281,118 @@ public class DSL {
return new Round(value);
}
/**
* The <code>SHL</code> function.
* <p>
* Left shift all bits in a number
*
* @param value The number whose bits to shift left.
* @param count The number of bits to shift.
*/
@NotNull
@Support({ CUBRID, FIREBIRD, H2, HSQLDB, MARIADB, MYSQL, POSTGRES, SQLITE, YUGABYTE })
public static <T extends Number> Field<T> shl(T value, Number count) {
return new Shl(Tools.field(value), Tools.field(count));
}
/**
* The <code>SHL</code> function.
* <p>
* Left shift all bits in a number
*
* @param value The number whose bits to shift left.
* @param count The number of bits to shift.
*/
@NotNull
@Support({ CUBRID, FIREBIRD, H2, HSQLDB, MARIADB, MYSQL, POSTGRES, SQLITE, YUGABYTE })
public static <T extends Number> Field<T> shl(T value, Field<? extends Number> count) {
return new Shl(Tools.field(value), count);
}
/**
* The <code>SHL</code> function.
* <p>
* Left shift all bits in a number
*
* @param value The number whose bits to shift left.
* @param count The number of bits to shift.
*/
@NotNull
@Support({ CUBRID, FIREBIRD, H2, HSQLDB, MARIADB, MYSQL, POSTGRES, SQLITE, YUGABYTE })
public static <T extends Number> Field<T> shl(Field<T> value, Number count) {
return new Shl(value, Tools.field(count));
}
/**
* The <code>SHL</code> function.
* <p>
* Left shift all bits in a number
*
* @param value The number whose bits to shift left.
* @param count The number of bits to shift.
*/
@NotNull
@Support({ CUBRID, FIREBIRD, H2, HSQLDB, MARIADB, MYSQL, POSTGRES, SQLITE, YUGABYTE })
public static <T extends Number> Field<T> shl(Field<T> value, Field<? extends Number> count) {
return new Shl(value, count);
}
/**
* The <code>SHR</code> function.
* <p>
* Right shift all bits in a number
*
* @param value The number whose bits to shift right
* @param count The number of bits to shift.
*/
@NotNull
@Support({ CUBRID, FIREBIRD, H2, HSQLDB, MARIADB, MYSQL, POSTGRES, SQLITE, YUGABYTE })
public static <T extends Number> Field<T> shr(T value, Number count) {
return new Shr(Tools.field(value), Tools.field(count));
}
/**
* The <code>SHR</code> function.
* <p>
* Right shift all bits in a number
*
* @param value The number whose bits to shift right
* @param count The number of bits to shift.
*/
@NotNull
@Support({ CUBRID, FIREBIRD, H2, HSQLDB, MARIADB, MYSQL, POSTGRES, SQLITE, YUGABYTE })
public static <T extends Number> Field<T> shr(T value, Field<? extends Number> count) {
return new Shr(Tools.field(value), count);
}
/**
* The <code>SHR</code> function.
* <p>
* Right shift all bits in a number
*
* @param value The number whose bits to shift right
* @param count The number of bits to shift.
*/
@NotNull
@Support({ CUBRID, FIREBIRD, H2, HSQLDB, MARIADB, MYSQL, POSTGRES, SQLITE, YUGABYTE })
public static <T extends Number> Field<T> shr(Field<T> value, Number count) {
return new Shr(value, Tools.field(count));
}
/**
* The <code>SHR</code> function.
* <p>
* Right shift all bits in a number
*
* @param value The number whose bits to shift right
* @param count The number of bits to shift.
*/
@NotNull
@Support({ CUBRID, FIREBIRD, H2, HSQLDB, MARIADB, MYSQL, POSTGRES, SQLITE, YUGABYTE })
public static <T extends Number> Field<T> shr(Field<T> value, Field<? extends Number> count) {
return new Shr(value, count);
}
/**
* The <code>SIGN</code> function.
* <p>
@ -22622,108 +22734,6 @@ public class DSL {
return new Expression<>(ExpressionOperator.BIT_XNOR, false, Tools.nullSafe(field1), Tools.nullSafe(field2));
}
/**
* The bitwise left shift operator.
*
* @see #shl(Field, Field)
* @see #power(Field, Number)
*/
@NotNull
@Support({ CUBRID, FIREBIRD, H2, HSQLDB, MARIADB, MYSQL, POSTGRES, SQLITE, YUGABYTE })
public static <T extends Number> Field<T> shl(T value1, Number value2) {
return shl(Tools.field(value1), Tools.field(value2));
}
/**
* The bitwise left shift operator.
*
* @see #shl(Field, Field)
* @see #power(Field, Number)
*/
@NotNull
@Support({ CUBRID, FIREBIRD, H2, HSQLDB, MARIADB, MYSQL, POSTGRES, SQLITE, YUGABYTE })
public static <T extends Number> Field<T> shl(T value1, Field<? extends Number> value2) {
return shl(Tools.field(value1), Tools.nullSafe(value2));
}
/**
* The bitwise left shift operator.
*
* @see #shl(Field, Field)
* @see #power(Field, Number)
*/
@NotNull
@Support({ CUBRID, FIREBIRD, H2, HSQLDB, MARIADB, MYSQL, POSTGRES, SQLITE, YUGABYTE })
public static <T extends Number> Field<T> shl(Field<T> value1, Number value2) {
return shl(Tools.nullSafe(value1), Tools.field(value2));
}
/**
* The bitwise left shift operator.
* <p>
* Some dialects natively support this using <code>[field1] &lt;&lt; [field2]</code>.
* jOOQ emulates this operator in some dialects using
* <code>[field1] * power(2, [field2])</code>, where power might also be emulated.
*
* @see #power(Field, Field)
*/
@NotNull
@Support({ CUBRID, FIREBIRD, H2, HSQLDB, MARIADB, MYSQL, POSTGRES, SQLITE, YUGABYTE })
public static <T extends Number> Field<T> shl(Field<T> field1, Field<? extends Number> field2) {
return new Expression<>(ExpressionOperator.SHL, false, Tools.nullSafe(field1), Tools.nullSafe(field2));
}
/**
* The bitwise right shift operator.
*
* @see #shr(Field, Field)
* @see #power(Field, Number)
*/
@NotNull
@Support({ CUBRID, FIREBIRD, H2, HSQLDB, MARIADB, MYSQL, POSTGRES, SQLITE, YUGABYTE })
public static <T extends Number> Field<T> shr(T value1, Number value2) {
return shr(Tools.field(value1), Tools.field(value2));
}
/**
* The bitwise right shift operator.
*
* @see #shr(Field, Field)
* @see #power(Field, Number)
*/
@NotNull
@Support({ CUBRID, FIREBIRD, H2, HSQLDB, MARIADB, MYSQL, POSTGRES, SQLITE, YUGABYTE })
public static <T extends Number> Field<T> shr(T value1, Field<? extends Number> value2) {
return shr(Tools.field(value1), Tools.nullSafe(value2));
}
/**
* The bitwise right shift operator.
*
* @see #shr(Field, Field)
* @see #power(Field, Number)
*/
@NotNull
@Support({ CUBRID, FIREBIRD, H2, HSQLDB, MARIADB, MYSQL, POSTGRES, SQLITE, YUGABYTE })
public static <T extends Number> Field<T> shr(Field<T> value1, Number value2) {
return shr(Tools.nullSafe(value1), Tools.field(value2));
}
/**
* The bitwise right shift operator.
* <p>
* Some dialects natively support this using <code>[field1] &gt;&gt; [field2]</code>.
* jOOQ emulates this operator in some dialects using
* <code>[field1] / power(2, [field2])</code>, where power might also be emulated.
*
* @see #power(Field, Field)
*/
@NotNull
@Support({ CUBRID, FIREBIRD, H2, HSQLDB, MARIADB, MYSQL, POSTGRES, SQLITE, YUGABYTE })
public static <T extends Number> Field<T> shr(Field<T> field1, Field<? extends Number> field2) {
return new Expression<>(ExpressionOperator.SHR, false, Tools.nullSafe(field1), Tools.nullSafe(field2));
}
// ------------------------------------------------------------------------
// XXX Mathematical functions
// ------------------------------------------------------------------------

View File

@ -77,8 +77,6 @@ import static org.jooq.impl.ExpressionOperator.BIT_OR;
import static org.jooq.impl.ExpressionOperator.BIT_XNOR;
import static org.jooq.impl.ExpressionOperator.BIT_XOR;
import static org.jooq.impl.ExpressionOperator.MULTIPLY;
import static org.jooq.impl.ExpressionOperator.SHL;
import static org.jooq.impl.ExpressionOperator.SHR;
import static org.jooq.impl.ExpressionOperator.SUBTRACT;
import static org.jooq.impl.Internal.iadd;
import static org.jooq.impl.Internal.idiv;
@ -150,7 +148,6 @@ final class Expression<T> extends AbstractTransformable<T> {
private static final Set<SQLDialect> SUPPORT_BIT_AND = SQLDialect.supportedBy(H2, HSQLDB);
private static final Set<SQLDialect> SUPPORT_BIT_OR_XOR = SQLDialect.supportedBy(H2, HSQLDB);
private static final Set<SQLDialect> EMULATE_BIT_XOR = SQLDialect.supportedBy(SQLITE);
private static final Set<SQLDialect> EMULATE_SHR_SHL = SQLDialect.supportedBy(HSQLDB);
private static final Set<SQLDialect> HASH_OP_FOR_BIT_XOR = SQLDialect.supportedBy(POSTGRES, YUGABYTE);
private static final Set<SQLDialect> SUPPORT_YEAR_TO_SECOND = SQLDialect.supportedBy(POSTGRES, YUGABYTE);
@ -232,45 +229,6 @@ final class Expression<T> extends AbstractTransformable<T> {
DSL.bitNot(DSL.bitAnd(lhsAsNumber(), rhsAsNumber())),
DSL.bitOr(lhsAsNumber(), rhsAsNumber())));
else if (operator == SHL || operator == SHR) {
switch (family) {
case FIREBIRD:
ctx.visit(function(SHL == operator ? N_BIN_SHL : N_BIN_SHR, getDataType(), lhs, rhs));
break;
case H2:
ctx.visit(function(SHL == operator ? N_LSHIFT : N_RSHIFT, getDataType(), lhs, rhs));
break;
default:
// Many dialects don't support shifts. Use multiplication/division instead
if (SHL == operator && EMULATE_SHR_SHL.contains(ctx.dialect()))
ctx.visit(imul(lhs, (Field<? extends Number>) castIfNeeded(DSL.power(two(), rhsAsNumber()), lhs)));
// [#3962] This emulation is expensive. If this is emulated, BitCount should
// use division instead of SHR directly
else if (SHR == operator && EMULATE_SHR_SHL.contains(ctx.dialect()))
ctx.visit(idiv(lhs, (Field<? extends Number>) castIfNeeded(DSL.power(two(), rhsAsNumber()), lhs)));
// Use the default operator expression for all other cases
else
ctx.visit(new DefaultExpression<>(lhs, operator, rhs));
break;
}
}
// These operators are not supported in any dialect
else if (BIT_NAND == operator)
ctx.visit(DSL.bitNot(DSL.bitAnd(lhsAsNumber(), rhsAsNumber())));
@ -323,8 +281,6 @@ final class Expression<T> extends AbstractTransformable<T> {

View File

@ -111,16 +111,6 @@ enum ExpressionOperator {
*/
BIT_XNOR("~^"),
/**
* Bitwise shift left
*/
SHL("<<"),
/**
* Bitwise shift right
*/
SHR(">>"),
;
private final String sql;

View File

@ -326,6 +326,8 @@ final class Names {
static final Name N_SGN = unquotedName("sgn");
static final Name N_SHIFTLEFT = unquotedName("shiftleft");
static final Name N_SHIFTRIGHT = unquotedName("shiftright");
static final Name N_SHL = unquotedName("shl");
static final Name N_SHR = unquotedName("shr");
static final Name N_SIGN = unquotedName("sign");
static final Name N_SIN = unquotedName("sin");
static final Name N_SINH = unquotedName("sinh");

View File

@ -0,0 +1,162 @@
/*
* 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 static org.jooq.impl.DSL.*;
import static org.jooq.impl.Internal.*;
import static org.jooq.impl.Keywords.*;
import static org.jooq.impl.Names.*;
import static org.jooq.impl.SQLDataType.*;
import static org.jooq.impl.Tools.*;
import static org.jooq.impl.Tools.BooleanDataKey.*;
import static org.jooq.impl.Tools.DataExtendedKey.*;
import static org.jooq.impl.Tools.DataKey.*;
import static org.jooq.SQLDialect.*;
import org.jooq.*;
import org.jooq.Record;
import org.jooq.conf.*;
import org.jooq.impl.*;
import org.jooq.tools.*;
import java.util.*;
/**
* The <code>SHL</code> statement.
*/
@SuppressWarnings({ "rawtypes", "unchecked", "unused" })
final class Shl<T extends Number>
extends
AbstractField<T>
{
private final Field<T> value;
private final Field<? extends Number> count;
Shl(
Field<T> value,
Field<? extends Number> count
) {
super(
N_SHL,
allNotNull((DataType) dataType(INTEGER, value, false), value, count)
);
this.value = nullSafeNotNull(value, INTEGER);
this.count = nullSafeNotNull(count, INTEGER);
}
// -------------------------------------------------------------------------
// XXX: QueryPart API
// -------------------------------------------------------------------------
@Override
public final void accept(Context<?> ctx) {
switch (ctx.family()) {
case FIREBIRD:
ctx.visit(function(N_BIN_SHL, getDataType(), value, count));
break;
case H2:
ctx.visit(function(N_LSHIFT, getDataType(), value, count));
break;
case HSQLDB:
ctx.visit(imul(value, (Field<? extends Number>) castIfNeeded(DSL.power(two(), count), value)));
break;
default:
ctx.sql('(').visit(value).sql(" << ").visit(count).sql(')');
break;
}
}
// -------------------------------------------------------------------------
// The Object API
// -------------------------------------------------------------------------
@Override
public boolean equals(Object that) {
if (that instanceof Shl) {
return
StringUtils.equals(value, ((Shl) that).value) &&
StringUtils.equals(count, ((Shl) that).count)
;
}
else
return super.equals(that);
}
}

View File

@ -0,0 +1,162 @@
/*
* 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 static org.jooq.impl.DSL.*;
import static org.jooq.impl.Internal.*;
import static org.jooq.impl.Keywords.*;
import static org.jooq.impl.Names.*;
import static org.jooq.impl.SQLDataType.*;
import static org.jooq.impl.Tools.*;
import static org.jooq.impl.Tools.BooleanDataKey.*;
import static org.jooq.impl.Tools.DataExtendedKey.*;
import static org.jooq.impl.Tools.DataKey.*;
import static org.jooq.SQLDialect.*;
import org.jooq.*;
import org.jooq.Record;
import org.jooq.conf.*;
import org.jooq.impl.*;
import org.jooq.tools.*;
import java.util.*;
/**
* The <code>SHR</code> statement.
*/
@SuppressWarnings({ "rawtypes", "unchecked", "unused" })
final class Shr<T extends Number>
extends
AbstractField<T>
{
private final Field<T> value;
private final Field<? extends Number> count;
Shr(
Field<T> value,
Field<? extends Number> count
) {
super(
N_SHR,
allNotNull((DataType) dataType(INTEGER, value, false), value, count)
);
this.value = nullSafeNotNull(value, INTEGER);
this.count = nullSafeNotNull(count, INTEGER);
}
// -------------------------------------------------------------------------
// XXX: QueryPart API
// -------------------------------------------------------------------------
@Override
public final void accept(Context<?> ctx) {
switch (ctx.family()) {
case FIREBIRD:
ctx.visit(function(N_BIN_SHR, getDataType(), value, count));
break;
case H2:
ctx.visit(function(N_RSHIFT, getDataType(), value, count));
break;
case HSQLDB:
ctx.visit(idiv(value, (Field<? extends Number>) castIfNeeded(DSL.power(two(), count), value)));
break;
default:
ctx.sql('(').visit(value).sql(" >> ").visit(count).sql(')');
break;
}
}
// -------------------------------------------------------------------------
// The Object API
// -------------------------------------------------------------------------
@Override
public boolean equals(Object that) {
if (that instanceof Shr) {
return
StringUtils.equals(value, ((Shr) that).value) &&
StringUtils.equals(count, ((Shr) that).count)
;
}
else
return super.equals(that);
}
}