Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix error when trying to drop columns from temp tables. #410

Conversation

Sairakan
Copy link
Contributor

@Sairakan Sairakan commented Jul 18, 2024

Description

Our original code for ENRgetSystableScan did not take into account the fact that pg_depend scans can use up to three keys. Fix the issue by making sure to use the third key if it is supplied.

Also fix the logic around performing the deletion so that we don't try to drop the entire ENR table when deleting columns.

Backport to PG15 as well.

Issues Resolved

BABEL-4912

Check List

  • Commits are signed per the DCO using --signoff

By submitting this pull request, I confirm that my contribution is under the terms of the PostgreSQL license, and grant any person obtaining a copy of the contribution permission to relicense all or a portion of my contribution to the PostgreSQL License solely to contribute all or a portion of my contribution to the PostgreSQL open source project.

For more information on following Developer Certificate of Origin and signing off your commits, please check here.

@@ -1392,7 +1392,8 @@ deleteOneObject(const ObjectAddress *object, Relation *depRel, int flags)
DeleteInitPrivs(object);

// Delete from ENR - noop if not found from ENR
ENRDropEntry(object->objectId);
if (object->objectSubId == 0)
Copy link
Contributor

Choose a reason for hiding this comment

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

so then how does an ENR entry with object->objectSubId != 0 get cleaned up?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

There aren't any ENR entries for such objects - ENR entries are only created for the base table, which would have a subid of 0. This test case is to fix an erroneous case where we are trying to delete something that doesn't actually have an ENR entry at all.

Copy link
Contributor

@lejaokri lejaokri Jul 22, 2024

Choose a reason for hiding this comment

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

nit: please add a comment why we explicitly check for objectSubId. I cant seem to find the testcase for this code change

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sorry, I worded my comment awkwardly - the overall fix requires this change in order to work. Without it, we will get an error when trying to ALTER TABLE DROP COLUMN, as the table will erroneously be deleted when we only wanted to drop one column. So in a sense, all of the test cases for the feature in babelfish-for-postgresql/babelfish_extensions#2753 exercise this code path.

This test case is to fix an erroneous case should have been This check is to fix an erroneous case.

I'll add a comment clarifying why we need this check.

* So we cannot return right away if there is a match.
*/
ListCell *lc;
foreach(lc, enr->md.cattups[ENR_CATTUP_DEPEND]) {
Form_pg_depend tup = (Form_pg_depend) GETSTRUCT((HeapTuple) lfirst(lc));
if (indexId == DependDependerIndexId &&
tup->classid == (Oid)v1 &&
tup->objid == (Oid)v2)
tup->objid == (Oid)v2 &&
(nkeys == 2 || tup->objsubid == (int32)v3))
Copy link
Contributor

Choose a reason for hiding this comment

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

is it safe to just check if tup->objsubid == v3? since v3 if not set is 0, and tup->objsubid will be 0 for non-column lookups

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That doesn't work - if the caller of this function only wants 2 keys, then they want all pg_depend entries that match the objid, no matter what the subid is - so we need to completely ignore the subid in that case.

@@ -1392,7 +1392,8 @@ deleteOneObject(const ObjectAddress *object, Relation *depRel, int flags)
DeleteInitPrivs(object);

// Delete from ENR - noop if not found from ENR
ENRDropEntry(object->objectId);
if (object->objectSubId == 0)
Copy link
Contributor

Choose a reason for hiding this comment

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

Should use InvalidOid instead of 0 in this case

Copy link
Contributor Author

Choose a reason for hiding this comment

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

objectSubId is not an Oid, it is an int32 (see the definition in pg_depend https://www.postgresql.org/docs/current/catalog-pg-depend.html or in the code for FormData_pg_depend). I don't think it would be appropriate to use InvalidOid when this is not an Oid value, this is an int value representing the column number represented in the pg_depend tuple (or 0 in the case that it is not used).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

In all other places in the code, this value is explicitly compared to 0, e.g. https://github.com/postgres/postgres/blob/master/src/backend/catalog/dependency.c#L557

* So we cannot return right away if there is a match.
*/
ListCell *lc;
foreach(lc, enr->md.cattups[ENR_CATTUP_DEPEND]) {
Form_pg_depend tup = (Form_pg_depend) GETSTRUCT((HeapTuple) lfirst(lc));
if (indexId == DependDependerIndexId &&
tup->classid == (Oid)v1 &&
tup->objid == (Oid)v2)
tup->objid == (Oid)v2 &&
(nkeys == 2 || tup->objsubid == (int32)v3))
Copy link
Contributor

Choose a reason for hiding this comment

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

Why other have (Oid) to cast to Oid, while v3 is cast to (int32) , and v1,v2,v3 is really confusing in naming, should assign a more reasonable naming.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

As above, this is cast to int32 in order to match the definition of the field in ForData_pg_depend. We use generic v1, v2, v3 naming as they are used to refer to the keys being passed into the function, which could be for any catalog table, not just pg_depend. Thus, the value they represent can be multiple different types depending on which catalog we are searching.

Comment on lines +457 to +458
tup->refobjid == (Oid)v2 &&
(nkeys == 2 || tup->refobjsubid == (int32)v3))
Copy link
Contributor

