org.apache.calcite.avatica.ColumnMetaData.AvaticaType Java Examples

The following examples show how to use org.apache.calcite.avatica.ColumnMetaData.AvaticaType. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: ArrayTypeTest.java    From calcite-avatica with Apache License 2.0 6 votes vote down vote up
/**
 * Creates a JDBC {@link Array} from a list of values.
 *
 * @param typeName the SQL type name of the elements in the array
 * @param componentType The Avatica type for the array elements
 * @param arrayValues The array elements
 * @return An Array instance for the given component and values
 */
@SuppressWarnings("unchecked")
private <T> Array createArray(String typeName, AvaticaType componentType, List<T> arrayValues) {
  // Make a "row" with one "column" (which is really a list)
  final List<Object> oneRow = Collections.singletonList((Object) arrayValues);
  // Make an iterator over this one "row"
  final Iterator<List<Object>> rowIterator = Collections.singletonList(oneRow).iterator();

  ArrayType array = ColumnMetaData.array(componentType, typeName, Rep.ARRAY);
  try (ListIteratorCursor cursor = new ListIteratorCursor(rowIterator)) {
    List<ColumnMetaData> types = Collections.singletonList(ColumnMetaData.dummy(array, true));
    Calendar calendar = Unsafe.localCalendar();
    List<Accessor> accessors = cursor.createAccessors(types, calendar, null);
    assertTrue("Expected at least one accessor, found " + accessors.size(),
        !accessors.isEmpty());
    ArrayAccessor arrayAccessor = (ArrayAccessor) accessors.get(0);

    return new ArrayImpl((List<Object>) arrayValues, arrayAccessor);
  }
}
 
Example #2
Source File: AvaticaConnection.java    From calcite-avatica with Apache License 2.0 6 votes vote down vote up
public Array createArrayOf(String typeName, Object[] elements) throws SQLException {
  checkOpen();
  @SuppressWarnings("unchecked")
  List<Object> elementList = (List<Object>) AvaticaUtils.primitiveList(elements);
  SqlType type;
  try {
    type = SqlType.valueOf(typeName);
  } catch (IllegalArgumentException e) {
    throw new SQLException("Could not find JDBC type for '" + typeName + "'");
  }
  AvaticaType avaticaType = null;
  switch (type) {
  case ARRAY:
    // TODO: Nested ARRAYs
    throw HELPER.createException("Cannot create an ARRAY of ARRAY's");
  case STRUCT:
    // TODO: ARRAYs of STRUCTs
    throw HELPER.createException("Cannot create an ARRAY of STRUCT's");
  default:
    // This is an ARRAY, we need to use Objects, not primitives (nullable).
    avaticaType = ColumnMetaData.scalar(type.id, typeName, Rep.nonPrimitiveRepOf(type));
  }
  ArrayFactoryImpl arrayFactory = new ArrayFactoryImpl(getTimeZone());
  return arrayFactory.createArray(avaticaType, elementList);
}
 
Example #3
Source File: ArrayFactoryImpl.java    From calcite-avatica with Apache License 2.0 6 votes vote down vote up
@Override public ResultSet create(AvaticaType elementType, Iterable<Object> elements)
    throws SQLException {
  // The ColumnMetaData for offset "1" in the ResultSet for an Array.
  ScalarType arrayOffsetType = ColumnMetaData.scalar(Types.INTEGER, "INTEGER", Rep.PRIMITIVE_INT);
  // Two columns (types) in the ResultSet we will create
  List<ColumnMetaData> types = Arrays.asList(ColumnMetaData.dummy(arrayOffsetType, false),
      ColumnMetaData.dummy(elementType, true));
  List<List<Object>> rows = createResultSetRowsForArrayData(elements);
  // `(List<Object>) rows` is a compile error.
  @SuppressWarnings({ "unchecked", "rawtypes" })
  List<Object> untypedRows = (List<Object>) ((List) rows);
  try (ListIteratorCursor cursor = new ListIteratorCursor(rows.iterator())) {
    final String sql = "MOCKED";
    QueryState state = new QueryState(sql);
    Meta.Signature signature = new Meta.Signature(types, sql,
        Collections.<AvaticaParameter>emptyList(), Collections.<String, Object>emptyMap(),
        Meta.CursorFactory.LIST, Meta.StatementType.SELECT);
    AvaticaResultSetMetaData resultSetMetaData = new AvaticaResultSetMetaData(null, sql,
        signature);
    Meta.Frame frame = new Meta.Frame(0, true, untypedRows);
    AvaticaResultSet resultSet = new AvaticaResultSet(null, state, signature, resultSetMetaData,
        timeZone, frame);
    resultSet.execute2(cursor, types);
    return resultSet;
  }
}
 
