fix(db-postgres): joins with versions and hasMany relationship (#9370)
Fixes errors when having joins with versions +drafts on `hasMany: true` relationships. Removes `joinQuery` overhead if we don't need it for the current operation. Right now, in all adapters we support joins only for `find`, `findOne`, and `queryDrafts`. Fixes https://github.com/payloadcms/payload/issues/9369
This commit is contained in:
@@ -19,6 +19,7 @@ export const deleteMany: DeleteMany = async function deleteMany(
|
|||||||
const result = await findMany({
|
const result = await findMany({
|
||||||
adapter: this,
|
adapter: this,
|
||||||
fields: collectionConfig.fields,
|
fields: collectionConfig.fields,
|
||||||
|
joins: false,
|
||||||
limit: 0,
|
limit: 0,
|
||||||
locale: req.locale,
|
locale: req.locale,
|
||||||
page: 1,
|
page: 1,
|
||||||
|
|||||||
@@ -12,13 +12,7 @@ import { transform } from './transform/read/index.js'
|
|||||||
|
|
||||||
export const deleteOne: DeleteOne = async function deleteOne(
|
export const deleteOne: DeleteOne = async function deleteOne(
|
||||||
this: DrizzleAdapter,
|
this: DrizzleAdapter,
|
||||||
{
|
{ collection: collectionSlug, req = {} as PayloadRequest, select, where: whereArg },
|
||||||
collection: collectionSlug,
|
|
||||||
joins: joinQuery,
|
|
||||||
req = {} as PayloadRequest,
|
|
||||||
select,
|
|
||||||
where: whereArg,
|
|
||||||
},
|
|
||||||
) {
|
) {
|
||||||
const db = this.sessions[await req?.transactionID]?.db || this.drizzle
|
const db = this.sessions[await req?.transactionID]?.db || this.drizzle
|
||||||
const collection = this.payload.collections[collectionSlug].config
|
const collection = this.payload.collections[collectionSlug].config
|
||||||
@@ -54,7 +48,7 @@ export const deleteOne: DeleteOne = async function deleteOne(
|
|||||||
adapter: this,
|
adapter: this,
|
||||||
depth: 0,
|
depth: 0,
|
||||||
fields: collection.fields,
|
fields: collection.fields,
|
||||||
joinQuery,
|
joinQuery: false,
|
||||||
select,
|
select,
|
||||||
tableName,
|
tableName,
|
||||||
})
|
})
|
||||||
@@ -69,7 +63,7 @@ export const deleteOne: DeleteOne = async function deleteOne(
|
|||||||
config: this.payload.config,
|
config: this.payload.config,
|
||||||
data: docToDelete,
|
data: docToDelete,
|
||||||
fields: collection.fields,
|
fields: collection.fields,
|
||||||
joinQuery,
|
joinQuery: false,
|
||||||
})
|
})
|
||||||
|
|
||||||
await this.deleteWhere({
|
await this.deleteWhere({
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ export const deleteVersions: DeleteVersions = async function deleteVersion(
|
|||||||
const { docs } = await findMany({
|
const { docs } = await findMany({
|
||||||
adapter: this,
|
adapter: this,
|
||||||
fields,
|
fields,
|
||||||
|
joins: false,
|
||||||
limit: 0,
|
limit: 0,
|
||||||
locale,
|
locale,
|
||||||
page: 1,
|
page: 1,
|
||||||
|
|||||||
@@ -330,7 +330,6 @@ export const traverseFields = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
case 'group':
|
case 'group':
|
||||||
|
|
||||||
case 'tab': {
|
case 'tab': {
|
||||||
const fieldSelect = select?.[field.name]
|
const fieldSelect = select?.[field.name]
|
||||||
|
|
||||||
@@ -364,6 +363,7 @@ export const traverseFields = ({
|
|||||||
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'join': {
|
case 'join': {
|
||||||
// when `joinsQuery` is false, do not join
|
// when `joinsQuery` is false, do not join
|
||||||
if (joinQuery === false) {
|
if (joinQuery === false) {
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ export const findVersions: FindVersions = async function findVersions(
|
|||||||
return findMany({
|
return findMany({
|
||||||
adapter: this,
|
adapter: this,
|
||||||
fields,
|
fields,
|
||||||
|
joins: false,
|
||||||
limit,
|
limit,
|
||||||
locale,
|
locale,
|
||||||
page,
|
page,
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ export async function updateVersion<T extends TypeWithID>(
|
|||||||
data: versionData,
|
data: versionData,
|
||||||
db,
|
db,
|
||||||
fields,
|
fields,
|
||||||
|
joinQuery: false,
|
||||||
operation: 'update',
|
operation: 'update',
|
||||||
req,
|
req,
|
||||||
select,
|
select,
|
||||||
|
|||||||
@@ -411,6 +411,8 @@ export const upsertRow = async <T extends Record<string, unknown> | TypeWithID>(
|
|||||||
// RETRIEVE NEWLY UPDATED ROW
|
// RETRIEVE NEWLY UPDATED ROW
|
||||||
// //////////////////////////////////
|
// //////////////////////////////////
|
||||||
|
|
||||||
|
joinQuery = operation === 'create' ? false : joinQuery
|
||||||
|
|
||||||
const findManyArgs = buildFindManyArgs({
|
const findManyArgs = buildFindManyArgs({
|
||||||
adapter,
|
adapter,
|
||||||
depth: 0,
|
depth: 0,
|
||||||
|
|||||||
@@ -13,6 +13,12 @@ export const CategoriesVersions: CollectionConfig = {
|
|||||||
collection: versionsSlug,
|
collection: versionsSlug,
|
||||||
on: 'categoryVersion',
|
on: 'categoryVersion',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'relatedVersionsMany',
|
||||||
|
type: 'join',
|
||||||
|
collection: versionsSlug,
|
||||||
|
on: 'categoryVersions',
|
||||||
|
},
|
||||||
],
|
],
|
||||||
versions: {
|
versions: {
|
||||||
drafts: true,
|
drafts: true,
|
||||||
|
|||||||
@@ -15,6 +15,12 @@ export const Versions: CollectionConfig = {
|
|||||||
relationTo: 'categories-versions',
|
relationTo: 'categories-versions',
|
||||||
type: 'relationship',
|
type: 'relationship',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'categoryVersions',
|
||||||
|
relationTo: 'categories-versions',
|
||||||
|
type: 'relationship',
|
||||||
|
hasMany: true,
|
||||||
|
},
|
||||||
],
|
],
|
||||||
versions: {
|
versions: {
|
||||||
drafts: true,
|
drafts: true,
|
||||||
|
|||||||
@@ -480,7 +480,20 @@ describe('Joins Field', () => {
|
|||||||
expect(res.docs[0].relatedVersions.docs[0].id).toBe(version.id)
|
expect(res.docs[0].relatedVersions.docs[0].id).toBe(version.id)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should populate joins when versions on both sides draft true payload.db.queryDrafts', async () => {
|
it('should populate joins with hasMany relationships when versions on both sides draft false', async () => {
|
||||||
|
const category = await payload.create({ collection: 'categories-versions', data: {} })
|
||||||
|
|
||||||
|
const version = await payload.create({
|
||||||
|
collection: 'versions',
|
||||||
|
data: { categoryVersions: [category.id] },
|
||||||
|
})
|
||||||
|
|
||||||
|
const res = await payload.find({ collection: 'categories-versions', draft: false })
|
||||||
|
|
||||||
|
expect(res.docs[0].relatedVersionsMany.docs[0].id).toBe(version.id)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should populate joins with hasMany relationships when versions on both sides draft true payload.db.queryDrafts', async () => {
|
||||||
const category = await payload.create({ collection: 'categories-versions', data: {} })
|
const category = await payload.create({ collection: 'categories-versions', data: {} })
|
||||||
|
|
||||||
const version = await payload.create({
|
const version = await payload.create({
|
||||||
@@ -495,6 +508,22 @@ describe('Joins Field', () => {
|
|||||||
|
|
||||||
expect(res.docs[0].relatedVersions.docs[0].id).toBe(version.id)
|
expect(res.docs[0].relatedVersions.docs[0].id).toBe(version.id)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('should populate joins when versions on both sides draft true payload.db.queryDrafts', async () => {
|
||||||
|
const category = await payload.create({ collection: 'categories-versions', data: {} })
|
||||||
|
|
||||||
|
const version = await payload.create({
|
||||||
|
collection: 'versions',
|
||||||
|
data: { categoryVersions: [category.id] },
|
||||||
|
})
|
||||||
|
|
||||||
|
const res = await payload.find({
|
||||||
|
collection: 'categories-versions',
|
||||||
|
draft: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(res.docs[0].relatedVersionsMany.docs[0].id).toBe(version.id)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('REST', () => {
|
describe('REST', () => {
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ export interface Config {
|
|||||||
};
|
};
|
||||||
'categories-versions': {
|
'categories-versions': {
|
||||||
relatedVersions: 'versions';
|
relatedVersions: 'versions';
|
||||||
|
relatedVersionsMany: 'versions';
|
||||||
};
|
};
|
||||||
'localized-categories': {
|
'localized-categories': {
|
||||||
relatedPosts: 'localized-posts';
|
relatedPosts: 'localized-posts';
|
||||||
@@ -197,6 +198,7 @@ export interface Version {
|
|||||||
id: string;
|
id: string;
|
||||||
category?: (string | null) | Category;
|
category?: (string | null) | Category;
|
||||||
categoryVersion?: (string | null) | CategoriesVersion;
|
categoryVersion?: (string | null) | CategoriesVersion;
|
||||||
|
categoryVersions?: (string | CategoriesVersion)[] | null;
|
||||||
updatedAt: string;
|
updatedAt: string;
|
||||||
createdAt: string;
|
createdAt: string;
|
||||||
_status?: ('draft' | 'published') | null;
|
_status?: ('draft' | 'published') | null;
|
||||||
@@ -211,6 +213,10 @@ export interface CategoriesVersion {
|
|||||||
docs?: (string | Version)[] | null;
|
docs?: (string | Version)[] | null;
|
||||||
hasNextPage?: boolean | null;
|
hasNextPage?: boolean | null;
|
||||||
} | null;
|
} | null;
|
||||||
|
relatedVersionsMany?: {
|
||||||
|
docs?: (string | Version)[] | null;
|
||||||
|
hasNextPage?: boolean | null;
|
||||||
|
} | null;
|
||||||
updatedAt: string;
|
updatedAt: string;
|
||||||
createdAt: string;
|
createdAt: string;
|
||||||
_status?: ('draft' | 'published') | null;
|
_status?: ('draft' | 'published') | null;
|
||||||
@@ -442,6 +448,7 @@ export interface UploadsSelect<T extends boolean = true> {
|
|||||||
export interface VersionsSelect<T extends boolean = true> {
|
export interface VersionsSelect<T extends boolean = true> {
|
||||||
category?: T;
|
category?: T;
|
||||||
categoryVersion?: T;
|
categoryVersion?: T;
|
||||||
|
categoryVersions?: T;
|
||||||
updatedAt?: T;
|
updatedAt?: T;
|
||||||
createdAt?: T;
|
createdAt?: T;
|
||||||
_status?: T;
|
_status?: T;
|
||||||
@@ -452,6 +459,7 @@ export interface VersionsSelect<T extends boolean = true> {
|
|||||||
*/
|
*/
|
||||||
export interface CategoriesVersionsSelect<T extends boolean = true> {
|
export interface CategoriesVersionsSelect<T extends boolean = true> {
|
||||||
relatedVersions?: T;
|
relatedVersions?: T;
|
||||||
|
relatedVersionsMany?: T;
|
||||||
updatedAt?: T;
|
updatedAt?: T;
|
||||||
createdAt?: T;
|
createdAt?: T;
|
||||||
_status?: T;
|
_status?: T;
|
||||||
|
|||||||
Reference in New Issue
Block a user