Fix failure-to-copy bug in commit 6f6b99d13.
authorTom Lane <tgl@sss.pgh.pa.us>
Sat, 9 Sep 2017 00:45:31 +0000 (20:45 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Sat, 9 Sep 2017 00:45:31 +0000 (20:45 -0400)
The previous coding of get_qual_for_list() was careful to copy everything
it was using from the input data structure.  The new version missed
making a copy of pass-by-ref datum values that it's inserting into Consts.
This is not optional, however, as revealed by buildfarm failures on
machines running -DRELCACHE_FORCE_RELEASE: we're copying from a relcache
entry that could go away before the required lifespan of our output
expression.  I'm pretty sure -DCLOBBER_CACHE_ALWAYS machines won't like
this either, but none of them have reported in yet.

src/backend/catalog/partition.c

index c94ee941ded1d5e863b744874ad183ccd175e993..73eff17202c90f1d546228dbc61be7d6279026a7 100644 (file)
@@ -1559,12 +1559,18 @@ get_qual_for_list(Relation parent, PartitionBoundSpec *spec)
                {
                        Const      *val;
 
-                       /* Construct const from datum */
+                       /*
+                        * Construct Const from known-not-null datum.  We must be careful
+                        * to copy the value, because our result has to be able to outlive
+                        * the relcache entry we're copying from.
+                        */
                        val = makeConst(key->parttypid[0],
                                                        key->parttypmod[0],
                                                        key->parttypcoll[0],
                                                        key->parttyplen[0],
-                                                       *boundinfo->datums[i],
+                                                       datumCopy(*boundinfo->datums[i],
+                                                                         key->parttypbyval[0],
+                                                                         key->parttyplen[0]),
                                                        false,  /* isnull */
                                                        key->parttypbyval[0]);