Skip to content

Commit 4352966

Browse files
authored
[BABEL] Fix: Rectified removal and updates of incorrect tuples from ENR catalogs (babelfish-for-postgresql#700)
PG18 introduced a new constraint which is created for all non-null attributes including p_keys. So now, an attribute which is a p_key will create two constraints - p_key and not-null constraint. When adding these constraints on the catalog in ENR, the condition tf2.oid > tf1.oid will keep the catalog list sorted, however, while removing or updating any tuple in this catalog list, we compare oids in a way which is interpreted as remove/update oid of tuple which has an oid greater than or equal to the requested oid. This leads to catalog corruption since we are removing/updating a different tuple than the requested one. This change rectifies this condition and breaks it down based on the operation being performed. Task: BABEL-6211 Signed-off-by: Ayush Shah <ayushdsh@amazon.com>
1 parent 6e6ec7f commit 4352966

File tree

1 file changed

+64
-14
lines changed

1 file changed

+64
-14
lines changed

src/backend/utils/misc/queryenvironment.c

Lines changed: 64 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -788,6 +788,53 @@ bool ENRUpdateTuple(Relation rel, HeapTuple tup)
788788
return _ENR_tuple_operation(rel, tup, ENR_OP_UPDATE, false, false);
789789
}
790790

791+
/*
792+
* Find matching tuple in ENR catalog list for DROP/UPDATE operations.
793+
* Returns the ListCell containing the matching tuple, or NULL if not found.
794+
*/
795+
static ListCell *
796+
find_tuple_in_enr_catalog(List *cattups, HeapTuple search_tup, Oid catalog_oid)
797+
{
798+
ListCell *lc;
799+
800+
foreach(lc, cattups)
801+
{
802+
HeapTuple enr_tup = (HeapTuple) lfirst(lc);
803+
804+
switch (catalog_oid)
805+
{
806+
case IndexRelationId:
807+
{
808+
Form_pg_index idx1 = (Form_pg_index) GETSTRUCT(search_tup);
809+
Form_pg_index idx2 = (Form_pg_index) GETSTRUCT(enr_tup);
810+
if (idx1->indexrelid == idx2->indexrelid)
811+
return lc;
812+
break;
813+
}
814+
case AttrDefaultRelationId:
815+
{
816+
Form_pg_attrdef def1 = (Form_pg_attrdef) GETSTRUCT(search_tup);
817+
Form_pg_attrdef def2 = (Form_pg_attrdef) GETSTRUCT(enr_tup);
818+
if (def1->oid == def2->oid)
819+
return lc;
820+
break;
821+
}
822+
case ConstraintRelationId:
823+
{
824+
Form_pg_constraint con1 = (Form_pg_constraint) GETSTRUCT(search_tup);
825+
Form_pg_constraint con2 = (Form_pg_constraint) GETSTRUCT(enr_tup);
826+
if (con1->oid == con2->oid)
827+
return lc;
828+
break;
829+
}
830+
default:
831+
elog(ERROR, "Unsupported catalog OID %u for tuple matching", catalog_oid);
832+
}
833+
}
834+
835+
return NULL;
836+
}
837+
791838
/*
792839
* Workhorse for add/update/drop tuples in the ENR.
793840
*
@@ -914,8 +961,10 @@ static bool _ENR_tuple_operation(Relation catalog_rel, HeapTuple tup, ENRTupleOp
914961
rel_oid = ((Form_pg_index) GETSTRUCT(tup))->indrelid;
915962
if ((enr = get_ENR_withoid(queryEnv, rel_oid, ENR_TSQL_TEMP, false))) {
916963
list_ptr = &enr->md.cattups[ENR_CATTUP_INDEX];
917-
lc = list_head(enr->md.cattups[ENR_CATTUP_INDEX]);
918964
ret = true;
965+
966+
if (op == ENR_OP_DROP || op == ENR_OP_UPDATE)
967+
lc = find_tuple_in_enr_catalog(*list_ptr, tup, catalog_oid);
919968

920969
if ((op == ENR_OP_ADD || op == ENR_OP_UPDATE) && HeapTupleIsValid(tup))
921970
{
@@ -994,20 +1043,19 @@ static bool _ENR_tuple_operation(Relation catalog_rel, HeapTuple tup, ENRTupleOp
9941043
case ConstraintRelationId:
9951044
rel_oid = ((Form_pg_constraint) GETSTRUCT(tup))->conrelid;
9961045
if ((enr = get_ENR_withoid(queryEnv, rel_oid, ENR_TSQL_TEMP, false))) {
997-
Form_pg_constraint tf1, tf2; /* tuple forms*/
998-
ListCell *curlc;
999-
10001046
list_ptr = &enr->md.cattups[ENR_CATTUP_CONSTRAINT];
1001-
tf1 = (Form_pg_constraint) GETSTRUCT(tup);
1002-
foreach(curlc, enr->md.cattups[ENR_CATTUP_CONSTRAINT]) {
1003-
tf2 = (Form_pg_constraint) GETSTRUCT((HeapTuple) lfirst(curlc));
1004-
if (tf2->oid >= tf1->oid) {
1005-
lc = curlc;
1006-
insert_at = foreach_current_index(curlc) + 1;
1047+
ret = true;
1048+
1049+
switch (op)
1050+
{
1051+
case ENR_OP_ADD:
1052+
insert_at = list_length(enr->md.cattups[ENR_CATTUP_CONSTRAINT]);
1053+
break;
1054+
case ENR_OP_DROP:
1055+
case ENR_OP_UPDATE:
1056+
lc = find_tuple_in_enr_catalog(*list_ptr, tup, catalog_oid);
10071057
break;
1008-
}
10091058
}
1010-
ret = true;
10111059
}
10121060
break;
10131061
case StatisticRelationId:
@@ -1060,8 +1108,10 @@ static bool _ENR_tuple_operation(Relation catalog_rel, HeapTuple tup, ENRTupleOp
10601108
rel_oid = ((Form_pg_attrdef) GETSTRUCT(tup))->adrelid;
10611109
if ((enr = get_ENR_withoid(queryEnv, rel_oid, ENR_TSQL_TEMP, false))) {
10621110
list_ptr = &enr->md.cattups[ENR_CATTUP_ATTR_DEF_REL];
1063-
lc = list_head(enr->md.cattups[ENR_CATTUP_ATTR_DEF_REL]);
10641111
ret = true;
1112+
1113+
if (op == ENR_OP_DROP || op == ENR_OP_UPDATE)
1114+
lc = find_tuple_in_enr_catalog(*list_ptr, tup, catalog_oid);
10651115
}
10661116
break;
10671117
default:
@@ -1850,4 +1900,4 @@ bool has_existing_enr_relations()
18501900
}
18511901

18521902
return false;
1853-
}
1903+
}

0 commit comments

Comments
 (0)