Fix multi-select option removal crashing when records contain removed values (#18871)
## Summary
- Fixes a bug where removing an option from a MULTI_SELECT field fails
with `invalid input value for enum` when existing records contain the
removed value alongside surviving values.
- The root cause was the `ELSE` branch in `updateArrayEnum` which tried
to cast removed enum values (e.g. `DISTRIBUTOR`) to the new enum type
that no longer includes them.
- The fix replaces the `ELSE` cast with a NULL-producing implicit CASE
default and uses `array_agg(...) FILTER (WHERE mapped_value IS NOT
NULL)` to silently strip removed values from existing arrays.
### Before (bug)
```sql
-- ELSE branch tries to cast removed value to new enum → crash
CASE unnest_value::text
WHEN 'IMPL' THEN 'IMPL'::new_enum
WHEN 'APP' THEN 'APP'::new_enum
ELSE unnest_value::text::new_enum -- 'DISTRIBUTOR' fails here
END
```
### After (fix)
```sql
-- No ELSE: removed values produce NULL, filtered out by array_agg
SELECT array_agg(mapped_value) FILTER (WHERE mapped_value IS NOT NULL)
FROM (
SELECT CASE unnest_value::text
WHEN 'IMPL' THEN 'IMPL'::new_enum
WHEN 'APP' THEN 'APP'::new_enum
END AS mapped_value
FROM unnest(old_column) AS unnest_value
) enum_mapping
```
This commit is contained in:
+8
-10
@@ -327,7 +327,6 @@ export class WorkspaceSchemaEnumManagerService {
|
||||
escapedTable,
|
||||
escapedOldColumn,
|
||||
escapedNewColumn,
|
||||
escapedNewEnumType,
|
||||
escapedOldEnumType: `${escapedSchema}.${escapeIdentifier(oldEnumTypeName)}`,
|
||||
caseStatements,
|
||||
mappedValuesCondition,
|
||||
@@ -349,7 +348,6 @@ export class WorkspaceSchemaEnumManagerService {
|
||||
escapedOldColumn,
|
||||
escapedSchema,
|
||||
escapedTable,
|
||||
escapedNewEnumType,
|
||||
escapedOldEnumType,
|
||||
caseStatements,
|
||||
mappedValuesCondition,
|
||||
@@ -358,7 +356,6 @@ export class WorkspaceSchemaEnumManagerService {
|
||||
escapedTable: string;
|
||||
escapedOldColumn: string;
|
||||
escapedNewColumn: string;
|
||||
escapedNewEnumType: string;
|
||||
escapedOldEnumType: string;
|
||||
caseStatements: string;
|
||||
mappedValuesCondition: string;
|
||||
@@ -366,13 +363,14 @@ export class WorkspaceSchemaEnumManagerService {
|
||||
return `
|
||||
UPDATE ${escapedSchema}.${escapedTable}
|
||||
SET ${escapedNewColumn} = (
|
||||
SELECT array_agg(
|
||||
CASE unnest_value::text
|
||||
${caseStatements}
|
||||
ELSE unnest_value::text::${escapedNewEnumType}
|
||||
END
|
||||
)
|
||||
FROM unnest(${escapedOldColumn}) AS unnest_value
|
||||
SELECT array_agg(mapped_value) FILTER (WHERE mapped_value IS NOT NULL)
|
||||
FROM (
|
||||
SELECT
|
||||
CASE unnest_value::text
|
||||
${caseStatements}
|
||||
END AS mapped_value
|
||||
FROM unnest(${escapedOldColumn}) AS unnest_value
|
||||
) enum_mapping
|
||||
)
|
||||
WHERE ${escapedOldColumn} IS NOT NULL
|
||||
AND ${escapedOldColumn} && ARRAY[${mappedValuesCondition}]::${escapedOldEnumType}[]`;
|
||||
|
||||
Reference in New Issue
Block a user