From af99ba6d7e1b1ded31ccde393c692240b3893cc5 Mon Sep 17 00:00:00 2001 From: Jan-Willem Gmelig Meyling Date: Thu, 29 Aug 2024 09:46:52 +0200 Subject: [PATCH] Add missing TREAT, CAST and LITERAL functions --- integration/querydsl/expressions/pom.xml | 2 + .../querydsl/JPQLNextExpressions.java | 62 ++++++++++++++++++- .../persistence/querydsl/JPQLNextOps.java | 34 +++++++++- .../querydsl/JPQLNextTemplates.java | 25 +++++++- 4 files changed, 117 insertions(+), 6 deletions(-) diff --git a/integration/querydsl/expressions/pom.xml b/integration/querydsl/expressions/pom.xml index 7c0fda2921..0e69d92cc9 100644 --- a/integration/querydsl/expressions/pom.xml +++ b/integration/querydsl/expressions/pom.xml @@ -8,6 +8,8 @@ com.blazebit.persistence.querydsl + 1.8 + 1.8 4.0.0 blaze-persistence-integration-querydsl-expressions diff --git a/integration/querydsl/expressions/src/main/java/com/blazebit/persistence/querydsl/JPQLNextExpressions.java b/integration/querydsl/expressions/src/main/java/com/blazebit/persistence/querydsl/JPQLNextExpressions.java index 5292de3a5f..168a2826a3 100644 --- a/integration/querydsl/expressions/src/main/java/com/blazebit/persistence/querydsl/JPQLNextExpressions.java +++ b/integration/querydsl/expressions/src/main/java/com/blazebit/persistence/querydsl/JPQLNextExpressions.java @@ -40,13 +40,32 @@ import java.math.BigInteger; import java.sql.Time; import java.sql.Timestamp; +import java.time.Instant; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.OffsetDateTime; +import java.time.OffsetTime; +import java.time.ZonedDateTime; import java.util.Arrays; import java.util.Calendar; import java.util.Date; import java.util.EnumMap; import java.util.Map; +import static com.blazebit.persistence.querydsl.JPQLNextOps.LITERAL_CALENDAR; +import static com.blazebit.persistence.querydsl.JPQLNextOps.LITERAL_DATE; +import static com.blazebit.persistence.querydsl.JPQLNextOps.LITERAL_INSTANT; +import static com.blazebit.persistence.querydsl.JPQLNextOps.LITERAL_LOCALDATE; +import static com.blazebit.persistence.querydsl.JPQLNextOps.LITERAL_LOCALDATETIME; +import static com.blazebit.persistence.querydsl.JPQLNextOps.LITERAL_LOCALTIME; +import static com.blazebit.persistence.querydsl.JPQLNextOps.LITERAL_OFFSETDATETIME; +import static com.blazebit.persistence.querydsl.JPQLNextOps.LITERAL_OFFSETTIME; +import static com.blazebit.persistence.querydsl.JPQLNextOps.LITERAL_TIME; +import static com.blazebit.persistence.querydsl.JPQLNextOps.LITERAL_TIMESTAMP; +import static com.blazebit.persistence.querydsl.JPQLNextOps.LITERAL_ZONEDDATETIME; import static com.querydsl.core.types.dsl.Expressions.asNumber; +import static com.querydsl.core.types.dsl.Expressions.constant; /** * Utility methods for creating JPQL.next expressions @@ -979,7 +998,30 @@ public static > Expression least(Expression> Expression literal(Class clasz, T value) { - return (Expression) Expressions.template(clasz, JPQLNextTemplates.DEFAULT.asLiteral(value)); + if (Time.class.isAssignableFrom(clasz)) { + return (Expression) Expressions.timeOperation(Time.class, LITERAL_TIME, constant(value)); + } else if (Date.class.isAssignableFrom(clasz)) { + return (Expression) Expressions.dateOperation(Date.class, LITERAL_DATE, constant(value)); + } else if (Timestamp.class.isAssignableFrom(clasz)) { + return (Expression) Expressions.dateTimeOperation(Timestamp.class, LITERAL_TIMESTAMP, constant(value)); + } else if (Calendar.class.isAssignableFrom(clasz)) { + return (Expression) Expressions.operation(Calendar.class, LITERAL_CALENDAR, constant(value)); + } else if (Instant.class.isAssignableFrom(clasz)) { + return (Expression) Expressions.operation(Instant.class, LITERAL_INSTANT, constant(value)); + } else if (LocalDate.class.isAssignableFrom(clasz)) { + return (Expression) Expressions.dateOperation(LocalDate.class, LITERAL_LOCALDATE, constant(value)); + } else if (LocalDateTime.class.isAssignableFrom(clasz)) { + return (Expression) Expressions.dateTimeOperation(LocalDateTime.class, LITERAL_LOCALDATETIME, constant(value)); + } else if (LocalTime.class.isAssignableFrom(clasz)) { + return (Expression) Expressions.timeOperation(LocalTime.class, LITERAL_LOCALTIME, constant(value)); + } else if (OffsetDateTime.class.isAssignableFrom(clasz)) { + return (Expression) Expressions.dateTimeOperation(OffsetDateTime.class, LITERAL_OFFSETDATETIME, constant(value)); + } else if (OffsetTime.class.isAssignableFrom(clasz)) { + return (Expression) Expressions.timeOperation(OffsetTime.class, LITERAL_OFFSETTIME, constant(value)); + } else if (ZonedDateTime.class.isAssignableFrom(clasz)) { + return (Expression) Expressions.dateTimeOperation(ZonedDateTime.class, LITERAL_ZONEDDATETIME, constant(value)); + } + return Expressions.template(clasz, JPQLNextTemplates.DEFAULT.asLiteral(value)); } /** @@ -990,7 +1032,7 @@ public static > Expression literal(Class c * @return the literal value */ public static > Expression literal(T value) { - return (Expression) Expressions.template(value.getClass(), JPQLNextTemplates.DEFAULT.asLiteral(value)); + return literal((Class) value.getClass(), JPQLNextTemplates.DEFAULT.asLiteral(value)); } /** @@ -1169,8 +1211,22 @@ public static Expression treat(Class result, Expression expression) return Expressions.simpleOperation(result, JPQLNextOps.TREAT_TIME, expression); } else if (Date.class.isAssignableFrom(result)) { return Expressions.simpleOperation(result, JPQLNextOps.TREAT_DATE, expression); + } else if (Instant.class.isAssignableFrom(result)) { + return Expressions.simpleOperation(result, JPQLNextOps.TREAT_INSTANT, expression); + } else if (LocalDate.class.isAssignableFrom(result)) { + return Expressions.simpleOperation(result, JPQLNextOps.TREAT_LOCALDATE, expression); + } else if (LocalDateTime.class.isAssignableFrom(result)) { + return Expressions.simpleOperation(result, JPQLNextOps.TREAT_LOCALDATETIME, expression); + } else if (LocalTime.class.isAssignableFrom(result)) { + return Expressions.simpleOperation(result, JPQLNextOps.TREAT_LOCALTIME, expression); + } else if (OffsetDateTime.class.isAssignableFrom(result)) { + return Expressions.simpleOperation(result, JPQLNextOps.TREAT_OFFSETDATETIME, expression); + } else if (OffsetTime.class.isAssignableFrom(result)) { + return Expressions.simpleOperation(result, JPQLNextOps.TREAT_OFFSETTIME, expression); + } else if (ZonedDateTime.class.isAssignableFrom(result)) { + return Expressions.simpleOperation(result, JPQLNextOps.TREAT_ZONEDDATETIME, expression); } else { - throw new IllegalArgumentException("No cast operation for " + result.getName()); + throw new IllegalArgumentException("No treat operation for " + result.getName()); } } diff --git a/integration/querydsl/expressions/src/main/java/com/blazebit/persistence/querydsl/JPQLNextOps.java b/integration/querydsl/expressions/src/main/java/com/blazebit/persistence/querydsl/JPQLNextOps.java index 85b5c8de12..5f89528860 100644 --- a/integration/querydsl/expressions/src/main/java/com/blazebit/persistence/querydsl/JPQLNextOps.java +++ b/integration/querydsl/expressions/src/main/java/com/blazebit/persistence/querydsl/JPQLNextOps.java @@ -23,6 +23,13 @@ import java.sql.Date; import java.sql.Time; import java.sql.Timestamp; +import java.time.Instant; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.OffsetDateTime; +import java.time.OffsetTime; +import java.time.ZonedDateTime; import java.util.Calendar; import java.util.Collections; import java.util.EnumSet; @@ -71,11 +78,12 @@ public enum JPQLNextOps implements Operator { WITH_COLUMNS(Object.class), WITH_RECURSIVE_COLUMNS(Object.class), BIND(Object.class), + CAST_BOOLEAN(Boolean.class), CAST_BYTE(Byte.class), CAST_SHORT(Short.class), - CAST_LONG(Long.class), CAST_INTEGER(Integer.class), + CAST_LONG(Long.class), CAST_FLOAT(Float.class), CAST_DOUBLE(Double.class), CAST_CHARACTER(Character.class), @@ -86,11 +94,12 @@ public enum JPQLNextOps implements Operator { CAST_DATE(Date.class), CAST_TIMESTAMP(Timestamp.class), CAST_CALENDAR(Calendar.class), + TREAT_BOOLEAN(Boolean.class), TREAT_BYTE(Byte.class), TREAT_SHORT(Short.class), - TREAT_LONG(Long.class), TREAT_INTEGER(Integer.class), + TREAT_LONG(Long.class), TREAT_FLOAT(Float.class), TREAT_DOUBLE(Double.class), TREAT_CHARACTER(Character.class), @@ -101,6 +110,25 @@ public enum JPQLNextOps implements Operator { TREAT_DATE(Date.class), TREAT_TIMESTAMP(Timestamp.class), TREAT_CALENDAR(Calendar.class), + TREAT_INSTANT(Instant.class), + TREAT_LOCALDATE(LocalDate.class), + TREAT_LOCALDATETIME(LocalDateTime.class), + TREAT_LOCALTIME(LocalTime.class), + TREAT_OFFSETDATETIME(OffsetDateTime.class), + TREAT_OFFSETTIME(OffsetTime.class), + TREAT_ZONEDDATETIME(ZonedDateTime.class), + + LITERAL_TIME(Time.class), + LITERAL_DATE(Date.class), + LITERAL_TIMESTAMP(Timestamp.class), + LITERAL_CALENDAR(Calendar.class), + LITERAL_INSTANT(Instant.class), + LITERAL_LOCALDATE(LocalDate.class), + LITERAL_LOCALDATETIME(LocalDateTime.class), + LITERAL_LOCALTIME(LocalTime.class), + LITERAL_OFFSETDATETIME(OffsetDateTime.class), + LITERAL_OFFSETTIME(OffsetTime.class), + LITERAL_ZONEDDATETIME(ZonedDateTime.class), WINDOW_NAME(Object.class), WINDOW_BASE(Object.class), @@ -120,6 +148,8 @@ public enum JPQLNextOps implements Operator { WINDOW_UNBOUNDED_FOLLOWING(Object.class), WINDOW_CURRENT_ROW(Object.class), + JSON_GET(Object.class), + FILTER(Object.class); public static final Set LEFT_NESTED_SET_OPERATIONS = Collections.unmodifiableSet(EnumSet.of( diff --git a/integration/querydsl/expressions/src/main/java/com/blazebit/persistence/querydsl/JPQLNextTemplates.java b/integration/querydsl/expressions/src/main/java/com/blazebit/persistence/querydsl/JPQLNextTemplates.java index d9af96da39..47b6680ac4 100644 --- a/integration/querydsl/expressions/src/main/java/com/blazebit/persistence/querydsl/JPQLNextTemplates.java +++ b/integration/querydsl/expressions/src/main/java/com/blazebit/persistence/querydsl/JPQLNextTemplates.java @@ -20,6 +20,7 @@ import com.blazebit.persistence.parser.util.TypeUtils; import com.querydsl.core.types.Ops; import com.querydsl.jpa.DefaultQueryHandler; +import com.querydsl.jpa.JPQLOps; import com.querydsl.jpa.JPQLTemplates; import com.querydsl.jpa.QueryHandler; @@ -113,6 +114,8 @@ public JPQLNextTemplates(char escape, QueryHandler queryHandler) { add(JPQLNextOps.LEFT_NESTED_SET_EXCEPT, "({0}) EXCEPT {1}", Precedence.OR + 1); add(JPQLNextOps.LEFT_NESTED_SET_EXCEPT_ALL, "({0}) EXCEPT ALL {1}", Precedence.OR + 1); + add(Ops.STRING_CAST, "CAST_STRING({0})"); + add(JPQLNextOps.CAST_BOOLEAN, "CAST_BOOLEAN({0})"); add(JPQLNextOps.CAST_BYTE, "CAST_BYTE({0})"); add(JPQLNextOps.CAST_SHORT, "CAST_SHORT({0})"); @@ -144,7 +147,25 @@ public JPQLNextTemplates(char escape, QueryHandler queryHandler) { add(JPQLNextOps.TREAT_DATE, "TREAT_BOOLEAN({0})"); add(JPQLNextOps.TREAT_TIMESTAMP, "TREAT_TIMESTAMP({0})"); add(JPQLNextOps.TREAT_CALENDAR, "TREAT_CALENDAR({0})"); - + add(JPQLNextOps.TREAT_INSTANT, "TREAT_INSTANT({0})"); + add(JPQLNextOps.TREAT_LOCALDATE, "TREAT_LOCALDATE({0})"); + add(JPQLNextOps.TREAT_LOCALDATETIME, "TREAT_LOCALDATETIME({0})"); + add(JPQLNextOps.TREAT_LOCALTIME, "TREAT_LOCALTIME({0})"); + add(JPQLNextOps.TREAT_OFFSETDATETIME, "TREAT_OFFSETDATETIME({0})"); + add(JPQLNextOps.TREAT_OFFSETTIME, "TREAT_OFFSETTIME({0})"); + add(JPQLNextOps.TREAT_ZONEDDATETIME, "TREAT_ZONEDDATETIME({0})"); + + add(JPQLNextOps.LITERAL_TIME, "LITERAL_TIME({0})"); + add(JPQLNextOps.LITERAL_DATE, "LITERAL_DATE({0})"); + add(JPQLNextOps.LITERAL_TIMESTAMP, "LITERAL_TIMESTAMP({0})"); + add(JPQLNextOps.LITERAL_CALENDAR, "LITERAL_CALENDAR({0})"); + add(JPQLNextOps.LITERAL_INSTANT, "LITERAL_INSTANT({0})"); + add(JPQLNextOps.LITERAL_LOCALDATE, "LITERAL_LOCALDATE({0})"); + add(JPQLNextOps.LITERAL_LOCALDATETIME, "LITERAL_LOCALDATETIME({0})"); + add(JPQLNextOps.LITERAL_LOCALTIME, "LITERAL_LOCALTIME({0})"); + add(JPQLNextOps.LITERAL_OFFSETDATETIME, "LITERAL_OFFSETDATETIME({0})"); + add(JPQLNextOps.LITERAL_OFFSETTIME, "LITERAL_OFFSETTIME({0})"); + add(JPQLNextOps.LITERAL_ZONEDDATETIME, "LITERAL_ZONEDDATETIME({0})"); add(JPQLNextOps.LEAST, "LEAST({0}, {1})"); add(Ops.MathOps.MIN, "LEAST({0}, {1})"); @@ -175,6 +196,8 @@ public JPQLNextTemplates(char escape, QueryHandler queryHandler) { add(JPQLNextOps.WINDOW_DEFINITION_4, "{0} {1} {2} {3}"); add(JPQLNextOps.FILTER, "{0} FILTER (WHERE {1})"); + + add(JPQLNextOps.JSON_GET, "JSON_GET({0}, {1})"); } @Override