@VisibleForTesting
    Set<VariableReferenceExpression> getExistingNotNullVariables(Optional<RowExpression> joinFilter)
    {
        if (!joinFilter.isPresent()) {
            return ImmutableSet.of();
        }

        ImmutableSet.Builder<VariableReferenceExpression> builder = ImmutableSet.builder();

        DefaultRowExpressionTraversalVisitor<ImmutableSet.Builder<VariableReferenceExpression>> isNotNullExtractingVisitor =
                new DefaultRowExpressionTraversalVisitor<ImmutableSet.Builder<VariableReferenceExpression>>()
                {
                    @Override
                    public Void visitCall(CallExpression call, ImmutableSet.Builder<VariableReferenceExpression> context)
                    {
                        // Match a 'not(IS_NULL(VariableReferenceExpression))' call *exactly*
                        if (functionResolution.isNotFunction(call.getFunctionHandle()) &&
                                call.getArguments().size() == 1 &&
                                call.getArguments().get(0) instanceof SpecialFormExpression &&
                                ((SpecialFormExpression) call.getArguments().get(0)).getForm() == IS_NULL &&
                                ((SpecialFormExpression) call.getArguments().get(0)).getArguments().size() == 1 &&
                                ((SpecialFormExpression) call.getArguments().get(0)).getArguments().get(0) instanceof VariableReferenceExpression) {
                            context.add((VariableReferenceExpression) ((SpecialFormExpression) call.getArguments().get(0)).getArguments().get(0));
                        }
                        return null;
                    }

                    @Override
                    public Void visitIntermediateFormExpression(IntermediateFormExpression expression, ImmutableSet.Builder<VariableReferenceExpression> context)
                    {
                        return null;
                    }

                    @Override
                    public Void visitSpecialForm(SpecialFormExpression specialForm, ImmutableSet.Builder<VariableReferenceExpression> context)
                    {
                        if (specialForm.getForm() == AND) {
                            return super.visitSpecialForm(specialForm, context);
                        }
                        return null;
                    }
                };

        joinFilter.get().accept(isNotNullExtractingVisitor, builder);
        return builder.build();
    }
@Test(dataProvider = "getExistingNotNullVarsTestCases")
    public void testGetExistingNotNullVars(String filterSql, String[] expectedNotNullVars)
    {
        Set<VariableReferenceExpression> actual = new AddNotNullFiltersToJoinNode(functionAndTypeManager).getExistingNotNullVariables(
                Optional.of(rowExpressionTranslator.translate(filterSql, testVariableTypeMap)));

        assertEquals(actual, buildVariableReferencesList(expectedNotNullVars));
    }