Class DocumentRow
- All Implemented Interfaces:
Row
Row backed by a nested StructValue document — the row shape
produced by an open (schema-on-read) source such as the JSON file
connector.
Unlike ArrayRow (fixed positional columns under a closed schema), a
document row has no fixed columns: schema() is open, and get(String) resolves a name as a null-propagating
path into the document (user.name, items[0]), returning
NullValue for any miss rather
than throwing. This is what lets heterogeneous documents be queried by path
without a declared schema.
A document row may also know the origins of its top-level fields — the
relation-qualified names each one answers to. A scan anchors every field to the
relation it read (reanchored(String)), and a join records each field it
assembled (origins()). That is what lets products.name and
orders.product_id name fields of the document rather than paths into fields
called products and orders. See get(String).
-
Constructor Summary
ConstructorsConstructorDescriptionDocumentRow(StructValue document) DocumentRow(StructValue document, Map<String, List<ColumnProvenance>> origins) Creates a document row that knows where its fields came from. -
Method Summary
Modifier and TypeMethodDescriptionReturns the document's top-level field names in document order — the dynamically-discovered columns of this open row.document()Returns the backing document.get(int index) Returns the value at the given zero-based column index.Resolvesnameagainst the document, yieldingNullValueon any miss.origins()Returns the explicit origins, keyed by field name — the relation-qualified names a join recorded for each field it assembled; empty for any other row.The relation-qualified names the top-level fieldfieldanswers to: its explicit origins where it has them, else its owner's, else none.owner()Returns the relation every field without an explicit origin answers to under its own name — the relation a scan read this row from, or the name a rename gave it.reanchored(String relation) Returns this row as it reads underrelation: every top-level field answers torelationunder its own name, and to nothing else.Returns this row with its top-level fields renamed:renamesmaps a field name, matched case-insensitively, to its new name.schema()Returns the schema that describes this row's columns.intwidth()Returns the number of columns in this row.Returns a copy of this document row with the top-level fieldfieldset tovalue(replacing an existing field case-insensitively, or adding it).
-
Constructor Details
-
DocumentRow
- Parameters:
document- the backing document; must not be null
-
DocumentRow
Creates a document row that knows where its fields came from.- Parameters:
document- the backing document; must not be nullorigins- for each top-level field name (as the document spells it), the relation-qualified names that field answers to; a field with no entry answers to none. Must not be null
-
-
Method Details
-
document
Returns the backing document.- Returns:
- the backing document
-
schema
Description copied from interface:RowReturns the schema that describes this row's columns. -
origins
Returns the explicit origins, keyed by field name — the relation-qualified names a join recorded for each field it assembled; empty for any other row.- Returns:
- the explicit origins, keyed by field name — the relation-qualified names a join recorded for each field it assembled; empty for any other row
- See Also:
-
owner
Returns the relation every field without an explicit origin answers to under its own name — the relation a scan read this row from, or the name a rename gave it.- Returns:
- the relation every field without an explicit origin answers to under its own name — the relation a scan read this row from, or the name a rename gave it
-
originsOf
The relation-qualified names the top-level fieldfieldanswers to: its explicit origins where it has them, else its owner's, else none.- Parameters:
field- a top-level field name, as the document spells it- Returns:
- the names it answers to; empty when it answers to none
-
reanchored
Returns this row as it reads underrelation: every top-level field answers torelationunder its own name, and to nothing else. That is what a scan ofrelationmeans, and whatρ relation (…)does to a declared heading's provenance.- Parameters:
relation- the relation name; must not be blank- Returns:
- a row over the same document, anchored to
relation
-
renamed
Returns this row with its top-level fields renamed:renamesmaps a field name, matched case-insensitively, to its new name. A name the document does not carry is ignored — whether a field exists is a fact about each document. A field keeps its position and value, and an explicit origin follows it under the new name, as a declared column's provenance does.- Parameters:
renames- old field name → new field name; must not be null- Returns:
- the renamed row, or this row when nothing it carries is renamed
- Throws:
IllegalArgumentException- if a new name collides with a field the document still carries, or with another renamed field
-
get
Resolvesnameagainst the document, yieldingNullValueon any miss.A name is first read as a relation-qualified reference when its leading segment is a relation some field originates from:
orders.product_idis the field whose origin isorders.product_id, whatever the document calls it, andproducts.details.citynavigates into the fieldproducts.detailsnames. A relation in scope that owns no such field reads as NULL, the same answer a document gives for a field it does not carry. Otherwise — and always, for a row with no origins — the name is a path into the document:"field","a.b","items[0].price".The relation reading is tried first because that is the order a declared row resolves a dotted name in, and a joined row must not answer the same query differently for having one open input. Where two fields answer to the same qualified name — a self-join with no rename — the first wins, as it does in a join condition.
- Specified by:
getin interfaceRow- Parameters:
name- the column name to look up- Returns:
- the value; never
null(absent values useNullValue.INSTANCE)
-
get
Description copied from interface:RowReturns the value at the given zero-based column index. -
width
public int width()Description copied from interface:RowReturns the number of columns in this row. -
columnNames
Returns the document's top-level field names in document order — the dynamically-discovered columns of this open row.- Specified by:
columnNamesin interfaceRow- Returns:
- the ordered, possibly empty list of column names; never null
-
with
Returns a copy of this document row with the top-level fieldfieldset tovalue(replacing an existing field case-insensitively, or adding it). Used by unnest to bind the exploded element back into the row. The field keeps whatever origin it had.- Parameters:
field- the field namevalue- the new value- Returns:
- a new document row
-