From 289992c462b504ffa289202ce8fc34a56b4048c3 Mon Sep 17 00:00:00 2001 From: Robert Haas Date: Tue, 24 Jan 2017 08:57:10 -0500 Subject: [PATCH] Don't invoke arbitrary code inside a possibly-aborted transaction. The code here previously tried to call the partitioning operator, but really the right thing to do (and the safe thing to do) is use datumIsEqual(). Amit Langote, but I expanded the comment and fixed a compiler warning. --- src/backend/catalog/partition.c | 20 ++++++++++++++------ src/backend/utils/adt/datum.c | 4 ++++ 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/backend/catalog/partition.c b/src/backend/catalog/partition.c index ad95b1bc55..1df9af110a 100644 --- a/src/backend/catalog/partition.c +++ b/src/backend/catalog/partition.c @@ -639,12 +639,20 @@ partition_bounds_equal(PartitionKey key, continue; } - /* Compare the actual values */ - cmpval = DatumGetInt32(FunctionCall2Coll(&key->partsupfunc[j], - key->partcollation[j], - b1->datums[i][j], - b2->datums[i][j])); - if (cmpval != 0) + /* + * Compare the actual values. Note that it would be both incorrect + * and unsafe to invoke the comparison operator derived from the + * partitioning specification here. It would be incorrect because + * we want the relcache entry to be updated for ANY change to the + * partition bounds, not just those that the partitioning operator + * thinks are significant. It would be unsafe because we might + * reach this code in the context of an aborted transaction, and + * an arbitrary partitioning operator might not be safe in that + * context. datumIsEqual() should be simple enough to be safe. + */ + if (!datumIsEqual(b1->datums[i][j], b2->datums[i][j], + key->parttypbyval[j], + key->parttyplen[j])) return false; } diff --git a/src/backend/utils/adt/datum.c b/src/backend/utils/adt/datum.c index 535e4277cc..071a7d4db1 100644 --- a/src/backend/utils/adt/datum.c +++ b/src/backend/utils/adt/datum.c @@ -209,6 +209,10 @@ datumTransfer(Datum value, bool typByVal, int typLen) * of say the representation of zero in one's complement arithmetic). * Also, it will probably not give the answer you want if either * datum has been "toasted". + * + * Do not try to make this any smarter than it currently is with respect + * to "toasted" datums, because some of the callers could be working in the + * context of an aborted transaction. *------------------------------------------------------------------------- */ bool -- 2.40.0