zeroshade commented on code in PR #1326:
URL: https://github.com/apache/iceberg-go/pull/1326#discussion_r3521466790


##########
catalog/hadoop/hadoop.go:
##########
@@ -547,17 +584,27 @@ func (c *Catalog) CommitTable(ctx context.Context, ident 
table.Identifier, reqs
                return nil, "", fmt.Errorf("hadoop catalog: failed to create 
metadata directory: %w", err)
        }
 
-       newMetaPath := c.metadataFilePath(ident, newVersion)
-       tempPath := joinPath(c.isLocal, metaDir, 
uuid.New().String()+".metadata.json")
-
        compression := updated.Properties().Get(table.MetadataCompressionKey, 
table.MetadataCompressionDefault)
+       newMetaPath, err := c.metadataFilePathForCompression(ident, newVersion, 
compression)
+       if err != nil {
+               return nil, "", fmt.Errorf("hadoop catalog: failed to determine 
metadata file path: %w", err)
+       }
+
+       tempPath := joinPath(c.isLocal, metaDir, 
uuid.New().String()+".metadata.json")
 
        if err := internal.WriteTableMetadata(updated, c.filesystem, tempPath, 
compression); err != nil {
                _ = c.filesystem.Remove(tempPath)
 
                return nil, "", fmt.Errorf("hadoop catalog: failed to write 
table metadata: %w", err)
        }
 
+       if existingPath, exists := c.metadataVersionLocation(ident, 
newVersion); exists {
+               _ = c.filesystem.Remove(tempPath)

Review Comment:
   [MAJOR] The cross-codec commit conflict check is non-atomic. Two concurrent 
writers can both compute the same newVersion, both pass 
metadataVersionLocation(ident, newVersion) before either publishes, then one 
RenameNoReplace can publish vN.metadata.json while the other publishes 
vN.gz.metadata.json; both succeed, leaving two files claiming the same version. 
Fix by taking an atomic per-version claim independent of codec suffix before 
publishing (for example a RenameNoReplace sentinel for vN), and add a 
concurrent mixed-codec commit test where both writers pass preflight before 
either final rename.



##########
catalog/hadoop/hadoop.go:
##########
@@ -424,16 +459,20 @@ func (c *Catalog) CreateTable(ctx context.Context, ident 
table.Identifier, sc *i
        }
 
        version := 1
-       metaPath := c.metadataFilePath(ident, version)
-       tempPath := joinPath(c.isLocal, metaDir, 
uuid.New().String()+".metadata.json")
-
        compression := table.MetadataCompressionDefault
        if cfg.Properties != nil {
                if v, ok := cfg.Properties[table.MetadataCompressionKey]; ok {
                        compression = v
                }
        }
 
+       metaPath, err := c.metadataFilePathForCompression(ident, version, 
compression)

Review Comment:
   [MAJOR] CreateTable has the same duplicate-version race with different 
compression. Two concurrent creators can both pass isTableDir, then publish 
v1.metadata.json and v1.gz.metadata.json successfully. Reuse a 
codec-independent per-version/table-creation claim before publishing metadata, 
and add a concurrent create test with default and gzip writers.



-- 
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]

Reply via email to