From 2a735553e978918f2cf6c996cb466c20f0a5f28a Mon Sep 17 00:00:00 2001 From: Denis Bykhov Date: Sat, 22 Mar 2025 18:32:28 +0500 Subject: [PATCH] Fix sql batch update (#8296) --- server/postgres/src/storage.ts | 72 +++++++++++++++++++++------------- 1 file changed, 44 insertions(+), 28 deletions(-) diff --git a/server/postgres/src/storage.ts b/server/postgres/src/storage.ts index a06bdbb4b3..9459287b56 100644 --- a/server/postgres/src/storage.ts +++ b/server/postgres/src/storage.ts @@ -1810,26 +1810,49 @@ export class PostgresAdapter extends PostgresAdapterBase { this._helper.domains = new Set(resultDomains as Domain[]) } - private process (ops: OperationBulk, tx: Tx): void { - switch (tx._class) { - case core.class.TxCreateDoc: - ops.add.push(TxProcessor.createDoc2Doc(tx as TxCreateDoc)) - break - case core.class.TxUpdateDoc: - ops.updates.push(tx as TxUpdateDoc) - break - case core.class.TxRemoveDoc: - ops.removes.push(tx as TxRemoveDoc) - break - case core.class.TxMixin: - ops.mixins.push(tx as TxMixin) - break - case core.class.TxApplyIf: - return undefined - default: - console.error('Unknown/Unsupported operation:', tx._class, tx) - break + private process (txes: Tx[]): OperationBulk { + const ops: OperationBulk = { + add: [], + mixins: [], + removes: [], + updates: [] } + const updateGroup = new Map, TxUpdateDoc>() + for (const tx of txes) { + switch (tx._class) { + case core.class.TxCreateDoc: + ops.add.push(TxProcessor.createDoc2Doc(tx as TxCreateDoc)) + break + case core.class.TxUpdateDoc: { + const updateTx = tx as TxUpdateDoc + if (isOperator(updateTx.operations)) { + ops.updates.push(updateTx) + } else { + const current = updateGroup.get(updateTx.objectId) + if (current !== undefined) { + current.operations = { ...current.operations, ...updateTx.operations } + updateGroup.set(updateTx.objectId, current) + } else { + updateGroup.set(updateTx.objectId, updateTx) + } + } + break + } + case core.class.TxRemoveDoc: + ops.removes.push(tx as TxRemoveDoc) + break + case core.class.TxMixin: + ops.mixins.push(tx as TxMixin) + break + case core.class.TxApplyIf: + break + default: + console.error('Unknown/Unsupported operation:', tx._class, tx) + break + } + } + ops.updates.push(...updateGroup.values()) + return ops } private async txMixin (ctx: MeasureContext, tx: TxMixin, schemaFields: SchemaAndFields): Promise { @@ -1878,15 +1901,8 @@ export class PostgresAdapter extends PostgresAdapterBase { if (domain === undefined) { continue } - const ops: OperationBulk = { - add: [], - mixins: [], - removes: [], - updates: [] - } - for (const tx of txs) { - this.process(ops, tx) - } + + const ops = this.process(txs) const domainFields = getSchemaAndFields(domain) if (ops.add.length > 0) {