Internal mechanism to detect if a value is null. Handles the multiple ways
that Drill represents nulls:
- Required and repeated modes: value is never null.
- Optional mode: null state is carried by an associated "bits" vector.
- Union: null state is carried by both the bits state of
the union itself, and the null state of the associated nullable vector.
(The union states if the column value itself is null; the vector state is
if that value is null, which will occur if either the column is null, or
if the type of the column is something other than the type in question.)
- List, with a single data vector: null state is carried by the list vector
and the associated nullable data vector. Presumably the list vector state
takes precedence.
- List, with a union data vector (AKA variant array or union array): the
null state is carried by all three of a) the list vector, b) the union
vector, and c) the type vectors. Presumably, the list vector state has
precedence.
The interface here allows each reader to delegate the null logic to a
separate component, keeping the data access portion itself simple.
As with all readers, this reader must handle both the single-batch and
the hyper-batch cases.