Search in sources :

Example 1 with JdbcTypeHandle

use of io.prestosql.plugin.jdbc.JdbcTypeHandle in project hetu-core by openlookeng.

the class MySqlClient method getColumns.

@SuppressWarnings("SQL_PREPARED_STATEMENT_GENERATED_FROM_NONCONSTANT_STRING")
@Override
public Map<String, ColumnHandle> getColumns(ConnectorSession session, String sql, Map<String, Type> types) {
    try (Connection connection = connectionFactory.openConnection(JdbcIdentity.from(session));
        PreparedStatement statement = connection.prepareStatement(sql)) {
        ResultSetMetaData metaData = statement.getMetaData();
        ImmutableMap.Builder<String, ColumnHandle> columnBuilder = new ImmutableMap.Builder<>();
        for (int i = 1; i <= metaData.getColumnCount(); i++) {
            String columnName = metaData.getColumnLabel(i);
            String typeName = metaData.getColumnTypeName(i);
            int precision = metaData.getPrecision(i);
            int dataType = metaData.getColumnType(i);
            int scale = metaData.getScale(i);
            // extracted from logical plan during pre-processing
            if (dataType == Types.DECIMAL && (precision > MAX_PRECISION || scale < 0)) {
                // Covert MySql Decimal type to Presto type
                Type type = types.get(columnName.toLowerCase(ENGLISH));
                if (type instanceof AbstractType) {
                    TypeSignature signature = type.getTypeSignature();
                    typeName = signature.getBase().toUpperCase(ENGLISH);
                    dataType = JDBCType.valueOf(typeName).getVendorTypeNumber();
                    if (type instanceof DecimalType) {
                        precision = ((DecimalType) type).getPrecision();
                        scale = ((DecimalType) type).getScale();
                    }
                }
            }
            boolean isNullable = metaData.isNullable(i) != ResultSetMetaData.columnNoNulls;
            JdbcTypeHandle typeHandle = new JdbcTypeHandle(dataType, Optional.ofNullable(typeName), precision, scale, Optional.empty());
            Optional<ColumnMapping> columnMapping;
            try {
                columnMapping = toPrestoType(session, connection, typeHandle);
            } catch (UnsupportedOperationException ex) {
                throw new PrestoException(JDBC_UNSUPPORTED_EXPRESSION, format("Data type [%s] is not support", typeHandle.getJdbcTypeName()));
            }
            // skip unsupported column types
            if (columnMapping.isPresent()) {
                Type type = columnMapping.get().getType();
                JdbcColumnHandle handle = new JdbcColumnHandle(columnName, typeHandle, type, isNullable);
                columnBuilder.put(columnName.toLowerCase(ENGLISH), handle);
            } else {
                return Collections.emptyMap();
            }
        }
        return columnBuilder.build();
    } catch (SQLException | PrestoException e) {
        throw new PrestoException(JDBC_QUERY_GENERATOR_FAILURE, String.format("Query generator failed for [%s]", e.getMessage()));
    }
}
Also used : JdbcColumnHandle(io.prestosql.plugin.jdbc.JdbcColumnHandle) ColumnHandle(io.prestosql.spi.connector.ColumnHandle) SQLException(java.sql.SQLException) Connection(java.sql.Connection) JdbcColumnHandle(io.prestosql.plugin.jdbc.JdbcColumnHandle) PreparedStatement(java.sql.PreparedStatement) PrestoException(io.prestosql.spi.PrestoException) ImmutableMap(com.google.common.collect.ImmutableMap) ResultSetMetaData(java.sql.ResultSetMetaData) Varchars.isVarcharType(io.prestosql.spi.type.Varchars.isVarcharType) DecimalType(io.prestosql.spi.type.DecimalType) Type(io.prestosql.spi.type.Type) AbstractType(io.prestosql.spi.type.AbstractType) JDBCType(java.sql.JDBCType) VarcharType(io.prestosql.spi.type.VarcharType) TypeSignature(io.prestosql.spi.type.TypeSignature) JdbcTypeHandle(io.prestosql.plugin.jdbc.JdbcTypeHandle) AbstractType(io.prestosql.spi.type.AbstractType) DecimalType(io.prestosql.spi.type.DecimalType) ColumnMapping(io.prestosql.plugin.jdbc.ColumnMapping)

