Skip to content

Conversation

@chris-kobrzak
Copy link
Contributor

@chris-kobrzak chris-kobrzak commented Jul 4, 2021

When PostgreSQL.prototype.getDropForeignKeys gets called with duplicated foreign keys, an invalid ALTER TABLE statement gets created. This is because the duplicates are mapped to multiple DROP CONSTRAINT fk_key SQL actions, e.g.:

-- This will throw an error
ALTER TABLE "public"."foo"
  DROP CONSTRAINT "fk_duplicatedKey",
  DROP CONSTRAINT "fk_duplicatedKey",
  DROP CONSTRAINT "fk_duplicatedKey",
  DROP CONSTRAINT "fk_otherKey"

As the DROP CONSTRAINT actions are run sequentially, when the first action gets executed by PostgreSQL, the next one (for the same, but already dropped key) will no longer cause an SQL error thanks to the added IF EXISTS check:

-- This is valid SQL
ALTER TABLE "public"."foo"
  DROP CONSTRAINT IF EXISTS "fk_duplicatedKey",
  DROP CONSTRAINT IF EXISTS "fk_duplicatedKey",
  DROP CONSTRAINT IF EXISTS "fk_duplicatedKey",
  DROP CONSTRAINT IF EXISTS "fk_otherKey"

Please note, this is really a hack that fixes npm run migrate operations I have experienced when working on my project. We still need to understand why the getDropForeignKeys method gets called with duplicated foreign keys in certain conditions but I believe ensuring the generated SQL code is valid is still a step in the right direction.

Checklist

  • DCO (Developer Certificate of Origin) signed in all commits
  • npm test passes on your machine (with the exception of 1-2 tests that keep timing out both on the upstream and my fork master branches)
  • New tests added or existing tests modified to cover all changes (this part of code does not seem to have unit test coverage at the moment)
  • Code conforms with the style guide
  • Commit messages are following our guidelines

@slnode
Copy link

slnode commented Jul 4, 2021

Can one of the admins verify this patch? To accept patch and trigger a build add comment ".ok\W+to\W+test."

When `PostgreSQL.prototype.getDropForeignKeys` gets called with
duplicated foreign keys, an invalid `ALTER TABLE` statement gets
created. This is because the duplicates are mapped to multiple `DROP
CONSTRAINT fk_key` SQL actions, e.g.:

```sql
-- This will throw an error
ALTER TABLE "public"."foo"
  DROP CONSTRAINT "fk_duplicatedKey",
  DROP CONSTRAINT "fk_duplicatedKey",
  DROP CONSTRAINT "fk_duplicatedKey",
  DROP CONSTRAINT "fk_otherKey"
```

As the `DROP CONSTRAINT` actions are run sequentially, when the first
action gets executed by PostgreSQL, the next one (for the same, but
already dropped key) will not cause an SQL error thanks to the added IF
EXISTS check:

```sql
-- This is valid SQL
ALTER TABLE "public"."foo"
  DROP CONSTRAINT IF EXISTS "fk_duplicatedKey",
  DROP CONSTRAINT IF EXISTS "fk_duplicatedKey",
  DROP CONSTRAINT IF EXISTS "fk_duplicatedKey",
  DROP CONSTRAINT IF EXISTS "fk_otherKey"
```

Please note, this is really a hack and we still need to understand why
the method in question gets called with duplicated foreign keys in
certain conditions.

Signed-off-by: Chris Kobrzak <chris.kobrzak@gmail.com>
Copy link
Member

@dhmlau dhmlau left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@chris-kobrzak, thanks for the PR. LGTM.

@dhmlau dhmlau merged commit edc9c80 into loopbackio:master Jul 13, 2021
@chris-kobrzak
Copy link
Contributor Author

Thanks Diana!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants