Skip to content

Commit db3cf25

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 433853e commit db3cf25

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
@@ -1680,6 +1680,15 @@ typedef struct
16801680
itself.
16811681
</para>
16821682

1683+
<para>
1684+
Another important point is to avoid leaving any uninitialized bits
1685+
within data type values; for example, take care to zero out any
1686+
alignment padding bytes that might be present in structs. Without
1687+
this, logically-equivalent constants of your data type might be
1688+
seen as unequal by the planner, leading to inefficient (though not
1689+
incorrect) plans.
1690+
</para>
1691+
16831692
<warning>
16841693
<para>
16851694
<emphasis>Never</> modify the contents of a pass-by-reference input
@@ -1723,7 +1732,7 @@ typedef struct {
17231732
char buffer[40]; /* our source data */
17241733
...
17251734
text *destination = (text *) palloc(VARHDRSZ + 40);
1726-
destination->length = VARHDRSZ + 40;
1735+
SET_VARSIZE(destination, VARHDRSZ + 40);
17271736
memcpy(destination->data, buffer, 40);
17281737
...
17291738
]]>
@@ -1732,6 +1741,8 @@ memcpy(destination->data, buffer, 40);
17321741
<literal>VARHDRSZ</> is the same as <literal>sizeof(int4)</>, but
17331742
it's considered good style to use the macro <literal>VARHDRSZ</>
17341743
to refer to the size of the overhead for a variable-length type.
1744+
Also, the length field <emphasis>must</> be set using the
1745+
<literal>SET_VARSIZE</> macro, not by simple assignment.
17351746
</para>
17361747

17371748
<para>
@@ -2345,13 +2356,16 @@ concat_text(PG_FUNCTION_ARGS)
23452356

23462357
<listitem>
23472358
<para>
2348-
Always zero the bytes of your structures using
2349-
<function>memset</function>. Without this, it's difficult to
2359+
Always zero the bytes of your structures using <function>memset</>
2360+
(or allocate them with <function>palloc0</> in the first place).
2361+
Even if you assign to each field of your structure, there might be
2362+
alignment padding (holes in the structure) that contain
2363+
garbage values. Without this, it's difficult to
23502364
support hash indexes or hash joins, as you must pick out only
23512365
the significant bits of your data structure to compute a hash.
2352-
Even if you initialize all fields of your structure, there might be
2353-
alignment padding (holes in the structure) that contain
2354-
garbage values.
2366+
The planner also sometimes relies on comparing constants via
2367+
bitwise equality, so you can get undesirable planning results if
2368+
logically-equivalent values aren't bitwise equal.
23552369
</para>
23562370
</listitem>
23572371

0 commit comments

Comments
 (0)