Skip to content

Backport #37184 to 2.0: align entity_extension.extension with its table's collation on MySQL - #37186

Merged
manerow merged 1 commit into
2.0from
fix/37180-entity-extension-collation-2.0
Nov 6, 2026
Merged

manerow merged 1 commit into
2.0from
fix/37180-entity-extension-collation-2.0

Conversation

@manerow

@manerow manerow commented Nov 5, 2026

Copy link
Copy Markdown
Contributor

Fixes #37180

Backport of PR #37184 to 2.0. Same step: on MySQL, the 2.0.8 Java migration puts entity_extension.extension back on its table's default character set and collation when the old 2.0.3 statement left it on ascii_bin. It does nothing when the column already matches its table, and it stops before copying, naming the keys, if two keys of one entity would become equal under the table's collation.

Differences from main:

  • 2.0 has no 2.1.0 migration, so only the 2.0.8 migration runs the step.
  • The 2.0.8 migration on 2.0 also has LifeCycleCreatedSentinelMigration as its first step. The alignment runs before it, as on main.

Tests

@manerow
manerow requested a review from a team as a code owner November 5, 2026 15:43
@manerow
manerow requested review from IceS2 and removed request for a team November 5, 2026 15:43
@manerow manerow added safe to test Add this label to run secure Github workflows on PRs backend labels Nov 5, 2026
@manerow manerow self-assigned this Nov 5, 2026
@github-actions

github-actions Bot commented Nov 5, 2026

Copy link
Copy Markdown
Contributor

❌ PR checklist incomplete

