Search in sources :

Example 1 with UnionVectorState

use of org.apache.drill.exec.physical.resultSet.impl.UnionState.UnionVectorState 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);
}
Also used : VariantObjectWriter(org.apache.drill.exec.vector.accessor.writer.UnionWriterImpl.VariantObjectWriter) UnionVector(org.apache.drill.exec.vector.complex.UnionVector) UnionVectorState(org.apache.drill.exec.physical.resultSet.impl.UnionState.UnionVectorState) UnionWriterImpl(org.apache.drill.exec.vector.accessor.writer.UnionWriterImpl) UnionColumnState(org.apache.drill.exec.physical.resultSet.impl.UnionState.UnionColumnState)

Example 2 with UnionVectorState

use of org.apache.drill.exec.physical.resultSet.impl.UnionState.UnionVectorState 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));
}
Also used : UnionVectorShim(org.apache.drill.exec.vector.accessor.writer.UnionVectorShim) ListVector(org.apache.drill.exec.vector.complex.ListVector) SimpleListShim(org.apache.drill.exec.vector.accessor.writer.SimpleListShim) UnionVector(org.apache.drill.exec.vector.complex.UnionVector) UnionVectorState(org.apache.drill.exec.physical.resultSet.impl.UnionState.UnionVectorState) UnionWriterImpl(org.apache.drill.exec.vector.accessor.writer.UnionWriterImpl)

Aggregations

UnionVectorState (org.apache.drill.exec.physical.resultSet.impl.UnionState.UnionVectorState)2 UnionWriterImpl (org.apache.drill.exec.vector.accessor.writer.UnionWriterImpl)2 UnionVector (org.apache.drill.exec.vector.complex.UnionVector)2 UnionColumnState (org.apache.drill.exec.physical.resultSet.impl.UnionState.UnionColumnState)1 SimpleListShim (org.apache.drill.exec.vector.accessor.writer.SimpleListShim)1 UnionVectorShim (org.apache.drill.exec.vector.accessor.writer.UnionVectorShim)1 VariantObjectWriter (org.apache.drill.exec.vector.accessor.writer.UnionWriterImpl.VariantObjectWriter)1 ListVector (org.apache.drill.exec.vector.complex.ListVector)1