(For example, the standard integer data types use network
byte order as the external binary representation, while the internal
representation is in the machine's native byte order.) The receive
function should perform adequate checking to ensure that the value is
valid.
The receive function can be declared as taking one argument of type
<type>internal</type>, or as taking three arguments of types
<type>internal</type>, <type>oid</type>, <type>integer</type>.
The first argument is a pointer to a <type>StringInfo</type> buffer
holding the received byte string; the optional arguments are the
same as for the text input function.
The receive function must return a value of the data type itself.
Usually, a receive function should be declared STRICT; if it is not,
it will be called with a NULL first parameter when reading a NULL
input value. The function must still return NULL in this case, unless
it raises an error.
(This case is mainly meant to support domain receive functions, which
might need to reject NULL inputs.)
Similarly, the optional
<replaceable class="parameter">send_function</replaceable> converts
from the internal representation to the external binary representation.
If this function is not supplied, the type cannot participate in binary
output. The send function must be
declared as taking one argument of the new data type.
The send function must return type <type>bytea</type>.
Send functions are not invoked for NULL values.
</para>
<para>
You should at this point be wondering how the input and output functions
can be declared to have results or arguments of the new type, when they
have to be created before the new type can be created. The answer is that
the type should first be defined as a <firstterm>shell type</firstterm>, which is a
placeholder type that has no properties except a name and an owner. This
is done by issuing the command <literal>CREATE TYPE
<replaceable>name</replaceable></literal>, with no additional parameters. Then the
C I/O functions can be defined referencing the shell type. Finally,
<command>CREATE TYPE</command> with a full definition replaces the shell entry
with a complete, valid type definition, after which the new type can be
used normally.
</para>
<para>
The optional
<replaceable class="parameter">type_modifier_input_function</replaceable>
and <replaceable class="parameter">type_modifier_output_function</replaceable>
are needed if the type supports modifiers, that is optional constraints
attached to a type declaration, such as <literal>char(5)</literal> or
<literal>numeric(30,2)</literal>. <productname>PostgreSQL</productname> allows
user-defined types to take one or more simple constants or identifiers as
modifiers. However, this information must be capable of being packed into a
single non-negative integer value for storage in the system catalogs. The
<replaceable class="parameter">type_modifier_input_function</replaceable>
is passed the declared modifier(s) in the form of a <type>cstring</type>
array. It must check the values for validity (throwing an error if they
are wrong), and if they are correct, return a single non-negative
<type>integer</type> value that will be stored as the column <quote>typmod</quote>.
Type modifiers will be rejected if the type does not have a
<replaceable class="parameter">type_modifier_input_function</replaceable>.
The <replaceable class="parameter">type_modifier_output_function</replaceable>
converts the internal integer typmod value back to the correct form for
user display. It must return a <type>cstring</type> value that is the exact
string to append to the type name; for example <type>numeric</type>'s
function might return <literal>(30,2)</literal>.
It is allowed to omit the
<replaceable class="parameter">type_modifier_output_function</replaceable>,
in which