MP111criticalneeds databaseTimescaleDB

warn-timescale-columnstore-ddl

TimescaleDB rejects this ALTER on a hypertable that has compression / columnstore enabled.

operation
Tables
lock taken
no table lock
remediation
Multi-step plan
category
Extensions

What triggers it

ctx.tableExtensions.isHypertable true, compressionEnabled strictly true, and an AlterTableStmt containing a subcommand in the blocked set: AT_AlterColumnType, AT_SetStorage, AT_EnableRowSecurity, AT_DisableRowSecurity, AT_ForceRowSecurity, AT_NoForceRowSecurity. The first match in cmds wins, and its name supplies the column named in the message.

What does not

Every run without --database-url — the identical ALTER against an uncompressed hypertable is perfectly legal, so guessing would be wrong (requiresDatabaseUrl is set). A hypertable whose compressionEnabled is false or undefined, which the strict !== true test treats the same way. Hypertable ALTER forms outside the six blocked subtypes, which fall through to MP105. Ordinary tables.

Where it applies

Applies to every PostgreSQL version MigrationPilot targets. It only fires on tables managed by TimescaleDB. It needs --database-url: without a connection it has nothing to read and stays silent.

The lock, and what it blocks

No lock, because the statement never gets far enough to hold one usefully — TimescaleDB rejects it with operation not supported on hypertables that have columnstore enabled. The migration stops at that statement with everything before it already applied, which is why this is critical rather than a warning: the outcome is known, not merely likely.

Why it matters

This is not a slow path — the statement fails. TimescaleDB answers "operation not supported on hypertables that have columnstore enabled", and the migration stops partway through with whatever ran before it already applied. Getting the change through is a procedure rather than a fix: stop the columnstore policy, convert the compressed chunks back to rowstore, disable the columnstore, apply the change, then re-enable and restore the policy. Two of those steps rewrite every chunk, so they belong in their own maintenance window.

Unsafe, and safe

Flagged

-- metrics is a hypertable with the columnstore enabled
ALTER TABLE metrics ALTER COLUMN value TYPE numeric;
-- ERROR: operation not supported on hypertables that have columnstore enabled

Safe alternative

-- Confirm the columnstore state first — it decides whether this is a
-- one-line ALTER or a whole-hypertable maintenance window.
SELECT hypertable_name, compression_enabled, num_chunks
FROM timescaledb_information.hypertables
WHERE hypertable_name = 'metrics';

Deploy and transaction boundaries

Getting the change through is a five-step procedure — remove the columnstore policy, convert compressed chunks back to rowstore, disable the columnstore, apply the ALTER, then re-enable and restore the policy. Two of those steps move every row in the hypertable, so it belongs in its own maintenance window rather than inside a migration run.

What it assumes

The blocked list is a fixed set of six subtypes taken from TimescaleDB's documented restrictions rather than from the installed extension's version, so a release that lifts one of them, or adds another, is not tracked. compression_enabled is a hypertable-level policy flag, so a hypertable with the columnstore enabled but no chunks actually converted yet is still reported. And the flag is read from the database you connected to, which may not be the one the migration will run against.

This rule reads live catalogue state, so it says nothing at all without --database-url. That is the trade: no connection, no guess.

What the CLI prints

migrationpilot analyze migration.sql --database-url $DATABASE_URL
✗ [MP111] CRITICAL (line 2)
  ALTER COLUMN ... TYPE on "value" against "metrics", a hypertable with the columnstore enabled. TimescaleDB rejects this with "operation not supported on hypertables that have columnstore enabled". The migration will fail here, not run slowly.

  Safe alternative:
  -- Confirm the columnstore state first:
  SELECT hypertable_name, compression_enabled, num_chunks
  FROM timescaledb_information.hypertables
  WHERE hypertable_name = 'metrics';
  
  -- Getting this change through means unwinding the columnstore and putting it back:
  --   1. remove the columnstore policy for metrics
  --   2. convert the compressed chunks back to rowstore
  --   3. disable the columnstore on the hypertable
  --   4. run: ALTER TABLE metrics ALTER COLUMN value TYPE numeric
  --   5. re-enable the columnstore and restore the policy
  --
  -- Steps 2 and 5 move all of the hypertable's data, so schedule this as its own
  -- maintenance operation rather than a step inside a migration run.

  Why: TimescaleDB blocks several ALTER forms on a hypertable whose chunks are in the columnstore, and answers with "operation not supported on hypertables that have columnstore enabled". This is not a slow path: the statement fails. Getting it through means stopping the columnstore policy, converting the chunks back to rowstore, disabling the columnstore, applying the change, then putting all of it back: a long, data-moving procedure that does not belong in the middle of an ordinary migration run.
  Docs: https://migrationpilot.dev/rules/mp111

Generated by running the CLI's own formatter over the flagged example above, so it is the text the tool actually produces. A real run also reports the other rules that fire on the same statement; those blocks are left out here. The catalogue figures come from the production context this rule documents.

Turning it off

For one statement, put a comment on the line before it:

-- migrationpilot-disable MP111
ALTER TABLE metrics ALTER COLUMN value TYPE numeric;

For the whole project, in .migrationpilotrc.yml — by name or by id:

.migrationpilotrc.yml
rules:
  MP111: false

# or keep it, and downgrade it
rules:
  MP111:
    severity: warning

Try it

Open this rule's flagged example in the playground. It runs in your browser — edit it and watch the finding appear and disappear.

Run MP111 in the playground

Related rules