From 1651b7bb68e0f9c2b61e1462367295d846d253ec Mon Sep 17 00:00:00 2001
From: Florents Tselai <florents.tselai@gmail.com>
Date: Thu, 12 Sep 2024 12:23:13 +0300
Subject: [PATCH v2 1/2] Add some documentation on how to call internal
 functions

---
 doc/src/sgml/xfunc.sgml | 51 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 51 insertions(+)

diff --git a/doc/src/sgml/xfunc.sgml b/doc/src/sgml/xfunc.sgml
index af7864a1b5..eb26120def 100644
--- a/doc/src/sgml/xfunc.sgml
+++ b/doc/src/sgml/xfunc.sgml
@@ -2384,6 +2384,36 @@ PG_FUNCTION_INFO_V1(funcname);
      takes as its argument the actual value to return.
     </para>
 
+    <para>
+    To call another version-1 function, you can use
+    <function>DirectFunctionCall<replaceable>n</replaceable>(func, arg1,...,argn)</function>.
+    This is particularly useful when you want to call functions defined in the standard internal library,
+    by using an interface similar to their SQL signature.
+    </para>
+
+    <para>
+    Different flavors of similar macros can be found in <filename>fmgr.h</filename>.
+    The main point though is that they expect a C function name to call as their first argument
+    (or its <literal>Oid</literal> in some cases),
+    and actual arguments should be supplied as <literal>Datum</literal>s.
+    They always return <literal>Datum</literal>.
+    </para>
+
+    <para>
+    For example, to call the <function>starts_with(text, text) </function> from C,
+    you can search through the catalog and find out that its C implementation is based on the
+    <function>Datum text_starts_with(PG_FUNCTION_ARGS)</function> function.
+    </para>
+
+    <para>
+    In <filename>fmgr.h</filename> there are also available macros the facilitate conversions
+    between C types and <literal>Datum</literal>.
+    For example to turn <literal>text*</literal> into <literal>Datum</literal>,
+    you can use <function>DatumGetTextPP(X)</function>.
+    If your extension defines additional types,
+    it is usually convenient to define similar macros for these types too.
+    </para>
+
     <para>
      Here are some examples using the version-1 calling convention:
     </para>
@@ -2482,6 +2512,23 @@ concat_text(PG_FUNCTION_ARGS)
     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)
+{
+    Datum t1 = PG_GETARG_DATUM(0);
+    Datum t2 = PG_GETARG_DATUM(1);
+    bool  bool_res;
+
+    Datum datum_res = DirectFunctionCall2(text_starts_with, t1, t2);
+    bool_res = DatumGetBool(datum_res);
+
+    PG_RETURN_BOOL(bool_res);
+}
 ]]>
 </programlisting>
 
@@ -2513,6 +2560,10 @@ CREATE FUNCTION copytext(text) RETURNS text
 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>
-- 
2.39.5 (Apple Git-154)

