Add type property to Operator

This commit is contained in:
Timo Westkämper 2015-02-09 20:59:17 +02:00
parent 15e4f79625
commit 9026fdad91
13 changed files with 440 additions and 303 deletions

View File

@ -17,7 +17,9 @@ import java.util.List;
import javax.annotation.concurrent.Immutable;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.primitives.Primitives;
/**
@ -50,6 +52,8 @@ public class OperationImpl<T> extends ExpressionBase<T> implements Operation<T>
public OperationImpl(Class<? extends T> type, Operator operator, ImmutableList<Expression<?>> args) {
super(type);
Class<?> wrapped = Primitives.wrap(type);
Preconditions.checkArgument(operator.getType().isAssignableFrom(wrapped), operator.name());
this.operator = operator;
this.args = args;
}

View File

@ -28,5 +28,12 @@ public interface Operator extends Serializable{
* @return
*/
String name();
/**
* Get the result type of the operator
*
* @return
*/
Class<?> getType();
}

View File

@ -25,96 +25,106 @@ import com.google.common.collect.ImmutableSet;
public enum Ops implements Operator {
// general
EQ,
NE,
IS_NULL,
IS_NOT_NULL,
INSTANCE_OF,
NUMCAST,
STRING_CAST,
ALIAS,
LIST,
SINGLETON,
ORDINAL,
WRAPPED,
EQ(Boolean.class),
NE(Boolean.class),
IS_NULL(Boolean.class),
IS_NOT_NULL(Boolean.class),
INSTANCE_OF(Boolean.class),
NUMCAST(Number.class),
STRING_CAST(String.class),
ALIAS(Object.class),
LIST(Object.class),
SINGLETON(Object.class),
ORDINAL(Integer.class),
WRAPPED(Object.class),
// collection
IN, // cmp. contains
NOT_IN,
COL_IS_EMPTY,
COL_SIZE,
IN(Boolean.class), // cmp. contains
NOT_IN(Boolean.class),
COL_IS_EMPTY(Boolean.class),
COL_SIZE(Integer.class),
// array
ARRAY_SIZE,
ARRAY_SIZE(Number.class),
// map
CONTAINS_KEY,
CONTAINS_VALUE,
MAP_SIZE,
MAP_IS_EMPTY,
CONTAINS_KEY(Boolean.class),
CONTAINS_VALUE(Boolean.class),
MAP_SIZE(Integer.class),
MAP_IS_EMPTY(Boolean.class),
// Boolean
AND,
NOT,
OR,
XNOR,
XOR,
AND(Boolean.class),
NOT(Boolean.class),
OR(Boolean.class),
XNOR(Boolean.class),
XOR(Boolean.class),
// Comparable
BETWEEN,
GOE,
GT,
LOE,
LT,
BETWEEN(Boolean.class),
GOE(Boolean.class),
GT(Boolean.class),
LOE(Boolean.class),
LT(Boolean.class),
// Number
NEGATE,
ADD,
DIV,
MULT,
SUB,
MOD,
NEGATE(Number.class),
ADD(Number.class),
DIV(Number.class),
MULT(Number.class),
SUB(Number.class),
MOD(Number.class),
// String
CHAR_AT,
CONCAT,
LOWER,
SUBSTR_1ARG,
SUBSTR_2ARGS,
TRIM,
UPPER,
MATCHES,
MATCHES_IC,
STRING_LENGTH,
STRING_IS_EMPTY,
STARTS_WITH,
STARTS_WITH_IC,
INDEX_OF_2ARGS,
INDEX_OF,
EQ_IGNORE_CASE,
ENDS_WITH,
ENDS_WITH_IC,
STRING_CONTAINS,
STRING_CONTAINS_IC,
LIKE,
LIKE_ESCAPE,
CHAR_AT(Character.class),
CONCAT(String.class),
LOWER(String.class),
SUBSTR_1ARG(String.class),
SUBSTR_2ARGS(String.class),
TRIM(String.class),
UPPER(String.class),
MATCHES(Boolean.class),
MATCHES_IC(Boolean.class),
STRING_LENGTH(Integer.class),
STRING_IS_EMPTY(Boolean.class),
STARTS_WITH(Boolean.class),
STARTS_WITH_IC(Boolean.class),
INDEX_OF_2ARGS(Integer.class),
INDEX_OF(Integer.class),
EQ_IGNORE_CASE(Boolean.class),
ENDS_WITH(Boolean.class),
ENDS_WITH_IC(Boolean.class),
STRING_CONTAINS(Boolean.class),
STRING_CONTAINS_IC(Boolean.class),
LIKE(Boolean.class),
LIKE_ESCAPE(Boolean.class),
// case
CASE,
CASE_WHEN,
CASE_ELSE,
CASE(Object.class),
CASE_WHEN(Object.class),
CASE_ELSE(Object.class),
// case for eq
CASE_EQ,
CASE_EQ_WHEN,
CASE_EQ_ELSE,
CASE_EQ(Object.class),
CASE_EQ_WHEN(Object.class),
CASE_EQ_ELSE(Object.class),
// coalesce
COALESCE,
NULLIF,
COALESCE(Object.class),
NULLIF(Object.class),
// subquery operations
EXISTS;
EXISTS(Boolean.class);
private final Class<?> type;
private Ops(Class<?> type) {
this.type = type;
}
public Class<?> getType() {
return type;
}
public static final Set<Operator> equalsOps = ImmutableSet.<Operator>of(EQ);
@ -135,16 +145,26 @@ public enum Ops implements Operator {
*/
@SuppressWarnings("unchecked")
public enum AggOps implements Operator {
BOOLEAN_ALL,
BOOLEAN_ANY,
MAX_AGG,
MIN_AGG,
AVG_AGG,
SUM_AGG,
COUNT_AGG,
COUNT_DISTINCT_AGG,
COUNT_DISTINCT_ALL_AGG,
COUNT_ALL_AGG
BOOLEAN_ALL(Boolean.class),
BOOLEAN_ANY(Boolean.class),
MAX_AGG(Comparable.class),
MIN_AGG(Comparable.class),
AVG_AGG(Number.class),
SUM_AGG(Number.class),
COUNT_AGG(Number.class),
COUNT_DISTINCT_AGG(Number.class),
COUNT_DISTINCT_ALL_AGG(Number.class),
COUNT_ALL_AGG(Number.class);
private final Class<?> type;
private AggOps(Class<?> type) {
this.type = type;
}
public Class<?> getType() {
return type;
}
}
/**
@ -152,11 +172,21 @@ public enum Ops implements Operator {
*/
@SuppressWarnings("unchecked")
public enum QuantOps implements Operator {
AVG_IN_COL,
MAX_IN_COL,
MIN_IN_COL,
ANY,
ALL
AVG_IN_COL(Number.class),
MAX_IN_COL(Comparable.class),
MIN_IN_COL(Comparable.class),
ANY(Object.class),
ALL(Object.class);
private final Class<?> type;
private QuantOps(Class<?> type) {
this.type = type;
}
public Class<?> getType() {
return type;
}
}
/**
@ -164,44 +194,54 @@ public enum Ops implements Operator {
*/
@SuppressWarnings("unchecked")
public enum DateTimeOps implements Operator {
DATE,
CURRENT_DATE,
CURRENT_TIME,
CURRENT_TIMESTAMP,
ADD_YEARS,
ADD_MONTHS,
ADD_WEEKS,
ADD_DAYS,
ADD_HOURS,
ADD_MINUTES,
ADD_SECONDS,
DIFF_YEARS,
DIFF_MONTHS,
DIFF_WEEKS,
DIFF_DAYS,
DIFF_HOURS,
DIFF_MINUTES,
DIFF_SECONDS,
TRUNC_YEAR,
TRUNC_MONTH,
TRUNC_WEEK,
TRUNC_DAY,
TRUNC_HOUR,
TRUNC_MINUTE,
TRUNC_SECOND,
HOUR,
MINUTE,
MONTH,
SECOND,
MILLISECOND,
SYSDATE,
YEAR,
WEEK,
YEAR_MONTH,
YEAR_WEEK,
DAY_OF_WEEK,
DAY_OF_MONTH,
DAY_OF_YEAR
DATE(Comparable.class),
CURRENT_DATE(Comparable.class),
CURRENT_TIME(Comparable.class),
CURRENT_TIMESTAMP(Comparable.class),
ADD_YEARS(Comparable.class),
ADD_MONTHS(Comparable.class),
ADD_WEEKS(Comparable.class),
ADD_DAYS(Comparable.class),
ADD_HOURS(Comparable.class),
ADD_MINUTES(Comparable.class),
ADD_SECONDS(Comparable.class),
DIFF_YEARS(Comparable.class),
DIFF_MONTHS(Comparable.class),
DIFF_WEEKS(Comparable.class),
DIFF_DAYS(Comparable.class),
DIFF_HOURS(Comparable.class),
DIFF_MINUTES(Comparable.class),
DIFF_SECONDS(Comparable.class),
TRUNC_YEAR(Comparable.class),
TRUNC_MONTH(Comparable.class),
TRUNC_WEEK(Comparable.class),
TRUNC_DAY(Comparable.class),
TRUNC_HOUR(Comparable.class),
TRUNC_MINUTE(Comparable.class),
TRUNC_SECOND(Comparable.class),
HOUR(Integer.class),
MINUTE(Integer.class),
MONTH(Integer.class),
SECOND(Integer.class),
MILLISECOND(Integer.class),
SYSDATE(Comparable.class),
YEAR(Integer.class),
WEEK(Integer.class),
YEAR_MONTH(Integer.class),
YEAR_WEEK(Integer.class),
DAY_OF_WEEK(Integer.class),
DAY_OF_MONTH(Integer.class),
DAY_OF_YEAR(Integer.class);
private final Class<?> type;
private DateTimeOps(Class<?> type) {
this.type = type;
}
public Class<?> getType() {
return type;
}
}
/**
@ -209,50 +249,70 @@ public enum Ops implements Operator {
*
*/
public enum MathOps implements Operator {
ABS,
ACOS,
ASIN,
ATAN,
CEIL,
COS,
TAN,
SQRT,
SIN,
ROUND,
ROUND2,
RANDOM,
RANDOM2,
POWER,
MIN,
MAX,
LOG,
FLOOR,
EXP,
COSH,
COT,
COTH,
DEG,
LN,
RAD,
SIGN,
SINH,
TANH
ABS(Number.class),
ACOS(Number.class),
ASIN(Number.class),
ATAN(Number.class),
CEIL(Number.class),
COS(Number.class),
TAN(Number.class),
SQRT(Number.class),
SIN(Number.class),
ROUND(Number.class),
ROUND2(Number.class),
RANDOM(Number.class),
RANDOM2(Number.class),
POWER(Number.class),
MIN(Number.class),
MAX(Number.class),
LOG(Number.class),
FLOOR(Number.class),
EXP(Number.class),
COSH(Number.class),
COT(Number.class),
COTH(Number.class),
DEG(Number.class),
LN(Number.class),
RAD(Number.class),
SIGN(Number.class),
SINH(Number.class),
TANH(Number.class);
private final Class<?> type;
private MathOps(Class<?> type) {
this.type = type;
}
public Class<?> getType() {
return type;
}
}
/**
* String operators
*/
public enum StringOps implements Operator {
LEFT,
RIGHT,
LTRIM,
RTRIM,
LPAD,
RPAD,
LPAD2,
RPAD2,
LOCATE,
LOCATE2
LEFT(String.class),
RIGHT(String.class),
LTRIM(String.class),
RTRIM(String.class),
LPAD(String.class),
RPAD(String.class),
LPAD2(String.class),
RPAD2(String.class),
LOCATE(Number.class),
LOCATE2(Number.class);
private final Class<?> type;
private StringOps(Class<?> type) {
this.type = type;
}
public Class<?> getType() {
return type;
}
}
}

View File

@ -66,5 +66,9 @@ public enum PathType implements Operator {
* Root path
*/
VARIABLE;
public Class<?> getType() {
return Object.class;
}
}

View File

@ -45,9 +45,9 @@ public class OperationTest {
operations.add(new ComparableOperation(String.class, Ops.SUBSTR_1ARG, args));
operations.add(new DateOperation(Date.class, Ops.DateTimeOps.CURRENT_DATE, args));
operations.add(new DateTimeOperation(Date.class,Ops.DateTimeOps.CURRENT_TIMESTAMP, args));
operations.add(new EnumOperation(ExampleEnum.class,Ops.IS_NOT_NULL, args));
operations.add(new EnumOperation(ExampleEnum.class,Ops.ALIAS, args));
operations.add(new NumberOperation(Integer.class,Ops.ADD, args));
operations.add(new SimpleOperation(String.class,Ops.EQ, args));
operations.add(new SimpleOperation(String.class,Ops.TRIM, args));
operations.add(new StringOperation(Ops.CONCAT, args));
operations.add(new TimeOperation(Time.class,Ops.DateTimeOps.CURRENT_TIME, args));

View File

@ -20,12 +20,22 @@ import com.querydsl.core.types.Operator;
*
*/
public enum JPQLOps implements Operator {
TREAT,
INDEX,
TYPE,
CAST,
MEMBER_OF,
NOT_MEMBER_OF,
KEY,
VALUE
TREAT(Object.class),
INDEX(Integer.class),
TYPE(String.class),
CAST(Object.class),
MEMBER_OF(Boolean.class),
NOT_MEMBER_OF(Boolean.class),
KEY(Object.class),
VALUE(Object.class);
private final Class<?> type;
private JPQLOps(Class<?> type) {
this.type = type;
}
public Class<?> getType() {
return type;
}
}

View File

@ -34,6 +34,7 @@ public class JPAQueryMutability2Test implements JPATest {
private final Operator customOperator = new Operator() {
public String name() { return "custom"; }
public String toString() { return name(); }
public Class<?> getType() { return Object.class; }
};
private final JPQLTemplates customTemplates = new HQLTemplates() {{

View File

@ -20,7 +20,17 @@ import com.querydsl.core.types.Operator;
*
*/
public enum LuceneOps implements Operator {
LUCENE_QUERY,
PHRASE,
TERM
LUCENE_QUERY(Object.class),
PHRASE(String.class),
TERM(String.class);
private final Class<?> type;
private LuceneOps(Class<?> type) {
this.type = type;
}
public Class<?> getType() {
return type;
}
}

View File

@ -20,7 +20,17 @@ import com.querydsl.core.types.Operator;
*
*/
public enum LuceneOps implements Operator {
LUCENE_QUERY,
PHRASE,
TERM
LUCENE_QUERY(Object.class),
PHRASE(String.class),
TERM(String.class);
private final Class<?> type;
private LuceneOps(Class<?> type) {
this.type = type;
}
public Class<?> getType() {
return type;
}
}

View File

@ -20,6 +20,16 @@ import com.querydsl.core.types.Operator;
*
*/
public enum MongodbOps implements Operator {
NEAR,
ELEM_MATCH
NEAR(Boolean.class),
ELEM_MATCH(Boolean.class);
private final Class<?> type;
private MongodbOps(Class<?> type) {
this.type = type;
}
public Class<?> getType() {
return type;
}
}

View File

@ -22,99 +22,109 @@ import com.querydsl.core.types.Operator;
public enum SpatialOps implements Operator {
// Geometry
DIMENSION,
GEOMETRY_TYPE,
AS_TEXT,
AS_BINARY,
SRID,
SRID2,
IS_EMPTY,
IS_SIMPLE,
BOUNDARY,
ENVELOPE,
WKTTOSQL,
WKBTOSQL,
EQUALS,
DISJOINT,
INTERSECTS,
TOUCHES,
CROSSES,
WITHIN,
CONTAINS,
OVERLAPS,
RELATE,
DISTANCE,
DISTANCE2,
DISTANCE_SPHERE,
DISTANCE_SPHEROID,
INTERSECTION,
DIFFERENCE,
UNION,
SYMDIFFERENCE,
BUFFER,
BUFFER2,
CONVEXHULL,
TRANSFORM,
DIMENSION(Integer.class),
GEOMETRY_TYPE(String.class),
AS_TEXT(String.class),
AS_BINARY(Object.class),
SRID(Integer.class),
SRID2(Integer.class),
IS_EMPTY(Boolean.class),
IS_SIMPLE(Boolean.class),
BOUNDARY(Object.class),
ENVELOPE(Object.class),
WKTTOSQL(Object.class),
WKBTOSQL(Object.class),
EQUALS(Boolean.class),
DISJOINT(Boolean.class),
INTERSECTS(Boolean.class),
TOUCHES(Boolean.class),
CROSSES(Boolean.class),
WITHIN(Boolean.class),
CONTAINS(Boolean.class),
OVERLAPS(Boolean.class),
RELATE(Boolean.class),
DISTANCE(Number.class),
DISTANCE2(Number.class),
DISTANCE_SPHERE(Number.class),
DISTANCE_SPHEROID(Number.class),
INTERSECTION(Object.class),
DIFFERENCE(Object.class),
UNION(Object.class),
SYMDIFFERENCE(Object.class),
BUFFER(Object.class),
BUFFER2(Object.class),
CONVEXHULL(Object.class),
TRANSFORM(Object.class),
// Point
X,
X2,
Y,
Y2,
Z,
Z2,
M,
M2,
X(Number.class),
X2(Number.class),
Y(Number.class),
Y2(Number.class),
Z(Number.class),
Z2(Number.class),
M(Number.class),
M2(Number.class),
// Curve
START_POINT,
END_POINT,
IS_RING,
LENGTH,
LENGTH2,
START_POINT(Object.class),
END_POINT(Object.class),
IS_RING(Object.class),
LENGTH(Object.class),
LENGTH2(Object.class),
// LineString
NUM_POINTS,
POINTN,
NUM_POINTS(Integer.class),
POINTN(Object.class),
// Surface
AREA,
AREA2,
CENTROID,
POINT_ON_SURFACE,
AREA(Number.class),
AREA2(Number.class),
CENTROID(Object.class),
POINT_ON_SURFACE(Object.class),
// Polygon
EXTERIOR_RING,
EXTERIOR_RING2,
INTERIOR_RINGS,
INTERIOR_RINGS2,
NUM_INTERIOR_RING,
INTERIOR_RINGN,
EXTERIOR_RING(Object.class),
EXTERIOR_RING2(Object.class),
INTERIOR_RINGS(Object.class),
INTERIOR_RINGS2(Object.class),
NUM_INTERIOR_RING(Integer.class),
INTERIOR_RINGN(Object.class),
// Polyhedral Surface
GEOMETRIES,
NUM_SURFACES,
SURFACE,
GEOMETRIES(Object.class),
NUM_SURFACES(Integer.class),
SURFACE(Object.class),
// GeometryCollection
NUM_GEOMETRIES,
GEOMETRYN,
NUM_GEOMETRIES(Integer.class),
GEOMETRYN(Object.class),
// MultiCurve
IS_CLOSED,
IS_CLOSED(Boolean.class),
// Extensions
AS_EWKT,
GEOM_FROM_TEXT,
SET_SRID,
XMIN,
XMAX,
YMIN,
YMAX,
DWITHIN,
EXTENT,
COLLECT,
COLLECT2,
TRANSLATE,
TRANSLATE2;
AS_EWKT(String.class),
GEOM_FROM_TEXT(Object.class),
SET_SRID(Object.class),
XMIN(Number.class),
XMAX(Number.class),
YMIN(Number.class),
YMAX(Number.class),
DWITHIN(Boolean.class),
EXTENT(Object.class),
COLLECT(Object.class),
COLLECT2(Object.class),
TRANSLATE(Object.class),
TRANSLATE2(Object.class);
private final Class<?> type;
private SpatialOps(Class<?> type) {
this.type = type;
}
public Class<?> getType() {
return type;
}
}

View File

@ -27,55 +27,65 @@ import com.querydsl.core.types.Operator;
*
*/
public enum SQLOps implements Operator {
ALL,
CAST,
CORR,
COVARPOP,
COVARSAMP,
CUMEDIST,
CUMEDIST2,
DENSERANK,
DENSERANK2,
FIRSTVALUE,
FOR_SHARE,
FOR_UPDATE,
LAG,
LASTVALUE,
LEAD,
LISTAGG,
NEXTVAL,
NO_WAIT,
NTHVALUE,
NTILE,
PERCENTRANK,
PERCENTRANK2,
PERCENTILECONT,
PERCENTILEDISC,
QUALIFY,
RANK,
RANK2,
REGR_SLOPE,
REGR_INTERCEPT,
REGR_COUNT,
REGR_R2,
REGR_AVGX,
REGR_AVGY,
REGR_SXX,
REGR_SYY,
REGR_SXY,
RATIOTOREPORT,
ROWNUMBER,
STDDEV,
STDDEVPOP,
STDDEVSAMP,
STDDEV_DISTINCT,
UNION,
UNION_ALL,
VARIANCE,
VARPOP,
VARSAMP,
WITH_ALIAS,
WITH_COLUMNS;
ALL(Object.class),
CAST(Object.class),
CORR(Double.class),
COVARPOP(Double.class),
COVARSAMP(Double.class),
CUMEDIST(Double.class),
CUMEDIST2(Double.class),
DENSERANK(Long.class),
DENSERANK2(Long.class),
FIRSTVALUE(Object.class),
FOR_SHARE(Object.class),
FOR_UPDATE(Object.class),
LAG(Object.class),
LASTVALUE(Object.class),
LEAD(Object.class),
LISTAGG(Object.class),
NEXTVAL(Object.class),
NO_WAIT(Object.class),
NTHVALUE(Object.class),
NTILE(Object.class),
PERCENTRANK(Double.class),
PERCENTRANK2(Double.class),
PERCENTILECONT(Object.class),
PERCENTILEDISC(Object.class),
QUALIFY(Boolean.class),
RANK(Long.class),
RANK2(Long.class),
REGR_SLOPE(Object.class),
REGR_INTERCEPT(Object.class),
REGR_COUNT(Object.class),
REGR_R2(Object.class),
REGR_AVGX(Object.class),
REGR_AVGY(Object.class),
REGR_SXX(Object.class),
REGR_SYY(Object.class),
REGR_SXY(Object.class),
RATIOTOREPORT(Object.class),
ROWNUMBER(Long.class),
STDDEV(Object.class),
STDDEVPOP(Object.class),
STDDEVSAMP(Object.class),
STDDEV_DISTINCT(Object.class),
UNION(Object.class),
UNION_ALL(Object.class),
VARIANCE(Object.class),
VARPOP(Object.class),
VARSAMP(Object.class),
WITH_ALIAS(Object.class),
WITH_COLUMNS(Object.class);
private final Class<?> type;
private SQLOps(Class<?> type) {
this.type = type;
}
public Class<?> getType() {
return type;
}
public static final QueryFlag FOR_SHARE_FLAG = new QueryFlag(Position.END, new OperationImpl<Object>(
Object.class, FOR_SHARE, ImmutableList.<Expression<?>>of()));

View File

@ -38,6 +38,7 @@ public class SQLSubQueryTest {
Operator op = new Operator() {
public String name() { return "unknownfn"; }
public String toString() { return name(); }
public Class<?> getType() { return Object.class; }
};
SQLSubQuery query = new SQLSubQuery();
query.from(employee)