Open ebyhr opened 1 year ago
Marking this as "release-blocker", since it's a functionality regression present in master, but not present in the last release.
@ebyhr did you by any chance bisect the history to determine cause?
@findepi 84848cbafb85c4c78f1b48ebff2e4d7d289dccb1 is the first commit that throws an exception.
@findepi 84848cb is the first commit that throws an exception.
cc @djsstarburst
This test, transliterated from the SQL in the summary, shows the same problem when added to BaseIcebergConnectorTest
:
@Test
public void testDeleteAll()
{
String tableName = "test_delete_all_" + randomNameSuffix();
assertUpdate(getSession(), "CREATE TABLE %s (parent row(child int))".formatted(tableName));
assertUpdate("INSERT INTO %s SELECT row(1)".formatted(tableName), 1);
assertUpdate(getSession(), "ALTER TABLE %s SET PROPERTIES partitioning = ARRAY['\"parent.child\"']".formatted(tableName));
assertUpdate("DELETE FROM " + tableName, 1);
assertUpdate(getSession(), "DROP TABLE " + tableName);
}
As reported, this regression in DELETE was introduced by 84848cb. That commit unconditionally creates a MergeAnalysis
instance when analyzing a DELETE, whether or not we are planning the DELETE using MERGE components. When creating the MergeAnalysis
instance, the code calls metadata.getInsertLayout()
. For Iceberg, this calls IcebergMetadata.getWriteLayout()
. getWriteLayout()
enumerates the ids of the top-level columns in the table, but does not include the ids of columns nested inside of structs. But the subsequent code in getWriteLayout()
expects the id of the nested child column to appear in the enumeration, because it is a partition key.
During analysis for legacy DELETE, there is no need to call createMergeAnalysis()
at all. However, as @ebyhr reported, the bug happens whether or not we are running legacy DELETE. I'm guessing we have the same bug in Iceberg UPDATE and MERGE.
Bottom line: we need to figure out how to bring the Iceberg enumeration of column ids into alignment with what IcebergMetadata.getWriteLayout()
is expecting. I tried including all columns, including nested columns, in the map of column id to column handle used by getWriteLayout()
, but that fails in the INSERT before we ever get to the DELETE.
This PR fixes the DELETE regression by not creating an insert layout if the operation is a DELETE.
HOWEVER, I'm pretty sure that Iceberg still has a problem with UPDATE and MERGE operations with partition columns that are elements of a struct column. I haven't been able to fix that Iceberg problem. Perhaps @electrum or @alexjo2144 might have suggestions?
Iceberg still has a problem with UPDATE and MERGE operations with partition columns that are elements of a struct column
Yep, @ebyhr has a PR to address that situation. It isn't clear yet if that should be supported in the first place, Spark has some issue reading those tables.
The PR shows failures in some Hive DELETE and UPDATE tests. If those failures don't appear in the master branch, it doesn't make sense to merge the PR.
Does this break anything that should've worked before? From the comments above, my understanding is that nested fields as partition keys shouldn't work anyway. In that case, this wouldn't be a release blocker.
If I understand the change in https://github.com/trinodb/trino/pull/15142 correctly, that would break the INSERT
part of this reproduction? Thus we don't need this to be a release blocker?
Does this break anything that should've worked before?
Yes. I guess it's not a common issue in Iceberg connector's users though. The connector doesn't support creating such tables, so it requires changing the partition definition after the creation or other query engines (e.g. Spark).
INSERT
part of this reproduction should still work because the statement is executed before setting partitioning. INSERT
for partitioned by nested fields didn't work even in 403.
Partitioning on nested row fields seems to be pretty broken across the board, both in Trino and in Spark. Deleting the entire contents on these tables happened to work before, but most operations don't and never have. I don't think we need to call this a release blocker.
Please remove the release blocker tag.
Steps to reproduce:
DELETE statement works in 403.
DELETE statement doesn't work in upstream master regardless of
legacy_update_delete_implementation
properties.