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

com.hazelcast.org.apache.calcite.rel.type.RelDataTypeSystem Maven / Gradle / Ivy

/*
 * 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 compliance with
 * the License.  You may obtain a copy of the License at
 *
 * http://www.apache.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.rel.type;

import com.hazelcast.org.apache.calcite.sql.type.SqlTypeName;
import com.hazelcast.org.apache.calcite.sql.type.SqlTypeUtil;
import com.hazelcast.org.apache.calcite.util.Glossary;

/**
 * Type system.
 *
 * 

Provides behaviors concerning type limits and behaviors. For example, * in the default system, a DECIMAL can have maximum precision 19, but Hive * overrides to 38. * *

The default implementation is {@link #DEFAULT}. */ public interface RelDataTypeSystem { /** Default type system. */ RelDataTypeSystem DEFAULT = new RelDataTypeSystemImpl() { }; /** Returns the maximum scale of a given type. */ int getMaxScale(SqlTypeName typeName); /** * Returns default precision for this type if supported, otherwise -1 if * precision is either unsupported or must be specified explicitly. * * @return Default precision */ int getDefaultPrecision(SqlTypeName typeName); /** * Returns the maximum precision (or length) allowed for this type, or -1 if * precision/length are not applicable for this type. * * @return Maximum allowed precision */ int getMaxPrecision(SqlTypeName typeName); /** Returns the maximum scale of a NUMERIC or DECIMAL type. */ int getMaxNumericScale(); /** Returns the maximum precision of a NUMERIC or DECIMAL type. */ int getMaxNumericPrecision(); /** Returns the LITERAL string for the type, either PREFIX/SUFFIX. */ String getLiteral(SqlTypeName typeName, boolean isPrefix); /** Returns whether the type is case sensitive. */ boolean isCaseSensitive(SqlTypeName typeName); /** Returns whether the type can be auto increment. */ boolean isAutoincrement(SqlTypeName typeName); /** Returns the numeric type radix, typically 2 or 10. * 0 means "not applicable". */ int getNumTypeRadix(SqlTypeName typeName); /** Returns the return type of a call to the {@code SUM} aggregate function, * inferred from its argument type. */ RelDataType deriveSumType(RelDataTypeFactory typeFactory, RelDataType argumentType); /** Returns the return type of a call to the {@code AVG}, {@code STDDEV} or * {@code VAR} aggregate functions, inferred from its argument type. */ RelDataType deriveAvgAggType(RelDataTypeFactory typeFactory, RelDataType argumentType); /** Returns the return type of a call to the {@code COVAR} aggregate function, * inferred from its argument types. */ RelDataType deriveCovarType(RelDataTypeFactory typeFactory, RelDataType arg0Type, RelDataType arg1Type); /** Returns the return type of the {@code CUME_DIST} and {@code PERCENT_RANK} * aggregate functions. */ RelDataType deriveFractionalRankType(RelDataTypeFactory typeFactory); /** Returns the return type of the {@code NTILE}, {@code RANK}, * {@code DENSE_RANK}, and {@code ROW_NUMBER} aggregate functions. */ RelDataType deriveRankType(RelDataTypeFactory typeFactory); /** Whether two record types are considered distinct if their field names * are the same but in different cases. */ boolean isSchemaCaseSensitive(); /** Whether the least restrictive type of a number of CHAR types of different * lengths should be a VARCHAR type. And similarly BINARY to VARBINARY. */ boolean shouldConvertRaggedUnionTypesToVarying(); /** * Returns whether a decimal multiplication should be implemented by casting * arguments to double values. * *

Pre-condition: createDecimalProduct(type1, type2) != null */ default boolean shouldUseDoubleMultiplication( RelDataTypeFactory typeFactory, RelDataType type1, RelDataType type2) { assert deriveDecimalMultiplyType(typeFactory, type1, type2) != null; return false; } /** * Infers the return type of a decimal addition. Decimal addition involves * at least one decimal operand and requires both operands to have exact * numeric types. * *

Rules: * *

    *
  • Let p1, s1 be the precision and scale of the first operand
  • *
  • Let p2, s2 be the precision and scale of the second operand
  • *
  • Let p, s be the precision and scale of the result
  • *
  • Let d be the number of whole digits in the result
  • *
  • Then the result type is a decimal with: *
      *
    • s = max(s1, s2)
    • *
    • p = max(p1 - s1, p2 - s2) + s + 1
    • *
    *
  • *
  • p and s are capped at their maximum values
  • *
* * @see Glossary#SQL2003 SQL:2003 Part 2 Section 6.26 * * @param typeFactory TypeFactory used to create output type * @param type1 Type of the first operand * @param type2 Type of the second operand * @return Result type for a decimal addition */ default RelDataType deriveDecimalPlusType(RelDataTypeFactory typeFactory, RelDataType type1, RelDataType type2) { if (SqlTypeUtil.isExactNumeric(type1) && SqlTypeUtil.isExactNumeric(type2)) { if (SqlTypeUtil.isDecimal(type1) || SqlTypeUtil.isDecimal(type2)) { // Java numeric will always have invalid precision/scale, // use its default decimal precision/scale instead. type1 = RelDataTypeFactoryImpl.isJavaType(type1) ? typeFactory.decimalOf(type1) : type1; type2 = RelDataTypeFactoryImpl.isJavaType(type2) ? typeFactory.decimalOf(type2) : type2; int p1 = type1.getPrecision(); int p2 = type2.getPrecision(); int s1 = type1.getScale(); int s2 = type2.getScale(); int scale = Math.max(s1, s2); assert scale <= getMaxNumericScale(); int precision = Math.max(p1 - s1, p2 - s2) + scale + 1; precision = Math.min( precision, getMaxNumericPrecision()); assert precision > 0; return typeFactory.createSqlType( SqlTypeName.DECIMAL, precision, scale); } } return null; } /** * Infers the return type of a decimal multiplication. Decimal * multiplication involves at least one decimal operand and requires both * operands to have exact numeric types. * *

The default implementation is SQL:2003 compliant. * *

Rules: * *

    *
  • Let p1, s1 be the precision and scale of the first operand
  • *
  • Let p2, s2 be the precision and scale of the second operand
  • *
  • Let p, s be the precision and scale of the result
  • *
  • Let d be the number of whole digits in the result
  • *
  • Then the result type is a decimal with: *
      *
    • p = p1 + p2)
    • *
    • s = s1 + s2
    • *
    *
  • *
  • p and s are capped at their maximum values
  • *
* *

p and s are capped at their maximum values * * @see Glossary#SQL2003 SQL:2003 Part 2 Section 6.26 * * @param typeFactory TypeFactory used to create output type * @param type1 Type of the first operand * @param type2 Type of the second operand * @return Result type for a decimal multiplication, or null if decimal * multiplication should not be applied to the operands */ default RelDataType deriveDecimalMultiplyType(RelDataTypeFactory typeFactory, RelDataType type1, RelDataType type2) { if (SqlTypeUtil.isExactNumeric(type1) && SqlTypeUtil.isExactNumeric(type2)) { if (SqlTypeUtil.isDecimal(type1) || SqlTypeUtil.isDecimal(type2)) { // Java numeric will always have invalid precision/scale, // use its default decimal precision/scale instead. type1 = RelDataTypeFactoryImpl.isJavaType(type1) ? typeFactory.decimalOf(type1) : type1; type2 = RelDataTypeFactoryImpl.isJavaType(type2) ? typeFactory.decimalOf(type2) : type2; int p1 = type1.getPrecision(); int p2 = type2.getPrecision(); int s1 = type1.getScale(); int s2 = type2.getScale(); int scale = s1 + s2; scale = Math.min(scale, getMaxNumericScale()); int precision = p1 + p2; precision = Math.min( precision, getMaxNumericPrecision()); RelDataType ret; ret = typeFactory.createSqlType( SqlTypeName.DECIMAL, precision, scale); return ret; } } return null; } /** * Infers the return type of a decimal division. Decimal division involves * at least one decimal operand and requires both operands to have exact * numeric types. * *

The default implementation is SQL:2003 compliant. * *

Rules: * *

    *
  • Let p1, s1 be the precision and scale of the first operand
  • *
  • Let p2, s2 be the precision and scale of the second operand
  • *
  • Let p, s be the precision and scale of the result
  • *
  • Let d be the number of whole digits in the result
  • *
  • Then the result type is a decimal with: *
      *
    • d = p1 - s1 + s2
    • *
    • s < max(6, s1 + p2 + 1)
    • *
    • p = d + s
    • *
    *
  • *
  • p and s are capped at their maximum values
  • *
* * @see Glossary#SQL2003 SQL:2003 Part 2 Section 6.26 * * @param typeFactory TypeFactory used to create output type * @param type1 Type of the first operand * @param type2 Type of the second operand * @return Result type for a decimal division, or null if decimal * division should not be applied to the operands */ default RelDataType deriveDecimalDivideType(RelDataTypeFactory typeFactory, RelDataType type1, RelDataType type2) { if (SqlTypeUtil.isExactNumeric(type1) && SqlTypeUtil.isExactNumeric(type2)) { if (SqlTypeUtil.isDecimal(type1) || SqlTypeUtil.isDecimal(type2)) { // Java numeric will always have invalid precision/scale, // use its default decimal precision/scale instead. type1 = RelDataTypeFactoryImpl.isJavaType(type1) ? typeFactory.decimalOf(type1) : type1; type2 = RelDataTypeFactoryImpl.isJavaType(type2) ? typeFactory.decimalOf(type2) : type2; int p1 = type1.getPrecision(); int p2 = type2.getPrecision(); int s1 = type1.getScale(); int s2 = type2.getScale(); final int maxNumericPrecision = getMaxNumericPrecision(); int dout = Math.min( p1 - s1 + s2, maxNumericPrecision); int scale = Math.max(6, s1 + p2 + 1); scale = Math.min( scale, maxNumericPrecision - dout); scale = Math.min(scale, getMaxNumericScale()); int precision = dout + scale; assert precision <= maxNumericPrecision; assert precision > 0; RelDataType ret; ret = typeFactory. createSqlType( SqlTypeName.DECIMAL, precision, scale); return ret; } } return null; } /** * Infers the return type of a decimal modulus operation. Decimal modulus * involves at least one decimal operand. * *

The default implementation is SQL:2003 compliant: the declared type of * the result is the declared type of the second operand (expression divisor). * * @see Glossary#SQL2003 SQL:2003 Part 2 Section 6.27 * *

Rules: * *

    *
  • Let p1, s1 be the precision and scale of the first operand
  • *
  • Let p2, s2 be the precision and scale of the second operand
  • *
  • Let p, s be the precision and scale of the result
  • *
  • Let d be the number of whole digits in the result
  • *
  • Then the result type is a decimal with: *
      *
    • s = max(s1, s2)
    • *
    • p = min(p1 - s1, p2 - s2) + max(s1, s2)
    • *
    *
  • *
  • p and s are capped at their maximum values
  • *
* * @param typeFactory TypeFactory used to create output type * @param type1 Type of the first operand * @param type2 Type of the second operand * @return Result type for a decimal modulus, or null if decimal * modulus should not be applied to the operands */ default RelDataType deriveDecimalModType(RelDataTypeFactory typeFactory, RelDataType type1, RelDataType type2) { if (SqlTypeUtil.isExactNumeric(type1) && SqlTypeUtil.isExactNumeric(type2)) { if (SqlTypeUtil.isDecimal(type1) || SqlTypeUtil.isDecimal(type2)) { // Java numeric will always have invalid precision/scale, // use its default decimal precision/scale instead. type1 = RelDataTypeFactoryImpl.isJavaType(type1) ? typeFactory.decimalOf(type1) : type1; type2 = RelDataTypeFactoryImpl.isJavaType(type2) ? typeFactory.decimalOf(type2) : type2; int p1 = type1.getPrecision(); int p2 = type2.getPrecision(); int s1 = type1.getScale(); int s2 = type2.getScale(); // Keep consistency with SQL standard. if (s1 == 0 && s2 == 0) { return type2; } int scale = Math.max(s1, s2); assert scale <= getMaxNumericScale(); int precision = Math.min(p1 - s1, p2 - s2) + Math.max(s1, s2); precision = Math.min(precision, getMaxNumericPrecision()); assert precision > 0; return typeFactory.createSqlType(SqlTypeName.DECIMAL, precision, scale); } } return null; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy