use of org.apache.drill.exec.vector.complex.UnionVector in project drill by apache.
the class PromotableWriter method promoteToUnion.
private FieldWriter promoteToUnion() {
String name = vector.getField().getLastName();
TransferPair tp = vector.getTransferPair(vector.getField().getType().getMinorType().name().toLowerCase(), vector.getAllocator());
tp.transfer();
if (parentContainer != null) {
unionVector = parentContainer.addOrGet(name, Types.optional(MinorType.UNION), UnionVector.class);
} else if (listVector != null) {
unionVector = listVector.promoteToUnion();
}
unionVector.addVector(tp.getTo());
writer = new UnionWriter(unionVector);
writer.setPosition(idx());
for (int i = 0; i < idx(); i++) {
unionVector.getMutator().setType(i, vector.getField().getType().getMinorType());
}
vector = null;
state = State.UNION;
return writer;
}
use of org.apache.drill.exec.vector.complex.UnionVector in project drill by axbaretto.
the class SchemaUtil method coerceVector.
@SuppressWarnings("resource")
private static ValueVector coerceVector(ValueVector v, VectorContainer c, MaterializedField field, int recordCount, BufferAllocator allocator) {
if (v != null) {
int valueCount = v.getAccessor().getValueCount();
TransferPair tp = v.getTransferPair(allocator);
tp.transfer();
if (v.getField().getType().getMinorType().equals(field.getType().getMinorType())) {
if (field.getType().getMinorType() == MinorType.UNION) {
UnionVector u = (UnionVector) tp.getTo();
for (MinorType t : field.getType().getSubTypeList()) {
u.addSubType(t);
}
}
return tp.getTo();
} else {
ValueVector newVector = TypeHelper.getNewVector(field, allocator);
Preconditions.checkState(field.getType().getMinorType() == MinorType.UNION, "Can only convert vector to Union vector");
UnionVector u = (UnionVector) newVector;
u.setFirstType(tp.getTo(), valueCount);
return u;
}
} else {
v = TypeHelper.getNewVector(field, allocator);
v.allocateNew();
v.getMutator().setValueCount(recordCount);
return v;
}
}
use of org.apache.drill.exec.vector.complex.UnionVector in project drill by apache.
the class SingleSchemaInference method inferListSchema.
private VariantSchema inferListSchema(ListVector vector) {
final ValueVector dataVector = vector.getDataVector();
if (dataVector instanceof UnionVector) {
return inferUnionSchema((UnionVector) dataVector);
}
final VariantSchema schema = new VariantSchema();
if (!vector.isEmptyType()) {
schema.addType(inferVector(dataVector));
}
return schema;
}
use of org.apache.drill.exec.vector.complex.UnionVector in project drill by apache.
the class ColumnBuilder method buildUnion.
/**
* Builds a union column.
* <p>
* The union vector type is not well supported in Drill. The idea is that
* arbitrary operators can absorb schema changes by converting vectors to
* unions so that an operator can handle, say, a nullable int and a varchar.
* In practice, most operators don't support this feature. (Sort does -- but
* does not manage memory for the union case.) In principal, union can't solve
* the problem because ODBC and JDBC don't support unions, and it is easy
* to envision changes that unions won't solve (int and varchar types combining
* in a join column, say.) Still, Drill supports unions, so the code here
* does so. Unions are fully tested in the row set writer mechanism.
*
* @param parent container of vectors
* @param columnSchema implied projection type for the column
* @return column
*/
private ColumnState buildUnion(ContainerState parent, ColumnMetadata columnSchema) {
assert columnSchema.isVariant() && !columnSchema.isArray();
// vectors can be cached.
assert columnSchema.variantSchema().size() == 0;
final UnionVector vector = new UnionVector(columnSchema.schema(), parent.loader().allocator(), null);
// Then the union writer.
final UnionWriterImpl unionWriter = new UnionWriterImpl(columnSchema, vector, null);
final VariantObjectWriter writer = new VariantObjectWriter(unionWriter);
// The union vector state which manages the types vector.
final UnionVectorState vectorState = new UnionVectorState(vector, unionWriter);
// Create the manager for the columns within the union.
final UnionState unionState = new UnionState(parent.loader(), parent.vectorCache().childCache(columnSchema.name()));
// Bind the union state to the union writer to handle column additions.
unionWriter.bindListener(unionState);
// Assemble it all into a union column state.
return new UnionColumnState(parent.loader(), writer, vectorState, unionState);
}
use of org.apache.drill.exec.vector.complex.UnionVector in project drill by apache.
the class ListState method addSecondType.
/**
* Perform the delicate dance of promoting a list vector from a single type to
* a union, while leaving the writer client blissfully ignorant that the underlying
* vector representation just did a radical change. Key tasks:
* <ul>
* <li>Create the new column (type member) requested by the client.</li>
* <li>The List vector currently has a single type. Promote the list to
* a union, adding the existing type (column) as the first union member.</li>
* <li>Initialize the union's type vector with either the type of the existing
* column, or null, depending on the setting of the is-set bits in the existing
* column vector.</li>
* <li>Since we've written values into the union's type vector, mark the
* last-write position in the union vector's type vector writer to reflect
* these writes. (Otherwise, the writer will helpfully zero-fill the previous
* positions as part of it's back-fill handling.</li>
* <li>Replace the single-type shim in the union vector with a full union
* shim.</li>
* <li>Move the existing column writer or the member column across from the
* single-writer shim to the new union shim.</li>
* <li>Augment the list vector's vector state to include a vector state for
* the newly created union vector.</li>
* </ul>
* <p>
* Here, yet again, an editorial comment might be useful. List vectors are
* very strange and not at all well designed for high-speed writing. They are
* too complex; too much can go wrong and there are too many states to handle.
* Not only that, variant types don't play well with a relational model like
* SQL. This code works, but the overall list concept really needs rethinking.
*
* @param colState the column state for the newly added type column; the
* one causing the list to change from single-type to a union
*/
private void addSecondType(ColumnState colState) {
final UnionWriterImpl unionWriter = unionWriter();
final ListVector listVector = listVector();
// Going from one type to a union
// Convert the list from single type to a union,
// moving across the previous type vector.
final int typeFillCount = unionWriter.elementPosition().writeIndex();
final UnionVector unionVector = listVector.convertToUnion(innerCardinality(), typeFillCount);
unionVector.addType(colState.vector());
// Replace the single-type shim with a union shim, copying
// across the existing writer.
final SimpleListShim oldShim = (SimpleListShim) unionWriter.shim();
final UnionVectorShim newShim = new UnionVectorShim(unionVector);
unionWriter.bindShim(newShim);
newShim.addMemberWriter(oldShim.memberWriter());
newShim.initTypeIndex(typeFillCount);
// The union vector will be managed within the list vector state.
// (Do this last because the union vector state expects the union
// writer to be operating in "union mode".
listVectorState().replaceMember(new UnionVectorState(unionVector, unionWriter));
}
Aggregations