presto-main/src/main/java/io/prestosql/sql/planner/iterative/rule/RemoveRedundantTableScanPredicate.java/RemoveRedundantTableScanPredicate/removeRedundantTableScanPredicate
class RemoveRedundantTableScanPredicate:    private PlanNode removeRedundantTableScanPredicate(
            TableScanNode node,
            Expression predicate,
            Session session,
            TypeProvider types,
            PlanNodeIdAllocator idAllocator)
    {
        Expression deterministicPredicate = filterDeterministicConjuncts(metadata, predicate);
        Expression nonDeterministicPredicate = filterNonDeterministicConjuncts(metadata, predicate);

        DomainTranslator.ExtractionResult decomposedPredicate = DomainTranslator.fromPredicate(
                metadata,
                session,
                deterministicPredicate,
                types);

        TupleDomain<ColumnHandle> predicateDomain = decomposedPredicate.getTupleDomain()
                .transform(node.getAssignments()::get);

        TupleDomain<ColumnHandle> unenforcedDomain;
        if (predicateDomain.getDomains().isPresent()) {
            Map<ColumnHandle, Domain> predicateColumnDomains = predicateDomain.getDomains().get();

            // table scans with none domain should be converted to ValuesNode
            checkState(node.getEnforcedConstraint().getDomains().isPresent());
            Map<ColumnHandle, Domain> enforcedColumnDomains = node.getEnforcedConstraint().getDomains().get();

            ImmutableMap.Builder<ColumnHandle, Domain> unenforcedColumnDomains = ImmutableMap.builder();
            for (Map.Entry<ColumnHandle, Domain> entry : predicateColumnDomains.entrySet()) {
                ColumnHandle columnHandle = entry.getKey();
                Domain predicateColumnDomain = entry.getValue();
                Domain enforcedColumnDomain = enforcedColumnDomains.getOrDefault(columnHandle, Domain.all(predicateColumnDomain.getType()));
                predicateColumnDomain = predicateColumnDomain.intersect(enforcedColumnDomain);
                if (!predicateColumnDomain.contains(enforcedColumnDomain)) {
                    unenforcedColumnDomains.put(columnHandle, predicateColumnDomain);
                }
            }

            unenforcedDomain = TupleDomain.withColumnDomains(unenforcedColumnDomains.build());
        }
        else {
            // TODO: DomainTranslator.fromPredicate can infer that the expression is "false" in some cases (TupleDomain.none()).
            // This should move to another rule that simplifies the filter using that logic and then rely on RemoveTrivialFilters
            // to turn the subtree into a Values node
            return new ValuesNode(node.getId(), node.getOutputSymbols(), ImmutableList.of());
        }

        Map<ColumnHandle, Symbol> assignments = ImmutableBiMap.copyOf(node.getAssignments()).inverse();
        Expression resultingPredicate = createResultingPredicate(
                metadata,
                domainTranslator.toPredicate(unenforcedDomain.transform(assignments::get)),
                nonDeterministicPredicate,
                decomposedPredicate.getRemainingExpression());

        if (!TRUE_LITERAL.equals(resultingPredicate)) {
            return new FilterNode(idAllocator.getNextId(), node, resultingPredicate);
        }

        return node;
    }