Example #4
Source File: ArrayFactoryImpl.java    From calcite-avatica with Apache License 2.0 6 votes vote down vote up
@Override public Array createArray(AvaticaType elementType, Iterable<Object> elements) {
  final ArrayType array = ColumnMetaData.array(elementType, elementType.name, Rep.ARRAY);
  final List<ColumnMetaData> types = Collections.singletonList(ColumnMetaData.dummy(array, true));
  // Avoid creating a new List if we already have a List
  List<Object> elementList;
  if (elements instanceof List) {
    elementList = (List<Object>) elements;
  } else {
    elementList = new ArrayList<>();
    for (Object element : elements) {
      elementList.add(element);
    }
  }
  try (ListIteratorCursor cursor = new ListIteratorCursor(createRowForArrayData(elementList))) {
    List<Accessor> accessor = cursor.createAccessors(types, Unsafe.localCalendar(), this);
    assert 1 == accessor.size();
    return new ArrayImpl(elementList, (ArrayAccessor) accessor.get(0));
  }
}
 
Example #5
Source File: ArrayTypeTest.java    From calcite-avatica with Apache License 2.0 5 votes vote down vote up
@Test public void testCreateArrayOf() throws Exception {
  try (Connection conn = DriverManager.getConnection(url)) {
    final String componentName = SqlType.INTEGER.name();
    Array a1 = conn.createArrayOf(componentName, new Object[] {1, 2, 3, 4, 5});
    Array a2 = conn.createArrayOf(componentName, new Object[] {2, 3, 4, 5, 6});
    Array a3 = conn.createArrayOf(componentName, new Object[] {3, 4, 5, 6, 7});
    AvaticaType arrayType = ColumnMetaData.array(
        ColumnMetaData.scalar(Types.INTEGER, componentName, Rep.INTEGER), "NUMBERS", Rep.ARRAY);
    writeAndReadArrays(conn, "CREATE_ARRAY_OF_INTEGERS", componentName, arrayType,
        Arrays.asList(a1, a2, a3), PRIMITIVE_LIST_VALIDATOR);
  }
}
 
Example #6
Source File: MetaImpl.java    From calcite-avatica with Apache License 2.0 5 votes vote down vote up
public static ColumnMetaData columnMetaData(String name, int index,
    Class<?> type, int columnNullable) {
  TypeInfo pair = TypeInfo.m.get(type);
  ColumnMetaData.Rep rep =
      ColumnMetaData.Rep.VALUE_MAP.get(type);
  ColumnMetaData.AvaticaType scalarType =
      ColumnMetaData.scalar(pair.sqlType, pair.sqlTypeName, rep);
  return columnMetaData(name, index, scalarType, columnNullable);
}
 
Example #7
Source File: MetaImpl.java    From calcite-avatica with Apache License 2.0 5 votes vote down vote up
public static ColumnMetaData columnMetaData(String name, int index, AvaticaType type,
    int columnNullable) {
  return new ColumnMetaData(
      index, false, true, false, false,
      columnNullable,
      true, -1, name, name, null,
      0, 0, null, null, type, true, false, false,
      type.columnClassName());
}
 
Example #8
Source File: DremioColumnMetaDataList.java    From dremio-oss with Apache License 2.0 5 votes vote down vote up
/**
 * Update the metadata with given metadata received from server.
 * @param metadata
 */
