Skip to content

Commit 90bca15

Browse files
r1tsuuDanRibbens
andauthored
fix(drizzle): enforce uniqueness on index names (#8754)
Fixes #8752 Previously, trying to define a config like this: ```ts { type: 'text', name: 'someText', index: true, }, { type: 'array', name: 'some', index: true, fields: [ { type: 'text', name: 'text', index: true, }, ], } ``` Lead to the error: ``` Warning We've found duplicated index name across public schema. Please rename your index in either the demonstration table or the table with the duplicated index name ``` Now, if we encounter duplicates, we increment the name like this: `collection_some_text_idx` `collection_some_text_1_idx` --------- Co-authored-by: Dan Ribbens <dan.ribbens@gmail.com>
1 parent 872b205 commit 90bca15

File tree

14 files changed

+102
-31
lines changed

14 files changed

+102
-31
lines changed

packages/db-postgres/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ export function postgresAdapter(args: Args): DatabaseAdapterObj<PostgresAdapter>
136136
findGlobalVersions,
137137
findOne,
138138
findVersions,
139+
indexes: new Set<string>(),
139140
init,
140141
insert,
141142
migrate,

packages/db-sqlite/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ export function sqliteAdapter(args: Args): DatabaseAdapterObj<SQLiteAdapter> {
133133
findGlobalVersions,
134134
findOne,
135135
findVersions,
136+
indexes: new Set<string>(),
136137
init,
137138
insert,
138139
migrate,

packages/db-sqlite/src/schema/build.ts

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import type { DrizzleAdapter } from '@payloadcms/drizzle/types'
12
import type { Relation } from 'drizzle-orm'
23
import type {
34
AnySQLiteColumn,
@@ -9,7 +10,7 @@ import type {
910
} from 'drizzle-orm/sqlite-core'
1011
import type { Field, SanitizedJoins } from 'payload'
1112

12-
import { createTableName } from '@payloadcms/drizzle'
13+
import { buildIndexName, createTableName } from '@payloadcms/drizzle'
1314
import { relations, sql } from 'drizzle-orm'
1415
import {
1516
foreignKey,
@@ -416,21 +417,25 @@ export const buildTable = ({
416417
foreignColumns: [adapter.tables[formattedRelationTo].id],
417418
}).onDelete('cascade')
418419

419-
const indexName = [colName]
420+
const indexColumns = [colName]
420421

421422
const unique = !disableUnique && uniqueRelationships.has(relationTo)
422423

423424
if (unique) {
424-
indexName.push('path')
425+
indexColumns.push('path')
425426
}
426427
if (hasLocalizedRelationshipField) {
427-
indexName.push('locale')
428+
indexColumns.push('locale')
428429
}
429430

430-
relationExtraConfig[`${relationTo}IdIdx`] = createIndex({
431-
name: indexName,
432-
columnName: `${formattedRelationTo}_id`,
433-
tableName: relationshipsTableName,
431+
const indexName = buildIndexName({
432+
name: `${relationshipsTableName}_${formattedRelationTo}_id`,
433+
adapter: adapter as unknown as DrizzleAdapter,
434+
})
435+
436+
relationExtraConfig[indexName] = createIndex({
437+
name: indexColumns,
438+
indexName,
434439
unique,
435440
})
436441
})

packages/db-sqlite/src/schema/createIndex.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,12 @@ import type { AnySQLiteColumn } from 'drizzle-orm/sqlite-core'
33
import { index, uniqueIndex } from 'drizzle-orm/sqlite-core'
44

55
type CreateIndexArgs = {
6-
columnName: string
6+
indexName: string
77
name: string | string[]
8-
tableName: string
98
unique?: boolean
109
}
1110

12-
export const createIndex = ({ name, columnName, tableName, unique }: CreateIndexArgs) => {
11+
export const createIndex = ({ name, indexName, unique }: CreateIndexArgs) => {
1312
return (table: { [x: string]: AnySQLiteColumn }) => {
1413
let columns
1514
if (Array.isArray(name)) {
@@ -21,8 +20,8 @@ export const createIndex = ({ name, columnName, tableName, unique }: CreateIndex
2120
columns = [table[name]]
2221
}
2322
if (unique) {
24-
return uniqueIndex(`${tableName}_${columnName}_idx`).on(columns[0], ...columns.slice(1))
23+
return uniqueIndex(indexName).on(columns[0], ...columns.slice(1))
2524
}
26-
return index(`${tableName}_${columnName}_idx`).on(columns[0], ...columns.slice(1))
25+
return index(indexName).on(columns[0], ...columns.slice(1))
2726
}
2827
}

packages/db-sqlite/src/schema/traverseFields.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1+
import type { DrizzleAdapter } from '@payloadcms/drizzle/types'
12
import type { Relation } from 'drizzle-orm'
23
import type { IndexBuilder, SQLiteColumnBuilder } from 'drizzle-orm/sqlite-core'
34
import type { Field, SanitizedJoins, TabAsField } from 'payload'
45

56
import {
7+
buildIndexName,
68
createTableName,
79
hasLocalesTable,
810
validateExistingBlockIsIdentical,
@@ -164,10 +166,15 @@ export const traverseFields = ({
164166
}
165167
adapter.fieldConstraints[rootTableName][`${columnName}_idx`] = constraintValue
166168
}
167-
targetIndexes[`${newTableName}_${field.name}Idx`] = createIndex({
169+
170+
const indexName = buildIndexName({
171+
name: `${newTableName}_${columnName}`,
172+
adapter: adapter as unknown as DrizzleAdapter,
173+
})
174+
175+
targetIndexes[indexName] = createIndex({
168176
name: field.localized ? [fieldName, '_locale'] : fieldName,
169-
columnName,
170-
tableName: newTableName,
177+
indexName,
171178
unique,
172179
})
173180
}

packages/db-vercel-postgres/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ export function vercelPostgresAdapter(args: Args = {}): DatabaseAdapterObj<Verce
9090
fieldConstraints: {},
9191
getMigrationTemplate,
9292
idType: postgresIDType,
93+
indexes: new Set<string>(),
9394
initializing,
9495
localesSuffix: args.localesSuffix || '_locales',
9596
logger: args.logger,

packages/drizzle/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ export { updateGlobal } from './updateGlobal.js'
3232
export { updateGlobalVersion } from './updateGlobalVersion.js'
3333
export { updateVersion } from './updateVersion.js'
3434
export { upsertRow } from './upsertRow/index.js'
35+
export { buildIndexName } from './utilities/buildIndexName.js'
3536
export { executeSchemaHooks } from './utilities/executeSchemaHooks.js'
3637
export { extendDrizzleTable } from './utilities/extendDrizzleTable.js'
3738
export { hasLocalesTable } from './utilities/hasLocalesTable.js'

packages/drizzle/src/postgres/schema/build.ts

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import type {
3030
} from '../types.js'
3131

3232
import { createTableName } from '../../createTableName.js'
33+
import { buildIndexName } from '../../utilities/buildIndexName.js'
3334
import { createIndex } from './createIndex.js'
3435
import { parentIDColumnMap } from './parentIDColumnMap.js'
3536
import { setColumnID } from './setColumnID.js'
@@ -389,21 +390,25 @@ export const buildTable = ({
389390
foreignColumns: [adapter.tables[formattedRelationTo].id],
390391
}).onDelete('cascade')
391392

392-
const indexName = [colName]
393+
const indexColumns = [colName]
393394

394395
const unique = !disableUnique && uniqueRelationships.has(relationTo)
395396

396397
if (unique) {
397-
indexName.push('path')
398+
indexColumns.push('path')
398399
}
399400
if (hasLocalizedRelationshipField) {
400-
indexName.push('locale')
401+
indexColumns.push('locale')
401402
}
402403

403-
relationExtraConfig[`${relationTo}IdIdx`] = createIndex({
404-
name: indexName,
405-
columnName: `${formattedRelationTo}_id`,
406-
tableName: relationshipsTableName,
404+
const indexName = buildIndexName({
405+
name: `${relationshipsTableName}_${formattedRelationTo}_id`,
406+
adapter,
407+
})
408+
409+
relationExtraConfig[indexName] = createIndex({
410+
name: indexColumns,
411+
indexName,
407412
unique,
408413
})
409414
})

packages/drizzle/src/postgres/schema/createIndex.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,12 @@ import { index, uniqueIndex } from 'drizzle-orm/pg-core'
33
import type { GenericColumn } from '../types.js'
44

55
type CreateIndexArgs = {
6-
columnName: string
6+
indexName: string
77
name: string | string[]
8-
tableName: string
98
unique?: boolean
109
}
1110

12-
export const createIndex = ({ name, columnName, tableName, unique }: CreateIndexArgs) => {
11+
export const createIndex = ({ name, indexName, unique }: CreateIndexArgs) => {
1312
return (table: { [x: string]: GenericColumn }) => {
1413
let columns
1514
if (Array.isArray(name)) {
@@ -21,8 +20,8 @@ export const createIndex = ({ name, columnName, tableName, unique }: CreateIndex
2120
columns = [table[name]]
2221
}
2322
if (unique) {
24-
return uniqueIndex(`${tableName}_${columnName}_idx`).on(columns[0], ...columns.slice(1))
23+
return uniqueIndex(indexName).on(columns[0], ...columns.slice(1))
2524
}
26-
return index(`${tableName}_${columnName}_idx`).on(columns[0], ...columns.slice(1))
25+
return index(indexName).on(columns[0], ...columns.slice(1))
2726
}
2827
}

packages/drizzle/src/postgres/schema/traverseFields.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import type {
3030
} from '../types.js'
3131

3232
import { createTableName } from '../../createTableName.js'
33+
import { buildIndexName } from '../../utilities/buildIndexName.js'
3334
import { hasLocalesTable } from '../../utilities/hasLocalesTable.js'
3435
import { validateExistingBlockIsIdentical } from '../../utilities/validateExistingBlockIsIdentical.js'
3536
import { buildTable } from './build.js'
@@ -169,10 +170,12 @@ export const traverseFields = ({
169170
}
170171
adapter.fieldConstraints[rootTableName][`${columnName}_idx`] = constraintValue
171172
}
172-
targetIndexes[`${newTableName}_${field.name}Idx`] = createIndex({
173+
174+
const indexName = buildIndexName({ name: `${newTableName}_${columnName}`, adapter })
175+
176+
targetIndexes[indexName] = createIndex({
173177
name: field.localized ? [fieldName, '_locale'] : fieldName,
174-
columnName,
175-
tableName: newTableName,
178+
indexName,
176179
unique,
177180
})
178181
}

0 commit comments

Comments
 (0)