public class ListState extends ContainerState implements VariantWriter.VariantWriterListener
At the writer level, the list consists of two parts: an array writer and a union writer. The union writer is needed because, unless the client tells us otherwise, we must be prepared for the list to become a union.
Holds the column states for the "columns" that make up the type members of the union, and implements the writer callbacks to add members to a list (disguised as a union), creating the actual union with the number of member types becomes two or more.
This class is similar to the UnionState
, except that this
version must handle the list transitions from no members to single
member to union, and so this class is a bit more complex than the
simple union case.
This implementation is based on a desired invariant: that once a client obtains a writer for the list, that writer never becomes invalid. This means we must carefully consider the list lifecycle. The list is represented as an array writer. When the list has no members, there would be no child for the array writer, a call to listArray.entry() would have to return null, which would be awkward and unlike any other writer use case. Once the list has a single type, the call to listArray.entry() might return a writer for that type. But, once the list becomes a repeated union, then listArray.entry() would have to return a union writer. This is the kind of muddy semantics we wish to avoid.
Instead, we model the list as a repeated union at all times. When the
list has no type, then the list is a repeated union with no members.
Once the list has a member, we have a repeated union of one member type.
Finally, when adding another type, we have a repeated union of two
types. The key is, in all cases, listArray.entry() returns
a UnionWriter
, so the client gets a consistent view.
Since the list itself changes form (no type, single type, then union), we hide that lifecycle internal to the writer and to this list state. The result is that the client need not care about the odd list lifecycle. But, on the flip side, this class, and the union writer, must go out of their way to hide these details.
At the writer level, the union writer uses "shims" to map from the union view to the actual list representation (no type, single type or union.)
At this level, this class must handle those cases as well, creating the union (by promoting the list) when needed. The result is a bit complex (for the code here), but simple for the client.
Modifier and Type | Class and Description |
---|---|
protected static class |
ListState.ListVectorState
Wrapper around the list vector (and its optional contained union).
|
loader, parentColumn, projectionSet, vectorCache
Constructor and Description |
---|
ListState(org.apache.drill.exec.physical.resultSet.impl.LoaderInternals loader,
ResultVectorCache vectorCache) |
Modifier and Type | Method and Description |
---|---|
protected void |
addColumn(ColumnState colState)
Add a new column representing a type within the list.
|
ObjectWriter |
addMember(ColumnMetadata member) |
ObjectWriter |
addType(TypeProtos.MinorType type) |
protected Collection<ColumnState> |
columnStates() |
int |
innerCardinality() |
protected boolean |
isVersioned()
Reports whether this container is subject to version management.
|
ListWriterImpl |
listWriter() |
void |
setSubColumn(ColumnState memberState)
Set the one and only type when building a single-type list.
|
VariantMetadata |
variantSchema() |
addColumn, bindColumnState, close, harvestWithLookAhead, loader, projection, rollover, startBatch, updateCardinality, vectorCache
public ListState(org.apache.drill.exec.physical.resultSet.impl.LoaderInternals loader, ResultVectorCache vectorCache)
public VariantMetadata variantSchema()
public ListWriterImpl listWriter()
public ObjectWriter addType(TypeProtos.MinorType type)
addType
in interface VariantWriter.VariantWriterListener
public ObjectWriter addMember(ColumnMetadata member)
addMember
in interface VariantWriter.VariantWriterListener
protected void addColumn(ColumnState colState)
We must make three parallel changes:
addColumn
in class ContainerState
public void setSubColumn(ColumnState memberState)
memberState
- the column state for the list elementsprotected Collection<ColumnState> columnStates()
columnStates
in class ContainerState
public int innerCardinality()
innerCardinality
in class ContainerState
protected boolean isVersioned()
ContainerState
isVersioned
in class ContainerState
true
if versionedCopyright © 1970 The Apache Software Foundation. All rights reserved.