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

com.aliyun.odps.jdbc.utils.JdbcColumn 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.aliyun.odps.jdbc.utils;

import java.sql.DatabaseMetaData;
import java.sql.SQLException;
import java.sql.Types;
import java.util.HashMap;
import java.util.Map;

import com.aliyun.odps.OdpsType;
import com.aliyun.odps.data.OdpsTypeTransformer;
import com.aliyun.odps.type.CharTypeInfo;
import com.aliyun.odps.type.DecimalTypeInfo;
import com.aliyun.odps.type.SimplePrimitiveTypeInfo;
import com.aliyun.odps.type.TypeInfo;
import com.aliyun.odps.type.VarcharTypeInfo;

/**
 * Wrap around column attributes in this class so that we can display getColumns() easily.
 */
public class JdbcColumn {

  public static final String ODPS_TIMESTAMP_FORMAT = "yyyy-MM-dd HH:mm:ss.SSSSSSSSS";
  public static final String ODPS_DATETIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
  public static final String ODPS_DATE_FORMAT = "yyyy-MM-dd";
  public static final String ODPS_TIME_FORMAT = "HH:mm:ss";
  public static final int ODPS_DECIMAL_PRECISON = 54;
  public static final int ODPS_DECIMAL_SCALE = 18;
  public static final int ODPS_STRING_CHARACTERS = 8 * 1024 * 1024 / 3;
  private static Map ODPS_SQLTYPE_MAPPER = new HashMap<>();

  static {
    ODPS_SQLTYPE_MAPPER.put(OdpsType.VOID, java.sql.Types.NULL);
    ODPS_SQLTYPE_MAPPER.put(OdpsType.BIGINT, java.sql.Types.BIGINT);
    ODPS_SQLTYPE_MAPPER.put(OdpsType.STRING, java.sql.Types.VARCHAR);
    ODPS_SQLTYPE_MAPPER.put(OdpsType.DATETIME, java.sql.Types.TIMESTAMP);
    ODPS_SQLTYPE_MAPPER.put(OdpsType.DOUBLE, java.sql.Types.DOUBLE);
    ODPS_SQLTYPE_MAPPER.put(OdpsType.BOOLEAN, java.sql.Types.BOOLEAN);
    ODPS_SQLTYPE_MAPPER.put(OdpsType.DECIMAL, java.sql.Types.DECIMAL);
    ODPS_SQLTYPE_MAPPER.put(OdpsType.ARRAY, java.sql.Types.ARRAY);
    ODPS_SQLTYPE_MAPPER.put(OdpsType.MAP, java.sql.Types.JAVA_OBJECT);
    ODPS_SQLTYPE_MAPPER.put(OdpsType.STRUCT, java.sql.Types.STRUCT);
    ODPS_SQLTYPE_MAPPER.put(OdpsType.INT, java.sql.Types.INTEGER);
    ODPS_SQLTYPE_MAPPER.put(OdpsType.TINYINT, java.sql.Types.TINYINT);
    ODPS_SQLTYPE_MAPPER.put(OdpsType.SMALLINT, java.sql.Types.SMALLINT);
    ODPS_SQLTYPE_MAPPER.put(OdpsType.DATE, java.sql.Types.DATE);
    ODPS_SQLTYPE_MAPPER.put(OdpsType.TIMESTAMP, java.sql.Types.TIMESTAMP);
    ODPS_SQLTYPE_MAPPER.put(OdpsType.TIMESTAMP_NTZ, java.sql.Types.TIMESTAMP);
    ODPS_SQLTYPE_MAPPER.put(OdpsType.FLOAT, java.sql.Types.FLOAT);
    ODPS_SQLTYPE_MAPPER.put(OdpsType.CHAR, java.sql.Types.CHAR);
    ODPS_SQLTYPE_MAPPER.put(OdpsType.BINARY, java.sql.Types.BINARY);
    ODPS_SQLTYPE_MAPPER.put(OdpsType.VARCHAR, java.sql.Types.VARCHAR);
    ODPS_SQLTYPE_MAPPER.put(OdpsType.INTERVAL_YEAR_MONTH, java.sql.Types.OTHER);
    ODPS_SQLTYPE_MAPPER.put(OdpsType.INTERVAL_DAY_TIME, java.sql.Types.OTHER);
    ODPS_SQLTYPE_MAPPER.put(OdpsType.JSON, Types.VARCHAR);
  }

