-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Read interface support predicate (#22)
(cherry picked from commit 5e7d468)
- Loading branch information
Showing
11 changed files
with
735 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
################################################################################ | ||
# Licensed to the Apache Software Foundation (ASF) under one | ||
# or more contributor license agreements. See the NOTICE file | ||
# distributed with this work for additional information | ||
# regarding copyright ownership. The ASF licenses this file | ||
# to you under the Apache License, Version 2.0 (the | ||
# "License"); you may not use this file except in compliance | ||
# with the License. You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
################################################################################# | ||
|
||
from abc import ABC, abstractmethod | ||
from typing import Any, List | ||
|
||
|
||
class Predicate(ABC): | ||
"""Predicate which evaluates to a boolean. Now it doesn't have | ||
any methods because only paimon_python_java implement it and | ||
the Java implementation convert it to Java object.""" | ||
|
||
|
||
class PredicateBuilder(ABC): | ||
"""A utility class to create Predicate object for common filter conditions.""" | ||
|
||
@abstractmethod | ||
def equal(self, field: str, literal: Any) -> Predicate: | ||
"""field = literal""" | ||
|
||
@abstractmethod | ||
def not_equal(self, field: str, literal: Any) -> Predicate: | ||
"""field <> literal""" | ||
|
||
@abstractmethod | ||
def less_than(self, field: str, literal: Any) -> Predicate: | ||
"""field < literal""" | ||
|
||
@abstractmethod | ||
def less_or_equal(self, field: str, literal: Any) -> Predicate: | ||
"""field <= literal""" | ||
|
||
@abstractmethod | ||
def greater_than(self, field: str, literal: Any) -> Predicate: | ||
"""field > literal""" | ||
|
||
@abstractmethod | ||
def greater_or_equal(self, field: str, literal: Any) -> Predicate: | ||
"""field >= literal""" | ||
|
||
@abstractmethod | ||
def is_null(self, field: str) -> Predicate: | ||
"""field IS NULL""" | ||
|
||
@abstractmethod | ||
def is_not_null(self, field: str) -> Predicate: | ||
"""field IS NOT NULL""" | ||
|
||
@abstractmethod | ||
def startswith(self, field: str, pattern_literal: Any) -> Predicate: | ||
"""field.startswith""" | ||
|
||
@abstractmethod | ||
def endswith(self, field: str, pattern_literal: Any) -> Predicate: | ||
"""field.endswith()""" | ||
|
||
@abstractmethod | ||
def contains(self, field: str, pattern_literal: Any) -> Predicate: | ||
"""literal in field""" | ||
|
||
@abstractmethod | ||
def is_in(self, field: str, literals: List[Any]) -> Predicate: | ||
"""field IN literals""" | ||
|
||
@abstractmethod | ||
def is_not_in(self, field: str, literals: List[Any]) -> Predicate: | ||
"""field NOT IN literals""" | ||
|
||
@abstractmethod | ||
def between(self, field: str, included_lower_bound: Any, included_upper_bound: Any) \ | ||
-> Predicate: | ||
"""field BETWEEN included_lower_bound AND included_upper_bound""" | ||
|
||
@abstractmethod | ||
def and_predicates(self, predicates: List[Predicate]) -> Predicate: | ||
"""predicate1 AND predicate2 AND ...""" | ||
|
||
@abstractmethod | ||
def or_predicates(self, predicates: List[Predicate]) -> Predicate: | ||
"""predicate1 OR predicate2 OR ...""" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
111 changes: 111 additions & 0 deletions
111
...ava/paimon-python-java-bridge/src/main/java/org/apache/paimon/python/PredicationUtil.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
/* | ||
* Licensed to the Apache Software Foundation (ASF) under one | ||
* or more contributor license agreements. See the NOTICE file | ||
* distributed with this work for additional information | ||
* regarding copyright ownership. The ASF licenses this file | ||
* to you under the Apache License, Version 2.0 (the | ||
* "License"); you may not use this file except in compliance | ||
* with the License. You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package org.apache.paimon.python; | ||
|
||
import org.apache.paimon.data.BinaryString; | ||
import org.apache.paimon.predicate.Predicate; | ||
import org.apache.paimon.predicate.PredicateBuilder; | ||
import org.apache.paimon.types.DataType; | ||
import org.apache.paimon.types.RowType; | ||
|
||
import java.util.List; | ||
import java.util.stream.Collectors; | ||
|
||
/** For building Predicate. */ | ||
public class PredicationUtil { | ||
|
||
public static Predicate build( | ||
RowType rowType, | ||
PredicateBuilder builder, | ||
String method, | ||
int index, | ||
List<Object> literals) { | ||
literals = | ||
literals.stream() | ||
.map(l -> convertJavaObject(rowType.getTypeAt(index), l)) | ||
.collect(Collectors.toList()); | ||
switch (method) { | ||
case "equal": | ||
return builder.equal(index, literals.get(0)); | ||
case "notEqual": | ||
return builder.notEqual(index, literals.get(0)); | ||
case "lessThan": | ||
return builder.lessThan(index, literals.get(0)); | ||
case "lessOrEqual": | ||
return builder.lessOrEqual(index, literals.get(0)); | ||
case "greaterThan": | ||
return builder.greaterThan(index, literals.get(0)); | ||
case "greaterOrEqual": | ||
return builder.greaterOrEqual(index, literals.get(0)); | ||
case "isNull": | ||
return builder.isNull(index); | ||
case "isNotNull": | ||
return builder.isNotNull(index); | ||
case "startsWith": | ||
return builder.startsWith(index, literals.get(0)); | ||
case "endsWith": | ||
return builder.endsWith(index, literals.get(0)); | ||
case "contains": | ||
return builder.contains(index, literals.get(0)); | ||
case "in": | ||
return builder.in(index, literals); | ||
case "notIn": | ||
return builder.notIn(index, literals); | ||
case "between": | ||
return builder.between(index, literals.get(0), literals.get(1)); | ||
default: | ||
throw new UnsupportedOperationException( | ||
"Unknown PredicateBuilder method " + method); | ||
} | ||
} | ||
|
||
/** Some type is not convenient to transfer from Python to Java. */ | ||
private static Object convertJavaObject(DataType literalType, Object literal) { | ||
switch (literalType.getTypeRoot()) { | ||
case BOOLEAN: | ||
case DOUBLE: | ||
case INTEGER: | ||
return literal; | ||
case CHAR: | ||
case VARCHAR: | ||
return BinaryString.fromString((String) literal); | ||
case FLOAT: | ||
return ((Number) literal).floatValue(); | ||
case TINYINT: | ||
return ((Number) literal).byteValue(); | ||
case SMALLINT: | ||
return ((Number) literal).shortValue(); | ||
case BIGINT: | ||
return ((Number) literal).longValue(); | ||
default: | ||
throw new UnsupportedOperationException( | ||
"Unsupported predicate leaf type " + literalType.getTypeRoot().name()); | ||
} | ||
} | ||
|
||
public static Predicate buildAnd(List<Predicate> predicates) { | ||
// 'and' is keyword of Python | ||
return PredicateBuilder.and(predicates); | ||
} | ||
|
||
public static Predicate buildOr(List<Predicate> predicates) { | ||
// 'or' is keyword of Python | ||
return PredicateBuilder.or(predicates); | ||
} | ||
} |
Oops, something went wrong.