0

I'm trying to write a simple program that optimizes SQL query. I am getting "Missing conversion is LogicalTableScan[convention: NONE -> ENUMERABLE]" errors. Here is the optimize function code:

    public RelNode optimize(RelNode node) {
            RelOptCluster cluster = node.getCluster();
            RelTraitSet desiredTrait = cluster.traitSet().replace(EnumerableConvention.INSTANCE);
            RelNode newRoot = planner.changeTraits(node, desiredTrait);
            planner.setRoot(newRoot);
            RelNode optimized = planner.findBestExp();
            return optimized;
    }

Here is the initialization code:

    public static Optimizer create(SimpleSchema schema) {
        RelDataTypeFactory typeFactory = new JavaTypeFactoryImpl();

        Properties configProperties = new Properties();
        configProperties.put(CalciteConnectionProperty.CASE_SENSITIVE.camelName(), Boolean.TRUE.toString());
        configProperties.put(CalciteConnectionProperty.UNQUOTED_CASING.camelName(), Casing.UNCHANGED.toString());
        configProperties.put(CalciteConnectionProperty.QUOTED_CASING.camelName(), Casing.UNCHANGED.toString());
        CalciteConnectionConfig config = new CalciteConnectionConfigImpl(configProperties);

        CalciteSchema rootSchema = CalciteSchema.createRootSchema(false, false);
        rootSchema.add(schema.getSchemaName(), schema);
        Prepare.CatalogReader catalogReader = new CalciteCatalogReader(
            rootSchema,
            Collections.singletonList(schema.getSchemaName()),
            typeFactory,
            config
        );

        SqlOperatorTable operatorTable = SqlOperatorTables.chain(SqlStdOperatorTable.instance());

        SqlValidator.Config validatorConfig = SqlValidator.Config.DEFAULT
            .withLenientOperatorLookup(config.lenientOperatorLookup())
            .withConformance(config.conformance())
            .withDefaultNullCollation(config.defaultNullCollation())
            .withIdentifierExpansion(true);

        SqlValidator validator = SqlValidatorUtil.newValidator(operatorTable, catalogReader, typeFactory, validatorConfig);

        VolcanoPlanner planner = new VolcanoPlanner(RelOptCostImpl.FACTORY, Contexts.of(config));
                
        planner.addRelTraitDef(ConventionTraitDef.INSTANCE);
                planner.addRule(EnumerableRules.ENUMERABLE_MERGE_JOIN_RULE);
                planner.addRule(EnumerableRules.ENUMERABLE_SORT_RULE);
                planner.addRule(EnumerableRules.ENUMERABLE_VALUES_RULE);
                planner.addRule(EnumerableRules.ENUMERABLE_PROJECT_RULE);
                planner.addRule(EnumerableRules.ENUMERABLE_FILTER_RULE);
        RelOptCluster cluster = RelOptCluster.create(planner, new RexBuilder(typeFactory));

        SqlToRelConverter.Config converterConfig = SqlToRelConverter.CONFIG
            .withTrimUnusedFields(true)
            .withExpand(false); // https://issues.apache.org/jira/browse/CALCITE-1045

        SqlToRelConverter converter = new SqlToRelConverter(
            null,
            validator,
            catalogReader,
            cluster,
            StandardConvertletTable.INSTANCE,
            converterConfig
        );

        return new Optimizer(config, validator, converter, planner);
    }

Any ideas why this is not working? I tried removing the planner.addRule statements and using Plans standard plan but I always get this error. Same if I change convention to JDBC.

1 Answers1

0

Your code is missing the rule for table scan. Please add the table scan rule and verify.

planner.addRule(EnumerableRules.ENUMERABLE_TABLE_SCAN_RULE);

This might resolve your problem.

Sudip
  • 92
  • 7