Skip to content

Commit d1c2bfa

Browse files
committed
typed eval result
1 parent 6cc4de3 commit d1c2bfa

File tree

4 files changed

+168
-76
lines changed

4 files changed

+168
-76
lines changed

server/core/src/main/java/io/whitefox/core/ColumnRange.java

Lines changed: 74 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
package io.whitefox.core;
22

3-
import io.whitefox.core.types.DataType;
4-
import io.whitefox.core.types.IntegerType;
5-
import io.whitefox.core.types.LongType;
3+
import io.whitefox.core.types.*;
64

7-
import java.util.Comparator;
5+
import java.sql.Date;
6+
import java.sql.Timestamp;
87

98
public class ColumnRange {
109

@@ -36,13 +35,47 @@ else if (valueType instanceof LongType){
3635
var c2 = Long.compare(Long.parseLong(maxVal), Long.parseLong(point));
3736
return (c1 <= 0 && c2 >= 0);
3837
}
38+
else if (valueType instanceof TimestampType){
39+
var c1 = Timestamp.valueOf(minVal).before(Timestamp.valueOf(point));
40+
var c2 = Timestamp.valueOf(maxVal).before(Timestamp.valueOf(point));
41+
return c1 && c2;
42+
}
43+
else if (valueType instanceof FloatType){
44+
var c1 = Float.compare(Float.parseFloat(minVal), Float.parseFloat(point));
45+
var c2 = Float.compare(Float.parseFloat(maxVal), Float.parseFloat(point));
46+
return (c1 <= 0 && c2 >= 0);
47+
}
48+
else if (valueType instanceof DoubleType){
49+
var c1 = Double.compare(Double.parseDouble(minVal), Double.parseDouble(point));
50+
var c2 = Double.compare(Double.parseDouble(maxVal), Double.parseDouble(point));
51+
return (c1 <= 0 && c2 >= 0);
52+
}
53+
else if (valueType instanceof DateType){
54+
var c1 = Date.valueOf(minVal).before(Date.valueOf(point));
55+
var c2 = Date.valueOf(maxVal).before(Date.valueOf(point));
56+
return c1 && c2;
57+
}
58+
else if (valueType instanceof BooleanType){
59+
var c1 = Boolean.parseBoolean(minVal) == Boolean.parseBoolean(point);
60+
var c2 = Boolean.parseBoolean(maxVal) == Boolean.parseBoolean(point);
61+
return c1 || c2;
62+
}
3963
else {
4064
var c1 = minVal.compareTo(point);
4165
var c2 = maxVal.compareTo(point);
4266
return (c1 <= 0 && c2 >= 0);
4367
}
4468
}
4569

70+
public static void main(String[] args) {
71+
var minVal = "4";
72+
var point = "5";
73+
var maxVal = "8";
74+
75+
var cr = new ColumnRange(minVal,maxVal, IntegerType.INTEGER);
76+
cr.typedLessThan(point);
77+
}
78+
4679
private Boolean typedLessThan(String point){
4780
if (valueType instanceof IntegerType) {
4881
var c1 = Integer.compare(Integer.parseInt(minVal), Integer.parseInt(point));
@@ -52,24 +85,54 @@ else if (valueType instanceof LongType){
5285
var c1 = Long.compare(Long.parseLong(minVal), Long.parseLong(point));
5386
return (c1 < 0);
5487
}
88+
else if (valueType instanceof TimestampType){
89+
return Timestamp.valueOf(minVal).before(Timestamp.valueOf(point));
90+
}
91+
else if (valueType instanceof FloatType){
92+
var c1 = Float.compare(Float.parseFloat(minVal), Float.parseFloat(point));
93+
return (c1 < 0);
94+
}
95+
else if (valueType instanceof DoubleType){
96+
var c1 = Double.compare(Double.parseDouble(minVal), Double.parseDouble(point));
97+
return (c1 < 0);
98+
}
99+
else if (valueType instanceof DateType){
100+
return Date.valueOf(minVal).before(Date.valueOf(point));
101+
102+
}
55103
else {
56104
var c = minVal.compareTo(point);
57-
return (c >= 0);
105+
return (c < 0);
58106
}
59107
}
60108

61109
private Boolean typedGreaterThan(String point){
62110
if (valueType instanceof IntegerType) {
63-
var c = Integer.compare(Integer.parseInt(maxVal), Integer.parseInt(point));
64-
return (c > 0);
111+
var c = Integer.compare(Integer.parseInt(point), Integer.parseInt(maxVal));
112+
return (c < 0);
65113
}
66114
else if (valueType instanceof LongType){
67-
var c = Long.compare(Long.parseLong(maxVal), Long.parseLong(point));
68-
return (c > 0);
115+
var c = Long.compare(Long.parseLong(point), Long.parseLong(maxVal));
116+
return (c < 0);
117+
}
118+
else if (valueType instanceof TimestampType){
119+
return Timestamp.valueOf(point).before(Timestamp.valueOf(maxVal));
120+
}
121+
else if (valueType instanceof FloatType){
122+
var c = Float.compare(Float.parseFloat(maxVal), Float.parseFloat(point));
123+
return (c < 0);
124+
}
125+
else if (valueType instanceof DoubleType){
126+
var c = Double.compare(Double.parseDouble(maxVal), Double.parseDouble(point));
127+
return (c < 0);
128+
}
129+
else if (valueType instanceof DateType){
130+
return Date.valueOf(point).before(Date.valueOf(maxVal));
131+
69132
}
70133
else {
71-
var c = maxVal.compareTo(point);
72-
return (c >= 0);
134+
var c = point.compareTo(maxVal);
135+
return (c < 0);
73136
}
74137
}
75138

server/core/src/main/java/io/whitefox/core/types/predicates/EvalHelper.java

Lines changed: 62 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -6,24 +6,25 @@
66
import java.sql.Timestamp;
77
import java.util.List;
88
import java.util.Objects;
9+
import java.util.Optional;
910

1011
import org.apache.commons.lang3.tuple.Pair;
1112

1213
// Only for partition values
1314
public class EvalHelper {
1415

15-
static Pair<ColumnRange, String> validateAndGetRange(List<LeafOp> children, EvalContext ctx) throws PredicateException {
16+
static LeafEvaluationResult validateAndGetRange(List<LeafOp> children, EvalContext ctx) throws PredicateException {
1617
var leftChild = (ColumnOp) children.get(0);
1718
var columnRange = leftChild.evalExpectColumnRange(ctx);
1819

1920
var rightChild = children.get(1);
2021
var rightType = rightChild.evalExpectValueAndType(ctx).getRight();
2122
var rightVal = rightChild.evalExpectValueAndType(ctx).getLeft();
2223

23-
return Pair.of(columnRange, rightVal);
24+
return LeafEvaluationResult.createFromRange(Pair.of(columnRange, rightVal));
2425
}
2526

26-
static Pair<Pair<ColumnRange, String>,Pair<Pair<DataType, String>, Pair<DataType, String>>> validateAndGetTypeAndValue(
27+
static LeafEvaluationResult validateAndGetTypeAndValue(
2728
List<LeafOp> children, EvalContext ctx) throws PredicateException {
2829
var leftChild = children.get(0);
2930
var leftType = leftChild.evalExpectValueAndType(ctx).getRight();
@@ -39,76 +40,84 @@ static Pair<Pair<ColumnRange, String>,Pair<Pair<DataType, String>, Pair<DataType
3940
}
4041

4142
if (leftVal == null && leftChild instanceof ColumnOp){
42-
return Pair.of(validateAndGetRange(children, ctx), null);
43+
return validateAndGetRange(children, ctx);
4344
}
4445

4546
// We throw an exception for nulls, which will skip filtering.
4647
if (leftVal == null || rightVal == null) {
4748
throw new NullTypeException(leftChild, rightChild);
4849
}
49-
return Pair.of(null, Pair.of(Pair.of(leftType, leftVal), Pair.of(rightType, rightVal)));
50+
return LeafEvaluationResult.createFromPartitionColumn(Pair.of(Pair.of(leftType, leftVal), Pair.of(rightType, rightVal)));
5051
}
5152

5253
// Implements "equal" between two leaf operations.
5354
static Boolean equal(List<LeafOp> children, EvalContext ctx) throws PredicateException {
5455

55-
var columnRangeOrTypeAndValue = validateAndGetTypeAndValue(children, ctx);
56-
if (columnRangeOrTypeAndValue.getLeft() != null) {
57-
var columnRange = columnRangeOrTypeAndValue.getLeft().getLeft();
58-
var value = columnRangeOrTypeAndValue.getLeft().getRight();
56+
var leafEvaluationResult = validateAndGetTypeAndValue(children, ctx);
57+
var rangeEvaluation = leafEvaluationResult.rangeEvaluationResult.map(range -> {
58+
var columnRange = range.getLeft();
59+
var value = range.getRight();
5960
return columnRange.contains(value);
61+
});
62+
if (rangeEvaluation.isPresent())
63+
return rangeEvaluation.get();
64+
else if (leafEvaluationResult.partitionEvaluationResult.isPresent()){
65+
var typesAndValues = leafEvaluationResult.partitionEvaluationResult.get();
66+
var leftType = typesAndValues.getLeft().getLeft();
67+
var leftVal = typesAndValues.getLeft().getRight();
68+
var rightVal = typesAndValues.getRight().getRight();
69+
70+
if (BooleanType.BOOLEAN.equals(leftType)) {
71+
return Boolean.valueOf(leftVal) == Boolean.valueOf(rightVal);
72+
} else if (IntegerType.INTEGER.equals(leftType)) {
73+
return Integer.parseInt(leftVal) == Integer.parseInt(rightVal);
74+
} else if (LongType.LONG.equals(leftType)) {
75+
return Long.parseLong(leftVal) == Long.parseLong(rightVal);
76+
} else if (StringType.STRING.equals(leftType)) {
77+
return leftVal.equals(rightVal);
78+
} else if (DateType.DATE.equals(leftType)) {
79+
return Date.valueOf(leftVal).equals(Date.valueOf(rightVal));
80+
}
81+
else
82+
throw new TypeNotSupportedException(leftType);
6083
}
61-
62-
63-
var typesAndValues = columnRangeOrTypeAndValue.getRight();
64-
var leftType = typesAndValues.getLeft().getLeft();
65-
var leftVal = typesAndValues.getLeft().getRight();
66-
var rightVal = typesAndValues.getRight().getRight();
67-
68-
if (BooleanType.BOOLEAN.equals(leftType)) {
69-
return Boolean.valueOf(leftVal) == Boolean.valueOf(rightVal);
70-
} else if (IntegerType.INTEGER.equals(leftType)) {
71-
return Integer.parseInt(leftVal) == Integer.parseInt(rightVal);
72-
} else if (LongType.LONG.equals(leftType)) {
73-
return Long.parseLong(leftVal) == Long.parseLong(rightVal);
74-
} else if (StringType.STRING.equals(leftType)) {
75-
return leftVal.equals(rightVal);
76-
} else if (DateType.DATE.equals(leftType)) {
77-
return Date.valueOf(leftVal).equals(Date.valueOf(rightVal));
78-
}
79-
else
80-
throw new TypeNotSupportedException(leftType);
84+
else
85+
throw new PredicateException();
8186
}
8287

83-
// TODO: supported expressions; ie. check if column + constant
84-
// TODO: handle column comparisons with literals
8588
static Boolean lessThan(List<LeafOp> children, EvalContext ctx) throws PredicateException {
8689

87-
88-
var columnRangeOrTypeAndValue = validateAndGetTypeAndValue(children, ctx);
89-
if (columnRangeOrTypeAndValue.getLeft() != null) {
90-
var columnRange = columnRangeOrTypeAndValue.getLeft().getLeft();
91-
var value = columnRangeOrTypeAndValue.getLeft().getRight();
92-
return columnRange.contains(value);
93-
}
94-
95-
var typesAndValues = columnRangeOrTypeAndValue.getRight();
96-
var leftType = typesAndValues.getLeft().getLeft();
97-
var leftVal = typesAndValues.getLeft().getRight();
98-
var rightVal = typesAndValues.getRight().getRight();
99-
100-
if (IntegerType.INTEGER.equals(leftType)) {
101-
return Integer.parseInt(leftVal) < Integer.parseInt(rightVal);
102-
} else if (LongType.LONG.equals(leftType)) {
103-
return Long.parseLong(leftVal) < Long.parseLong(rightVal);
104-
} else if (StringType.STRING.equals(leftType)) {
105-
return leftVal.compareTo(rightVal) < 0;
106-
} else if (DateType.DATE.equals(leftType)) {
107-
return Date.valueOf(leftVal).before(Date.valueOf(rightVal));
90+
var leafEvaluationResult = validateAndGetTypeAndValue(children, ctx);
91+
var rangeEvaluation = leafEvaluationResult.rangeEvaluationResult.map(range -> {
92+
var columnRange = range.getLeft();
93+
var value = range.getRight();
94+
return columnRange.canBeLess(value);
95+
});
96+
97+
if (rangeEvaluation.isPresent())
98+
return rangeEvaluation.get();
99+
else if (leafEvaluationResult.partitionEvaluationResult.isPresent()){
100+
var typesAndValues = leafEvaluationResult.partitionEvaluationResult.get();
101+
var leftType = typesAndValues.getLeft().getLeft();
102+
var leftVal = typesAndValues.getLeft().getRight();
103+
var rightVal = typesAndValues.getRight().getRight();
104+
105+
if (IntegerType.INTEGER.equals(leftType)) {
106+
return Integer.parseInt(leftVal) < Integer.parseInt(rightVal);
107+
} else if (LongType.LONG.equals(leftType)) {
108+
return Long.parseLong(leftVal) < Long.parseLong(rightVal);
109+
} else if (StringType.STRING.equals(leftType)) {
110+
return leftVal.compareTo(rightVal) < 0;
111+
} else if (DateType.DATE.equals(leftType)) {
112+
return Date.valueOf(leftVal).before(Date.valueOf(rightVal));
113+
}
114+
else
115+
throw new TypeNotSupportedException(leftType);
108116
}
109117
else
110-
throw new TypeNotSupportedException(leftType);
118+
throw new PredicateException();
111119
}
120+
112121
// Validates that the specified value is in the correct format.
113122
// Throws an exception otherwise.
114123
public static void validateValue(String value, DataType valueType) {
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package io.whitefox.core.types.predicates;
2+
3+
import io.whitefox.core.ColumnRange;
4+
import io.whitefox.core.types.DataType;
5+
import org.apache.commons.lang3.tuple.Pair;
6+
7+
import java.util.Optional;
8+
9+
public class LeafEvaluationResult {
10+
11+
Optional<Pair<ColumnRange, String>> rangeEvaluationResult;
12+
Optional<Pair<Pair<DataType, String>, Pair<DataType, String>>> partitionEvaluationResult;
13+
14+
public LeafEvaluationResult(Optional<Pair<ColumnRange, String>> rangeEvaluationResult, Optional<Pair<Pair<DataType, String>, Pair<DataType, String>>> partitionEvaluationResult) {
15+
this.rangeEvaluationResult = rangeEvaluationResult;
16+
this.partitionEvaluationResult = partitionEvaluationResult;
17+
}
18+
19+
public static LeafEvaluationResult createFromRange(Pair<ColumnRange, String> rangeEvaluationResult) {
20+
return new LeafEvaluationResult(Optional.of(rangeEvaluationResult), Optional.empty());
21+
}
22+
23+
public static LeafEvaluationResult createFromPartitionColumn(Pair<Pair<DataType, String>, Pair<DataType, String>> partitionEvaluationResult) {
24+
return new LeafEvaluationResult(Optional.empty(), Optional.of(partitionEvaluationResult));
25+
}
26+
27+
28+
}

server/core/src/main/java/io/whitefox/core/types/predicates/LeafOp.java

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,13 @@
33
import com.fasterxml.jackson.annotation.JsonProperty;
44
import com.fasterxml.jackson.annotation.JsonSubTypes;
55
import com.fasterxml.jackson.annotation.JsonTypeInfo;
6-
import io.delta.standalone.DeltaLog;
7-
import io.delta.standalone.actions.AddFile;
8-
import io.whitefox.core.*;
6+
import io.whitefox.core.ColumnRange;
97
import io.whitefox.core.types.BooleanType;
108
import io.whitefox.core.types.DataType;
11-
12-
import java.nio.file.Path;
13-
import java.nio.file.Paths;
14-
import java.sql.Date;
15-
import java.util.*;
16-
17-
import io.whitefox.core.types.DateType;
18-
import io.whitefox.core.types.IntegerType;
199
import org.apache.commons.lang3.tuple.Pair;
20-
import org.apache.hadoop.conf.Configuration;
10+
11+
import java.util.List;
12+
import java.util.Objects;
2113

2214
import static io.whitefox.core.JsonPredicatesUtils.createColumnRange;
2315
import static io.whitefox.core.types.predicates.EvaluatorVersion.V1;

0 commit comments

Comments
 (0)