Skip to content

Initial spec for lists and structs#113

Open
hadley wants to merge 7 commits into
mainfrom
list-fields
Open

Initial spec for lists and structs#113
hadley wants to merge 7 commits into
mainfrom
list-fields

Conversation

@hadley

@hadley hadley commented Jul 9, 2026

Copy link
Copy Markdown
Member

Will eventually fix #56 and fix #57.

@hadley hadley requested a review from gaborcsardi July 9, 2026 22:28
Comment thread site/spec.md
* `date`: calendar dates, written as ISO 8601 strings (`YYYY-MM-DD`, e.g. `2024-01-31`).
* `datetime`: date-times, written as ISO 8601 strings. Without a `time_zone` they carry an offset (e.g. `2024-01-31T09:30:00Z`); with a `time_zone` they're written zoneless and interpreted in that zone (see [Time zones](#time-zones)).
* `enum`: a column with repeated values from a known set. The allowed values are listed in the `values` property.
* `list(element_type)`: an ordered sequence of zero or more elements of the given type (see [List element types](#list-element-types)).

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are list and struct the right names?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

list definitely. struct is as good as any imo

Comment thread site/spec.md

* `primary_key`: the set of columns with the `primary_key` constraint uniquely identifies each row. Implies `required` and `unique`.
* `foreign_key`: the column references a primary key in another table (or in the current table, if a self-join). The specific relationship is defined in [`relationships`](#relationships).
* `primary_key`: the set of columns with the `primary_key` constraint uniquely identifies each row. Implies `required` and `unique`. Not valid on `list` or `struct` columns, or on fields within a `struct`.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could consider consider other carve outs if you think support is going to be complex

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks OK for me, although I am not sure what more you would add.

Comment thread site/spec.md
Comment on lines +171 to +172
type: list(enum)
values: [food, drink, dessert]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks the same as an enum. What's different here?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a multiselect — an enum must have exactly one value for each row. A list(enum) can have any number of values for each row.

Comment thread site/spec.md
Comment on lines +167 to +168
type: list(string)
examples: [nature, outdoor, urban, photography, wildlife]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment below about the enum. How would this be different?

Comment thread site/spec.md
Comment on lines +195 to +209
- name: address
type: struct
fields:
- name: street
type: string
examples: [123 Main St, 456 Oak Ave, 789 Elm Dr]
- name: city
type: string
examples: [Portland, Austin, Chicago]
- name: zip
type: string
examples: ["97201", "78701", "60601"]
- name: country
type: enum
values: [US, CA, MX]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have a hard time seeing the difference here with the list(struct). I understand that the data itself might be different, but when the metadata looks the exact same, I'd have a hard time differentiating them both.

Comment thread site/spec.md
* `datetime`: date-times, written as ISO 8601 strings. Without a `time_zone` they carry an offset (e.g. `2024-01-31T09:30:00Z`); with a `time_zone` they're written zoneless and interpreted in that zone (see [Time zones](#time-zones)).
* `enum`: a column with repeated values from a known set. The allowed values are listed in the `values` property.
* `list(element_type)`: an ordered sequence of zero or more elements of the given type (see [List element types](#list-element-types)).
* `struct`: a structured record with named fields documented in the required `fields` property (see [Struct fields](#struct-fields)).

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you thinking of using these for very nested data? I personally haven't encountered these "in the wild". What would be the advantage of a list(struct) rather than as either another table or as a flattened set of columns with specific items appended to their column name.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not a data structure that I'd generally recommend, since I would prefer a relation framing with multiple tables, but it is something that you get in parquet files so its important that we can represent it.

Comment thread site/spec.md

#### Struct fields

A `struct` column may include a `fields` property — an ordered list of field descriptors. Each field descriptor uses the same schema as a column descriptor. A field may itself be `list(...)` or `struct` (with its own `fields`), allowing deep nesting.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So if I understand correctly list(..., struct(list(...)), ...) is allowed, but list(list(...)) is not? Is that intentional? Since the list -> struct -> list nesting is already allowed I don't see why the list(list(...)) would not be.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah yes, good point.

Comment thread site/spec.md
* `date`: calendar dates, written as ISO 8601 strings (`YYYY-MM-DD`, e.g. `2024-01-31`).
* `datetime`: date-times, written as ISO 8601 strings. Without a `time_zone` they carry an offset (e.g. `2024-01-31T09:30:00Z`); with a `time_zone` they're written zoneless and interpreted in that zone (see [Time zones](#time-zones)).
* `enum`: a column with repeated values from a known set. The allowed values are listed in the `values` property.
* `list(element_type)`: an ordered sequence of zero or more elements of the given type (see [List element types](#list-element-types)).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

list definitely. struct is as good as any imo

Comment thread site/spec.md

* `primary_key`: the set of columns with the `primary_key` constraint uniquely identifies each row. Implies `required` and `unique`.
* `foreign_key`: the column references a primary key in another table (or in the current table, if a self-join). The specific relationship is defined in [`relationships`](#relationships).
* `primary_key`: the set of columns with the `primary_key` constraint uniquely identifies each row. Implies `required` and `unique`. Not valid on `list` or `struct` columns, or on fields within a `struct`.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks OK for me, although I am not sure what more you would add.

@hadley

hadley commented Jul 10, 2026

Copy link
Copy Markdown
Member Author

To do:

  • Carefully review snapshots
  • Check that list/struct/list recursion is correctly implemented
  • Support list-list nesting

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Consider nested types Consider list types

3 participants