Skip to content

Commit ceea491

Browse files
committed
wip- sql predicates without error handling
1 parent d194a73 commit ceea491

File tree

12 files changed

+177
-69
lines changed

12 files changed

+177
-69
lines changed

server/app/src/main/java/io/whitefox/api/deltasharing/DeltaMappers.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public static ReadTableRequest api2ReadTableRequest(QueryRequest request) {
3131
if (request.getVersion() != null && request.getTimestamp() == null) {
3232
return new ReadTableRequest.ReadTableVersion(
3333
request.getPredicateHints(),
34-
Optional.ofNullable(request.getLimitHint()),
34+
jsonPredicateHints, Optional.ofNullable(request.getLimitHint()),
3535
request.getVersion());
3636
} else if (request.getVersion() == null && request.getTimestamp() != null) {
3737
return new ReadTableRequest.ReadTableAsOfTimestamp(

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

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ private Boolean typedContains(String point) {
3434
return (c1 <= 0 && c2 >= 0);
3535
} else if (valueType instanceof TimestampType) {
3636
var c1 = Timestamp.valueOf(minVal).before(Timestamp.valueOf(point));
37-
var c2 = Timestamp.valueOf(maxVal).before(Timestamp.valueOf(point));
37+
var c2 = Timestamp.valueOf(maxVal).after(Timestamp.valueOf(point));
3838
return c1 && c2;
3939
} else if (valueType instanceof FloatType) {
4040
var c1 = Float.compare(Float.parseFloat(minVal), Float.parseFloat(point));
@@ -46,7 +46,7 @@ private Boolean typedContains(String point) {
4646
return (c1 <= 0 && c2 >= 0);
4747
} else if (valueType instanceof DateType) {
4848
var c1 = Date.valueOf(minVal).before(Date.valueOf(point));
49-
var c2 = Date.valueOf(maxVal).before(Date.valueOf(point));
49+
var c2 = Date.valueOf(maxVal).after(Date.valueOf(point));
5050
return c1 && c2;
5151
} else if (valueType instanceof BooleanType) {
5252
var c1 = Boolean.parseBoolean(minVal) == Boolean.parseBoolean(point);
@@ -59,15 +59,6 @@ private Boolean typedContains(String point) {
5959
}
6060
}
6161

62-
public static void main(String[] args) {
63-
var minVal = "4";
64-
var point = "5";
65-
var maxVal = "8";
66-
67-
var cr = new ColumnRange(minVal, maxVal, IntegerType.INTEGER);
68-
cr.typedLessThan(point);
69-
}
70-
7162
private Boolean typedLessThan(String point) {
7263
if (valueType instanceof IntegerType) {
7364
var c1 = Integer.compare(Integer.parseInt(minVal), Integer.parseInt(point));
@@ -85,7 +76,6 @@ private Boolean typedLessThan(String point) {
8576
return (c1 < 0);
8677
} else if (valueType instanceof DateType) {
8778
return Date.valueOf(minVal).before(Date.valueOf(point));
88-
8979
} else {
9080
var c = minVal.compareTo(point);
9181
return (c < 0);

server/core/src/main/java/io/whitefox/core/JsonPredicatesUtils.java renamed to server/core/src/main/java/io/whitefox/core/PredicateUtils.java

Lines changed: 41 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,23 @@
22

33
import com.fasterxml.jackson.core.JsonProcessingException;
44
import com.fasterxml.jackson.databind.ObjectMapper;
5+
import io.delta.standalone.Snapshot;
56
import io.delta.standalone.actions.AddFile;
6-
import io.delta.standalone.expressions.IsNull;
77
import io.whitefox.core.types.DataType;
8-
import io.whitefox.core.types.DateType;
98
import io.whitefox.core.types.predicates.*;
109

1110
import java.util.List;
12-
import java.util.Objects;
1311
import java.util.Optional;
1412

1513
import net.sf.jsqlparser.JSQLParserException;
1614
import net.sf.jsqlparser.expression.BinaryExpression;
15+
import net.sf.jsqlparser.expression.Expression;
16+
import net.sf.jsqlparser.expression.StringValue;
1717
import net.sf.jsqlparser.expression.operators.relational.IsNullExpression;
1818
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
19-
import net.sf.jsqlparser.statement.select.PlainSelect;
2019
import org.apache.commons.lang3.tuple.Pair;
2120

22-
public class JsonPredicatesUtils {
21+
public class PredicateUtils {
2322

2423
private static final ObjectMapper objectMapper = DeltaObjectMapper.getInstance();
2524

@@ -31,29 +30,45 @@ public static BaseOp parseJsonPredicate(String predicate) throws PredicateParsin
3130
}
3231
}
3332

34-
public static BaseOp parseSqlPredicate(String predicate, DataType dataType) throws JSQLParserException, PredicateException {
35-
var expression = CCJSqlParserUtil.parseCondExpression(predicate);
36-
if (expression instanceof IsNullExpression){
37-
var isNullExpression = (IsNullExpression) expression;
38-
String column = isNullExpression.getLeftExpression().getASTNode().jjtGetFirstToken().toString();
39-
var colOp = new ColumnOp(column, dataType);
40-
var children = List.of((LeafOp) colOp);
41-
var operator = "isnull";
42-
return NonLeafOp.createPartitionFilter(children, operator);
33+
public static BaseOp parseSqlPredicate(String predicate, EvalContext ctx, Metadata metadata) throws PredicateException {
34+
try {
35+
var expression = CCJSqlParserUtil.parseCondExpression(predicate);
36+
if (expression instanceof IsNullExpression){
37+
var isNullExpression = (IsNullExpression) expression;
38+
String column = isNullExpression.getLeftExpression().getASTNode().jjtGetFirstToken().toString();
39+
var dataType = metadata.tableSchema().structType().get(column).getDataType();
40+
var colOp = new ColumnOp(column, dataType);
41+
var children = List.of((LeafOp) colOp);
42+
var operator = "isnull";
43+
return NonLeafOp.createPartitionFilter(children, operator);
44+
}
45+
else if (expression instanceof BinaryExpression) {
46+
BinaryExpression binaryExpression = (BinaryExpression) expression;
47+
String column = binaryExpression.getLeftExpression().toString();
48+
String operator = binaryExpression.getStringExpression();
49+
Expression value = binaryExpression.getRightExpression();
50+
if (value instanceof StringValue) {
51+
StringValue stringValue = (StringValue) value;
52+
var dataType = metadata.tableSchema().structType().get(column).getDataType();
53+
var colOp = new ColumnOp(column, dataType);
54+
var litOp = new LiteralOp(stringValue.getValue(), dataType);
55+
var children = List.of(colOp, litOp);
56+
return NonLeafOp.createPartitionFilter(children, operator);
57+
}
58+
else {
59+
var dataType = metadata.tableSchema().structType().get(column).getDataType();
60+
var colOp = new ColumnOp(column, dataType);
61+
var litOp = new LiteralOp(value.toString(), dataType);
62+
var children = List.of(colOp, litOp);
63+
return NonLeafOp.createPartitionFilter(children, operator);
64+
}
65+
}
66+
else
67+
throw new ExpressionNotSupportedException(predicate);
4368
}
44-
else if (expression instanceof BinaryExpression) {
45-
BinaryExpression binaryExpression = (BinaryExpression) expression;
46-
String column = binaryExpression.getLeftExpression().toString();
47-
String operator = binaryExpression.getStringExpression();
48-
String value = binaryExpression.getRightExpression().toString();
49-
var colOp = new ColumnOp(column, dataType);
50-
var litOp = new LiteralOp(value, dataType);
51-
var children = List.of(colOp, litOp);
52-
return NonLeafOp.createPartitionFilter(children, operator);
69+
catch (JSQLParserException e) {
70+
throw new PredicateParsingException(e);
5371
}
54-
// TODO: PARSING FAIL on sql;
55-
else
56-
throw new PredicateException();
5772
}
5873

5974

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

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,23 @@ public interface ReadTableRequest {
99

1010
public static class ReadTableVersion implements ReadTableRequest {
1111
private final List<String> predicateHints;
12+
private final List<String> jsonPredicateHints;
1213
private final Optional<Integer> limitHint;
1314

1415
private final Long version;
1516

1617
public ReadTableVersion(
17-
List<String> predicateHints, Optional<Integer> limitHint, Long version) {
18+
List<String> predicateHints, List<String> jsonPredicateHints, Optional<Integer> limitHint, Long version) {
1819
this.predicateHints = predicateHints;
20+
this.jsonPredicateHints = jsonPredicateHints;
1921
this.limitHint = limitHint;
2022
this.version = version;
2123
}
2224

25+
public List<String> jsonPredicateHints() {
26+
return jsonPredicateHints;
27+
}
28+
2329
public List<String> predicateHints() {
2430
return predicateHints;
2531
}
@@ -39,60 +45,70 @@ public boolean equals(Object o) {
3945
if (o == null || getClass() != o.getClass()) return false;
4046
ReadTableVersion that = (ReadTableVersion) o;
4147
return Objects.equals(predicateHints, that.predicateHints)
48+
&& Objects.equals(jsonPredicateHints, that.jsonPredicateHints)
4249
&& Objects.equals(limitHint, that.limitHint)
4350
&& Objects.equals(version, that.version);
4451
}
4552

4653
@Override
4754
@SkipCoverageGenerated
4855
public int hashCode() {
49-
return Objects.hash(predicateHints, limitHint, version);
56+
return Objects.hash(predicateHints, jsonPredicateHints, limitHint, version);
5057
}
5158

5259
@Override
5360
@SkipCoverageGenerated
5461
public String toString() {
5562
return "ReadTableVersion{" + "predicateHints="
56-
+ predicateHints + ", limitHint="
63+
+ predicateHints + "jsonPredicateHints="
64+
+ jsonPredicateHints + ", limitHint="
5765
+ limitHint + ", version="
5866
+ version + '}';
5967
}
6068
}
6169

6270
public static class ReadTableAsOfTimestamp implements ReadTableRequest {
6371
private final List<String> predicateHints;
72+
private final List<String> jsonPredicateHints;
6473
private final Optional<Integer> limitHint;
6574
private final Long timestamp;
6675

6776
public ReadTableAsOfTimestamp(
68-
List<String> predicateHints, Optional<Integer> limitHint, Long timestamp) {
77+
List<String> predicateHints, List<String> jsonPredicateHints, Optional<Integer> limitHint, Long timestamp) {
6978
this.predicateHints = predicateHints;
79+
this.jsonPredicateHints = jsonPredicateHints;
7080
this.limitHint = limitHint;
7181
this.timestamp = timestamp;
7282
}
7383

84+
public List<String> jsonPredicateHints() {
85+
return jsonPredicateHints;
86+
}
87+
7488
@Override
7589
@SkipCoverageGenerated
7690
public boolean equals(Object o) {
7791
if (this == o) return true;
7892
if (o == null || getClass() != o.getClass()) return false;
7993
ReadTableAsOfTimestamp that = (ReadTableAsOfTimestamp) o;
8094
return Objects.equals(predicateHints, that.predicateHints)
95+
&& Objects.equals(jsonPredicateHints, that.jsonPredicateHints)
8196
&& Objects.equals(limitHint, that.limitHint)
8297
&& Objects.equals(timestamp, that.timestamp);
8398
}
8499

85100
@Override
86101
@SkipCoverageGenerated
87102
public int hashCode() {
88-
return Objects.hash(predicateHints, limitHint, timestamp);
103+
return Objects.hash(jsonPredicateHints, predicateHints, limitHint, timestamp);
89104
}
90105

91106
@Override
92107
@SkipCoverageGenerated
93108
public String toString() {
94109
return "ReadTableAsOfTimestamp{" + "predicateHints="
95-
+ predicateHints + ", limitHint="
110+
+ predicateHints + "jsonPredicateHints="
111+
+ jsonPredicateHints + ", limitHint="
96112
+ limitHint + ", timestamp="
97113
+ timestamp + '}';
98114
}
@@ -112,17 +128,23 @@ public Long timestamp() {
112128

113129
public static class ReadTableCurrentVersion implements ReadTableRequest {
114130
private final List<String> predicateHints;
131+
private final List<String> jsonPredicateHints;
115132
private final Optional<Integer> limitHint;
116133

117-
public ReadTableCurrentVersion(List<String> predicateHints, Optional<Integer> limitHint) {
134+
public ReadTableCurrentVersion(List<String> predicateHints, List<String> jsonPredicateHints, Optional<Integer> limitHint) {
118135
this.predicateHints = predicateHints;
136+
this.jsonPredicateHints = jsonPredicateHints;
119137
this.limitHint = limitHint;
120138
}
121139

122140
public List<String> predicateHints() {
123141
return predicateHints;
124142
}
125143

144+
public List<String> jsonPredicateHints() {
145+
return jsonPredicateHints;
146+
}
147+
126148
public Optional<Integer> limitHint() {
127149
return limitHint;
128150
}
@@ -131,7 +153,8 @@ public Optional<Integer> limitHint() {
131153
@SkipCoverageGenerated
132154
public String toString() {
133155
return "ReadTableCurrentVersion{" + "predicateHints="
134-
+ predicateHints + ", limitHint="
156+
+ predicateHints + "jsonPredicateHints="
157+
+ jsonPredicateHints + ", limitHint="
135158
+ limitHint + '}';
136159
}
137160

@@ -142,13 +165,14 @@ public boolean equals(Object o) {
142165
if (o == null || getClass() != o.getClass()) return false;
143166
ReadTableCurrentVersion that = (ReadTableCurrentVersion) o;
144167
return Objects.equals(predicateHints, that.predicateHints)
168+
&& Objects.equals(jsonPredicateHints, that.jsonPredicateHints)
145169
&& Objects.equals(limitHint, that.limitHint);
146170
}
147171

148172
@Override
149173
@SkipCoverageGenerated
150174
public int hashCode() {
151-
return Objects.hash(predicateHints, limitHint);
175+
return Objects.hash(jsonPredicateHints, predicateHints, limitHint);
152176
}
153177
}
154178
}

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

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ public Optional<Long> getTableVersion(Optional<String> startingTimestamp) {
8888

8989
private boolean evaluateJsonPredicate(String predicate, EvalContext ctx, AddFile f) {
9090
try {
91-
var parsedPredicate = JsonPredicatesUtils.parseJsonPredicate(predicate);
91+
var parsedPredicate = PredicateUtils.parseJsonPredicate(predicate);
9292
return parsedPredicate.evalExpectBoolean(ctx);
9393
} catch (PredicateException e) {
9494
logger.debug("Caught exception for predicate: " + predicate + " - " + e.getMessage());
@@ -99,13 +99,42 @@ private boolean evaluateJsonPredicate(String predicate, EvalContext ctx, AddFile
9999
}
100100
}
101101

102+
private boolean evaluateSqlPredicate(String predicate, EvalContext ctx, AddFile f, Metadata metadata) {
103+
try {
104+
var parsedPredicate = PredicateUtils.parseSqlPredicate(predicate, ctx, metadata);
105+
return parsedPredicate.evalExpectBoolean(ctx);
106+
} catch (PredicateException e) {
107+
logger.debug("Caught exception for predicate: " + predicate + " - " + e.getMessage());
108+
logger.info("File: " + f.getPath()
109+
+ " will be used in processing due to failure in parsing or processing the predicate: "
110+
+ predicate);
111+
return true;
112+
}
113+
}
114+
115+
public boolean filterFilesBasedOnSqlPredicates(List<String> predicates, AddFile f, Metadata metadata) {
116+
// if there are no predicates return all possible files
117+
if (predicates == null) {
118+
return true;
119+
}
120+
try {
121+
var ctx = PredicateUtils.createEvalContext(f);
122+
return predicates.stream().allMatch(p -> evaluateSqlPredicate(p, ctx, f, metadata));
123+
} catch (PredicateException e) {
124+
logger.debug("Caught exception: " + e.getMessage());
125+
logger.info("File: " + f.getPath()
126+
+ " will be used in processing due to failure in parsing or processing the predicate");
127+
return true;
128+
}
129+
}
130+
102131
public boolean filterFilesBasedOnJsonPredicates(List<String> predicates, AddFile f) {
103132
// if there are no predicates return all possible files
104133
if (predicates == null) {
105134
return true;
106135
}
107136
try {
108-
var ctx = JsonPredicatesUtils.createEvalContext(f);
137+
var ctx = PredicateUtils.createEvalContext(f);
109138
return predicates.stream().allMatch(p -> evaluateJsonPredicate(p, ctx, f));
110139
} catch (PredicateException e) {
111140
logger.debug("Caught exception: " + e.getMessage());
@@ -114,30 +143,35 @@ public boolean filterFilesBasedOnJsonPredicates(List<String> predicates, AddFile
114143
return true;
115144
}
116145
}
117-
;
118146

119147
public ReadTableResultToBeSigned queryTable(ReadTableRequest readTableRequest) {
120148
List<String> predicates;
149+
List<String> sqlPredicates;
121150
Snapshot snapshot;
122151
if (readTableRequest instanceof ReadTableRequest.ReadTableCurrentVersion) {
123152
snapshot = deltaLog.snapshot();
124-
predicates = ((ReadTableRequest.ReadTableCurrentVersion) readTableRequest).predicateHints();
153+
predicates = ((ReadTableRequest.ReadTableCurrentVersion) readTableRequest).jsonPredicateHints();
154+
sqlPredicates = ((ReadTableRequest.ReadTableCurrentVersion) readTableRequest).predicateHints();
125155
} else if (readTableRequest instanceof ReadTableRequest.ReadTableAsOfTimestamp) {
126156
snapshot = deltaLog.getSnapshotForTimestampAsOf(
127157
((ReadTableRequest.ReadTableAsOfTimestamp) readTableRequest).timestamp());
128-
predicates = ((ReadTableRequest.ReadTableAsOfTimestamp) readTableRequest).predicateHints();
158+
predicates = ((ReadTableRequest.ReadTableAsOfTimestamp) readTableRequest).jsonPredicateHints();
159+
sqlPredicates = ((ReadTableRequest.ReadTableAsOfTimestamp) readTableRequest).predicateHints();
129160
} else if (readTableRequest instanceof ReadTableRequest.ReadTableVersion) {
130161
snapshot = deltaLog.getSnapshotForVersionAsOf(
131162
((ReadTableRequest.ReadTableVersion) readTableRequest).version());
132-
predicates = ((ReadTableRequest.ReadTableVersion) readTableRequest).predicateHints();
163+
predicates = ((ReadTableRequest.ReadTableVersion) readTableRequest).jsonPredicateHints();
164+
sqlPredicates = ((ReadTableRequest.ReadTableVersion) readTableRequest).predicateHints();
133165
} else {
134166
throw new IllegalArgumentException("Unknown ReadTableRequest type: " + readTableRequest);
135167
}
168+
var metadata = metadataFromSnapshot(snapshot);
136169
return new ReadTableResultToBeSigned(
137170
new Protocol(Optional.of(1)),
138-
metadataFromSnapshot(snapshot),
171+
metadata,
139172
snapshot.getAllFiles().stream()
140173
.filter(f -> filterFilesBasedOnJsonPredicates(predicates, f))
174+
.filter(f -> filterFilesBasedOnSqlPredicates(sqlPredicates, f, metadata))
141175
.map(f -> new TableFileToBeSigned(
142176
location() + "/" + f.getPath(),
143177
f.getSize(),

0 commit comments

Comments
 (0)