Skip to content

Commit 6172a5f

Browse files
authored
Merge pull request #675 from mspruc/cast-for-filters
passthrough fields for filters using CAST
2 parents 534ccc4 + 03c870b commit 6172a5f

File tree

4 files changed

+112
-115
lines changed

4 files changed

+112
-115
lines changed

wayang-api/wayang-api-sql/src/main/java/org/apache/wayang/api/sql/calcite/converter/functions/CallTreeFactory.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import org.apache.calcite.rex.RexLiteral;
2828
import org.apache.calcite.rex.RexNode;
2929
import org.apache.calcite.sql.SqlKind;
30+
import org.apache.calcite.sql.type.SqlTypeName;
3031
import org.apache.calcite.util.Sarg;
3132
import org.apache.wayang.basic.data.Record;
3233
import org.apache.wayang.core.function.FunctionDescriptor.SerializableFunction;
@@ -55,10 +56,11 @@ public default Node fromRexNode(final RexNode node) {
5556
* serializable function
5657
*
5758
* @param kind {@link SqlKind} from {@link RexCall} SqlOperator
59+
* @param returnType return type of the {@link RexCall}
5860
* @return a serializable function of +, -, * or /
5961
* @throws UnsupportedOperationException on unrecognized {@link SqlKind}
6062
*/
61-
public SerializableFunction<List<Object>, Object> deriveOperation(final SqlKind kind);
63+
public SerializableFunction<List<Object>, Object> deriveOperation(final SqlKind kind, final SqlTypeName returnType);
6264
}
6365

