rdblue commented on code in PR #14234: URL: https://github.com/apache/iceberg/pull/14234#discussion_r3244930644
########## format/spec.md: ########## @@ -686,9 +687,31 @@ Notes: 5. The `content_offset` and `content_size_in_bytes` fields are used to reference a specific blob for direct access to a deletion vector. For deletion vectors, these values are required and must exactly match the `offset` and `length` stored in the Puffin footer for the deletion vector blob. 6. The following field ids are reserved on `data_file`: 141. -###### Bounds for Variant, Geometry, and Geography +##### Field-level Metrics and Statistics -For Variant, values in the `lower_bounds` and `upper_bounds` maps store serialized Variant objects that contain lower or upper bounds respectively. The object keys for the bound-variants are normalized JSON path expressions that uniquely identify a field. The object values are primitive Variant representations of the lower or upper bound for that field. Including bounds for any field is optional and upper and lower bounds must have the same Variant type. +Field statistics (or, interchangeably, metrics) are used when filtering to select data and delete files. + +In v3 and earlier, metrics are stored in maps keyed by column id: `value_counts`, `null_value_counts`, `nan_value_counts`, `lower_bounds` and `upper_bounds`. + +In v4, metrics are stored as typed values in the `content_stats` struct, documented in the [Content Stats](#content-stats) section. + +Both representations store equivalent information. If a map or id in a map is missing in v3, it is equivalent to a `null` value or missing field struct in v4. Lower bounds must be less than or equal to all non-null and non-NaN values and upper bounds must be greater than or equal to all non-null and non-NaN values. + +For delete files, metrics must store bounds and counts for all deleted rows, or must be omitted. Storing metrics for deleted rows ensures that the values can be used during job planning to find delete files that must be merged during a scan. + +###### Bounds for Geometry and Geography + +For `geometry` and `geography` types, `lower_bounds` and `upper_bounds` are points with coordinates X, Y, Z (optional), and M (optional) that represent the lower and upper bounds of a bounding box that contains all objects in the file. + +For `geography` only, xmin (X value of `lower_bounds`) may be greater than xmax (X value of `upper_bounds`), in which case an object in this bounding box may match if it contains an X such that x >= xmin OR x <= xmax. In geographic terminology, the concepts of xmin, xmax, ymin, and ymax are also known as westernmost, easternmost, southernmost and northernmost, respectively. These points are further restricted to the canonical ranges of [-180..180] for X and [-90..90] for Y. + +When calculating upper and lower bounds for `geometry` and `geography`, null or NaN values in a coordinate dimension are skipped; for example, POINT (1 NaN) contributes a value to X but no values to Y, Z, or M dimension bounds. If a dimension has only null or NaN values, that dimension is omitted from the bounding box. If either the X or Y dimension is missing then the bounding box itself is not produced. + +In v3, lower and upper bound points are serialized as binary (see [Bound Serialization](#bound-serialization) in Appendix D). In v4, bounds are stored in `geo_lower` and `geo_upper` structs (see [Content Stats](#content-stats)). + +###### Bounds for Variant + +For Variant, lower and upper bound values store Variant objects that contain lower or upper bounds, respectively, for fields within the variant. The object keys for the bound-variants are normalized JSON path expressions that uniquely identify a field. The object values are primitive Variant representations of the lower or upper bound for that field. Including bounds for any field is optional and upper and lower bounds must have the same Variant type. Review Comment: > For the last line here, "Variant Type" means they contain the same schema? Good question. This is pre-existing so I want to first note that it is not a blocker for this PR. I believe that the idea here is that all of the fields in the lower bound variant must also be fields of the upper bound variant. That way if your data has field `ts`, you should have both lower and upper bounds for `$["ts"]` or neither one. However, I think this is not a good way to state that requirement, since we don't talk about variants having schemas anywhere else. I'll update this in a follow-up. > Why do we have to store them in a variant now with content struct? Can't we just do a typed struct? If we did, we would run into the same issues as variant shredding: there isn't a good way to assign and track IDs, and the values could all have different types (upper and lower may match, but only for a single data file). The solution to these is to use a `variant` and allow it to be shredded. This takes the first step and specifies that the type is `variant`. But there's a problem with shredding: some idiot (me) thought it was a great idea to use JSON path expressions as the keys so we could have a flat map-like structure and not need to perform multiple lookups for nested fields. But when we think about shredding that structure we would have to create Parquet fields with names like `$["ts"]`. We can check whether Parquet allows and handles these names across implementations, or we can change to a nested representation by original field name. The reason why I left this as unshredded (the note about not shredding is below in the v4 content stats section) is that I don't want to depend on that to get this in. Definitely happy to talk about solving this for v4 though! -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected] --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