Choose a reason for hiding this comment

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

I see. good catch!

Signed-off-by: Jason Teng <[email protected]>
@2jungkook 2jungkook merged commit 799ea9e into babelfish-for-postgresql:BABEL_4_X_DEV__PG_16_X Jul 23, 2024
2 checks passed
@2jungkook 2jungkook deleted the jira-babel-4912 branch July 23, 2024 16:59
2jungkook pushed a commit to babelfish-for-postgresql/babelfish_extensions that referenced this pull request Jul 23, 2024
Sairakan added a commit to amazon-aurora/postgresql_modified_for_babelfish that referenced this pull request Jul 24, 2024
…r-postgresql#410)

Our original code for ENRgetSystableScan did not take into account the fact that pg_depend scans can use up to three keys. Fix the issue by making sure to use the third key if it is supplied.

Also fix the logic around performing the deletion so that we don't try to drop the entire ENR table when deleting columns.

Backport to PG15 as well.

Task: BABEL-4912
Signed-off-by: Jason Teng <[email protected]>
Sairakan added a commit to amazon-aurora/babelfish_extensions that referenced this pull request Jul 24, 2024
2jungkook pushed a commit that referenced this pull request Jul 24, 2024
Our original code for ENRgetSystableScan did not take into account the fact that pg_depend scans can use up to three keys. Fix the issue by making sure to use the third key if it is supplied.

Also fix the logic around performing the deletion so that we don't try to drop the entire ENR table when deleting columns.

Backport to PG15 as well.

Task: BABEL-4912

Signed-off-by: Jason Teng <[email protected]>
2jungkook pushed a commit to babelfish-for-postgresql/babelfish_extensions that referenced this pull request Jul 24, 2024
sharathbp pushed a commit to amazon-aurora/babelfish_extensions that referenced this pull request Aug 20, 2024
staticlibs pushed a commit to wiltondb/postgresql_modified_for_babelfish that referenced this pull request Oct 8, 2024
…r-postgresql#410) (babelfish-for-postgresql#414)

Our original code for ENRgetSystableScan did not take into account the fact that pg_depend scans can use up to three keys. Fix the issue by making sure to use the third key if it is supplied.

Also fix the logic around performing the deletion so that we don't try to drop the entire ENR table when deleting columns.

Backport to PG15 as well.

Task: BABEL-4912

Signed-off-by: Jason Teng <[email protected]>
roshan0708 pushed a commit to amazon-aurora/postgresql_modified_for_babelfish that referenced this pull request Oct 15, 2024
…fish-for-postgresql#410)

Our original code for ENRgetSystableScan did not take into account the fact that pg_depend scans can use up to three keys. Fix the issue by making sure to use the third key if it is supplied.

Also fix the logic around performing the deletion so that we don't try to drop the entire ENR table when deleting columns.

Backport to PG15 as well.

Task: BABEL-4912
Signed-off-by: Jason Teng <[email protected]>
roshan0708 pushed a commit to amazon-aurora/postgresql_modified_for_babelfish that referenced this pull request Oct 18, 2024
…fish-for-postgresql#410)

Our original code for ENRgetSystableScan did not take into account the fact that pg_depend scans can use up to three keys. Fix the issue by making sure to use the third key if it is supplied.

Also fix the logic around performing the deletion so that we don't try to drop the entire ENR table when deleting columns.

Backport to PG15 as well.

Task: BABEL-4912
Signed-off-by: Jason Teng <[email protected]>
roshan0708 pushed a commit to amazon-aurora/postgresql_modified_for_babelfish that referenced this pull request Oct 18, 2024
…fish-for-postgresql#410)

Our original code for ENRgetSystableScan did not take into account the fact that pg_depend scans can use up to three keys. Fix the issue by making sure to use the third key if it is supplied.

Also fix the logic around performing the deletion so that we don't try to drop the entire ENR table when deleting columns.

Backport to PG15 as well.

Task: BABEL-4912
Signed-off-by: Jason Teng <[email protected]>
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.

5 participants