/**
   * Returns true if a type is a simple cast of another type. It is if the cast type is nullable and
   * the cast is one of the following:
   * <li>x TO x
   * <li>char(n) TO varchar(m)
   * <li>varchar(n) TO varchar(m)
   * <li>x not null TO x nullable
   *
   * @param origType original type passed into the cast operand
   * @param castType type the operand will be casted to
   * @return true if the cast is simple
   */
  private boolean isCastSimple(RelDataType origType, RelDataType castType) {
    SqlTypeName origTypeName = origType.getSqlTypeName();
    SqlTypeName castTypeName = castType.getSqlTypeName();

    if (!(castType.isNullable())) {
      return false;
    }

    Charset origCharset = origType.getCharset();
    Charset castCharset = castType.getCharset();
    if ((origCharset != null) || (castCharset != null)) {
      if ((origCharset == null) || (castCharset == null)) {
        return false;
      }
      if (!origCharset.equals(castCharset)) {
        return false;
      }
    }

    return ((origType == castType)
        || ((origTypeName == SqlTypeName.CHAR) && (castTypeName == SqlTypeName.VARCHAR))
        || ((origTypeName == SqlTypeName.VARCHAR) && (castTypeName == SqlTypeName.VARCHAR))
        || ((origTypeName == castTypeName)
            && (origType.getPrecision() == castType.getPrecision())
            && ((origTypeName != SqlTypeName.DECIMAL)
                || (origType.getScale() == castType.getScale()))
            && (!origType.isNullable() && castType.isNullable())));
  }
コード例 #2
0
ファイル: JdbcImplementor.java プロジェクト: vlsi/optiq
 private SqlNode toSql(RelDataType type) {
   if (dialect.getDatabaseProduct() == SqlDialect.DatabaseProduct.MYSQL) {
     final SqlTypeName sqlTypeName = type.getSqlTypeName();
     switch (sqlTypeName) {
       case VARCHAR:
         // MySQL doesn't have a VARCHAR type, only CHAR.
         return new SqlDataTypeSpec(
             new SqlIdentifier("CHAR", POS), type.getPrecision(), -1, null, null, POS);
       case INTEGER:
         return new SqlDataTypeSpec(
             new SqlIdentifier("_UNSIGNED", POS), type.getPrecision(), -1, null, null, POS);
     }
   }
   if (type instanceof BasicSqlType) {
     return new SqlDataTypeSpec(
         new SqlIdentifier(type.getSqlTypeName().name(), POS),
         type.getPrecision(),
         type.getScale(),
         type.getCharset() != null && dialect.supportsCharSet()
             ? type.getCharset().name()
             : null,
         null,
         POS);
   }
   throw new AssertionError(type); // TODO: implement
 }
コード例 #3
0
ファイル: ReturnTypes.java プロジェクト: richwhitjr/optiq
        /** @pre SqlTypeUtil.sameNamedType(argTypes[0], (argTypes[1])) */
        public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
          final RelDataType argType0 = opBinding.getOperandType(0);
          final RelDataType argType1 = opBinding.getOperandType(1);
          if (!(SqlTypeUtil.inCharOrBinaryFamilies(argType0)
              && SqlTypeUtil.inCharOrBinaryFamilies(argType1))) {
            Util.pre(
                SqlTypeUtil.sameNamedType(argType0, argType1),
                "SqlTypeUtil.sameNamedType(argTypes[0], argTypes[1])");
          }
          SqlCollation pickedCollation = null;
          if (SqlTypeUtil.inCharFamily(argType0)) {
            if (!SqlTypeUtil.isCharTypeComparable(opBinding.collectOperandTypes().subList(0, 2))) {
              throw opBinding.newError(
                  RESOURCE.typeNotComparable(
                      argType0.getFullTypeString(), argType1.getFullTypeString()));
            }

            pickedCollation =
                SqlCollation.getCoercibilityDyadicOperator(
                    argType0.getCollation(), argType1.getCollation());
            assert null != pickedCollation;
          }

          // Determine whether result is variable-length
          SqlTypeName typeName = argType0.getSqlTypeName();
          if (SqlTypeUtil.isBoundedVariableWidth(argType1)) {
            typeName = argType1.getSqlTypeName();
          }

          RelDataType ret;
          ret =
              opBinding
                  .getTypeFactory()
                  .createSqlType(typeName, argType0.getPrecision() + argType1.getPrecision());
          if (null != pickedCollation) {
            RelDataType pickedType;
            if (argType0.getCollation().equals(pickedCollation)) {
              pickedType = argType0;
            } else if (argType1.getCollation().equals(pickedCollation)) {
              pickedType = argType1;
            } else {
              throw Util.newInternal("should never come here");
            }
            ret =
                opBinding
                    .getTypeFactory()
                    .createTypeWithCharsetAndCollation(
                        ret, pickedType.getCharset(), pickedType.getCollation());
          }
          return ret;
        }
コード例 #4
0
ファイル: SqlValidatorUtil.java プロジェクト: jacques-n/optiq
 public static void checkCharsetAndCollateConsistentIfCharType(RelDataType type) {
   // (every charset must have a default collation)
   if (SqlTypeUtil.inCharFamily(type)) {
     Charset strCharset = type.getCharset();
     Charset colCharset = type.getCollation().getCharset();
     assert null != strCharset;
     assert null != colCharset;
     if (!strCharset.equals(colCharset)) {
       if (false) {
         // todo: enable this checking when we have a charset to
         //   collation mapping
         throw new Error(
             type.toString()
                 + " was found to have charset '"
                 + strCharset.name()
                 + "' and a mismatched collation charset '"
                 + colCharset.name()
                 + "'");
       }
     }
   }
 }