Repository navigation
Conversation
|
|
||
| Every non-null `vector(E, D)` value must contain exactly D non-null elements of type E. Floating-point elements must not be `NaN`, positive infinity, or negative infinity. The vector value itself may be null when the containing field is optional. | ||
|
|
||
| No type promotion to or from `vector` is defined, including changes to its element type or dimension. Lower and upper bounds are not defined for vector values. |
There was a problem hiding this comment.
You might want to add something to the effect of "a list of type E and length D is not equivalent to a vector(E,D)"
There was a problem hiding this comment.
+1.
I want to add two more points
- "No type promotion is defined" reads as unspecified, not forbidden.
- The
unknownexception is the v3+ rule thatunknownpromotes to any type. Without it, this sentence contradicts that table.
A
vectormust not be promoted to another type. No type other thanunknownmay be promoted tovector. The element type and dimension must not change. Alistof element type E is not avector(E, D), even when every value has length D.
I would also add more details along with the upper and lower bounds
Equality of vector values is element-wise, using the equality rules of element type. A vector must not be an identifier field. No sort order is defined for a vector value. Writers must not write lower or upper bounds for a vector field.
There was a problem hiding this comment.
Concerning lower/upper bounds, we should also adjust the table in the "Field Statistics" section to mention vectors are excluded.
There was a problem hiding this comment.
If we don't have stats for vectors, then we need to rely on other means to identify int8/uint8 etc.
There was a problem hiding this comment.
What stats would let you know the type width? I know we have some things around variable length types but with int float and friends I'm not sure they would make sense
|
|
||
| ##### Vector | ||
|
|
||
| Every non-null `vector(E, D)` value must contain exactly D non-null elements of type E. Floating-point elements must not be `NaN`, positive infinity, or negative infinity. The vector value itself may be null when the containing field is optional. |
There was a problem hiding this comment.
The last sentence is doing more work than it looks like, and "containing field" makes it harder to read than it needs to be. Suggested:
A non-null
vector(E, D)contains exactly D elements of type E, and every element is non-null.floatanddoubleelements must be finite:NaN,+Infinity, and-Infinityare invalid. The vector value may be null only when the vector field is optional.
| | | **`uuid`** | Universally unique identifiers | Should use 16-byte fixed | | ||
| | | **`fixed(L)`** | Fixed-length byte array of length L | | | ||
| | | **`binary`** | Arbitrary-length byte array | | | ||
| | [v4](#version-4) | **`vector(E, D)`** | Fixed-length collection of finite numeric values with element type E and dimension D | E must be `int`, `long`, `float`, or `double`; D must be positive | |
There was a problem hiding this comment.
identity still allows every primitive except geometry and geography. We probably should exclude vector there.
There was a problem hiding this comment.
What do we think about storing smaller precision int/uint/float values?
The current types are very wide, and don't match types used on real world AI workloads.
There was a problem hiding this comment.
+1, vectors used in search are predominantly 8-bit integer types, half- and single-precision floats. Double and long are rarely used.
There was a problem hiding this comment.
That would have to be a subsequent proposal since we don't have such types defined in iceberg yet.
There was a problem hiding this comment.
➕1 to support 8-bit byte data type as well.
| | **`binary`** | `binary` | | | | ||
| | **`struct`** | `group` | | | | ||
| | **`list`** | `3-level list` | `LIST` | See Parquet docs for 3-level representation. | | ||
| | **`vector(E, D)`** | `3-level list` | `VECTOR(D)` | The element must be required and use the Parquet mapping for E. See [apache/parquet-format#624](https://github.com/apache/parquet-format/pull/624). | |
There was a problem hiding this comment.
We need to restate the physical contract here instead of using an unmerged Parquet PR as the normative text. We can update it later as the Parquet spec finalizes.
I am putting some keywords here. VECTOR(D), repeated group list, required primitive element mapped from E, exactly D elements, elements non-null and finite.
| |**`binary`**|`bytes`|| | ||
| |**`struct`**|`record`|| | ||
| |**`list`**|`array`|| | ||
| |**`vector(E, D)`**|`array`|Array elements must use the Avro mapping for E and must not be null. Readers and writers must enforce the vector dimension and element requirements.| |
There was a problem hiding this comment.
Avro stores both list and vector as array. The file type alone does not say which one it is.
Iceberg marks a list by writing element-id on the Avro array. That is the list element's field id. A vector has no element field id, so its array must not have element-id. A writer that adds one makes the file look like a list.
Suggested note on the Avro row:
Array elements must use the Avro mapping for E and must not be null. The array must not have
element-id. Readers and writers enforce dimension D and the element rules from the Iceberg schema. An array of length D is not a vector.
There was a problem hiding this comment.
Would it make sense to add an Avro logical type for vector?
There was a problem hiding this comment.
In the community sync, we said it might make sense to ask the Avro community about this. I started a discussion thread on the Avro dev mailing list: https://lists.apache.org/thread.html/ds0gm18b8cghotv4xtsmgo2ybghht60m
|
|
||
| Every non-null `vector(E, D)` value must contain exactly D non-null elements of type E. Floating-point elements must not be `NaN`, positive infinity, or negative infinity. The vector value itself may be null when the containing field is optional. | ||
|
|
||
| No type promotion to or from `vector` is defined, including changes to its element type or dimension. Lower and upper bounds are not defined for vector values. |
There was a problem hiding this comment.
+1.
I want to add two more points
- "No type promotion is defined" reads as unspecified, not forbidden.
- The
unknownexception is the v3+ rule thatunknownpromotes to any type. Without it, this sentence contradicts that table.
A
vectormust not be promoted to another type. No type other thanunknownmay be promoted tovector. The element type and dimension must not change. Alistof element type E is not avector(E, D), even when every value has length D.
I would also add more details along with the upper and lower bounds
Equality of vector values is element-wise, using the equality rules of element type. A vector must not be an identifier field. No sort order is defined for a vector value. Writers must not write lower or upper bounds for a vector field.
|
|
||
| ### Version 4 | ||
|
|
||
| The `vector` type is added in v4. Writing `vector` into a v3 or earlier schema is invalid. |
There was a problem hiding this comment.
this seems unnecessary. I don't think we say this for the new types introduced in v3.
Writing `vector` into a v3 or earlier schema is invalid.
|
|
||
| ##### Vector | ||
|
|
||
| Every non-null `vector(E, D)` value must contain exactly D non-null elements of type E. Floating-point elements must not be `NaN`, positive infinity, or negative infinity. The vector value itself may be null when the containing field is optional. |
There was a problem hiding this comment.
Are you suggesting we might only allow one representation of the number zero? If yes, do you have use-cases in mind?
There was a problem hiding this comment.
I did some research, and found that some AI hardware has some issues with these values. That said, I agree with the things discussed on the sync, and we should support these values as most other vector storage systems support it.
PFischbeck
left a comment
There was a problem hiding this comment.
Thanks for working on this!
- We should (probably) disallow vector default values, i.e., only allow null as default
- We should disallow vector in all partition transforms (in
expressions-spec.md)
|
|
||
| ##### Vector | ||
|
|
||
| Every non-null `vector(E, D)` value must contain exactly D non-null elements of type E. Floating-point elements must not be `NaN`, positive infinity, or negative infinity. The vector value itself may be null when the containing field is optional. |
There was a problem hiding this comment.
Are you suggesting we might only allow one representation of the number zero? If yes, do you have use-cases in mind?
|
|
||
| Every non-null `vector(E, D)` value must contain exactly D non-null elements of type E. Floating-point elements must not be `NaN`, positive infinity, or negative infinity. The vector value itself may be null when the containing field is optional. | ||
|
|
||
| No type promotion to or from `vector` is defined, including changes to its element type or dimension. Lower and upper bounds are not defined for vector values. |
There was a problem hiding this comment.
Concerning lower/upper bounds, we should also adjust the table in the "Field Statistics" section to mention vectors are excluded.
| | **`binary`** | **`JSON string`** | `"000102ff"` | Stored as a hexadecimal string | | ||
| | **`struct`** | **`JSON object by field ID`** | `{"1": 1, "2": "bar"}` | Stores struct fields using the field ID as the JSON field name; field values are stored using this JSON single-value format | | ||
| | **`list`** | **`JSON array of values`** | `[1, 2, 3]` | Stores a JSON array of values that are serialized using this JSON single-value format | | ||
| | **`vector(E, D)`** | **`JSON array of values`** | `[1.0, 2.0, 3.0]` | Stores exactly D values using E's JSON single-value format | |
There was a problem hiding this comment.
Are we allowing defaults? If so that would be one use case but this would be a pretty inefficient storage since I assume folks would want to default to all 0 or something
| | **`binary`** | `binary` | | | | ||
| | **`struct`** | `struct` | | | | ||
| | **`list`** | `array` | | | | ||
| | **`vector(E, D)`** | `array` | | Array elements must use the ORC mapping for E and must not be null. Readers and writers must enforce the vector dimension and element requirements. | |
There was a problem hiding this comment.
I'm not too familiar with ORC, but does it make sense to also add new ORC type attributes to mark it as vector?
There was a problem hiding this comment.
Honestly orc is a zombie in our ecosystem at the moment so whatever we do that is minimally sufficient is probably fine.
| |**`binary`**|`bytes`|| | ||
| |**`struct`**|`record`|| | ||
| |**`list`**|`array`|| | ||
| |**`vector(E, D)`**|`array`|Array elements must use the Avro mapping for E and must not be null. Readers and writers must enforce the vector dimension and element requirements.| |
There was a problem hiding this comment.
Would it make sense to add an Avro logical type for vector?
I think these are reasonable. For the purposes of the spec, while this is a primitive it basically should follow the same rules as list imho |
Adds a v4
vector(E, D)primitive type for fixed-length dense numeric vectors. Non-null vectors contain exactly D non-null finite elements of the allowed type E. Avro and ORC map vectors to arrays with reader and writer enforcement, while Parquet usesVECTOR(D)following apache/parquet-format#624. Schema JSON usesvector(<E>, <D>), and Appendix D defines JSON value serialization.Issue: #18297
Test plan:
git diff --check origin/main...HEADformat/spec.mdusing Python-Markdown with the tables extension.make lintcould not install its Python dependencies because the package index was unreachable; docs CI is required.AI Disclosure