Home Explore Blog CI



postgresql

31th chunk of `doc/src/sgml/xfunc.sgml`
1364c508bd99d8bcc2be0d673b62254b8259de1efa1bd21d0000000100000fc1
 Construct the copy with a
     * full-length header.
     */
    text     *new_t = (text *) palloc(VARSIZE_ANY_EXHDR(t) + VARHDRSZ);
    SET_VARSIZE(new_t, VARSIZE_ANY_EXHDR(t) + VARHDRSZ);

    /*
     * VARDATA is a pointer to the data region of the new struct.  The source
     * could be a short datum, so retrieve its data through VARDATA_ANY.
     */
    memcpy(VARDATA(new_t),          /* destination */
           VARDATA_ANY(t),          /* source */
           VARSIZE_ANY_EXHDR(t));   /* how many bytes */
    PG_RETURN_TEXT_P(new_t);
}

PG_FUNCTION_INFO_V1(concat_text);

Datum
concat_text(PG_FUNCTION_ARGS)
{
    text  *arg1 = PG_GETARG_TEXT_PP(0);
    text  *arg2 = PG_GETARG_TEXT_PP(1);
    int32 arg1_size = VARSIZE_ANY_EXHDR(arg1);
    int32 arg2_size = VARSIZE_ANY_EXHDR(arg2);
    int32 new_text_size = arg1_size + arg2_size + VARHDRSZ;
    text *new_text = (text *) palloc(new_text_size);

    SET_VARSIZE(new_text, new_text_size);
    memcpy(VARDATA(new_text), VARDATA_ANY(arg1), arg1_size);
    memcpy(VARDATA(new_text) + arg1_size, VARDATA_ANY(arg2), arg2_size);
    PG_RETURN_TEXT_P(new_text);
}

/* A wrapper around starts_with(text, text) */

PG_FUNCTION_INFO_V1(t_starts_with);

Datum
t_starts_with(PG_FUNCTION_ARGS)
{
    text       *t1 = PG_GETARG_TEXT_PP(0);
    text       *t2 = PG_GETARG_TEXT_PP(1);
    Oid         collid = PG_GET_COLLATION();
    bool        result;

    result = DatumGetBool(DirectFunctionCall2Coll(text_starts_with,
                                                  collid,
                                                  PointerGetDatum(t1),
                                                  PointerGetDatum(t2)));
    PG_RETURN_BOOL(result);
}
]]>
</programlisting>

    <para>
     Supposing that the above code has been prepared in file
     <filename>funcs.c</filename> and compiled into a shared object,
     we could define the functions to <productname>PostgreSQL</productname>
     with commands like this:
    </para>

<programlisting>
CREATE FUNCTION add_one(integer) RETURNS integer
     AS '<replaceable>DIRECTORY</replaceable>/funcs', 'add_one'
     LANGUAGE C STRICT;

-- note overloading of SQL function name "add_one"
CREATE FUNCTION add_one(double precision) RETURNS double precision
     AS '<replaceable>DIRECTORY</replaceable>/funcs', 'add_one_float8'
     LANGUAGE C STRICT;

CREATE FUNCTION makepoint(point, point) RETURNS point
     AS '<replaceable>DIRECTORY</replaceable>/funcs', 'makepoint'
     LANGUAGE C STRICT;

CREATE FUNCTION copytext(text) RETURNS text
     AS '<replaceable>DIRECTORY</replaceable>/funcs', 'copytext'
     LANGUAGE C STRICT;

CREATE FUNCTION concat_text(text, text) RETURNS text
     AS '<replaceable>DIRECTORY</replaceable>/funcs', 'concat_text'
     LANGUAGE C STRICT;

CREATE FUNCTION t_starts_with(text, text) RETURNS boolean
     AS '<replaceable>DIRECTORY</replaceable>/funcs', 't_starts_with'
     LANGUAGE C STRICT;
</programlisting>

    <para>
     Here, <replaceable>DIRECTORY</replaceable> stands for the
     directory of the shared library file (for instance the
     <productname>PostgreSQL</productname> tutorial directory, which
     contains the code for the examples used in this section).
     (Better style would be to use just <literal>'funcs'</literal> in the
     <literal>AS</literal> clause, after having added
     <replaceable>DIRECTORY</replaceable> to the search path.  In any
     case, we can omit the system-specific extension for a shared
     library, commonly <literal>.so</literal>.)
    </para>

    <para>
     Notice that we have specified the functions as <quote>strict</quote>,
     meaning that
     the system should automatically assume a null result if any input
     value is null.  By doing this, we avoid having to check for null inputs
     in the function code.  Without this, we'd have to check for null values
     explicitly, using <function>PG_ARGISNULL()</function>.
    </para>

    <para>
     The macro <function>PG_ARGISNULL(<replaceable>n</replaceable>)</function>

Title: C Function Examples and SQL Definition for PostgreSQL Extensions
Summary
This section provides C code examples for PostgreSQL functions, including `copytext`, `concat_text`, and `t_starts_with` (a wrapper for `starts_with`). It illustrates how to handle text data, memory allocation, and collation in C functions. The section also shows how to define these C functions in PostgreSQL using `CREATE FUNCTION` statements, specifying the shared library path and function names. It highlights the use of the `STRICT` keyword to automatically handle null inputs, avoiding the need for explicit null checks within the C code. It then introduces the `PG_ARGISNULL()` macro.