Skip to content

Instantly share code, notes, and snippets.

@vkartaviy
Created July 29, 2026 23:07
Show Gist options
  • Select an option

  • Save vkartaviy/bd393135dc77bd8f34fa6cd718e185ac to your computer and use it in GitHub Desktop.

Select an option

Save vkartaviy/bd393135dc77bd8f34fa6cd718e185ac to your computer and use it in GitHub Desktop.
MikroORM 7.1.8 PostgreSQL trigger statement-splitting reproduction

MikroORM PostgreSQL trigger statement-splitting reproduction

This uses only public EntitySchema, migrator, and schema-generator APIs.

docker run --rm --name mikro-trigger-repro \
  -e POSTGRES_PASSWORD=postgres \
  -e POSTGRES_DB=trigger_repro \
  -p 127.0.0.1:54329:5432 \
  postgres:17-alpine

In another terminal:

pnpm install
DB_PORT=54329 pnpm repro

createInitial() splits the dollar-quoted PostgreSQL function into two migration statements:

create or replace function ... as $$ begin update ...;
return NEW;; end; $$ language plpgsql;

The same metadata then fails through orm.schema.refresh():

syntax error at or near ";"

Expected: semicolons and newlines inside a dollar-quoted function body do not split the generated SQL statement.

{
"name": "mikro-orm-postgres-trigger-split-repro",
"private": true,
"type": "module",
"scripts": {
"repro": "tsx repro.ts"
},
"dependencies": {
"@mikro-orm/core": "7.1.8",
"@mikro-orm/migrations": "7.1.8",
"@mikro-orm/postgresql": "7.1.8",
"tsx": "4.23.0"
},
"packageManager": "pnpm@11.0.0"
}
packages:
- .
allowBuilds:
esbuild: true
import { rm } from 'node:fs/promises';
import { EntitySchema } from '@mikro-orm/core';
import { Migrator } from '@mikro-orm/migrations';
import { MikroORM } from '@mikro-orm/postgresql';
class Item {
id!: number;
value = 0;
}
const itemSchema = new EntitySchema({
class: Item,
tableName: 'items',
properties: {
id: { type: 'number', primary: true },
value: { type: 'number' },
},
triggers: [
{
name: 'items_increment_after_insert',
timing: 'after',
events: ['insert'],
body: [
'update items set value = value + 1 where id = NEW.id;',
'return NEW;',
].join('\n'),
},
],
});
await rm('./migrations', { force: true, recursive: true });
const orm = await MikroORM.init({
entities: [itemSchema],
extensions: [Migrator],
dbName: process.env.DB_NAME ?? 'trigger_repro',
host: process.env.DB_HOST ?? '127.0.0.1',
port: Number(process.env.DB_PORT ?? 5432),
user: process.env.DB_USER ?? 'postgres',
password: process.env.DB_PASSWORD ?? 'postgres',
migrations: {
path: './migrations',
snapshot: false,
},
});
try {
await orm.schema.drop();
const migration = await orm.migrator.createInitial(
'./migrations',
'trigger-split'
);
console.log(JSON.stringify(migration.diff.up, null, 2));
await orm.schema.refresh();
} finally {
await orm.close(true);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment