Postgres: prepend className to unique indexes (#6741)

* prepend className to unique index to allow multiple unique indexes for different classes

* add testcase

* switched test so it can be tested on older versions of parse-server and show failure

* get rid of console log messages on restart by checking if the index exists before creating it

* add IF NOT EXISTS and IF EXISTS to ALTER TABLE

* revert some of code

* ensureIndex use IF NOT EXISTS

* ALTER TABLE CONSTRAINT can't use IF, ADD/DROP COLUMN can

* retesting

* update

* switchted to CREATE UNIQUE INDEX instrad of ALTER TABLE... ALTER TABLE doesn't seem to be needed
This commit is contained in:
Corey
2020-10-12 01:47:45 -04:00
committed by GitHub
parent 8c88d8197b
commit de7ec58de3
2 changed files with 96 additions and 35 deletions

View File

@@ -1128,7 +1128,7 @@ export class PostgresStorageAdapter implements StorageAdapter {
if (type.type !== 'Relation') {
try {
await t.none(
'ALTER TABLE $<className:name> ADD COLUMN $<fieldName:name> $<postgresType:raw>',
'ALTER TABLE $<className:name> ADD COLUMN IF NOT EXISTS $<fieldName:name> $<postgresType:raw>',
{
className,
fieldName,
@@ -1271,7 +1271,10 @@ export class PostgresStorageAdapter implements StorageAdapter {
{ schema, className }
);
if (values.length > 1) {
await t.none(`ALTER TABLE $1:name DROP COLUMN ${columns}`, values);
await t.none(
`ALTER TABLE $1:name DROP COLUMN IF EXISTS ${columns}`,
values
);
}
});
}
@@ -2063,13 +2066,11 @@ export class PostgresStorageAdapter implements StorageAdapter {
schema: SchemaType,
fieldNames: string[]
) {
// Use the same name for every ensureUniqueness attempt, because postgres
// Will happily create the same index with multiple names.
const constraintName = `unique_${fieldNames.sort().join('_')}`;
const constraintName = `${className}_unique_${fieldNames.sort().join('_')}`;
const constraintPatterns = fieldNames.map(
(fieldName, index) => `$${index + 3}:name`
);
const qs = `ALTER TABLE $1:name ADD CONSTRAINT $2:name UNIQUE (${constraintPatterns.join()})`;
const qs = `CREATE UNIQUE INDEX IF NOT EXISTS $2:name ON $1:name(${constraintPatterns.join()})`;
return this._client
.none(qs, [className, constraintName, ...fieldNames])
.catch(error => {
@@ -2491,7 +2492,7 @@ export class PostgresStorageAdapter implements StorageAdapter {
return (conn || this._client).tx(t =>
t.batch(
indexes.map(i => {
return t.none('CREATE INDEX $1:name ON $2:name ($3:name)', [
return t.none('CREATE INDEX IF NOT EXISTS $1:name ON $2:name ($3:name)', [
i.name,
className,
i.key,
@@ -2509,7 +2510,7 @@ export class PostgresStorageAdapter implements StorageAdapter {
): Promise<void> {
await (
conn || this._client
).none('CREATE INDEX $1:name ON $2:name ($3:name)', [
).none('CREATE INDEX IF NOT EXISTS $1:name ON $2:name ($3:name)', [
fieldName,
className,
type,
@@ -2588,7 +2589,7 @@ export class PostgresStorageAdapter implements StorageAdapter {
(fieldName, index) => `lower($${index + 3}:name) varchar_pattern_ops`
)
: fieldNames.map((fieldName, index) => `$${index + 3}:name`);
const qs = `CREATE INDEX $1:name ON $2:name (${constraintPatterns.join()})`;
const qs = `CREATE INDEX IF NOT EXISTS $1:name ON $2:name (${constraintPatterns.join()})`;
await conn
.none(qs, [indexNameOptions.name, className, ...fieldNames])
.catch(error => {