question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Core: Dropping an old partition column causes NPE (and corrupt metadata on v2 tables)

See original GitHub issue

Apache Iceberg version

0.14.0 (latest release)

Query engine

Spark

Please describe the bug 🐞

On a format version 2 table, dropping an old partition column on an iceberg table causes a NullPointerException in PartitionSpecBuilder, and every subsequent operation on the table throws the same exception.

java.lang.NullPointerException: Cannot find source column: 2
	at org.apache.iceberg.relocated.com.google.common.base.Preconditions.checkNotNull(Preconditions.java:963)
	at org.apache.iceberg.PartitionSpec$Builder.add(PartitionSpec.java:517)
	at org.apache.iceberg.UnboundPartitionSpec.copyToBuilder(UnboundPartitionSpec.java:56)
	at org.apache.iceberg.UnboundPartitionSpec.bind(UnboundPartitionSpec.java:44)
	at org.apache.iceberg.PartitionSpecParser.fromJson(PartitionSpecParser.java:87)

On a v1 table, the table is still accessible after, but the ALTER TABLE throws the same NPE.

The issue is easily reproducible using the following script in a Spark Shell:

CREATE TABLE data.test_table (ts timestamp not null, day_of_ts date) USING iceberg PARTITIONED BY (day_of_ts);
ALTER TABLE data.test_table SET TBLPROPERTIES ('format-version' = '2');
ALTER TABLE data.test_table REPLACE PARTITION FIELD day_of_ts WITH days(ts);
ALTER TABLE data.test_table DROP COLUMN day_of_ts;
REFRESH TABLE data.test_table;
SELECT * FROM data.test_table;

On closer inspection of the metadata, I see that on a v1 table, the metadata is not updated when dropping the old partition field, which explains why the table is still working on v1 after, but I also don’t see what the issue is with the v2 metadata.

I am using Spark Shell on Spark 3.3.0 with Iceberg 0.14.0

Issue Analytics

  • State:closed
  • Created a year ago
  • Comments:10 (7 by maintainers)

github_iconTop GitHub Comments

2reactions
singhpk234commented, Sep 1, 2022

As per my understanding, I think the issue here is that we are trying to bind all partition specs to to current schema which will always not be possible.

For ex : we find current schema and assign this to local var schema

https://github.com/apache/iceberg/blob/84f40cff9b98ee15b706289e551078355bb8a7a5/core/src/main/java/org/apache/iceberg/TableMetadataParser.java#L344-L351

we bind all partition specs to the schema which is equal to current schema

https://github.com/apache/iceberg/blob/84f40cff9b98ee15b706289e551078355bb8a7a5/core/src/main/java/org/apache/iceberg/TableMetadataParser.java#L381-L385

which is where I think it’s failing as we have dropped day_of_ts so current schema doesn’t have this and partition spec 0 (initial partitioning ) has reference to day_of_ts hence it’s failing to bind it.

1reaction
Fokkocommented, Sep 1, 2022

@kbendick The tests are different, it doesn’t drop the source column.

I did some digging around in the code, and we bind the partition spec right away because we need the column type for the transform:

    Builder add(int sourceId, int fieldId, String name, String transform) {
      Types.NestedField column = schema.findField(sourceId);
      Preconditions.checkNotNull(column, "Cannot find source column: %s", sourceId);
      return add(sourceId, fieldId, name, Transforms.fromString(column.type(), transform));
    }

There is a PR https://github.com/apache/iceberg/pull/5601 that will decouple this, and then we can also solve this issue.

A simple test reproduces this behavior:

  @Test
  public void testDropColumnOfOldPartitionField() {
    sql("CREATE TABLE %s (id bigint NOT NULL, ts timestamp, day_of_ts date) USING iceberg PARTITIONED BY (day_of_ts)", tableName);

    sql("ALTER TABLE %s  SET TBLPROPERTIES ('format-version' = '2');", tableName);

    sql("ALTER TABLE %s REPLACE PARTITION FIELD day_of_ts WITH days(ts)", tableName);

    sql("ALTER TABLE %s DROP COLUMN day_of_ts", tableName);
  }

I think this should be quite straightforward to fix this once https://github.com/apache/iceberg/pull/5601 has been merged

Read more comments on GitHub >

github_iconTop Results From Across the Web

issues - The Mail Archive
... 2022/09/30 [GitHub] [iceberg] rdblue closed issue #5676: Core: Dropping an old partition column causes NPE (and corrupt metadata on v2 tables) GitBox ......
Read more >
Releases - Apache Iceberg
Fixed partition field IDs in table replacement [#2906]. Hive. Enabled dropping HMS tables even if the metadata on disk gets corrupted [#2583]. Parquet....
Read more >
Fixed Issues in Apache Impala | 5.x - Cloudera Documentation
IMPALA-4315 - Allow USE and SHOW TABLES if there is at least one table in a database where the user has table or...
Read more >
FIX: Database corruption if data compression enabled on a ...
Cause. This issue occurs because the accessor that SQL Server uses to insert data into different partitions recognizes the metadata changes incorrectly.
Read more >
Release Notes for IIDR 11.4 Replication Engines for Linux ...
Improved replication into tables that have identity column on the target in MS SQL ... JR63301 IDR ORACLE FASTLOAD REFRESH CAN CAUSE A...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found