@vantreeseba/drizzle-graphql 15.1.3 → 15.1.4

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.
package/dist/index.d.cts CHANGED
@@ -1112,6 +1112,11 @@ declare const drizzleExecutorKey: unique symbol;
1112
1112
  * Returns the JS property name of the local column on the parent table and the
1113
1113
  * Column object for the foreign column on the target table, or undefined if the
1114
1114
  * relation internals are not accessible.
1115
+ *
1116
+ * Only the relation's *first* column pair is reported. A relation joined on several columns
1117
+ * (`from: [a, b], to: [x, y]`) is not described fully by it, so anything that reads rows by
1118
+ * this pair alone mixes up parents that share the first column. Read paths use
1119
+ * {@link extractRelationJoinColumnPairs}, which returns every pair.
1115
1120
  */
1116
1121
  declare const extractRelationJoinColumns: (relEntry: TableNamedRelations, parentTable: Table, targetTable: Table) => {
1117
1122
  localColPropName: string;
package/dist/index.d.ts CHANGED
@@ -1112,6 +1112,11 @@ declare const drizzleExecutorKey: unique symbol;
1112
1112
  * Returns the JS property name of the local column on the parent table and the
1113
1113
  * Column object for the foreign column on the target table, or undefined if the
1114
1114
  * relation internals are not accessible.
1115
+ *
1116
+ * Only the relation's *first* column pair is reported. A relation joined on several columns
1117
+ * (`from: [a, b], to: [x, y]`) is not described fully by it, so anything that reads rows by
1118
+ * this pair alone mixes up parents that share the first column. Read paths use
1119
+ * {@link extractRelationJoinColumnPairs}, which returns every pair.
1115
1120
  */
1116
1121
  declare const extractRelationJoinColumns: (relEntry: TableNamedRelations, parentTable: Table, targetTable: Table) => {
1117
1122
  localColPropName: string;
package/dist/index.js CHANGED
@@ -1778,6 +1778,11 @@ const warnUnresolvedJoin = (relEntry, tableName, relationName, omitted) => {
1778
1778
  * Returns the JS property name of the local column on the parent table and the
1779
1779
  * Column object for the foreign column on the target table, or undefined if the
1780
1780
  * relation internals are not accessible.
1781
+ *
1782
+ * Only the relation's *first* column pair is reported. A relation joined on several columns
1783
+ * (`from: [a, b], to: [x, y]`) is not described fully by it, so anything that reads rows by
1784
+ * this pair alone mixes up parents that share the first column. Read paths use
1785
+ * {@link extractRelationJoinColumnPairs}, which returns every pair.
1781
1786
  */
1782
1787
  const extractRelationJoinColumns = (relEntry, parentTable, targetTable) => {
1783
1788
  const rel = relEntry.relation ?? relEntry;
@@ -1796,6 +1801,48 @@ const extractRelationJoinColumns = (relEntry, parentTable, targetTable) => {
1796
1801
  };
1797
1802
  };
1798
1803
  /**
1804
+ * Every column pair the relation joins on, in declaration order — one for an ordinary relation,
1805
+ * several for one declared `from: [a, b], to: [x, y]`. A row of the target belongs to a parent
1806
+ * only when *all* pairs match, so a read path has to correlate on every one of them.
1807
+ *
1808
+ * `undefined` when the relation's columns cannot be matched to the two tables, or when its two
1809
+ * sides list a different number of columns.
1810
+ */
1811
+ const extractRelationJoinColumnPairs = (relEntry, parentTable, targetTable) => {
1812
+ const rel = relEntry.relation ?? relEntry;
1813
+ const sourceCols = relationColumns(rel, "source");
1814
+ const targetCols = relationColumns(rel, "target");
1815
+ if (!sourceCols?.length || sourceCols.length !== targetCols?.length) return;
1816
+ const parentEntries = Object.entries(getColumns(parentTable));
1817
+ const targetEntries = Object.entries(getColumns(targetTable));
1818
+ const pairs = [];
1819
+ for (let i = 0; i < sourceCols.length; i++) {
1820
+ const localCol = sourceCols[i];
1821
+ const foreignCol = targetCols[i];
1822
+ const localColPropName = parentEntries.find(([, c]) => c === localCol)?.[0];
1823
+ const foreignColPropName = targetEntries.find(([, c]) => c === foreignCol)?.[0];
1824
+ if (!localColPropName || !foreignColPropName) return;
1825
+ pairs.push({
1826
+ localColPropName,
1827
+ localCol,
1828
+ foreignColPropName,
1829
+ foreignCol
1830
+ });
1831
+ }
1832
+ return pairs;
1833
+ };
1834
+ /**
1835
+ * A string identifying one combination of join-column values, for grouping a batch's rows by
1836
+ * parent. Values are compared by their string form, as a single-column key always has been.
1837
+ */
1838
+ const joinKeyOf = (values) => values.length === 1 ? String(values[0]) : JSON.stringify(values.map((value) => String(value)));
1839
+ /**
1840
+ * The rows whose `cols` hold one of `keys`: `col IN (…)` for a single join column, and an `OR`
1841
+ * of per-parent equalities for several — `(a = 1 AND b = 1) OR (a = 1 AND b = 2)` — which
1842
+ * every dialect accepts, unlike a row-value `IN` list.
1843
+ */
1844
+ const parentKeyCondition = (cols, keys) => cols.length === 1 ? inArray(cols[0], keys.map((key) => key[0])) : or(...keys.map((key) => and(...cols.map((col, i) => eq(col, key[i])))));
1845
+ /**
1799
1846
  * The junction table and its two columns for a `.through()` (many-to-many) relation:
1800
1847
  * `sourceCol` holds the parent's key, `targetCol` the target's. `undefined` for a relation
1801
1848
  * with no junction; `null` for one whose junction cannot be used here — more than one column
@@ -1826,16 +1873,18 @@ const extractJunctionColumns = (relEntry) => {
1826
1873
  *
1827
1874
  * A reversed filter (inherited from the relation on the other side) is written against the
1828
1875
  * parent table, so it is applied as "the row's parent key belongs to a parent that passes it".
1829
- * `parentKeyCol` is the parent's join column and `groupCol` the column in the query that holds
1830
- * the parent key for each row — the target's foreign key, or the junction's source column.
1876
+ * `parentKeyCols` are the parent's join columns and `groupCols` the columns in the query that
1877
+ * hold the parent key for each row — the target's foreign key, or the junction's source
1878
+ * column — in the same order. A key of several columns is compared as a row value.
1831
1879
  */
1832
- const relationOwnCondition = (relEntry, parentTable, targetTable, parentKeyCol, groupCol) => {
1880
+ const relationOwnCondition = (relEntry, parentTable, targetTable, parentKeyCols, groupCols) => {
1833
1881
  const rel = relEntry.relation ?? relEntry;
1834
1882
  const ownWhere = relationOwnWhere(rel);
1835
1883
  if (!ownWhere) return;
1836
1884
  if (!isRelationFilterReversed(rel)) return relationsFilterToSQL(targetTable, ownWhere);
1837
1885
  const parentFilter = relationsFilterToSQL(parentTable, ownWhere);
1838
- return sql`${groupCol} in (select ${parentKeyCol} from ${parentTable} where ${parentFilter})`;
1886
+ if (groupCols.length === 1) return sql`${groupCols[0]} in (select ${parentKeyCols[0]} from ${parentTable} where ${parentFilter})`;
1887
+ return sql`(${sql.join([...groupCols], sql`, `)}) in (select ${sql.join([...parentKeyCols], sql`, `)} from ${parentTable} where ${parentFilter})`;
1839
1888
  };
1840
1889
  /**
1841
1890
  * Whether a to-one relation can back a relation orderBy hop. `.through()` (junction)
@@ -3821,8 +3870,7 @@ const relationJoinColumns = (tree, table, selectionCtx) => {
3821
3870
  const relEntry = fieldData.name.endsWith(AGGREGATE_FIELD_SUFFIX) ? relations[fieldData.name.slice(0, -9)] : relations[fieldData.name];
3822
3871
  const targetTable = relEntry ? selectionCtx.tables[relEntry.targetTableName] : void 0;
3823
3872
  if (!relEntry || !targetTable) continue;
3824
- const joinCols = extractRelationJoinColumns(relEntry, table, targetTable);
3825
- if (joinCols) needed.push(joinCols.localColPropName);
3873
+ for (const pair of extractRelationJoinColumnPairs(relEntry, table, targetTable) ?? []) needed.push(pair.localColPropName);
3826
3874
  }
3827
3875
  return needed;
3828
3876
  };
@@ -4843,13 +4891,12 @@ const identifyRows = (field, args) => {
4843
4891
  * Window functions require PostgreSQL, MySQL >= 8.0, or SQLite >= 3.25.
4844
4892
  * Returns raw rows (NOT remapped); the caller groups + remaps them.
4845
4893
  */
4846
- const batchedPaginatedRelationQuery = async (db, targetTable, foreignCol, whereCondition, orderByArg, limit, offset, pkNames, columns, orderCtx, whereArgs, junction) => {
4894
+ const batchedPaginatedRelationQuery = async (db, targetTable, foreignCol, partitionCols, whereCondition, orderByArg, limit, offset, pkNames, columns, orderCtx, whereArgs, junction) => {
4847
4895
  const cols = columns ?? getColumns(targetTable);
4848
4896
  const orderExprs = [...orderByArg ? extractOrderBy(targetTable, orderByArg, orderCtx, whereArgs) : [], ...primaryKeyOrderExprs(targetTable, pkNames)];
4849
4897
  const orderClause = orderExprs.length ? sql` order by ${sql.join(orderExprs, sql`, `)}` : sql``;
4850
4898
  const RN = "__drizzle_graphql_rn";
4851
- const partitionCol = junction ? junction.sourceCol : foreignCol;
4852
- const rowNumber = sql`row_number() over (partition by ${partitionCol}${orderClause})`.as(RN);
4899
+ const rowNumber = sql`row_number() over (partition by ${sql.join([...partitionCols], sql`, `)}${orderClause})`.as(RN);
4853
4900
  const sub = withJunction(db.select({
4854
4901
  ...cols,
4855
4902
  [RN]: rowNumber
@@ -4888,13 +4935,14 @@ const createRelationResolverFactory = (db, tables, nullOrdering, filterCtx, limi
4888
4935
  const targetTableName = relEntry.targetTableName;
4889
4936
  const targetTable = tables[targetTableName];
4890
4937
  if (!parentTable || !targetTable) return;
4891
- const joinCols = extractRelationJoinColumns(relEntry, parentTable, targetTable);
4892
- if (!joinCols) return;
4893
- const { localColPropName, foreignCol, foreignColPropName } = joinCols;
4938
+ const joinPairs = extractRelationJoinColumnPairs(relEntry, parentTable, targetTable);
4939
+ if (!joinPairs) return;
4940
+ const localColPropNames = joinPairs.map((pair) => pair.localColPropName);
4941
+ const foreignCol = joinPairs[0].foreignCol;
4894
4942
  const junction = extractJunctionColumns(relEntry);
4895
- const groupCol = junction ? junction.sourceCol : foreignCol;
4896
- const groupKey = junction ? PARENT_KEY : foreignColPropName;
4897
- const ownCondition = relationOwnCondition(relEntry, parentTable, targetTable, getColumns(parentTable)[localColPropName], groupCol);
4943
+ const groupCols = junction ? [junction.sourceCol] : joinPairs.map((pair) => pair.foreignCol);
4944
+ const groupKeys = junction ? [PARENT_KEY] : joinPairs.map((pair) => pair.foreignColPropName);
4945
+ const ownCondition = relationOwnCondition(relEntry, parentTable, targetTable, joinPairs.map((pair) => pair.localCol), groupCols);
4898
4946
  const defaultDeleted = relationDeletedDefault(policies?.softDelete, targetTableName, isOne && relEntry.relation?.optional === false);
4899
4947
  const limitPolicy = isOne ? void 0 : limits?.(targetTableName);
4900
4948
  const targetPkNames = relEntry.targetPkNames ?? [];
@@ -4923,7 +4971,7 @@ const createRelationResolverFactory = (db, tables, nullOrdering, filterCtx, limi
4923
4971
  allRelations: filterCtx?.relationMap
4924
4972
  });
4925
4973
  const targetColumns = getColumns(targetTable);
4926
- columns[foreignColPropName] = foreignCol;
4974
+ for (const pair of joinPairs) columns[pair.foreignColPropName] = pair.foreignCol;
4927
4975
  for (const [columnName] of cursorEntries ?? []) {
4928
4976
  const column = targetColumns[columnName];
4929
4977
  if (column) columns[columnName] = column;
@@ -4935,8 +4983,8 @@ const createRelationResolverFactory = (db, tables, nullOrdering, filterCtx, limi
4935
4983
  };
4936
4984
  const resolve = async (parent, args, context, info) => {
4937
4985
  if (parent[relationName] !== void 0) return parent[relationName];
4938
- const localValue = parent[localColPropName];
4939
- if (localValue == null) return isOne ? null : [];
4986
+ const localValues = localColPropNames.map((name) => parent[name]);
4987
+ if (localValues.some((value) => value == null)) return isOne ? null : [];
4940
4988
  const { where: whereArg, limit: requestedLimit, offset, after, deleted } = args ?? {};
4941
4989
  const { orderByArg, limit, distinct, cursorEntries, cursorValues, columns, loaderKey } = getOrCreateRequestValue(context, info?.fieldNodes?.[0], `relation:${tableName}::${relationName}`, () => {
4942
4990
  const orderByArg = isOne ? args?.orderBy : withDefaultOrderBy(args ?? {}, targetTableName, policies?.defaultOrderBy).orderBy;
@@ -4977,11 +5025,11 @@ const createRelationResolverFactory = (db, tables, nullOrdering, filterCtx, limi
4977
5025
  };
4978
5026
  });
4979
5027
  if (junction === null) throw drizzleError(`Relation '${tableName}.${relationName}' goes through a junction with a composite key, which can only be loaded together with its parent. Leave it to eager loading (eagerLoadRelations).`, { code: "DRIZZLE_UNSUPPORTED_RELATION" });
4980
- return getOrCreateLoader(context, loaderKey, async (parentIds) => {
5028
+ return getOrCreateLoader(context, loaderKey, async (parentKeys) => {
4981
5029
  const executor = resolveExecutor(db, context);
4982
- const uniqueIds = [...new Set(parentIds)];
5030
+ const uniqueKeys = [...new Map(parentKeys.map((key) => [joinKeyOf(key), key])).values()];
4983
5031
  const scope = resolveScope(policies, context, filterCtx);
4984
- let whereCondition = withScope(scope, targetTableName, targetTable, and(inArray(groupCol, uniqueIds), ownCondition, whereArg ? extractFilters(targetTable, targetTableName, whereArg, relationFilterCtx(filterCtx, targetTableName, scope)) : void 0, cursorValues ? buildCursorCondition(targetTable, cursorEntries, cursorValues, nullOrdering) : void 0), deleted ?? defaultDeleted);
5032
+ let whereCondition = withScope(scope, targetTableName, targetTable, and(parentKeyCondition(groupCols, uniqueKeys), ownCondition, whereArg ? extractFilters(targetTable, targetTableName, whereArg, relationFilterCtx(filterCtx, targetTableName, scope)) : void 0, cursorValues ? buildCursorCondition(targetTable, cursorEntries, cursorValues, nullOrdering) : void 0), deleted ?? defaultDeleted);
4985
5033
  if (distinct) {
4986
5034
  const keys = await selectDistinctKeys({
4987
5035
  db: executor,
@@ -4991,22 +5039,22 @@ const createRelationResolverFactory = (db, tables, nullOrdering, filterCtx, limi
4991
5039
  pkNames: targetPkNames,
4992
5040
  where: whereCondition,
4993
5041
  orderBy: orderByArg,
4994
- partitionBy: [groupCol],
5042
+ partitionBy: groupCols,
4995
5043
  junction: junction ? {
4996
5044
  table: junction.table,
4997
5045
  on: eq(junction.targetCol, foreignCol),
4998
- parentKey: groupCol
5046
+ parentKey: junction.sourceCol
4999
5047
  } : void 0
5000
5048
  });
5001
- if (!keys.length) return parentIds.map(() => isOne ? null : []);
5002
- whereCondition = and(whereCondition, junction ? or(...keys.map((key) => and(eq(groupCol, key[DISTINCT_PARENT]), primaryKeyRestriction(targetTable, targetPkNames, [key])))) : primaryKeyRestriction(targetTable, targetPkNames, keys));
5049
+ if (!keys.length) return parentKeys.map(() => isOne ? null : []);
5050
+ whereCondition = and(whereCondition, junction ? or(...keys.map((key) => and(eq(junction.sourceCol, key[DISTINCT_PARENT]), primaryKeyRestriction(targetTable, targetPkNames, [key])))) : primaryKeyRestriction(targetTable, targetPkNames, keys));
5003
5051
  }
5004
5052
  const selection = junction ? {
5005
5053
  ...columns ?? getColumns(targetTable),
5006
- [PARENT_KEY]: groupCol
5054
+ [PARENT_KEY]: junction.sourceCol
5007
5055
  } : columns;
5008
5056
  let rows;
5009
- if (limit != null || offset != null) rows = await batchedPaginatedRelationQuery(executor, targetTable, foreignCol, whereCondition, orderByArg, limit ?? null, offset ?? null, targetPkNames, selection, relationFilterCtx(filterCtx, targetTableName, scope), whereArg, junction);
5057
+ if (limit != null || offset != null) rows = await batchedPaginatedRelationQuery(executor, targetTable, foreignCol, groupCols, whereCondition, orderByArg, limit ?? null, offset ?? null, targetPkNames, selection, relationFilterCtx(filterCtx, targetTableName, scope), whereArg, junction);
5010
5058
  else {
5011
5059
  let q = withJunction((selection ? executor.select(selection) : executor.select()).from(targetTable), junction, foreignCol).where(whereCondition);
5012
5060
  const orderExprs = cursorEntries ? cursorOrderExprs(targetTable, cursorEntries) : orderByArg ? extractOrderBy(targetTable, orderByArg, relationFilterCtx(filterCtx, targetTableName, scope), whereArg) : [];
@@ -5015,20 +5063,20 @@ const createRelationResolverFactory = (db, tables, nullOrdering, filterCtx, limi
5015
5063
  }
5016
5064
  if (cursorEntries) attachRowCursors(rows, cursorEntries);
5017
5065
  const keyOf = (row) => {
5018
- const key = String(row[groupKey]);
5066
+ const key = joinKeyOf(groupKeys.map((name) => row[name]));
5019
5067
  if (junction) delete row[PARENT_KEY];
5020
5068
  return key;
5021
5069
  };
5022
5070
  if (isOne) {
5023
5071
  const byKey = new Map(rows.map((row) => [keyOf(row), row]));
5024
5072
  remapToGraphQLArrayOutput(rows, targetTableName, targetTable);
5025
- return parentIds.map((id) => byKey.get(String(id)) ?? null);
5073
+ return parentKeys.map((key) => byKey.get(joinKeyOf(key)) ?? null);
5026
5074
  }
5027
- const grouped = new Map(uniqueIds.map((id) => [String(id), []]));
5075
+ const grouped = new Map(uniqueKeys.map((key) => [joinKeyOf(key), []]));
5028
5076
  for (const row of rows) grouped.get(keyOf(row))?.push(row);
5029
5077
  remapToGraphQLArrayOutput(rows, targetTableName, targetTable);
5030
- return parentIds.map((id) => grouped.get(String(id)) ?? []);
5031
- }).load(localValue);
5078
+ return parentKeys.map((key) => grouped.get(joinKeyOf(key)) ?? []);
5079
+ }).load(localValues);
5032
5080
  };
5033
5081
  return async (parent, args, context, info) => {
5034
5082
  try {
@@ -6104,8 +6152,8 @@ const createRelationAggregateFactory = (db, tables, cacheCtx, typeNameMapper, fi
6104
6152
  const targetTableName = relEntry.targetTableName;
6105
6153
  const targetTable = tables[targetTableName];
6106
6154
  if (!parentTable || !targetTable) return;
6107
- const joinCols = extractRelationJoinColumns(relEntry, parentTable, targetTable);
6108
- if (!joinCols) {
6155
+ const joinPairs = extractRelationJoinColumnPairs(relEntry, parentTable, targetTable);
6156
+ if (!joinPairs) {
6109
6157
  const key = `${tableName}.${relationName}`;
6110
6158
  if (!warned.has(key)) {
6111
6159
  warned.add(key);
@@ -6113,11 +6161,13 @@ const createRelationAggregateFactory = (db, tables, cacheCtx, typeNameMapper, fi
6113
6161
  }
6114
6162
  return;
6115
6163
  }
6116
- const { localColPropName, foreignCol } = joinCols;
6164
+ const localColPropNames = joinPairs.map((pair) => pair.localColPropName);
6165
+ const foreignCol = joinPairs[0].foreignCol;
6117
6166
  const junction = extractJunctionColumns(relEntry);
6118
6167
  if (junction === null) return;
6119
- const groupCol = junction ? junction.sourceCol : foreignCol;
6120
- const ownCondition = relationOwnCondition(relEntry, parentTable, targetTable, getColumns(parentTable)[localColPropName], groupCol);
6168
+ const groupCols = junction ? [junction.sourceCol] : joinPairs.map((pair) => pair.foreignCol);
6169
+ const groupAliases = groupCols.map((_, i) => `${GROUP_KEY}${i}`);
6170
+ const ownCondition = relationOwnCondition(relEntry, parentTable, targetTable, joinPairs.map((pair) => pair.localCol), groupCols);
6121
6171
  const defaultDeleted = relationDeletedDefault(policies?.softDelete, targetTableName, false);
6122
6172
  const targetTypeName = resolveTypeName(targetTableName, typeNameMapper);
6123
6173
  const type = generateAggregateTypes(targetTable, targetTableName, targetTypeName, cacheCtx);
@@ -6141,24 +6191,25 @@ const createRelationAggregateFactory = (db, tables, cacheCtx, typeNameMapper, fi
6141
6191
  };
6142
6192
  });
6143
6193
  if (!Object.keys(request.selection).length) return {};
6144
- const localValue = parent[localColPropName];
6145
- if (localValue == null) return assembleAggregateRow({}, request, target);
6194
+ const localValues = localColPropNames.map((name) => parent[name]);
6195
+ if (localValues.some((value) => value == null)) return assembleAggregateRow({}, request, target);
6146
6196
  const whereArg = args?.where;
6147
6197
  const deleted = args?.deleted;
6148
- const loader = getOrCreateLoader(context, loaderKey, async (parentIds) => {
6198
+ const loader = getOrCreateLoader(context, loaderKey, async (parentKeys) => {
6149
6199
  const executor = resolveExecutor(db, context);
6150
- const uniqueIds = [...new Set(parentIds)];
6200
+ const uniqueKeys = [...new Map(parentKeys.map((key) => [joinKeyOf(key), key])).values()];
6151
6201
  const scope = resolveScope(policies, context, filterCtx);
6152
- const whereCondition = withScope(scope, targetTableName, targetTable, and(inArray(groupCol, uniqueIds), ownCondition, whereArg ? extractFilters(targetTable, targetTableName, whereArg, relationFilterCtx(filterCtx, targetTableName, scope)) : void 0), deleted ?? defaultDeleted);
6202
+ const whereCondition = withScope(scope, targetTableName, targetTable, and(parentKeyCondition(groupCols, uniqueKeys), ownCondition, whereArg ? extractFilters(targetTable, targetTableName, whereArg, relationFilterCtx(filterCtx, targetTableName, scope)) : void 0), deleted ?? defaultDeleted);
6203
+ const groupSelection = Object.fromEntries(groupAliases.map((alias, i) => [alias, groupCols[i]]));
6153
6204
  const selected = executor.select({
6154
- [GROUP_KEY]: groupCol,
6205
+ ...groupSelection,
6155
6206
  ...request.selection
6156
6207
  }).from(targetTable);
6157
- const rows = await (junction ? selected.innerJoin(junction.table, eq(junction.targetCol, foreignCol)) : selected).where(whereCondition).groupBy(groupCol);
6158
- const byKey = new Map(rows.map((row) => [row[GROUP_KEY], row]));
6159
- return parentIds.map((id) => byKey.get(id) ?? {});
6208
+ const rows = await (junction ? selected.innerJoin(junction.table, eq(junction.targetCol, foreignCol)) : selected).where(whereCondition).groupBy(...groupCols);
6209
+ const byKey = new Map(rows.map((row) => [joinKeyOf(groupAliases.map((alias) => row[alias])), row]));
6210
+ return parentKeys.map((key) => byKey.get(joinKeyOf(key)) ?? {});
6160
6211
  });
6161
- return assembleAggregateRow(await loader.load(localValue), request, target);
6212
+ return assembleAggregateRow(await loader.load(localValues), request, target);
6162
6213
  } catch (e) {
6163
6214
  throw withErrorContext(toGraphQLError(e), errorCtx);
6164
6215
  }