]> granicus.if.org Git - postgresql/commitdiff
Don't invoke arbitrary code inside a possibly-aborted transaction.
authorRobert Haas <rhaas@postgresql.org>
Tue, 24 Jan 2017 13:57:10 +0000 (08:57 -0500)
committerRobert Haas <rhaas@postgresql.org>
Tue, 24 Jan 2017 13:57:10 +0000 (08:57 -0500)
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
src/backend/utils/adt/datum.c

index ad95b1bc55d78b67df6f74634b17f9079e459c92..1df9af110a42cdc02477980b78cd07442b96bf76 100644 (file)
@@ -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;
                }
 
index 535e4277ccb0d57c6b997371f940a48d73c6a082..071a7d4db168986a193966580da7216710259f79 100644 (file)
@@ -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