fix(db-postgres): handle select query on select fields (#9607)
Fixes https://github.com/payloadcms/payload/issues/9606 With Postgres / SQLite, select fields (non `hasMany: true`) weren't properly handled in the `traverseFields.ts` function for `select` query.
This commit is contained in:
@@ -540,16 +540,16 @@ export const traverseFields = ({
|
||||
}
|
||||
|
||||
case 'select': {
|
||||
if (field.hasMany) {
|
||||
if (select) {
|
||||
if (
|
||||
(selectMode === 'include' && !select[field.name]) ||
|
||||
(selectMode === 'exclude' && select[field.name] === false)
|
||||
) {
|
||||
break
|
||||
}
|
||||
if (select && !selectAllOnCurrentLevel) {
|
||||
if (
|
||||
(selectMode === 'include' && !select[field.name]) ||
|
||||
(selectMode === 'exclude' && select[field.name] === false)
|
||||
) {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if (field.hasMany) {
|
||||
const withSelect: Result = {
|
||||
columns: {
|
||||
id: false,
|
||||
@@ -560,6 +560,17 @@ export const traverseFields = ({
|
||||
}
|
||||
|
||||
currentArgs.with[`${path}${field.name}`] = withSelect
|
||||
break
|
||||
}
|
||||
|
||||
if (select || selectAllOnCurrentLevel) {
|
||||
const fieldPath = `${path}${field.name}`
|
||||
|
||||
if ((field.localized || withinLocalizedField) && _locales) {
|
||||
_locales.columns[fieldPath] = true
|
||||
} else if (adapter.tables[currentTableName]?.[fieldPath]) {
|
||||
currentArgs.columns[fieldPath] = true
|
||||
}
|
||||
}
|
||||
|
||||
break
|
||||
|
||||
@@ -16,6 +16,17 @@ export const LocalizedPostsCollection: CollectionConfig = {
|
||||
localized: true,
|
||||
type: 'number',
|
||||
},
|
||||
{
|
||||
name: 'select',
|
||||
type: 'select',
|
||||
options: ['a', 'b'],
|
||||
},
|
||||
{
|
||||
name: 'selectMany',
|
||||
type: 'select',
|
||||
options: ['a', 'b'],
|
||||
hasMany: true,
|
||||
},
|
||||
{
|
||||
name: 'group',
|
||||
localized: true,
|
||||
|
||||
@@ -14,6 +14,17 @@ export const PostsCollection: CollectionConfig = {
|
||||
name: 'number',
|
||||
type: 'number',
|
||||
},
|
||||
{
|
||||
name: 'select',
|
||||
type: 'select',
|
||||
options: ['a', 'b'],
|
||||
},
|
||||
{
|
||||
name: 'selectMany',
|
||||
type: 'select',
|
||||
options: ['a', 'b'],
|
||||
hasMany: true,
|
||||
},
|
||||
{
|
||||
name: 'group',
|
||||
type: 'group',
|
||||
|
||||
@@ -86,6 +86,36 @@ describe('Select', () => {
|
||||
})
|
||||
})
|
||||
|
||||
it('should select only select', async () => {
|
||||
const res = await payload.findByID({
|
||||
collection: 'posts',
|
||||
id: postId,
|
||||
select: {
|
||||
select: true,
|
||||
},
|
||||
})
|
||||
|
||||
expect(res).toStrictEqual({
|
||||
id: postId,
|
||||
select: post.select,
|
||||
})
|
||||
})
|
||||
|
||||
it('should select only hasMany select', async () => {
|
||||
const res = await payload.findByID({
|
||||
collection: 'posts',
|
||||
id: postId,
|
||||
select: {
|
||||
selectMany: true,
|
||||
},
|
||||
})
|
||||
|
||||
expect(res).toStrictEqual({
|
||||
id: postId,
|
||||
selectMany: post.selectMany,
|
||||
})
|
||||
})
|
||||
|
||||
it('should select number and text', async () => {
|
||||
const res = await payload.findByID({
|
||||
collection: 'posts',
|
||||
@@ -367,6 +397,38 @@ describe('Select', () => {
|
||||
expect(res).toStrictEqual(expected)
|
||||
})
|
||||
|
||||
it('should exclude select', async () => {
|
||||
const res = await payload.findByID({
|
||||
collection: 'posts',
|
||||
id: postId,
|
||||
select: {
|
||||
select: false,
|
||||
},
|
||||
})
|
||||
|
||||
const expected = { ...post }
|
||||
|
||||
delete expected['select']
|
||||
|
||||
expect(res).toStrictEqual(expected)
|
||||
})
|
||||
|
||||
it('should exclude hasMany select', async () => {
|
||||
const res = await payload.findByID({
|
||||
collection: 'posts',
|
||||
id: postId,
|
||||
select: {
|
||||
selectMany: false,
|
||||
},
|
||||
})
|
||||
|
||||
const expected = { ...post }
|
||||
|
||||
delete expected['selectMany']
|
||||
|
||||
expect(res).toStrictEqual(expected)
|
||||
})
|
||||
|
||||
it('should exclude number and text', async () => {
|
||||
const res = await payload.findByID({
|
||||
collection: 'posts',
|
||||
@@ -573,6 +635,36 @@ describe('Select', () => {
|
||||
})
|
||||
})
|
||||
|
||||
it('should select only select', async () => {
|
||||
const res = await payload.findByID({
|
||||
collection: 'localized-posts',
|
||||
id: postId,
|
||||
select: {
|
||||
select: true,
|
||||
},
|
||||
})
|
||||
|
||||
expect(res).toStrictEqual({
|
||||
id: postId,
|
||||
select: post.select,
|
||||
})
|
||||
})
|
||||
|
||||
it('should select only hasMany select', async () => {
|
||||
const res = await payload.findByID({
|
||||
collection: 'localized-posts',
|
||||
id: postId,
|
||||
select: {
|
||||
selectMany: true,
|
||||
},
|
||||
})
|
||||
|
||||
expect(res).toStrictEqual({
|
||||
id: postId,
|
||||
selectMany: post.selectMany,
|
||||
})
|
||||
})
|
||||
|
||||
it('should select number and text', async () => {
|
||||
const res = await payload.findByID({
|
||||
collection: 'localized-posts',
|
||||
@@ -877,6 +969,38 @@ describe('Select', () => {
|
||||
expect(res).toStrictEqual(expected)
|
||||
})
|
||||
|
||||
it('should exclude select', async () => {
|
||||
const res = await payload.findByID({
|
||||
collection: 'localized-posts',
|
||||
id: postId,
|
||||
select: {
|
||||
select: false,
|
||||
},
|
||||
})
|
||||
|
||||
const expected = { ...post }
|
||||
|
||||
delete expected['select']
|
||||
|
||||
expect(res).toStrictEqual(expected)
|
||||
})
|
||||
|
||||
it('should exclude hasMany select', async () => {
|
||||
const res = await payload.findByID({
|
||||
collection: 'localized-posts',
|
||||
id: postId,
|
||||
select: {
|
||||
selectMany: false,
|
||||
},
|
||||
})
|
||||
|
||||
const expected = { ...post }
|
||||
|
||||
delete expected['selectMany']
|
||||
|
||||
expect(res).toStrictEqual(expected)
|
||||
})
|
||||
|
||||
it('should exclude number and text', async () => {
|
||||
const res = await payload.findByID({
|
||||
collection: 'localized-posts',
|
||||
@@ -1963,6 +2087,8 @@ function createPost() {
|
||||
data: {
|
||||
number: 1,
|
||||
text: 'text',
|
||||
select: 'a',
|
||||
selectMany: ['a'],
|
||||
group: {
|
||||
number: 1,
|
||||
text: 'text',
|
||||
@@ -2002,6 +2128,8 @@ function createLocalizedPost() {
|
||||
data: {
|
||||
number: 1,
|
||||
text: 'text',
|
||||
select: 'a',
|
||||
selectMany: ['a'],
|
||||
group: {
|
||||
number: 1,
|
||||
text: 'text',
|
||||
|
||||
@@ -79,6 +79,8 @@ export interface Post {
|
||||
id: string;
|
||||
text?: string | null;
|
||||
number?: number | null;
|
||||
select?: ('a' | 'b') | null;
|
||||
selectMany?: ('a' | 'b')[] | null;
|
||||
group?: {
|
||||
text?: string | null;
|
||||
number?: number | null;
|
||||
@@ -125,6 +127,8 @@ export interface LocalizedPost {
|
||||
id: string;
|
||||
text?: string | null;
|
||||
number?: number | null;
|
||||
select?: ('a' | 'b') | null;
|
||||
selectMany?: ('a' | 'b')[] | null;
|
||||
group?: {
|
||||
text?: string | null;
|
||||
number?: number | null;
|
||||
@@ -424,6 +428,8 @@ export interface PayloadMigration {
|
||||
export interface PostsSelect<T extends boolean = true> {
|
||||
text?: T;
|
||||
number?: T;
|
||||
select?: T;
|
||||
selectMany?: T;
|
||||
group?:
|
||||
| T
|
||||
| {
|
||||
@@ -475,6 +481,8 @@ export interface PostsSelect<T extends boolean = true> {
|
||||
export interface LocalizedPostsSelect<T extends boolean = true> {
|
||||
text?: T;
|
||||
number?: T;
|
||||
select?: T;
|
||||
selectMany?: T;
|
||||
group?:
|
||||
| T
|
||||
| {
|
||||
|
||||
Reference in New Issue
Block a user