  private final String columnName;
  private final String tableName;
  private final String tableSchema;
  private final OdpsType type;
  private final String comment;
  private final int ordinalPos;
  private final TypeInfo typeInfo;

  public JdbcColumn(String columnName, String tableName, String tableSchema, OdpsType type,
                    TypeInfo typeInfo, String comment, int ordinalPos) {
    this.columnName = columnName;
    this.tableName = tableName;
    this.tableSchema = tableSchema;
    this.type = type;
    this.typeInfo = typeInfo;
    this.comment = comment;
    this.ordinalPos = ordinalPos;
  }


  public static int odpsTypeToSqlType(OdpsType type) throws SQLException {
    if (ODPS_SQLTYPE_MAPPER.containsKey(type)) {
      return ODPS_SQLTYPE_MAPPER.get(type);
    }
    throw new SQLException("Invalid odps type: " + type);
  }

  public static String columnClassName(OdpsType type) throws SQLException {
    return OdpsTypeTransformer.odpsTypeToJavaType(type).getName();
  }

  public static int columnDisplaySize(TypeInfo typeInfo) throws SQLException {
    // according to odpsTypeToSqlType possible options are:
    int columnType = odpsTypeToSqlType(typeInfo.getOdpsType());
    switch (columnType) {
      case Types.NULL:
        return 4; // "NULL"
      case Types.BOOLEAN:
        return columnPrecision(typeInfo);
      case Types.CHAR:
      case Types.VARCHAR:
        return columnPrecision(typeInfo);
      case Types.BINARY:
        return Integer.MAX_VALUE; // hive has no max limit for binary
      case Types.TINYINT:
      case Types.SMALLINT:
      case Types.INTEGER:
      case Types.BIGINT:
        return columnPrecision(typeInfo) + 1; // allow +/-
      case Types.DATE:
        return 10;
      case Types.TIMESTAMP:
        return columnPrecision(typeInfo);
      // see
      // http://download.oracle.com/javase/6/docs/api/constant-values.html#java.lang.Float.MAX_EXPONENT
      case Types.FLOAT:
        return 24; // e.g. -(17#).e-###
      // see
      // http://download.oracle.com/javase/6/docs/api/constant-values.html#java.lang.Double.MAX_EXPONENT
      case Types.DOUBLE:
        return 25; // e.g. -(17#).e-####
      case Types.DECIMAL:
        return columnPrecision(typeInfo) + 2; // '-' sign and '.'
      case Types.OTHER:
      case Types.JAVA_OBJECT:
        return columnPrecision(typeInfo);
      case Types.ARRAY:
      case Types.STRUCT:
        return Integer.MAX_VALUE;
      default:
        throw new SQLException("Invalid odps type: " + columnType);
    }
  }

  public static int columnPrecision(TypeInfo typeInfo) throws SQLException {
    int columnType = odpsTypeToSqlType(typeInfo.getOdpsType());
    // according to odpsTypeToSqlType possible options are:
    switch (columnType) {
      case Types.NULL:
        return 0;
      case Types.BOOLEAN:
        return 1;
      case Types.CHAR:
      case Types.VARCHAR:
        if (typeInfo instanceof VarcharTypeInfo) {
          return ((VarcharTypeInfo) typeInfo).getLength();
        }
        if (typeInfo instanceof CharTypeInfo) {
          return ((CharTypeInfo) typeInfo).getLength();
        }
        return Integer.MAX_VALUE; // hive has no max limit for strings
      case Types.BINARY:
        return Integer.MAX_VALUE; // hive has no max limit for binary
      case Types.TINYINT:
        return 3;
      case Types.SMALLINT:
        return 5;
      case Types.INTEGER:
        return 10;
      case Types.BIGINT:
        return 19;
      case Types.FLOAT:
        return 7;
      case Types.DOUBLE:
        return 15;
      case Types.DATE:
        return 10;
      case Types.TIMESTAMP:
        return 29;
      case Types.DECIMAL:
        return ((DecimalTypeInfo) typeInfo).getPrecision();
      case Types.OTHER:
      case Types.JAVA_OBJECT: {
        if (typeInfo instanceof SimplePrimitiveTypeInfo) {
          SimplePrimitiveTypeInfo spti = (SimplePrimitiveTypeInfo) typeInfo;
          if (OdpsType.INTERVAL_YEAR_MONTH.equals(spti.getOdpsType())) {
            // -yyyyyyy-mm : should be more than enough
            return 11;
          } else if (OdpsType.INTERVAL_DAY_TIME.equals(spti.getOdpsType())) {
            // -ddddddddd hh:mm:ss.nnnnnnnnn
            return 29;
          }
        }
        return Integer.MAX_VALUE;
      }
      case Types.ARRAY:
      case Types.STRUCT:
        return Integer.MAX_VALUE;
      default:
        throw new SQLException("Invalid odps type: " + columnType);
    }
  }

