Skip to content

Commit c843f96

Browse files
Alibaba-HZYwuchong
authored andcommitted
[common] Introduce Predicate interface and basic predicate expressions (#515)
1 parent 9e04120 commit c843f96

34 files changed

+2800
-0
lines changed
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package com.alibaba.fluss.predicate;
19+
20+
import com.alibaba.fluss.row.InternalRow;
21+
22+
import java.util.ArrayList;
23+
import java.util.List;
24+
import java.util.Optional;
25+
26+
/* This file is based on source code of Apache Paimon Project (https://paimon.apache.org/), licensed by the Apache
27+
* Software Foundation (ASF) under the Apache License, Version 2.0. See the NOTICE file distributed with this work for
28+
* additional information regarding copyright ownership. */
29+
30+
/** A {@link CompoundPredicate.Function} to eval and. */
31+
public class And extends CompoundPredicate.Function {
32+
33+
private static final long serialVersionUID = -2977938814804928712L;
34+
35+
public static final And INSTANCE = new And();
36+
37+
private And() {}
38+
39+
@Override
40+
public boolean test(InternalRow row, List<Predicate> children) {
41+
for (Predicate child : children) {
42+
if (!child.test(row)) {
43+
return false;
44+
}
45+
}
46+
return true;
47+
}
48+
49+
@Override
50+
public Optional<Predicate> negate(List<Predicate> children) {
51+
List<Predicate> negatedChildren = new ArrayList<>();
52+
for (Predicate child : children) {
53+
Optional<Predicate> negatedChild = child.negate();
54+
if (negatedChild.isPresent()) {
55+
negatedChildren.add(negatedChild.get());
56+
} else {
57+
return Optional.empty();
58+
}
59+
}
60+
return Optional.of(new CompoundPredicate(Or.INSTANCE, negatedChildren));
61+
}
62+
63+
@Override
64+
public <T> T visit(FunctionVisitor<T> visitor, List<T> children) {
65+
return visitor.visitAnd(children);
66+
}
67+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package com.alibaba.fluss.predicate;
19+
20+
import com.alibaba.fluss.row.BinaryString;
21+
import com.alibaba.fluss.types.DataType;
22+
23+
import static java.lang.Math.min;
24+
25+
/* This file is based on source code of Apache Paimon Project (https://paimon.apache.org/), licensed by the Apache
26+
* Software Foundation (ASF) under the Apache License, Version 2.0. See the NOTICE file distributed with this work for
27+
* additional information regarding copyright ownership. */
28+
29+
/** Utils for comparator. */
30+
public class CompareUtils {
31+
private CompareUtils() {}
32+
33+
public static int compareLiteral(DataType type, Object v1, Object v2) {
34+
if (v1 instanceof Comparable) {
35+
// because BinaryString can not serialize so v1 or v2 may be BinaryString convert to
36+
// String for compare
37+
if (v1 instanceof BinaryString) {
38+
v1 = ((BinaryString) v1).toString();
39+
}
40+
if (v2 instanceof BinaryString) {
41+
v2 = ((BinaryString) v2).toString();
42+
}
43+
return ((Comparable<Object>) v1).compareTo(v2);
44+
} else if (v1 instanceof byte[]) {
45+
return compare((byte[]) v1, (byte[]) v2);
46+
} else {
47+
throw new RuntimeException("Unsupported type: " + type);
48+
}
49+
}
50+
51+
private static int compare(byte[] first, byte[] second) {
52+
for (int x = 0; x < min(first.length, second.length); x++) {
53+
int cmp = first[x] - second[x];
54+
if (cmp != 0) {
55+
return cmp;
56+
}
57+
}
58+
return first.length - second.length;
59+
}
60+
}
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package com.alibaba.fluss.predicate;
19+
20+
import com.alibaba.fluss.row.InternalRow;
21+
22+
import java.io.Serializable;
23+
import java.util.List;
24+
import java.util.Objects;
25+
import java.util.Optional;
26+
27+
/* This file is based on source code of Apache Paimon Project (https://paimon.apache.org/), licensed by the Apache
28+
* Software Foundation (ASF) under the Apache License, Version 2.0. See the NOTICE file distributed with this work for
29+
* additional information regarding copyright ownership. */
30+
31+
/**
32+
* Non-leaf node in a {@link Predicate} tree. Its evaluation result depends on the results of its
33+
* children.
34+
*/
35+
public class CompoundPredicate implements Predicate {
36+
37+
private final Function function;
38+
private final List<Predicate> children;
39+
40+
public CompoundPredicate(Function function, List<Predicate> children) {
41+
this.function = function;
42+
this.children = children;
43+
}
44+
45+
public Function function() {
46+
return function;
47+
}
48+
49+
public List<Predicate> children() {
50+
return children;
51+
}
52+
53+
@Override
54+
public boolean test(InternalRow row) {
55+
return function.test(row, children);
56+
}
57+
58+
@Override
59+
public Optional<Predicate> negate() {
60+
return function.negate(children);
61+
}
62+
63+
@Override
64+
public <T> T visit(PredicateVisitor<T> visitor) {
65+
return visitor.visit(this);
66+
}
67+
68+
@Override
69+
public boolean equals(Object o) {
70+
if (!(o instanceof CompoundPredicate)) {
71+
return false;
72+
}
73+
CompoundPredicate that = (CompoundPredicate) o;
74+
return Objects.equals(function, that.function) && Objects.equals(children, that.children);
75+
}
76+
77+
@Override
78+
public int hashCode() {
79+
return Objects.hash(function, children);
80+
}
81+
82+
@Override
83+
public String toString() {
84+
return function + "(" + children + ")";
85+
}
86+
87+
/** Evaluate the predicate result based on multiple {@link Predicate}s. */
88+
public abstract static class Function implements Serializable {
89+
90+
public abstract boolean test(InternalRow row, List<Predicate> children);
91+
92+
public abstract Optional<Predicate> negate(List<Predicate> children);
93+
94+
public abstract <T> T visit(FunctionVisitor<T> visitor, List<T> children);
95+
96+
@Override
97+
public int hashCode() {
98+
return this.getClass().getName().hashCode();
99+
}
100+
101+
@Override
102+
public boolean equals(Object o) {
103+
if (this == o) {
104+
return true;
105+
}
106+
return o != null && getClass() == o.getClass();
107+
}
108+
109+
@Override
110+
public String toString() {
111+
return getClass().getSimpleName();
112+
}
113+
}
114+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package com.alibaba.fluss.predicate;
19+
20+
import com.alibaba.fluss.types.DataType;
21+
22+
import java.util.List;
23+
import java.util.Optional;
24+
25+
/* This file is based on source code of Apache Paimon Project (https://paimon.apache.org/), licensed by the Apache
26+
* Software Foundation (ASF) under the Apache License, Version 2.0. See the NOTICE file distributed with this work for
27+
* additional information regarding copyright ownership. */
28+
29+
/** A {@link NullFalseLeafBinaryFunction} to evaluate {@code filter like '%abc%'}. */
30+
public class Contains extends NullFalseLeafBinaryFunction {
31+
32+
public static final Contains INSTANCE = new Contains();
33+
34+
private Contains() {}
35+
36+
@Override
37+
public boolean test(DataType type, Object field, Object patternLiteral) {
38+
String fieldString = field.toString();
39+
return fieldString.contains((String) patternLiteral);
40+
}
41+
42+
@Override
43+
public boolean test(
44+
DataType type,
45+
long rowCount,
46+
Object min,
47+
Object max,
48+
Long nullCount,
49+
Object patternLiteral) {
50+
return true;
51+
}
52+
53+
@Override
54+
public Optional<LeafFunction> negate() {
55+
return Optional.empty();
56+
}
57+
58+
@Override
59+
public <T> T visit(FunctionVisitor<T> visitor, FieldRef fieldRef, List<Object> literals) {
60+
return visitor.visitContains(fieldRef, literals.get(0));
61+
}
62+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package com.alibaba.fluss.predicate;
19+
20+
import com.alibaba.fluss.types.DataType;
21+
22+
import java.util.List;
23+
import java.util.Optional;
24+
25+
/* This file is based on source code of Apache Paimon Project (https://paimon.apache.org/), licensed by the Apache
26+
* Software Foundation (ASF) under the Apache License, Version 2.0. See the NOTICE file distributed with this work for
27+
* additional information regarding copyright ownership. */
28+
29+
/**
30+
* A {@link NullFalseLeafBinaryFunction} to evaluate {@code filter like '%abc' or filter like
31+
* '_abc'}.
32+
*/
33+
public class EndsWith extends NullFalseLeafBinaryFunction {
34+
35+
public static final EndsWith INSTANCE = new EndsWith();
36+
37+
private EndsWith() {}
38+
39+
@Override
40+
public boolean test(DataType type, Object field, Object patternLiteral) {
41+
String fieldString = field.toString();
42+
return fieldString.endsWith((String) patternLiteral);
43+
}
44+
45+
@Override
46+
public boolean test(
47+
DataType type,
48+
long rowCount,
49+
Object min,
50+
Object max,
51+
Long nullCount,
52+
Object patternLiteral) {
53+
return true;
54+
}
55+
56+
@Override
57+
public Optional<LeafFunction> negate() {
58+
return Optional.empty();
59+
}
60+
61+
@Override
62+
public <T> T visit(FunctionVisitor<T> visitor, FieldRef fieldRef, List<Object> literals) {
63+
return visitor.visitEndsWith(fieldRef, literals.get(0));
64+
}
65+
}

0 commit comments

Comments
 (0)