Search in sources :

Example 1 with SqlType

use of org.apache.calcite.avatica.SqlType in project calcite-avatica by apache.

the class JdbcResultSet method frame.

/** Creates a frame containing a given number or unlimited number of rows
   * from a result set. */
static Meta.Frame frame(StatementInfo info, ResultSet resultSet, long offset, int fetchMaxRowCount, Calendar calendar, Optional<Meta.Signature> sig) throws SQLException {
    final ResultSetMetaData metaData = resultSet.getMetaData();
    final int columnCount = metaData.getColumnCount();
    final int[] types = new int[columnCount];
    Set<Integer> arrayOffsets = new HashSet<>();
    for (int i = 0; i < types.length; i++) {
        types[i] = metaData.getColumnType(i + 1);
        if (Types.ARRAY == types[i]) {
            arrayOffsets.add(i);
        }
    }
    final List<Object> rows = new ArrayList<>();
    // Meta prepare/prepareAndExecute 0 return 0 row and done
    boolean done = fetchMaxRowCount == 0;
    for (int i = 0; fetchMaxRowCount < 0 || i < fetchMaxRowCount; i++) {
        final boolean hasRow;
        if (null != info) {
            hasRow = info.next();
        } else {
            hasRow = resultSet.next();
        }
        if (!hasRow) {
            done = true;
            resultSet.close();
            break;
        }
        Object[] columns = new Object[columnCount];
        for (int j = 0; j < columnCount; j++) {
            columns[j] = getValue(resultSet, types[j], j, calendar);
            if (arrayOffsets.contains(j)) {
                // If we have an Array type, our Signature is lacking precision. We can't extract the
                // component type of an Array from metadata, we have to update it as we're serializing
                // the ResultSet.
                final Array array = resultSet.getArray(j + 1);
                // Only attempt to determine the component type for the array when non-null
                if (null != array && sig.isPresent()) {
                    ColumnMetaData columnMetaData = sig.get().columns.get(j);
                    ArrayType arrayType = (ArrayType) columnMetaData.type;
                    SqlType componentSqlType = SqlType.valueOf(array.getBaseType());
                    // Avatica Server will always return non-primitives to ensure nullable is guaranteed.
                    ColumnMetaData.Rep rep = ColumnMetaData.Rep.serialRepOf(componentSqlType);
                    AvaticaType componentType = ColumnMetaData.scalar(array.getBaseType(), array.getBaseTypeName(), rep);
                    // Update the ArrayType from the Signature
                    arrayType.updateComponentType(componentType);
                    // We only need to update the array's type once.
                    arrayOffsets.remove(j);
                }
            }
        }
        rows.add(columns);
    }
    return new Meta.Frame(offset, done, rows);
}
Also used : AvaticaType(org.apache.calcite.avatica.ColumnMetaData.AvaticaType) ArrayList(java.util.ArrayList) ResultSetMetaData(java.sql.ResultSetMetaData) Array(java.sql.Array) ArrayType(org.apache.calcite.avatica.ColumnMetaData.ArrayType) SqlType(org.apache.calcite.avatica.SqlType) ColumnMetaData(org.apache.calcite.avatica.ColumnMetaData) HashSet(java.util.HashSet)

Example 2 with SqlType

use of org.apache.calcite.avatica.SqlType in project calcite-avatica by apache.

the class JdbcMeta method columns.

/**
   * Converts from JDBC metadata to Avatica columns.
   */
protected static List<ColumnMetaData> columns(ResultSetMetaData metaData) throws SQLException {
    if (metaData == null) {
        return Collections.emptyList();
    }
    final List<ColumnMetaData> columns = new ArrayList<>();
    for (int i = 1; i <= metaData.getColumnCount(); i++) {
        final SqlType sqlType = SqlType.valueOf(metaData.getColumnType(i));
        final ColumnMetaData.Rep rep = ColumnMetaData.Rep.of(sqlType.internal);
        final ColumnMetaData.AvaticaType t;
        if (sqlType == SqlType.ARRAY || sqlType == SqlType.STRUCT || sqlType == SqlType.MULTISET) {
            ColumnMetaData.AvaticaType arrayValueType = ColumnMetaData.scalar(Types.JAVA_OBJECT, metaData.getColumnTypeName(i), ColumnMetaData.Rep.OBJECT);
            t = ColumnMetaData.array(arrayValueType, metaData.getColumnTypeName(i), rep);
        } else {
            t = ColumnMetaData.scalar(metaData.getColumnType(i), metaData.getColumnTypeName(i), rep);
        }
        ColumnMetaData md = new ColumnMetaData(i - 1, metaData.isAutoIncrement(i), metaData.isCaseSensitive(i), metaData.isSearchable(i), metaData.isCurrency(i), metaData.isNullable(i), metaData.isSigned(i), metaData.getColumnDisplaySize(i), metaData.getColumnLabel(i), metaData.getColumnName(i), metaData.getSchemaName(i), metaData.getPrecision(i), metaData.getScale(i), metaData.getTableName(i), metaData.getCatalogName(i), t, metaData.isReadOnly(i), metaData.isWritable(i), metaData.isDefinitelyWritable(i), metaData.getColumnClassName(i));
        columns.add(md);
    }
    return columns;
}
Also used : ArrayList(java.util.ArrayList) SqlType(org.apache.calcite.avatica.SqlType) ColumnMetaData(org.apache.calcite.avatica.ColumnMetaData)

Example 3 with SqlType

use of org.apache.calcite.avatica.SqlType in project calcite-avatica by apache.

the class TypedValue method ofJdbc.

/** Creates a TypedValue from a value in JDBC representation. */
public static TypedValue ofJdbc(ColumnMetaData.Rep rep, Object value, Calendar calendar) {
    if (value == null) {
        return EXPLICIT_NULL;
    }
    final Object serialValue;
    if (ColumnMetaData.Rep.ARRAY == rep) {
        // Sanity check that we were given an Array
        if (null != value && !(value instanceof Array)) {
            throw new IllegalArgumentException("Provided Rep was ARRAY, but the value was " + value.getClass());
        }
        final Array array = (Array) value;
        try {
            SqlType type = SqlType.valueOf(array.getBaseType());
            serialValue = jdbcToSerial(rep, array, calendar, type);
            // variants of the array values.
            return new TypedValue(rep, Rep.nonPrimitiveRepOf(type), serialValue);
        } catch (SQLException e) {
            throw new RuntimeException("Could not extract Array component type", e);
        }
    } else {
        serialValue = jdbcToSerial(rep, value, calendar);
    }
    return new TypedValue(rep, serialValue);
}
Also used : Array(java.sql.Array) SQLException(java.sql.SQLException) SqlType(org.apache.calcite.avatica.SqlType)

Aggregations

SqlType (org.apache.calcite.avatica.SqlType)3 Array (java.sql.Array)2 ArrayList (java.util.ArrayList)2 ColumnMetaData (org.apache.calcite.avatica.ColumnMetaData)2 ResultSetMetaData (java.sql.ResultSetMetaData)1 SQLException (java.sql.SQLException)1 HashSet (java.util.HashSet)1 ArrayType (org.apache.calcite.avatica.ColumnMetaData.ArrayType)1 AvaticaType (org.apache.calcite.avatica.ColumnMetaData.AvaticaType)1