Skip to content

Commit 4f6c75b

Browse files
committed
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.
1 parent 18c0b4e commit 4f6c75b

File tree

1 file changed

+20
-6
lines changed

1 file changed

+20
-6
lines changed

doc/src/sgml/xfunc.sgml

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1741,6 +1741,15 @@ typedef struct
17411741
itself.
17421742
</para>
17431743

1744+
<para>
1745+
Another important point is to avoid leaving any uninitialized bits
1746+
within data type values; for example, take care to zero out any
1747+
alignment padding bytes that might be present in structs. Without
1748+
this, logically-equivalent constants of your data type might be
1749+
seen as unequal by the planner, leading to inefficient (though not
1750+
incorrect) plans.
1751+
</para>
1752+
17441753
<warning>
17451754
<para>
17461755
<emphasis>Never</> modify the contents of a pass-by-reference input
@@ -1784,7 +1793,7 @@ typedef struct {
17841793
char buffer[40]; /* our source data */
17851794
...
17861795
text *destination = (text *) palloc(VARHDRSZ + 40);
1787-
destination->length = VARHDRSZ + 40;
1796+
SET_VARSIZE(destination, VARHDRSZ + 40);
17881797
memcpy(destination->data, buffer, 40);
17891798
...
17901799
]]>
@@ -1793,6 +1802,8 @@ memcpy(destination->data, buffer, 40);
17931802
<literal>VARHDRSZ</> is the same as <literal>sizeof(int4)</>, but
17941803
it's considered good style to use the macro <literal>VARHDRSZ</>
17951804
to refer to the size of the overhead for a variable-length type.
1805+
Also, the length field <emphasis>must</> be set using the
1806+
<literal>SET_VARSIZE</> macro, not by simple assignment.
17961807
</para>
17971808

17981809
<para>
@@ -2406,13 +2417,16 @@ concat_text(PG_FUNCTION_ARGS)
24062417

24072418
<listitem>
24082419
<para>
2409-
Always zero the bytes of your structures using
2410-
<function>memset</function>. Without this, it's difficult to
2420+
Always zero the bytes of your structures using <function>memset</>
2421+
(or allocate them with <function>palloc0</> in the first place).
2422+
Even if you assign to each field of your structure, there might be
2423+
alignment padding (holes in the structure) that contain
2424+
garbage values. Without this, it's difficult to
24112425
support hash indexes or hash joins, as you must pick out only
24122426
the significant bits of your data structure to compute a hash.
2413-
Even if you initialize all fields of your structure, there might be
2414-
alignment padding (holes in the structure) that contain
2415-
garbage values.
2427+
The planner also sometimes relies on comparing constants via
2428+
bitwise equality, so you can get undesirable planning results if
2429+
logically-equivalent values aren't bitwise equal.
24162430
</para>
24172431
</listitem>
24182432

0 commit comments

Comments
 (0)