Example 2 with JdbcTypeHandle

use of io.prestosql.plugin.jdbc.JdbcTypeHandle in project hetu-core by openlookeng.

the class GreenPlumSqlClient method toPrestoType.

@Override
public Optional<ColumnMapping> toPrestoType(ConnectorSession session, Connection connection, JdbcTypeHandle typeHandle) {
    String jdbcTypeName = typeHandle.getJdbcTypeName().orElseThrow(() -> new PrestoException(JDBC_ERROR, "Type name is missing: " + typeHandle));
    switch(jdbcTypeName) {
        case "uuid":
            return Optional.of(uuidColumnMapping());
        case "jsonb":
        case "json":
            return Optional.of(jsonColumnMapping());
        case "timestamptz":
            // PostgreSQL's "timestamp with time zone" is reported as Types.TIMESTAMP rather than Types.TIMESTAMP_WITH_TIMEZONE
            return Optional.of(timestampWithTimeZoneColumnMapping());
        default:
            break;
    }
    if (typeHandle.getJdbcType() == Types.VARCHAR && !jdbcTypeName.equals("varchar")) {
        // This can be e.g. an ENUM
        return Optional.of(typedVarcharColumnMapping(jdbcTypeName));
    }
    if (typeHandle.getJdbcType() == Types.TIMESTAMP) {
        return Optional.of(timestampColumnMapping());
    }
    if (typeHandle.getJdbcType() == Types.ARRAY && supportArrays) {
        if (!typeHandle.getArrayDimensions().isPresent()) {
            return Optional.empty();
        }
        JdbcTypeHandle elementTypeHandle = getArrayElementTypeHandle(connection, typeHandle);
        String elementTypeName = typeHandle.getJdbcTypeName().orElseThrow(() -> new PrestoException(JDBC_ERROR, "Element type name is missing: " + elementTypeHandle));
        if (elementTypeHandle.getJdbcType() == Types.VARBINARY) {
            // https://github.com/pgjdbc/pgjdbc/pull/1184
            return Optional.empty();
        }
        return toPrestoType(session, connection, elementTypeHandle).map(elementMapping -> {
            ArrayType prestoArrayType = new ArrayType(elementMapping.getType());
            int arrayDimensions = typeHandle.getArrayDimensions().get();
            for (int i = 1; i < arrayDimensions; i++) {
                prestoArrayType = new ArrayType(prestoArrayType);
            }
            return arrayColumnMapping(session, prestoArrayType, elementTypeName);
        });
    }
    // in the scenario of push down, we will verify the type correctness in our query push down
    return super.toPrestoType(session, connection, typeHandle);
}
Also used : ArrayType(io.prestosql.spi.type.ArrayType) JdbcTypeHandle(io.prestosql.plugin.jdbc.JdbcTypeHandle) PrestoException(io.prestosql.spi.PrestoException)

Example 3 with JdbcTypeHandle

use of io.prestosql.plugin.jdbc.JdbcTypeHandle in project hetu-core by openlookeng.

the class GreenPlumSqlClient method getArrayElementTypeHandle.

