diff --git a/priv/repo/migrations/20260421100900_drop_unused_packet_columns.exs b/priv/repo/migrations/20260421100900_drop_unused_packet_columns.exs new file mode 100644 index 0000000..b4134ff --- /dev/null +++ b/priv/repo/migrations/20260421100900_drop_unused_packet_columns.exs @@ -0,0 +1,73 @@ +defmodule Aprsme.Repo.Migrations.DropUnusedPacketColumns do + use Ecto.Migration + + @moduledoc """ + Drops 10 legacy parser-compat columns from the partitioned `packets` table + that are never read by any application code. Values are stripped from incoming + attrs by `Aprsme.Packet.strip_dead_fields/1` before insert, so the columns + have been write-only noise on the wire. + + Each column is `ALTER TABLE ... DROP COLUMN IF EXISTS` on the parent + partitioned table; PostgreSQL cascades the drop to every child partition. + `IF EXISTS` keeps this migration idempotent against databases where the + earlier `ConsolidatePacketsColumns` (20260220230000) DROP/RECREATE already + removed these columns. + + Columns dropped and rationale (one-liner each): + + * `srccallsign` - duplicate of `sender`; never read. + * `dstcallsign` - duplicate of `destination`; never read. + * `origpacket` - duplicate of `raw_packet`; never read. + * `header` - raw packet header bytes; never read after `raw_packet` + superseded it. + * `body` - raw packet body bytes; never read after `raw_packet` + superseded it. + * `alive` - legacy parser "liveness" flag (default 1); never read. + * `posambiguity` - duplicate of `position_ambiguity`; never read (the + canonical column lives in the `data` JSONB now). + * `symboltable` - duplicate of `symbol_table_id`; never read. + * `symbolcode` - duplicate of `symbol_code`; never read. + * `messaging` - legacy int flag duplicating `aprs_messaging` (bool); + never read. + + The `down/0` recreates the columns with their original types from + `PartitionPacketsTable` (20260220200000) so the migration is mechanically + reversible — though column DATA is permanently lost on drop. + """ + + @dropped_columns [ + {:srccallsign, :varchar}, + {:dstcallsign, :varchar}, + {:origpacket, :text}, + {:header, :text}, + {:body, :text}, + {:alive, :integer, "DEFAULT 1"}, + {:posambiguity, :integer}, + {:symboltable, :varchar}, + {:symbolcode, :varchar}, + {:messaging, :integer} + ] + + def up do + execute("SET LOCAL statement_timeout = '0'") + + for col <- @dropped_columns do + name = elem(col, 0) + execute("ALTER TABLE packets DROP COLUMN IF EXISTS #{name}") + end + end + + def down do + execute("SET LOCAL statement_timeout = '0'") + + for col <- @dropped_columns do + {name, type, default} = + case col do + {n, t} -> {n, t, ""} + {n, t, d} -> {n, t, " " <> d} + end + + execute("ALTER TABLE packets ADD COLUMN IF NOT EXISTS #{name} #{type}#{default}") + end + end +end