public RowExpression extract(PlanNode node)
    {
        return node.accept(new Visitor(domainTranslator, functionAndTypeManager), null);
    }
@Test
    public void testLeftJoinWithFalseInner()
    {
        List<EquiJoinClause> criteria = ImmutableList.of(new EquiJoinClause(AV, DV));

        Map<VariableReferenceExpression, ColumnHandle> leftAssignments = Maps.filterKeys(scanAssignments, Predicates.in(ImmutableList.of(AV, BV, CV)));
        TableScanNode leftScan = tableScanNode(leftAssignments);

        Map<VariableReferenceExpression, ColumnHandle> rightAssignments = Maps.filterKeys(scanAssignments, Predicates.in(ImmutableList.of(DV, EV, FV)));
        TableScanNode rightScan = tableScanNode(rightAssignments);

        FilterNode left = filter(leftScan,
                and(
                        lessThan(BV, AV),
                        lessThan(CV, bigintLiteral(10)),
                        equals(GV, bigintLiteral(10))));
        FilterNode right = filter(rightScan, FALSE_CONSTANT);
        PlanNode node = new JoinNode(
                Optional.empty(),
                newId(),
                JoinType.LEFT,
                left,
                right,
                criteria,
                ImmutableList.<VariableReferenceExpression>builder()
                        .addAll(left.getOutputVariables())
                        .addAll(right.getOutputVariables())
                        .build(),
                Optional.empty(),
                Optional.empty(),
                Optional.empty(),
                Optional.empty(),
                ImmutableMap.of());

        RowExpression effectivePredicate = effectivePredicateExtractor.extract(node);

        // False literal on the right side should be ignored
        assertEquals(normalizeConjuncts(effectivePredicate),
                normalizeConjuncts(lessThan(BV, AV),
                        lessThan(CV, bigintLiteral(10)),
                        or(equals(AV, DV), isNull(DV))));
    }