Skip to content

fix(0.6): claim batch index check, SET-only migrator grants, and review follow-ups - #701

Merged
hardbyte merged 7 commits into
release/0.6.6from
brian/0.6.16-review-fixes
Nov 9, 2026
Merged

hardbyte merged 7 commits into
release/0.6.6from
brian/0.6.16-review-fixes

Conversation

@hardbyte

@hardbyte hardbyte commented Nov 9, 2026

Copy link
Copy Markdown
Owner

Follow-ups from reviewing the 0.6.15 forward-port that apply to the 0.6 line.

Summary

  • Claim batch index check. ensure_claim_batch_job_index now checks the catalog for a valid GIN index on job_ids alone (no predicate, no expressions, default opclass) instead of matching definition text, so a partial index no longer counts. A different index already using the target name raises a warning naming it and is left in place. The function pins quote_all_identifiers = off. The pending probe requires the new body, so 0.6.15 databases re-apply claim_batch_job_index on awa migrate.
  • SET-only migrator grants (bug). A migrator that is a member of the schema owner with INHERIT FALSE, SET TRUE, refreshing as itself, handed the function to the table owner before resetting EXECUTE, then could no longer revoke, so PUBLIC kept EXECUTE. The helper now resets EXECUTE before the ownership transfer. The documented role=<owner> path was already correct.
  • Wording. Compat batch inserts take each lane's enqueue lock when they reach that lane and hold it until the transaction ends; the 0.6.15 notes and docs said "only while they write that lane".
  • Coverage. A direct test of awa.insert_jobs_compat_batch with skipping off: a claimed or repeated key fails the batch with 23505 and leaves nothing behind.
  • Benchmark accounting. The lane-contention benchmark counts rows each insert actually returned and reconciles landed rows against acknowledged rows exactly.

Testing

New tests fail before and pass after (claim index shapes, SET-only migrator on PG16+). queue_storage_runtime_test claim-index cases, insert_many_batch_test, lane_ownership_roles_test, migration_test, insert_many_schema_fallback_test, migrate_patch_cli_test, prepare_schema_reset_guard_test and awa-model lib tests pass on PG17; the contention gate passes with exact reconciliation. patch_upgrade_rehearsal_test was updated for the re-applied patch but only compiled locally (it needs released wheels); CI runs it. Conflicts expected with #700 in the CHANGELOG, the 0.6.16 upgrade guide and the rehearsal's pending-patch assertion.

…batch index build

`ensure_claim_batch_job_index` decided a claim partition was already indexed by matching `USING gin (job_ids)` in the index definition text. A partial GIN index on `job_ids` matched, so claim prune never built the real one, and with `quote_all_identifiers` on the text did not match at all. An index of any definition already holding the target name made `CREATE INDEX IF NOT EXISTS` a silent no-op that still reported the slot indexed.

The check now reads `pg_index` directly: a valid GIN index with no predicate and no expressions on `job_ids` alone, with the default `array_ops` opclass. When something else already has the target name, the function raises a warning naming it, returns false and leaves it in place; the slot keeps scanning until an operator drops or renames it. The index is created without `IF NOT EXISTS`, so a name taken concurrently also reports false. The generated function pins `quote_all_identifiers = off`.

The patch probe now requires the new helper and index function, so a 0.6.15 database sees `claim_batch_job_index` as pending and `awa migrate` replaces the function. The patch still replaces functions only and takes no relation locks.
…the transaction ends

The 0.6.15 release notes, the 0.6.14 to 0.6.15 upgrade guide, the lane contention troubleshooting entry and the insert module comment said `awa.insert_jobs_compat_batch` holds a lane's enqueue lock only while it writes that lane, or only for the write and the commit. The lock is transaction-scoped: the batch takes it when it reaches that lane, no longer at its first ready row, and it stays held until the calling transaction commits or rolls back, including any work the caller does after the batch.
…mode

`awa.insert_jobs_compat_batch` documents that with `p_skip_unique_conflicts = false` a unique conflict fails the whole batch with a unique violation. The Rust entry points pass `true` whenever a batch carries a unique key, so nothing exercised that mode with a conflict.

The new test calls the function directly on queue storage and on canonical storage, with a key that is already claimed and with a key repeated inside the batch. Each fails with `23505` and leaves no row behind; the same batch with skipping inserts the rest.
… to the table owner

`awa.refresh_claim_batch_job_index_helper` transferred `ensure_claim_batch_job_index` to the owner of `lease_claim_batches` and then revoked `EXECUTE` from everyone but the owner and granted it to the roles holding `TRUNCATE`. A migration role that owned the function but was a member of the table owner only `WITH INHERIT FALSE, SET TRUE` (PostgreSQL 16+) could make the transfer, but afterwards held neither ownership nor grant options, so the revoke and grant only raised warnings and `PUBLIC` kept `EXECUTE`.

The helper now resets `EXECUTE` while the running role still owns the function, then transfers ownership; `ALTER FUNCTION ... OWNER TO` keeps the ACL. Running the patch with the schema owner as the effective role, as the database-roles guide says, already produced the right ACL; the new test covers both that and the transfer path with a SET-only membership.
…benchmark

The benchmark added the batch size to its job count for every batch, so a skipping insert (`insert_many_skip_unique_conflicts`, `insert_many_copy`) that left out a duplicate still counted it, inflating the reported rate, and the integrity check only asked that at least the measured window's count had landed.

Each mode now reports the rows its insert returned, the row-at-a-time fallback counts the rows that went in, and throughput uses those. The output shows inserted against requested jobs, the JSON record carries both, and the integrity check requires the rows that landed to equal the jobs the inserts returned over the whole run.
@hardbyte hardbyte added the full-ci Run the full CI matrix (Python build+test, E2E) on this PR label Nov 9, 2026
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 9, 2026 •

Copy link
Copy Markdown
Codex Review Summary: ✅ Completed

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-09T00:41:29.830435Z be1aa3c PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@coderabbitai

coderabbitai Bot commented Nov 9, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 11af489f-b6b6-435b-b44f-29d48c40d144

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • Trigger review
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

…6.16-review-fixes

# Conflicts:
#	CHANGELOG.md

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: be1aa3cad3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

…rship transfer

Resetting `EXECUTE` before handing `ensure_claim_batch_job_index` to the table owner lost the former owner's access: its grant to itself was its owner entry, and `ALTER FUNCTION ... OWNER TO` rewrites that entry to the new owner. A former owner that holds `TRUNCATE` on `lease_claim_batches`, and runs claim prune, could then no longer execute the function, so its prunes skipped the index build.

The helper now transfers ownership first and resets `EXECUTE` as a role with the owner's privileges. A role that may only `SET ROLE` to the table owner (PostgreSQL 16+ `INHERIT FALSE, SET TRUE`) switches to it with a transaction-local `role` setting for the reset and then restores its previous `role` value, so a `role` set through `PGOPTIONS` is kept. The final ACL on every path is the roles holding `TRUNCATE`, including a former owner, and not `PUBLIC`. The SET-only test now gives the migration role `TRUNCATE`, also covers an ordinary member refreshing as itself, and checks the caller's role is unchanged afterwards.
@hardbyte
hardbyte merged commit 7c1f9c1 into release/0.6.6 Nov 9, 2026
34 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

full-ci Run the full CI matrix (Python build+test, E2E) on this PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant