blob: 95a99d900584ba29bee438cc4ef72360d0ae7527 [file] [log] [blame]
################################################################################
# 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 typing import Dict, List, Set
from pypaimon.common.predicate import Predicate
def extract_predicate_to_list(result: list, input_predicate: 'Predicate', keys: List[str]):
if not input_predicate or not keys:
return
if input_predicate.method == 'and':
for sub_predicate in input_predicate.literals:
extract_predicate_to_list(result, sub_predicate, keys)
return
elif input_predicate.method == 'or':
# condition: involved keys all belong to primary keys
involved_fields = _get_all_fields(input_predicate)
if involved_fields and involved_fields.issubset(keys):
result.append(input_predicate)
return
if input_predicate.field in keys:
result.append(input_predicate)
def _get_all_fields(predicate: 'Predicate') -> Set[str]:
if predicate.field is not None:
return {predicate.field}
involved_fields = set()
if predicate.literals:
for sub_predicate in predicate.literals:
involved_fields.update(_get_all_fields(sub_predicate))
return involved_fields
def extract_predicate_to_dict(result: Dict, input_predicate: 'Predicate', keys: List[str]):
if not input_predicate or not keys:
return
if input_predicate.method == 'and':
for sub_predicate in input_predicate.literals:
extract_predicate_to_dict(result, sub_predicate, keys)
return
elif input_predicate.method == 'or':
# ensure no recursive and/or
if not input_predicate.literals or any(p.field is None for p in input_predicate.literals):
return
# condition: only one key for 'or', and the key belongs to keys
involved_fields = {p.field for p in input_predicate.literals}
field = involved_fields.pop() if len(involved_fields) == 1 else None
if field is not None and field in keys:
result[field].append(input_predicate)
return
if input_predicate.field in keys:
result[input_predicate.field].append(input_predicate)