6466
interface Node extends Serializable {
@@ -71,7 +73,7 @@ final class Call implements Node {
7173

7274
protected Call(final RexCall call, final CallTreeFactory tree) {
7375
operands = call.getOperands().stream().map(tree::fromRexNode).toList();
74-
operation = tree.deriveOperation(call.getKind());
76+
operation = tree.deriveOperation(call.getKind(), call.getType().getSqlTypeName());
7577
}
7678

7779
@Override

wayang-api/wayang-api-sql/src/main/java/org/apache/wayang/api/sql/calcite/converter/functions/FilterPredicateImpl.java

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import org.apache.calcite.rex.RexNode;
2727
import org.apache.calcite.runtime.SqlFunctions;
2828
import org.apache.calcite.sql.SqlKind;
29+
import org.apache.calcite.sql.type.SqlTypeName;
2930
import org.apache.calcite.util.DateString;
3031
import org.apache.calcite.util.NlsString;
3132
import org.apache.wayang.basic.data.Record;
@@ -37,7 +38,7 @@
3738

3839
public class FilterPredicateImpl implements FunctionDescriptor.SerializablePredicate<Record> {
3940
class FilterCallTreeFactory implements CallTreeFactory {
40-
public SerializableFunction<List<Object>, Object> deriveOperation(final SqlKind kind) {
41+
public SerializableFunction<List<Object>, Object> deriveOperation(final SqlKind kind, final SqlTypeName returnType) {
4142
return input -> switch (kind) {
4243
case NOT -> !(boolean) input.get(0);
4344
case IS_NOT_NULL -> !isEqualTo(input.get(0), null);
@@ -55,6 +56,8 @@ public SerializableFunction<List<Object>, Object> deriveOperation(final SqlKind
5556
case OR -> input.stream().anyMatch(obj -> Boolean.class.cast(obj).booleanValue());
5657
case MINUS -> widenToDouble.apply(input.get(0)) - widenToDouble.apply(input.get(1));
5758
case PLUS -> widenToDouble.apply(input.get(0)) + widenToDouble.apply(input.get(1));
59+
// TODO: may need better support for CASTing in the future. See sqlCast() in this file.
60+
case CAST -> input.get(0) instanceof Number ? widenToDouble.apply(input.get(0)) : ensureComparable.apply(input.get(0));
5861
case SEARCH -> {
5962
if (input.get(0) instanceof final ImmutableRangeSet range) {
6063
assert input.get(1) instanceof Comparable
@@ -81,14 +84,24 @@ public SerializableFunction<List<Object>, Object> deriveOperation(final SqlKind
8184
};
8285
}
8386

87+
/**
88+
* Java implementation of SQL cast.
89+
* @param input input field
90+
* @param type the new return type of the field
91+
* @return Java-type equivalent to {@link SqlTypeName} counterpart.
92+
*/
93+
private static Object sqlCast(Object input, SqlTypeName type){
94+
throw new UnsupportedOperationException("sqlCasting is not yet implemented.");
95+
}
96+
8497
/**
8598
* Java equivalent of SQL like clauses
8699
*
87100
* @param s1
88101
* @param s2
89102
* @return true if {@code s1} like {@code s2}
90103
*/
91-
private boolean like(final String s1, final String s2) {
104+
private static boolean like(final String s1, final String s2) {
92105
return new SqlFunctions.LikeFunction().like(s1, s2);
93106
}
94107

@@ -99,7 +112,7 @@ private boolean like(final String s1, final String s2) {
99112
* @param o2
100113
* @return true if {@code o1 > o2}
101114
*/
102-
private boolean isGreaterThan(final Object o1, final Object o2) {
115+
private static boolean isGreaterThan(final Object o1, final Object o2) {
103116
return ensureComparable.apply(o1).compareTo(ensureComparable.apply(o2)) > 0;
104117
}
105118

@@ -110,7 +123,7 @@ private boolean isGreaterThan(final Object o1, final Object o2) {
110123
* @param o2
111124
* @return true if {@code o1 < o2}
112125
*/
113-
private boolean isLessThan(final Object o1, final Object o2) {
126+
private static boolean isLessThan(final Object o1, final Object o2) {
114127
return ensureComparable.apply(o1).compareTo(ensureComparable.apply(o2)) < 0;
115128
}
116129

@@ -121,7 +134,7 @@ private boolean isLessThan(final Object o1, final Object o2) {
121134
* @param o2
122135
* @return true if {@code o1 == o2}
123136
*/
124-
private boolean isEqualTo(final Object o1, final Object o2) {
137+
private static boolean isEqualTo(final Object o1, final Object o2) {
125138
return Objects.equals(ensureComparable.apply(o1), ensureComparable.apply(o2));
126139
}
127140
}
@@ -133,7 +146,7 @@ private boolean isEqualTo(final Object o1, final Object o2) {
133146
*
134147
* @throws UnsupportedOperationException if conversion was not possible
135148
*/
136-
final SerializableFunction<Object, Double> widenToDouble = field -> {
149+
final static SerializableFunction<Object, Double> widenToDouble = field -> {
137150
if (field instanceof final Number number) {
138151
return number.doubleValue();
139152
} else if (field instanceof final Date date) {
@@ -148,7 +161,7 @@ private boolean isEqualTo(final Object o1, final Object o2) {
148161
/**
149162
* Widening conversions, all numbers to double
150163
*/
151-
final SerializableFunction<Object, Comparable> ensureComparable = field -> {
164+
final static SerializableFunction<Object, Comparable> ensureComparable = field -> {
152165
if (field instanceof final Number number) {
153166
return number.doubleValue();
154167
} else if (field instanceof final Date date) {

wayang-api/wayang-api-sql/src/main/java/org/apache/wayang/api/sql/calcite/converter/functions/ProjectMapFuncImpl.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222

2323
import org.apache.calcite.rex.RexNode;
2424
import org.apache.calcite.sql.SqlKind;
25-
25+
import org.apache.calcite.sql.type.SqlTypeName;
2626
import org.apache.wayang.core.function.FunctionDescriptor;
2727
import org.apache.wayang.core.function.FunctionDescriptor.SerializableFunction;
2828
import org.apache.wayang.basic.data.Record;
@@ -38,7 +38,7 @@ public ProjectMapFuncImpl(final List<RexNode> projects) {
3838
}
3939

4040
class ProjectCallTreeFactory implements CallTreeFactory {
41-
public SerializableFunction<List<Object>, Object> deriveOperation(final SqlKind kind) {
41+
public SerializableFunction<List<Object>, Object> deriveOperation(final SqlKind kind, final SqlTypeName returnType) {
4242
return input ->
4343
switch (kind) {
4444
case PLUS -> asDouble(input.get(0)) + asDouble(input.get(1));

0 commit comments

Comments
 (0)