|
26 | 26 | #include "parser/parse_relation.h"
|
27 | 27 | #include "parser/parse_type.h"
|
28 | 28 | #include "utils/builtins.h"
|
| 29 | +#include "utils/datum.h" |
29 | 30 | #include "utils/lsyscache.h"
|
30 | 31 | #include "utils/syscache.h"
|
31 | 32 | #include "utils/typcache.h"
|
@@ -308,6 +309,43 @@ coerce_type(ParseState *pstate, Node *node,
|
308 | 309 | NULL,
|
309 | 310 | inputTypeMod);
|
310 | 311 |
|
| 312 | + /* |
| 313 | + * If it's a varlena value, force it to be in non-expanded |
| 314 | + * (non-toasted) format; this avoids any possible dependency on |
| 315 | + * external values and improves consistency of representation. |
| 316 | + */ |
| 317 | + if (!con->constisnull && newcon->constlen == -1) |
| 318 | + newcon->constvalue = |
| 319 | + PointerGetDatum(PG_DETOAST_DATUM(newcon->constvalue)); |
| 320 | + |
| 321 | +#ifdef RANDOMIZE_ALLOCATED_MEMORY |
| 322 | + |
| 323 | + /* |
| 324 | + * For pass-by-reference data types, repeat the conversion to see if |
| 325 | + * the input function leaves any uninitialized bytes in the result. We |
| 326 | + * can only detect that reliably if RANDOMIZE_ALLOCATED_MEMORY is |
| 327 | + * enabled, so we don't bother testing otherwise. The reason we don't |
| 328 | + * want any instability in the input function is that comparison of |
| 329 | + * Const nodes relies on bytewise comparison of the datums, so if the |
| 330 | + * input function leaves garbage then subexpressions that should be |
| 331 | + * identical may not get recognized as such. See pgsql-hackers |
| 332 | + * discussion of 2008-04-04. |
| 333 | + */ |
| 334 | + if (!con->constisnull && !newcon->constbyval) |
| 335 | + { |
| 336 | + Datum val2; |
| 337 | + |
| 338 | + val2 = stringTypeDatum(baseType, |
| 339 | + DatumGetCString(con->constvalue), |
| 340 | + inputTypeMod); |
| 341 | + if (newcon->constlen == -1) |
| 342 | + val2 = PointerGetDatum(PG_DETOAST_DATUM(val2)); |
| 343 | + if (!datumIsEqual(newcon->constvalue, val2, false, newcon->constlen)) |
| 344 | + elog(WARNING, "type %s has unstable input conversion for \"%s\"", |
| 345 | + typeTypeName(baseType), DatumGetCString(con->constvalue)); |
| 346 | + } |
| 347 | +#endif |
| 348 | + |
311 | 349 | cancel_parser_errposition_callback(&pcbstate);
|
312 | 350 |
|
313 | 351 | result = (Node *) newcon;
|
|
0 commit comments