public void updateColumnMetaData(List<ResultColumnMetadata> metadata) {
  final List<ColumnMetaData> newColumns = new ArrayList<>(metadata.size());
  int offset = 0;
  for(ResultColumnMetadata m : metadata) {

    final AvaticaType bundledSqlDataType = getAvaticaType(m.getDataType());

    newColumns.add(new ColumnMetaData(
        offset,
        m.getAutoIncrement(),
        m.getCaseSensitivity(),
        m.getSearchability() != ColumnSearchability.NONE,
        m.getIsCurrency(),
        m.getIsNullable() ? ResultSetMetaData.columnNullable : ResultSetMetaData.columnNoNulls,
        m.getSigned(),
        m.getDisplaySize(),
        m.getLabel(),
        m.getColumnName(),
        m.getSchemaName(),
        m.getPrecision(),
        m.getScale(),
        m.getTableName(),
        m.getCatalogName(),
        bundledSqlDataType,
        m.getUpdatability() == ColumnUpdatability.READ_ONLY,
        m.getUpdatability() == ColumnUpdatability.WRITABLE,
        m.getUpdatability() == ColumnUpdatability.WRITABLE,
        m.getClassName()
    ));
    offset++;
  }
  columns = ImmutableList.copyOf(newColumns);
}
 
Example #9
Source File: DremioColumnMetaDataList.java    From dremio-oss with Apache License 2.0 5 votes vote down vote up
/**
 * Gets AvaticaType carrying both JDBC {@code java.sql.Type.*} type code
 * and SQL type name for given RPC-level type (from batch schema).
 */
private static AvaticaType getAvaticaType( MajorType rpcDateType ) {
  final String sqlTypeName = Types.getSqlTypeName( rpcDateType );
  final int jdbcTypeId = Types.getJdbcTypeCode( sqlTypeName );
  return ColumnMetaData.scalar( jdbcTypeId, sqlTypeName,
      Rep.BOOLEAN /* dummy value, unused */ );
}
 
Example #10
Source File: QuicksqlServerResultSet.java    From Quicksql with MIT License 4 votes vote down vote up
/** 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<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);
  }
  // final List<Object> rows = new ArrayList<>();
  // rows.addAll(signature.columns);
  return new Meta.Frame(offset, done, rows);
}
 
Example #11
Source File: JdbcResultSet.java    From calcite-avatica with Apache License 2.0 4 votes vote down vote up
/** 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);
}
 
Example #12
Source File: MetaImpl.java    From calcite-avatica with Apache License 2.0 4 votes vote down vote up
public static ColumnMetaData columnMetaData(String name, int index, AvaticaType type,
    boolean columnNullable) {
  return columnMetaData(name, index, type, intForColumnNullable(columnNullable));
}
 
Example #13
Source File: TypedValue.java    From calcite-avatica with Apache License 2.0 4 votes vote down vote up
/**
 * Converts the given value from serial form to JDBC form.
 *
 * @param type The type of the value
 * @param value The value
 * @param calendar A calendar instance
 * @return The JDBC representation of the value.
 */
private static Object serialToJdbc(ColumnMetaData.Rep type, ColumnMetaData.Rep componentRep,
    Object value, Calendar calendar) {
  switch (type) {
  case BYTE_STRING:
    return ByteString.ofBase64((String) value).getBytes();
  case JAVA_UTIL_DATE:
    return new java.util.Date(adjust((Number) value, calendar));
  case JAVA_SQL_DATE:
    return new java.sql.Date(
        adjust(((Number) value).longValue() * DateTimeUtils.MILLIS_PER_DAY,
            calendar));
  case JAVA_SQL_TIME:
    return new java.sql.Time(adjust((Number) value, calendar));
  case JAVA_SQL_TIMESTAMP:
    return new java.sql.Timestamp(adjust((Number) value, calendar));
  case ARRAY:
    if (null == value) {
      return null;
    }
    final List<?> list = (List<?>) value;
    final List<Object> copy = new ArrayList<>(list.size());
    // Copy the list from the serial representation to a JDBC representation
    for (Object o : list) {
      if (null == o) {
        copy.add(null);
      } else if (o instanceof TypedValue) {
        // Protobuf can maintain the TypedValue hierarchy to simplify things
        copy.add(((TypedValue) o).toJdbc(calendar));
      } else {
        // We can't get the above recursion with the JSON serialization
        copy.add(serialToJdbc(componentRep, null, o, calendar));
      }
    }
    if (componentRep == null && list.size() > 0) {
      componentRep = ((TypedValue) list.get(0)).type;
      if (componentRep == null) {
        throw new RuntimeException("ComponentRep of element must not be null for ARRAYs");
      }
    }
    AvaticaType elementType = new AvaticaType(componentRep.typeId, componentRep.name(),
        componentRep);
    return new ArrayFactoryImpl(calendar.getTimeZone()).createArray(elementType, copy);
  default:
    return serialToLocal(type, value);
  }
}
 
