You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@iceberg.apache.org by "binayakd (via GitHub)" <gi...@apache.org> on 2024/11/21 02:43:51 UTC
[PR] fix `KeyError` raised by `add_files` when parquet file doe not have column stats [iceberg-python]
binayakd opened a new pull request, #1354:
URL: https://github.com/apache/iceberg-python/pull/1354
Resolves #1353, by switching `del` with `pop` to prevent `KeyError`.
--
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: issues-unsubscribe@iceberg.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@iceberg.apache.org
For additional commands, e-mail: issues-help@iceberg.apache.org
Re: [PR] fix `KeyError` raised by `add_files` when parquet file doe not have column stats [iceberg-python]
Posted by "binayakd (via GitHub)" <gi...@apache.org>.
binayakd commented on PR #1354:
URL: https://github.com/apache/iceberg-python/pull/1354#issuecomment-2490391612
@Fokko I have added the unit test, hopefully its up to make.
--
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: issues-unsubscribe@iceberg.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@iceberg.apache.org
For additional commands, e-mail: issues-help@iceberg.apache.org
Re: [PR] fix `KeyError` raised by `add_files` when parquet file doe not have column stats [iceberg-python]
Posted by "binayakd (via GitHub)" <gi...@apache.org>.
binayakd commented on code in PR #1354:
URL: https://github.com/apache/iceberg-python/pull/1354#discussion_r1853343720
##########
tests/io/test_pyarrow_stats.py:
##########
@@ -681,6 +681,73 @@ def test_stats_types(table_schema_nested: Schema) -> None:
]
+def construct_test_table_without_stats() -> Tuple[pq.FileMetaData, Union[TableMetadataV1, TableMetadataV2]]:
Review Comment:
Updated the existing function to take in a `write_statistics` argument, which can be `bool` or `list`:
```python
def construct_test_table(
write_statistics: bool | List[str] = True,
) -> Tuple[pq.FileMetaData, Union[TableMetadataV1, TableMetadataV2]]:
```
so that it can passed directly to the `ParquetWriter`:
```python
with pa.BufferOutputStream() as f:
with pq.ParquetWriter(
f, table.schema, metadata_collector=metadata_collector, write_statistics=write_statistics
) as writer:
writer.write_table(table)
```
--
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: issues-unsubscribe@iceberg.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@iceberg.apache.org
For additional commands, e-mail: issues-help@iceberg.apache.org
Re: [PR] fix `KeyError` raised by `add_files` when parquet file doe not have column stats [iceberg-python]
Posted by "binayakd (via GitHub)" <gi...@apache.org>.
binayakd commented on code in PR #1354:
URL: https://github.com/apache/iceberg-python/pull/1354#discussion_r1853344003
##########
tests/io/test_pyarrow_stats.py:
##########
@@ -681,6 +681,73 @@ def test_stats_types(table_schema_nested: Schema) -> None:
]
+def construct_test_table_without_stats() -> Tuple[pq.FileMetaData, Union[TableMetadataV1, TableMetadataV2]]:
+ table_metadata = {
+ "format-version": 2,
+ "location": "s3://bucket/test/location",
+ "last-column-id": 7,
+ "current-schema-id": 0,
+ "schemas": [
+ {
+ "type": "struct",
+ "schema-id": 0,
+ "fields": [
+ {"id": 1, "name": "strings", "required": False, "type": "string"},
+ {"id": 2, "name": "floats", "required": False, "type": "float"}
+ ]
+ }
+ ],
+ "default-spec-id": 0,
+ "partition-specs": [{"spec-id": 0, "fields": []}],
+ "properties": {},
+ }
+
+ table_metadata = TableMetadataUtil.parse_obj(table_metadata)
+ arrow_schema = schema_to_pyarrow(table_metadata.schemas[0])
+ _strings = ["zzzzzzzzzzzzzzzzzzzz", "rrrrrrrrrrrrrrrrrrrr", None, "aaaaaaaaaaaaaaaaaaaa"]
+ _floats = [3.14, math.nan, 1.69, 100]
+
+ table = pa.Table.from_pydict(
+ {
+ "strings": _strings,
+ "floats": _floats
+ },
+ schema=arrow_schema,
+ )
+
+ metadata_collector: List[Any] = []
+
+ with pa.BufferOutputStream() as f:
+ with pq.ParquetWriter(f, table.schema, metadata_collector=metadata_collector, write_statistics=False) as writer:
+ writer.write_table(table)
+
+ return metadata_collector[0], table_metadata
+
+
+def test_is_stats_set_false() -> None:
Review Comment:
Updated the test function name to this.
--
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: issues-unsubscribe@iceberg.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@iceberg.apache.org
For additional commands, e-mail: issues-help@iceberg.apache.org
Re: [PR] fix `KeyError` raised by `add_files` when parquet file doe not have column stats [iceberg-python]
Posted by "kevinjqliu (via GitHub)" <gi...@apache.org>.
kevinjqliu commented on code in PR #1354:
URL: https://github.com/apache/iceberg-python/pull/1354#discussion_r1852506143
##########
tests/io/test_pyarrow_stats.py:
##########
@@ -681,6 +681,73 @@ def test_stats_types(table_schema_nested: Schema) -> None:
]
+def construct_test_table_without_stats() -> Tuple[pq.FileMetaData, Union[TableMetadataV1, TableMetadataV2]]:
Review Comment:
nit: this seems to be similar to `construct_test_table` above, wydt of adding a parameter to `construct_test_table` to control stat generation?
```
def construct_test_table(write_statistics: bool = True) -> Tuple[pq.FileMetaData, Union[TableMetadataV1, TableMetadataV2]]:
```
that way, we don't need this extra function
##########
tests/io/test_pyarrow_stats.py:
##########
@@ -681,6 +681,73 @@ def test_stats_types(table_schema_nested: Schema) -> None:
]
+def construct_test_table_without_stats() -> Tuple[pq.FileMetaData, Union[TableMetadataV1, TableMetadataV2]]:
+ table_metadata = {
+ "format-version": 2,
+ "location": "s3://bucket/test/location",
+ "last-column-id": 7,
+ "current-schema-id": 0,
+ "schemas": [
+ {
+ "type": "struct",
+ "schema-id": 0,
+ "fields": [
+ {"id": 1, "name": "strings", "required": False, "type": "string"},
+ {"id": 2, "name": "floats", "required": False, "type": "float"}
+ ]
+ }
+ ],
+ "default-spec-id": 0,
+ "partition-specs": [{"spec-id": 0, "fields": []}],
+ "properties": {},
+ }
+
+ table_metadata = TableMetadataUtil.parse_obj(table_metadata)
+ arrow_schema = schema_to_pyarrow(table_metadata.schemas[0])
+ _strings = ["zzzzzzzzzzzzzzzzzzzz", "rrrrrrrrrrrrrrrrrrrr", None, "aaaaaaaaaaaaaaaaaaaa"]
+ _floats = [3.14, math.nan, 1.69, 100]
+
+ table = pa.Table.from_pydict(
+ {
+ "strings": _strings,
+ "floats": _floats
+ },
+ schema=arrow_schema,
+ )
+
+ metadata_collector: List[Any] = []
+
+ with pa.BufferOutputStream() as f:
+ with pq.ParquetWriter(f, table.schema, metadata_collector=metadata_collector, write_statistics=False) as writer:
+ writer.write_table(table)
+
+ return metadata_collector[0], table_metadata
+
+
+def test_is_stats_set_false() -> None:
+ metadata, table_metadata = construct_test_table_without_stats()
+ schema = get_current_schema(table_metadata)
+ statistics = data_file_statistics_from_parquet_metadata(
+ parquet_metadata=metadata,
+ stats_columns=compute_statistics_plan(schema, table_metadata.properties),
+ parquet_column_mapping=parquet_path_to_id_mapping(schema),
+ )
+ datafile = DataFile(**statistics.to_serialized_dict())
+
+ # assert attributes except for column_aggregates and null_value_counts are present
Review Comment:
I think the error case is when the `parquet_metadata` for `data_file_statistics_from_parquet_metadata` does not have specific `col_aggs` and `null_value_counts`, leading the function to error.
in that case, can we assert that the input (`metadata`) does not contain them, and maybe assert that the output (`datafile`) also doesn't contain them.
this function should fail without the `pyarrow` change above
##########
tests/io/test_pyarrow_stats.py:
##########
@@ -681,6 +681,73 @@ def test_stats_types(table_schema_nested: Schema) -> None:
]
+def construct_test_table_without_stats() -> Tuple[pq.FileMetaData, Union[TableMetadataV1, TableMetadataV2]]:
Review Comment:
looks like write_statistics can also take in a list
https://arrow.apache.org/docs/python/generated/pyarrow.parquet.ParquetWriter.html
##########
tests/io/test_pyarrow_stats.py:
##########
@@ -681,6 +681,73 @@ def test_stats_types(table_schema_nested: Schema) -> None:
]
+def construct_test_table_without_stats() -> Tuple[pq.FileMetaData, Union[TableMetadataV1, TableMetadataV2]]:
+ table_metadata = {
+ "format-version": 2,
+ "location": "s3://bucket/test/location",
+ "last-column-id": 7,
+ "current-schema-id": 0,
+ "schemas": [
+ {
+ "type": "struct",
+ "schema-id": 0,
+ "fields": [
+ {"id": 1, "name": "strings", "required": False, "type": "string"},
+ {"id": 2, "name": "floats", "required": False, "type": "float"}
+ ]
+ }
+ ],
+ "default-spec-id": 0,
+ "partition-specs": [{"spec-id": 0, "fields": []}],
+ "properties": {},
+ }
+
+ table_metadata = TableMetadataUtil.parse_obj(table_metadata)
+ arrow_schema = schema_to_pyarrow(table_metadata.schemas[0])
+ _strings = ["zzzzzzzzzzzzzzzzzzzz", "rrrrrrrrrrrrrrrrrrrr", None, "aaaaaaaaaaaaaaaaaaaa"]
+ _floats = [3.14, math.nan, 1.69, 100]
+
+ table = pa.Table.from_pydict(
+ {
+ "strings": _strings,
+ "floats": _floats
+ },
+ schema=arrow_schema,
+ )
+
+ metadata_collector: List[Any] = []
+
+ with pa.BufferOutputStream() as f:
+ with pq.ParquetWriter(f, table.schema, metadata_collector=metadata_collector, write_statistics=False) as writer:
+ writer.write_table(table)
+
+ return metadata_collector[0], table_metadata
+
+
+def test_is_stats_set_false() -> None:
Review Comment:
nit: maybe something like, `test_read_missing_statistics`
--
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: issues-unsubscribe@iceberg.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@iceberg.apache.org
For additional commands, e-mail: issues-help@iceberg.apache.org
Re: [PR] fix `KeyError` raised by `add_files` when parquet file doe not have column stats [iceberg-python]
Posted by "Fokko (via GitHub)" <gi...@apache.org>.
Fokko commented on PR #1354:
URL: https://github.com/apache/iceberg-python/pull/1354#issuecomment-2491751808
@binayakd Thanks for adding these tests 👍 Can you run `make lint` to fix the formatting issues?
--
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: issues-unsubscribe@iceberg.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@iceberg.apache.org
For additional commands, e-mail: issues-help@iceberg.apache.org
Re: [PR] fix `KeyError` raised by `add_files` when parquet file doe not have column stats [iceberg-python]
Posted by "binayakd (via GitHub)" <gi...@apache.org>.
binayakd commented on PR #1354:
URL: https://github.com/apache/iceberg-python/pull/1354#issuecomment-2496921401
@kevinjqliu pushed the test readability fix. Thanks!
--
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: issues-unsubscribe@iceberg.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@iceberg.apache.org
For additional commands, e-mail: issues-help@iceberg.apache.org
Re: [PR] fix `KeyError` raised by `add_files` when parquet file doe not have column stats [iceberg-python]
Posted by "kevinjqliu (via GitHub)" <gi...@apache.org>.
kevinjqliu commented on code in PR #1354:
URL: https://github.com/apache/iceberg-python/pull/1354#discussion_r1855235419
##########
tests/io/test_pyarrow_stats.py:
##########
@@ -681,6 +685,39 @@ def test_stats_types(table_schema_nested: Schema) -> None:
]
+def test_read_missing_statistics() -> None:
+ # write statistics for only for "strings" column
+ metadata, table_metadata = construct_test_table(write_statistics=["strings"])
+
+ # expect only "strings" column to have statistics in metadata
+ assert metadata.row_group(0).column(0).is_stats_set is True
+ assert metadata.row_group(0).column(0).statistics is not None
+
+ # expect all other columns to have no statistics
+ for r in range(metadata.num_row_groups):
+ for pos in range(1, metadata.num_columns):
+ assert metadata.row_group(r).column(pos).is_stats_set is False
+ assert metadata.row_group(r).column(pos).statistics is None
+
+ schema = get_current_schema(table_metadata)
+ statistics = data_file_statistics_from_parquet_metadata(
+ parquet_metadata=metadata,
+ stats_columns=compute_statistics_plan(schema, table_metadata.properties),
+ parquet_column_mapping=parquet_path_to_id_mapping(schema),
+ )
+
+ datafile = DataFile(**statistics.to_serialized_dict())
+
+ # expect only "strings" column values to be reflected in the
+ # upper_bound, lower_bound and null_value_counts props of datafile
+ assert len(datafile.lower_bounds) == 1
+ assert datafile.lower_bounds[1].decode() == "aaaaaaaaaaaaaaaa"
Review Comment:
ah i see, for readability, wdyt about something like
```
string_col_idx = 1
datafile.lower_bounds[string_col_idx]
```
##########
tests/io/test_pyarrow_stats.py:
##########
@@ -681,6 +685,39 @@ def test_stats_types(table_schema_nested: Schema) -> None:
]
+def test_read_missing_statistics() -> None:
+ # write statistics for only for "strings" column
+ metadata, table_metadata = construct_test_table(write_statistics=["strings"])
+
+ # expect only "strings" column to have statistics in metadata
+ assert metadata.row_group(0).column(0).is_stats_set is True
+ assert metadata.row_group(0).column(0).statistics is not None
+
+ # expect all other columns to have no statistics
+ for r in range(metadata.num_row_groups):
+ for pos in range(1, metadata.num_columns):
+ assert metadata.row_group(r).column(pos).is_stats_set is False
+ assert metadata.row_group(r).column(pos).statistics is None
+
+ schema = get_current_schema(table_metadata)
+ statistics = data_file_statistics_from_parquet_metadata(
+ parquet_metadata=metadata,
+ stats_columns=compute_statistics_plan(schema, table_metadata.properties),
+ parquet_column_mapping=parquet_path_to_id_mapping(schema),
+ )
+
+ datafile = DataFile(**statistics.to_serialized_dict())
+
+ # expect only "strings" column values to be reflected in the
+ # upper_bound, lower_bound and null_value_counts props of datafile
+ assert len(datafile.lower_bounds) == 1
+ assert datafile.lower_bounds[1].decode() == "aaaaaaaaaaaaaaaa"
+ assert len(datafile.upper_bounds) == 1
+ assert datafile.upper_bounds[1].decode() == "zzzzzzzzzzzzzzz{"
+ assert len(datafile.null_value_counts) == 1
+ assert datafile.null_value_counts[1] == 1
Review Comment:
ah https://github.com/apache/iceberg-python/blob/939d325693e5a484bed0377310d49f04eb1fef31/pyiceberg/io/pyarrow.py#L2305-L2306
its calculated in `to_serialized_dict`. `column_aggregates` is converted to `lower_bounds` and `upper_bounds`
##########
tests/io/test_pyarrow_stats.py:
##########
@@ -681,6 +685,39 @@ def test_stats_types(table_schema_nested: Schema) -> None:
]
+def test_read_missing_statistics() -> None:
+ # write statistics for only for "strings" column
+ metadata, table_metadata = construct_test_table(write_statistics=["strings"])
+
+ # expect only "strings" column to have statistics in metadata
+ assert metadata.row_group(0).column(0).is_stats_set is True
+ assert metadata.row_group(0).column(0).statistics is not None
+
+ # expect all other columns to have no statistics
+ for r in range(metadata.num_row_groups):
+ for pos in range(1, metadata.num_columns):
+ assert metadata.row_group(r).column(pos).is_stats_set is False
+ assert metadata.row_group(r).column(pos).statistics is None
+
+ schema = get_current_schema(table_metadata)
+ statistics = data_file_statistics_from_parquet_metadata(
+ parquet_metadata=metadata,
+ stats_columns=compute_statistics_plan(schema, table_metadata.properties),
+ parquet_column_mapping=parquet_path_to_id_mapping(schema),
+ )
+
+ datafile = DataFile(**statistics.to_serialized_dict())
+
+ # expect only "strings" column values to be reflected in the
+ # upper_bound, lower_bound and null_value_counts props of datafile
+ assert len(datafile.lower_bounds) == 1
+ assert datafile.lower_bounds[1].decode() == "aaaaaaaaaaaaaaaa"
+ assert len(datafile.upper_bounds) == 1
+ assert datafile.upper_bounds[1].decode() == "zzzzzzzzzzzzzzz{"
+ assert len(datafile.null_value_counts) == 1
+ assert datafile.null_value_counts[1] == 1
Review Comment:
we can check the `statistics` variable, but I'm now wondering if we forgot to propagate `column_aggregates` to DataFile.
Otherwise, why even [update `column_aggregates`](https://github.com/apache/iceberg-python/blob/939d325693e5a484bed0377310d49f04eb1fef31/pyiceberg/io/pyarrow.py#L2387-L2388)?
##########
tests/io/test_pyarrow_stats.py:
##########
@@ -681,6 +685,39 @@ def test_stats_types(table_schema_nested: Schema) -> None:
]
+def test_read_missing_statistics() -> None:
+ # write statistics for only for "strings" column
+ metadata, table_metadata = construct_test_table(write_statistics=["strings"])
+
+ # expect only "strings" column to have statistics in metadata
+ assert metadata.row_group(0).column(0).is_stats_set is True
+ assert metadata.row_group(0).column(0).statistics is not None
+
+ # expect all other columns to have no statistics
+ for r in range(metadata.num_row_groups):
+ for pos in range(1, metadata.num_columns):
+ assert metadata.row_group(r).column(pos).is_stats_set is False
+ assert metadata.row_group(r).column(pos).statistics is None
+
+ schema = get_current_schema(table_metadata)
+ statistics = data_file_statistics_from_parquet_metadata(
+ parquet_metadata=metadata,
+ stats_columns=compute_statistics_plan(schema, table_metadata.properties),
+ parquet_column_mapping=parquet_path_to_id_mapping(schema),
+ )
+
+ datafile = DataFile(**statistics.to_serialized_dict())
+
+ # expect only "strings" column values to be reflected in the
+ # upper_bound, lower_bound and null_value_counts props of datafile
+ assert len(datafile.lower_bounds) == 1
+ assert datafile.lower_bounds[1].decode() == "aaaaaaaaaaaaaaaa"
+ assert len(datafile.upper_bounds) == 1
+ assert datafile.upper_bounds[1].decode() == "zzzzzzzzzzzzzzz{"
+ assert len(datafile.null_value_counts) == 1
+ assert datafile.null_value_counts[1] == 1
Review Comment:
and those are checked in the test already! thanks
##########
tests/io/test_pyarrow_stats.py:
##########
@@ -681,6 +685,39 @@ def test_stats_types(table_schema_nested: Schema) -> None:
]
+def test_read_missing_statistics() -> None:
+ # write statistics for only for "strings" column
+ metadata, table_metadata = construct_test_table(write_statistics=["strings"])
+
+ # expect only "strings" column to have statistics in metadata
+ assert metadata.row_group(0).column(0).is_stats_set is True
+ assert metadata.row_group(0).column(0).statistics is not None
+
+ # expect all other columns to have no statistics
+ for r in range(metadata.num_row_groups):
+ for pos in range(1, metadata.num_columns):
+ assert metadata.row_group(r).column(pos).is_stats_set is False
+ assert metadata.row_group(r).column(pos).statistics is None
+
+ schema = get_current_schema(table_metadata)
+ statistics = data_file_statistics_from_parquet_metadata(
+ parquet_metadata=metadata,
+ stats_columns=compute_statistics_plan(schema, table_metadata.properties),
+ parquet_column_mapping=parquet_path_to_id_mapping(schema),
+ )
+
+ datafile = DataFile(**statistics.to_serialized_dict())
+
+ # expect only "strings" column values to be reflected in the
+ # upper_bound, lower_bound and null_value_counts props of datafile
+ assert len(datafile.lower_bounds) == 1
+ assert datafile.lower_bounds[1].decode() == "aaaaaaaaaaaaaaaa"
+ assert len(datafile.upper_bounds) == 1
+ assert datafile.upper_bounds[1].decode() == "zzzzzzzzzzzzzzz{"
+ assert len(datafile.null_value_counts) == 1
+ assert datafile.null_value_counts[1] == 1
Review Comment:
weird, [`DataFileStatistics` sets the `column_aggregates`](https://github.com/apache/iceberg-python/blob/939d325693e5a484bed0377310d49f04eb1fef31/pyiceberg/io/pyarrow.py#L2409), which does not exist in [DataFile](https://github.com/apache/iceberg-python/blob/63169004facb053d3ac3725388411ee7a05c4156/pyiceberg/manifest.py#L311-L330)
--
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: issues-unsubscribe@iceberg.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@iceberg.apache.org
For additional commands, e-mail: issues-help@iceberg.apache.org
Re: [PR] fix `KeyError` raised by `add_files` when parquet file doe not have column stats [iceberg-python]
Posted by "binayakd (via GitHub)" <gi...@apache.org>.
binayakd commented on PR #1354:
URL: https://github.com/apache/iceberg-python/pull/1354#issuecomment-2495238970
Pushed a change to fix the python 3.9 compatibility and updated the test based on the comment, @kevinjqliu. Thanks!
--
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: issues-unsubscribe@iceberg.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@iceberg.apache.org
For additional commands, e-mail: issues-help@iceberg.apache.org
Re: [PR] fix `KeyError` raised by `add_files` when parquet file doe not have column stats [iceberg-python]
Posted by "binayakd (via GitHub)" <gi...@apache.org>.
binayakd commented on code in PR #1354:
URL: https://github.com/apache/iceberg-python/pull/1354#discussion_r1855019099
##########
tests/io/test_pyarrow_stats.py:
##########
@@ -681,6 +685,39 @@ def test_stats_types(table_schema_nested: Schema) -> None:
]
+def test_read_missing_statistics() -> None:
+ # write statistics for only for "strings" column
+ metadata, table_metadata = construct_test_table(write_statistics=["strings"])
+
+ # expect only "strings" column to have statistics in metadata
+ assert metadata.row_group(0).column(0).is_stats_set is True
+ assert metadata.row_group(0).column(0).statistics is not None
+
+ # expect all other columns to have no statistics
+ for r in range(metadata.num_row_groups):
+ for pos in range(1, metadata.num_columns):
+ assert metadata.row_group(r).column(pos).is_stats_set is False
+ assert metadata.row_group(r).column(pos).statistics is None
+
+ schema = get_current_schema(table_metadata)
+ statistics = data_file_statistics_from_parquet_metadata(
+ parquet_metadata=metadata,
+ stats_columns=compute_statistics_plan(schema, table_metadata.properties),
+ parquet_column_mapping=parquet_path_to_id_mapping(schema),
+ )
+
+ datafile = DataFile(**statistics.to_serialized_dict())
+
+ # expect only "strings" column values to be reflected in the
+ # upper_bound, lower_bound and null_value_counts props of datafile
+ assert len(datafile.lower_bounds) == 1
+ assert datafile.lower_bounds[1].decode() == "aaaaaaaaaaaaaaaa"
Review Comment:
There the bounds attributes are actually Dicts, and `1` is the key to access the values for the column in position 1, the "strings" column. So looks like Pyarrow sets up the column positions with 1 index.
--
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: issues-unsubscribe@iceberg.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@iceberg.apache.org
For additional commands, e-mail: issues-help@iceberg.apache.org
Re: [PR] fix `KeyError` raised by `add_files` when parquet file doe not have column stats [iceberg-python]
Posted by "binayakd (via GitHub)" <gi...@apache.org>.
binayakd commented on code in PR #1354:
URL: https://github.com/apache/iceberg-python/pull/1354#discussion_r1855024655
##########
tests/io/test_pyarrow_stats.py:
##########
@@ -681,6 +685,39 @@ def test_stats_types(table_schema_nested: Schema) -> None:
]
+def test_read_missing_statistics() -> None:
+ # write statistics for only for "strings" column
+ metadata, table_metadata = construct_test_table(write_statistics=["strings"])
+
+ # expect only "strings" column to have statistics in metadata
+ assert metadata.row_group(0).column(0).is_stats_set is True
+ assert metadata.row_group(0).column(0).statistics is not None
+
+ # expect all other columns to have no statistics
+ for r in range(metadata.num_row_groups):
+ for pos in range(1, metadata.num_columns):
+ assert metadata.row_group(r).column(pos).is_stats_set is False
+ assert metadata.row_group(r).column(pos).statistics is None
Review Comment:
Pushed the change to combine the checks as you suggested. Thanks!
--
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: issues-unsubscribe@iceberg.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@iceberg.apache.org
For additional commands, e-mail: issues-help@iceberg.apache.org
Re: [PR] fix `KeyError` raised by `add_files` when parquet file doe not have column stats [iceberg-python]
Posted by "binayakd (via GitHub)" <gi...@apache.org>.
binayakd commented on PR #1354:
URL: https://github.com/apache/iceberg-python/pull/1354#issuecomment-2492978374
@kevinjqliu, @Fokko, pushed the linting fix, and also updated the test based on the suggestions. Thank you!
--
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: issues-unsubscribe@iceberg.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@iceberg.apache.org
For additional commands, e-mail: issues-help@iceberg.apache.org
Re: [PR] fix `KeyError` raised by `add_files` when parquet file doe not have column stats [iceberg-python]
Posted by "binayakd (via GitHub)" <gi...@apache.org>.
binayakd commented on code in PR #1354:
URL: https://github.com/apache/iceberg-python/pull/1354#discussion_r1855021256
##########
tests/io/test_pyarrow_stats.py:
##########
@@ -681,6 +685,39 @@ def test_stats_types(table_schema_nested: Schema) -> None:
]
+def test_read_missing_statistics() -> None:
+ # write statistics for only for "strings" column
+ metadata, table_metadata = construct_test_table(write_statistics=["strings"])
+
+ # expect only "strings" column to have statistics in metadata
+ assert metadata.row_group(0).column(0).is_stats_set is True
+ assert metadata.row_group(0).column(0).statistics is not None
+
+ # expect all other columns to have no statistics
+ for r in range(metadata.num_row_groups):
+ for pos in range(1, metadata.num_columns):
+ assert metadata.row_group(r).column(pos).is_stats_set is False
+ assert metadata.row_group(r).column(pos).statistics is None
+
+ schema = get_current_schema(table_metadata)
+ statistics = data_file_statistics_from_parquet_metadata(
+ parquet_metadata=metadata,
+ stats_columns=compute_statistics_plan(schema, table_metadata.properties),
+ parquet_column_mapping=parquet_path_to_id_mapping(schema),
+ )
+
+ datafile = DataFile(**statistics.to_serialized_dict())
+
+ # expect only "strings" column values to be reflected in the
+ # upper_bound, lower_bound and null_value_counts props of datafile
+ assert len(datafile.lower_bounds) == 1
+ assert datafile.lower_bounds[1].decode() == "aaaaaaaaaaaaaaaa"
+ assert len(datafile.upper_bounds) == 1
+ assert datafile.upper_bounds[1].decode() == "zzzzzzzzzzzzzzz{"
+ assert len(datafile.null_value_counts) == 1
+ assert datafile.null_value_counts[1] == 1
Review Comment:
`datafile` doesn't have a direct `col_aggs` attribute, but the bounds attributes gets set based on that. I saw that the other tests also assert on this, so i followed this.
--
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: issues-unsubscribe@iceberg.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@iceberg.apache.org
For additional commands, e-mail: issues-help@iceberg.apache.org
Re: [PR] fix `KeyError` raised by `add_files` when parquet file doe not have column stats [iceberg-python]
Posted by "binayakd (via GitHub)" <gi...@apache.org>.
binayakd commented on code in PR #1354:
URL: https://github.com/apache/iceberg-python/pull/1354#discussion_r1853355886
##########
tests/io/test_pyarrow_stats.py:
##########
@@ -681,6 +681,73 @@ def test_stats_types(table_schema_nested: Schema) -> None:
]
+def construct_test_table_without_stats() -> Tuple[pq.FileMetaData, Union[TableMetadataV1, TableMetadataV2]]:
+ table_metadata = {
+ "format-version": 2,
+ "location": "s3://bucket/test/location",
+ "last-column-id": 7,
+ "current-schema-id": 0,
+ "schemas": [
+ {
+ "type": "struct",
+ "schema-id": 0,
+ "fields": [
+ {"id": 1, "name": "strings", "required": False, "type": "string"},
+ {"id": 2, "name": "floats", "required": False, "type": "float"}
+ ]
+ }
+ ],
+ "default-spec-id": 0,
+ "partition-specs": [{"spec-id": 0, "fields": []}],
+ "properties": {},
+ }
+
+ table_metadata = TableMetadataUtil.parse_obj(table_metadata)
+ arrow_schema = schema_to_pyarrow(table_metadata.schemas[0])
+ _strings = ["zzzzzzzzzzzzzzzzzzzz", "rrrrrrrrrrrrrrrrrrrr", None, "aaaaaaaaaaaaaaaaaaaa"]
+ _floats = [3.14, math.nan, 1.69, 100]
+
+ table = pa.Table.from_pydict(
+ {
+ "strings": _strings,
+ "floats": _floats
+ },
+ schema=arrow_schema,
+ )
+
+ metadata_collector: List[Any] = []
+
+ with pa.BufferOutputStream() as f:
+ with pq.ParquetWriter(f, table.schema, metadata_collector=metadata_collector, write_statistics=False) as writer:
+ writer.write_table(table)
+
+ return metadata_collector[0], table_metadata
+
+
+def test_is_stats_set_false() -> None:
+ metadata, table_metadata = construct_test_table_without_stats()
+ schema = get_current_schema(table_metadata)
+ statistics = data_file_statistics_from_parquet_metadata(
+ parquet_metadata=metadata,
+ stats_columns=compute_statistics_plan(schema, table_metadata.properties),
+ parquet_column_mapping=parquet_path_to_id_mapping(schema),
+ )
+ datafile = DataFile(**statistics.to_serialized_dict())
+
+ # assert attributes except for column_aggregates and null_value_counts are present
Review Comment:
Rewrote the test to use the test table but only with the "strings" column having statistics.
```python
# write statistics for only for "strings" column
metadata, table_metadata = construct_test_table(write_statistics=["strings"])
```
Added asserts to make sure the input metadata only has stats for the first (strings) column, and the rest don't have have any stats, specially the floats column (since the non-primitive columns get skipped in the iteration)
```python
# expect only "strings" column to have statistics in metadata
assert metadata.row_group(0).column(0).is_stats_set is True
assert metadata.row_group(0).column(0).statistics is not None
# expect all other columns to have no statistics
for r in range(metadata.num_row_groups):
for pos in range(1, metadata.num_columns):
assert metadata.row_group(r).column(pos).is_stats_set is False
assert metadata.row_group(r).column(pos).statistics is None
```
From what I understand `col_aggs` is used to compute the `upper_bound`, `lower_bound` if the `datafile`, so
then we assert that the `upper_bound`, `lower_bound` and `null_value_counts` props of the `datafile` reflect only the values from the "strings" column, and no error is thrown:
```python
# expect only "strings" column values to be reflected in the
# upper_bound, lower_bound and null_value_counts props of datafile
assert len(datafile.lower_bounds) == 1
assert datafile.lower_bounds[1].decode() == "aaaaaaaaaaaaaaaa"
assert len(datafile.upper_bounds) == 1
assert datafile.upper_bounds[1].decode() == "zzzzzzzzzzzzzzz{"
assert len(datafile.null_value_counts) == 1
assert datafile.null_value_counts[1] == 1
```
This should cover the case of some columns having stats, and some not? Not sure if its a valid case.
Hopefully this makes sense?
--
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: issues-unsubscribe@iceberg.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@iceberg.apache.org
For additional commands, e-mail: issues-help@iceberg.apache.org
Re: [PR] fix `KeyError` raised by `add_files` when parquet file doe not have column stats [iceberg-python]
Posted by "kevinjqliu (via GitHub)" <gi...@apache.org>.
kevinjqliu merged PR #1354:
URL: https://github.com/apache/iceberg-python/pull/1354
--
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: issues-unsubscribe@iceberg.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@iceberg.apache.org
For additional commands, e-mail: issues-help@iceberg.apache.org
Re: [PR] fix `KeyError` raised by `add_files` when parquet file doe not have column stats [iceberg-python]
Posted by "Fokko (via GitHub)" <gi...@apache.org>.
Fokko commented on PR #1354:
URL: https://github.com/apache/iceberg-python/pull/1354#issuecomment-2498113008
Gentle ping @kevinjqliu, so we can wrap the 0.8.1 release up :)
--
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: issues-unsubscribe@iceberg.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@iceberg.apache.org
For additional commands, e-mail: issues-help@iceberg.apache.org
Re: [PR] fix `KeyError` raised by `add_files` when parquet file doe not have column stats [iceberg-python]
Posted by "binayakd (via GitHub)" <gi...@apache.org>.
binayakd commented on PR #1354:
URL: https://github.com/apache/iceberg-python/pull/1354#issuecomment-2490301659
Thanks @Fokko! Yes that did come to mind, I was also thinking of its possible to create the stats on the fly, but though it might be left as an enhancement.
Ok let me try and add some unit tests.
--
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: issues-unsubscribe@iceberg.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@iceberg.apache.org
For additional commands, e-mail: issues-help@iceberg.apache.org
Re: [PR] fix `KeyError` raised by `add_files` when parquet file doe not have column stats [iceberg-python]
Posted by "kevinjqliu (via GitHub)" <gi...@apache.org>.
kevinjqliu commented on code in PR #1354:
URL: https://github.com/apache/iceberg-python/pull/1354#discussion_r1854238935
##########
tests/io/test_pyarrow_stats.py:
##########
@@ -681,6 +685,39 @@ def test_stats_types(table_schema_nested: Schema) -> None:
]
+def test_read_missing_statistics() -> None:
+ # write statistics for only for "strings" column
+ metadata, table_metadata = construct_test_table(write_statistics=["strings"])
+
+ # expect only "strings" column to have statistics in metadata
+ assert metadata.row_group(0).column(0).is_stats_set is True
+ assert metadata.row_group(0).column(0).statistics is not None
+
+ # expect all other columns to have no statistics
+ for r in range(metadata.num_row_groups):
+ for pos in range(1, metadata.num_columns):
+ assert metadata.row_group(r).column(pos).is_stats_set is False
+ assert metadata.row_group(r).column(pos).statistics is None
Review Comment:
nit, why does the range start at 1 here?
wdyt about combining both checks in a single loop?
if its `string` column, assert stat in metadata
if its not `string` column, assert no stat
##########
tests/io/test_pyarrow_stats.py:
##########
@@ -681,6 +685,39 @@ def test_stats_types(table_schema_nested: Schema) -> None:
]
+def test_read_missing_statistics() -> None:
+ # write statistics for only for "strings" column
+ metadata, table_metadata = construct_test_table(write_statistics=["strings"])
+
+ # expect only "strings" column to have statistics in metadata
+ assert metadata.row_group(0).column(0).is_stats_set is True
+ assert metadata.row_group(0).column(0).statistics is not None
+
+ # expect all other columns to have no statistics
+ for r in range(metadata.num_row_groups):
+ for pos in range(1, metadata.num_columns):
+ assert metadata.row_group(r).column(pos).is_stats_set is False
+ assert metadata.row_group(r).column(pos).statistics is None
+
+ schema = get_current_schema(table_metadata)
+ statistics = data_file_statistics_from_parquet_metadata(
+ parquet_metadata=metadata,
+ stats_columns=compute_statistics_plan(schema, table_metadata.properties),
+ parquet_column_mapping=parquet_path_to_id_mapping(schema),
+ )
+
+ datafile = DataFile(**statistics.to_serialized_dict())
+
+ # expect only "strings" column values to be reflected in the
+ # upper_bound, lower_bound and null_value_counts props of datafile
+ assert len(datafile.lower_bounds) == 1
+ assert datafile.lower_bounds[1].decode() == "aaaaaaaaaaaaaaaa"
Review Comment:
nit, if theres 1 item, i think we need to access [0], not [1]
##########
tests/io/test_pyarrow_stats.py:
##########
@@ -681,6 +685,39 @@ def test_stats_types(table_schema_nested: Schema) -> None:
]
+def test_read_missing_statistics() -> None:
+ # write statistics for only for "strings" column
+ metadata, table_metadata = construct_test_table(write_statistics=["strings"])
+
+ # expect only "strings" column to have statistics in metadata
+ assert metadata.row_group(0).column(0).is_stats_set is True
+ assert metadata.row_group(0).column(0).statistics is not None
+
+ # expect all other columns to have no statistics
+ for r in range(metadata.num_row_groups):
+ for pos in range(1, metadata.num_columns):
+ assert metadata.row_group(r).column(pos).is_stats_set is False
+ assert metadata.row_group(r).column(pos).statistics is None
+
+ schema = get_current_schema(table_metadata)
+ statistics = data_file_statistics_from_parquet_metadata(
+ parquet_metadata=metadata,
+ stats_columns=compute_statistics_plan(schema, table_metadata.properties),
+ parquet_column_mapping=parquet_path_to_id_mapping(schema),
+ )
+
+ datafile = DataFile(**statistics.to_serialized_dict())
+
+ # expect only "strings" column values to be reflected in the
+ # upper_bound, lower_bound and null_value_counts props of datafile
+ assert len(datafile.lower_bounds) == 1
+ assert datafile.lower_bounds[1].decode() == "aaaaaaaaaaaaaaaa"
+ assert len(datafile.upper_bounds) == 1
+ assert datafile.upper_bounds[1].decode() == "zzzzzzzzzzzzzzz{"
+ assert len(datafile.null_value_counts) == 1
+ assert datafile.null_value_counts[1] == 1
Review Comment:
nit, check for both `col_aggs` and `null_value_counts` since thats what this PR changes
--
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: issues-unsubscribe@iceberg.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@iceberg.apache.org
For additional commands, e-mail: issues-help@iceberg.apache.org