@prisma/orm-family-sql 8.0.0-rc.17-dev.42 → 8.0.0-rc.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1610,9 +1610,13 @@ function aliasTarget(namespaceId, tableName) {
1610
1610
  tableName
1611
1611
  });
1612
1612
  }
1613
- function buildReturningColumns(contract, modelName, target, returningColumns) {
1613
+ function projectTableColumns(contract, target, columns) {
1614
1614
  const { namespaceId, tableName } = target.storage;
1615
- return (returningColumns && returningColumns.length > 0 ? [...returningColumns] : getColumnsReadOnTable(contract, namespaceId, modelName, tableName)).map((column) => ProjectionItem.of(column, target.column(column), codecRefForStorageColumn(contract.storage, namespaceId, tableName, column)));
1615
+ return columns.map((column) => ProjectionItem.of(column, target.column(column), codecRefForStorageColumn(contract.storage, namespaceId, tableName, column)));
1616
+ }
1617
+ function returningProjection(contract, modelName, target, returningColumns) {
1618
+ const { namespaceId, tableName } = target.storage;
1619
+ return projectTableColumns(contract, target, returningColumns && returningColumns.length > 0 ? [...returningColumns] : getColumnsReadOnTable(contract, namespaceId, modelName, tableName));
1616
1620
  }
1617
1621
  function toParamAssignments(contract, namespaceId, tableName, values) {
1618
1622
  const assignments = {};
@@ -1671,7 +1675,7 @@ function conflictSkipClause(target, conflictSkip) {
1671
1675
  function compileInsertReturning(contract, namespaceId, modelName, tableName, rows, returningColumns, conflictSkip) {
1672
1676
  const target = aliasTarget(namespaceId, tableName);
1673
1677
  const { rows: normalizedRows } = normalizeInsertRows(contract, namespaceId, tableName, rows);
1674
- const ast = InsertAst.into(target.tableSource(contract)).withRows(normalizedRows).withOnConflict(conflictSkipClause(target, conflictSkip)).withReturning(buildReturningColumns(contract, modelName, target, returningColumns));
1678
+ const ast = InsertAst.into(target.tableSource(contract)).withRows(normalizedRows).withOnConflict(conflictSkipClause(target, conflictSkip)).withReturning(returningProjection(contract, modelName, target, returningColumns));
1675
1679
  const { params } = deriveParamsFromAst(ast);
1676
1680
  return buildOrmQueryPlan(contract, ast, params);
1677
1681
  }
@@ -1687,7 +1691,7 @@ function stripUndefinedValues(row) {
1687
1691
  for (const [key, value] of Object.entries(row)) if (value !== void 0) result[key] = value;
1688
1692
  return result;
1689
1693
  }
1690
- function buildCountMutationWhere(contract, tables, filters, variantValue) {
1694
+ function countMutationWhere(contract, tables, filters, variantValue) {
1691
1695
  const variantTable = variantValue === void 0 ? void 0 : tables.variants.get(variantValue);
1692
1696
  if (variantTable === void 0) return combineWhereExprs(filters);
1693
1697
  const { root } = tables;
@@ -1736,42 +1740,31 @@ function compileUpsertReturning(contract, namespaceId, modelName, tableName, cre
1736
1740
  const target = aliasTarget(namespaceId, tableName);
1737
1741
  const conflictTarget = InsertOnConflict.on(conflictColumns.map((column) => target.column(column)));
1738
1742
  const onConflict = updateAssignments ? conflictTarget.doUpdateSet(updateAssignments.assignments) : conflictTarget.doNothing();
1739
- const ast = InsertAst.into(target.tableSource(contract)).withRows([createAssignments.assignments]).withOnConflict(onConflict).withReturning(buildReturningColumns(contract, modelName, target, returningColumns));
1743
+ const ast = InsertAst.into(target.tableSource(contract)).withRows([createAssignments.assignments]).withOnConflict(onConflict).withReturning(returningProjection(contract, modelName, target, returningColumns));
1740
1744
  const { params } = deriveParamsFromAst(ast);
1741
1745
  return buildOrmQueryPlan(contract, ast, params);
1742
1746
  }
1743
- function compileUpdateReturning(contract, modelName, tables, setValues, filters, returningColumns) {
1747
+ function updateAst(contract, tables, setValues, where) {
1744
1748
  const { root } = tables;
1745
1749
  const { namespaceId, tableName } = root.storage;
1746
- const where = combineWhereExprs(filters);
1747
1750
  const { assignments } = toParamAssignments(contract, namespaceId, tableName, setValues);
1748
- let ast = UpdateAst.table(root.tableSource(contract)).withSet(assignments).withReturning(buildReturningColumns(contract, modelName, root, returningColumns));
1749
- if (where) ast = ast.withWhere(where);
1750
- const { params } = deriveParamsFromAst(ast);
1751
- return buildOrmQueryPlan(contract, ast, params);
1751
+ return UpdateAst.table(root.tableSource(contract)).withSet(assignments).withWhere(where);
1752
1752
  }
1753
- function compileUpdateCount(contract, tables, setValues, filters, variantValue) {
1754
- const { root } = tables;
1755
- const { namespaceId, tableName } = root.storage;
1756
- const where = buildCountMutationWhere(contract, tables, filters, variantValue);
1757
- const { assignments } = toParamAssignments(contract, namespaceId, tableName, setValues);
1758
- let ast = UpdateAst.table(root.tableSource(contract)).withSet(assignments);
1759
- if (where) ast = ast.withWhere(where);
1753
+ function deleteAst(contract, tables, where) {
1754
+ return DeleteAst.from(tables.root.tableSource(contract)).withWhere(where);
1755
+ }
1756
+ function compileUpdateReturning(contract, modelName, tables, setValues, filters, returningColumns) {
1757
+ const ast = updateAst(contract, tables, setValues, combineWhereExprs(filters)).withReturning(returningProjection(contract, modelName, tables.root, returningColumns));
1760
1758
  const { params } = deriveParamsFromAst(ast);
1761
1759
  return buildOrmQueryPlan(contract, ast, params);
1762
1760
  }
1763
- function compileDeleteReturning(contract, modelName, tables, filters, returningColumns) {
1764
- const { root } = tables;
1765
- const where = combineWhereExprs(filters);
1766
- let ast = DeleteAst.from(root.tableSource(contract)).withReturning(buildReturningColumns(contract, modelName, root, returningColumns));
1767
- if (where) ast = ast.withWhere(where);
1761
+ function compileUpdateCount(contract, tables, setValues, filters, variantValue) {
1762
+ const ast = updateAst(contract, tables, setValues, countMutationWhere(contract, tables, filters, variantValue));
1768
1763
  const { params } = deriveParamsFromAst(ast);
1769
1764
  return buildOrmQueryPlan(contract, ast, params);
1770
1765
  }
1771
1766
  function compileDeleteCount(contract, tables, filters, variantValue) {
1772
- const where = buildCountMutationWhere(contract, tables, filters, variantValue);
1773
- let ast = DeleteAst.from(tables.root.tableSource(contract));
1774
- if (where) ast = ast.withWhere(where);
1767
+ const ast = deleteAst(contract, tables, countMutationWhere(contract, tables, filters, variantValue));
1775
1768
  const { params } = deriveParamsFromAst(ast);
1776
1769
  return buildOrmQueryPlan(contract, ast, params);
1777
1770
  }
@@ -2366,21 +2359,24 @@ function buildRootPolymorphism(contract, state, modelName) {
2366
2359
  projection: [...mtiArtifacts?.projection ?? [], ...buildHiddenDiscriminatorProjection(contract, root, polyInfo, selection.needsHiddenDiscriminator)]
2367
2360
  };
2368
2361
  }
2369
- function compileSelect(contract, modelName, state) {
2362
+ function collectionSelectAst(contract, modelName, state) {
2370
2363
  assertLockCompatible(state);
2371
2364
  if (state.distinctOn !== void 0 && state.distinctOn.length > 0) assertDistinctOnCapability(contract, "distinctOn");
2372
2365
  const polymorphism = buildRootPolymorphism(contract, state, modelName);
2373
- const ast = buildSelectAst(contract, modelName, {
2366
+ return buildSelectAst(contract, modelName, {
2374
2367
  ...polymorphism.projectionState,
2375
2368
  includes: []
2376
2369
  }, {
2377
2370
  joins: polymorphism.joins,
2378
2371
  includeProjection: polymorphism.projection
2379
2372
  });
2373
+ }
2374
+ function compileSelect(contract, modelName, state) {
2375
+ const ast = collectionSelectAst(contract, modelName, state);
2380
2376
  const { params } = deriveParamsFromAst(ast);
2381
2377
  return buildOrmQueryPlan(contract, ast, params, state.annotations);
2382
2378
  }
2383
- function compileSelectWithIncludes(contract, aggregates, modelName, state) {
2379
+ function collectionSelectWithIncludesAst(contract, aggregates, modelName, state) {
2384
2380
  assertLockCompatible(state);
2385
2381
  const topLevelWhere = buildStateWhere(contract, state);
2386
2382
  const polymorphism = buildRootPolymorphism(contract, state, modelName);
@@ -2391,7 +2387,7 @@ function compileSelectWithIncludes(contract, aggregates, modelName, state) {
2391
2387
  const artifact = buildCorrelatedIncludeProjection(contract, aggregates, scope, parent, include);
2392
2388
  includeProjection.push(artifact.projection);
2393
2389
  }
2394
- const ast = buildSelectAst(contract, modelName, {
2390
+ return buildSelectAst(contract, modelName, {
2395
2391
  ...polymorphism.projectionState,
2396
2392
  includes: []
2397
2393
  }, {
@@ -2399,6 +2395,9 @@ function compileSelectWithIncludes(contract, aggregates, modelName, state) {
2399
2395
  includeProjection,
2400
2396
  ...ifDefined("where", topLevelWhere)
2401
2397
  });
2398
+ }
2399
+ function compileSelectWithIncludes(contract, aggregates, modelName, state) {
2400
+ const ast = collectionSelectWithIncludesAst(contract, aggregates, modelName, state);
2402
2401
  const { params } = deriveParamsFromAst(ast);
2403
2402
  return buildOrmQueryPlan(contract, ast, params, state.annotations);
2404
2403
  }
@@ -2412,22 +2411,20 @@ function describeCollectionRows(options) {
2412
2411
  };
2413
2412
  }
2414
2413
  function describeExecutionRows(options) {
2415
- const { context, state, modelName, namespaceId } = options;
2414
+ const { context, state, modelName } = options;
2416
2415
  const { contract } = context;
2417
- const polyInfo = resolvePolymorphismInfo(contract, namespaceId, modelName);
2418
- if (state.includes.length === 0) {
2419
- const compiled = compileSelect(contract, modelName, state);
2420
- const mapper = polyInfo ? (rawRow) => blindCast(mapPolymorphicRow(contract, namespaceId, modelName, polyInfo, state.tables, rawRow, state.variantValue)) : (rawRow) => blindCast(mapStorageRowToModelFields(contract, namespaceId, modelName, rawRow));
2421
- return {
2422
- plan: compiled,
2423
- consume: (rows) => mapResultRows(rows, mapper)
2424
- };
2425
- }
2426
2416
  return {
2427
- plan: compileSelectWithIncludes(contract, context.aggregateDescriptors, modelName, state),
2428
- consume: (rows) => consumeIncludeRows(context, state, namespaceId, modelName, rows)
2417
+ plan: state.includes.length === 0 ? compileSelect(contract, modelName, state) : compileSelectWithIncludes(contract, context.aggregateDescriptors, modelName, state),
2418
+ consume: (rows) => consumeCollectionRows(options, rows)
2429
2419
  };
2430
2420
  }
2421
+ function consumeCollectionRows(options, rows) {
2422
+ const { context, state, modelName, namespaceId } = options;
2423
+ const { contract } = context;
2424
+ if (state.includes.length > 0) return consumeIncludeRows(context, state, namespaceId, modelName, rows);
2425
+ const polyInfo = resolvePolymorphismInfo(contract, namespaceId, modelName);
2426
+ return mapResultRows(rows, polyInfo ? (rawRow) => blindCast(mapPolymorphicRow(contract, namespaceId, modelName, polyInfo, state.tables, rawRow, state.variantValue)) : (rawRow) => blindCast(mapStorageRowToModelFields(contract, namespaceId, modelName, rawRow)));
2427
+ }
2431
2428
  function deferResolution(resolve) {
2432
2429
  try {
2433
2430
  const value = resolve();
@@ -4088,7 +4085,7 @@ async function executeNestedCreateMutation(options) {
4088
4085
  return withMutationScope(options.runtime, async (scope) => createGraph(scope, options.context, options.namespaceId, options.modelName, options.data));
4089
4086
  }
4090
4087
  async function executeNestedUpdateMutation(options) {
4091
- return withMutationScope(options.runtime, async (scope) => updateFirstGraph(scope, options.context, options.namespaceId, options.modelName, options.tables, options.filters, options.data));
4088
+ return withMutationScope(options.runtime, async (scope) => updateFirstGraph$1(scope, options.context, options.namespaceId, options.modelName, options.tables, options.filters, options.data));
4092
4089
  }
4093
4090
  function buildRowIdentityFilterFromRow(contract, namespaceId, modelName, row) {
4094
4091
  const tableName = resolveModelTableName(contract, namespaceId, modelName);
@@ -4165,7 +4162,7 @@ async function createGraph(scope, context, namespaceId, modelName, input) {
4165
4162
  for (const relationMutation of junctionOwned) await applyJunctionOwnedMutation(scope, context, namespaceId, modelName, parentRow, relationMutation.relation, relationMutation.mutation);
4166
4163
  return parentRow;
4167
4164
  }
4168
- async function updateFirstGraph(scope, context, namespaceId, modelName, tables, filters, input) {
4165
+ async function updateFirstGraph$1(scope, context, namespaceId, modelName, tables, filters, input) {
4169
4166
  const contract = context.contract;
4170
4167
  const existingRow = await findFirstByFilters(scope, contract, namespaceId, modelName, tables, filters);
4171
4168
  if (!existingRow) return null;
@@ -4596,6 +4593,352 @@ function getRelationDefinitions(contract, namespaceId, modelName) {
4596
4593
  function toFieldName(contract, namespaceId, modelName, columnName) {
4597
4594
  return fieldOfColumn(getModelColumnFields(contract, namespaceId, modelName), modelName, columnName);
4598
4595
  }
4596
+ function executeFiltered(ast, filter, run) {
4597
+ if (filter === null) return executeStatement$1(ast, run);
4598
+ if (filter.some((conditions) => conditions.length === 0)) return noRows();
4599
+ const where = combineWhereExprs([...ast.where === void 0 ? [] : [ast.where], ...filter.map(anyOf)]);
4600
+ return executeStatement$1(ast.withWhere(where), run);
4601
+ }
4602
+ function executeStatement$1(ast, run) {
4603
+ return ast.kind === "select" || ast.returning !== void 0 ? run.query(ast) : run.execute(ast);
4604
+ }
4605
+ function anyOf(conditions) {
4606
+ const [first, ...others] = conditions;
4607
+ return first !== void 0 && others.length === 0 ? first : OrExpr.of(conditions);
4608
+ }
4609
+ function withColumns(returned, columns) {
4610
+ const present = new Set(returned.map((item) => item.alias));
4611
+ return [...returned, ...columns.filter((column) => !present.has(column.alias))];
4612
+ }
4613
+ function noRows() {
4614
+ const generator = async function* () {};
4615
+ return new AsyncIterableResult(generator());
4616
+ }
4617
+ var Node = class {};
4618
+ var Delete = class Delete extends Node {
4619
+ ast;
4620
+ constructor(ast) {
4621
+ super();
4622
+ this.ast = ast;
4623
+ Object.freeze(this);
4624
+ }
4625
+ get returns() {
4626
+ return this.ast.returning ?? [];
4627
+ }
4628
+ execute(inputs, run) {
4629
+ return executeFiltered(this.ast, inputs.filter, run);
4630
+ }
4631
+ withReturning(columns) {
4632
+ return new Delete(this.ast.withReturning(withColumns(this.returns, columns)));
4633
+ }
4634
+ };
4635
+ var Edge = class {
4636
+ from;
4637
+ columns;
4638
+ constructor(from, columns) {
4639
+ this.from = from;
4640
+ this.columns = Object.freeze([...columns]);
4641
+ }
4642
+ };
4643
+ var FilterData = class extends Edge {
4644
+ constructor(from, columns) {
4645
+ super(from, columns);
4646
+ Object.freeze(this);
4647
+ }
4648
+ output(sourceRow) {
4649
+ const conditions = this.columns.map(([source, target]) => BinaryExpr.eq(target.expr, ParamRef.of(sourceRow[source.alias], {
4650
+ name: target.alias,
4651
+ ...ifDefined("codec", target.codec)
4652
+ })));
4653
+ const [first, ...others] = conditions;
4654
+ return first !== void 0 && others.length === 0 ? first : AndExpr.of(conditions);
4655
+ }
4656
+ };
4657
+ var Find = class Find extends Node {
4658
+ ast;
4659
+ constructor(ast) {
4660
+ super();
4661
+ this.ast = ast;
4662
+ Object.freeze(this);
4663
+ }
4664
+ get returns() {
4665
+ return this.ast.projection;
4666
+ }
4667
+ execute(inputs, run) {
4668
+ return executeFiltered(this.ast, inputs.filter, run);
4669
+ }
4670
+ withReturning(columns) {
4671
+ return new Find(this.ast.withProjection(withColumns(this.returns, columns)));
4672
+ }
4673
+ };
4674
+ var Graph = class {
4675
+ #ids = [];
4676
+ #nodes = [];
4677
+ #inputs = [];
4678
+ #readers = [];
4679
+ #result = void 0;
4680
+ get result() {
4681
+ return this.#result;
4682
+ }
4683
+ setResult(node) {
4684
+ this.#result = node;
4685
+ }
4686
+ add(node, inputs) {
4687
+ const id = blindCast(this.#nodes.length);
4688
+ this.#ids.push(id);
4689
+ this.#nodes.push(node);
4690
+ this.#inputs.push(inputs);
4691
+ this.#readers.push([]);
4692
+ for (const edge of Object.values(inputs).flat()) {
4693
+ this.#readers[edge.from]?.push({
4694
+ reader: id,
4695
+ edge
4696
+ });
4697
+ this.#nodes[edge.from] = this.#nodes[edge.from]?.withReturning(edge.columns.map(([source]) => source));
4698
+ }
4699
+ return id;
4700
+ }
4701
+ replace(id, next) {
4702
+ this.#nodes[id] = next;
4703
+ }
4704
+ remove(id) {
4705
+ for (const edge of Object.values(this.inputsOf(id)).flat()) this.#readers[edge.from] = this.readersOf(edge.from).filter((entry) => entry.edge !== edge);
4706
+ for (const { reader, edge } of this.readersOf(id)) this.#inputs[reader] = Object.fromEntries(Object.entries(this.inputsOf(reader)).map(([slot, edges]) => [slot, edges.filter((other) => other !== edge)]));
4707
+ this.#nodes[id] = void 0;
4708
+ this.#inputs[id] = {};
4709
+ this.#readers[id] = [];
4710
+ }
4711
+ nodes() {
4712
+ return this.#ids.flatMap((id) => {
4713
+ const node = this.#nodes[id];
4714
+ return node === void 0 ? [] : [[id, node]];
4715
+ });
4716
+ }
4717
+ inputsOf(id) {
4718
+ return this.#inputs[id] ?? {};
4719
+ }
4720
+ readersOf(id) {
4721
+ return this.#readers[id] ?? [];
4722
+ }
4723
+ };
4724
+ var Update = class Update extends Node {
4725
+ ast;
4726
+ constructor(ast) {
4727
+ super();
4728
+ this.ast = ast;
4729
+ Object.freeze(this);
4730
+ }
4731
+ get returns() {
4732
+ return this.ast.returning ?? [];
4733
+ }
4734
+ execute(inputs, run) {
4735
+ return executeFiltered(this.ast, inputs.filter, run);
4736
+ }
4737
+ withReturning(columns) {
4738
+ return new Update(this.ast.withReturning(withColumns(this.returns, columns)));
4739
+ }
4740
+ };
4741
+ function updateAllGraph(collection, set) {
4742
+ const { context, state } = collection;
4743
+ const graph = new Graph();
4744
+ if (Object.keys(set).length === 0) {
4745
+ graph.setResult(graph.add(new Find(selectRowsAst(collection, state)), { filter: [] }));
4746
+ return graph;
4747
+ }
4748
+ requireIdentityColumnsForIncludes(collection);
4749
+ const update = updateAst(context.contract, state.tables, set, whereOf(collection));
4750
+ const updated = graph.add(new Update(update), { filter: [] });
4751
+ graph.setResult(addWithIncludes(graph, collection, updated));
4752
+ return graph;
4753
+ }
4754
+ function deleteAllGraph(collection) {
4755
+ const { context, state } = collection;
4756
+ const graph = new Graph();
4757
+ const del = new Delete(deleteAst(context.contract, state.tables, whereOf(collection)));
4758
+ if (state.includes.length === 0) {
4759
+ graph.setResult(graph.add(del, { filter: [] }));
4760
+ return graph;
4761
+ }
4762
+ graph.setResult(graph.add(new Find(selectRowsAst(collection, state)), { filter: [] }));
4763
+ graph.add(del, { filter: [] });
4764
+ return graph;
4765
+ }
4766
+ function updateFirstGraph(collection, set) {
4767
+ const { context, state } = collection;
4768
+ const graph = new Graph();
4769
+ const nothingToSet = Object.keys(set).length === 0;
4770
+ if (!nothingToSet) {
4771
+ requireIdentityColumns(collection);
4772
+ requireIdentityColumnsForIncludes(collection);
4773
+ }
4774
+ const find = addFindOfFirstRow(graph, collection, nothingToSet ? selectRowsAst : selectIdentityAst);
4775
+ if (find === void 0) return graph;
4776
+ if (nothingToSet) {
4777
+ graph.setResult(find);
4778
+ return graph;
4779
+ }
4780
+ const update = updateAst(context.contract, state.tables, set, void 0);
4781
+ const updated = graph.add(new Update(update), { filter: [sameRow(find, collection)] });
4782
+ graph.setResult(addWithIncludes(graph, collection, updated));
4783
+ return graph;
4784
+ }
4785
+ function deleteFirstGraph(collection) {
4786
+ const { context, state } = collection;
4787
+ const withIncludes = state.includes.length > 0;
4788
+ const graph = new Graph();
4789
+ requireIdentityColumns(collection);
4790
+ const find = addFindOfFirstRow(graph, collection, withIncludes ? selectRowsAst : selectIdentityAst);
4791
+ if (find === void 0) return graph;
4792
+ const del = deleteAst(context.contract, state.tables, void 0);
4793
+ const deleted = graph.add(new Delete(del), { filter: [sameRow(find, collection)] });
4794
+ graph.setResult(withIncludes ? find : deleted);
4795
+ return graph;
4796
+ }
4797
+ function addWithIncludes(graph, collection, written) {
4798
+ const { state } = collection;
4799
+ if (state.includes.length === 0) return written;
4800
+ const select = selectRowsAst(collection, {
4801
+ ...emptyState(state.tables),
4802
+ selectedFields: state.selectedFields,
4803
+ includes: state.includes
4804
+ });
4805
+ return graph.add(new Find(select), { filter: [sameRow(written, collection)] });
4806
+ }
4807
+ function requireIdentityColumnsForIncludes(collection) {
4808
+ const { modelName, state } = collection;
4809
+ const { tableName } = state.tables.root.storage;
4810
+ if (state.includes.length > 0 && identityColumnsOf(collection).length === 0) throw ormError("ORM.ROW_IDENTITY_MISSING", `Cannot load includes for the mutation result on model "${modelName}": table "${tableName}" has no primary key or unique constraint to key the include read-back on.`, { meta: {
4811
+ model: modelName,
4812
+ table: tableName
4813
+ } });
4814
+ }
4815
+ function addFindOfFirstRow(graph, collection, select) {
4816
+ const { state } = collection;
4817
+ checkLimitOffset("limit", state.limit);
4818
+ if (state.limit === 0) return;
4819
+ return graph.add(new Find(select(collection, {
4820
+ ...state,
4821
+ limit: 1
4822
+ })), { filter: [] });
4823
+ }
4824
+ function requireIdentityColumns(collection) {
4825
+ const { modelName, state } = collection;
4826
+ const { tableName } = state.tables.root.storage;
4827
+ if (identityColumnsOf(collection).length === 0) throw ormError("ORM.ROW_IDENTITY_MISSING", `update()/delete() on model "${modelName}" requires the table to have a primary key or unique constraint`, { meta: {
4828
+ model: modelName,
4829
+ table: tableName
4830
+ } });
4831
+ }
4832
+ function selectIdentityAst(collection, state) {
4833
+ return collectionSelectAst(collection.context.contract, collection.modelName, {
4834
+ ...state,
4835
+ includes: [],
4836
+ selectedFields: identityColumnsOf(collection)
4837
+ });
4838
+ }
4839
+ function selectRowsAst(collection, state) {
4840
+ const { context, modelName } = collection;
4841
+ if (state.includes.length === 0) return collectionSelectAst(context.contract, modelName, state);
4842
+ return collectionSelectWithIncludesAst(context.contract, context.aggregateDescriptors, modelName, state);
4843
+ }
4844
+ function identityColumnsOf(collection) {
4845
+ const { namespaceId, tableName } = collection.state.tables.root.storage;
4846
+ return resolveRowIdentityColumns(collection.context.contract, namespaceId, tableName);
4847
+ }
4848
+ function sameRow(find, collection) {
4849
+ const { context, state } = collection;
4850
+ return new FilterData(find, projectTableColumns(context.contract, state.tables.root, identityColumnsOf(collection)).map((column) => [column, column]));
4851
+ }
4852
+ function whereOf(collection) {
4853
+ const { context, state } = collection;
4854
+ return countMutationWhere(context.contract, state.tables, state.filters, state.variantValue);
4855
+ }
4856
+ function queryGraph(graph, ctx, annotations, callerRows) {
4857
+ returnCallerColumns(graph, callerRows);
4858
+ const [only, ...others] = graph.nodes();
4859
+ if (only !== void 0 && others.length === 0 && only[0] === graph.result) {
4860
+ const [id, node] = only;
4861
+ const run = runOn(ctx, annotations);
4862
+ return shapeRows(graph, id, rowStream(node.execute(inputsOf(graph, id, []), run)), callerRows);
4863
+ }
4864
+ const generator = async function* () {
4865
+ yield* (await runAllNodes(graph, ctx, annotations, callerRows)).rows;
4866
+ };
4867
+ return new AsyncIterableResult(generator());
4868
+ }
4869
+ async function executeGraph(graph, ctx, annotations) {
4870
+ return { affectedRows: (await runAllNodes(graph, ctx, annotations, void 0)).count };
4871
+ }
4872
+ function returnCallerColumns(graph, callerRows) {
4873
+ const { context, modelName, state } = callerRows;
4874
+ const columns = returningProjection(context.contract, modelName, state.tables.root, state.selectedFields);
4875
+ for (const [id, node] of graph.nodes()) if (id === graph.result) graph.replace(id, node.withReturning(columns));
4876
+ }
4877
+ function runAllNodes(graph, ctx, annotations, callerRows) {
4878
+ if (graph.nodes().length > 1) return withMutationScope(ctx.runtime, (scope) => runNodesInOrder(graph, {
4879
+ ...ctx,
4880
+ runtime: scope
4881
+ }, annotations, callerRows));
4882
+ return runNodesInOrder(graph, ctx, annotations, callerRows);
4883
+ }
4884
+ async function runNodesInOrder(graph, ctx, annotations, callerRows) {
4885
+ const run = runOn(ctx, annotations);
4886
+ const collected = [];
4887
+ let rows = [];
4888
+ let count = 0;
4889
+ for (const [id, node] of graph.nodes()) {
4890
+ const executed = await node.execute(inputsOf(graph, id, collected), run);
4891
+ collected[id] = executed;
4892
+ if (id !== graph.result) continue;
4893
+ const storageRows = rowsOf(executed);
4894
+ count = typeof executed === "number" ? executed : storageRows.length;
4895
+ if (callerRows !== void 0) rows = await shapeRows(graph, id, streamOf(storageRows), callerRows).toArray();
4896
+ }
4897
+ return {
4898
+ rows,
4899
+ count
4900
+ };
4901
+ }
4902
+ function inputsOf(graph, id, collected) {
4903
+ const outputs = {};
4904
+ const slots = graph.inputsOf(id);
4905
+ for (const slot in slots) {
4906
+ const edges = slots[slot] ?? [];
4907
+ outputs[slot] = edges.length === 0 ? null : edges.map((edge) => rowsOf(collected[edge.from]).map((row) => edge.output(row)));
4908
+ }
4909
+ return outputs;
4910
+ }
4911
+ function runOn(ctx, annotations) {
4912
+ const { contract } = ctx.context;
4913
+ const planOf = (ast) => mergeAnnotations(buildOrmQueryPlan(contract, ast, deriveParamsFromAst(ast).params), annotations);
4914
+ return {
4915
+ query: (ast) => queryPlanRows(ctx.runtime, planOf(ast)),
4916
+ execute: async (ast) => (await ctx.runtime.execute(planOf(ast))).affectedRows
4917
+ };
4918
+ }
4919
+ function shapeRows(graph, id, storageRows, callerRows) {
4920
+ const { context, namespaceId, modelName, state } = callerRows;
4921
+ const { contract } = context;
4922
+ const { tableName } = state.tables.root.storage;
4923
+ const selected = state.selectedFields ?? getColumnsReadOnTable(contract, namespaceId, modelName, tableName);
4924
+ const hiddenColumns = graph.readersOf(id).flatMap(({ edge }) => edge.columns.map(([source]) => source.alias)).filter((column) => !selected.includes(column));
4925
+ return mapResultRows(consumeCollectionRows(callerRows, storageRows), (row) => {
4926
+ stripHiddenMappedFields(contract, namespaceId, modelName, row, hiddenColumns);
4927
+ return blindCast(row);
4928
+ });
4929
+ }
4930
+ function rowsOf(executed) {
4931
+ return typeof executed === "object" ? executed : [];
4932
+ }
4933
+ function rowStream(executed) {
4934
+ return executed instanceof AsyncIterableResult ? executed : streamOf([]);
4935
+ }
4936
+ function streamOf(rows) {
4937
+ const generator = async function* () {
4938
+ yield* rows;
4939
+ };
4940
+ return new AsyncIterableResult(generator());
4941
+ }
4599
4942
  function normalizeWhereArg(arg, options) {
4600
4943
  if (arg === void 0) return;
4601
4944
  if (arg === null) throw ormError("ORM.ARGUMENT_INVALID", "WhereArg cannot be null. Pass undefined or a valid WhereExpr/ToWhereExpr payload.", { meta: { argument: "where" } });
@@ -5451,132 +5794,56 @@ var CollectionBase = class CollectionBase {
5451
5794
  return this.#reloadMutationRowByIdentity(identityCriterion);
5452
5795
  }
5453
5796
  assertModelFieldNames(this.contract, this.namespaceId, this.modelName, blindCast(data));
5454
- return withMutationScope(this.ctx.runtime, async (scope) => {
5455
- const scoped = this.#withRuntime(scope);
5456
- const identityWhere = await scoped.#findFirstMatchingRowIdentityWhere();
5457
- if (!identityWhere) return null;
5458
- return (await scoped.#clone({ filters: [identityWhere] }).#updateAllWithAnnotations(blindCast(data), annotationsMap))[0] ?? null;
5459
- });
5797
+ const values = this.#updateValues(blindCast(data));
5798
+ return consumeFirstRow(queryGraph(updateFirstGraph(this.#descriptionOptions(), values), this.ctx, annotationsMap, this.#descriptionOptions()));
5460
5799
  }
5461
5800
  updateAll(data, configure) {
5462
5801
  assertBulkWriteIgnoresNothing(this.state, this.modelName, "updateAll");
5463
5802
  assertLockCompatible(this.state, "mutation");
5464
- return this.#updateAllWithAnnotations(data, this.#collectAnnotationsFromMeta(configure, "write", "updateAll"));
5465
- }
5466
- #updateAllWithAnnotations(data, annotationsMap) {
5803
+ const annotationsMap = this.#collectAnnotationsFromMeta(configure, "write", "updateAll");
5467
5804
  assertReturningCapability(this.contract, "updateAll()");
5468
- const mappedData = mapModelDataToStorageRow(this.contract, this.namespaceId, this.modelName, data);
5469
- if (Object.keys(mappedData).length === 0) {
5470
- const generator = async function* () {};
5471
- return new AsyncIterableResult(generator());
5472
- }
5473
- applyUpdateDefaults(this.ctx, this.namespaceId, this.tableName, mappedData);
5474
- const { selectedForQuery: selectedForUpdate, hiddenColumns } = this.#augmentMutationSelection();
5475
- const compiled = mergeAnnotations(compileUpdateReturning(this.contract, this.modelName, this.state.tables, mappedData, this.state.filters, selectedForUpdate), annotationsMap);
5476
- return dispatchMutationRows({
5477
- context: this.ctx.context,
5478
- runtime: this.ctx.runtime,
5479
- compiled,
5480
- tables: this.state.tables,
5481
- modelName: this.modelName,
5482
- namespaceId: this.namespaceId,
5483
- variantValue: this.state.variantValue,
5484
- includes: this.state.includes,
5485
- selectedFields: this.state.selectedFields,
5486
- hiddenColumns,
5487
- mapRow: (mapped) => blindCast(mapped)
5488
- });
5805
+ return queryGraph(updateAllGraph(this.#descriptionOptions(), this.#updateValues(data)), this.ctx, annotationsMap, this.#descriptionOptions());
5489
5806
  }
5490
5807
  async updateAndCount(data, configure) {
5491
5808
  assertBulkWriteIgnoresNothing(this.state, this.modelName, "updateAndCount");
5492
5809
  assertLockCompatible(this.state, "mutation");
5493
- const mappedData = mapModelDataToStorageRow(this.contract, this.namespaceId, this.modelName, data);
5494
- if (Object.keys(mappedData).length === 0) return 0;
5495
- applyUpdateDefaults(this.ctx, this.namespaceId, this.tableName, mappedData);
5810
+ const values = this.#updateValues(data);
5811
+ const graph = Object.keys(values).length === 0 ? new Graph() : updateAllGraph(this.#descriptionWithoutIncludes(), values);
5496
5812
  const annotationsMap = this.#collectAnnotationsFromMeta(configure, "write", "updateAndCount");
5497
- const compiled = mergeAnnotations(compileUpdateCount(this.contract, this.state.tables, mappedData, this.state.filters, this.state.variantValue), annotationsMap);
5498
- return (await this.ctx.runtime.execute(compiled)).affectedRows;
5813
+ return (await executeGraph(graph, this.ctx, annotationsMap)).affectedRows;
5499
5814
  }
5500
5815
  async delete(configure) {
5501
5816
  assertLockCompatible(this.state, "mutation");
5502
5817
  assertReturningCapability(this.contract, "delete()");
5503
5818
  const annotationsMap = this.#collectAnnotationsFromMeta(configure, "write", "delete");
5504
- return withMutationScope(this.ctx.runtime, async (scope) => {
5505
- const scoped = this.#withRuntime(scope);
5506
- const identityWhere = await scoped.#findFirstMatchingRowIdentityWhere();
5507
- if (!identityWhere) return null;
5508
- return (await scoped.#clone({
5509
- filters: [identityWhere],
5510
- limit: void 0,
5511
- offset: void 0
5512
- }).#executeDeleteReturning(annotationsMap).toArray())[0] ?? null;
5513
- });
5819
+ return consumeFirstRow(queryGraph(deleteFirstGraph(this.#descriptionOptions()), this.ctx, annotationsMap, this.#descriptionOptions()));
5514
5820
  }
5515
5821
  deleteAll(configure) {
5516
5822
  assertBulkWriteIgnoresNothing(this.state, this.modelName, "deleteAll");
5517
5823
  assertLockCompatible(this.state, "mutation");
5518
- return this.#deleteAllWithAnnotations(this.#collectAnnotationsFromMeta(configure, "write", "deleteAll"));
5519
- }
5520
- #deleteAllWithAnnotations(annotationsMap) {
5824
+ const annotationsMap = this.#collectAnnotationsFromMeta(configure, "write", "deleteAll");
5521
5825
  assertReturningCapability(this.contract, "deleteAll()");
5522
- return this.#executeDeleteReturning(annotationsMap);
5523
- }
5524
- #executeDeleteReturning(annotationsMap) {
5525
- if (this.state.includes.length > 0) return this.#executeDeleteReturningWithIncludes(annotationsMap);
5526
- const { selectedForQuery: selectedForDelete, hiddenColumns } = this.#augmentMutationSelection();
5527
- const compiled = mergeAnnotations(compileDeleteReturning(this.contract, this.modelName, this.state.tables, this.state.filters, selectedForDelete), annotationsMap);
5528
- return dispatchMutationRows({
5529
- context: this.ctx.context,
5530
- runtime: this.ctx.runtime,
5531
- compiled,
5532
- tables: this.state.tables,
5533
- modelName: this.modelName,
5534
- namespaceId: this.namespaceId,
5535
- variantValue: this.state.variantValue,
5536
- includes: this.state.includes,
5537
- selectedFields: this.state.selectedFields,
5538
- hiddenColumns,
5539
- mapRow: (mapped) => blindCast(mapped)
5540
- });
5541
- }
5542
- /**
5543
- * Delete read-back with includes.
5544
- *
5545
- * A parent-anchored single-query include read can't observe a row
5546
- * that has already been deleted, so this reads the rows together with
5547
- * their relations BEFORE issuing the DELETE. The snapshot is fully
5548
- * drained into a plain array with `.toArray()` while the rows still
5549
- * exist; only then does the DELETE run. The yielded `for..of` walks
5550
- * that in-memory array, not a live cursor, so nothing reads from the
5551
- * deleted rows after the fact. Snapshot read and delete share one
5552
- * `withMutationScope` so they are atomic; the returned relations
5553
- * reflect the row's state at delete time.
5554
- */
5555
- #executeDeleteReturningWithIncludes(annotationsMap) {
5556
- const collection = this;
5557
- const generator = async function* () {
5558
- const snapshot = await withMutationScope(collection.ctx.runtime, async (scope) => {
5559
- const rows = await dispatchCollectionRows({
5560
- context: collection.ctx.context,
5561
- runtime: scope,
5562
- state: collection.state,
5563
- modelName: collection.modelName,
5564
- namespaceId: collection.namespaceId
5565
- }).toArray();
5566
- const deletePlan = mergeAnnotations(compileDeleteCount(collection.contract, collection.state.tables, collection.state.filters, collection.state.variantValue), annotationsMap);
5567
- await scope.execute(deletePlan);
5568
- return rows;
5569
- });
5570
- for (const row of snapshot) yield row;
5571
- };
5572
- return new AsyncIterableResult(generator());
5826
+ return queryGraph(deleteAllGraph(this.#descriptionOptions()), this.ctx, annotationsMap, this.#descriptionOptions());
5573
5827
  }
5574
5828
  async deleteAndCount(configure) {
5575
5829
  assertBulkWriteIgnoresNothing(this.state, this.modelName, "deleteAndCount");
5576
5830
  assertLockCompatible(this.state, "mutation");
5577
5831
  const annotationsMap = this.#collectAnnotationsFromMeta(configure, "write", "deleteAndCount");
5578
- const compiled = mergeAnnotations(compileDeleteCount(this.contract, this.state.tables, this.state.filters, this.state.variantValue), annotationsMap);
5579
- return (await this.ctx.runtime.execute(compiled)).affectedRows;
5832
+ return (await executeGraph(deleteAllGraph(this.#descriptionWithoutIncludes()), this.ctx, annotationsMap)).affectedRows;
5833
+ }
5834
+ #descriptionWithoutIncludes() {
5835
+ return {
5836
+ ...this.#descriptionOptions(),
5837
+ state: {
5838
+ ...this.state,
5839
+ includes: []
5840
+ }
5841
+ };
5842
+ }
5843
+ #updateValues(data) {
5844
+ const values = mapModelDataToStorageRow(this.contract, this.namespaceId, this.modelName, data);
5845
+ if (Object.keys(values).length > 0) applyUpdateDefaults(this.ctx, this.namespaceId, this.tableName, values);
5846
+ return values;
5580
5847
  }
5581
5848
  #buildUpsertConflictCriterion(createValues, conflictColumns) {
5582
5849
  const criterion = {};
@@ -5618,28 +5885,6 @@ var CollectionBase = class CollectionBase {
5618
5885
  hiddenColumns: []
5619
5886
  };
5620
5887
  }
5621
- async #findFirstMatchingRowIdentityWhere() {
5622
- const identityColumns = resolveRowIdentityColumns(this.contract, this.namespaceId, this.tableName);
5623
- if (identityColumns.length === 0) throw ormError("ORM.ROW_IDENTITY_MISSING", `update()/delete() on model "${this.modelName}" requires the table to have a primary key or unique constraint`, { meta: {
5624
- model: this.modelName,
5625
- table: this.tableName
5626
- } });
5627
- checkLimitOffset("limit", this.state.limit);
5628
- if (this.state.limit === 0) return null;
5629
- const firstRow = await this.#clone({
5630
- selectedFields: [...identityColumns],
5631
- includes: []
5632
- }).first();
5633
- if (!firstRow) return null;
5634
- const criterion = {};
5635
- for (const column of identityColumns) {
5636
- const fieldName = fieldOfColumn(getModelColumnFields(this.contract, this.namespaceId, this.modelName), this.modelName, column);
5637
- const value = blindCast(firstRow)[fieldName];
5638
- if (value === void 0) throw new InternalError(`Missing identity field "${fieldName}" while resolving single-row scope for model "${this.modelName}"`);
5639
- criterion[fieldName] = value;
5640
- }
5641
- return shorthandToWhereExpr(this.ctx.context, this.namespaceId, this.modelName, blindCast(criterion), this.state.tables.root) ?? null;
5642
- }
5643
5888
  async #reloadMutationRowByIdentity(criterion) {
5644
5889
  return this.#reloadMutationRowByCriterion(criterion, "row identity");
5645
5890
  }
@@ -5689,18 +5934,6 @@ var CollectionBase = class CollectionBase {
5689
5934
  ...overrides
5690
5935
  }));
5691
5936
  }
5692
- #withRuntime(runtime) {
5693
- return blindCast(new (blindCast(this.constructor))({
5694
- ...this.ctx,
5695
- runtime
5696
- }, this.modelName, {
5697
- tableName: this.tableName,
5698
- namespaceId: this.namespaceId,
5699
- state: this.state,
5700
- registry: this.registry,
5701
- includeRefinementMode: this.includeRefinementMode
5702
- }));
5703
- }
5704
5937
  #cloneWithRow(overrides) {
5705
5938
  return this.#createSelf({
5706
5939
  ...this.state,