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


##########
catalog/sql/sql.go:
##########
@@ -1269,9 +1269,46 @@ func (c *Catalog) CreateNamespace(ctx context.Context, 
namespace table.Identifie
                        })
                }
 
-               _, err := tx.NewInsert().Model(&toInsert).Exec(ctx)
-               if err != nil {
-                       return fmt.Errorf("error inserting namespace properties 
for namespace '%s': %w", namespace, err)
+               // A concurrent writer may have won the race; return the 
sentinel in the same
+               // form as the pre-check above. This must stay the first read 
on the outer tx
+               // so MySQL's REPEATABLE READ snapshot lands after the winner 
committed.
+               recheck := func(insertErr error) error {
+                       _, exists, checkErr := c.resolveNamespaceKeyInTx(ctx, 
tx, namespace)
+                       if checkErr == nil && exists {
+                               return fmt.Errorf("%w: %s", 
catalog.ErrNamespaceAlreadyExists, strings.Join(namespace, "."))
+                       }
+                       if checkErr != nil {
+                               return fmt.Errorf("error inserting namespace 
properties for namespace '%s': %w", namespace, errors.Join(insertErr, checkErr))
+                       }
+
+                       return fmt.Errorf("error inserting namespace properties 
for namespace '%s': %w", namespace, insertErr)
+               }
+
+               // Postgres aborts the whole tx on a failed insert, so only it 
needs the
+               // savepoint for the re-check; SQLite/MySQL don't, and Oracle 
can't RELEASE it.
+               if tx.Dialect().Name() == dialect.PG {
+                       sp, err := tx.BeginTx(ctx, nil)

Review Comment:
   **nit** — Postgres-only gate on the savepoint branch is unpinned by any test
   
   The dialect gate exists so Oracle (no RELEASE SAVEPOINT) and SQLite/MySQL 
(statement-level rollback) skip the savepoint. Removing it is behaviourally 
invisible to the suite because sqlite supports savepoints, so the emulation 
cannot distinguish gated from ungated. Cheaply pinnable: have 
dupInsertConn.ExecContext (sql_test.go:2188) record whether any statement 
matching a SAVEPOINT prefix was seen, and assert it was NOT in 
TestCreateNamespaceLosesInsertRaceSQLite. Follow-up, not a merge blocker.



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