From 5ffa81c02ac01cc3420ca345b05835e331c879e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ad=C3=A1mek?= Date: Fri, 2 Dec 2022 11:40:35 +0100 Subject: [PATCH] fix(postgres): quote array literal items containing a comma Closes #3810 --- packages/postgresql/src/PostgreSqlPlatform.ts | 2 +- tests/issues/GH3810.test.ts | 59 +++++++++++++++++++ 2 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 tests/issues/GH3810.test.ts diff --git a/packages/postgresql/src/PostgreSqlPlatform.ts b/packages/postgresql/src/PostgreSqlPlatform.ts index c82ccb868613..8ad0ea476880 100644 --- a/packages/postgresql/src/PostgreSqlPlatform.ts +++ b/packages/postgresql/src/PostgreSqlPlatform.ts @@ -142,7 +142,7 @@ export class PostgreSqlPlatform extends AbstractSqlPlatform { } marshallArray(values: string[]): string { - const quote = (v: string) => v === '' || v.match(/["{}]/) ? JSON.stringify(v) : v; + const quote = (v: string) => v === '' || v.match(/["{},]/) ? JSON.stringify(v) : v; return `{${values.map(v => quote('' + v)).join(',')}}`; } diff --git a/tests/issues/GH3810.test.ts b/tests/issues/GH3810.test.ts new file mode 100644 index 000000000000..c81fe08f6d9c --- /dev/null +++ b/tests/issues/GH3810.test.ts @@ -0,0 +1,59 @@ +import { Entity, OptionalProps, PrimaryKey, Property, SimpleLogger } from '@mikro-orm/core'; +import { MikroORM } from '@mikro-orm/postgresql'; +import { mockLogger } from '../helpers'; + +@Entity() +class User { + + [OptionalProps]?: 'options'; + + @PrimaryKey() + id!: number; + + @Property({ type: 'string[]', default: ['foo'] }) + options = ['foo']; + +} + +let orm: MikroORM; + +beforeAll(async () => { + orm = await MikroORM.init({ + entities: [User], + dbName: 'mikro_orm_test_gh_3810', + loggerFactory: options => new SimpleLogger(options), + }); + await orm.schema.refreshDatabase(); +}); + +afterAll(async () => { + await orm.close(); +}); + +test('3810', async () => { + const mock = mockLogger(orm, ['query', 'query-params']); + const u1 = orm.em.create(User, { options: ['foo,'] }); + await orm.em.flush(); + + u1.options.push('asd,'); + u1.options.push('bar'); + u1.options.push(',baz'); + await orm.em.flush(); + + await orm.em.refresh(u1); + u1.options.push('qux,'); + await orm.em.flush(); + + expect(mock.mock.calls).toEqual([ + ['[query] begin'], + ["[query] insert into \"user\" (\"options\") values ('{\"foo,\"}') returning \"id\", \"options\""], + ['[query] commit'], + ['[query] begin'], + ["[query] update \"user\" set \"options\" = '{\"foo,\",\"asd,\",bar,\",baz\"}' where \"id\" = 1"], + ['[query] commit'], + ['[query] select "u0".* from "user" as "u0" where "u0"."id" = 1 limit 1'], + ['[query] begin'], + ["[query] update \"user\" set \"options\" = '{\"foo,\",\"asd,\",bar,\",baz\",\"qux,\"}' where \"id\" = 1"], + ['[query] commit'], + ]); +});