From 7988bb0b1ac03e5441d42e0da3b5e5a94d355935 Mon Sep 17 00:00:00 2001 From: Jason Teng Date: Thu, 18 Jul 2024 18:33:31 +0000 Subject: [PATCH 1/5] Fix error when trying to drop columns from temp tables. Signed-off-by: Jason Teng --- src/backend/catalog/dependency.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/backend/catalog/dependency.c b/src/backend/catalog/dependency.c index 563b5e3dc91..f5d085ca977 100644 --- a/src/backend/catalog/dependency.c +++ b/src/backend/catalog/dependency.c @@ -887,6 +887,11 @@ findDependentObjects(const ObjectAddress *object, Form_pg_depend foundDep = (Form_pg_depend) GETSTRUCT(tup); int subflags; + if (foundDep->refclassid == object->classId && + foundDep->refobjid == object->objectId && + foundDep->refobjsubid != object->objectSubId) + continue; + otherObject.classId = foundDep->classid; otherObject.objectId = foundDep->objid; otherObject.objectSubId = foundDep->objsubid; @@ -1392,7 +1397,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) + ENRDropEntry(object->objectId); /* * CommandCounterIncrement here to ensure that preceding changes are all From a483195d1483a07300d49a1fbb5d4770e45c9af2 Mon Sep 17 00:00:00 2001 From: Jason Teng Date: Thu, 18 Jul 2024 19:21:21 +0000 Subject: [PATCH 2/5] Fix the source of the incorrect systable scan lookup where objsubid was not being checked. Signed-off-by: Jason Teng --- src/backend/catalog/dependency.c | 5 ----- src/backend/utils/misc/queryenvironment.c | 10 ++++++---- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/src/backend/catalog/dependency.c b/src/backend/catalog/dependency.c index f5d085ca977..79f509ff416 100644 --- a/src/backend/catalog/dependency.c +++ b/src/backend/catalog/dependency.c @@ -887,11 +887,6 @@ findDependentObjects(const ObjectAddress *object, Form_pg_depend foundDep = (Form_pg_depend) GETSTRUCT(tup); int subflags; - if (foundDep->refclassid == object->classId && - foundDep->refobjid == object->objectId && - foundDep->refobjsubid != object->objectSubId) - continue; - otherObject.classId = foundDep->classid; otherObject.objectId = foundDep->objid; otherObject.objectSubId = foundDep->objsubid; diff --git a/src/backend/utils/misc/queryenvironment.c b/src/backend/utils/misc/queryenvironment.c index 1d5f3e11a28..419536a604d 100644 --- a/src/backend/utils/misc/queryenvironment.c +++ b/src/backend/utils/misc/queryenvironment.c @@ -435,9 +435,9 @@ bool ENRgetSystableScan(Relation rel, Oid indexId, int nkeys, ScanKey key, List * Search through the entire ENR relation list for everything * that has a relation (non-recursive) to this object. * If indexId is DependDependerIndexId, we try to mimic - * SELECT * FROM pg_depend WHERE classid=v1 AND objid=v2 + * SELECT * FROM pg_depend WHERE classid=v1 AND objid=v2 AND objsubid = v3 * Otherwise if it is DependReferenceIndexId we try to mimic - * SELECT * FROM pg_depend WHERE refclassid=v1 AND refobjid=v2 + * SELECT * FROM pg_depend WHERE refclassid=v1 AND refobjid=v2 AND refobjsubid = v3 * So we cannot return right away if there is a match. */ ListCell *lc; @@ -445,7 +445,8 @@ bool ENRgetSystableScan(Relation rel, Oid indexId, int nkeys, ScanKey key, List 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 && + tup->objsubid == (int32) v3) { *tuplist = list_insert_nth(*tuplist, index++, lfirst(lc)); *tuplist_flags |= SYSSCAN_ENR_NEEDFREE; @@ -453,7 +454,8 @@ bool ENRgetSystableScan(Relation rel, Oid indexId, int nkeys, ScanKey key, List } else if (indexId == DependReferenceIndexId && tup->refclassid == (Oid)v1 && - tup->refobjid == (Oid)v2) + tup->refobjid == (Oid)v2 && + tup->refobjsubid == (int32) v3) { *tuplist = list_insert_nth(*tuplist, index++, lfirst(lc)); *tuplist_flags |= SYSSCAN_ENR_NEEDFREE; From ec4ac302ac41d5d9cc520194516c981de2ff79ee Mon Sep 17 00:00:00 2001 From: Jason Teng Date: Thu, 18 Jul 2024 19:59:38 +0000 Subject: [PATCH 3/5] Make pg_depend lookup more specific based on number of supplied keys. Signed-off-by: Jason Teng --- src/backend/utils/misc/queryenvironment.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/backend/utils/misc/queryenvironment.c b/src/backend/utils/misc/queryenvironment.c index 419536a604d..1b35a925bad 100644 --- a/src/backend/utils/misc/queryenvironment.c +++ b/src/backend/utils/misc/queryenvironment.c @@ -435,9 +435,9 @@ bool ENRgetSystableScan(Relation rel, Oid indexId, int nkeys, ScanKey key, List * Search through the entire ENR relation list for everything * that has a relation (non-recursive) to this object. * If indexId is DependDependerIndexId, we try to mimic - * SELECT * FROM pg_depend WHERE classid=v1 AND objid=v2 AND objsubid = v3 + * SELECT * FROM pg_depend WHERE classid=v1 AND objid=v2 (AND objsubid = v3 if applicable) * Otherwise if it is DependReferenceIndexId we try to mimic - * SELECT * FROM pg_depend WHERE refclassid=v1 AND refobjid=v2 AND refobjsubid = v3 + * SELECT * FROM pg_depend WHERE refclassid=v1 AND refobjid=v2 (AND refobjsubid = v3 if applicable) * So we cannot return right away if there is a match. */ ListCell *lc; @@ -446,7 +446,7 @@ bool ENRgetSystableScan(Relation rel, Oid indexId, int nkeys, ScanKey key, List if (indexId == DependDependerIndexId && tup->classid == (Oid)v1 && tup->objid == (Oid)v2 && - tup->objsubid == (int32) v3) + (nkeys > 2 ? tup->objsubid == (int32)v3 : true)) { *tuplist = list_insert_nth(*tuplist, index++, lfirst(lc)); *tuplist_flags |= SYSSCAN_ENR_NEEDFREE; @@ -455,7 +455,7 @@ bool ENRgetSystableScan(Relation rel, Oid indexId, int nkeys, ScanKey key, List else if (indexId == DependReferenceIndexId && tup->refclassid == (Oid)v1 && tup->refobjid == (Oid)v2 && - tup->refobjsubid == (int32) v3) + (nkeys > 2 ? tup->refobjsubid == (int32)v3 : true)) { *tuplist = list_insert_nth(*tuplist, index++, lfirst(lc)); *tuplist_flags |= SYSSCAN_ENR_NEEDFREE; From 573599321ef9598610b18d2868824330d6ca3faa Mon Sep 17 00:00:00 2001 From: Jason Teng Date: Thu, 18 Jul 2024 20:08:40 +0000 Subject: [PATCH 4/5] Clean up code logic. Signed-off-by: Jason Teng --- src/backend/utils/misc/queryenvironment.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/backend/utils/misc/queryenvironment.c b/src/backend/utils/misc/queryenvironment.c index 1b35a925bad..dad4fdc5483 100644 --- a/src/backend/utils/misc/queryenvironment.c +++ b/src/backend/utils/misc/queryenvironment.c @@ -446,7 +446,7 @@ bool ENRgetSystableScan(Relation rel, Oid indexId, int nkeys, ScanKey key, List if (indexId == DependDependerIndexId && tup->classid == (Oid)v1 && tup->objid == (Oid)v2 && - (nkeys > 2 ? tup->objsubid == (int32)v3 : true)) + (nkeys == 2 || tup->objsubid == (int32)v3)) { *tuplist = list_insert_nth(*tuplist, index++, lfirst(lc)); *tuplist_flags |= SYSSCAN_ENR_NEEDFREE; @@ -455,7 +455,7 @@ bool ENRgetSystableScan(Relation rel, Oid indexId, int nkeys, ScanKey key, List else if (indexId == DependReferenceIndexId && tup->refclassid == (Oid)v1 && tup->refobjid == (Oid)v2 && - (nkeys > 2 ? tup->refobjsubid == (int32)v3 : true)) + (nkeys == 2 || tup->refobjsubid == (int32)v3)) { *tuplist = list_insert_nth(*tuplist, index++, lfirst(lc)); *tuplist_flags |= SYSSCAN_ENR_NEEDFREE; From 2e7a35956231dbad53ecf4042fa158aba38f0229 Mon Sep 17 00:00:00 2001 From: Jason Teng Date: Mon, 22 Jul 2024 20:22:56 +0000 Subject: [PATCH 5/5] Update code comment. Signed-off-by: Jason Teng --- src/backend/catalog/dependency.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/backend/catalog/dependency.c b/src/backend/catalog/dependency.c index 79f509ff416..f1a581c61ae 100644 --- a/src/backend/catalog/dependency.c +++ b/src/backend/catalog/dependency.c @@ -1391,7 +1391,12 @@ deleteOneObject(const ObjectAddress *object, Relation *depRel, int flags) DeleteSecurityLabel(object); DeleteInitPrivs(object); - // Delete from ENR - noop if not found from ENR + /* + * If objectSubId != 0, then this is a column. There are no ENR entries + * for individual columns, so skip ENRDropEntry in this case (or else we + * will delete the entire table instead of just the column). Note that this + * is a no-op if the objectId is not found from ENR. + */ if (object->objectSubId == 0) ENRDropEntry(object->objectId);