This PR cannot be merged until the following are addressed on its linked issue:

  • No GitHub issue is linked. Link an issue in the Development section of the PR (or add Fixes #12345 to the description). For a same-org cross-repo issue, add Fixes open-metadata/<repo>#123 to the description.

The fields live on the linked issue in the Shipping project (open the issue → right sidebar → Projects). After you set them, re-run this check (or push a commit) — issue/project changes do not re-trigger it automatically.

Maintainers can bypass this check by adding the skip-pr-checks label.

Comment on lines +22 to +27
* Puts {@code entity_extension.extension} back on its table's default character set and collation
* on MySQL. Until #37167, the 2.0.3 migration switched the column to {@code ascii_bin}, so databases
* upgraded through 2.0.3 to 2.0.7 differ from the rest of the table and from databases that never
* ran that statement. The target is the table's own default: OpenMetadata never set a collation, so
* each table carries the server default of the day it was created.
*

@gitar-bot gitar-bot Bot Nov 5, 2026 •

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Bug: 2.0 branch still runs the 2.0.3 ascii_bin ALTER, so the table is copied twice

The class Javadoc says the ascii_bin conversion happened "until #37167", but on this 2.0 branch bootstrap/sql/migrations/native/2.0.3/mysql/schemaChanges.sql:15-16 still runs MODIFY COLUMN extension VARCHAR(512) CHARACTER SET ascii COLLATE ascii_bin NOT NULL. So every fresh install, and every upgrade that starts below 2.0.3, first converts the column to ascii_bin (a full table copy that blocks writes), and then the new 2.0.8 step converts it back (a second full copy, after a GROUP BY scan for collisions). On large entity_extension tables this doubles the hours of write-blocking downtime that this PR is trying to keep down. Backport #37167 together with this PR, so the 2.0.3 statement keeps the table default (VARCHAR(512) NOT NULL with no charset). That way the 2.0.8 step only runs on databases that really went through the old 2.0.3.

Backport #37167's 2.0.3 change to the 2.0 branch (bootstrap/sql/migrations/native/2.0.3/mysql/schemaChanges.sql):

ALTER TABLE entity_extension
  MODIFY COLUMN extension VARCHAR(512) NOT NULL;

Was this helpful? React with 👍 / 👎

Comment on lines +34 to +35
* <p>2.1.0 runs it again, because a database that recorded 2.0.8 before this step existed reruns
* 2.0.8 for its SQL only.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Quality: Javadoc says 2.1.0 reruns the step, but 2.0 has no 2.1.0 migration

The Javadoc says that 2.1.0 runs the step again for databases that recorded 2.0.8 before this step existed. The PR description says 2.0 has no 2.1.0 migration, so on this branch nothing reruns the step. That comment is copied from main and is wrong here. It also hides the fact that a 2.0.x database that already applied 2.0.8 will not be aligned by this branch. Remove or reword that paragraph for the 2.0 backport.

Was this helpful? React with 👍 / 👎

@gitar-bot

gitar-bot Bot commented Nov 5, 2026 •

Copy link
Copy Markdown
Code Review ⚠️ Changes requested 0 closed / 2 findings

🔴 High risk · The migration changes the indexed extension collation and copies entity_extension, potentially blocking writes for hours or halting on newly equivalent keys.

Backports the MySQL entity_extension.extension collation alignment into the 2.0.8 migration so it matches its table's default collation, and stops before copying if keys would collide.

Changes are requested before merge. The 2.0.3 ascii_bin ALTER still runs on this branch, so the table is copied twice on upgrades from below 2.0.3, roughly doubling write-blocking downtime on large tables; backport #37167 alongside this PR to fix it. The Javadoc also wrongly claims 2.1.0 reruns the step, which does not exist on 2.0 and should be reworded.

⚠️ Bug: 2.0 branch still runs the 2.0.3 ascii_bin ALTER, so the table is copied twice

📄 openmetadata-service/src/main/java/org/openmetadata/service/migration/utils/v208/EntityExtensionCollationAlignment.java:22-27 📄 openmetadata-service/src/main/java/org/openmetadata/service/migration/mysql/v208/Migration.java:36-40

The class Javadoc says the ascii_bin conversion happened "until #37167", but on this 2.0 branch bootstrap/sql/migrations/native/2.0.3/mysql/schemaChanges.sql:15-16 still runs MODIFY COLUMN extension VARCHAR(512) CHARACTER SET ascii COLLATE ascii_bin NOT NULL. So every fresh install, and every upgrade that starts below 2.0.3, first converts the column to ascii_bin (a full table copy that blocks writes), and then the new 2.0.8 step converts it back (a second full copy, after a GROUP BY scan for collisions). On large entity_extension tables this doubles the hours of write-blocking downtime that this PR is trying to keep down. Backport #37167 together with this PR, so the 2.0.3 statement keeps the table default (VARCHAR(512) NOT NULL with no charset). That way the 2.0.8 step only runs on databases that really went through the old 2.0.3.

Backport #37167's 2.0.3 change to the 2.0 branch (bootstrap/sql/migrations/native/2.0.3/mysql/schemaChanges.sql)
ALTER TABLE entity_extension
  MODIFY COLUMN extension VARCHAR(512) NOT NULL;
💡 Quality: Javadoc says 2.1.0 reruns the step, but 2.0 has no 2.1.0 migration

📄 openmetadata-service/src/main/java/org/openmetadata/service/migration/utils/v208/EntityExtensionCollationAlignment.java:34-35

The Javadoc says that 2.1.0 runs the step again for databases that recorded 2.0.8 before this step existed. The PR description says 2.0 has no 2.1.0 migration, so on this branch nothing reruns the step. That comment is copied from main and is wrong here. It also hides the fact that a 2.0.x database that already applied 2.0.8 will not be aligned by this branch. Remove or reword that paragraph for the 2.0 backport.

🤖 Prompt for agents
Code Review: Backports the MySQL `entity_extension.extension` collation alignment into the 2.0.8 migration so it matches its table's default collation, and stops before copying if keys would collide.
  
  Changes are requested before merge. The 2.0.3 `ascii_bin` ALTER still runs on this branch, so the table is copied twice on upgrades from below 2.0.3, roughly doubling write-blocking downtime on large tables; backport #37167 alongside this PR to fix it. The Javadoc also wrongly claims 2.1.0 reruns the step, which does not exist on 2.0 and should be reworded.

1. ⚠️ Bug: 2.0 branch still runs the 2.0.3 ascii_bin ALTER, so the table is copied twice
   Files: openmetadata-service/src/main/java/org/openmetadata/service/migration/utils/v208/EntityExtensionCollationAlignment.java:22-27, openmetadata-service/src/main/java/org/openmetadata/service/migration/mysql/v208/Migration.java:36-40

   The class Javadoc says the ascii_bin conversion happened "until #37167", but on this `2.0` branch `bootstrap/sql/migrations/native/2.0.3/mysql/schemaChanges.sql:15-16` still runs `MODIFY COLUMN extension VARCHAR(512) CHARACTER SET ascii COLLATE ascii_bin NOT NULL`. So every fresh install, and every upgrade that starts below 2.0.3, first converts the column to ascii_bin (a full table copy that blocks writes), and then the new 2.0.8 step converts it back (a second full copy, after a GROUP BY scan for collisions). On large `entity_extension` tables this doubles the hours of write-blocking downtime that this PR is trying to keep down. Backport #37167 together with this PR, so the 2.0.3 statement keeps the table default (`VARCHAR(512) NOT NULL` with no charset). That way the 2.0.8 step only runs on databases that really went through the old 2.0.3.

   Fix (Backport #37167's 2.0.3 change to the 2.0 branch (bootstrap/sql/migrations/native/2.0.3/mysql/schemaChanges.sql)):
   ALTER TABLE entity_extension
     MODIFY COLUMN extension VARCHAR(512) NOT NULL;

2. 💡 Quality: Javadoc says 2.1.0 reruns the step, but 2.0 has no 2.1.0 migration
   Files: openmetadata-service/src/main/java/org/openmetadata/service/migration/utils/v208/EntityExtensionCollationAlignment.java:34-35

   The Javadoc says that 2.1.0 runs the step again for databases that recorded 2.0.8 before this step existed. The PR description says `2.0` has no 2.1.0 migration, so on this branch nothing reruns the step. That comment is copied from `main` and is wrong here. It also hides the fact that a 2.0.x database that already applied 2.0.8 will not be aligned by this branch. Remove or reword that paragraph for the 2.0 backport.

Verification

Rules No rules evaluated

Functional validation Not enabled

Set up

Auto-approval Not enabled

Set up

For more verification details, comment gitar display:verbose.

Options

Display: compact → Showing compact verification results.

Comment with these commands to change the behavior for this request:

Compact
gitar display:verbose         

Was this helpful? React with 👍 / 👎 | Powered by Gitar — free for open source

@manerow
manerow merged commit 5d14825 into 2.0 Nov 6, 2026
91 of 106 checks passed
@manerow
manerow deleted the fix/37180-entity-extension-collation-2.0 branch November 6, 2026 13:46
mohityadav766 added a commit that referenced this pull request Nov 6, 2026
#37186 added EntityExtensionCollationAlignment to the 2.0.8 MySQL data migration without the matching change to WorkflowRedeployEntryPointTest, so the test's mocked Handle reached the step's query. This is the test change main made in #37184.
mohityadav766 added a commit that referenced this pull request Nov 6, 2026
…37162)

* fix(sql): bind names in the prefix-rename statements

The FQN prefix renames, the tag-usage prefix rewrites and the thread-link rename bind every value; only the table name stays a template attribute. A guard test fails on any DAO statement that is a bare template attribute. Tag lists count usage with the bound per-tag query. ListFilter.escapeForMySqlRegexReplacement stays, deprecated, for extensions.

* fix(auth): resolve our own tokens to the account they name

A token verified against OpenMetadata's own signing key, on a request or a WebSocket connection, resolves to the user name it was minted for instead of the configured principal claims, whose email local part can belong to another account. SecurityUtil.getUserName uses the principal name whole.

* fix(sessions): logout retires the request's token; password changes end sign-ins

Logout denylists the verified bearer token of the request, not a token named in the body. Denylist entries are keyed by a digest of the token's signed part, hold only who signed out and when, and are capped. A new password, from a reset link, the user, an admin or the reset-password command, ends the user's refresh tokens, live sessions and MCP grants; personal access tokens and bot tokens stay.

* fix(sessions): replace a refresh token in one update

A refresh replaces its refresh token with the new one in a single UPDATE keyed by the old token, for basic and LDAP sign-ins. Only the request whose update changed the row gets new tokens; a token deleted while the request ran is not renewed.

* fix(sso): a SAML login completes in the browser that started it

The login keeps its AuthnRequest id, and the ACS accepts only a response whose signed assertion answers it. The ACS no longer signs anyone in: it attaches the account to the pending login and redirects to /api/v1/saml/complete on the login's own origin with a one-time code. Completing the login needs both the browser's session cookie and that code, read from the session store.

* fix(input): bound parsing of names, patches and descriptions

The email pattern matches in linear time and accepts the same addresses. The message parser's entity-link pattern cannot backtrack across unclosed links. JSON Patch bodies are read with Jackson limits and an operation cap, and a patch on the document root is refused. Description placeholders are restored in one pass, in text positions only.

* fix(users): keep account restore, deletion and role changes with admins

A PUT naming the caller's own account refuses a deleted self with 404 and treats an unknown self as a sign-up, allowed only when self sign-up is. Deleting your own account needs an admin. A role list that differs from the stored one, in either direction, is an admin change, and a non-admin PUT keeps the stored admin and bot flags and, when omitted, the stored roles. A non-admin CSV row fails for a stored admin or bot.

* fix(policies): reviewers, disabled and owner-team policies, RBAC writes

Rules of a disabled policy no longer apply. An owning team's policies give their allow rules to its members only. A reviewer is matched by user id. Startup no longer rewrites seeded policies. Impersonated requests cannot write policies or roles, and BotNonAdminImpersonationPolicy denies bot targets, added to stored copies by the 2.0.8 migration. A soft-deleted team or role keeps the policy conditions that name it; only a hard delete rewrites them.

* fix(patch-authz): authorize every location a patch touches

A JSON Patch is authorized at every location it touches, the from location of a move or copy included. Narrow edit operations apply only at real fields of the entity; tag changes are compared with their location, and an operation beside a tag change keeps that change's tag operation. The user PATCH guards and the domain check read the same locations. A patch's copies are bounded in size, and a date field refuses an object or array.

* fix(users): decide team membership and self-delete on the stored result; refuse impersonated team grants

A user's team changes are decided on the patched result, whatever shape the PATCH operations take, and joining or leaving a closed team needs an admin; a non-admin PUT that omits teams keeps the stored ones. The by-name self-delete check resolves the user and compares ids. Team writes that change default roles or policies, and team CSV imports, refuse impersonated requests.

* fix(ui): offer Join and Leave team only where the user may change the membership

The team page shows Join and Leave only on a joinable team, or to an admin, as the server allows joining and leaving a closed team only for admins.

* fix(create-put): authorize creates and PUTs against the stored entity

- On create, hasDomain() needs a domain of the stored container and every domain the request
  names.
- A root parent reference without an id is loaded by name and a missing one fails the request;
  TagMapper resolves the classification by name.
- A tag's parent must belong to the tag's classification.
- PUT contexts see soft-deleted entities, as the write does.
- A system tag's fully qualified name cannot change through its parent or classification either.

ADR:2026-11-03-a-create-is-authorized-against-its-stored-container

* fix(delete): a hard delete removes only rows of the deleted entity

- The FQN-prefix cleanup of field relationships runs only for taggable types and for types, whose custom property definitions live under their name; tag labels are removed by FQN prefix only for taggable types.
- Custom property definitions are removed only when their type is deleted.
- The tag-FQN label delete without a source is removed; tags and glossary terms keep removing their own source-bound labels.

ADR:2026-11-03-a-hard-delete-removes-only-rows-of-the-deleted-entity

* fix(reads): read handlers authorize like the entity reads they mirror

- Tasks read by id, and their versions, also need ViewBasic on the entity they are about.
- Activity by entity link matches the link's entity type as well as its FQN.
- Team hierarchy, task counts, domain hierarchy and the type custom-property reads need ViewBasic on their type; the team hierarchy still serves joinable teams to someone signing up. The role list uses the standard listing.
- The global profiler setting is always authorized on tables.

ADR:2026-11-03-read-handlers-authorize-like-the-entity-reads-they-mirror

* test(mcp): give create_entity's root parent a repository in the tool test

CreateResourceContext now loads the root parent a create names (a glossary term's glossary) and no longer swallows a failed load, so the test's static Entity stub has to answer for that parent's repository.

* test(sessions): fit the session ITs to 2.0's authenticator and tokens

2.0's BasicAuthenticator reads the authorizer configuration at init, so PasswordChangeIT gives it one. 2.0 tokens carry no jti, so the logout test mints its two tokens with different expiries; two tokens minted in the same second would otherwise be the same token.

* docs(decisions): name only the patch guards 2.0 has

The 2.0 record no longer mentions the connection and sourceConfig copy guard, context-file sharing or conversations, which 2.0 does not have.

* test(migrations): mock the collation step in the v208 entry-point test

#37186 added EntityExtensionCollationAlignment to the 2.0.8 MySQL data migration without the matching change to WorkflowRedeployEntryPointTest, so the test's mocked Handle reached the step's query. This is the test change main made in #37184.

This branch was previously deployed

1 inactive deployment
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backend safe to test Add this label to run secure Github workflows on PRs

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants