Fix composite upsert (#16718)

Doing an upsert on existing value, composite field not updated properly.

```
Input: {
  id: "08ca34fe-fc39-474f-adac-4d89f844e922",
  name: "tom",
  linkedinLink: {
    primaryLinkUrl: "https://www.linkedin.com/in/etienneyaouni1982",
    primaryLinkLabel: "etienne",
    secondaryLinks: null,
  },
}
```

Building `overwrites` for upsert forgets `linkedinLink` because column
names are not flattened yet.
We don't want to call formatData yet on the input, because this is
heavy.

Overriding `overwrites` on execute.
This commit is contained in:
Thomas Trompette
2025-12-19 18:28:28 +01:00
committed by GitHub
parent 0849dda153
commit 9aa77ab991
@@ -115,6 +115,40 @@ export class WorkspaceInsertQueryBuilder<
shouldBypassPermissionChecks: this.shouldBypassPermissionChecks,
});
// Fix overwrites for composite fields - valuesSet contains formatted/flattened column names
// but overwrites was computed before formatData, missing composite field columns
if (
isDefined(this.expressionMap.onUpdate?.overwrite) &&
isDefined(this.expressionMap.valuesSet)
) {
const valuesArray = Array.isArray(this.expressionMap.valuesSet)
? this.expressionMap.valuesSet
: [this.expressionMap.valuesSet];
const allValueKeys = new Set(
valuesArray.flatMap((value) => Object.keys(value)),
);
const mainAliasMetadata = this.expressionMap.mainAlias?.metadata;
if (mainAliasMetadata) {
const missingColumns = mainAliasMetadata.columns
.filter(
(col) =>
allValueKeys.has(col.databaseName) &&
!this.expressionMap.onUpdate.overwrite!.includes(
col.databaseName,
),
)
.map((col) => col.databaseName);
this.expressionMap.onUpdate.overwrite = [
...this.expressionMap.onUpdate.overwrite,
...missingColumns,
];
}
}
const mainAliasTarget = this.getMainAliasTarget();
const objectMetadata = getObjectMetadataFromEntityTarget(