Skip to content

fix(db): Resolve the execution table through search_path in the revision guard - #929

Merged
bupd merged 1 commit into
mainfrom
fix/execution-revision-guard-search-path
Sep 16, 2026
Merged

bupd merged 1 commit into
mainfrom
fix/execution-revision-guard-search-path

Conversation

@bupd

@bupd bupd commented Sep 16, 2026

Copy link
Copy Markdown
Member

Follow-up to #924, which merged before the cubic bot's review comment on it was addressed. The finding is valid, so it is fixed here rather than on the merged branch.

What broke

The guard #924 added tests information_schema against current_schema(), which is only the first entry in search_path. If a connection's search_path puts another schema first and execution lives in a later one, the guard reads false while the unqualified ALTER TABLE execution below it resolves to that later table. The widening is skipped silently and execution.revision stays integer.

What changed

Resolve the relation with to_regclass and read its type from pg_attribute, so the guard and the ALTER always agree on which table they mean. to_regclass returns NULL when no execution table is reachable, which leaves the guard false exactly as before.

How it was verified

Both predicates run against the same two-schema setup, search_path = first_schema, later_schema with execution in the later one:

 OLD guard sees: | f     <- skips the widening
 NEW guard sees: | t     <- widens correctly

Applying the block twice in that layout lands on bigint both times, so the guard stays idempotent:

 after 1st: | bigint
 after 2nd: | bigint

go test -tags db ./migration/ -run TestAuthoritativeSchemaAgainstPostgreSQL passes.

Copilot AI lite review requested due to automatic review settings September 16, 2026 07:10
@coderabbitai

coderabbitai Bot commented Sep 16, 2026

Copy link
Copy Markdown

Warning

Review limit reached

Next included review available in 30 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Advanced

Run ID: 67752fcb-97cb-4bec-87e1-60304b4a9647

📥 Commits

Reviewing files that changed from the base of the PR and between 4f01b71 and 8e01e5e.

📒 Files selected for processing (2)
  • make/migrations/postgresql/harbor_next.sql
  • src/migration/authoritative_db_test.go

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

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown
Contributor

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

Scanned Files

None

@github-actions

Copy link
Copy Markdown
Contributor

This change may need patch-release backports. Comment with one of these commands to open a cherry-pick PR:

/backport v2.15

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

Add coverage for search_path = first_schema, later_schema with execution only in the later schema.

Get a fresh assessment by requesting another Copilot review.

Pull request overview

Fixes the PostgreSQL revision guard so execution resolves consistently through search_path.

Changes:

  • Uses to_regclass and pg_attribute for relation/type detection.
  • Preserves idempotent widening to bigint.
File summaries
File Summary
make/migrations/postgresql/harbor_next.sql Corrects relation resolution; a moderate finding remains that the two-schema regression scenario lacks test coverage.
Review details
  • Files reviewed: 1/1 changed files
  • Comments generated: 1
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread make/migrations/postgresql/harbor_next.sql

@cubic-dev-ai cubic-dev-ai 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.

All reported issues were addressed across 1 file

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread make/migrations/postgresql/harbor_next.sql Outdated
Comment thread make/migrations/postgresql/harbor_next.sql
Comment thread make/migrations/postgresql/harbor_next.sql
@bupd
bupd force-pushed the fix/execution-revision-guard-search-path branch from be13377 to e03143b Compare September 16, 2026 07:26
@github-actions github-actions Bot added the tests label Sep 16, 2026

@cubic-dev-ai cubic-dev-ai 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.

1 issue found across 2 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="make/migrations/postgresql/harbor_next.sql">

<violation number="1" location="make/migrations/postgresql/harbor_next.sql:164">
P3: The new domain-preserving guard branch is untested. Add cases for a domain over `bigint`, which must remain unchanged, and a domain over `integer`, which must widen without losing the intended behavior.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

AND a.attname = 'revision'
AND a.attnum > 0
AND NOT a.attisdropped
AND CASE WHEN t.typtype = 'd' THEN t.typbasetype ELSE a.atttypid END

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P3: The new domain-preserving guard branch is untested. Add cases for a domain over bigint, which must remain unchanged, and a domain over integer, which must widen without losing the intended behavior.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At make/migrations/postgresql/harbor_next.sql, line 164:

<comment>The new domain-preserving guard branch is untested. Add cases for a domain over `bigint`, which must remain unchanged, and a domain over `integer`, which must widen without losing the intended behavior.</comment>

<file context>
@@ -143,14 +143,26 @@ BEGIN
           AND a.attnum > 0
           AND NOT a.attisdropped
-          AND a.atttypid <> 'bigint'::regtype
+          AND CASE WHEN t.typtype = 'd' THEN t.typbasetype ELSE a.atttypid END
+              <> 'bigint'::regtype
     ) THEN
</file context>

…ion guard

The guard added in #924 tested information_schema against
current_schema(), which is only the first entry in search_path. On a
connection whose search_path puts another schema first, an execution
table in a later schema makes the predicate false while the unqualified
ALTER below it resolves to that same later table, so the widening is
skipped without a word and execution.revision silently stays integer.

Resolve the relation with to_regclass and read its type from
pg_attribute, so the guard and the ALTER always agree on which table
they are talking about. to_regclass returns NULL when no execution
relation is reachable, which leaves the guard false as before.

Two narrower cases came out of review. to_regclass resolves any
relation, so the guard is restricted to tables by relkind: an index
named execution earlier in search_path would otherwise match a
pg_attribute row and send ALTER TABLE at something it cannot alter,
failing the whole file. And the column type is compared after resolving
a domain to its base, so a column already typed as a domain over bigint
keeps the domain and its CHECK constraints instead of having them
stripped by the ALTER.

Covered by two tests against a real Postgres: execution in a schema
that is not first in search_path is widened and its rows preserved on
two consecutive applies, and a non-table relation of that name leaves
the apply clean rather than aborting it.

Reported by the review bots on #924 and on this PR.

Signed-off-by: Prasanth Baskar <prasanth@8gears.com>
@bupd
bupd force-pushed the fix/execution-revision-guard-search-path branch from e03143b to 8e01e5e Compare September 16, 2026 07:39
@bupd
bupd merged commit b6a9fa0 into main Sep 16, 2026
16 checks passed
@bupd
bupd deleted the fix/execution-revision-guard-search-path branch September 16, 2026 07:40
@bupd

bupd commented Sep 16, 2026

Copy link
Copy Markdown
Member Author

/backport v2.15

@github-actions

Copy link
Copy Markdown
Contributor

Backport to release-2.15 has conflicts. Please cherry-pick b6a9fa0f68307a055eba52b1bb817f66aa0b888d manually.

bupd added a commit that referenced this pull request Sep 16, 2026
…ion guard (backport #929)

The guard backported in #910 tested information_schema against
current_schema(), which is only the first entry in search_path. On a
connection whose search_path puts another schema first, an execution
table in a later schema makes the predicate false while the unqualified
ALTER below it resolves to that same later table, so the widening is
skipped without a word and execution.revision silently stays integer.

Resolve the relation with to_regclass and read its type from
pg_attribute, so the guard and the ALTER always agree on which table
they are talking about. to_regclass returns NULL when no execution
relation is reachable, which leaves the guard false as before.

Two narrower cases came with it. to_regclass resolves any relation, so
the guard is restricted to tables by relkind: an index named execution
earlier in search_path would otherwise match a pg_attribute row and send
ALTER TABLE at something it cannot alter, failing the whole file. And
the column type is compared after resolving a domain to its base, so a
column already typed as a domain over bigint keeps the domain and its
CHECK constraints instead of having them stripped by the ALTER.

Covered by two tests against a real Postgres: execution in a schema that
is not first in search_path is widened and its rows preserved on two
consecutive applies, and a non-table relation of that name leaves the
apply clean rather than aborting it.

Signed-off-by: Prasanth Baskar <prasanth@8gears.com>
@github-actions

Copy link
Copy Markdown
Contributor

Preview images for this PR are available in 8gears.container-registry.com/8gcr-pr with tag pr-929, built from 8e01e5e:

  • 8gears.container-registry.com/8gcr-pr/harbor-core:pr-929
  • 8gears.container-registry.com/8gcr-pr/harbor-jobservice:pr-929
  • 8gears.container-registry.com/8gcr-pr/harbor-registryctl:pr-929
  • 8gears.container-registry.com/8gcr-pr/harbor-exporter:pr-929
  • 8gears.container-registry.com/8gcr-pr/harbor-portal:pr-929
  • 8gears.container-registry.com/8gcr-pr/harbor-registry:pr-929
  • 8gears.container-registry.com/8gcr-pr/trivy-adapter:pr-929

Verify a preview image:

cosign verify \
  --certificate-identity-regexp="https://github.com/container-registry/harbor-next/.github/workflows/pr-ci.yml@.*" \
  --certificate-oidc-issuer="https://token.actions.githubusercontent.com" \
  8gears.container-registry.com/8gcr-pr/harbor-core:pr-929

Verify the SBOM attestation:

cosign verify-attestation \
  --certificate-identity-regexp="https://github.com/container-registry/harbor-next/.github/workflows/pr-ci.yml@.*" \
  --certificate-oidc-issuer="https://token.actions.githubusercontent.com" \
  --type spdxjson \
  8gears.container-registry.com/8gcr-pr/harbor-core:pr-929

bupd added a commit that referenced this pull request Sep 16, 2026
…ion guard (backport #929) (#933)

Signed-off-by: Prasanth Baskar <prasanth@8gears.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants