Skip to content

infer_rel_schema raises AttributeError on an unbound column: the nullability helpers assume every Type.kind has a nullability field #276

Open

Description

@nielspardon

_field_nullability (src/substrait/type_inference.py:624) and _with_field_nullability (type_inference.py:630) both do getattr(t, kind).nullability after only checking that t has a kind. Type.Unbound is the one Type.kind oneof variant with no nullability field, so both raise on it.

Per spec v0.99.0 site/docs/types/type_classes.md, the unbound type "may appear wherever a concrete type would normally appear, for example as a field type within ReadRel.base_schema", and it "carries no nullability and accepts no parameters; those properties are determined when it is bound to a concrete type". So an unbound field should pass through nullability derivation untouched rather than crash.

Reached today through _set_output_struct, i.e. any SetRel over a partially bound input.

Reproducer

import substrait.algebra_pb2 as stalg, substrait.type_pb2 as stt
from substrait.type_inference import infer_rel_schema


def read(name, type_):
    return stalg.Rel(read=stalg.ReadRel(
        named_table=stalg.ReadRel.NamedTable(names=[name]),
        base_schema=stt.NamedStruct(names=[name], struct=stt.Type.Struct(
            types=[type_], nullability=stt.Type.NULLABILITY_REQUIRED))))


unbound = stt.Type(unbound=stt.Type.Unbound())
rel = stalg.Rel(set=stalg.SetRel(
    inputs=[read("a", unbound), read("b", unbound)],
    op=stalg.SetRel.SET_OP_UNION_ALL))

print(infer_rel_schema(rel))
  File "src/substrait/type_inference.py", line 627, in _field_nullability
    return getattr(t, kind).nullability if kind else stt.Type.NULLABILITY_UNSPECIFIED
AttributeError: nullability

Measured on main at afa3c52. Pre-existing.

Guarding both helpers on kind != "unbound" covers it. Note #272 introduces a second caller of _with_field_nullability (join null-padding), which reaches the same gap for LEFT / RIGHT / OUTER / *_SINGLE joins; that half is raised on the PR. The set-operation nullability rules themselves came from #219.

🤖 Filed with AI assistance as a follow-up to review of #272.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions