[ 
https://issues.apache.org/jira/browse/CALCITE-3447?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16959840#comment-16959840
 ] 

daimin commented on CALCITE-3447:
---------------------------------

[~rubenql] Sure. This test case fails while it should not be. The materialized 
view is:
{code:sql}
SELECT "empid", "deptno", SUM("salary") FROM "emps" GROUP BY "empid", "deptno"
{code}
And the query is: 
{code:sql}
SELECT "empid", SUM("salary") FROM "emps" GROUP BY "empid"
{code}
And the entire unit test code is here:
{code:java}
package org.apache.calcite.test;

import org.apache.calcite.plan.MaterializedViewSubstitutionVisitor;
import org.apache.calcite.plan.RelOptUtil;
import org.apache.calcite.plan.hep.HepProgram;
import org.apache.calcite.plan.hep.HepProgramBuilder;
import org.apache.calcite.rel.RelNode;
import org.apache.calcite.rel.rules.FilterProjectTransposeRule;
import org.apache.calcite.rel.rules.ProjectMergeRule;
import org.apache.calcite.rel.rules.ProjectRemoveRule;
import org.apache.calcite.rex.RexUtil;
import org.apache.calcite.schema.SchemaPlus;
import org.apache.calcite.schema.impl.ViewTable;
import org.apache.calcite.sql.SqlNode;
import org.apache.calcite.sql.parser.SqlParseException;
import org.apache.calcite.sql.parser.SqlParser;
import org.apache.calcite.tools.FrameworkConfig;
import org.apache.calcite.tools.Frameworks;
import org.apache.calcite.tools.Planner;
import org.apache.calcite.tools.RelBuilder;
import org.apache.calcite.tools.RelConversionException;
import org.apache.calcite.tools.ValidationException;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class SubstitutionVisitorTest {

    @Test
    public void test() throws Exception {
        String mv = "SELECT \"empid\", \"deptno\", SUM(\"salary\") FROM 
\"emps\" GROUP BY \"empid\", \"deptno\"";
        String query = "SELECT \"empid\", SUM(\"salary\") FROM \"emps\" GROUP 
BY \"empid\"";

        RelNode rel_mv = compile(mv);
        RelNode rel_query = compile(query);

        SchemaPlus hr = rootSchema.getSubSchema("hr");
        hr.add("mv", ViewTable.viewMacro(hr, mv,
                Collections.singletonList("hr"),
                Arrays.asList("hr", "mv"), false));

        RelNode tableScan = relBuilder.scan("hr", "mv").build();

        System.out.println("query:");
        show(rel_query);
        System.out.println("mv:");
        show(rel_mv);
        System.out.println("scan:");
        show(tableScan);

        HepProgram program =
            new HepProgramBuilder()
                .addRuleInstance(FilterProjectTransposeRule.INSTANCE)
                .addRuleInstance(ProjectMergeRule.INSTANCE)
                .addRuleInstance(ProjectRemoveRule.INSTANCE)
                .build();

        List<RelNode> relNodes = new 
MaterializedViewSubstitutionVisitor(rel_mv, rel_query)
            .go(tableScan);

        Assert.assertEquals(relNodes.size(), 1);
    }

    private RelNode compile(String sql) throws SqlParseException, 
ValidationException, RelConversionException {
        SqlNode parse = planner.parse(sql);
        SqlNode validate = planner.validate(parse);
        RelNode convert = planner.rel(validate).rel;
        planner.close();
        return convert;
    }

    private void show(RelNode relNode) {
        System.out.println(RelOptUtil.toString(relNode));
    }

    // Before
    private SchemaPlus rootSchema;
    private Planner planner;
    private RelBuilder relBuilder;

    @Before
    public void setUp() {
        rootSchema = Frameworks.createRootSchema(true);
        final FrameworkConfig config = Frameworks.newConfigBuilder()
                .parserConfig(SqlParser.Config.DEFAULT)
                .executor(RexUtil.EXECUTOR)
                .defaultSchema(
                        CalciteAssert.addSchema(rootSchema, 
CalciteAssert.SchemaSpec.HR))
                .build();
        planner = Frameworks.getPlanner(config);
        relBuilder = RelBuilder.create(config);
    }

    @After
    public void tearDown() {
        rootSchema = null;
        planner = null;
    }
}

{code}
 

> Fix equivalents in method SubstitutionVisitor#go
> ------------------------------------------------
>
>                 Key: CALCITE-3447
>                 URL: https://issues.apache.org/jira/browse/CALCITE-3447
>             Project: Calcite
>          Issue Type: Bug
>          Components: core
>            Reporter: daimin
>            Priority: Minor
>              Labels: pull-request-available
>          Time Spent: 10m
>  Remaining Estimate: 0h
>
> Code segment here depends on `hashcode` and `equals` methods of class 
> `MutableRel`:
> [https://github.com/apache/calcite/blob/master/core/src/main/java/org/apache/calcite/plan/SubstitutionVisitor.java#L492-L502]
>  
> However the implementations of class `MutableScan` delegates to class 
> `TableScan`, which directly relies on implementations of class `Object`. This 
> leads to a situation that two `MutableScan` on the exactly same table will 
> not be considered as equivalent.



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

Reply via email to