Skip to content

Conversation

@bplunkett-stripe
Copy link
Collaborator

Description

Index columns effectively have two occurrences in pg_attribute, one is a "virtual column" created for the index and the other is the actual referenced column. For our purposes, we care about the latter, i.e., ensuring an index is deleted before its owning column is dropped, otherwise the index will be implicitly deleted (and not concurrently).

When a column is renamed, the virtual column name stays the same, but the underlying column name obviously changes. pg-schema-diff contained a bug where it referenced the virtual column name. Effectively, a column would be renamed but the column names in the fetched index would not change, leading to incorrectly generated dependencies.

I found this thread in the Postgres maling list to be very useful.

What I did:

  • Updated pg-schema-diff to reference the actual column name
  • (added benefit) Index columns are now fetched in the same query as the indexes, reducing round trips to the database

Motivation

Bug fix

Testing

See added test case

@bplunkett-stripe bplunkett-stripe added the bug Something isn't working label Jul 19, 2024
}
}

// Otherwise, we can drop the index whenever we want.
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Initially was debugging this problem and thought adding a comment helped document it a little better

Indexes: []Index{
{
OwningTable: SchemaQualifiedName{SchemaName: "public", EscapedName: "\"foo\""},
Name: "foo_value_idx", Columns: []string{"renamed_value"},
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Previously, it would have fetched the column as "value" instead of "renamed_value"

@bplunkett-stripe bplunkett-stripe force-pushed the bplunkett/fix-column-renames-for-indexes branch from fdaed98 to 8320e14 Compare July 19, 2024 07:43
Copy link
Collaborator

@alexaub-stripe alexaub-stripe left a comment

Choose a reason for hiding this comment

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

Amazing catch

Comment on lines +99 to +100
SELECT ARRAY_AGG(att.attname ORDER BY indkey_ord.ord)
FROM UNNEST(i.indkey) WITH ORDINALITY AS indkey_ord (attnum, ord)
Copy link
Collaborator

Choose a reason for hiding this comment

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

The ordinality here is just to make it explicit that the unnested array should be aggregated back in the same order after converting to column names right? And this isn't technically necessary since that should be the order anyways?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yep exactly. It's to enforce the order. I don't think it's technically necessary, but I definitely feel more comfortable with explicit ORDER BY

COALESCE(parent_c.relname, '')::TEXT AS parent_index_name,
COALESCE(parent_namespace.nspname, '')::TEXT AS parent_index_schema_name,
(
SELECT ARRAY_AGG(att.attname ORDER BY indkey_ord.ord)
Copy link
Collaborator

Choose a reason for hiding this comment

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

I almost wonder if it's worth a comment on this block here that this is just i.indkey.map(attnum -> column_name(attnum)) but in sql.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Might leave out the comment, since it's probably best to read from the docs on it. Pretty nifty SQL function!

@bplunkett-stripe bplunkett-stripe merged commit 4fc0bff into main Jul 19, 2024
@bplunkett-stripe bplunkett-stripe deleted the bplunkett/fix-column-renames-for-indexes branch July 19, 2024 16:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants