Home Explore Blog CI



postgresql

5th chunk of `doc/src/sgml/ref/create_type.sgml`
b418a01c6c1f5bb4700d258c743c1aec8d5aa4d5244ea40b0000000100000fa5
 (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

Title: CREATE TYPE - Binary Representation, Shell Types, and Type Modifiers
Summary
This section details the `send_function` for converting from internal to external binary representation, complementary to the `receive_function`. It also explains the concept of a "shell type" created with `CREATE TYPE name` as a placeholder for defining I/O functions before the full type definition. The optional `type_modifier_input_function` and `type_modifier_output_function` handle type modifiers (constraints like char(5)), converting them to and from a single integer value for storage. The input function validates the modifiers, while the output function formats the modifier for user display.