  public static int columnScale(OdpsType type, TypeInfo typeInfo) throws SQLException {
    int columnType = odpsTypeToSqlType(type);
    // according to odpsTypeToSqlType possible options are:
    switch (columnType) {
      case Types.NULL:
      case Types.BOOLEAN:
      case Types.CHAR:
      case Types.VARCHAR:
      case Types.TINYINT:
      case Types.SMALLINT:
      case Types.INTEGER:
      case Types.BIGINT:
      case Types.DATE:
      case Types.BINARY:
        return 0;
      case Types.FLOAT:
        return 7;
      case Types.DOUBLE:
        return 15;
      case Types.TIMESTAMP:
        return 9;
      case Types.DECIMAL:
        return ((DecimalTypeInfo) typeInfo).getScale();
      case Types.OTHER:
      case Types.JAVA_OBJECT:
      case Types.ARRAY:
      case Types.STRUCT:
        return 0;
      default:
        throw new SQLException("Invalid odps type: " + columnType);
    }
  }

  public static boolean columnCaseSensitive(OdpsType type) throws SQLException {
    int columnType = odpsTypeToSqlType(type);
    // according to odpsTypeToSqlType possible options are:
    switch (columnType) {
      case Types.NULL:
      case Types.BOOLEAN:
      case Types.TINYINT:
      case Types.SMALLINT:
      case Types.INTEGER:
      case Types.BIGINT:
      case Types.DATE:
      case Types.BINARY:
      case Types.FLOAT:
      case Types.DOUBLE:
      case Types.TIMESTAMP:
      case Types.DECIMAL:
      case Types.OTHER:
      case Types.JAVA_OBJECT:
      case Types.ARRAY:
      case Types.STRUCT:
        return false;
      case Types.CHAR:
      case Types.VARCHAR:
        return true;
      default:
        throw new SQLException("Invalid odps type: " + columnType);
    }
  }

  public static boolean columnSigned(OdpsType type) throws SQLException {
    int columnType = odpsTypeToSqlType(type);
    // according to odpsTypeToSqlType possible options are:
    switch (columnType) {
      case Types.NULL:
      case Types.BOOLEAN:
      case Types.DATE:
      case Types.BINARY:
      case Types.TIMESTAMP:
      case Types.OTHER:
      case Types.JAVA_OBJECT:
      case Types.ARRAY:
      case Types.STRUCT:
      case Types.CHAR:
      case Types.VARCHAR:
        return false;
      case Types.TINYINT:
      case Types.SMALLINT:
      case Types.INTEGER:
      case Types.BIGINT:
      case Types.FLOAT:
      case Types.DOUBLE:
      case Types.DECIMAL:
        return true;
      default:
        throw new SQLException("unknown OdpsType");
    }
  }

  public String getColumnName() {
    return columnName;
  }

  public String getTableName() {
    return tableName;
  }

  public String getTableSchema() {
    return tableSchema;
  }

  public int getType() throws SQLException {
    return odpsTypeToSqlType(type);
  }

  public String getComment() {
    return comment;
  }

  public String getTypeName() {
    return typeInfo.getTypeName();
  }

  public int getOrdinalPos() {
    return ordinalPos;
  }

  public int getNumPercRaidx() {
    return 10;
  }

  public int getIsNullable() {
    return DatabaseMetaData.columnNullable;
  }

  public String getIsNullableString() {
    switch (getIsNullable()) {
      case (DatabaseMetaData.columnNoNulls):
        return "NO";
      case (DatabaseMetaData.columnNullable):
        return "YES";
      case (DatabaseMetaData.columnNullableUnknown):
        return null;
      default:
        return null;
    }
  }

  public int getDecimalDigits() {
    return 0;
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy