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

com.hazelcast.org.apache.calcite.sql.type.FamilyOperandTypeChecker Maven / Gradle / Ivy

There is a newer version: 5.4.0
Show newest version
/*
 * 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 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.org.apache.calcite.sql.type;

import com.hazelcast.org.apache.calcite.linq4j.Ord;
import com.hazelcast.org.apache.calcite.rel.type.RelDataType;
import com.hazelcast.org.apache.calcite.sql.SqlCallBinding;
import com.hazelcast.org.apache.calcite.sql.SqlNode;
import com.hazelcast.org.apache.calcite.sql.SqlOperandCountRange;
import com.hazelcast.org.apache.calcite.sql.SqlOperator;
import com.hazelcast.org.apache.calcite.sql.SqlUtil;
import com.hazelcast.org.apache.calcite.sql.validate.implicit.TypeCoercion;

import com.hazelcast.com.google.com.hazelcast.com.on.collect.ImmutableList;

import java.util.List;
import java.util.function.Predicate;

import static com.hazelcast.org.apache.calcite.util.Static.RESOURCE;

/**
 * Operand type-checking strategy which checks operands for inclusion in type
 * families.
 */
public class FamilyOperandTypeChecker implements SqlSingleOperandTypeChecker,
    ImplicitCastOperandTypeChecker {
  //~ Instance fields --------------------------------------------------------

  protected final ImmutableList families;
  protected final Predicate optional;

  //~ Constructors -----------------------------------------------------------

  /**
   * Package private. Create using {@link OperandTypes#family}.
   */
  FamilyOperandTypeChecker(List families,
      Predicate optional) {
    this.families = ImmutableList.copyOf(families);
    this.optional = optional;
  }

  //~ Methods ----------------------------------------------------------------

  public boolean isOptional(int i) {
    return optional.test(i);
  }

  public boolean checkSingleOperandType(
      SqlCallBinding callBinding,
      SqlNode node,
      int iFormalOperand,
      boolean throwOnFailure) {
    SqlTypeFamily family = families.get(iFormalOperand);
    if (family == SqlTypeFamily.ANY) {
      // no need to check
      return true;
    }
    if (SqlUtil.isNullLiteral(node, false)) {
      if (callBinding.isTypeCoercionEnabled()) {
        return true;
      } else if (throwOnFailure) {
        throw callBinding.getValidator().newValidationError(node,
            RESOURCE.nullIllegal());
      } else {
        return false;
      }
    }
    RelDataType type =
        callBinding.getValidator().deriveType(
            callBinding.getScope(),
            node);
    SqlTypeName typeName = type.getSqlTypeName();

    // Pass type checking for operators if it's of type 'ANY'.
    if (typeName.getFamily() == SqlTypeFamily.ANY) {
      return true;
    }

    if (!family.getTypeNames().contains(typeName)) {
      if (throwOnFailure) {
        throw callBinding.newValidationSignatureError();
      }
      return false;
    }
    return true;
  }

  public boolean checkOperandTypes(
      SqlCallBinding callBinding,
      boolean throwOnFailure) {
    if (families.size() != callBinding.getOperandCount()) {
      // assume this is an inapplicable sub-rule of a com.hazelcast.com.osite rule;
      // don't throw
      return false;
    }
    for (Ord op : Ord.zip(callBinding.operands())) {
      if (!checkSingleOperandType(
          callBinding,
          op.e,
          op.i,
          false)) {
        // try to coerce type if it is allowed.
        boolean coerced = false;
        if (callBinding.isTypeCoercionEnabled()) {
          TypeCoercion typeCoercion = callBinding.getValidator().getTypeCoercion();
          ImmutableList.Builder builder = ImmutableList.builder();
          for (int i = 0; i < callBinding.getOperandCount(); i++) {
            builder.add(callBinding.getOperandType(i));
          }
          ImmutableList dataTypes = builder.build();
          coerced = typeCoercion.builtinFunctionCoercion(callBinding, dataTypes, families);
        }
        // re-validate the new nodes type.
        for (Ord op1 : Ord.zip(callBinding.operands())) {
          if (!checkSingleOperandType(
              callBinding,
              op1.e,
              op1.i,
              throwOnFailure)) {
            return false;
          }
        }
        return coerced;
      }
    }
    return true;
  }

  @Override public boolean checkOperandTypesWithoutTypeCoercion(SqlCallBinding callBinding,
      boolean throwOnFailure) {
    if (families.size() != callBinding.getOperandCount()) {
      // assume this is an inapplicable sub-rule of a com.hazelcast.com.osite rule;
      // don't throw exception.
      return false;
    }

    for (Ord op : Ord.zip(callBinding.operands())) {
      if (!checkSingleOperandType(
          callBinding,
          op.e,
          op.i,
          throwOnFailure)) {
        return false;
      }
    }
    return true;
  }

  @Override public SqlTypeFamily getOperandSqlTypeFamily(int iFormalOperand) {
    return families.get(iFormalOperand);
  }

  public SqlOperandCountRange getOperandCountRange() {
    final int max = families.size();
    int min = max;
    while (min > 0 && optional.test(min - 1)) {
      --min;
    }
    return SqlOperandCountRanges.between(min, max);
  }

  public String getAllowedSignatures(SqlOperator op, String opName) {
    return SqlUtil.getAliasedSignature(op, opName, families);
  }

  public Consistency getConsistency() {
    return Consistency.NONE;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy