From 4f6c75b541385eb2d48f7ef62c1c323ec2642134 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Wed, 27 Apr 2011 14:05:58 -0400 Subject: [PATCH] Add comments about the need to avoid uninitialized bits in datatype values. There was already one recommendation in the documentation about writing C functions to ensure padding bytes are zeroes, but make it stronger. Also fix an example that was still using direct assignment to a varlena length word, which no longer works since the varvarlena changes. --- doc/src/sgml/xfunc.sgml | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/doc/src/sgml/xfunc.sgml b/doc/src/sgml/xfunc.sgml index 58b83bbf12..a6d2a1355c 100644 --- a/doc/src/sgml/xfunc.sgml +++ b/doc/src/sgml/xfunc.sgml @@ -1741,6 +1741,15 @@ typedef struct itself. + + Another important point is to avoid leaving any uninitialized bits + within data type values; for example, take care to zero out any + alignment padding bytes that might be present in structs. Without + this, logically-equivalent constants of your data type might be + seen as unequal by the planner, leading to inefficient (though not + incorrect) plans. + + Never modify the contents of a pass-by-reference input @@ -1784,7 +1793,7 @@ typedef struct { char buffer[40]; /* our source data */ ... text *destination = (text *) palloc(VARHDRSZ + 40); -destination->length = VARHDRSZ + 40; +SET_VARSIZE(destination, VARHDRSZ + 40); memcpy(destination->data, buffer, 40); ... ]]> @@ -1793,6 +1802,8 @@ memcpy(destination->data, buffer, 40); VARHDRSZ is the same as sizeof(int4), but it's considered good style to use the macro VARHDRSZ to refer to the size of the overhead for a variable-length type. + Also, the length field must be set using the + SET_VARSIZE macro, not by simple assignment. @@ -2406,13 +2417,16 @@ concat_text(PG_FUNCTION_ARGS) - Always zero the bytes of your structures using - memset. Without this, it's difficult to + Always zero the bytes of your structures using memset + (or allocate them with palloc0 in the first place). + Even if you assign to each field of your structure, there might be + alignment padding (holes in the structure) that contain + garbage values. Without this, it's difficult to support hash indexes or hash joins, as you must pick out only the significant bits of your data structure to compute a hash. - Even if you initialize all fields of your structure, there might be - alignment padding (holes in the structure) that contain - garbage values. + The planner also sometimes relies on comparing constants via + bitwise equality, so you can get undesirable planning results if + logically-equivalent values aren't bitwise equal. -- 2.11.0