/*
 * 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.druid.segment.join;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import nl.jqno.equalsverifier.EqualsVerifier;
import org.apache.druid.common.config.NullHandling;
import org.apache.druid.java.util.common.IAE;
import org.apache.druid.java.util.common.Intervals;
import org.apache.druid.java.util.common.StringUtils;
import org.apache.druid.java.util.common.granularity.Granularities;
import org.apache.druid.math.expr.ExprMacroTable;
import org.apache.druid.query.QueryContexts;
import org.apache.druid.query.expression.TestExprMacroTable;
import org.apache.druid.query.filter.BoundDimFilter;
import org.apache.druid.query.filter.ExpressionDimFilter;
import org.apache.druid.query.filter.Filter;
import org.apache.druid.query.filter.InDimFilter;
import org.apache.druid.segment.VirtualColumn;
import org.apache.druid.segment.VirtualColumns;
import org.apache.druid.segment.column.ValueType;
import org.apache.druid.segment.filter.AndFilter;
import org.apache.druid.segment.filter.BoundFilter;
import org.apache.druid.segment.filter.FalseFilter;
import org.apache.druid.segment.filter.Filters;
import org.apache.druid.segment.filter.OrFilter;
import org.apache.druid.segment.filter.SelectorFilter;
import org.apache.druid.segment.join.filter.JoinFilterAnalyzer;
import org.apache.druid.segment.join.filter.JoinFilterPreAnalysis;
import org.apache.druid.segment.join.filter.JoinFilterPreAnalysisKey;
import org.apache.druid.segment.join.filter.JoinFilterSplit;
import org.apache.druid.segment.join.filter.JoinableClauses;
import org.apache.druid.segment.join.filter.rewrite.JoinFilterRewriteConfig;
import org.apache.druid.segment.join.lookup.LookupJoinable;
import org.apache.druid.segment.join.table.IndexedTableJoinable;
import org.apache.druid.segment.virtual.ExpressionVirtualColumn;
import org.junit.Assert;
import org.junit.Test;

import java.util.Arrays;
import java.util.List;
import java.util.Set;

public class JoinFilterAnalyzerTest extends BaseHashJoinSegmentStorageAdapterTest
{
  @Test
  public void test_filterPushDown_factToRegionToCountryLeftFilterOnChannel()
  {
    Filter originalFilter = new SelectorFilter("channel", "#en.wikipedia");
    List<JoinableClause> joinableClauses = ImmutableList.of(
        factToRegion(JoinType.LEFT),
        regionToCountry(JoinType.LEFT)
    );

    JoinFilterPreAnalysis joinFilterPreAnalysis = makeDefaultConfigPreAnalysis(
        originalFilter,
        joinableClauses,
        VirtualColumns.EMPTY
    );

    HashJoinSegmentStorageAdapter adapter = new HashJoinSegmentStorageAdapter(
        factSegment.asStorageAdapter(),
        joinableClauses,
        joinFilterPreAnalysis
    );

    JoinTestHelper.verifyCursors(
        adapter.makeCursors(
            originalFilter,
            Intervals.ETERNITY,
            VirtualColumns.EMPTY,
            Granularities.ALL,
            false,
            null
        ),
        ImmutableList.of(
            "page",
            FACT_TO_REGION_PREFIX + "regionName",
            REGION_TO_COUNTRY_PREFIX + "countryName"
        ),
        ImmutableList.of(
            new Object[]{"Talk:Oswald Tilghman", null, null},
            new Object[]{"Peremptory norm", "New South Wales", "Australia"},
            new Object[]{"President of India", "California", "United States"},
            new Object[]{"Glasgow", "Kingston upon Hull", "United Kingdom"},
            new Object[]{"Otjiwarongo Airport", "California", "United States"},
            new Object[]{"Sarah Michelle Gellar", "Ontario", "Canada"},
            new Object[]{"DirecTV", "North Carolina", "United States"},
            new Object[]{"Carlo Curti", "California", "United States"},
            new Object[]{"Giusy Ferreri discography", "Provincia di Varese", "Italy"},
            new Object[]{"Roma-Bangkok", "Provincia di Varese", "Italy"},
            new Object[]{"Old Anatolian Turkish", "Virginia", "United States"},
            new Object[]{"Cream Soda", "Ainigriv", "States United"},
            new Object[]{"Orange Soda", null, null},
            new Object[]{"History of Fourems", "Fourems Province", "Fourems"}
        )
    );

    JoinFilterSplit expectedFilterSplit = new JoinFilterSplit(
        new SelectorFilter("channel", "#en.wikipedia"),
        null,
        ImmutableSet.of()
    );
    JoinFilterSplit actualFilterSplit = JoinFilterAnalyzer.splitFilter(joinFilterPreAnalysis);
    Assert.assertEquals(expectedFilterSplit, actualFilterSplit);
  }

  @Test
  public void test_filterPushDown_factToRegionExprToCountryLeftFilterOnCountryName()
  {

    Filter originalFilter = new SelectorFilter("rtc.countryName", "United States");
    JoinableClause regionExprToCountry = new JoinableClause(
        REGION_TO_COUNTRY_PREFIX,
        new IndexedTableJoinable(countriesTable),
        JoinType.LEFT,
        JoinConditionAnalysis.forExpression(
            StringUtils.format(
                "reverse(\"%scountryIsoCode\") == \"%scountryIsoCode\"",
                FACT_TO_REGION_PREFIX,
                REGION_TO_COUNTRY_PREFIX
            ),
            REGION_TO_COUNTRY_PREFIX,
            ExprMacroTable.nil()
        )
    );
    List<JoinableClause> joinableClauses = ImmutableList.of(
        factToRegion(JoinType.LEFT),
        regionExprToCountry
    );

    JoinFilterPreAnalysis joinFilterPreAnalysis = makeDefaultConfigPreAnalysis(
        originalFilter,
        joinableClauses,
        VirtualColumns.EMPTY
    );

    HashJoinSegmentStorageAdapter adapter = new HashJoinSegmentStorageAdapter(
        factSegment.asStorageAdapter(),
        joinableClauses,
        joinFilterPreAnalysis
    );

    JoinTestHelper.verifyCursors(
        adapter.makeCursors(
            originalFilter,
            Intervals.ETERNITY,
            VirtualColumns.EMPTY,
            Granularities.ALL,
            false,
            null
        ),
        ImmutableList.of(
            "page",
            FACT_TO_REGION_PREFIX + "regionName",
            REGION_TO_COUNTRY_PREFIX + "countryName"
        ),
        ImmutableList.of(
            new Object[]{"Cream Soda", "Ainigriv", "United States"}
        )
    );

    JoinFilterSplit expectedFilterSplit = new JoinFilterSplit(
        null,
        new SelectorFilter("rtc.countryName", "United States"),
        ImmutableSet.of()
    );
    JoinFilterSplit actualFilterSplit = JoinFilterAnalyzer.splitFilter(joinFilterPreAnalysis);
    Assert.assertEquals(expectedFilterSplit, actualFilterSplit);
  }

  @Test
  public void test_filterPushDown_factToRegionToCountryLeftFilterOnChannelAndCountryName()
  {
    Filter originalFilter = new AndFilter(
        ImmutableList.of(
            new SelectorFilter("channel", "#en.wikipedia"),
            new SelectorFilter("rtc.countryName", "United States")
        )
    );

    List<JoinableClause> joinableClauses = ImmutableList.of(
        factToRegion(JoinType.LEFT),
        regionToCountry(JoinType.LEFT)
    );


    JoinFilterPreAnalysis joinFilterPreAnalysis = makeDefaultConfigPreAnalysis(
        originalFilter,
        joinableClauses,
        VirtualColumns.EMPTY
    );

    HashJoinSegmentStorageAdapter adapter = new HashJoinSegmentStorageAdapter(
        factSegment.asStorageAdapter(),
        joinableClauses,
        joinFilterPreAnalysis
    );

    JoinTestHelper.verifyCursors(
        adapter.makeCursors(
            originalFilter,
            Intervals.ETERNITY,
            VirtualColumns.EMPTY,
            Granularities.ALL,
            false,
            null
        ),
        ImmutableList.of(
            "page",
            FACT_TO_REGION_PREFIX + "regionName",
            REGION_TO_COUNTRY_PREFIX + "countryName"
        ),
        ImmutableList.of(
            new Object[]{"President of India", "California", "United States"},
            new Object[]{"Otjiwarongo Airport", "California", "United States"},
            new Object[]{"DirecTV", "North Carolina", "United States"},
            new Object[]{"Carlo Curti", "California", "United States"},
            new Object[]{"Old Anatolian Turkish", "Virginia", "United States"}
        )
    );

    JoinFilterSplit expectedFilterSplit = new JoinFilterSplit(
        new AndFilter(
            ImmutableList.of(
                new SelectorFilter("channel", "#en.wikipedia"),
                new InDimFilter("countryIsoCode", ImmutableSet.of("US"), null, null).toFilter()
            )
        ),
        new SelectorFilter("rtc.countryName", "United States"),
        ImmutableSet.of()
    );

    JoinFilterSplit actualFilterSplit = JoinFilterAnalyzer.splitFilter(joinFilterPreAnalysis);
    Assert.assertEquals(expectedFilterSplit, actualFilterSplit);
  }

  @Test
  public void test_filterPushDown_factToRegionToCountryLeftFilterOnNullColumns()
  {
    Filter originalFilter = new AndFilter(
        ImmutableList.of(
            new SelectorFilter("countryIsoCode", null),
            new SelectorFilter("countryNumber", null),
            new SelectorFilter("rtc.countryName", null),
            new SelectorFilter("r1.regionName", null)
        )
    );

    List<JoinableClause> joinableClauses = ImmutableList.of(
        factToRegion(JoinType.LEFT),
        regionToCountry(JoinType.LEFT)
    );

    JoinFilterPreAnalysis joinFilterPreAnalysis = makeDefaultConfigPreAnalysis(
        originalFilter,
        joinableClauses,
        VirtualColumns.EMPTY
    );

    HashJoinSegmentStorageAdapter adapter = new HashJoinSegmentStorageAdapter(
        factSegment.asStorageAdapter(),
        joinableClauses,
        joinFilterPreAnalysis
    );

    JoinTestHelper.verifyCursors(
        adapter.makeCursors(
            originalFilter,
            Intervals.ETERNITY,
            VirtualColumns.EMPTY,
            Granularities.ALL,
            false,
            null
        ),
        ImmutableList.of(
            "page",
            FACT_TO_REGION_PREFIX + "regionName",
            REGION_TO_COUNTRY_PREFIX + "countryName"
        ),
        NullHandling.sqlCompatible() ?
        ImmutableList.of(
            new Object[]{"Talk:Oswald Tilghman", null, null},
            new Object[]{"Rallicula", null, null},
            new Object[]{"Apamea abruzzorum", null, null},
            new Object[]{"Atractus flammigerus", null, null},
            new Object[]{"Agama mossambica", null, null}
        ) :
        ImmutableList.of() // when not running in SQL compatible mode, countryNumber does not have nulls
    );

    JoinFilterSplit expectedFilterSplit = new JoinFilterSplit(
        null,
        new AndFilter(
            ImmutableList.of(
                new SelectorFilter("countryIsoCode", null),
                new SelectorFilter("countryNumber", null),
                new SelectorFilter("rtc.countryName", null),
                new SelectorFilter("r1.regionName", null)
            )
        ),
        ImmutableSet.of()
    );

    JoinFilterSplit actualFilterSplit = JoinFilterAnalyzer.splitFilter(joinFilterPreAnalysis);
    Assert.assertEquals(expectedFilterSplit, actualFilterSplit);
  }

  @Test
  public void test_filterPushDown_factToRegionToCountryLeftFilterOnInvalidColumns()
  {
    List<JoinableClause> joinableClauses = ImmutableList.of(
        factToRegion(JoinType.LEFT),
        regionToCountry(JoinType.LEFT)
    );

    Filter originalFilter = new AndFilter(
        ImmutableList.of(
            new SelectorFilter("baseTableInvalidColumn", "abcd"),
            new SelectorFilter("baseTableInvalidColumn2", null),
            new SelectorFilter("rtc.invalidColumn", "abcd"),
            new SelectorFilter("r1.invalidColumn", "abcd")
        )
    );

    JoinFilterPreAnalysis joinFilterPreAnalysis = makeDefaultConfigPreAnalysis(
        originalFilter,
        joinableClauses,
        VirtualColumns.EMPTY
    );

    HashJoinSegmentStorageAdapter adapter = new HashJoinSegmentStorageAdapter(
        factSegment.asStorageAdapter(),
        joinableClauses,
        joinFilterPreAnalysis
    );

    JoinTestHelper.verifyCursors(
        adapter.makeCursors(
            originalFilter,
            Intervals.ETERNITY,
            VirtualColumns.EMPTY,
            Granularities.ALL,
            false,
            null
        ),
        ImmutableList.of(
            "page",
            FACT_TO_REGION_PREFIX + "regionName",
            REGION_TO_COUNTRY_PREFIX + "countryName"
        ),
        ImmutableList.of()
    );

    JoinFilterSplit expectedFilterSplit = new JoinFilterSplit(
        new SelectorFilter("baseTableInvalidColumn", "abcd"),
        new AndFilter(
            ImmutableList.of(
                new SelectorFilter("baseTableInvalidColumn2", null),
                new SelectorFilter("rtc.invalidColumn", "abcd"),
                new SelectorFilter("r1.invalidColumn", "abcd")
            )
        ),
        ImmutableSet.of()
    );

    JoinFilterSplit actualFilterSplit = JoinFilterAnalyzer.splitFilter(joinFilterPreAnalysis);
    Assert.assertEquals(expectedFilterSplit, actualFilterSplit);
  }

  @Test
  public void test_filterPushDown_factToRegionToCountryLeftFilterOnChannelVirtualColumn()
  {
    List<JoinableClause> joinableClauses = ImmutableList.of(
        factToRegion(JoinType.LEFT),
        regionToCountry(JoinType.LEFT)
    );

    Filter originalFilter = new AndFilter(
        ImmutableList.of(
            new SelectorFilter("v1", "virtual-column-#en.wikipedia")
        )
    );

    VirtualColumns virtualColumns = VirtualColumns.create(
        ImmutableList.of(
            new ExpressionVirtualColumn(
                "v1",
                "concat('virtual-column-', \"channel\")",
                ValueType.STRING,
                TestExprMacroTable.INSTANCE
            )
        )
    );

    JoinFilterPreAnalysis joinFilterPreAnalysis = makeDefaultConfigPreAnalysis(
        originalFilter,
        joinableClauses,
        virtualColumns
    );

    HashJoinSegmentStorageAdapter adapter = new HashJoinSegmentStorageAdapter(
        factSegment.asStorageAdapter(),
        joinableClauses,
        joinFilterPreAnalysis
    );

    JoinTestHelper.verifyCursors(
        adapter.makeCursors(
            originalFilter,
            Intervals.ETERNITY,
            virtualColumns,
            Granularities.ALL,
            false,
            null
        ),
        ImmutableList.of(
            "page",
            FACT_TO_REGION_PREFIX + "regionName",
            REGION_TO_COUNTRY_PREFIX + "countryName"
        ),
        ImmutableList.of(
            new Object[]{"Talk:Oswald Tilghman", null, null},
            new Object[]{"Peremptory norm", "New South Wales", "Australia"},
            new Object[]{"President of India", "California", "United States"},
            new Object[]{"Glasgow", "Kingston upon Hull", "United Kingdom"},
            new Object[]{"Otjiwarongo Airport", "California", "United States"},
            new Object[]{"Sarah Michelle Gellar", "Ontario", "Canada"},
            new Object[]{"DirecTV", "North Carolina", "United States"},
            new Object[]{"Carlo Curti", "California", "United States"},
            new Object[]{"Giusy Ferreri discography", "Provincia di Varese", "Italy"},
            new Object[]{"Roma-Bangkok", "Provincia di Varese", "Italy"},
            new Object[]{"Old Anatolian Turkish", "Virginia", "United States"},
            new Object[]{"Cream Soda", "Ainigriv", "States United"},
            new Object[]{"Orange Soda", null, null},
            new Object[]{"History of Fourems", "Fourems Province", "Fourems"}
        )
    );

    JoinFilterSplit expectedFilterSplit = new JoinFilterSplit(
        new SelectorFilter("v1", "virtual-column-#en.wikipedia"),
        null,
        ImmutableSet.of()
    );

    JoinFilterSplit actualFilterSplit = JoinFilterAnalyzer.splitFilter(joinFilterPreAnalysis);
    Assert.assertEquals(expectedFilterSplit, actualFilterSplit);
  }

  @Test
  public void test_filterPushDown_factToRegionFilterOnRHSRegionNameExprVirtualColumn()
  {
    // If our query had a filter that uses expressions, such as upper(r1.regionName) == 'VIRGINIA', this plans into
    // a selector filter on an ExpressionVirtualColumn
    Filter originalFilter = new SelectorFilter("v0", "VIRGINIA");
    VirtualColumns virtualColumns = VirtualColumns.create(
        ImmutableList.of(
            new ExpressionVirtualColumn(
                "v0",
                "upper(\"r1.regionName\")",
                ValueType.STRING,
                TestExprMacroTable.INSTANCE
            )
        )
    );

    JoinableClauses joinableClauses = JoinableClauses.fromList(ImmutableList.of(
        factToRegion(JoinType.LEFT)
    ));

    JoinFilterPreAnalysis joinFilterPreAnalysis = makeDefaultConfigPreAnalysis(
        originalFilter,
        joinableClauses.getJoinableClauses(),
        virtualColumns
    );
    HashJoinSegmentStorageAdapter adapter = new HashJoinSegmentStorageAdapter(
        factSegment.asStorageAdapter(),
        joinableClauses.getJoinableClauses(),
        joinFilterPreAnalysis
    );

    JoinTestHelper.verifyCursors(
        adapter.makeCursors(
            originalFilter,
            Intervals.ETERNITY,
            virtualColumns,
            Granularities.ALL,
            false,
            null
        ),
        ImmutableList.of(
            "page",
            "v0"
        ),
        ImmutableList.of(
            new Object[]{"Old Anatolian Turkish", "VIRGINIA"}
        )
    );

    JoinFilterSplit expectedFilterSplit = new JoinFilterSplit(
        null,
        new SelectorFilter("v0", "VIRGINIA"),
        ImmutableSet.of()
    );

    JoinFilterSplit actualFilterSplit = JoinFilterAnalyzer.splitFilter(joinFilterPreAnalysis);
    Assert.assertEquals(expectedFilterSplit, actualFilterSplit);
  }

  @Test
  public void test_filterPushDown_factToRegionToCountryLeftFilterNormalizedAlreadyPushDownVariety()
  {
    Filter originalFilter = new AndFilter(
        ImmutableList.of(
            new SelectorFilter("channel", "#fr.wikipedia"),
            new BoundFilter(new BoundDimFilter(
                "page",
                "Les Argonautes",
                "Les Argonautes",
                false,
                false,
                null,
                null,
                null
            )),
            new SelectorFilter("rtc.countryName", "Canada"),
            new BoundFilter(new BoundDimFilter(
                "rtc.countryName",
                "Canada",
                "Canada",
                false,
                false,
                null,
                null,
                null
            )),
            new OrFilter(
                ImmutableList.of(
                    new SelectorFilter("namespace", "main"),
                    new BoundFilter(new BoundDimFilter(
                        "user",
                        "24.122.168.111",
                        "24.122.168.111",
                        false,
                        false,
                        null,
                        null,
                        null
                    ))
                )
            ),
            new OrFilter(
                ImmutableList.of(
                    new SelectorFilter("namespace", "main"),
                    new BoundFilter(new BoundDimFilter(
                        "r1.regionName",
                        "Quebec",
                        "Quebec",
                        false,
                        false,
                        null,
                        null,
                        null
                    ))
                )
            )
        )
    );

    List<JoinableClause> joinableClauses = ImmutableList.of(
        factToRegion(JoinType.LEFT),
        regionToCountry(JoinType.LEFT)
    );

    JoinFilterPreAnalysis joinFilterPreAnalysis = makeDefaultConfigPreAnalysis(
        originalFilter,
        joinableClauses,
        VirtualColumns.EMPTY
    );
    HashJoinSegmentStorageAdapter adapter = new HashJoinSegmentStorageAdapter(
        factSegment.asStorageAdapter(),
        joinableClauses,
        joinFilterPreAnalysis
    );

    JoinTestHelper.verifyCursors(
        adapter.makeCursors(
            originalFilter,
            Intervals.ETERNITY,
            VirtualColumns.EMPTY,
            Granularities.ALL,
            false,
            null
        ),
        ImmutableList.of(
            "page",
            FACT_TO_REGION_PREFIX + "regionName",
            REGION_TO_COUNTRY_PREFIX + "countryName"
        ),
        ImmutableList.of(
            new Object[]{"Les Argonautes", "Quebec", "Canada"}
        )
    );

    JoinFilterSplit expectedFilterSplit = new JoinFilterSplit(
        new AndFilter(
            ImmutableList.of(
                new SelectorFilter("channel", "#fr.wikipedia"),
                new BoundFilter(new BoundDimFilter(
                    "page",
                    "Les Argonautes",
                    "Les Argonautes",
                    false,
                    false,
                    null,
                    null,
                    null
                )),
                new OrFilter(
                    ImmutableList.of(
                        new SelectorFilter("namespace", "main"),
                        new BoundFilter(new BoundDimFilter(
                            "user",
                            "24.122.168.111",
                            "24.122.168.111",
                            false,
                            false,
                            null,
                            null,
                            null
                        ))
                    )
                ),
                new InDimFilter("countryIsoCode", ImmutableSet.of("CA"), null, null).toFilter()
            )
        ),
        new AndFilter(
            ImmutableList.of(
                new SelectorFilter("rtc.countryName", "Canada"),
                new BoundFilter(new BoundDimFilter(
                    "rtc.countryName",
                    "Canada",
                    "Canada",
                    false,
                    false,
                    null,
                    null,
                    null
                )),
                new OrFilter(
                    ImmutableList.of(
                        new SelectorFilter("namespace", "main"),
                        new BoundFilter(new BoundDimFilter(
                            "r1.regionName",
                            "Quebec",
                            "Quebec",
                            false,
                            false,
                            null,
                            null,
                            null
                        ))
                    )
                )
            )
        ),
        ImmutableSet.of()
    );

    JoinFilterSplit actualFilterSplit = JoinFilterAnalyzer.splitFilter(joinFilterPreAnalysis);
    Assert.assertEquals(expectedFilterSplit, actualFilterSplit);
  }

  @Test
  public void test_filterPushDown_factExpressionsToRegionToCountryLeftFilterOnChannelAndCountryName()
  {
    JoinableClause factExprToRegon = new JoinableClause(
        FACT_TO_REGION_PREFIX,
        new IndexedTableJoinable(regionsTable),
        JoinType.LEFT,
        JoinConditionAnalysis.forExpression(
            StringUtils.format(
                "\"%sregionIsoCode\" == reverse(regionIsoCode) && \"%scountryIsoCode\" == reverse(countryIsoCode)",
                FACT_TO_REGION_PREFIX,
                FACT_TO_REGION_PREFIX
            ),
            FACT_TO_REGION_PREFIX,
            ExprMacroTable.nil()
        )
    );
    List<JoinableClause> joinableClauses = ImmutableList.of(
        factExprToRegon,
        regionToCountry(JoinType.LEFT)
    );
    Filter originalFilter = new AndFilter(
        ImmutableList.of(
            new SelectorFilter("channel", "#en.wikipedia"),
            new SelectorFilter("rtc.countryName", "States United")
        )
    );

    JoinFilterPreAnalysis joinFilterPreAnalysis = makeDefaultConfigPreAnalysis(
        originalFilter,
        joinableClauses,
        VirtualColumns.EMPTY
    );
    HashJoinSegmentStorageAdapter adapter = new HashJoinSegmentStorageAdapter(
        factSegment.asStorageAdapter(),
        joinableClauses,
        joinFilterPreAnalysis
    );

    JoinTestHelper.verifyCursors(
        adapter.makeCursors(
            originalFilter,
            Intervals.ETERNITY,
            VirtualColumns.EMPTY,
            Granularities.ALL,
            false,
            null
        ),
        ImmutableList.of(
            "page",
            FACT_TO_REGION_PREFIX + "regionName",
            REGION_TO_COUNTRY_PREFIX + "countryName"
        ),
        ImmutableList.of(
            new Object[]{"Old Anatolian Turkish", "Ainigriv", "States United"}
        )
    );

    JoinFilterSplit expectedFilterSplit = new JoinFilterSplit(
        new AndFilter(
            ImmutableList.of(
                new SelectorFilter("channel", "#en.wikipedia"),
                new InDimFilter("JOIN-FILTER-PUSHDOWN-VIRTUAL-COLUMN-0", ImmutableSet.of("SU"), null, null).toFilter()
            )
        ),
        new SelectorFilter("rtc.countryName", "States United"),
        ImmutableSet.of()
    );

    JoinFilterSplit actualFilterSplit = JoinFilterAnalyzer.splitFilter(joinFilterPreAnalysis);

    ExpressionVirtualColumn expectedVirtualColumn = new ExpressionVirtualColumn(
        "JOIN-FILTER-PUSHDOWN-VIRTUAL-COLUMN-0",
        "reverse(countryIsoCode)",
        ValueType.STRING,
        ExprMacroTable.nil()
    );
    Assert.assertEquals(
        expectedFilterSplit.getBaseTableFilter(),
        actualFilterSplit.getBaseTableFilter()
    );
    Assert.assertEquals(
        expectedFilterSplit.getJoinTableFilter(),
        actualFilterSplit.getJoinTableFilter()
    );
    ExpressionVirtualColumn actualVirtualColumn = (ExpressionVirtualColumn) actualFilterSplit.getPushDownVirtualColumns()
                                                                                             .iterator().next();
    compareExpressionVirtualColumns(expectedVirtualColumn, actualVirtualColumn);
  }

  @Test
  public void test_filterPushDown_factToRegionToCountryNotEquiJoinLeftFilterOnChannelAndCountryName()
  {
    JoinableClause factExprToRegon = new JoinableClause(
        FACT_TO_REGION_PREFIX,
        new IndexedTableJoinable(regionsTable),
        JoinType.LEFT,
        JoinConditionAnalysis.forExpression(
            StringUtils.format(
                "\"%sregionIsoCode\" == regionIsoCode && reverse(\"%scountryIsoCode\") == countryIsoCode",
                FACT_TO_REGION_PREFIX,
                FACT_TO_REGION_PREFIX
            ),
            FACT_TO_REGION_PREFIX,
            ExprMacroTable.nil()
        )
    );
    List<JoinableClause> joinableClauses = ImmutableList.of(
        factExprToRegon,
        regionToCountry(JoinType.LEFT)
    );

    Filter originalFilter = new AndFilter(
        ImmutableList.of(
            new SelectorFilter("channel", "#en.wikipedia"),
            new SelectorFilter("rtc.countryName", "States United")
        )
    );

    JoinFilterPreAnalysis joinFilterPreAnalysis = makeDefaultConfigPreAnalysis(
        originalFilter,
        joinableClauses,
        VirtualColumns.EMPTY
    );
    expectedException.expect(IllegalArgumentException.class);
    expectedException.expectMessage(
        "Cannot build hash-join matcher on non-equi-join condition: \"r1.regionIsoCode\" == regionIsoCode && reverse(\"r1.countryIsoCode\") == countryIsoCode");

    HashJoinSegmentStorageAdapter adapter = new HashJoinSegmentStorageAdapter(
        factSegment.asStorageAdapter(),
        joinableClauses,
        joinFilterPreAnalysis
    );
    JoinTestHelper.verifyCursors(
        adapter.makeCursors(
            originalFilter,
            Intervals.ETERNITY,
            VirtualColumns.EMPTY,
            Granularities.ALL,
            false,
            null
        ),
        ImmutableList.of(
            "page",
            FACT_TO_REGION_PREFIX + "regionName",
            REGION_TO_COUNTRY_PREFIX + "countryName"
        ),
        ImmutableList.of(
            new Object[]{"Old Anatolian Turkish", "Ainigriv", "States United"}
        )
    );
  }

  @Test
  public void test_filterPushDown_factToRegionToCountryLeftUnnormalizedFilter()
  {
    List<JoinableClause> joinableClauses = ImmutableList.of(
        factToRegion(JoinType.LEFT),
        regionToCountry(JoinType.LEFT)
    );
    Filter originalFilter = new OrFilter(
        ImmutableList.of(
            new SelectorFilter("channel", "#ko.wikipedia"),
            new AndFilter(
                ImmutableList.of(
                    new SelectorFilter("rtc.countryName", "United States"),
                    new SelectorFilter("r1.regionName", "Virginia")
                )
            )
        )
    );

    JoinFilterPreAnalysis joinFilterPreAnalysis = makeDefaultConfigPreAnalysis(
        originalFilter,
        joinableClauses,
        VirtualColumns.EMPTY
    );
    HashJoinSegmentStorageAdapter adapter = new HashJoinSegmentStorageAdapter(
        factSegment.asStorageAdapter(),
        joinableClauses,
        joinFilterPreAnalysis
    );

    JoinTestHelper.verifyCursors(
        adapter.makeCursors(
            originalFilter,
            Intervals.ETERNITY,
            VirtualColumns.EMPTY,
            Granularities.ALL,
            false,
            null
        ),
        ImmutableList.of(
            "page",
            FACT_TO_REGION_PREFIX + "regionName",
            REGION_TO_COUNTRY_PREFIX + "countryName"
        ),
        ImmutableList.of(
            new Object[]{"유희왕 GX", "Seoul", "Republic of Korea"},
            new Object[]{"Old Anatolian Turkish", "Virginia", "United States"}
        )
    );

    JoinFilterSplit expectedFilterSplit = new JoinFilterSplit(
        new AndFilter(
            ImmutableList.of(
                new OrFilter(
                    ImmutableList.of(
                        new SelectorFilter("channel", "#ko.wikipedia"),
                        new InDimFilter("countryIsoCode", ImmutableSet.of("US"), null, null).toFilter()
                    )
                ),
                new OrFilter(
                    ImmutableList.of(
                        new SelectorFilter("channel", "#ko.wikipedia"),
                        new AndFilter(
                            ImmutableList.of(
                                new InDimFilter("countryIsoCode", ImmutableSet.of("US"), null, null).toFilter(),
                                new InDimFilter("regionIsoCode", ImmutableSet.of("VA"), null, null).toFilter()
                            )
                        )
                    )
                )
            )
        ),
        new AndFilter(
            ImmutableList.of(
                new OrFilter(
                    ImmutableList.of(
                        new SelectorFilter("channel", "#ko.wikipedia"),
                        new SelectorFilter("rtc.countryName", "United States")
                    )
                ),
                new OrFilter(
                    ImmutableList.of(
                        new SelectorFilter("channel", "#ko.wikipedia"),
                        new SelectorFilter("r1.regionName", "Virginia")
                    )
                )
            )
        ),
        ImmutableSet.of()
    );

    JoinFilterSplit actualFilterSplit = JoinFilterAnalyzer.splitFilter(joinFilterPreAnalysis);
    Assert.assertEquals(expectedFilterSplit, actualFilterSplit);
  }

  @Test
  public void test_filterPushDown_factConcatExpressionToCountryLeftFilterOnChannelAndCountryName()
  {
    JoinableClause factExprToCountry = new JoinableClause(
        FACT_TO_COUNTRY_ON_ISO_CODE_PREFIX,
        new IndexedTableJoinable(countriesTable),
        JoinType.LEFT,
        JoinConditionAnalysis.forExpression(
            StringUtils.format(
                "\"%scountryIsoCode\" == concat(countryIsoCode, regionIsoCode)",
                FACT_TO_COUNTRY_ON_ISO_CODE_PREFIX
            ),
            FACT_TO_COUNTRY_ON_ISO_CODE_PREFIX,
            ExprMacroTable.nil()
        )
    );
    List<JoinableClause> joinableClauses = ImmutableList.of(
        factExprToCountry
    );
    Filter filter = new AndFilter(
        ImmutableList.of(
            new SelectorFilter("channel", "#en.wikipedia"),
            new SelectorFilter("c1.countryName", "Usca")
        )
    );

    JoinFilterPreAnalysis joinFilterPreAnalysis = makeDefaultConfigPreAnalysis(
        filter,
        joinableClauses,
        VirtualColumns.EMPTY
    );
    HashJoinSegmentStorageAdapter adapter = new HashJoinSegmentStorageAdapter(
        factSegment.asStorageAdapter(),
        joinableClauses,
        joinFilterPreAnalysis
    );

    JoinTestHelper.verifyCursors(
        adapter.makeCursors(
            filter,
            Intervals.ETERNITY,
            VirtualColumns.EMPTY,
            Granularities.ALL,
            false,
            null
        ),
        ImmutableList.of(
            "page",
            FACT_TO_COUNTRY_ON_ISO_CODE_PREFIX + "countryName"
        ),
        ImmutableList.of(
            new Object[]{"President of India", "Usca"},
            new Object[]{"Otjiwarongo Airport", "Usca"},
            new Object[]{"Carlo Curti", "Usca"}
        )
    );

    ExpressionVirtualColumn expectedVirtualColumn = new ExpressionVirtualColumn(
        "JOIN-FILTER-PUSHDOWN-VIRTUAL-COLUMN-0",
        "concat(countryIsoCode, regionIsoCode)",
        ValueType.STRING,
        ExprMacroTable.nil()
    );
    JoinFilterSplit expectedFilterSplit = new JoinFilterSplit(
        new AndFilter(
            ImmutableList.of(
                new SelectorFilter("channel", "#en.wikipedia"),
                new InDimFilter("JOIN-FILTER-PUSHDOWN-VIRTUAL-COLUMN-0", ImmutableSet.of("USCA"), null, null).toFilter()
            )
        ),
        new SelectorFilter("c1.countryName", "Usca"),
        ImmutableSet.of(
            expectedVirtualColumn
        )
    );

    JoinFilterSplit actualFilterSplit = JoinFilterAnalyzer.splitFilter(joinFilterPreAnalysis);
    Assert.assertEquals(
        expectedFilterSplit.getBaseTableFilter(),
        actualFilterSplit.getBaseTableFilter()
    );
    Assert.assertEquals(
        expectedFilterSplit.getJoinTableFilter(),
        actualFilterSplit.getJoinTableFilter()
    );
    ExpressionVirtualColumn actualVirtualColumn = (ExpressionVirtualColumn) actualFilterSplit.getPushDownVirtualColumns()
                                                                                             .iterator().next();
    compareExpressionVirtualColumns(expectedVirtualColumn, actualVirtualColumn);
  }

  @Test
  public void test_filterPushDown_factConcatExpressionToCountryLeftFilterOnChannelAndCountryNameUsingLookup()
  {
    JoinableClause factExprToCountry = new JoinableClause(
        FACT_TO_COUNTRY_ON_ISO_CODE_PREFIX,
        LookupJoinable.wrap(countryIsoCodeToNameLookup),
        JoinType.LEFT,
        JoinConditionAnalysis.forExpression(
            StringUtils.format(
                "\"%sk\" == concat(countryIsoCode, regionIsoCode)",
                FACT_TO_COUNTRY_ON_ISO_CODE_PREFIX
            ),
            FACT_TO_COUNTRY_ON_ISO_CODE_PREFIX,
            ExprMacroTable.nil()
        )
    );
    List<JoinableClause> joinableClauses = ImmutableList.of(
        factExprToCountry
    );
    Filter filter = new AndFilter(
        ImmutableList.of(
            new SelectorFilter("channel", "#en.wikipedia"),
            new SelectorFilter("c1.v", "Usca")
        )
    );

    JoinFilterPreAnalysis joinFilterPreAnalysis = makeDefaultConfigPreAnalysis(
        filter,
        joinableClauses,
        VirtualColumns.EMPTY
    );
    HashJoinSegmentStorageAdapter adapter = new HashJoinSegmentStorageAdapter(
        factSegment.asStorageAdapter(),
        joinableClauses,
        joinFilterPreAnalysis
    );

    JoinTestHelper.verifyCursors(
        adapter.makeCursors(
            filter,
            Intervals.ETERNITY,
            VirtualColumns.EMPTY,
            Granularities.ALL,
            false,
            null
        ),
        ImmutableList.of(
            "page",
            FACT_TO_COUNTRY_ON_ISO_CODE_PREFIX + "v"
        ),
        ImmutableList.of(
            new Object[]{"President of India", "Usca"},
            new Object[]{"Otjiwarongo Airport", "Usca"},
            new Object[]{"Carlo Curti", "Usca"}
        )
    );

    ExpressionVirtualColumn expectedVirtualColumn = new ExpressionVirtualColumn(
        "JOIN-FILTER-PUSHDOWN-VIRTUAL-COLUMN-0",
        "concat(countryIsoCode, regionIsoCode)",
        ValueType.STRING,
        ExprMacroTable.nil()
    );
    JoinFilterSplit expectedFilterSplit = new JoinFilterSplit(
        new AndFilter(
            ImmutableList.of(
                new SelectorFilter("channel", "#en.wikipedia"),
                new InDimFilter("JOIN-FILTER-PUSHDOWN-VIRTUAL-COLUMN-0", ImmutableSet.of("USCA"), null, null).toFilter()
            )
        ),
        new SelectorFilter("c1.v", "Usca"),
        ImmutableSet.of(
            expectedVirtualColumn
        )
    );

    JoinFilterSplit actualFilterSplit = JoinFilterAnalyzer.splitFilter(joinFilterPreAnalysis);
    Assert.assertEquals(
        expectedFilterSplit.getBaseTableFilter(),
        actualFilterSplit.getBaseTableFilter()
    );
    Assert.assertEquals(
        expectedFilterSplit.getJoinTableFilter(),
        actualFilterSplit.getJoinTableFilter()
    );
    ExpressionVirtualColumn actualVirtualColumn = (ExpressionVirtualColumn) actualFilterSplit.getPushDownVirtualColumns()
                                                                                             .iterator().next();
    compareExpressionVirtualColumns(expectedVirtualColumn, actualVirtualColumn);
  }

  @Test
  public void test_filterPushDown_factToCountryRightWithFilterOnChannelAndJoinable()
  {
    List<JoinableClause> joinableClauses = ImmutableList.of(factToCountryOnIsoCode(JoinType.RIGHT));
    Filter originalFilter = new AndFilter(
        ImmutableList.of(
            new SelectorFilter("channel", "#de.wikipedia"),
            new SelectorFilter(FACT_TO_COUNTRY_ON_ISO_CODE_PREFIX + "countryName", "Germany")
        )
    );
    JoinFilterPreAnalysis joinFilterPreAnalysis = makeDefaultConfigPreAnalysis(
        originalFilter,
        joinableClauses,
        VirtualColumns.EMPTY
    );
    HashJoinSegmentStorageAdapter adapter = new HashJoinSegmentStorageAdapter(
        factSegment.asStorageAdapter(),
        joinableClauses,
        joinFilterPreAnalysis
    );

    JoinTestHelper.verifyCursors(
        adapter.makeCursors(
            originalFilter,
            Intervals.ETERNITY,
            VirtualColumns.EMPTY,
            Granularities.ALL,
            false,
            null
        ),
        ImmutableList.of(
            "page",
            "countryIsoCode",
            "countryNumber",
            FACT_TO_COUNTRY_ON_ISO_CODE_PREFIX + "countryIsoCode",
            FACT_TO_COUNTRY_ON_ISO_CODE_PREFIX + "countryName",
            FACT_TO_COUNTRY_ON_ISO_CODE_PREFIX + "countryNumber"
        ),
        ImmutableList.of(
            new Object[]{"Diskussion:Sebastian Schulz", "DE", 3L, "DE", "Germany", 3L}
        )
    );

    JoinFilterSplit expectedFilterSplit = new JoinFilterSplit(
        new AndFilter(
            ImmutableList.of(
                new SelectorFilter("channel", "#de.wikipedia"),
                new InDimFilter("countryIsoCode", ImmutableSet.of("DE"), null, null).toFilter()
            )
        ),
        new SelectorFilter(FACT_TO_COUNTRY_ON_ISO_CODE_PREFIX + "countryName", "Germany"),
        ImmutableSet.of()
    );

    JoinFilterSplit actualFilterSplit = JoinFilterAnalyzer.splitFilter(joinFilterPreAnalysis);
    Assert.assertEquals(expectedFilterSplit, actualFilterSplit);
  }

  @Test
  public void test_filterPushDown_factToCountryRightWithFilterOnChannelAndJoinableUsingLookup()
  {
    List<JoinableClause> joinableClauses = ImmutableList.of(factToCountryNameUsingIsoCodeLookup(JoinType.RIGHT));
    Filter originalFilter = new AndFilter(
        ImmutableList.of(
            new SelectorFilter("channel", "#de.wikipedia"),
            new SelectorFilter(FACT_TO_COUNTRY_ON_ISO_CODE_PREFIX + "v", "Germany")
        )
    );
    JoinFilterPreAnalysis joinFilterPreAnalysis = makeDefaultConfigPreAnalysis(
        originalFilter,
        joinableClauses,
        VirtualColumns.EMPTY
    );
    HashJoinSegmentStorageAdapter adapter = new HashJoinSegmentStorageAdapter(
        factSegment.asStorageAdapter(),
        joinableClauses,
        joinFilterPreAnalysis
    );

    JoinTestHelper.verifyCursors(
        adapter.makeCursors(
            originalFilter,
            Intervals.ETERNITY,
            VirtualColumns.EMPTY,
            Granularities.ALL,
            false,
            null
        ),
        ImmutableList.of(
            "page",
            "countryIsoCode",
            "countryNumber",
            FACT_TO_COUNTRY_ON_ISO_CODE_PREFIX + "k",
            FACT_TO_COUNTRY_ON_ISO_CODE_PREFIX + "v"
        ),
        ImmutableList.of(
            new Object[]{"Diskussion:Sebastian Schulz", "DE", 3L, "DE", "Germany"}
        )
    );

    JoinFilterSplit expectedFilterSplit = new JoinFilterSplit(
        new AndFilter(
            ImmutableList.of(
                new SelectorFilter("channel", "#de.wikipedia"),
                new InDimFilter("countryIsoCode", ImmutableSet.of("DE"), null, null).toFilter()
            )
        ),
        new SelectorFilter(FACT_TO_COUNTRY_ON_ISO_CODE_PREFIX + "v", "Germany"),
        ImmutableSet.of()
    );

    JoinFilterSplit actualFilterSplit = JoinFilterAnalyzer.splitFilter(joinFilterPreAnalysis);
    Assert.assertEquals(expectedFilterSplit, actualFilterSplit);
  }

  @Test
  public void test_filterPushDown_factToCountryRightWithFilterOnNullColumns()
  {
    List<JoinableClause> joinableClauses = ImmutableList.of(factToCountryOnIsoCode(JoinType.RIGHT));
    Filter originalFilter = new AndFilter(
        ImmutableList.of(
            new SelectorFilter("channel", null),
            new SelectorFilter(FACT_TO_COUNTRY_ON_ISO_CODE_PREFIX + "countryName", null)
        )
    );
    JoinFilterPreAnalysis joinFilterPreAnalysis = makeDefaultConfigPreAnalysis(
        originalFilter,
        joinableClauses,
        VirtualColumns.EMPTY
    );
    HashJoinSegmentStorageAdapter adapter = new HashJoinSegmentStorageAdapter(
        factSegment.asStorageAdapter(),
        joinableClauses,
        joinFilterPreAnalysis
    );

    JoinTestHelper.verifyCursors(
        adapter.makeCursors(
            originalFilter,
            Intervals.ETERNITY,
            VirtualColumns.EMPTY,
            Granularities.ALL,
            false,
            null
        ),
        ImmutableList.of(
            "page",
            "countryIsoCode",
            "countryNumber",
            FACT_TO_COUNTRY_ON_ISO_CODE_PREFIX + "countryIsoCode",
            FACT_TO_COUNTRY_ON_ISO_CODE_PREFIX + "countryName",
            FACT_TO_COUNTRY_ON_ISO_CODE_PREFIX + "countryNumber"
        ),
        ImmutableList.of()
    );

    JoinFilterSplit expectedFilterSplit = new JoinFilterSplit(
        null,
        new AndFilter(
            ImmutableList.of(
                new SelectorFilter("channel", null),
                new SelectorFilter(FACT_TO_COUNTRY_ON_ISO_CODE_PREFIX + "countryName", null)
            )
        ),
        ImmutableSet.of()
    );

    JoinFilterSplit actualFilterSplit = JoinFilterAnalyzer.splitFilter(joinFilterPreAnalysis);
    Assert.assertEquals(expectedFilterSplit, actualFilterSplit);
  }

  @Test
  public void test_filterPushDown_factToCountryRightWithFilterOnValueThatMatchesNothing()
  {
    List<JoinableClause> joinableClauses = ImmutableList.of(factToCountryOnIsoCode(JoinType.RIGHT));
    Filter originalFilter = new AndFilter(
        ImmutableList.of(
            new SelectorFilter("channel", null),
            new SelectorFilter(FACT_TO_COUNTRY_ON_ISO_CODE_PREFIX + "countryName", "NO MATCH")
        )
    );
    JoinFilterPreAnalysis joinFilterPreAnalysis = makeDefaultConfigPreAnalysis(
        originalFilter,
        joinableClauses,
        VirtualColumns.EMPTY
    );
    HashJoinSegmentStorageAdapter adapter = new HashJoinSegmentStorageAdapter(
        factSegment.asStorageAdapter(),
        joinableClauses,
        joinFilterPreAnalysis
    );

    JoinTestHelper.verifyCursors(
        adapter.makeCursors(
            originalFilter,
            Intervals.ETERNITY,
            VirtualColumns.EMPTY,
            Granularities.ALL,
            false,
            null
        ),
        ImmutableList.of(
            "page",
            "countryIsoCode",
            "countryNumber",
            FACT_TO_COUNTRY_ON_ISO_CODE_PREFIX + "countryIsoCode",
            FACT_TO_COUNTRY_ON_ISO_CODE_PREFIX + "countryName",
            FACT_TO_COUNTRY_ON_ISO_CODE_PREFIX + "countryNumber"
        ),
        ImmutableList.of()
    );


    JoinFilterSplit expectedFilterSplit = new JoinFilterSplit(
        FalseFilter.instance(),
        new AndFilter(
            ImmutableList.of(
                new SelectorFilter("channel", null),
                new SelectorFilter(FACT_TO_COUNTRY_ON_ISO_CODE_PREFIX + "countryName", "NO MATCH")
            )
        ),
        ImmutableSet.of()
    );

    JoinFilterSplit actualFilterSplit = JoinFilterAnalyzer.splitFilter(joinFilterPreAnalysis);
    Assert.assertEquals(expectedFilterSplit, actualFilterSplit);
  }

  @Test
  public void test_filterPushDown_factToCountryRightWithFilterOnNullColumnsUsingLookup()
  {
    List<JoinableClause> joinableClauses = ImmutableList.of(factToCountryNameUsingIsoCodeLookup(JoinType.RIGHT));
    Filter originalFilter = new AndFilter(
        ImmutableList.of(
            new SelectorFilter("channel", null),
            new SelectorFilter(FACT_TO_COUNTRY_ON_ISO_CODE_PREFIX + "v", null)
        )
    );
    JoinFilterPreAnalysis joinFilterPreAnalysis = makeDefaultConfigPreAnalysis(
        originalFilter,
        joinableClauses,
        VirtualColumns.EMPTY
    );
    HashJoinSegmentStorageAdapter adapter = new HashJoinSegmentStorageAdapter(
        factSegment.asStorageAdapter(),
        joinableClauses,
        joinFilterPreAnalysis
    );

    JoinTestHelper.verifyCursors(
        adapter.makeCursors(
            originalFilter,
            Intervals.ETERNITY,
            VirtualColumns.EMPTY,
            Granularities.ALL,
            false,
            null
        ),
        ImmutableList.of(
            "page",
            "countryIsoCode",
            "countryNumber",
            FACT_TO_COUNTRY_ON_ISO_CODE_PREFIX + "k",
            FACT_TO_COUNTRY_ON_ISO_CODE_PREFIX + "v"
        ),
        ImmutableList.of()
    );

    JoinFilterSplit expectedFilterSplit = new JoinFilterSplit(
        null,
        new AndFilter(
            ImmutableList.of(
                new SelectorFilter("channel", null),
                new SelectorFilter(FACT_TO_COUNTRY_ON_ISO_CODE_PREFIX + "v", null)
            )
        ),
        ImmutableSet.of()
    );

    JoinFilterSplit actualFilterSplit = JoinFilterAnalyzer.splitFilter(joinFilterPreAnalysis);
    Assert.assertEquals(expectedFilterSplit, actualFilterSplit);
  }

  @Test
  public void test_filterPushDown_factToCountryInnerUsingCountryNumberFilterOnChannelAndCountryName()
  {
    List<JoinableClause> joinableClauses = ImmutableList.of(factToCountryOnNumber(JoinType.INNER));
    Filter originalFilter = new AndFilter(
        ImmutableList.of(
            new SelectorFilter("channel", "#en.wikipedia"),
            new SelectorFilter(FACT_TO_COUNTRY_ON_NUMBER_PREFIX + "countryName", "Australia")
        )
    );
    JoinFilterPreAnalysis joinFilterPreAnalysis = makeDefaultConfigPreAnalysis(
        originalFilter,
        joinableClauses,
        VirtualColumns.EMPTY
    );
    HashJoinSegmentStorageAdapter adapter = new HashJoinSegmentStorageAdapter(
        factSegment.asStorageAdapter(),
        joinableClauses,
        joinFilterPreAnalysis
    );

    // In non-SQL-compatible mode, we get an extra row, since the 'null' countryNumber for "Talk:Oswald Tilghman"
    // is interpreted as 0 (a.k.a. Australia).
    JoinTestHelper.verifyCursors(
        adapter.makeCursors(
            originalFilter,
            Intervals.ETERNITY,
            VirtualColumns.EMPTY,
            Granularities.ALL,
            false,
            null
        ),
        ImmutableList.of(
            "page",
            "countryIsoCode",
            FACT_TO_COUNTRY_ON_NUMBER_PREFIX + "countryIsoCode",
            FACT_TO_COUNTRY_ON_NUMBER_PREFIX + "countryName",
            FACT_TO_COUNTRY_ON_NUMBER_PREFIX + "countryNumber"
        ),
        NullHandling.sqlCompatible() ?
        ImmutableList.of(
            new Object[]{"Peremptory norm", "AU", "AU", "Australia", 0L}
        ) :
        ImmutableList.of(
            new Object[]{"Talk:Oswald Tilghman", null, "AU", "Australia", 0L},
            new Object[]{"Peremptory norm", "AU", "AU", "Australia", 0L}
        )
    );

    JoinFilterSplit expectedFilterSplit = new JoinFilterSplit(
        new AndFilter(
            ImmutableList.of(
                new SelectorFilter("channel", "#en.wikipedia"),
                new InDimFilter("countryNumber", ImmutableSet.of("0"), null, null).toFilter()
            )
        ),
        new SelectorFilter(FACT_TO_COUNTRY_ON_NUMBER_PREFIX + "countryName", "Australia"),
        ImmutableSet.of()
    );

    JoinFilterSplit actualFilterSplit = JoinFilterAnalyzer.splitFilter(joinFilterPreAnalysis);
    Assert.assertEquals(expectedFilterSplit, actualFilterSplit);
  }

  @Test
  public void test_filterPushDown_factToCountryInnerUsingCountryNumberFilterOnChannelAndCountryNameUsingLookup()
  {
    List<JoinableClause> joinableClauses = ImmutableList.of(factToCountryNameUsingNumberLookup(JoinType.INNER));
    Filter originalFilter = new AndFilter(
        ImmutableList.of(
            new SelectorFilter("channel", "#en.wikipedia"),
            new SelectorFilter(FACT_TO_COUNTRY_ON_NUMBER_PREFIX + "v", "Australia")
        )
    );
    JoinFilterPreAnalysis joinFilterPreAnalysis = makeDefaultConfigPreAnalysis(
        originalFilter,
        joinableClauses,
        VirtualColumns.EMPTY
    );
    HashJoinSegmentStorageAdapter adapter = new HashJoinSegmentStorageAdapter(
        factSegment.asStorageAdapter(),
        joinableClauses,
        joinFilterPreAnalysis
    );

    // In non-SQL-compatible mode, we get an extra row, since the 'null' countryNumber for "Talk:Oswald Tilghman"
    // is interpreted as 0 (a.k.a. Australia).
    JoinTestHelper.verifyCursors(
        adapter.makeCursors(
            originalFilter,
            Intervals.ETERNITY,
            VirtualColumns.EMPTY,
            Granularities.ALL,
            false,
            null
        ),
        ImmutableList.of(
            "page",
            "countryIsoCode",
            FACT_TO_COUNTRY_ON_NUMBER_PREFIX + "k",
            FACT_TO_COUNTRY_ON_NUMBER_PREFIX + "v"
        ),
        NullHandling.sqlCompatible() ?
        ImmutableList.of(
            new Object[]{"Peremptory norm", "AU", "0", "Australia"}
        ) :
        ImmutableList.of(
            new Object[]{"Talk:Oswald Tilghman", null, "0", "Australia"},
            new Object[]{"Peremptory norm", "AU", "0", "Australia"}
        )
    );

    JoinFilterSplit expectedFilterSplit = new JoinFilterSplit(
        new AndFilter(
            ImmutableList.of(
                new SelectorFilter("channel", "#en.wikipedia"),
                new InDimFilter("countryNumber", ImmutableSet.of("0"), null, null).toFilter()
            )
        ),
        new SelectorFilter(FACT_TO_COUNTRY_ON_NUMBER_PREFIX + "v", "Australia"),
        ImmutableSet.of()
    );

    JoinFilterSplit actualFilterSplit = JoinFilterAnalyzer.splitFilter(joinFilterPreAnalysis);
    Assert.assertEquals(expectedFilterSplit, actualFilterSplit);
  }

  @Test
  public void test_filterPushDown_factToCountryInnerUsingCountryNumberFilterOnNulls()
  {
    List<JoinableClause> joinableClauses = ImmutableList.of(factToCountryOnNumber(JoinType.INNER));
    Filter originalFilter = new AndFilter(
        ImmutableList.of(
            new SelectorFilter("channel", null),
            new SelectorFilter(FACT_TO_COUNTRY_ON_NUMBER_PREFIX + "countryName", null)
        )
    );
    JoinFilterPreAnalysis joinFilterPreAnalysis = makeDefaultConfigPreAnalysis(
        originalFilter,
        joinableClauses,
        VirtualColumns.EMPTY
    );
    HashJoinSegmentStorageAdapter adapter = new HashJoinSegmentStorageAdapter(
        factSegment.asStorageAdapter(),
        joinableClauses,
        joinFilterPreAnalysis
    );

    JoinTestHelper.verifyCursors(
        adapter.makeCursors(
            originalFilter,
            Intervals.ETERNITY,
            VirtualColumns.EMPTY,
            Granularities.ALL,
            false,
            null
        ),
        ImmutableList.of(
            "page",
            "countryIsoCode",
            FACT_TO_COUNTRY_ON_NUMBER_PREFIX + "countryIsoCode",
            FACT_TO_COUNTRY_ON_NUMBER_PREFIX + "countryName",
            FACT_TO_COUNTRY_ON_NUMBER_PREFIX + "countryNumber"
        ),
        ImmutableList.of()
    );

    JoinFilterSplit expectedFilterSplit = new JoinFilterSplit(
        null,
        new AndFilter(
            ImmutableList.of(
                new SelectorFilter("channel", null),
                new SelectorFilter(FACT_TO_COUNTRY_ON_NUMBER_PREFIX + "countryName", null)
            )
        ),
        ImmutableSet.of()
    );

    JoinFilterSplit actualFilterSplit = JoinFilterAnalyzer.splitFilter(joinFilterPreAnalysis);
    Assert.assertEquals(expectedFilterSplit, actualFilterSplit);
  }

  @Test
  public void test_filterPushDown_factToCountryInnerUsingCountryNumberFilterOnNullsUsingLookup()
  {
    List<JoinableClause> joinableClauses = ImmutableList.of(factToCountryNameUsingIsoCodeLookup(JoinType.INNER));
    Filter originalFilter = new AndFilter(
        ImmutableList.of(
            new SelectorFilter("channel", null),
            new SelectorFilter(FACT_TO_COUNTRY_ON_NUMBER_PREFIX + "v", null)
        )
    );
    JoinFilterPreAnalysis joinFilterPreAnalysis = makeDefaultConfigPreAnalysis(
        originalFilter,
        joinableClauses,
        VirtualColumns.EMPTY
    );
    HashJoinSegmentStorageAdapter adapter = new HashJoinSegmentStorageAdapter(
        factSegment.asStorageAdapter(),
        joinableClauses,
        joinFilterPreAnalysis
    );

    JoinTestHelper.verifyCursors(
        adapter.makeCursors(
            originalFilter,
            Intervals.ETERNITY,
            VirtualColumns.EMPTY,
            Granularities.ALL,
            false,
            null
        ),
        ImmutableList.of(
            "page",
            "countryIsoCode",
            FACT_TO_COUNTRY_ON_NUMBER_PREFIX + "k",
            FACT_TO_COUNTRY_ON_NUMBER_PREFIX + "v"
        ),
        ImmutableList.of()
    );

    JoinFilterSplit expectedFilterSplit = new JoinFilterSplit(
        null,
        new AndFilter(
            ImmutableList.of(
                new SelectorFilter("channel", null),
                new SelectorFilter(FACT_TO_COUNTRY_ON_NUMBER_PREFIX + "v", null)
            )
        ),
        ImmutableSet.of()
    );

    JoinFilterSplit actualFilterSplit = JoinFilterAnalyzer.splitFilter(joinFilterPreAnalysis);
    Assert.assertEquals(expectedFilterSplit, actualFilterSplit);
  }

  @Test
  public void test_filterPushDown_factToCountryFullWithFilterOnChannelAndCountryName()
  {
    Filter filter = new AndFilter(
        ImmutableList.of(
            new SelectorFilter("channel", "#es.wikipedia"),
            new SelectorFilter(FACT_TO_COUNTRY_ON_ISO_CODE_PREFIX + "countryName", "El Salvador")
        )
    );
    List<JoinableClause> joinableClauses = ImmutableList.of(factToCountryOnIsoCode(JoinType.FULL));
    JoinFilterPreAnalysis joinFilterPreAnalysis = makeDefaultConfigPreAnalysis(
        filter,
        joinableClauses,
        VirtualColumns.EMPTY
    );
    HashJoinSegmentStorageAdapter adapter = new HashJoinSegmentStorageAdapter(
        factSegment.asStorageAdapter(),
        joinableClauses,
        joinFilterPreAnalysis
    );

    JoinTestHelper.verifyCursors(
        adapter.makeCursors(
            filter,
            Intervals.ETERNITY,
            VirtualColumns.EMPTY,
            Granularities.ALL,
            false,
            null
        ),
        ImmutableList.of(
            "page",
            "countryIsoCode",
            "countryNumber",
            FACT_TO_COUNTRY_ON_ISO_CODE_PREFIX + "countryIsoCode",
            FACT_TO_COUNTRY_ON_ISO_CODE_PREFIX + "countryName",
            FACT_TO_COUNTRY_ON_ISO_CODE_PREFIX + "countryNumber"
        ),
        ImmutableList.of(
            new Object[]{"Wendigo", "SV", 12L, "SV", "El Salvador", 12L}
        )
    );

    JoinFilterSplit expectedFilterSplit = new JoinFilterSplit(
        new AndFilter(
            ImmutableList.of(
                new SelectorFilter("channel", "#es.wikipedia"),
                new InDimFilter("countryIsoCode", ImmutableSet.of("SV"), null, null).toFilter()
            )
        ),
        new SelectorFilter(FACT_TO_COUNTRY_ON_ISO_CODE_PREFIX + "countryName", "El Salvador"),
        ImmutableSet.of()
    );

    JoinFilterSplit actualFilterSplit = JoinFilterAnalyzer.splitFilter(joinFilterPreAnalysis);
    Assert.assertEquals(expectedFilterSplit, actualFilterSplit);
  }

  @Test
  public void test_filterPushDown_factToCountryFullWithFilterOnChannelAndCountryNameUsingLookup()
  {
    Filter filter = new AndFilter(
        ImmutableList.of(
            new SelectorFilter("channel", "#es.wikipedia"),
            new SelectorFilter(FACT_TO_COUNTRY_ON_ISO_CODE_PREFIX + "v", "El Salvador")
        )
    );
    List<JoinableClause> joinableClauses = ImmutableList.of(factToCountryNameUsingIsoCodeLookup(JoinType.FULL));
    JoinFilterPreAnalysis joinFilterPreAnalysis = makeDefaultConfigPreAnalysis(
        filter,
        joinableClauses,
        VirtualColumns.EMPTY
    );
    HashJoinSegmentStorageAdapter adapter = new HashJoinSegmentStorageAdapter(
        factSegment.asStorageAdapter(),
        joinableClauses,
        joinFilterPreAnalysis
    );

    JoinTestHelper.verifyCursors(
        adapter.makeCursors(
            filter,
            Intervals.ETERNITY,
            VirtualColumns.EMPTY,
            Granularities.ALL,
            false,
            null
        ),
        ImmutableList.of(
            "page",
            "countryIsoCode",
            "countryNumber",
            FACT_TO_COUNTRY_ON_ISO_CODE_PREFIX + "k",
            FACT_TO_COUNTRY_ON_ISO_CODE_PREFIX + "v"
        ),
        ImmutableList.of(
            new Object[]{"Wendigo", "SV", 12L, "SV", "El Salvador"}
        )
    );

    JoinFilterSplit expectedFilterSplit = new JoinFilterSplit(
        new AndFilter(
            ImmutableList.of(
                new SelectorFilter("channel", "#es.wikipedia"),
                new InDimFilter("countryIsoCode", ImmutableSet.of("SV"), null, null).toFilter()
            )
        ),
        new SelectorFilter(FACT_TO_COUNTRY_ON_ISO_CODE_PREFIX + "v", "El Salvador"),
        ImmutableSet.of()
    );

    JoinFilterSplit actualFilterSplit = JoinFilterAnalyzer.splitFilter(joinFilterPreAnalysis);
    Assert.assertEquals(expectedFilterSplit, actualFilterSplit);
  }

  @Test
  public void test_filterPushDown_factToCountryFullWithFilterOnNulls()
  {
    List<JoinableClause> joinableClauses = ImmutableList.of(factToCountryOnIsoCode(JoinType.FULL));
    Filter originalFilter = new AndFilter(
        ImmutableList.of(
            new SelectorFilter("channel", null),
            new SelectorFilter(FACT_TO_COUNTRY_ON_ISO_CODE_PREFIX + "countryName", null)
        )
    );
    JoinFilterPreAnalysis joinFilterPreAnalysis = makeDefaultConfigPreAnalysis(
        originalFilter,
        joinableClauses,
        VirtualColumns.EMPTY
    );
    HashJoinSegmentStorageAdapter adapter = new HashJoinSegmentStorageAdapter(
        factSegment.asStorageAdapter(),
        joinableClauses,
        joinFilterPreAnalysis
    );

    JoinTestHelper.verifyCursors(
        adapter.makeCursors(
            originalFilter,
            Intervals.ETERNITY,
            VirtualColumns.EMPTY,
            Granularities.ALL,
            false,
            null
        ),
        ImmutableList.of(
            "page",
            "countryIsoCode",
            "countryNumber",
            FACT_TO_COUNTRY_ON_ISO_CODE_PREFIX + "countryIsoCode",
            FACT_TO_COUNTRY_ON_ISO_CODE_PREFIX + "countryName",
            FACT_TO_COUNTRY_ON_ISO_CODE_PREFIX + "countryNumber"
        ),
        ImmutableList.of()
    );

    JoinFilterSplit expectedFilterSplit = new JoinFilterSplit(
        null,
        new AndFilter(
            ImmutableList.of(
                new SelectorFilter("channel", null),
                new SelectorFilter(FACT_TO_COUNTRY_ON_ISO_CODE_PREFIX + "countryName", null)
            )
        ),
        ImmutableSet.of()
    );

    JoinFilterSplit actualFilterSplit = JoinFilterAnalyzer.splitFilter(joinFilterPreAnalysis);
    Assert.assertEquals(expectedFilterSplit, actualFilterSplit);
  }

  @Test
  public void test_filterPushDown_factToCountryFullWithFilterOnNullsUsingLookup()
  {
    List<JoinableClause> joinableClauses = ImmutableList.of(factToCountryNameUsingIsoCodeLookup(JoinType.FULL));
    Filter originalFilter = new AndFilter(
        ImmutableList.of(
            new SelectorFilter("channel", null),
            new SelectorFilter(FACT_TO_COUNTRY_ON_ISO_CODE_PREFIX + "v", null)
        )
    );
    JoinFilterPreAnalysis joinFilterPreAnalysis = makeDefaultConfigPreAnalysis(
        originalFilter,
        joinableClauses,
        VirtualColumns.EMPTY
    );
    HashJoinSegmentStorageAdapter adapter = new HashJoinSegmentStorageAdapter(
        factSegment.asStorageAdapter(),
        joinableClauses,
        joinFilterPreAnalysis
    );

    JoinTestHelper.verifyCursors(
        adapter.makeCursors(
            originalFilter,
            Intervals.ETERNITY,
            VirtualColumns.EMPTY,
            Granularities.ALL,
            false,
            null
        ),
        ImmutableList.of(
            "page",
            "countryIsoCode",
            "countryNumber",
            FACT_TO_COUNTRY_ON_ISO_CODE_PREFIX + "k",
            FACT_TO_COUNTRY_ON_ISO_CODE_PREFIX + "v"
        ),
        ImmutableList.of()
    );

    JoinFilterSplit expectedFilterSplit = new JoinFilterSplit(
        null,
        new AndFilter(
            ImmutableList.of(
                new SelectorFilter("channel", null),
                new SelectorFilter(FACT_TO_COUNTRY_ON_ISO_CODE_PREFIX + "v", null)
            )
        ),
        ImmutableSet.of()
    );

    JoinFilterSplit actualFilterSplit = JoinFilterAnalyzer.splitFilter(joinFilterPreAnalysis);
    Assert.assertEquals(expectedFilterSplit, actualFilterSplit);
  }

  @Test
  public void test_filterPushDown_factToRegionTwoColumnsToOneRHSColumnAndFilterOnRHS()
  {
    JoinableClause factExprToRegon = new JoinableClause(
        FACT_TO_REGION_PREFIX,
        new IndexedTableJoinable(regionsTable),
        JoinType.LEFT,
        JoinConditionAnalysis.forExpression(
            StringUtils.format(
                "\"%sregionIsoCode\" == regionIsoCode && \"%sregionIsoCode\" == countryIsoCode",
                FACT_TO_REGION_PREFIX,
                FACT_TO_REGION_PREFIX
            ),
            FACT_TO_REGION_PREFIX,
            ExprMacroTable.nil()
        )
    );
    List<JoinableClause> joinableClauses = ImmutableList.of(
        factExprToRegon
    );
    Filter originalFilter = new SelectorFilter("r1.regionName", "Fourems Province");

    JoinFilterPreAnalysis joinFilterPreAnalysis = makeDefaultConfigPreAnalysis(
        originalFilter,
        joinableClauses,
        VirtualColumns.EMPTY
    );
    HashJoinSegmentStorageAdapter adapter = new HashJoinSegmentStorageAdapter(
        factSegment.asStorageAdapter(),
        joinableClauses,
        joinFilterPreAnalysis
    );

    JoinTestHelper.verifyCursors(
        adapter.makeCursors(
            originalFilter,
            Intervals.ETERNITY,
            VirtualColumns.EMPTY,
            Granularities.ALL,
            false,
            null
        ),
        ImmutableList.of(
            "page",
            FACT_TO_REGION_PREFIX + "regionName"
        ),
        ImmutableList.of(
            new Object[]{"History of Fourems", "Fourems Province"}
        )
    );

    JoinFilterSplit expectedFilterSplit = new JoinFilterSplit(
        new AndFilter(
            ImmutableList.of(
                new InDimFilter("countryIsoCode", ImmutableSet.of("MMMM"), null, null).toFilter(),
                new InDimFilter("regionIsoCode", ImmutableSet.of("MMMM"), null, null).toFilter()
            )
        ),
        new SelectorFilter("r1.regionName", "Fourems Province"),
        ImmutableSet.of()
    );

    JoinFilterSplit actualFilterSplit = JoinFilterAnalyzer.splitFilter(joinFilterPreAnalysis);
    Assert.assertEquals(expectedFilterSplit, actualFilterSplit);
  }

  @Test
  public void test_filterPushDown_factToRegionOneColumnToTwoRHSColumnsAndFilterOnRHS()
  {
    JoinableClause factExprToRegon = new JoinableClause(
        FACT_TO_REGION_PREFIX,
        new IndexedTableJoinable(regionsTable),
        JoinType.LEFT,
        JoinConditionAnalysis.forExpression(
            StringUtils.format(
                "\"%sregionIsoCode\" == regionIsoCode && \"%scountryIsoCode\" == regionIsoCode",
                FACT_TO_REGION_PREFIX,
                FACT_TO_REGION_PREFIX
            ),
            FACT_TO_REGION_PREFIX,
            ExprMacroTable.nil()
        )
    );
    List<JoinableClause> joinableClauses = ImmutableList.of(
        factExprToRegon
    );
    Filter originalFilter = new OrFilter(
        ImmutableList.of(
            new SelectorFilter("r1.regionName", "Fourems Province"),
            new SelectorFilter("r1.regionIsoCode", "AAAA")
        )
    );

    JoinFilterPreAnalysis joinFilterPreAnalysis = makeDefaultConfigPreAnalysis(
        originalFilter,
        joinableClauses,
        VirtualColumns.EMPTY
    );
    HashJoinSegmentStorageAdapter adapter = new HashJoinSegmentStorageAdapter(
        factSegment.asStorageAdapter(),
        joinableClauses,
        joinFilterPreAnalysis
    );

    JoinTestHelper.verifyCursors(
        adapter.makeCursors(
            originalFilter,
            Intervals.ETERNITY,
            VirtualColumns.EMPTY,
            Granularities.ALL,
            false,
            null
        ),
        ImmutableList.of(
            "page",
            FACT_TO_REGION_PREFIX + "regionName"
        ),
        ImmutableList.of(
            new Object[]{"History of Fourems", "Fourems Province"}
        )
    );

    JoinFilterSplit expectedFilterSplit = new JoinFilterSplit(
        new OrFilter(
            ImmutableList.of(
                new InDimFilter("regionIsoCode", ImmutableSet.of("MMMM"), null, null).toFilter(),
                new SelectorFilter("regionIsoCode", "AAAA")
            )
        ),
        originalFilter,
        ImmutableSet.of()
    );

    JoinFilterSplit actualFilterSplit = JoinFilterAnalyzer.splitFilter(joinFilterPreAnalysis);
    Assert.assertEquals(expectedFilterSplit, actualFilterSplit);
  }


  @Test
  public void test_filterPushDown_factToRegionThreeRHSColumnsAllDirectAndFilterOnRHS()
  {
    JoinableClause factExprToRegon = new JoinableClause(
        FACT_TO_REGION_PREFIX,
        new IndexedTableJoinable(regionsTable),
        JoinType.LEFT,
        JoinConditionAnalysis.forExpression(
            StringUtils.format(
                "\"%sregionIsoCode\" == regionIsoCode && \"%scountryIsoCode\" == regionIsoCode && \"%sregionName\" == user",
                FACT_TO_REGION_PREFIX,
                FACT_TO_REGION_PREFIX,
                FACT_TO_REGION_PREFIX
            ),
            FACT_TO_REGION_PREFIX,
            ExprMacroTable.nil()
        )
    );
    List<JoinableClause> joinableClauses = ImmutableList.of(
        factExprToRegon
    );
    Filter originalFilter = new OrFilter(
        ImmutableList.of(
            new SelectorFilter("r1.regionName", "Fourems Province"),
            new SelectorFilter("r1.regionIsoCode", "AAAA")
        )
    );

    JoinFilterPreAnalysis joinFilterPreAnalysis = makeDefaultConfigPreAnalysis(
        originalFilter,
        joinableClauses,
        VirtualColumns.EMPTY
    );
    HashJoinSegmentStorageAdapter adapter = new HashJoinSegmentStorageAdapter(
        factSegment.asStorageAdapter(),
        joinableClauses,
        joinFilterPreAnalysis
    );

    // This query doesn't execute because regionName is not a key column, but we can still check the
    // filter rewrites.
    expectedException.expect(IAE.class);
    expectedException.expectMessage(
        "Cannot build hash-join matcher on non-key-based condition: Equality{leftExpr=user, rightColumn='regionName'}"
    );

    JoinTestHelper.verifyCursors(
        adapter.makeCursors(
            originalFilter,
            Intervals.ETERNITY,
            VirtualColumns.EMPTY,
            Granularities.ALL,
            false,
            null
        ),
        ImmutableList.of(
            "page",
            FACT_TO_REGION_PREFIX + "regionName"
        ),
        ImmutableList.of()
    );

    JoinFilterSplit expectedFilterSplit = new JoinFilterSplit(
        new OrFilter(
            ImmutableList.of(
                new SelectorFilter("user", "Fourems Province"),
                new SelectorFilter("regionIsoCode", "AAAA")
            )
        ),
        null,
        ImmutableSet.of()
    );

    JoinFilterSplit actualFilterSplit = JoinFilterAnalyzer.splitFilter(joinFilterPreAnalysis);
    Assert.assertEquals(expectedFilterSplit, actualFilterSplit);
  }

  @Test
  public void test_filterPushDown_factToRegionToCountryLeftFilterOnPageDisablePushDown()
  {
    JoinableClauses joinableClauses = JoinableClauses.fromList(ImmutableList.of(
        factToRegion(JoinType.LEFT),
        regionToCountry(JoinType.LEFT)
    ));
    Filter originalFilter = new SelectorFilter("page", "Peremptory norm");

    JoinFilterPreAnalysis joinFilterPreAnalysis = JoinFilterAnalyzer.computeJoinFilterPreAnalysis(
        new JoinFilterPreAnalysisKey(
            new JoinFilterRewriteConfig(
                false,
                true,
                true,
                QueryContexts.DEFAULT_ENABLE_REWRITE_JOIN_TO_FILTER,
                QueryContexts.DEFAULT_ENABLE_JOIN_FILTER_REWRITE_MAX_SIZE
            ),
            joinableClauses.getJoinableClauses(),
            VirtualColumns.EMPTY,
            originalFilter
        )
    );

    HashJoinSegmentStorageAdapter adapter = new HashJoinSegmentStorageAdapter(
        factSegment.asStorageAdapter(),
        joinableClauses.getJoinableClauses(),
        joinFilterPreAnalysis
    );

    JoinTestHelper.verifyCursors(
        adapter.makeCursors(
            originalFilter,
            Intervals.ETERNITY,
            VirtualColumns.EMPTY,
            Granularities.ALL,
            false,
            null
        ),
        ImmutableList.of(
            "page",
            FACT_TO_REGION_PREFIX + "regionName",
            REGION_TO_COUNTRY_PREFIX + "countryName"
        ),
        ImmutableList.of(
            new Object[]{"Peremptory norm", "New South Wales", "Australia"}
        )
    );

    JoinFilterSplit expectedFilterSplit = new JoinFilterSplit(
        null,
        new SelectorFilter("page", "Peremptory norm"),
        ImmutableSet.of()
    );

    JoinFilterSplit actualFilterSplit = JoinFilterAnalyzer.splitFilter(joinFilterPreAnalysis);
    Assert.assertEquals(expectedFilterSplit, actualFilterSplit);
  }

  @Test
  public void test_filterPushDown_factToRegionToCountryLeftEnablePushDownDisableRewrite()
  {
    JoinableClauses joinableClauses = JoinableClauses.fromList(ImmutableList.of(
        factToRegion(JoinType.LEFT),
        regionToCountry(JoinType.LEFT)
    ));
    Filter originalFilter = new AndFilter(
        ImmutableList.of(
            new SelectorFilter("channel", "#en.wikipedia"),
            new SelectorFilter("rtc.countryName", "United States"),
            new OrFilter(
                ImmutableList.of(
                    new SelectorFilter("page", "DirecTV"),
                    new SelectorFilter("rtc.countryIsoCode", "US")
                )
            ),
            new BoundFilter(new BoundDimFilter(
                "namespace",
                "Main",
                "Main",
                false,
                false,
                null,
                null,
                null
            ))
        )
    );

    JoinFilterPreAnalysis joinFilterPreAnalysis = JoinFilterAnalyzer.computeJoinFilterPreAnalysis(
        new JoinFilterPreAnalysisKey(
            new JoinFilterRewriteConfig(
                true,
                false,
                true,
                QueryContexts.DEFAULT_ENABLE_REWRITE_JOIN_TO_FILTER,
                QueryContexts.DEFAULT_ENABLE_JOIN_FILTER_REWRITE_MAX_SIZE
            ),
            joinableClauses.getJoinableClauses(),
            VirtualColumns.EMPTY,
            originalFilter
        )
    );

    HashJoinSegmentStorageAdapter adapter = new HashJoinSegmentStorageAdapter(
        factSegment.asStorageAdapter(),
        joinableClauses.getJoinableClauses(),
        joinFilterPreAnalysis
    );

    JoinTestHelper.verifyCursors(
        adapter.makeCursors(
            originalFilter,
            Intervals.ETERNITY,
            VirtualColumns.EMPTY,
            Granularities.ALL,
            false,
            null
        ),
        ImmutableList.of(
            "page",
            FACT_TO_REGION_PREFIX + "regionName",
            REGION_TO_COUNTRY_PREFIX + "countryName"
        ),
        ImmutableList.of(
            new Object[]{"President of India", "California", "United States"},
            new Object[]{"Otjiwarongo Airport", "California", "United States"},
            new Object[]{"DirecTV", "North Carolina", "United States"},
            new Object[]{"Carlo Curti", "California", "United States"},
            new Object[]{"Old Anatolian Turkish", "Virginia", "United States"}
        )
    );

    JoinFilterSplit expectedFilterSplit = new JoinFilterSplit(
        new AndFilter(
            ImmutableList.of(
                new SelectorFilter("channel", "#en.wikipedia"),
                new BoundFilter(new BoundDimFilter(
                    "namespace",
                    "Main",
                    "Main",
                    false,
                    false,
                    null,
                    null,
                    null
                ))
            )
        ),
        new AndFilter(
            ImmutableList.of(
                new SelectorFilter("rtc.countryName", "United States"),
                new OrFilter(
                    ImmutableList.of(
                        new SelectorFilter("page", "DirecTV"),
                        new SelectorFilter("rtc.countryIsoCode", "US")
                    )
                )
            )
        ),
        ImmutableSet.of()
    );

    JoinFilterSplit actualFilterSplit = JoinFilterAnalyzer.splitFilter(joinFilterPreAnalysis);
    Assert.assertEquals(expectedFilterSplit, actualFilterSplit);
  }

  @Test
  public void test_filterPushDown_factToRegionToCountryLeftFilterOnRHSJoinConditionColumns()
  {
    test_filterPushDown_factToRegionToCountryLeftFilterOnRHSJoinConditionColumnsHelper(false);
  }

  @Test
  public void test_filterPushDown_factToRegionToCountryLeftFilterOnRHSJoinConditionColumnsWithLhsExpr()
  {
    test_filterPushDown_factToRegionToCountryLeftFilterOnRHSJoinConditionColumnsHelper(true);
  }

  private void test_filterPushDown_factToRegionToCountryLeftFilterOnRHSJoinConditionColumnsHelper(boolean hasLhsExpressionInJoinCondition)
  {
    Filter expressionFilter = new ExpressionDimFilter(
        "\"rtc.countryIsoCode\" == 'CA'",
        ExprMacroTable.nil()
    ).toFilter();

    Filter specialSelectorFilter = new SelectorFilter("rtc.countryIsoCode", "CA")
    {
      @Override
      public boolean supportsRequiredColumnRewrite()
      {
        return false;
      }
    };

    Filter originalFilter = new AndFilter(
        ImmutableList.of(
            new SelectorFilter("r1.regionIsoCode", "ON"),
            new SelectorFilter("rtc.countryIsoCode", "CA"),
            specialSelectorFilter,
            new BoundFilter(new BoundDimFilter(
                "rtc.countryIsoCode",
                "CA",
                "CB",
                false,
                false,
                null,
                null,
                null
            )),
            expressionFilter,
            new InDimFilter("rtc.countryIsoCode", ImmutableSet.of("CA", "CA2", "CA3"), null, null).toFilter(),
            new OrFilter(
                ImmutableList.of(
                    new SelectorFilter("channel", "#fr.wikipedia"),
                    new SelectorFilter("rtc.countryIsoCode", "QQQ"),
                    new BoundFilter(new BoundDimFilter(
                        "rtc.countryIsoCode",
                        "YYY",
                        "ZZZ",
                        false,
                        false,
                        null,
                        null,
                        null
                    ))
                )
            ),
            new OrFilter(
                ImmutableList.of(
                    new SelectorFilter("namespace", "Main"),
                    new SelectorFilter("rtc.countryIsoCode", "ABCDEF"),
                    new SelectorFilter("rtc.countryName", "Canada"),
                    new BoundFilter(new BoundDimFilter(
                        "rtc.countryIsoCode",
                        "XYZXYZ",
                        "XYZXYZ",
                        false,
                        false,
                        null,
                        null,
                        null
                    ))
                )
            )
        )
    );

    JoinableClause factToRegionClause;
    if (hasLhsExpressionInJoinCondition) {
      factToRegionClause = new JoinableClause(
          FACT_TO_REGION_PREFIX,
          new IndexedTableJoinable(regionsTable),
          JoinType.LEFT,
          JoinConditionAnalysis.forExpression(
              StringUtils.format(
                  "\"%sregionIsoCode\" == upper(lower(regionIsoCode)) && \"%scountryIsoCode\" == upper(lower(countryIsoCode))",
                  FACT_TO_REGION_PREFIX,
                  FACT_TO_REGION_PREFIX
              ),
              FACT_TO_REGION_PREFIX,
              ExprMacroTable.nil()
          )
      );
    } else {
      factToRegionClause = factToRegion(JoinType.LEFT);
    }

    List<JoinableClause> joinableClauses = ImmutableList.of(
        factToRegionClause,
        regionToCountry(JoinType.LEFT)
    );

    JoinFilterPreAnalysis joinFilterPreAnalysis = makeDefaultConfigPreAnalysis(
        originalFilter,
        joinableClauses,
        VirtualColumns.EMPTY
    );
    HashJoinSegmentStorageAdapter adapter = new HashJoinSegmentStorageAdapter(
        factSegment.asStorageAdapter(),
        joinableClauses,
        joinFilterPreAnalysis
    );

    String rewrittenCountryIsoCodeColumnName = hasLhsExpressionInJoinCondition
                                               ? "JOIN-FILTER-PUSHDOWN-VIRTUAL-COLUMN-1"
                                               : "countryIsoCode";


    String rewrittenRegionIsoCodeColumnName = hasLhsExpressionInJoinCondition
                                              ? "JOIN-FILTER-PUSHDOWN-VIRTUAL-COLUMN-0"
                                              : "regionIsoCode";

    Set<VirtualColumn> expectedVirtualColumns;
    if (hasLhsExpressionInJoinCondition) {
      expectedVirtualColumns = ImmutableSet.of(
          new ExpressionVirtualColumn(
              rewrittenRegionIsoCodeColumnName,
              "(upper [(lower [regionIsoCode])])",
              ValueType.STRING,
              ExprMacroTable.nil()
          ),
          new ExpressionVirtualColumn(
              rewrittenCountryIsoCodeColumnName,
              "(upper [(lower [countryIsoCode])])",
              ValueType.STRING,
              ExprMacroTable.nil()
          )
      );
    } else {
      expectedVirtualColumns = ImmutableSet.of();
    }

    JoinTestHelper.verifyCursors(
        adapter.makeCursors(
            originalFilter,
            Intervals.ETERNITY,
            VirtualColumns.EMPTY,
            Granularities.ALL,
            false,
            null
        ),
        ImmutableList.of(
            "page",
            FACT_TO_REGION_PREFIX + "regionName",
            REGION_TO_COUNTRY_PREFIX + "countryName"
        ),
        ImmutableList.of(
            new Object[]{"Didier Leclair", "Ontario", "Canada"}
        )
    );

    JoinFilterSplit expectedFilterSplit = new JoinFilterSplit(
        new AndFilter(
            ImmutableList.of(
                new SelectorFilter(rewrittenRegionIsoCodeColumnName, "ON"),
                new SelectorFilter(rewrittenCountryIsoCodeColumnName, "CA"),
                new InDimFilter(rewrittenCountryIsoCodeColumnName, ImmutableSet.of("CA"), null, null).toFilter(),
                new BoundFilter(new BoundDimFilter(
                    rewrittenCountryIsoCodeColumnName,
                    "CA",
                    "CB",
                    false,
                    false,
                    null,
                    null,
                    null
                )),
                new InDimFilter(
                    rewrittenCountryIsoCodeColumnName,
                    ImmutableSet.of("CA", "CA2", "CA3"),
                    null,
                    null
                ).toFilter(),
                new OrFilter(
                    ImmutableList.of(
                        new SelectorFilter("channel", "#fr.wikipedia"),
                        new SelectorFilter(rewrittenCountryIsoCodeColumnName, "QQQ"),
                        new BoundFilter(new BoundDimFilter(
                            rewrittenCountryIsoCodeColumnName,
                            "YYY",
                            "ZZZ",
                            false,
                            false,
                            null,
                            null,
                            null
                        ))
                    )
                ),
                new OrFilter(
                    ImmutableList.of(
                        new SelectorFilter("namespace", "Main"),
                        new SelectorFilter(rewrittenCountryIsoCodeColumnName, "ABCDEF"),
                        new InDimFilter(
                            rewrittenCountryIsoCodeColumnName,
                            ImmutableSet.of("CA"),
                            null,
                            null
                        ).toFilter(),
                        new BoundFilter(new BoundDimFilter(
                            rewrittenCountryIsoCodeColumnName,
                            "XYZXYZ",
                            "XYZXYZ",
                            false,
                            false,
                            null,
                            null,
                            null
                        ))
                    )
                )
            )
        ),
        new AndFilter(
            ImmutableList.of(
                specialSelectorFilter,
                expressionFilter,
                new OrFilter(
                    ImmutableList.of(
                        new SelectorFilter("namespace", "Main"),
                        new SelectorFilter("rtc.countryIsoCode", "ABCDEF"),
                        new SelectorFilter("rtc.countryName", "Canada"),
                        new BoundFilter(new BoundDimFilter(
                            "rtc.countryIsoCode",
                            "XYZXYZ",
                            "XYZXYZ",
                            false,
                            false,
                            null,
                            null,
                            null
                        ))
                    )
                )
            )
        ),
        expectedVirtualColumns
    );

    JoinFilterSplit actualFilterSplit = JoinFilterAnalyzer.splitFilter(joinFilterPreAnalysis);
    Assert.assertEquals(expectedFilterSplit, actualFilterSplit);
  }

  @Test
  public void test_filterPushDown_factToRegionToCountryLeftFilterOnTwoRHSColumnsSameValue()
  {
    Filter originalFilter = new AndFilter(
        ImmutableList.of(
            new SelectorFilter("r1.regionName", "California"),
            new SelectorFilter("r1.extraField", "California")
        )
    );

    List<JoinableClause> joinableClauses = ImmutableList.of(
        factToRegion(JoinType.LEFT),
        regionToCountry(JoinType.LEFT)
    );

    JoinFilterPreAnalysis joinFilterPreAnalysis = makeDefaultConfigPreAnalysis(
        originalFilter,
        joinableClauses,
        VirtualColumns.EMPTY
    );

    HashJoinSegmentStorageAdapter adapter = new HashJoinSegmentStorageAdapter(
        factSegment.asStorageAdapter(),
        joinableClauses,
        joinFilterPreAnalysis
    );

    JoinTestHelper.verifyCursors(
        adapter.makeCursors(
            originalFilter,
            Intervals.ETERNITY,
            VirtualColumns.EMPTY,
            Granularities.ALL,
            false,
            null
        ),
        ImmutableList.of(
            "page",
            FACT_TO_REGION_PREFIX + "regionName",
            REGION_TO_COUNTRY_PREFIX + "countryName"
        ),
        ImmutableList.of(
        )
    );

    JoinFilterSplit expectedFilterSplit = new JoinFilterSplit(
        new AndFilter(
            ImmutableList.of(
                new InDimFilter("countryIsoCode", ImmutableSet.of("US"), null, null).toFilter(),
                new InDimFilter("regionIsoCode", ImmutableSet.of("CA"), null, null).toFilter(),
                new InDimFilter("countryIsoCode", ImmutableSet.of("MMMM", "AAAA"), null, null).toFilter(),
                new InDimFilter("regionIsoCode", ImmutableSet.of("MMMM", "AAAA"), null, null).toFilter()
            )
        ),
        originalFilter,
        ImmutableSet.of()
    );

    JoinFilterSplit actualFilterSplit = JoinFilterAnalyzer.splitFilter(joinFilterPreAnalysis);
    Assert.assertEquals(expectedFilterSplit, actualFilterSplit);
  }


  @Test
  public void test_filterPushDown_factToRegionExprToCountryLeftFilterOnCountryNameWithMultiLevelMode()
  {
    Filter originalFilter = new SelectorFilter("rtc.countryName", "United States");
    JoinableClause regionExprToCountry = new JoinableClause(
        REGION_TO_COUNTRY_PREFIX,
        new IndexedTableJoinable(countriesTable),
        JoinType.LEFT,
        JoinConditionAnalysis.forExpression(
            StringUtils.format(
                "reverse(\"%scountryIsoCode\") == \"%scountryIsoCode\"",
                FACT_TO_REGION_PREFIX,
                REGION_TO_COUNTRY_PREFIX
            ),
            REGION_TO_COUNTRY_PREFIX,
            ExprMacroTable.nil()
        )
    );
    List<JoinableClause> joinableClauses = ImmutableList.of(
        factToRegion(JoinType.LEFT),
        regionExprToCountry
    );

    JoinFilterPreAnalysis joinFilterPreAnalysis = JoinFilterAnalyzer.computeJoinFilterPreAnalysis(
        new JoinFilterPreAnalysisKey(
            new JoinFilterRewriteConfig(
                true,
                true,
                true,
                QueryContexts.DEFAULT_ENABLE_REWRITE_JOIN_TO_FILTER,
                QueryContexts.DEFAULT_ENABLE_JOIN_FILTER_REWRITE_MAX_SIZE
            ),
            joinableClauses,
            VirtualColumns.EMPTY,
            originalFilter
        )
    );

    HashJoinSegmentStorageAdapter adapter = new HashJoinSegmentStorageAdapter(
        factSegment.asStorageAdapter(),
        joinableClauses,
        joinFilterPreAnalysis
    );

    JoinTestHelper.verifyCursors(
        adapter.makeCursors(
            originalFilter,
            Intervals.ETERNITY,
            VirtualColumns.EMPTY,
            Granularities.ALL,
            false,
            null
        ),
        ImmutableList.of(
            "page",
            FACT_TO_REGION_PREFIX + "regionName",
            REGION_TO_COUNTRY_PREFIX + "countryName"
        ),
        ImmutableList.of(
            new Object[]{"Cream Soda", "Ainigriv", "United States"}
        )
    );

    JoinFilterSplit expectedFilterSplit = new JoinFilterSplit(
        null,
        new SelectorFilter("rtc.countryName", "United States"),
        ImmutableSet.of()
    );

    JoinFilterSplit actualFilterSplit = JoinFilterAnalyzer.splitFilter(joinFilterPreAnalysis);
    Assert.assertEquals(expectedFilterSplit, actualFilterSplit);
  }

  @Test
  public void test_JoinFilterSplit_equals()
  {
    EqualsVerifier.forClass(JoinFilterSplit.class)
                  .usingGetClass()
                  .withNonnullFields("baseTableFilter", "pushDownVirtualColumns")
                  .verify();
  }


  @Test
  public void test_joinFilterPreAnalysisKey_equals()
  {
    EqualsVerifier.forClass(JoinFilterPreAnalysisKey.class)
                  .usingGetClass()
                  .withNonnullFields("virtualColumns")
                  .verify();
  }

  @Test
  public void test_filterPushDown_baseTableFilter()
  {
    Filter originalFilter = new SelectorFilter("channel", "#en.wikipedia");
    Filter baseTableFilter = new SelectorFilter("countryIsoCode", "CA");
    List<JoinableClause> joinableClauses = ImmutableList.of(
        factToRegion(JoinType.LEFT),
        regionToCountry(JoinType.LEFT)
    );

    JoinFilterPreAnalysis joinFilterPreAnalysis = makeDefaultConfigPreAnalysis(
        originalFilter,
        joinableClauses,
        VirtualColumns.EMPTY
    );

    JoinFilterSplit expectedFilterSplit = new JoinFilterSplit(
        Filters.and(Arrays.asList(originalFilter, baseTableFilter)),
        null,
        ImmutableSet.of()
    );
    JoinFilterSplit actualFilterSplit = JoinFilterAnalyzer.splitFilter(joinFilterPreAnalysis, baseTableFilter);
    Assert.assertEquals(expectedFilterSplit, actualFilterSplit);
  }
}