private JdbcTypeHandle getArrayElementTypeHandle(Connection connection, JdbcTypeHandle arrayTypeHandle) {
    String jdbcTypeName = arrayTypeHandle.getJdbcTypeName().orElseThrow(() -> new PrestoException(JDBC_ERROR, "Type name is missing: " + arrayTypeHandle));
    try {
        TypeInfo typeInfo = connection.unwrap(PgConnection.class).getTypeInfo();
        int pgElementOid = typeInfo.getPGArrayElement(typeInfo.getPGType(jdbcTypeName));
        return new JdbcTypeHandle(typeInfo.getSQLType(pgElementOid), Optional.of(typeInfo.getPGType(pgElementOid)), arrayTypeHandle.getColumnSize(), arrayTypeHandle.getDecimalDigits(), arrayTypeHandle.getArrayDimensions());
    } catch (SQLException e) {
        throw new PrestoException(JDBC_ERROR, e);
    }
}
Also used : JdbcTypeHandle(io.prestosql.plugin.jdbc.JdbcTypeHandle) SQLException(java.sql.SQLException) PgConnection(org.postgresql.jdbc.PgConnection) PrestoException(io.prestosql.spi.PrestoException) TypeInfo(org.postgresql.core.TypeInfo)

Example 4 with JdbcTypeHandle

use of io.prestosql.plugin.jdbc.JdbcTypeHandle in project hetu-core by openlookeng.

the class GreenPlumSqlClient method getColumns.

@Override
public List<JdbcColumnHandle> getColumns(ConnectorSession session, JdbcTableHandle tableHandle) {
    try (Connection connection = connectionFactory.openConnection(JdbcIdentity.from(session))) {
        Map<String, Integer> arrayColumnDimensions = getArrayColumnDimensions(connection, tableHandle);
        try (ResultSet resultSet = getColumns(tableHandle, connection.getMetaData())) {
            List<JdbcColumnHandle> columns = new ArrayList<>();
            while (resultSet.next()) {
                String columnName = resultSet.getString("COLUMN_NAME");
                JdbcTypeHandle typeHandle = new JdbcTypeHandle(resultSet.getInt("DATA_TYPE"), Optional.of(resultSet.getString("TYPE_NAME")), resultSet.getInt("COLUMN_SIZE"), resultSet.getInt("DECIMAL_DIGITS"), Optional.ofNullable(arrayColumnDimensions.get(columnName)));
                Optional<ColumnMapping> columnMapping = toPrestoType(session, connection, typeHandle);
                // skip unsupported column types
                if (columnMapping.isPresent()) {
                    boolean nullable = (resultSet.getInt("NULLABLE") != columnNoNulls);
                    columns.add(new JdbcColumnHandle(columnName, typeHandle, columnMapping.get().getType(), nullable));
                }
            }
            if (columns.isEmpty()) {
                // In rare cases a table might have no columns.
                throw new TableNotFoundException(tableHandle.getSchemaTableName());
            }
            return ImmutableList.copyOf(columns);
        }
    } catch (SQLException e) {
        throw new PrestoException(JDBC_ERROR, e);
    }
}
Also used : SQLException(java.sql.SQLException) Connection(java.sql.Connection) PgConnection(org.postgresql.jdbc.PgConnection) JdbcColumnHandle(io.prestosql.plugin.jdbc.JdbcColumnHandle) ArrayList(java.util.ArrayList) PrestoException(io.prestosql.spi.PrestoException) TableNotFoundException(io.prestosql.spi.connector.TableNotFoundException) JdbcTypeHandle(io.prestosql.plugin.jdbc.JdbcTypeHandle) ResultSet(java.sql.ResultSet) StandardColumnMappings.timestampColumnMapping(io.prestosql.plugin.jdbc.StandardColumnMappings.timestampColumnMapping) ColumnMapping(io.prestosql.plugin.jdbc.ColumnMapping)

Example 5 with JdbcTypeHandle

use of io.prestosql.plugin.jdbc.JdbcTypeHandle in project hetu-core by openlookeng.

the class OpenGaussClient method toPrestoType.

@Override
public Optional<ColumnMapping> toPrestoType(ConnectorSession session, Connection connection, JdbcTypeHandle typeHandle) {
    String jdbcTypeName = typeHandle.getJdbcTypeName().orElseThrow(() -> new PrestoException(JDBC_ERROR, "Type name is missing: " + typeHandle));
    switch(jdbcTypeName) {
        case "uuid":
            return Optional.of(uuidColumnMapping());
        case "jsonb":
        case "json":
            return Optional.of(jsonColumnMapping());
        case "timestamptz":
            // OpenGauss's "timestamp with time zone" is reported as Types.TIMESTAMP rather than Types.TIMESTAMP_WITH_TIMEZONE
            return Optional.of(timestampWithTimeZoneColumnMapping());
        default:
            break;
    }
    if (typeHandle.getJdbcType() == Types.VARCHAR && !jdbcTypeName.equals("varchar")) {
        // This can be e.g. an ENUM
        return Optional.of(typedVarcharColumnMapping(jdbcTypeName));
    }
    if (typeHandle.getJdbcType() == Types.TIMESTAMP) {
        return Optional.of(timestampColumnMappingUsingSqlTimestamp());
    }
    if (typeHandle.getJdbcType() == Types.ARRAY && supportArrays) {
        if (!typeHandle.getArrayDimensions().isPresent()) {
            return Optional.empty();
        }
        JdbcTypeHandle elementTypeHandle = getArrayElementTypeHandle(connection, typeHandle);
        String elementTypeName = typeHandle.getJdbcTypeName().orElseThrow(() -> new PrestoException(JDBC_ERROR, "Element type name is missing: " + elementTypeHandle));
        if (elementTypeHandle.getJdbcType() == Types.VARBINARY) {
            // https://github.com/pgjdbc/pgjdbc/pull/1184
            return Optional.empty();
        }
        return toPrestoType(session, connection, elementTypeHandle).map(elementMapping -> {
            ArrayType prestoArrayType = new ArrayType(elementMapping.getType());
            int arrayDimensions = typeHandle.getArrayDimensions().get();
            for (int i = 1; i < arrayDimensions; i++) {
                prestoArrayType = new ArrayType(prestoArrayType);
            }
            return arrayColumnMapping(session, prestoArrayType, elementTypeName);
        });
    }
    return super.toPrestoType(session, connection, typeHandle);
}
Also used : ArrayType(io.prestosql.spi.type.ArrayType) JdbcTypeHandle(io.prestosql.plugin.jdbc.JdbcTypeHandle) PrestoException(io.prestosql.spi.PrestoException)

Aggregations

JdbcTypeHandle (io.prestosql.plugin.jdbc.JdbcTypeHandle)13 PrestoException (io.prestosql.spi.PrestoException)12 SQLException (java.sql.SQLException)9 ColumnMapping (io.prestosql.plugin.jdbc.ColumnMapping)7 JdbcColumnHandle (io.prestosql.plugin.jdbc.JdbcColumnHandle)7 Connection (java.sql.Connection)7 ImmutableMap (com.google.common.collect.ImmutableMap)5 ColumnHandle (io.prestosql.spi.connector.ColumnHandle)5 DecimalType (io.prestosql.spi.type.DecimalType)5 Type (io.prestosql.spi.type.Type)5 PreparedStatement (java.sql.PreparedStatement)5 ResultSetMetaData (java.sql.ResultSetMetaData)5 PgConnection (org.postgresql.jdbc.PgConnection)5 ArrayType (io.prestosql.spi.type.ArrayType)4 VarcharType (io.prestosql.spi.type.VarcharType)4 SuppressFBWarnings (io.prestosql.spi.SuppressFBWarnings)3 StandardColumnMappings.bigintColumnMapping (io.prestosql.plugin.jdbc.StandardColumnMappings.bigintColumnMapping)2 StandardColumnMappings.integerColumnMapping (io.prestosql.plugin.jdbc.StandardColumnMappings.integerColumnMapping)2 StandardColumnMappings.smallintColumnMapping (io.prestosql.plugin.jdbc.StandardColumnMappings.smallintColumnMapping)2 StandardColumnMappings.timestampColumnMapping (io.prestosql.plugin.jdbc.StandardColumnMappings.timestampColumnMapping)2