Skip to content

Commit 8f18c09

Browse files
committed
refactor everything to ColumnRange
1 parent fdcb954 commit 8f18c09

File tree

10 files changed

+89
-101
lines changed

10 files changed

+89
-101
lines changed

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

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

33
import io.whitefox.annotations.SkipCoverageGenerated;
44
import io.whitefox.core.types.*;
5+
import io.whitefox.core.types.predicates.TypeNotSupportedException;
56
import java.sql.Date;
67
import java.sql.Timestamp;
78

@@ -28,11 +29,11 @@ public DataType getValueType() {
2829
return valueType;
2930
}
3031

31-
public String getOnlyValue() {
32+
public String getSingleValue() {
3233
return minVal;
3334
}
3435

35-
private Boolean typedContains(String point) {
36+
private Boolean typedContains(String point) throws TypeNotSupportedException {
3637
if (valueType instanceof IntegerType) {
3738
var c1 = Integer.compare(Integer.parseInt(minVal), Integer.parseInt(point));
3839
var c2 = Integer.compare(Integer.parseInt(maxVal), Integer.parseInt(point));
@@ -44,7 +45,7 @@ private Boolean typedContains(String point) {
4445
} else if (valueType instanceof TimestampType) {
4546
var c1 = Timestamp.valueOf(minVal).before(Timestamp.valueOf(point));
4647
var c2 = Timestamp.valueOf(maxVal).after(Timestamp.valueOf(point));
47-
return c1 && c2;
48+
return (c1 && c2) || Timestamp.valueOf(minVal).equals(Timestamp.valueOf(point));
4849
} else if (valueType instanceof FloatType) {
4950
var c1 = Float.compare(Float.parseFloat(minVal), Float.parseFloat(point));
5051
var c2 = Float.compare(Float.parseFloat(maxVal), Float.parseFloat(point));
@@ -56,19 +57,19 @@ private Boolean typedContains(String point) {
5657
} else if (valueType instanceof DateType) {
5758
var c1 = Date.valueOf(minVal).before(Date.valueOf(point));
5859
var c2 = Date.valueOf(maxVal).after(Date.valueOf(point));
59-
return c1 && c2;
60+
return (c1 && c2) || Date.valueOf(minVal).equals(Date.valueOf(point));
6061
} else if (valueType instanceof BooleanType) {
6162
var c1 = Boolean.parseBoolean(minVal) == Boolean.parseBoolean(point);
6263
var c2 = Boolean.parseBoolean(maxVal) == Boolean.parseBoolean(point);
6364
return c1 || c2;
64-
} else {
65+
} else if (valueType instanceof StringType) {
6566
var c1 = minVal.compareTo(point);
6667
var c2 = maxVal.compareTo(point);
6768
return (c1 <= 0 && c2 >= 0);
68-
}
69+
} else throw new TypeNotSupportedException(valueType);
6970
}
7071

71-
private Boolean typedLessThan(String point) {
72+
private Boolean typedLessThan(String point) throws TypeNotSupportedException {
7273
if (valueType instanceof IntegerType) {
7374
var c1 = Integer.compare(Integer.parseInt(minVal), Integer.parseInt(point));
7475
return (c1 < 0);
@@ -85,12 +86,13 @@ private Boolean typedLessThan(String point) {
8586
return (c1 < 0);
8687
} else if (valueType instanceof DateType) {
8788
return Date.valueOf(minVal).before(Date.valueOf(point));
88-
} else {
89+
} else if (valueType instanceof StringType) {
8990
var c = minVal.compareTo(point);
9091
return (c < 0);
91-
}
92+
} else throw new TypeNotSupportedException(valueType);
9293
}
9394

95+
// not used currently
9496
@SkipCoverageGenerated
9597
private Boolean typedGreaterThan(String point) {
9698
if (valueType instanceof IntegerType) {
@@ -116,11 +118,11 @@ private Boolean typedGreaterThan(String point) {
116118
}
117119
}
118120

119-
public Boolean contains(String point) {
121+
public Boolean contains(String point) throws TypeNotSupportedException {
120122
return typedContains(point);
121123
}
122124

123-
public Boolean canBeLess(String point) {
125+
public Boolean canBeLess(String point) throws TypeNotSupportedException {
124126
return typedLessThan(point);
125127
}
126128

server/core/src/main/java/io/whitefox/core/services/DeltaSharedTable.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,11 @@
1111
import io.whitefox.core.TableSchema;
1212
import io.whitefox.core.types.predicates.PredicateException;
1313
import java.sql.Timestamp;
14-
import java.time.OffsetDateTime;
15-
import java.time.format.DateTimeFormatter;
1614
import java.util.List;
1715
import java.util.Optional;
1816
import java.util.stream.Collectors;
1917
import org.apache.log4j.Logger;
2018

21-
2219
public class DeltaSharedTable implements InternalSharedTable {
2320

2421
private final Logger logger = Logger.getLogger(this.getClass());

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
import io.whitefox.core.types.BooleanType;
1010
import io.whitefox.core.types.DataType;
1111
import java.util.Objects;
12-
import org.apache.commons.lang3.tuple.Pair;
1312

1413
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "column")
1514
public class ColumnOp extends LeafOp {
@@ -52,7 +51,7 @@ public DataType getOpValueType() {
5251
@Override
5352
public Object eval(EvalContext ctx) {
5453
// TODO: handle case of null column + column ranges
55-
return Pair.of(resolve(ctx), valueType);
54+
return new ColumnRange(resolve(ctx), valueType);
5655
}
5756

5857
public void validate() throws PredicateException {

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

Lines changed: 52 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
import io.whitefox.core.ColumnRange;
44
import io.whitefox.core.types.*;
5+
import org.apache.commons.lang3.tuple.Pair;
6+
57
import java.sql.Date;
68
import java.sql.Timestamp;
79
import java.util.List;
@@ -13,100 +15,84 @@ public class EvalHelper {
1315
private static LeafEvaluationResult validateAndGetRange(
1416
ColumnOp columnChild, LiteralOp literalChild, EvalContext ctx) throws PredicateException {
1517
var columnRange = columnChild.evalExpectColumnRange(ctx);
16-
var rightVal = literalChild.evalExpectValueAndType(ctx).getLeft();
18+
var rightVal = literalChild.evalExpectValueAndType(ctx).getSingleValue();
1719

1820
return LeafEvaluationResult.createFromRange(new RangeEvaluationResult(columnRange, rightVal));
1921
}
2022

2123
private static LeafEvaluationResult validateAndGetTypeAndValue(
22-
List<LeafOp> children, EvalContext ctx) throws PredicateException {
23-
var leftChild = children.get(0);
24-
var leftType = leftChild.evalExpectValueAndType(ctx).getRight();
25-
var leftVal = leftChild.evalExpectValueAndType(ctx).getLeft();
26-
27-
var rightChild = children.get(1);
28-
var rightType = rightChild.evalExpectValueAndType(ctx).getRight();
29-
var rightVal = rightChild.evalExpectValueAndType(ctx).getLeft();
24+
ColumnOp columnOp, LiteralOp literalOp, EvalContext ctx) throws PredicateException {
25+
var columnType = columnOp.evalExpectValueAndType(ctx).getValueType();
26+
var columnValue = columnOp.evalExpectValueAndType(ctx).getSingleValue();
27+
28+
var literalType = literalOp.evalExpectValueAndType(ctx).getValueType();
29+
var literalValue = literalOp.evalExpectValueAndType(ctx).getSingleValue();
3030
// If the types don't match, it implies a malformed predicate tree.
3131
// We simply throw an exception, which will cause filtering to be skipped.
32-
if (!Objects.equals(leftType, rightType)) {
33-
throw new TypeMismatchException(leftType, rightType);
34-
}
35-
36-
if (leftVal == null && leftChild instanceof ColumnOp) {
37-
return validateAndGetRange((ColumnOp) leftChild, (LiteralOp) rightChild, ctx);
32+
if (!Objects.equals(columnType, literalType)) {
33+
throw new TypeMismatchException(columnType, literalType);
3834
}
3935

40-
// maybe better to enforce the Equal/LessThan... to explicitly require a column child and
41-
// literal child
42-
if (rightVal == null && rightChild instanceof ColumnOp) {
43-
return validateAndGetRange((ColumnOp) rightChild, (LiteralOp) leftChild, ctx);
36+
if (columnValue == null) {
37+
return validateAndGetRange(columnOp, literalOp, ctx);
4438
}
4539

4640
// We throw an exception for nulls, which will skip filtering.
47-
if (leftVal == null || rightVal == null) {
48-
throw new NullTypeException(leftChild, rightChild);
41+
if (literalValue == null) {
42+
throw new NullTypeException(columnOp, literalOp);
4943
}
44+
5045
return LeafEvaluationResult.createFromPartitionColumn(new PartitionEvaluationResult(
51-
new ColumnRange(leftVal, leftType), new ColumnRange(rightVal, rightType)));
46+
new ColumnRange(columnValue, columnType), literalValue));
47+
}
48+
49+
private static Pair<ColumnOp, LiteralOp> arrangeChildren(List<LeafOp> children) {
50+
if (children.get(0) instanceof ColumnOp)
51+
return Pair.of((ColumnOp) children.get(0), (LiteralOp) children.get(1));
52+
else
53+
return Pair.of((ColumnOp) children.get(1), (LiteralOp) children.get(0));
5254
}
5355

5456
// Implements "equal" between two leaf operations.
5557
static Boolean equal(List<LeafOp> children, EvalContext ctx) throws PredicateException {
58+
var columnOp = arrangeChildren(children).getLeft();
59+
var literalOp = arrangeChildren(children).getRight();
60+
61+
var leafEvaluationResult = validateAndGetTypeAndValue(columnOp, literalOp, ctx);
5662

57-
var leafEvaluationResult = validateAndGetTypeAndValue(children, ctx);
58-
var rangeEvaluation = leafEvaluationResult.rangeEvaluationResult.map(range -> {
59-
var columnRange = range.getColumnRange();
60-
var value = range.getValue();
63+
if (leafEvaluationResult.rangeEvaluationResult.isPresent()){
64+
var evaluationResult = leafEvaluationResult.rangeEvaluationResult.get();
65+
var columnRange = evaluationResult.getColumnRange();
66+
var value = evaluationResult.getValue();
6167
return columnRange.contains(value);
62-
});
63-
if (rangeEvaluation.isPresent()) return rangeEvaluation.get();
68+
}
69+
6470
else if (leafEvaluationResult.partitionEvaluationResult.isPresent()) {
65-
var typesAndValues = leafEvaluationResult.partitionEvaluationResult.get();
66-
var leftType = typesAndValues.getPartitionValue().getValueType();
67-
var leftVal = typesAndValues.getPartitionValue().getOnlyValue();
68-
var rightVal = typesAndValues.getLiteralValue().getOnlyValue();
69-
70-
// we fear no exception here since it is validated before
71-
if (BooleanType.BOOLEAN.equals(leftType)) {
72-
return Boolean.valueOf(leftVal) == Boolean.valueOf(rightVal);
73-
} else if (IntegerType.INTEGER.equals(leftType)) {
74-
return Integer.parseInt(leftVal) == Integer.parseInt(rightVal);
75-
} else if (LongType.LONG.equals(leftType)) {
76-
return Long.parseLong(leftVal) == Long.parseLong(rightVal);
77-
} else if (StringType.STRING.equals(leftType)) {
78-
return leftVal.equals(rightVal);
79-
} else if (DateType.DATE.equals(leftType)) {
80-
return Date.valueOf(leftVal).equals(Date.valueOf(rightVal));
81-
} else throw new TypeNotSupportedException(leftType);
71+
var evaluationResult = leafEvaluationResult.partitionEvaluationResult.get();
72+
var literalValue = evaluationResult.getLiteralValue();
73+
74+
return evaluationResult.getPartitionValue().contains(literalValue);
8275
} else throw new PredicateColumnEvaluationException(ctx);
76+
8377
}
8478

8579
static Boolean lessThan(List<LeafOp> children, EvalContext ctx) throws PredicateException {
80+
var columnOp = arrangeChildren(children).getLeft();
81+
var literalOp = arrangeChildren(children).getRight();
8682

87-
var leafEvaluationResult = validateAndGetTypeAndValue(children, ctx);
88-
var rangeEvaluation = leafEvaluationResult.rangeEvaluationResult.map(range -> {
89-
var columnRange = range.getColumnRange();
90-
var value = range.getValue();
91-
return columnRange.canBeLess(value);
92-
});
83+
var leafEvaluationResult = validateAndGetTypeAndValue(columnOp, literalOp, ctx);
9384

94-
if (rangeEvaluation.isPresent()) return rangeEvaluation.get();
85+
if (leafEvaluationResult.rangeEvaluationResult.isPresent()){
86+
var evaluationResult = leafEvaluationResult.rangeEvaluationResult.get();
87+
var columnRange = evaluationResult.getColumnRange();
88+
var value = evaluationResult.getValue();
89+
return columnRange.canBeLess(value);
90+
}
9591
else if (leafEvaluationResult.partitionEvaluationResult.isPresent()) {
96-
var typesAndValues = leafEvaluationResult.partitionEvaluationResult.get();
97-
var leftType = typesAndValues.getPartitionValue().getValueType();
98-
var leftVal = typesAndValues.getPartitionValue().getOnlyValue();
99-
var rightVal = typesAndValues.getLiteralValue().getOnlyValue();
100-
101-
if (IntegerType.INTEGER.equals(leftType)) {
102-
return Integer.parseInt(leftVal) < Integer.parseInt(rightVal);
103-
} else if (LongType.LONG.equals(leftType)) {
104-
return Long.parseLong(leftVal) < Long.parseLong(rightVal);
105-
} else if (StringType.STRING.equals(leftType)) {
106-
return leftVal.compareTo(rightVal) < 0;
107-
} else if (DateType.DATE.equals(leftType)) {
108-
return Date.valueOf(leftVal).before(Date.valueOf(rightVal));
109-
} else throw new TypeNotSupportedException(leftType);
92+
var evaluationResult = leafEvaluationResult.partitionEvaluationResult.get();
93+
var literalValue = evaluationResult.getLiteralValue();
94+
95+
return evaluationResult.getPartitionValue().canBeLess(literalValue);
11096
} else throw new PredicateColumnEvaluationException(ctx);
11197
}
11298

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
import com.fasterxml.jackson.annotation.JsonProperty;
44
import com.fasterxml.jackson.annotation.JsonSubTypes;
55
import com.fasterxml.jackson.annotation.JsonTypeInfo;
6+
import io.whitefox.core.ColumnRange;
67
import io.whitefox.core.types.DataType;
78
import java.util.List;
8-
import org.apache.commons.lang3.tuple.Pair;
99

1010
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "op")
1111
@JsonSubTypes({
@@ -19,12 +19,12 @@ public abstract class LeafOp implements BaseOp {
1919
@JsonProperty("valueType")
2020
DataType valueType;
2121

22-
Pair<String, DataType> evalExpectValueAndType(EvalContext ctx) throws PredicateException {
22+
ColumnRange evalExpectValueAndType(EvalContext ctx) throws PredicateException {
2323
var res = eval(ctx);
24-
if (res instanceof Pair) {
25-
return (Pair<String, DataType>) res;
24+
if (res instanceof ColumnRange) {
25+
return (ColumnRange) res;
2626
} else {
27-
throw new WrongExpectedTypeException(res, Pair.class);
27+
throw new WrongExpectedTypeException(res, ColumnRange.class);
2828
}
2929
}
3030

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44

55
import com.fasterxml.jackson.annotation.JsonProperty;
66
import com.fasterxml.jackson.annotation.JsonTypeInfo;
7+
import io.whitefox.core.ColumnRange;
78
import io.whitefox.core.types.DataType;
8-
import org.apache.commons.lang3.tuple.Pair;
99

1010
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "literal")
1111
public class LiteralOp extends LeafOp {
@@ -25,7 +25,7 @@ public void validate() throws PredicateException {
2525

2626
@Override
2727
public Object eval(EvalContext ctx) {
28-
return Pair.of(value, valueType);
28+
return new ColumnRange(value, valueType);
2929
}
3030

3131
public LiteralOp() {

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
public class PartitionEvaluationResult {
66

77
ColumnRange partitionValue;
8-
ColumnRange literalValue;
8+
String literalValue;
99

10-
public PartitionEvaluationResult(ColumnRange partitionValue, ColumnRange literalValue) {
10+
public PartitionEvaluationResult(ColumnRange partitionValue, String literalValue) {
1111
this.partitionValue = partitionValue;
1212
this.literalValue = literalValue;
1313
}
@@ -16,7 +16,7 @@ public ColumnRange getPartitionValue() {
1616
return partitionValue;
1717
}
1818

19-
public ColumnRange getLiteralValue() {
19+
public String getLiteralValue() {
2020
return literalValue;
2121
}
2222
}

server/core/src/test/java/io/whitefox/core/services/DeltaShareServiceTest.java

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

33
import io.whitefox.DeltaTestUtils;
4+
import io.whitefox.core.*;
45
import io.whitefox.core.Principal;
56
import io.whitefox.core.Schema;
67
import io.whitefox.core.Share;
78
import io.whitefox.core.SharedTable;
8-
import io.whitefox.core.*;
99
import io.whitefox.core.services.exceptions.TableNotFound;
1010
import io.whitefox.persistence.StorageManager;
1111
import io.whitefox.persistence.memory.InMemoryStorageManager;
@@ -273,7 +273,7 @@ public void queryNonExistingTable() {
273273
"name"))));
274274
StorageManager storageManager = new InMemoryStorageManager(shares);
275275
DeltaSharesService deltaSharesService =
276-
new DeltaSharesServiceImpl(storageManager, 100, loader, fileSignerFactory);
276+
new DeltaSharesServiceImpl(storageManager, 100, tableLoaderFactory, fileSignerFactory);
277277
Assertions.assertThrows(
278278
TableNotFound.class,
279279
() -> deltaSharesService.queryTable("name", "default", "tableNotFound", null));

server/core/src/test/java/io/whitefox/core/services/DeltaSharedTableTest.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@
88
import io.whitefox.core.Protocol;
99
import io.whitefox.core.ReadTableRequest;
1010
import io.whitefox.core.SharedTable;
11-
12-
import java.sql.Timestamp;
1311
import java.time.format.DateTimeParseException;
1412
import java.util.List;
1513
import java.util.Optional;
@@ -74,7 +72,7 @@ void getTableVersionWithMalformedTimestamp() {
7472
var DTable = DeltaSharedTable.of(PTable);
7573
assertThrows(
7674
DateTimeParseException.class,
77-
() -> DTable.getTableVersion(Optional.of(Timestamp.valueOf("221rfewdsad10:15:30+01:00"))));
75+
() -> DTable.getTableVersion(TestDateUtils.parseTimestamp("221rfewdsad10:15:30+01:00")));
7876
}
7977

8078
@Test

0 commit comments

Comments
 (0)