All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.hazelcast.sql.impl.calcite.HazelcastSqlBackend Maven / Gradle / Ivy

There is a newer version: 5.4.0
Show newest version
/*
 * Copyright (c) 2008-2020, Hazelcast, Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in com.hazelcast.com.liance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.com.hazelcast.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 com.hazelcast.com.hazelcast.sql.impl.calcite;

import com.hazelcast.com.hazelcast.cluster.Member;
import com.hazelcast.com.hazelcast.spi.impl.NodeEngine;
import com.hazelcast.com.hazelcast.sql.impl.QueryParameterMetadata;
import com.hazelcast.com.hazelcast.sql.impl.QueryUtils;
import com.hazelcast.com.hazelcast.sql.impl.calcite.opt.OptUtils;
import com.hazelcast.com.hazelcast.sql.impl.calcite.opt.logical.LogicalRules;
import com.hazelcast.com.hazelcast.sql.impl.calcite.opt.logical.RootLogicalRel;
import com.hazelcast.com.hazelcast.sql.impl.calcite.opt.physical.PhysicalRel;
import com.hazelcast.com.hazelcast.sql.impl.calcite.opt.physical.PhysicalRules;
import com.hazelcast.com.hazelcast.sql.impl.calcite.opt.physical.visitor.NodeIdVisitor;
import com.hazelcast.com.hazelcast.sql.impl.calcite.opt.physical.visitor.PlanCreateVisitor;
import com.hazelcast.com.hazelcast.sql.impl.calcite.parse.QueryConvertResult;
import com.hazelcast.com.hazelcast.sql.impl.calcite.parse.QueryParseResult;
import com.hazelcast.com.hazelcast.sql.impl.calcite.parse.UnsupportedOperationVisitor;
import com.hazelcast.com.hazelcast.sql.impl.calcite.validate.HazelcastSqlValidator;
import com.hazelcast.com.hazelcast.sql.impl.calcite.validate.types.HazelcastTypeFactory;
import com.hazelcast.com.hazelcast.sql.impl.optimizer.OptimizationTask;
import com.hazelcast.com.hazelcast.sql.impl.optimizer.SqlPlan;
import com.hazelcast.com.hazelcast.sql.impl.plan.cache.PlanCacheKey;
import com.hazelcast.com.hazelcast.sql.impl.type.QueryDataType;
import com.hazelcast.org.apache.calcite.plan.RelOptCluster;
import com.hazelcast.org.apache.calcite.plan.RelOptTable.ViewExpander;
import com.hazelcast.org.apache.calcite.plan.RelTraitSet;
import com.hazelcast.org.apache.calcite.prepare.Prepare.CatalogReader;
import com.hazelcast.org.apache.calcite.rel.RelNode;
import com.hazelcast.org.apache.calcite.sql.parser.SqlParserImplFactory;
import com.hazelcast.org.apache.calcite.sql.util.SqlVisitor;
import com.hazelcast.org.apache.calcite.sql.validate.SqlConformance;
import com.hazelcast.org.apache.calcite.sql.validate.SqlValidator;
import com.hazelcast.org.apache.calcite.sql2rel.SqlRexConvertletTable;
import com.hazelcast.org.apache.calcite.sql2rel.SqlToRelConverter;
import com.hazelcast.org.apache.calcite.sql2rel.SqlToRelConverter.Config;
import com.hazelcast.org.apache.calcite.sql2rel.StandardConvertletTable;

import java.util.List;
import java.util.Map;

/**
 * An IMDG specific {@link SqlBackend}.
 */
public class HazelcastSqlBackend implements SqlBackend {

    private final NodeEngine nodeEngine;

    public HazelcastSqlBackend(NodeEngine nodeEngine) {
        this.nodeEngine = nodeEngine;
    }

    @Override
    public SqlParserImplFactory parserFactory() {
        return null;
    }

    @Override
    public SqlValidator validator(
            CatalogReader catalogReader,
            HazelcastTypeFactory typeFactory,
            SqlConformance conformance
    ) {
        return new HazelcastSqlValidator(catalogReader, typeFactory, conformance);
    }

    @Override
    public SqlVisitor unsupportedOperationVisitor(CatalogReader catalogReader) {
        return new UnsupportedOperationVisitor(catalogReader);
    }

    @Override
    public SqlToRelConverter converter(
            ViewExpander viewExpander,
            SqlValidator validator,
            CatalogReader catalogReader,
            RelOptCluster cluster,
            SqlRexConvertletTable convertletTable,
            Config config
    ) {
        return new HazelcastSqlToRelConverter(
                null,
                validator,
                catalogReader,
                cluster,
                StandardConvertletTable.INSTANCE,
                config
        );
    }

    @Override
    public SqlPlan createPlan(OptimizationTask task, QueryParseResult parseResult, OptimizerContext context) {
        QueryConvertResult convertResult = context.convert(parseResult);

        QueryDataType[] mappedParameterRowType = SqlToQueryType.mapRowType(parseResult.getParameterRowType());
        QueryParameterMetadata parameterMetadata = new QueryParameterMetadata(mappedParameterRowType);

        PhysicalRel physicalRel = optimize(context, convertResult.getRel(), parameterMetadata);

        String sql = task.getSql();
        // Assign IDs to nodes.
        NodeIdVisitor idVisitor = new NodeIdVisitor();
        physicalRel.visit(idVisitor);
        Map> relIdMap = idVisitor.getIdMap();

        // Create the plan.
        Member localMember = nodeEngine.getLocalMember();

        PlanCreateVisitor visitor = new PlanCreateVisitor(
            localMember.getUuid(),
            QueryUtils.createPartitionMap(nodeEngine, localMember.getVersion(), true),
            relIdMap,
            new PlanCacheKey(task.getSearchPaths(), sql),
            convertResult.getFieldNames(),
            parameterMetadata
        );

        physicalRel.visit(visitor);

        return visitor.getPlan();
    }

    private PhysicalRel optimize(
        OptimizerContext context,
        RelNode rel,
        QueryParameterMetadata parameterMetadata
    ) {
        // Make metadata available to planner
        context.setParameterMetadata(parameterMetadata);

        // Logical part.
        RelNode logicalRel = context.optimize(rel, LogicalRules.getRuleSet(), OptUtils.toLogicalConvention(rel.getTraitSet()));

        RootLogicalRel logicalRootRel = new RootLogicalRel(logicalRel.getCluster(), logicalRel.getTraitSet(), logicalRel);

        // Physical part.
        RelTraitSet physicalTraitSet = OptUtils.toPhysicalConvention(
                logicalRootRel.getTraitSet(),
                OptUtils.getDistributionDef(logicalRootRel).getTraitRoot()
        );

        return (PhysicalRel) context.optimize(logicalRootRel, PhysicalRules.getRuleSet(), physicalTraitSet);
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy