fix(migration): quote table names in create_hypertable calls#179
fix(migration): quote table names in create_hypertable calls#179TerrifiedBug merged 1 commit intomainfrom
Conversation
PostgreSQL's regclass input function folds unquoted identifiers to lowercase. The previous form 'PipelineMetric' was looked up as pipelinemetric and failed with 'relation does not exist' on every TimescaleDB-enabled deployment (the demo environment surfaced this). Plain-PostgreSQL deployments were unaffected because the surrounding IF EXISTS check made the entire block a no-op there. Fix: embed the case-preserved identifier inside the regclass string literal so it survives the regclass cast.
Greptile SummaryThis PR fixes a PostgreSQL Confidence Score: 5/5Safe to merge — targeted one-line fix per table with no side effects on plain-Postgres deployments. The change is minimal and correct: all four create_hypertable calls receive the properly quoted regclass string, the if_not_exists => true flag keeps the migration idempotent, and the TimescaleDB guard ensures plain-Postgres environments are unaffected. No logic, security, or data-integrity concerns were found. No files require special attention. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[prisma migrate deploy] --> B{TimescaleDB\nextension present?}
B -- No --> C[RAISE NOTICE: skipping\n plain-Postgres no-op]
B -- Yes --> D[DROP + recreate composite PKs\nid + timestamp]
D --> E["create_hypertable('PipelineMetric', ...)"]
E --> F["create_hypertable('NodeMetric', ...)"]
F --> G["create_hypertable('PipelineLog', ...)"]
G --> H["create_hypertable('NodeStatusEvent', ...)"]
H --> I[RAISE NOTICE: hypertables created]
style E fill:#d4edda,stroke:#28a745
style F fill:#d4edda,stroke:#28a745
style G fill:#d4edda,stroke:#28a745
style H fill:#d4edda,stroke:#28a745
Reviews (1): Last reviewed commit: "fix(migration): quote table names passed..." | Re-trigger Greptile |
…ings (#181) TimescaleDB's parser for compress_segmentby and compress_orderby folds unquoted identifiers to lowercase (same behaviour as PostgreSQL's regclass parser, which bit us in #179). Prisma's columns are camelCase ('pipelineId', 'nodeId'), so 'pipelineId' was being looked up as 'pipelineid' and the migration failed with: ERROR: column "pipelineid" does not exist HINT: The timescaledb.compress_segmentby option must reference a valid column. Wrap every column name in double quotes inside the option strings — the same pattern used for the table-name argument in #179.
#182) Bare SELECT inside a PL/pgSQL DO block is invalid when the result is discarded — Postgres raises 42601 "query has no destination for result data". Switch the four add_compression_policy calls to PERFORM so the migration applies cleanly on TimescaleDB. Follows #179, #180, #181 — same file, same DO block.
Summary
Migration `20260329000000_timescaledb_hypertables` calls `create_hypertable('PipelineMetric', ...)` (and the same pattern for `NodeMetric`, `PipelineLog`, `NodeStatusEvent`). PostgreSQL parses the first argument as a `regclass`, and `regclass` input folds unquoted identifiers to lowercase. So the lookup becomes `pipelinemetric`, which doesn't exist — Prisma created the table as case-preserved `"PipelineMetric"`.
Symptom on a TimescaleDB-enabled database (e.g. the new hosted demo on `timescale/timescaledb:2.16.0-pg16`):
```
ERROR: relation "pipelinemetric" does not exist
PL/pgSQL function inline_code_block line 17 at PERFORM
```
Fix: embed the case-preserved identifier inside the regclass string literal — `'PipelineMetric'` → `'"PipelineMetric"'` — for all four tables.
Why this didn't surface earlier
The whole block sits under `IF EXISTS (SELECT 1 FROM pg_extension WHERE extname = 'timescaledb')`, so plain-Postgres deployments silently no-op'd this migration. The demo environment is the first one in the wild to actually have the `timescaledb` extension, which is why we're only seeing it now.
Recovery instructions
For anyone whose DB is currently in the failed state (only TimescaleDB users; plain-Postgres users are unaffected):
Option A — wipe and reapply (cleanest if no real data):
```sh
docker compose down -v
docker compose up
```
Option B — preserve data:
```sh
Mark the failed migration as rolled back
npx prisma migrate resolve --rolled-back 20260329000000_timescaledb_hypertables
Apply the corrected migration
npx prisma migrate deploy
```
Drift warning for plain-Postgres users
The migration's checksum changes. On next `prisma migrate deploy` you may see a "migration was modified after applied" warning. Resolve with:
```sh
npx prisma migrate resolve --applied 20260329000000_timescaledb_hypertables
```
This is a one-time fix; the no-op effect on plain Postgres is unchanged.
Test plan
References