Example #14
Source File: DremioColumnMetaDataList.java    From dremio-oss with Apache License 2.0 4 votes vote down vote up
/**
 * Gets AvaticaType carrying both JDBC {@code java.sql.Type.*} type code
 * and SQL type name for given SQL type name.
 */
private static AvaticaType getAvaticaType(String sqlTypeName) {
  final int jdbcTypeId = Types.getJdbcTypeCode(sqlTypeName);
  return ColumnMetaData.scalar( jdbcTypeId, sqlTypeName,
      Rep.BOOLEAN /* dummy value, unused */ );
}
 
Example #15
Source File: DremioColumnMetaDataList.java    From dremio-oss with Apache License 2.0 4 votes vote down vote up
public void updateColumnMetaData(String catalogName, String schemaName,
                                 String tableName, BatchSchema schema,
                                 List<Class<?>> getObjectClasses ) {
  final List<ColumnMetaData> newColumns =
      new ArrayList<>(schema.getFieldCount());
  for (int colOffset = 0; colOffset < schema.getFieldCount(); colOffset++) {
    final Field field = schema.getColumn(colOffset);
    Class<?> objectClass = getObjectClasses.get( colOffset );

    final String columnName = field.getName();

    final MajorType rpcDataType = getMajorTypeForField(field);
    final AvaticaType bundledSqlDataType = getAvaticaType(rpcDataType);
    final String columnClassName = objectClass.getName();

    final int nullability;
    switch ( rpcDataType.getMode() ) {
      case OPTIONAL: nullability = ResultSetMetaData.columnNullable; break;
      case REQUIRED: nullability = ResultSetMetaData.columnNoNulls;  break;
      // Should REPEATED still map to columnNoNulls? or to columnNullable?
      case REPEATED: nullability = ResultSetMetaData.columnNoNulls;  break;
      default:
        throw new AssertionError( "Unexpected new DataMode value '"
                                  + rpcDataType.getMode() + "'" );
    }
    final boolean isSigned = Types.isJdbcSignedType( rpcDataType );

    // TODO(DRILL-3355):  TODO(DRILL-3356):  When string lengths, precisions,
    // interval kinds, etc., are available from RPC-level data, implement:
    // - precision for ResultSetMetadata.getPrecision(...) (like
    //   getColumns()'s COLUMN_SIZE)
    // - scale for getScale(...), and
    // - and displaySize for getColumnDisplaySize(...).
    final int precision = Types.getPrecision(rpcDataType);
    final int scale = Types.getScale(rpcDataType);
    final int displaySize = Types.getJdbcDisplaySize(rpcDataType);

    ColumnMetaData col = new ColumnMetaData(
        colOffset,    // (zero-based ordinal (for Java arrays/lists).)
        false,        /* autoIncrement */
        false,        /* caseSensitive */
        true,         /* searchable */
        false,        /* currency */
        nullability,
        isSigned,
        displaySize,
        columnName,   /* label */
        columnName,   /* columnName */
        schemaName,
        precision,
        scale,
        tableName,
        catalogName,
        bundledSqlDataType,
        true,         /* readOnly */
        false,        /* writable */
        false,        /* definitelyWritable */
        columnClassName
       );
    newColumns.add(col);
  }
  columns = newColumns;
}