java.lang.Object
com.darkcollective.relix.processor.internal.DocumentRow
All Implemented Interfaces:
Row

public final class DocumentRow extends Object implements Row
A 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

    Constructors
    Constructor
    Description
     
    Creates a document row that knows where its fields came from.
  • Method Summary

    Modifier and Type
    Method
    Description
    Returns the document's top-level field names in document order — the dynamically-discovered columns of this open row.
    Returns the backing document.
    get(int index)
    Returns the value at the given zero-based column index.
    get(String name)
    Resolves name against the document, yielding NullValue on any miss.
    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 field field answers to: its explicit origins where it has them, else its owner's, else none.
    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 under relation: every top-level field answers to relation under its own name, and to nothing else.
    Returns this row with its top-level fields renamed: renames maps a field name, matched case-insensitively, to its new name.
    Returns the schema that describes this row's columns.
    int
    Returns the number of columns in this row.
    with(String field, Value value)
    Returns a copy of this document row with the top-level field field set to value (replacing an existing field case-insensitively, or adding it).

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Constructor Details

    • DocumentRow

      public DocumentRow(StructValue document)
      Parameters:
      document - the backing document; must not be null
    • DocumentRow

      public DocumentRow(StructValue document, Map<String,List<ColumnProvenance>> origins)
      Creates a document row that knows where its fields came from.
      Parameters:
      document - the backing document; must not be null
      origins - 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

      public StructValue document()
      Returns the backing document.
      Returns:
      the backing document
    • schema

      public Schema schema()
      Description copied from interface: Row
      Returns the schema that describes this row's columns.
      Specified by:
      schema in interface Row
      Returns:
      the row's schema; never null
    • origins

      public Map<String,List<ColumnProvenance>> 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

      public Optional<String> 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

      public List<ColumnProvenance> originsOf(String field)
      The relation-qualified names the top-level field field answers 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

      public DocumentRow reanchored(String relation)
      Returns this row as it reads under relation: every top-level field answers to relation under its own name, and to nothing else. That is what a scan of relation means, 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

      public DocumentRow renamed(Map<String,String> renames)
      Returns this row with its top-level fields renamed: renames maps 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

      public Value get(String name)
      Resolves name against the document, yielding NullValue on 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_id is the field whose origin is orders.product_id, whatever the document calls it, and products.details.city navigates into the field products.details names. 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:
      get in interface Row
      Parameters:
      name - the column name to look up
      Returns:
      the value; never null (absent values use NullValue.INSTANCE)
    • get

      public Value get(int index)
      Description copied from interface: Row
      Returns the value at the given zero-based column index.
      Specified by:
      get in interface Row
      Parameters:
      index - zero-based column index
      Returns:
      the value; never null
    • width

      public int width()
      Description copied from interface: Row
      Returns the number of columns in this row.
      Specified by:
      width in interface Row
      Returns:
      column count; always ≥ 1
    • columnNames

      public List<String> columnNames()
      Returns the document's top-level field names in document order — the dynamically-discovered columns of this open row.
      Specified by:
      columnNames in interface Row
      Returns:
      the ordered, possibly empty list of column names; never null
    • with

      public DocumentRow with(String field, Value value)
      Returns a copy of this document row with the top-level field field set to value (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 name
      value - the new value
      Returns:
      a new document row