Repository: directus/directus
File: api/src/database/run-ast/utils/merge-with-parent-items.ts (TypeScript)

Code before:

		parentItems.forEach((parentItem: Item) => {
			if (!parentItem[parentRelationField]) parentItem[parentRelationField] = [];

			const parentPrimaryKey = parentItem[parentPrimaryKeyField];

			if (parentsByPrimaryKey.has(parentPrimaryKey)) {
				throw new Error(
					`Duplicate parent primary key '${parentPrimaryKey}' of '${parentCollectionName}' when merging o2m nested items`,
				);
			}

			parentsByPrimaryKey.set(parentPrimaryKey, parentItem);
		});

		const toAddToAllParents: Item[] = [];

		nestedItems.forEach((nestedItem) => {
			if (nestedItem === null) return;

			if (Array.isArray(nestedItem[nestedParentKeyField])) {
				toAddToAllParents.push(nestedItem); // TODO explain this odd case
				return; // Avoids adding the nestedItem twice
			}

			const parentPrimaryKey =
				nestedItem[nestedParentKeyField]?.[parentPrimaryKeyField] ?? nestedItem[nestedParentKeyField];

			const parentItem = parentsByPrimaryKey.get(parentPrimaryKey);

			if (!parentItem) {
				throw new Error(
					`Missing parentItem '${nestedItem[nestedParentKeyField]}' of '${parentCollectionName}' when merging o2m nested items`,
				);
			}

			parentItem[parentRelationField].push(nestedItem);
		});

		for (const [index, parentItem] of parentItems.entries()) {
			if (fieldAllowed === false || (isArray(fieldAllowed) && !fieldAllowed[index])) {
				parentItem[nestedNode.fieldKey] = null;
				continue;
			}

			parentItem[parentRelationField].push(...toAddToAllParents);

			const limit = nestedNode.query.limit ?? Number(env['QUERY_LIMIT_DEFAULT']);

			if (nestedNode.query.page && nestedNode.query.page > 1) {
				parentItem[nestedNode.fieldKey] = parentItem[nestedNode.fieldKey].slice(limit * (nestedNode.query.page - 1));

Review comment (bug):
Did you observe any specific bug that warrants this conversion?

We are not doing it in the M2O case above either and I would expect the fields to have the correct type when coming back from the DB?

Code after:

			for (const parentItem of parentsByForeignKey.get(nestedPK)!) {
				parentItem[nestedNode.fieldKey] = nestedItem;
			}
		}
	} else if (nestedNode.type === 'o2m') {
		const parentCollectionName = nestedNode.relation.related_collection;
		const parentPrimaryKeyField = schema.collections[parentCollectionName!]!.primary;
		const parentRelationField = nestedNode.fieldKey;
		const nestedParentKeyField = nestedNode.relation.field;

		const parentsByPrimaryKey = new Map<PrimaryKey, Item>();

		for (const parentItem of parentItems) {
			if (!parentItem[parentRelationField]) {
				parentItem[parentRelationField] = [];
			}

			let parentPrimaryKey: PrimaryKey | null = parentItem[parentPrimaryKeyField];

			// null if the user has no access to parent PK
			if (parentPrimaryKey === null) {
				continue;
			} else {
				// ensure key access is type agnostic
				parentPrimaryKey = parentPrimaryKey.toString();
			}

			if (parentsByPrimaryKey.has(parentPrimaryKey)) {
				throw new Error(
					`Duplicate parent primary key '${parentPrimaryKey}' of '${parentCollectionName}' when merging o2m nested items`,
				);
			}

			parentsByPrimaryKey.set(parentPrimaryKey, parentItem);
		}

		const toAddToAllParents: Item[] = [];

		for (const nestedItem of nestedItems) {
			if (nestedItem === null) {
				continue;
			}

			if (Array.isArray(nestedItem[nestedParentKeyField])) {
				toAddToAllParents.push(nestedItem); // TODO explain this odd case
				continue; // Avoids adding the nestedItem twice
			}

			const parentPrimaryKey: PrimaryKey | null =
				nestedItem[nestedParentKeyField]?.[parentPrimaryKeyField] ?? nestedItem[nestedParentKeyField];