aboutsummaryrefslogtreecommitdiff
path: root/src/backend/parser/parse_coerce.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/parser/parse_coerce.c')
-rw-r--r--src/backend/parser/parse_coerce.c38
1 files changed, 38 insertions, 0 deletions
diff --git a/src/backend/parser/parse_coerce.c b/src/backend/parser/parse_coerce.c
index f6e7be4e710..589183c277e 100644
--- a/src/backend/parser/parse_coerce.c
+++ b/src/backend/parser/parse_coerce.c
@@ -26,6 +26,7 @@
#include "parser/parse_relation.h"
#include "parser/parse_type.h"
#include "utils/builtins.h"
+#include "utils/datum.h"
#include "utils/lsyscache.h"
#include "utils/syscache.h"
#include "utils/typcache.h"
@@ -308,6 +309,43 @@ coerce_type(ParseState *pstate, Node *node,
NULL,
inputTypeMod);
+ /*
+ * If it's a varlena value, force it to be in non-expanded
+ * (non-toasted) format; this avoids any possible dependency on
+ * external values and improves consistency of representation.
+ */
+ if (!con->constisnull && newcon->constlen == -1)
+ newcon->constvalue =
+ PointerGetDatum(PG_DETOAST_DATUM(newcon->constvalue));
+
+#ifdef RANDOMIZE_ALLOCATED_MEMORY
+
+ /*
+ * For pass-by-reference data types, repeat the conversion to see if
+ * the input function leaves any uninitialized bytes in the result. We
+ * can only detect that reliably if RANDOMIZE_ALLOCATED_MEMORY is
+ * enabled, so we don't bother testing otherwise. The reason we don't
+ * want any instability in the input function is that comparison of
+ * Const nodes relies on bytewise comparison of the datums, so if the
+ * input function leaves garbage then subexpressions that should be
+ * identical may not get recognized as such. See pgsql-hackers
+ * discussion of 2008-04-04.
+ */
+ if (!con->constisnull && !newcon->constbyval)
+ {
+ Datum val2;
+
+ val2 = stringTypeDatum(baseType,
+ DatumGetCString(con->constvalue),
+ inputTypeMod);
+ if (newcon->constlen == -1)
+ val2 = PointerGetDatum(PG_DETOAST_DATUM(val2));
+ if (!datumIsEqual(newcon->constvalue, val2, false, newcon->constlen))
+ elog(WARNING, "type %s has unstable input conversion for \"%s\"",
+ typeTypeName(baseType), DatumGetCString(con->constvalue));
+ }
+#endif
+
cancel_parser_errposition_callback(&pcbstate);
result = (Node *) newcon;