From 021492a57772ff3178b8c21f215a1806c54b5ee3 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Tue, 20 Oct 2026 20:36:24 +0000 Subject: [PATCH] :bug: Make migration 0156 compatible with PostgreSQL 15 `SET STORAGE DEFAULT` needs PostgreSQL 16, but the official docker images pin `postgres:15`, so migration 0156 failed on those deployments. The migration now uses `SET STORAGE EXTENDED`, the storage mode of the type of every column it touches (text, text[], jsonb and bytea), which leaves the catalog in the same state on any supported version. The documented PostgreSQL floor goes back to >=15, the reason for raising it was that syntax. Verified on the test database: the 62 columns reset and no table column keeps the legacy EXTERNAL storage. The backend memory now records that migrations must stay within PostgreSQL 15 syntax. AI-assisted-by: minimax-m3.1-flash-free --- .serena/memories/backend/core.md | 2 + .../sql/0156-reset-pg-storage-defaults.sql | 136 +++++++++--------- docs/technical-guide/configuration.md | 2 +- 3 files changed, 72 insertions(+), 68 deletions(-) diff --git a/.serena/memories/backend/core.md b/.serena/memories/backend/core.md index 42e7c7b756..7ed309bd18 100644 --- a/.serena/memories/backend/core.md +++ b/.serena/memories/backend/core.md @@ -41,6 +41,8 @@ Backend RPC command areas without focused memories include access tokens, binfil Database migrations live in `backend/src/app/migrations/`; pure SQL migrations are under `backend/src/app/migrations/sql/`. SQL filenames conventionally start with a sequence and verb/table description, e.g. `0026-mod-profile-table-add-is-active-field`. Applied migrations are tracked in the `migrations` table. +Migrations must stay within PostgreSQL 15 syntax: the official docker images (`docker/images/docker-compose.yaml`) pin `postgres:15`, so anything newer breaks those deployments (`SET STORAGE DEFAULT` is PostgreSQL 16, for instance). The documented floor is >=15. + For interactive PostgreSQL access with correct dev defaults, use `scripts/psql`; to dump the current DDL schema, use `scripts/db-schema` (see `mem:scripts/psql`). diff --git a/backend/src/app/migrations/sql/0156-reset-pg-storage-defaults.sql b/backend/src/app/migrations/sql/0156-reset-pg-storage-defaults.sql index 54bd98ace5..46a7cce54b 100644 --- a/backend/src/app/migrations/sql/0156-reset-pg-storage-defaults.sql +++ b/backend/src/app/migrations/sql/0156-reset-pg-storage-defaults.sql @@ -12,118 +12,120 @@ -- already stored TOAST values keep their strategy until the row is -- rewritten, new writes use the default. -- --- NOTE: DEFAULT restores the storage mode of the column's data type --- (EXTENDED for every column below: text, text[], jsonb and bytea). It --- requires PostgreSQL 16 or newer, which is the minimum version the --- project supports (see the database section of the technical guide). --- RESET STORAGE is not valid syntax for a column. +-- NOTE: `SET STORAGE DEFAULT` would express the same thing (it restores +-- the storage mode of the column's data type), but it only exists since +-- PostgreSQL 16 and the project also runs on PostgreSQL 15. Here every +-- column below has a type whose default storage mode is EXTENDED +-- (text, text[], jsonb and bytea), so `SET STORAGE EXTENDED` reaches the +-- same catalog state on any supported version. RESET STORAGE is not +-- valid syntax for a column. ALTER TABLE access_token - ALTER COLUMN name SET STORAGE DEFAULT, - ALTER COLUMN perms SET STORAGE DEFAULT, - ALTER COLUMN token SET STORAGE DEFAULT; + ALTER COLUMN name SET STORAGE EXTENDED, + ALTER COLUMN perms SET STORAGE EXTENDED, + ALTER COLUMN token SET STORAGE EXTENDED; ALTER TABLE audit_log - ALTER COLUMN context SET STORAGE DEFAULT, - ALTER COLUMN name SET STORAGE DEFAULT, - ALTER COLUMN props SET STORAGE DEFAULT, - ALTER COLUMN source SET STORAGE DEFAULT, - ALTER COLUMN type SET STORAGE DEFAULT; + ALTER COLUMN context SET STORAGE EXTENDED, + ALTER COLUMN name SET STORAGE EXTENDED, + ALTER COLUMN props SET STORAGE EXTENDED, + ALTER COLUMN source SET STORAGE EXTENDED, + ALTER COLUMN type SET STORAGE EXTENDED; ALTER TABLE comment - ALTER COLUMN content SET STORAGE DEFAULT; + ALTER COLUMN content SET STORAGE EXTENDED; ALTER TABLE comment_thread - ALTER COLUMN page_name SET STORAGE DEFAULT, - ALTER COLUMN participants SET STORAGE DEFAULT; + ALTER COLUMN page_name SET STORAGE EXTENDED, + ALTER COLUMN participants SET STORAGE EXTENDED; ALTER TABLE file - ALTER COLUMN data SET STORAGE DEFAULT, - ALTER COLUMN data_backend SET STORAGE DEFAULT, - ALTER COLUMN features SET STORAGE DEFAULT, - ALTER COLUMN name SET STORAGE DEFAULT; + ALTER COLUMN data SET STORAGE EXTENDED, + ALTER COLUMN data_backend SET STORAGE EXTENDED, + ALTER COLUMN features SET STORAGE EXTENDED, + ALTER COLUMN name SET STORAGE EXTENDED; ALTER TABLE file_change - ALTER COLUMN changes SET STORAGE DEFAULT, - ALTER COLUMN data SET STORAGE DEFAULT, - ALTER COLUMN features SET STORAGE DEFAULT, - ALTER COLUMN label SET STORAGE DEFAULT; + ALTER COLUMN changes SET STORAGE EXTENDED, + ALTER COLUMN data SET STORAGE EXTENDED, + ALTER COLUMN features SET STORAGE EXTENDED, + ALTER COLUMN label SET STORAGE EXTENDED; ALTER TABLE file_data_fragment - ALTER COLUMN metadata SET STORAGE DEFAULT; + ALTER COLUMN metadata SET STORAGE EXTENDED; ALTER TABLE file_media_object - ALTER COLUMN mtype SET STORAGE DEFAULT, - ALTER COLUMN name SET STORAGE DEFAULT; + ALTER COLUMN mtype SET STORAGE EXTENDED, + ALTER COLUMN name SET STORAGE EXTENDED; ALTER TABLE file_thumbnail - ALTER COLUMN data SET STORAGE DEFAULT, - ALTER COLUMN props SET STORAGE DEFAULT; + ALTER COLUMN data SET STORAGE EXTENDED, + ALTER COLUMN props SET STORAGE EXTENDED; ALTER TABLE global_complaint_report - ALTER COLUMN content SET STORAGE DEFAULT, - ALTER COLUMN type SET STORAGE DEFAULT; + ALTER COLUMN content SET STORAGE EXTENDED, + ALTER COLUMN type SET STORAGE EXTENDED; ALTER TABLE profile - ALTER COLUMN auth_backend SET STORAGE DEFAULT, - ALTER COLUMN email SET STORAGE DEFAULT, - ALTER COLUMN fullname SET STORAGE DEFAULT, - ALTER COLUMN lang SET STORAGE DEFAULT, - ALTER COLUMN password SET STORAGE DEFAULT, - ALTER COLUMN props SET STORAGE DEFAULT, - ALTER COLUMN theme SET STORAGE DEFAULT; + ALTER COLUMN auth_backend SET STORAGE EXTENDED, + ALTER COLUMN email SET STORAGE EXTENDED, + ALTER COLUMN fullname SET STORAGE EXTENDED, + ALTER COLUMN lang SET STORAGE EXTENDED, + ALTER COLUMN password SET STORAGE EXTENDED, + ALTER COLUMN props SET STORAGE EXTENDED, + ALTER COLUMN theme SET STORAGE EXTENDED; ALTER TABLE profile_complaint_report - ALTER COLUMN content SET STORAGE DEFAULT, - ALTER COLUMN type SET STORAGE DEFAULT; + ALTER COLUMN content SET STORAGE EXTENDED, + ALTER COLUMN type SET STORAGE EXTENDED; ALTER TABLE project - ALTER COLUMN name SET STORAGE DEFAULT; + ALTER COLUMN name SET STORAGE EXTENDED; ALTER TABLE scheduled_task - ALTER COLUMN cron_expr SET STORAGE DEFAULT, - ALTER COLUMN id SET STORAGE DEFAULT; + ALTER COLUMN cron_expr SET STORAGE EXTENDED, + ALTER COLUMN id SET STORAGE EXTENDED; ALTER TABLE server_error_report - ALTER COLUMN content SET STORAGE DEFAULT; + ALTER COLUMN content SET STORAGE EXTENDED; ALTER TABLE server_prop - ALTER COLUMN content SET STORAGE DEFAULT, - ALTER COLUMN id SET STORAGE DEFAULT; + ALTER COLUMN content SET STORAGE EXTENDED, + ALTER COLUMN id SET STORAGE EXTENDED; ALTER TABLE storage_object - ALTER COLUMN backend SET STORAGE DEFAULT, - ALTER COLUMN metadata SET STORAGE DEFAULT; + ALTER COLUMN backend SET STORAGE EXTENDED, + ALTER COLUMN metadata SET STORAGE EXTENDED; ALTER TABLE task - ALTER COLUMN error SET STORAGE DEFAULT, - ALTER COLUMN label SET STORAGE DEFAULT, - ALTER COLUMN name SET STORAGE DEFAULT, - ALTER COLUMN props SET STORAGE DEFAULT, - ALTER COLUMN queue SET STORAGE DEFAULT, - ALTER COLUMN status SET STORAGE DEFAULT; + ALTER COLUMN error SET STORAGE EXTENDED, + ALTER COLUMN label SET STORAGE EXTENDED, + ALTER COLUMN name SET STORAGE EXTENDED, + ALTER COLUMN props SET STORAGE EXTENDED, + ALTER COLUMN queue SET STORAGE EXTENDED, + ALTER COLUMN status SET STORAGE EXTENDED; ALTER TABLE team - ALTER COLUMN name SET STORAGE DEFAULT; + ALTER COLUMN name SET STORAGE EXTENDED; ALTER TABLE team_font_variant - ALTER COLUMN font_family SET STORAGE DEFAULT, - ALTER COLUMN font_style SET STORAGE DEFAULT; + ALTER COLUMN font_family SET STORAGE EXTENDED, + ALTER COLUMN font_style SET STORAGE EXTENDED; ALTER TABLE team_invitation - ALTER COLUMN email_to SET STORAGE DEFAULT, - ALTER COLUMN role SET STORAGE DEFAULT; + ALTER COLUMN email_to SET STORAGE EXTENDED, + ALTER COLUMN role SET STORAGE EXTENDED; ALTER TABLE usage_quote - ALTER COLUMN target SET STORAGE DEFAULT; + ALTER COLUMN target SET STORAGE EXTENDED; ALTER TABLE webhook - ALTER COLUMN error_code SET STORAGE DEFAULT, - ALTER COLUMN mtype SET STORAGE DEFAULT, - ALTER COLUMN secret_key SET STORAGE DEFAULT, - ALTER COLUMN uri SET STORAGE DEFAULT; + ALTER COLUMN error_code SET STORAGE EXTENDED, + ALTER COLUMN mtype SET STORAGE EXTENDED, + ALTER COLUMN secret_key SET STORAGE EXTENDED, + ALTER COLUMN uri SET STORAGE EXTENDED; ALTER TABLE webhook_delivery - ALTER COLUMN error_code SET STORAGE DEFAULT, - ALTER COLUMN req_data SET STORAGE DEFAULT, - ALTER COLUMN rsp_data SET STORAGE DEFAULT; + ALTER COLUMN error_code SET STORAGE EXTENDED, + ALTER COLUMN req_data SET STORAGE EXTENDED, + ALTER COLUMN rsp_data SET STORAGE EXTENDED; diff --git a/docs/technical-guide/configuration.md b/docs/technical-guide/configuration.md index 59939a522b..374c5e408c 100644 --- a/docs/technical-guide/configuration.md +++ b/docs/technical-guide/configuration.md @@ -484,7 +484,7 @@ PENPOT_SECRET_KEY: my-super-secure-key ### Database -Penpot only supports PostgreSQL and we highly recommend >=16 version. If you are using official +Penpot only supports PostgreSQL and we highly recommend >=15 version. If you are using official docker images this is already solved for you. Essential database configuration: