use of org.apache.calcite.avatica.ColumnMetaData.ArrayType in project calcite-avatica by apache.
the class ArrayFactoryImpl method createArray.
@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));
}
}
use of org.apache.calcite.avatica.ColumnMetaData.ArrayType in project calcite-avatica by apache.
the class ArrayTypeTest method createArray.
/**
* 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);
assertFalse("Expected at least one accessor, found " + accessors.size(), accessors.isEmpty());
ArrayAccessor arrayAccessor = (ArrayAccessor) accessors.get(0);
return new ArrayImpl((List<Object>) arrayValues, arrayAccessor);
}
}
use of org.apache.calcite.avatica.ColumnMetaData.ArrayType 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);
}
use of org.apache.calcite.avatica.ColumnMetaData.ArrayType in project calcite-avatica by apache.
the class ArrayImplTest method resultSetFromArray.
@Test
public void resultSetFromArray() throws Exception {
// Define the struct type we're creating
ScalarType intType = ColumnMetaData.scalar(Types.INTEGER, "INTEGER", Rep.INTEGER);
ArrayType arrayType = ColumnMetaData.array(intType, "INTEGER", Rep.INTEGER);
ColumnMetaData arrayMetaData = MetaImpl.columnMetaData("MY_ARRAY", 1, arrayType, false);
ArrayImpl.Factory factory = new ArrayFactoryImpl(Unsafe.localCalendar().getTimeZone());
// Create some arrays from the structs
Array array1 = factory.createArray(intType, Arrays.<Object>asList(1, 2));
Array array2 = factory.createArray(intType, Arrays.<Object>asList(3));
Array array3 = factory.createArray(intType, Arrays.<Object>asList(4, 5, 6));
List<List<Object>> rows = Arrays.asList(Collections.<Object>singletonList(array1), Collections.<Object>singletonList(array2), Collections.<Object>singletonList(array3));
// Create two rows, each with one (array) column
try (Cursor cursor = new ListIteratorCursor(rows.iterator())) {
List<Accessor> accessors = cursor.createAccessors(Collections.singletonList(arrayMetaData), Unsafe.localCalendar(), factory);
assertEquals(1, accessors.size());
Accessor accessor = accessors.get(0);
assertTrue(cursor.next());
Array actualArray = accessor.getArray();
// An Array's result set has one row per array element.
// Each row has two columns. Column 1 is the array offset (1-based), Column 2 is the value.
ResultSet actualArrayResultSet = actualArray.getResultSet();
assertEquals(2, actualArrayResultSet.getMetaData().getColumnCount());
assertTrue(actualArrayResultSet.next());
// Order is Avatica implementation specific
assertEquals(1, actualArrayResultSet.getInt(1));
assertEquals(1, actualArrayResultSet.getInt(2));
assertTrue(actualArrayResultSet.next());
assertEquals(2, actualArrayResultSet.getInt(1));
assertEquals(2, actualArrayResultSet.getInt(2));
assertFalse(actualArrayResultSet.next());
assertTrue(cursor.next());
actualArray = accessor.getArray();
actualArrayResultSet = actualArray.getResultSet();
assertEquals(2, actualArrayResultSet.getMetaData().getColumnCount());
assertTrue(actualArrayResultSet.next());
assertEquals(1, actualArrayResultSet.getInt(1));
assertEquals(3, actualArrayResultSet.getInt(2));
assertFalse(actualArrayResultSet.next());
assertTrue(cursor.next());
actualArray = accessor.getArray();
actualArrayResultSet = actualArray.getResultSet();
assertEquals(2, actualArrayResultSet.getMetaData().getColumnCount());
assertTrue(actualArrayResultSet.next());
assertEquals(1, actualArrayResultSet.getInt(1));
assertEquals(4, actualArrayResultSet.getInt(2));
assertTrue(actualArrayResultSet.next());
assertEquals(2, actualArrayResultSet.getInt(1));
assertEquals(5, actualArrayResultSet.getInt(2));
assertTrue(actualArrayResultSet.next());
assertEquals(3, actualArrayResultSet.getInt(1));
assertEquals(6, actualArrayResultSet.getInt(2));
assertFalse(actualArrayResultSet.next());
assertFalse(cursor.next());
}
}
use of org.apache.calcite.avatica.ColumnMetaData.ArrayType in project calcite-avatica by apache.
the class ArrayImplTest method listOfJavaObjects.
/**
* Test case for when a column is a list of plain Java objects.
*/
@Test
public void listOfJavaObjects() throws Exception {
final ColumnMetaData.Rep rep = ColumnMetaData.Rep.of(PlainJavaObject.class);
final ColumnMetaData.Rep rep2 = ColumnMetaData.Rep.of(PlainJavaObject.class);
ColumnMetaData.AvaticaType objectAvaticaType = ColumnMetaData.scalar(Types.OTHER, "OTHER", rep);
String arrayTypeName = "JavaType(" + PlainJavaObject.class.toString() + ") ARRAY";
ArrayType arrayType = ColumnMetaData.array(objectAvaticaType, arrayTypeName, rep2);
ColumnMetaData javaObjectArrayMetaData = MetaImpl.columnMetaData("PLAIN_JAVA_OBJECT_ARRAY", 1, arrayType, true);
PlainJavaObject pjo1 = new PlainJavaObject(1, "one");
PlainJavaObject pjo2 = new PlainJavaObject(2, "two");
PlainJavaObject pjo3 = new PlainJavaObject(3, "three");
PlainJavaObject pjo4 = new PlainJavaObject(4, "four");
ArrayImpl.Factory factory = new ArrayFactoryImpl(Unsafe.localCalendar().getTimeZone());
List<Object> list1 = Arrays.asList(pjo1, pjo2);
List<Object> list2 = Arrays.asList(pjo3, pjo4);
List<List<Object>> rows = Arrays.asList(Arrays.asList(list1), Arrays.asList(list2));
try (Cursor cursor = new ListIteratorCursor(rows.iterator())) {
List<Accessor> accessors = cursor.createAccessors(Arrays.asList(javaObjectArrayMetaData), Unsafe.localCalendar(), factory);
assertEquals(1, accessors.size());
Accessor accessor = accessors.get(0);
assertTrue(cursor.next());
Array actualArray = accessor.getArray();
Object[] arrayData = (Object[]) actualArray.getArray();
assertEquals(2, arrayData.length);
assertEquals(pjo1, arrayData[0]);
assertEquals(pjo2, arrayData[1]);
assertTrue(cursor.next());
actualArray = accessor.getArray();
arrayData = (Object[]) actualArray.getArray();
assertEquals(2, arrayData.length);
assertEquals(pjo3, arrayData[0]);
assertEquals(pjo4, arrayData[1]);
}
}
Aggregations