Skip to content

fix: cast json column to text for PostgreSQL equality comparison#193

Merged
ManukMinasyan merged 1 commit intomainfrom
fix/ulid-migration-json-cast
Mar 23, 2026
Merged

fix: cast json column to text for PostgreSQL equality comparison#193
ManukMinasyan merged 1 commit intomainfrom
fix/ulid-migration-json-cast

Conversation

@ManukMinasyan
Copy link
Copy Markdown
Contributor

@ManukMinasyan ManukMinasyan commented Mar 23, 2026

Summary

  • PostgreSQL's json type does not support the = equality operator (only jsonb does)
  • The ULID migration compared json_value directly with =, causing operator does not exist: json = unknown on PostgreSQL
  • Cast json_value::text before comparing in both phaseA8_migrateEmailFieldValues and phaseA9_migrateDomainFieldValues

Fixes #178

Test plan

  • Run php artisan migrate on a fresh PostgreSQL database with existing custom field values
  • Verify email and domain field migrations complete without SQL errors

PostgreSQL's `json` type does not support the `=` operator. Cast
`json_value` to `text` via `::text` before comparing in the ULID
migration's email and domain field value queries.

Fixes #178
Copilot AI review requested due to automatic review settings March 23, 2026 16:41
@ManukMinasyan ManukMinasyan merged commit f4716cf into main Mar 23, 2026
13 checks passed
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Fixes the ULID migration failing on PostgreSQL due to comparing a json column with = by attempting to cast json_value to text before equality checks.

Changes:

  • Update phaseA8_migrateEmailFieldValues() to compare json_value::text against [] / null.
  • Update phaseA9_migrateDomainFieldValues() to compare json_value::text against [] / null.

Comment on lines 476 to +479
->where(function (Builder $query): void {
$query->whereNull('json_value')
->orWhere('json_value', '=', '[]')
->orWhere('json_value', '=', 'null');
->orWhereRaw('"json_value"::text = ?', ['[]'])
->orWhereRaw('"json_value"::text = ?', ['null']);
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

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

The raw SQL string is wrapped in single quotes, so \" is not an escape sequence in PHP and the backslashes will be sent to PostgreSQL literally (producing \"json_value\"::text, which is invalid SQL). Use plain "json_value"::text without backslashes (or just json_value::text) so the cast actually runs.

Copilot uses AI. Check for mistakes.
Comment on lines 476 to 480
->where(function (Builder $query): void {
$query->whereNull('json_value')
->orWhere('json_value', '=', '[]')
->orWhere('json_value', '=', 'null');
->orWhereRaw('"json_value"::text = ?', ['[]'])
->orWhereRaw('"json_value"::text = ?', ['null']);
})
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

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

::text is PostgreSQL-specific syntax, but this migration’s relational DB path is also used for MySQL/MariaDB (migrateForRelationalDb). As written, this will cause a syntax error on non-PostgreSQL drivers. Either branch on DB::getDriverName() (pgsql vs others) or use driver-appropriate casting (e.g., CAST(json_value AS CHAR) / JSON_UNQUOTE(...)) to keep the migration runnable across the supported drivers.

Copilot uses AI. Check for mistakes.
Comment on lines 532 to +535
->where(function (Builder $query): void {
$query->whereNull('json_value')
->orWhere('json_value', '=', '[]')
->orWhere('json_value', '=', 'null');
->orWhereRaw('"json_value"::text = ?', ['[]'])
->orWhereRaw('"json_value"::text = ?', ['null']);
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

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

The raw SQL string is wrapped in single quotes, so \" is not an escape sequence in PHP and the backslashes will be sent to PostgreSQL literally (producing \"json_value\"::text, which is invalid SQL). Use plain "json_value"::text without backslashes (or just json_value::text) so the cast actually runs.

Copilot uses AI. Check for mistakes.
Comment on lines 532 to 536
->where(function (Builder $query): void {
$query->whereNull('json_value')
->orWhere('json_value', '=', '[]')
->orWhere('json_value', '=', 'null');
->orWhereRaw('"json_value"::text = ?', ['[]'])
->orWhereRaw('"json_value"::text = ?', ['null']);
})
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

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

::text is PostgreSQL-specific syntax, but this migration’s relational DB path is also used for MySQL/MariaDB (migrateForRelationalDb). As written, this will cause a syntax error on non-PostgreSQL drivers. Either branch on DB::getDriverName() (pgsql vs others) or use driver-appropriate casting (e.g., CAST(json_value AS CHAR) / JSON_UNQUOTE(...)) to keep the migration runnable across the supported drivers.

Copilot uses AI. Check for mistakes.
@ManukMinasyan ManukMinasyan mentioned this pull request Mar 23, 2026
1 task
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.

Can't run migrate to ULID

2 participants