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

com.hazelcast.sql.impl.calcite.validate.types.HazelcastInferTypes Maven / Gradle / Ivy

/*
 * 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.validate.types;

import com.hazelcast.org.apache.calcite.rel.type.RelDataType;
import com.hazelcast.org.apache.calcite.sql.type.InferTypes;
import com.hazelcast.org.apache.calcite.sql.type.SqlOperandTypeInference;
import com.hazelcast.org.apache.calcite.sql.type.SqlTypeName;

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

import static com.hazelcast.com.hazelcast.sql.impl.calcite.validate.SqlNodeUtil.isParameter;
import static com.hazelcast.com.hazelcast.sql.impl.calcite.validate.types.HazelcastTypeSystem.typeName;
import static com.hazelcast.org.apache.calcite.sql.type.SqlTypeName.BIGINT;
import static com.hazelcast.org.apache.calcite.sql.type.SqlTypeName.NULL;

/**
 * A collection of operand type inference strategies. Basically, a mirror of
 * {@link InferTypes} provided by Calcite with various enhancements.
 */
public final class HazelcastInferTypes {

    /**
     * The same as Calcite's {@link InferTypes#FIRST_KNOWN}, but doesn't consider
     * NULL as a known type and widens integer types to BIGINT for dynamic parameters.
     */
    public static final SqlOperandTypeInference FIRST_KNOWN = (binding, returnType, operandTypes) -> {
        // NOTE: Calcite validator's unknown type has NULL SqlTypeName.

        RelDataType unknown = binding.getValidator().getUnknownType();

        boolean seenParameters = false;
        RelDataType known = unknown;
        for (int i = 0; i < binding.getOperandCount(); ++i) {
            RelDataType type = binding.getOperandType(i);

            if (isParameter(binding.operand(i))) {
                seenParameters = true;
            } else if (known.equals(unknown) && typeName(type) != NULL) {
                known = type;
            }
        }

        if (seenParameters && HazelcastIntegerType.supports(typeName(known))) {
            known = HazelcastTypeFactory.INSTANCE.createSqlType(BIGINT);
        }

        Arrays.fill(operandTypes, known);
    };

    /**
     * The same as Calcite's {@link InferTypes#ANY_NULLABLE}, but doesn't assign
     * OBJECT/ANY type to NULLs.
     */
    public static final SqlOperandTypeInference NULLABLE_OBJECT = (binding, returnType, operandTypes) -> {
        // NOTE: Calcite validator's unknown type has NULL SqlTypeName.

        assert binding.getTypeFactory() == HazelcastTypeFactory.INSTANCE;
        RelDataType unknown = binding.getValidator().getUnknownType();
        for (int i = 0; i < operandTypes.length; ++i) {
            RelDataType type = binding.getOperandType(i);

            if (unknown.equals(type) || typeName(type) != NULL) {
                operandTypes[i] = HazelcastObjectType.NULLABLE_INSTANCE;
            }
        }
    };

    private HazelcastInferTypes() {
        // No-op.
    }

    public static SqlOperandTypeInference explicit(SqlTypeName typeName) {
        return InferTypes.explicit(Collections.singletonList(HazelcastTypeFactory.INSTANCE.createSqlType(typeName)));
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy