{"Entry":{"collection":"language","key":"c","name":"c","aliases":[],"metadata":{"aliases":[],"category":"Native function languages","content_hash":"63eafefed998c086fab28cdf7d914b086ce0b886fbe441f4dd96924da93b915b","imported_at":"2026-09-30T00:40:44.289863+08:00","name":"c","name_zh":"","slug":"c","summary":"dynamically-loaded C functions"}},"Definition":{"Collection":"language","Key":"c","SourceDatabase":"center","Version":"18","SourceTable":"procedural_language","SourceKey":"c","SourceRevision":"555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f","Facts":{"aliases":[],"attributes":{"handler":"","kind":"Native function language","trusted":"f","validator":"fmgr_c_validator"},"catalog":{"descr":"dynamically-loaded C functions","lanacl":"_null_","laninline":"0","lanispl":"f","lanname":"c","lanowner":"POSTGRES","lanplcallfoid":"0","lanpltrusted":"f","lanvalidator":"fmgr_c_validator","oid":"13","oid_symbol":"ClanguageId"},"comparison_data":{"handler":"","kind":"Native function language","trusted":"f","validator":"fmgr_c_validator"},"comparison_hash":"e8a219c1a26602affef41a21da26d099cf721ba42739cb7b056898c9e2d6fbe6","description":["dynamically-loaded C functions"],"facts":[{"label":"Kind","value":"Native function language"},{"label":"Trusted","value":"f"},{"label":"Validator","value":"fmgr_c_validator"}],"manual_html":"\u003cdiv class=\"sect1\" id=\"XFUNC-C\"\u003e\n\u003cdiv class=\"titlepage\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch2 class=\"title\"\u003e36.10. C-Language Functions \u003c/h2\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\n\u003cp\u003eUser-defined functions can be written in C (or a language that can be made compatible with C, such as C++). Such functions are compiled into dynamically loadable objects (also called shared libraries) and are loaded by the server on demand. The dynamic loading feature is what distinguishes \u003cspan class=\"quote\"\u003e“\u003cspan class=\"quote\"\u003eC language\u003c/span\u003e”\u003c/span\u003e functions from \u003cspan class=\"quote\"\u003e“\u003cspan class=\"quote\"\u003einternal\u003c/span\u003e”\u003c/span\u003e functions — the actual coding conventions are essentially the same for both. (Hence, the standard internal function library is a rich source of coding examples for user-defined C functions.)\u003c/p\u003e\n\u003cp\u003eCurrently only one calling convention is used for C functions (\u003cspan class=\"quote\"\u003e“\u003cspan class=\"quote\"\u003eversion 1\u003c/span\u003e”\u003c/span\u003e). Support for that calling convention is indicated by writing a \u003ccode class=\"literal\"\u003ePG_FUNCTION_INFO_V1()\u003c/code\u003e macro call for the function, as illustrated below.\u003c/p\u003e\n\u003cdiv class=\"sect2\" id=\"XFUNC-C-DYNLOAD\"\u003e\n\u003cdiv class=\"titlepage\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch3 class=\"title\"\u003e36.10.1. Dynamic Loading \u003c/h3\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003eThe first time a user-defined function in a particular loadable object file is called in a session, the dynamic loader loads that object file into memory so that the function can be called. The \u003ccode class=\"command\"\u003eCREATE FUNCTION\u003c/code\u003e for a user-defined C function must therefore specify two pieces of information for the function: the name of the loadable object file, and the C name (link symbol) of the specific function to call within that object file. If the C name is not explicitly specified then it is assumed to be the same as the SQL function name.\u003c/p\u003e\n\u003cp\u003eThe following algorithm is used to locate the shared object file based on the name given in the \u003ccode class=\"command\"\u003eCREATE FUNCTION\u003c/code\u003e command:\u003c/p\u003e\n\u003cdiv class=\"orderedlist\"\u003e\n\u003col class=\"orderedlist\"\u003e\n\u003cli class=\"listitem\"\u003e\n\u003cp\u003eIf the name is an absolute path, the given file is loaded.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli class=\"listitem\"\u003e\n\u003cp\u003eIf the name starts with the string \u003ccode class=\"literal\"\u003e$libdir\u003c/code\u003e, that part is replaced by the \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e package library directory name, which is determined at build time.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli class=\"listitem\"\u003e\n\u003cp\u003eIf the name does not contain a directory part, the file is searched for in the path specified by the configuration variable \u003ca class=\"xref\" href=\"/docs/18/runtime-config-client.html#GUC-DYNAMIC-LIBRARY-PATH\"\u003edynamic_library_path\u003c/a\u003e.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli class=\"listitem\"\u003e\n\u003cp\u003eOtherwise (the file was not found in the path, or it contains a non-absolute directory part), the dynamic loader will try to take the name as given, which will most likely fail. (It is unreliable to depend on the current working directory.)\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/div\u003e\n\u003cp\u003eIf this sequence does not work, the platform-specific shared library file name extension (often \u003ccode class=\"filename\"\u003e.so\u003c/code\u003e) is appended to the given name and this sequence is tried again. If that fails as well, the load will fail.\u003c/p\u003e\n\u003cp\u003eIt is recommended to locate shared libraries either relative to \u003ccode class=\"literal\"\u003e$libdir\u003c/code\u003e or through the dynamic library path. This simplifies version upgrades if the new installation is at a different location. The actual directory that \u003ccode class=\"literal\"\u003e$libdir\u003c/code\u003e stands for can be found out with the command \u003ccode class=\"literal\"\u003epg_config --pkglibdir\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003eThe user ID the \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e server runs as must be able to traverse the path to the file you intend to load. Making the file or a higher-level directory not readable and/or not executable by the \u003cspan class=\"systemitem\"\u003epostgres\u003c/span\u003e user is a common mistake.\u003c/p\u003e\n\u003cp\u003eIn any case, the file name that is given in the \u003ccode class=\"command\"\u003eCREATE FUNCTION\u003c/code\u003e command is recorded literally in the system catalogs, so if the file needs to be loaded again the same procedure is applied.\u003c/p\u003e\n\u003cdiv class=\"note\"\u003e\n\u003ch3 class=\"title\"\u003eNote\u003c/h3\u003e\n\u003cp\u003e\u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e will not compile a C function automatically. The object file must be compiled before it is referenced in a \u003ccode class=\"command\"\u003eCREATE FUNCTION\u003c/code\u003e command. See \u003ca class=\"xref\" href=\"/docs/18/xfunc-c.html#DFUNC\" title=\"36.10.5. Compiling and Linking Dynamically-Loaded Functions\"\u003eSection 36.10.5\u003c/a\u003e for additional information.\u003c/p\u003e\n\u003c/div\u003e\n\u003cp\u003eTo ensure that a dynamically loaded object file is not loaded into an incompatible server, \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e checks that the file contains a \u003cspan class=\"quote\"\u003e“\u003cspan class=\"quote\"\u003emagic block\u003c/span\u003e”\u003c/span\u003e with the appropriate contents. This allows the server to detect obvious incompatibilities, such as code compiled for a different major version of \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e. To include a magic block, write this in one (and only one) of the module source files, after having included the header \u003ccode class=\"filename\"\u003efmgr.h\u003c/code\u003e:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003ePG_MODULE_MAGIC;\n\u003c/pre\u003e\n\u003cp\u003eor\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003ePG_MODULE_MAGIC_EXT(\u003cem class=\"replaceable\"\u003e\u003ccode\u003eparameters\u003c/code\u003e\u003c/em\u003e);\n\u003c/pre\u003e\n\u003cp\u003eThe \u003ccode class=\"literal\"\u003ePG_MODULE_MAGIC_EXT\u003c/code\u003e variant allows the specification of additional information about the module; currently, a name and/or a version string can be added. (More fields might be allowed in future.) Write something like this:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003ePG_MODULE_MAGIC_EXT(\n    .name = \"my_module_name\",\n    .version = \"1.2.3\"\n);\n\u003c/pre\u003e\n\u003cp\u003eSubsequently the name and version can be examined via the \u003ccode class=\"function\"\u003epg_get_loaded_modules()\u003c/code\u003e function. The meaning of the version string is not restricted by \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e, but use of semantic versioning rules is recommended.\u003c/p\u003e\n\u003cp\u003eAfter it is used for the first time, a dynamically loaded object file is retained in memory. Future calls in the same session to the function(s) in that file will only incur the small overhead of a symbol table lookup. If you need to force a reload of an object file, for example after recompiling it, begin a fresh session.\u003c/p\u003e\n\u003cp\u003eOptionally, a dynamically loaded file can contain an initialization function. If the file includes a function named \u003ccode class=\"function\"\u003e_PG_init\u003c/code\u003e, that function will be called immediately after loading the file. The function receives no parameters and should return void. There is presently no way to unload a dynamically loaded file.\u003c/p\u003e\n\u003c/div\u003e\n\u003cdiv class=\"sect2\" id=\"XFUNC-C-BASETYPE\"\u003e\n\u003cdiv class=\"titlepage\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch3 class=\"title\"\u003e36.10.2. Base Types in C-Language Functions \u003c/h3\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003eTo know how to write C-language functions, you need to know how \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e internally represents base data types and how they can be passed to and from functions. Internally, \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e regards a base type as a \u003cspan class=\"quote\"\u003e“\u003cspan class=\"quote\"\u003eblob of memory\u003c/span\u003e”\u003c/span\u003e. The user-defined functions that you define over a type in turn define the way that \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e can operate on it. That is, \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e will only store and retrieve the data from disk and use your user-defined functions to input, process, and output the data.\u003c/p\u003e\n\u003cp\u003eBase types can have one of three internal formats:\u003c/p\u003e\n\u003cdiv class=\"itemizedlist\"\u003e\n\u003cul class=\"itemizedlist\"\u003e\n\u003cli class=\"listitem\"\u003e\n\u003cp\u003epass by value, fixed-length\u003c/p\u003e\n\u003c/li\u003e\n\u003cli class=\"listitem\"\u003e\n\u003cp\u003epass by reference, fixed-length\u003c/p\u003e\n\u003c/li\u003e\n\u003cli class=\"listitem\"\u003e\n\u003cp\u003epass by reference, variable-length\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/div\u003e\n\u003cp\u003eBy-value types can only be 1, 2, or 4 bytes in length (also 8 bytes, if \u003ccode class=\"literal\"\u003esizeof(Datum)\u003c/code\u003e is 8 on your machine). You should be careful to define your types such that they will be the same size (in bytes) on all architectures. For example, the \u003ccode class=\"literal\"\u003elong\u003c/code\u003e type is dangerous because it is 4 bytes on some machines and 8 bytes on others, whereas \u003ccode class=\"type\"\u003eint\u003c/code\u003e type is 4 bytes on most Unix machines. A reasonable implementation of the \u003ccode class=\"type\"\u003eint4\u003c/code\u003e type on Unix machines might be:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003e/* 4-byte integer, passed by value */\ntypedef int int4;\n\u003c/pre\u003e\n\u003cp\u003e(The actual PostgreSQL C code calls this type \u003ccode class=\"type\"\u003eint32\u003c/code\u003e, because it is a convention in C that \u003ccode class=\"type\"\u003eint\u003cem class=\"replaceable\"\u003e\u003ccode\u003eXX\u003c/code\u003e\u003c/em\u003e\u003c/code\u003e means \u003cem class=\"replaceable\"\u003e\u003ccode\u003eXX\u003c/code\u003e\u003c/em\u003e \u003cspan class=\"emphasis\"\u003e\u003cem\u003ebits\u003c/em\u003e\u003c/span\u003e. Note therefore also that the C type \u003ccode class=\"type\"\u003eint8\u003c/code\u003e is 1 byte in size. The SQL type \u003ccode class=\"type\"\u003eint8\u003c/code\u003e is called \u003ccode class=\"type\"\u003eint64\u003c/code\u003e in C. See also \u003ca class=\"xref\" href=\"/docs/18/xfunc-c.html#XFUNC-C-TYPE-TABLE\" title=\"Table 36.2. Equivalent C Types for Built-in SQL Types\"\u003eTable 36.2\u003c/a\u003e.)\u003c/p\u003e\n\u003cp\u003eOn the other hand, fixed-length types of any size can be passed by-reference. For example, here is a sample implementation of a \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e type:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003e/* 16-byte structure, passed by reference */\ntypedef struct\n{\n    double  x, y;\n} Point;\n\u003c/pre\u003e\n\u003cp\u003eOnly pointers to such types can be used when passing them in and out of \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e functions. To return a value of such a type, allocate the right amount of memory with \u003ccode class=\"literal\"\u003epalloc\u003c/code\u003e, fill in the allocated memory, and return a pointer to it. (Also, if you just want to return the same value as one of your input arguments that's of the same data type, you can skip the extra \u003ccode class=\"literal\"\u003epalloc\u003c/code\u003e and just return the pointer to the input value.)\u003c/p\u003e\n\u003cp\u003eFinally, all variable-length types must also be passed by reference. All variable-length types must begin with an opaque length field of exactly 4 bytes, which will be set by \u003ccode class=\"symbol\"\u003eSET_VARSIZE\u003c/code\u003e; never set this field directly! All data to be stored within that type must be located in the memory immediately following that length field. The length field contains the total length of the structure, that is, it includes the size of the length field itself.\u003c/p\u003e\n\u003cp\u003eAnother important point is to avoid leaving any uninitialized bits within data type values; for example, take care to zero out any alignment padding bytes that might be present in structs. Without this, logically-equivalent constants of your data type might be seen as unequal by the planner, leading to inefficient (though not incorrect) plans.\u003c/p\u003e\n\u003cdiv class=\"warning\"\u003e\n\u003ch3 class=\"title\"\u003eWarning\u003c/h3\u003e\n\u003cp\u003e\u003cspan class=\"emphasis\"\u003e\u003cem\u003eNever\u003c/em\u003e\u003c/span\u003e modify the contents of a pass-by-reference input value. If you do so you are likely to corrupt on-disk data, since the pointer you are given might point directly into a disk buffer. The sole exception to this rule is explained in \u003ca class=\"xref\" href=\"/docs/18/xaggr.html\" title=\"36.12. User-Defined Aggregates\"\u003eSection 36.12\u003c/a\u003e.\u003c/p\u003e\n\u003c/div\u003e\n\u003cp\u003eAs an example, we can define the type \u003ccode class=\"type\"\u003etext\u003c/code\u003e as follows:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003etypedef struct {\n    int32 length;\n    char data[FLEXIBLE_ARRAY_MEMBER];\n} text;\n\u003c/pre\u003e\n\u003cp\u003eThe \u003ccode class=\"literal\"\u003e[FLEXIBLE_ARRAY_MEMBER]\u003c/code\u003e notation means that the actual length of the data part is not specified by this declaration.\u003c/p\u003e\n\u003cp\u003eWhen manipulating variable-length types, we must be careful to allocate the correct amount of memory and set the length field correctly. For example, if we wanted to store 40 bytes in a \u003ccode class=\"structname\"\u003etext\u003c/code\u003e structure, we might use a code fragment like this:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003e#include \"postgres.h\"\n...\nchar buffer[40]; /* our source data */\n...\ntext *destination = (text *) palloc(VARHDRSZ + 40);\nSET_VARSIZE(destination, VARHDRSZ + 40);\nmemcpy(destination-\u0026gt;data, buffer, 40);\n...\n\n\u003c/pre\u003e\n\u003cp\u003e\u003ccode class=\"literal\"\u003eVARHDRSZ\u003c/code\u003e is the same as \u003ccode class=\"literal\"\u003esizeof(int32)\u003c/code\u003e, but it's considered good style to use the macro \u003ccode class=\"literal\"\u003eVARHDRSZ\u003c/code\u003e to refer to the size of the overhead for a variable-length type. Also, the length field \u003cspan class=\"emphasis\"\u003e\u003cem\u003emust\u003c/em\u003e\u003c/span\u003e be set using the \u003ccode class=\"literal\"\u003eSET_VARSIZE\u003c/code\u003e macro, not by simple assignment.\u003c/p\u003e\n\u003cp\u003e\u003ca class=\"xref\" href=\"/docs/18/xfunc-c.html#XFUNC-C-TYPE-TABLE\" title=\"Table 36.2. Equivalent C Types for Built-in SQL Types\"\u003eTable 36.2\u003c/a\u003e shows the C types corresponding to many of the built-in SQL data types of \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e. The \u003cspan class=\"quote\"\u003e“\u003cspan class=\"quote\"\u003eDefined In\u003c/span\u003e”\u003c/span\u003e column gives the header file that needs to be included to get the type definition. (The actual definition might be in a different file that is included by the listed file. It is recommended that users stick to the defined interface.) Note that you should always include \u003ccode class=\"filename\"\u003epostgres.h\u003c/code\u003e first in any source file of server code, because it declares a number of things that you will need anyway, and because including other headers first can cause portability issues.\u003c/p\u003e\n\u003cdiv class=\"table\" id=\"XFUNC-C-TYPE-TABLE\"\u003e\n\u003cp class=\"title\"\u003e\u003cstrong\u003eTable 36.2. Equivalent C Types for Built-in SQL Types\u003c/strong\u003e\u003c/p\u003e\n\u003cdiv class=\"table-contents\"\u003e\n\u003ctable class=\"table\"\u003e\n\n\n\n\n\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003eSQL Type\u003c/th\u003e\n\u003cth\u003eC Type\u003c/th\u003e\n\u003cth\u003eDefined In\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003eboolean\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003ebool\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"filename\"\u003epostgres.h\u003c/code\u003e (maybe compiler built-in)\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003ebox\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003eBOX*\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"filename\"\u003eutils/geo_decls.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003ebytea\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003ebytea*\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"filename\"\u003epostgres.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003e\"char\"\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003echar\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e(compiler built-in)\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003echaracter\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003eBpChar*\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"filename\"\u003epostgres.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003ecid\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003eCommandId\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"filename\"\u003epostgres.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003edate\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003eDateADT\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"filename\"\u003eutils/date.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003efloat4\u003c/code\u003e (\u003ccode class=\"type\"\u003ereal\u003c/code\u003e)\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003efloat4\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"filename\"\u003epostgres.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003efloat8\u003c/code\u003e (\u003ccode class=\"type\"\u003edouble precision\u003c/code\u003e)\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003efloat8\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"filename\"\u003epostgres.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003eint2\u003c/code\u003e (\u003ccode class=\"type\"\u003esmallint\u003c/code\u003e)\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003eint16\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"filename\"\u003epostgres.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003eint4\u003c/code\u003e (\u003ccode class=\"type\"\u003einteger\u003c/code\u003e)\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003eint32\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"filename\"\u003epostgres.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003eint8\u003c/code\u003e (\u003ccode class=\"type\"\u003ebigint\u003c/code\u003e)\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003eint64\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"filename\"\u003epostgres.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003einterval\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003eInterval*\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"filename\"\u003edatatype/timestamp.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003elseg\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003eLSEG*\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"filename\"\u003eutils/geo_decls.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003ename\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003eName\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"filename\"\u003epostgres.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003enumeric\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003eNumeric\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"filename\"\u003eutils/numeric.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003eoid\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003eOid\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"filename\"\u003epostgres.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003eoidvector\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003eoidvector*\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"filename\"\u003epostgres.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003epath\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003ePATH*\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"filename\"\u003eutils/geo_decls.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003epoint\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003ePOINT*\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"filename\"\u003eutils/geo_decls.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003eregproc\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003eRegProcedure\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"filename\"\u003epostgres.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003etext\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003etext*\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"filename\"\u003epostgres.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003etid\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003eItemPointer\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"filename\"\u003estorage/itemptr.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003etime\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003eTimeADT\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"filename\"\u003eutils/date.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003etime with time zone\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003eTimeTzADT\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"filename\"\u003eutils/date.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003etimestamp\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003eTimestamp\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"filename\"\u003edatatype/timestamp.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003etimestamp with time zone\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003eTimestampTz\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"filename\"\u003edatatype/timestamp.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003evarchar\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003eVarChar*\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"filename\"\u003epostgres.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003exid\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003eTransactionId\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"filename\"\u003epostgres.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e\u003cbr class=\"table-break\"\u003e\n\u003cp\u003eNow that we've gone over all of the possible structures for base types, we can show some examples of real functions.\u003c/p\u003e\n\u003c/div\u003e\n\u003cdiv class=\"sect2\" id=\"XFUNC-C-V1-CALL-CONV\"\u003e\n\u003cdiv class=\"titlepage\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch3 class=\"title\"\u003e36.10.3. Version 1 Calling Conventions \u003c/h3\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003eThe version-1 calling convention relies on macros to suppress most of the complexity of passing arguments and results. The C declaration of a version-1 function is always:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003eDatum funcname(PG_FUNCTION_ARGS)\n\u003c/pre\u003e\n\u003cp\u003eIn addition, the macro call:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003ePG_FUNCTION_INFO_V1(funcname);\n\u003c/pre\u003e\n\u003cp\u003emust appear in the same source file. (Conventionally, it's written just before the function itself.) This macro call is not needed for \u003ccode class=\"literal\"\u003einternal\u003c/code\u003e-language functions, since \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e assumes that all internal functions use the version-1 convention. It is, however, required for dynamically-loaded functions.\u003c/p\u003e\n\u003cp\u003eIn a version-1 function, each actual argument is fetched using a \u003ccode class=\"function\"\u003ePG_GETARG_\u003cem class=\"replaceable\"\u003e\u003ccode\u003exxx\u003c/code\u003e\u003c/em\u003e()\u003c/code\u003e macro that corresponds to the argument's data type. (In non-strict functions there needs to be a previous check about argument null-ness using \u003ccode class=\"function\"\u003ePG_ARGISNULL()\u003c/code\u003e; see below.) The result is returned using a \u003ccode class=\"function\"\u003ePG_RETURN_\u003cem class=\"replaceable\"\u003e\u003ccode\u003exxx\u003c/code\u003e\u003c/em\u003e()\u003c/code\u003e macro for the return type. \u003ccode class=\"function\"\u003ePG_GETARG_\u003cem class=\"replaceable\"\u003e\u003ccode\u003exxx\u003c/code\u003e\u003c/em\u003e()\u003c/code\u003e takes as its argument the number of the function argument to fetch, where the count starts at 0. \u003ccode class=\"function\"\u003ePG_RETURN_\u003cem class=\"replaceable\"\u003e\u003ccode\u003exxx\u003c/code\u003e\u003c/em\u003e()\u003c/code\u003e takes as its argument the actual value to return.\u003c/p\u003e\n\u003cp\u003eTo call another version-1 function, you can use \u003ccode class=\"function\"\u003eDirectFunctionCall\u003cem class=\"replaceable\"\u003e\u003ccode\u003en\u003c/code\u003e\u003c/em\u003e(func, arg1, ..., argn)\u003c/code\u003e. 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.\u003c/p\u003e\n\u003cp\u003eThese convenience functions and similar ones can be found in \u003ccode class=\"filename\"\u003efmgr.h\u003c/code\u003e. The \u003ccode class=\"function\"\u003eDirectFunctionCall\u003cem class=\"replaceable\"\u003e\u003ccode\u003en\u003c/code\u003e\u003c/em\u003e\u003c/code\u003e family expect a C function name as their first argument. There are also \u003ccode class=\"function\"\u003eOidFunctionCall\u003cem class=\"replaceable\"\u003e\u003ccode\u003en\u003c/code\u003e\u003c/em\u003e\u003c/code\u003e which take the OID of the target function, and some other variants. All of these expect the function's arguments to be supplied as \u003ccode class=\"type\"\u003eDatum\u003c/code\u003es, and likewise they return \u003ccode class=\"type\"\u003eDatum\u003c/code\u003e. Note that neither arguments nor result are allowed to be NULL when using these convenience functions.\u003c/p\u003e\n\u003cp\u003eFor example, to call the \u003ccode class=\"function\"\u003estarts_with(text, text)\u003c/code\u003e function from C, you can search through the catalog and find out that its C implementation is the \u003ccode class=\"function\"\u003eDatum text_starts_with(PG_FUNCTION_ARGS)\u003c/code\u003e function. Typically you would use \u003ccode class=\"literal\"\u003eDirectFunctionCall2(text_starts_with, ...)\u003c/code\u003e to call such a function. However, \u003ccode class=\"function\"\u003estarts_with(text, text)\u003c/code\u003e requires collation information, so it will fail with \u003cspan class=\"quote\"\u003e“\u003cspan class=\"quote\"\u003ecould not determine which collation to use for string comparison\u003c/span\u003e”\u003c/span\u003e if called that way. Instead you must use \u003ccode class=\"literal\"\u003eDirectFunctionCall2Coll(text_starts_with, ...)\u003c/code\u003e and provide the desired collation, which typically is just passed through from \u003ccode class=\"function\"\u003ePG_GET_COLLATION()\u003c/code\u003e, as shown in the example below.\u003c/p\u003e\n\u003cp\u003e\u003ccode class=\"filename\"\u003efmgr.h\u003c/code\u003e also supplies macros that facilitate conversions between C types and \u003ccode class=\"type\"\u003eDatum\u003c/code\u003e. For example to turn \u003ccode class=\"type\"\u003eDatum\u003c/code\u003e into \u003ccode class=\"type\"\u003etext*\u003c/code\u003e, you can use \u003ccode class=\"function\"\u003eDatumGetTextPP(X)\u003c/code\u003e. While some types have macros named like \u003ccode class=\"function\"\u003eTypeGetDatum(X)\u003c/code\u003e for the reverse conversion, \u003ccode class=\"type\"\u003etext*\u003c/code\u003e does not; it's sufficient to use the generic macro \u003ccode class=\"function\"\u003ePointerGetDatum(X)\u003c/code\u003e for that. If your extension defines additional types, it is usually convenient to define similar macros for your types too.\u003c/p\u003e\n\u003cp\u003eHere are some examples using the version-1 calling convention:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003e#include \"postgres.h\"\n#include \u0026lt;string.h\u0026gt;\n#include \"fmgr.h\"\n#include \"utils/geo_decls.h\"\n#include \"varatt.h\"\n\nPG_MODULE_MAGIC;\n\n/* by value */\n\nPG_FUNCTION_INFO_V1(add_one);\n\nDatum\nadd_one(PG_FUNCTION_ARGS)\n{\n    int32   arg = PG_GETARG_INT32(0);\n\n    PG_RETURN_INT32(arg + 1);\n}\n\n/* by reference, fixed length */\n\nPG_FUNCTION_INFO_V1(add_one_float8);\n\nDatum\nadd_one_float8(PG_FUNCTION_ARGS)\n{\n    /* The macros for FLOAT8 hide its pass-by-reference nature. */\n    float8   arg = PG_GETARG_FLOAT8(0);\n\n    PG_RETURN_FLOAT8(arg + 1.0);\n}\n\nPG_FUNCTION_INFO_V1(makepoint);\n\nDatum\nmakepoint(PG_FUNCTION_ARGS)\n{\n    /* Here, the pass-by-reference nature of Point is not hidden. */\n    Point     *pointx = PG_GETARG_POINT_P(0);\n    Point     *pointy = PG_GETARG_POINT_P(1);\n    Point     *new_point = (Point *) palloc(sizeof(Point));\n\n    new_point-\u0026gt;x = pointx-\u0026gt;x;\n    new_point-\u0026gt;y = pointy-\u0026gt;y;\n\n    PG_RETURN_POINT_P(new_point);\n}\n\n/* by reference, variable length */\n\nPG_FUNCTION_INFO_V1(copytext);\n\nDatum\ncopytext(PG_FUNCTION_ARGS)\n{\n    text     *t = PG_GETARG_TEXT_PP(0);\n\n    /*\n     * VARSIZE_ANY_EXHDR is the size of the struct in bytes, minus the\n     * VARHDRSZ or VARHDRSZ_SHORT of its header.  Construct the copy with a\n     * full-length header.\n     */\n    text     *new_t = (text *) palloc(VARSIZE_ANY_EXHDR(t) + VARHDRSZ);\n    SET_VARSIZE(new_t, VARSIZE_ANY_EXHDR(t) + VARHDRSZ);\n\n    /*\n     * VARDATA is a pointer to the data region of the new struct.  The source\n     * could be a short datum, so retrieve its data through VARDATA_ANY.\n     */\n    memcpy(VARDATA(new_t),          /* destination */\n           VARDATA_ANY(t),          /* source */\n           VARSIZE_ANY_EXHDR(t));   /* how many bytes */\n    PG_RETURN_TEXT_P(new_t);\n}\n\nPG_FUNCTION_INFO_V1(concat_text);\n\nDatum\nconcat_text(PG_FUNCTION_ARGS)\n{\n    text  *arg1 = PG_GETARG_TEXT_PP(0);\n    text  *arg2 = PG_GETARG_TEXT_PP(1);\n    int32 arg1_size = VARSIZE_ANY_EXHDR(arg1);\n    int32 arg2_size = VARSIZE_ANY_EXHDR(arg2);\n    int32 new_text_size = arg1_size + arg2_size + VARHDRSZ;\n    text *new_text = (text *) palloc(new_text_size);\n\n    SET_VARSIZE(new_text, new_text_size);\n    memcpy(VARDATA(new_text), VARDATA_ANY(arg1), arg1_size);\n    memcpy(VARDATA(new_text) + arg1_size, VARDATA_ANY(arg2), arg2_size);\n    PG_RETURN_TEXT_P(new_text);\n}\n\n/* A wrapper around starts_with(text, text) */\n\nPG_FUNCTION_INFO_V1(t_starts_with);\n\nDatum\nt_starts_with(PG_FUNCTION_ARGS)\n{\n    text       *t1 = PG_GETARG_TEXT_PP(0);\n    text       *t2 = PG_GETARG_TEXT_PP(1);\n    Oid         collid = PG_GET_COLLATION();\n    bool        result;\n\n    result = DatumGetBool(DirectFunctionCall2Coll(text_starts_with,\n                                                  collid,\n                                                  PointerGetDatum(t1),\n                                                  PointerGetDatum(t2)));\n    PG_RETURN_BOOL(result);\n}\n\n\u003c/pre\u003e\n\u003cp\u003eSupposing that the above code has been prepared in file \u003ccode class=\"filename\"\u003efuncs.c\u003c/code\u003e and compiled into a shared object, we could define the functions to \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e with commands like this:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003eCREATE FUNCTION add_one(integer) RETURNS integer\n     AS '\u003cem class=\"replaceable\"\u003e\u003ccode\u003eDIRECTORY\u003c/code\u003e\u003c/em\u003e/funcs', 'add_one'\n     LANGUAGE C STRICT;\n\n-- note overloading of SQL function name \"add_one\"\nCREATE FUNCTION add_one(double precision) RETURNS double precision\n     AS '\u003cem class=\"replaceable\"\u003e\u003ccode\u003eDIRECTORY\u003c/code\u003e\u003c/em\u003e/funcs', 'add_one_float8'\n     LANGUAGE C STRICT;\n\nCREATE FUNCTION makepoint(point, point) RETURNS point\n     AS '\u003cem class=\"replaceable\"\u003e\u003ccode\u003eDIRECTORY\u003c/code\u003e\u003c/em\u003e/funcs', 'makepoint'\n     LANGUAGE C STRICT;\n\nCREATE FUNCTION copytext(text) RETURNS text\n     AS '\u003cem class=\"replaceable\"\u003e\u003ccode\u003eDIRECTORY\u003c/code\u003e\u003c/em\u003e/funcs', 'copytext'\n     LANGUAGE C STRICT;\n\nCREATE FUNCTION concat_text(text, text) RETURNS text\n     AS '\u003cem class=\"replaceable\"\u003e\u003ccode\u003eDIRECTORY\u003c/code\u003e\u003c/em\u003e/funcs', 'concat_text'\n     LANGUAGE C STRICT;\n\nCREATE FUNCTION t_starts_with(text, text) RETURNS boolean\n     AS '\u003cem class=\"replaceable\"\u003e\u003ccode\u003eDIRECTORY\u003c/code\u003e\u003c/em\u003e/funcs', 't_starts_with'\n     LANGUAGE C STRICT;\n\u003c/pre\u003e\n\u003cp\u003eHere, \u003cem class=\"replaceable\"\u003e\u003ccode\u003eDIRECTORY\u003c/code\u003e\u003c/em\u003e stands for the directory of the shared library file (for instance the \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e tutorial directory, which contains the code for the examples used in this section). (Better style would be to use just \u003ccode class=\"literal\"\u003e'funcs'\u003c/code\u003e in the \u003ccode class=\"literal\"\u003eAS\u003c/code\u003e clause, after having added \u003cem class=\"replaceable\"\u003e\u003ccode\u003eDIRECTORY\u003c/code\u003e\u003c/em\u003e to the search path. In any case, we can omit the system-specific extension for a shared library, commonly \u003ccode class=\"literal\"\u003e.so\u003c/code\u003e.)\u003c/p\u003e\n\u003cp\u003eNotice that we have specified the functions as \u003cspan class=\"quote\"\u003e“\u003cspan class=\"quote\"\u003estrict\u003c/span\u003e”\u003c/span\u003e, 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 \u003ccode class=\"function\"\u003ePG_ARGISNULL()\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003eThe macro \u003ccode class=\"function\"\u003ePG_ARGISNULL(\u003cem class=\"replaceable\"\u003e\u003ccode\u003en\u003c/code\u003e\u003c/em\u003e)\u003c/code\u003e allows a function to test whether each input is null. (Of course, doing this is only necessary in functions not declared \u003cspan class=\"quote\"\u003e“\u003cspan class=\"quote\"\u003estrict\u003c/span\u003e”\u003c/span\u003e.) As with the \u003ccode class=\"function\"\u003ePG_GETARG_\u003cem class=\"replaceable\"\u003e\u003ccode\u003exxx\u003c/code\u003e\u003c/em\u003e()\u003c/code\u003e macros, the input arguments are counted beginning at zero. Note that one should refrain from executing \u003ccode class=\"function\"\u003ePG_GETARG_\u003cem class=\"replaceable\"\u003e\u003ccode\u003exxx\u003c/code\u003e\u003c/em\u003e()\u003c/code\u003e until one has verified that the argument isn't null. To return a null result, execute \u003ccode class=\"function\"\u003ePG_RETURN_NULL()\u003c/code\u003e; this works in both strict and nonstrict functions.\u003c/p\u003e\n\u003cp\u003eAt first glance, the version-1 coding conventions might appear to be just pointless obscurantism, compared to using plain \u003ccode class=\"literal\"\u003eC\u003c/code\u003e calling conventions. They do however allow us to deal with \u003ccode class=\"literal\"\u003eNULL\u003c/code\u003eable arguments/return values, and \u003cspan class=\"quote\"\u003e“\u003cspan class=\"quote\"\u003etoasted\u003c/span\u003e”\u003c/span\u003e (compressed or out-of-line) values.\u003c/p\u003e\n\u003cp\u003eOther options provided by the version-1 interface are two variants of the \u003ccode class=\"function\"\u003ePG_GETARG_\u003cem class=\"replaceable\"\u003e\u003ccode\u003exxx\u003c/code\u003e\u003c/em\u003e()\u003c/code\u003e macros. The first of these, \u003ccode class=\"function\"\u003ePG_GETARG_\u003cem class=\"replaceable\"\u003e\u003ccode\u003exxx\u003c/code\u003e\u003c/em\u003e_COPY()\u003c/code\u003e, guarantees to return a copy of the specified argument that is safe for writing into. (The normal macros will sometimes return a pointer to a value that is physically stored in a table, which must not be written to. Using the \u003ccode class=\"function\"\u003ePG_GETARG_\u003cem class=\"replaceable\"\u003e\u003ccode\u003exxx\u003c/code\u003e\u003c/em\u003e_COPY()\u003c/code\u003e macros guarantees a writable result.) The second variant consists of the \u003ccode class=\"function\"\u003ePG_GETARG_\u003cem class=\"replaceable\"\u003e\u003ccode\u003exxx\u003c/code\u003e\u003c/em\u003e_SLICE()\u003c/code\u003e macros which take three arguments. The first is the number of the function argument (as above). The second and third are the offset and length of the segment to be returned. Offsets are counted from zero, and a negative length requests that the remainder of the value be returned. These macros provide more efficient access to parts of large values in the case where they have storage type \u003cspan class=\"quote\"\u003e“\u003cspan class=\"quote\"\u003eexternal\u003c/span\u003e”\u003c/span\u003e. (The storage type of a column can be specified using \u003ccode class=\"literal\"\u003eALTER TABLE \u003cem class=\"replaceable\"\u003e\u003ccode\u003etablename\u003c/code\u003e\u003c/em\u003e ALTER COLUMN \u003cem class=\"replaceable\"\u003e\u003ccode\u003ecolname\u003c/code\u003e\u003c/em\u003e SET STORAGE \u003cem class=\"replaceable\"\u003e\u003ccode\u003estoragetype\u003c/code\u003e\u003c/em\u003e\u003c/code\u003e. \u003cem class=\"replaceable\"\u003e\u003ccode\u003estoragetype\u003c/code\u003e\u003c/em\u003e is one of \u003ccode class=\"literal\"\u003eplain\u003c/code\u003e, \u003ccode class=\"literal\"\u003eexternal\u003c/code\u003e, \u003ccode class=\"literal\"\u003eextended\u003c/code\u003e, or \u003ccode class=\"literal\"\u003emain\u003c/code\u003e.)\u003c/p\u003e\n\u003cp\u003eFinally, the version-1 function call conventions make it possible to return set results (\u003ca class=\"xref\" href=\"/docs/18/xfunc-c.html#XFUNC-C-RETURN-SET\" title=\"36.10.9. Returning Sets\"\u003eSection 36.10.9\u003c/a\u003e) and implement trigger functions (\u003ca class=\"xref\" href=\"/docs/18/triggers.html\" title=\"Chapter 37. Triggers\"\u003eChapter 37\u003c/a\u003e) and procedural-language call handlers (\u003ca class=\"xref\" href=\"/docs/18/plhandler.html\" title=\"Chapter 57. Writing a Procedural Language Handler\"\u003eChapter 57\u003c/a\u003e). For more details see \u003ccode class=\"filename\"\u003esrc/backend/utils/fmgr/README\u003c/code\u003e in the source distribution.\u003c/p\u003e\n\u003c/div\u003e\n\u003cdiv class=\"sect2\" id=\"XFUNC-C-CODE\"\u003e\n\u003cdiv class=\"titlepage\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch3 class=\"title\"\u003e36.10.4. Writing Code \u003c/h3\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003eBefore we turn to the more advanced topics, we should discuss some coding rules for \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e C-language functions. While it might be possible to load functions written in languages other than C into \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e, this is usually difficult (when it is possible at all) because other languages, such as C++, FORTRAN, or Pascal often do not follow the same calling convention as C. That is, other languages do not pass argument and return values between functions in the same way. For this reason, we will assume that your C-language functions are actually written in C.\u003c/p\u003e\n\u003cp\u003eThe basic rules for writing and building C functions are as follows:\u003c/p\u003e\n\u003cdiv class=\"itemizedlist\"\u003e\n\u003cul class=\"itemizedlist\"\u003e\n\u003cli class=\"listitem\"\u003e\n\u003cp\u003eUse \u003ccode class=\"literal\"\u003epg_config --includedir-server\u003c/code\u003e to find out where the \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e server header files are installed on your system (or the system that your users will be running on).\u003c/p\u003e\n\u003c/li\u003e\n\u003cli class=\"listitem\"\u003e\n\u003cp\u003eCompiling and linking your code so that it can be dynamically loaded into \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e always requires special flags. See \u003ca class=\"xref\" href=\"/docs/18/xfunc-c.html#DFUNC\" title=\"36.10.5. Compiling and Linking Dynamically-Loaded Functions\"\u003eSection 36.10.5\u003c/a\u003e for a detailed explanation of how to do it for your particular operating system.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli class=\"listitem\"\u003e\n\u003cp\u003eRemember to define a \u003cspan class=\"quote\"\u003e“\u003cspan class=\"quote\"\u003emagic block\u003c/span\u003e”\u003c/span\u003e for your shared library, as described in \u003ca class=\"xref\" href=\"/docs/18/xfunc-c.html#XFUNC-C-DYNLOAD\" title=\"36.10.1. Dynamic Loading\"\u003eSection 36.10.1\u003c/a\u003e.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli class=\"listitem\"\u003e\n\u003cp\u003eWhen allocating memory, use the \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e functions \u003ccode class=\"function\"\u003epalloc\u003c/code\u003e and \u003ccode class=\"function\"\u003epfree\u003c/code\u003e instead of the corresponding C library functions \u003ccode class=\"function\"\u003emalloc\u003c/code\u003e and \u003ccode class=\"function\"\u003efree\u003c/code\u003e. The memory allocated by \u003ccode class=\"function\"\u003epalloc\u003c/code\u003e will be freed automatically at the end of each transaction, preventing memory leaks.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli class=\"listitem\"\u003e\n\u003cp\u003eAlways zero the bytes of your structures using \u003ccode class=\"function\"\u003ememset\u003c/code\u003e (or allocate them with \u003ccode class=\"function\"\u003epalloc0\u003c/code\u003e in the first place). Even if you assign to each field of your structure, there might be alignment padding (holes in the structure) that contain garbage values. Without this, it's difficult to support hash indexes or hash joins, as you must pick out only the significant bits of your data structure to compute a hash. The planner also sometimes relies on comparing constants via bitwise equality, so you can get undesirable planning results if logically-equivalent values aren't bitwise equal.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli class=\"listitem\"\u003e\n\u003cp\u003eMost of the internal \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e types are declared in \u003ccode class=\"filename\"\u003epostgres.h\u003c/code\u003e, while the function manager interfaces (\u003ccode class=\"symbol\"\u003ePG_FUNCTION_ARGS\u003c/code\u003e, etc.) are in \u003ccode class=\"filename\"\u003efmgr.h\u003c/code\u003e, so you will need to include at least these two files. For portability reasons it's best to include \u003ccode class=\"filename\"\u003epostgres.h\u003c/code\u003e \u003cspan class=\"emphasis\"\u003e\u003cem\u003efirst\u003c/em\u003e\u003c/span\u003e, before any other system or user header files. Including \u003ccode class=\"filename\"\u003epostgres.h\u003c/code\u003e will also include \u003ccode class=\"filename\"\u003eelog.h\u003c/code\u003e and \u003ccode class=\"filename\"\u003epalloc.h\u003c/code\u003e for you.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli class=\"listitem\"\u003e\n\u003cp\u003eSymbol names defined within object files must not conflict with each other or with symbols defined in the \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e server executable. You will have to rename your functions or variables if you get error messages to this effect.\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cdiv class=\"sect2\" id=\"DFUNC\"\u003e\n\u003cdiv class=\"titlepage\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch3 class=\"title\"\u003e36.10.5. Compiling and Linking Dynamically-Loaded Functions \u003c/h3\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003eBefore you are able to use your \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e extension functions written in C, they must be compiled and linked in a special way to produce a file that can be dynamically loaded by the server. To be precise, a \u003cem class=\"firstterm\"\u003eshared library\u003c/em\u003e needs to be created.\u003c/p\u003e\n\u003cp\u003eFor information beyond what is contained in this section you should read the documentation of your operating system, in particular the manual pages for the C compiler, \u003ccode class=\"command\"\u003ecc\u003c/code\u003e, and the link editor, \u003ccode class=\"command\"\u003eld\u003c/code\u003e. In addition, the \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e source code contains several working examples in the \u003ccode class=\"filename\"\u003econtrib\u003c/code\u003e directory. If you rely on these examples you will make your modules dependent on the availability of the \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e source code, however.\u003c/p\u003e\n\u003cp\u003eCreating shared libraries is generally analogous to linking executables: first the source files are compiled into object files, then the object files are linked together. The object files need to be created as \u003cem class=\"firstterm\"\u003eposition-independent code\u003c/em\u003e (PIC), which conceptually means that they can be placed at an arbitrary location in memory when they are loaded by the executable. (Object files intended for executables are usually not compiled that way.) The command to link a shared library contains special flags to distinguish it from linking an executable (at least in theory — on some systems the practice is much uglier).\u003c/p\u003e\n\u003cp\u003eIn the following examples we assume that your source code is in a file \u003ccode class=\"filename\"\u003efoo.c\u003c/code\u003e and we will create a shared library \u003ccode class=\"filename\"\u003efoo.so\u003c/code\u003e. The intermediate object file will be called \u003ccode class=\"filename\"\u003efoo.o\u003c/code\u003e unless otherwise noted. A shared library can contain more than one object file, but we only use one here.\u003c/p\u003e\n\u003cdiv class=\"variablelist\"\u003e\n\u003cdl class=\"variablelist\"\u003e\n\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003cspan class=\"systemitem\"\u003eFreeBSD\u003c/span\u003e \u003c/span\u003e\u003c/dt\u003e\n\u003cdd\u003e\n\u003cp\u003eThe compiler flag to create PIC is \u003ccode class=\"option\"\u003e-fPIC\u003c/code\u003e. To create shared libraries the compiler flag is \u003ccode class=\"option\"\u003e-shared\u003c/code\u003e.\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003ecc -fPIC -c foo.c\ncc -shared -o foo.so foo.o\n\u003c/pre\u003e\n\u003cp\u003eThis is applicable as of version 13.0 of \u003cspan class=\"systemitem\"\u003eFreeBSD\u003c/span\u003e, older versions used the \u003ccode class=\"filename\"\u003egcc\u003c/code\u003e compiler.\u003c/p\u003e\n\u003c/dd\u003e\n\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003cspan class=\"systemitem\"\u003eLinux\u003c/span\u003e \u003c/span\u003e\u003c/dt\u003e\n\u003cdd\u003e\n\u003cp\u003eThe compiler flag to create PIC is \u003ccode class=\"option\"\u003e-fPIC\u003c/code\u003e. The compiler flag to create a shared library is \u003ccode class=\"option\"\u003e-shared\u003c/code\u003e. A complete example looks like this:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003ecc -fPIC -c foo.c\ncc -shared -o foo.so foo.o\n\u003c/pre\u003e\n\u003c/dd\u003e\n\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003cspan class=\"systemitem\"\u003emacOS\u003c/span\u003e \u003c/span\u003e\u003c/dt\u003e\n\u003cdd\u003e\n\u003cp\u003eHere is an example. It assumes the developer tools are installed.\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003ecc -c foo.c\ncc -bundle -flat_namespace -undefined suppress -o foo.so foo.o\n\u003c/pre\u003e\n\u003c/dd\u003e\n\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003cspan class=\"systemitem\"\u003eNetBSD\u003c/span\u003e \u003c/span\u003e\u003c/dt\u003e\n\u003cdd\u003e\n\u003cp\u003eThe compiler flag to create PIC is \u003ccode class=\"option\"\u003e-fPIC\u003c/code\u003e. For ELF systems, the compiler with the flag \u003ccode class=\"option\"\u003e-shared\u003c/code\u003e is used to link shared libraries. On the older non-ELF systems, \u003ccode class=\"literal\"\u003eld -Bshareable\u003c/code\u003e is used.\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003egcc -fPIC -c foo.c\ngcc -shared -o foo.so foo.o\n\u003c/pre\u003e\n\u003c/dd\u003e\n\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003cspan class=\"systemitem\"\u003eOpenBSD\u003c/span\u003e \u003c/span\u003e\u003c/dt\u003e\n\u003cdd\u003e\n\u003cp\u003eThe compiler flag to create PIC is \u003ccode class=\"option\"\u003e-fPIC\u003c/code\u003e. \u003ccode class=\"literal\"\u003eld -Bshareable\u003c/code\u003e is used to link shared libraries.\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003egcc -fPIC -c foo.c\nld -Bshareable -o foo.so foo.o\n\u003c/pre\u003e\n\u003c/dd\u003e\n\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003cspan class=\"systemitem\"\u003eSolaris\u003c/span\u003e \u003c/span\u003e\u003c/dt\u003e\n\u003cdd\u003e\n\u003cp\u003eThe compiler flag to create PIC is \u003ccode class=\"option\"\u003e-KPIC\u003c/code\u003e with the Sun compiler and \u003ccode class=\"option\"\u003e-fPIC\u003c/code\u003e with \u003cspan class=\"application\"\u003eGCC\u003c/span\u003e. To link shared libraries, the compiler option is \u003ccode class=\"option\"\u003e-G\u003c/code\u003e with either compiler or alternatively \u003ccode class=\"option\"\u003e-shared\u003c/code\u003e with \u003cspan class=\"application\"\u003eGCC\u003c/span\u003e.\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003ecc -KPIC -c foo.c\ncc -G -o foo.so foo.o\n\u003c/pre\u003e\n\u003cp\u003eor\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003egcc -fPIC -c foo.c\ngcc -G -o foo.so foo.o\n\u003c/pre\u003e\n\u003c/dd\u003e\n\u003c/dl\u003e\n\u003c/div\u003e\n\u003cdiv class=\"tip\"\u003e\n\u003ch3 class=\"title\"\u003eTip\u003c/h3\u003e\n\u003cp\u003eIf this is too complicated for you, you should consider using \u003ca class=\"ulink\" href=\"https://www.gnu.org/software/libtool/\"\u003e\u003cspan class=\"productname\"\u003eGNU Libtool\u003c/span\u003e\u003c/a\u003e, which hides the platform differences behind a uniform interface.\u003c/p\u003e\n\u003c/div\u003e\n\u003cp\u003eThe resulting shared library file can then be loaded into \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e. When specifying the file name to the \u003ccode class=\"command\"\u003eCREATE FUNCTION\u003c/code\u003e command, one must give it the name of the shared library file, not the intermediate object file. Note that the system's standard shared-library extension (usually \u003ccode class=\"literal\"\u003e.so\u003c/code\u003e or \u003ccode class=\"literal\"\u003e.sl\u003c/code\u003e) can be omitted from the \u003ccode class=\"command\"\u003eCREATE FUNCTION\u003c/code\u003e command, and normally should be omitted for best portability.\u003c/p\u003e\n\u003cp\u003eRefer back to \u003ca class=\"xref\" href=\"/docs/18/xfunc-c.html#XFUNC-C-DYNLOAD\" title=\"36.10.1. Dynamic Loading\"\u003eSection 36.10.1\u003c/a\u003e about where the server expects to find the shared library files.\u003c/p\u003e\n\u003c/div\u003e\n\u003cdiv class=\"sect2\" id=\"XFUNC-API-ABI-STABILITY-GUIDANCE\"\u003e\n\u003cdiv class=\"titlepage\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch3 class=\"title\"\u003e36.10.6. Server API and ABI Stability Guidance \u003c/h3\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003eThis section contains guidance to authors of extensions and other server plugins about API and ABI stability in the \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e server.\u003c/p\u003e\n\u003cdiv class=\"sect3\" id=\"XFUNC-GUIDANCE-GENERAL\"\u003e\n\u003cdiv class=\"titlepage\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch4 class=\"title\"\u003e36.10.6.1. General \u003c/h4\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003eThe \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e server contains several well-demarcated APIs for server plugins, such as the function manager (fmgr, described in this chapter), SPI (\u003ca class=\"xref\" href=\"/docs/18/spi.html\" title=\"Chapter 45. Server Programming Interface\"\u003eChapter 45\u003c/a\u003e), and various hooks specifically designed for extensions. These interfaces are carefully managed for long-term stability and compatibility. However, the entire set of global functions and variables in the server effectively constitutes the publicly usable API, and most of it was not designed with extensibility and long-term stability in mind.\u003c/p\u003e\n\u003cp\u003eTherefore, while taking advantage of these interfaces is valid, the further one strays from the well-trodden path, the likelier it will be that one might encounter API or ABI compatibility issues at some point. Extension authors are encouraged to provide feedback about their requirements, so that over time, as new use patterns arise, certain interfaces can be considered more stabilized or new, better-designed interfaces can be added.\u003c/p\u003e\n\u003c/div\u003e\n\u003cdiv class=\"sect3\" id=\"XFUNC-GUIDANCE-API-COMPATIBILITY\"\u003e\n\u003cdiv class=\"titlepage\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch4 class=\"title\"\u003e36.10.6.2. API Compatibility \u003c/h4\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003eThe API, or application programming interface, is the interface used at compile time.\u003c/p\u003e\n\u003cdiv class=\"sect4\" id=\"XFUNC-GUIDANCE-API-MAJOR-VERSIONS\"\u003e\n\u003cdiv class=\"titlepage\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch5 class=\"title\"\u003e36.10.6.2.1. Major Versions \u003c/h5\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003eThere is \u003cspan class=\"emphasis\"\u003e\u003cem\u003eno\u003c/em\u003e\u003c/span\u003e promise of API compatibility between \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e major versions. Extension code therefore might require source code changes to work with multiple major versions. These can usually be managed with preprocessor conditions such as \u003ccode class=\"literal\"\u003e#if PG_VERSION_NUM \u0026gt;= 160000\u003c/code\u003e. Sophisticated extensions that use interfaces beyond the well-demarcated ones usually require a few such changes for each major server version.\u003c/p\u003e\n\u003c/div\u003e\n\u003cdiv class=\"sect4\" id=\"XFUNC-GUIDANCE-API-MNINOR-VERSIONS\"\u003e\n\u003cdiv class=\"titlepage\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch5 class=\"title\"\u003e36.10.6.2.2. Minor Versions \u003c/h5\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003e\u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e makes an effort to avoid server API breaks in minor releases. In general, extension code that compiles and works with a minor release should also compile and work with any other minor release of the same major version, past or future.\u003c/p\u003e\n\u003cp\u003eWhen a change \u003cspan class=\"emphasis\"\u003e\u003cem\u003eis\u003c/em\u003e\u003c/span\u003e required, it will be carefully managed, taking the requirements of extensions into account. Such changes will be communicated in the release notes (\u003ca class=\"xref\" href=\"/docs/18/release.html\" title=\"Appendix E. Release Notes\"\u003eAppendix E\u003c/a\u003e).\u003c/p\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cdiv class=\"sect3\" id=\"XFUNC-GUIDANCE-ABI-COMPATIBILITY\"\u003e\n\u003cdiv class=\"titlepage\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch4 class=\"title\"\u003e36.10.6.3. ABI Compatibility \u003c/h4\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003eThe ABI, or application binary interface, is the interface used at run time.\u003c/p\u003e\n\u003cdiv class=\"sect4\" id=\"XFUNC-GUIDANCE-ABI-MAJOR-VERSIONS\"\u003e\n\u003cdiv class=\"titlepage\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch5 class=\"title\"\u003e36.10.6.3.1. Major Versions \u003c/h5\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003eServers of different major versions have intentionally incompatible ABIs. Extensions that use server APIs must therefore be re-compiled for each major release. The inclusion of \u003ccode class=\"literal\"\u003ePG_MODULE_MAGIC\u003c/code\u003e (see \u003ca class=\"xref\" href=\"/docs/18/xfunc-c.html#XFUNC-C-DYNLOAD\" title=\"36.10.1. Dynamic Loading\"\u003eSection 36.10.1\u003c/a\u003e) ensures that code compiled for one major version will be rejected by other major versions.\u003c/p\u003e\n\u003c/div\u003e\n\u003cdiv class=\"sect4\" id=\"XFUNC-GUIDANCE-ABI-MNINOR-VERSIONS\"\u003e\n\u003cdiv class=\"titlepage\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch5 class=\"title\"\u003e36.10.6.3.2. Minor Versions \u003c/h5\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003e\u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e makes an effort to avoid server ABI breaks in minor releases. In general, an extension compiled against any minor release should work with any other minor release of the same major version, past or future.\u003c/p\u003e\n\u003cp\u003eWhen a change \u003cspan class=\"emphasis\"\u003e\u003cem\u003eis\u003c/em\u003e\u003c/span\u003e required, \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e will choose the least invasive change possible, for example by squeezing a new field into padding space or appending it to the end of a struct. These sorts of changes should not impact extensions unless they use very unusual code patterns.\u003c/p\u003e\n\u003cp\u003eIn rare cases, however, even such non-invasive changes may be impractical or impossible. In such an event, the change will be carefully managed, taking the requirements of extensions into account. Such changes will also be documented in the release notes (\u003ca class=\"xref\" href=\"/docs/18/release.html\" title=\"Appendix E. Release Notes\"\u003eAppendix E\u003c/a\u003e).\u003c/p\u003e\n\u003cp\u003eNote, however, that many parts of the server are not designed or maintained as publicly-consumable APIs (and that, in most cases, the actual boundary is also not well-defined). If urgent needs arise, changes in those parts will naturally be made with less consideration for extension code than changes in well-defined and widely used interfaces.\u003c/p\u003e\n\u003cp\u003eAlso, in the absence of automated detection of such changes, this is not a guarantee, but historically such breaking changes have been extremely rare.\u003c/p\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cdiv class=\"sect2\" id=\"XFUNC-C-COMPOSITE-TYPE-ARGS\"\u003e\n\u003cdiv class=\"titlepage\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch3 class=\"title\"\u003e36.10.7. Composite-Type Arguments \u003c/h3\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003eComposite types do not have a fixed layout like C structures. Instances of a composite type can contain null fields. In addition, composite types that are part of an inheritance hierarchy can have different fields than other members of the same inheritance hierarchy. Therefore, \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e provides a function interface for accessing fields of composite types from C.\u003c/p\u003e\n\u003cp\u003eSuppose we want to write a function to answer the query:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003eSELECT name, c_overpaid(emp, 1500) AS overpaid\n    FROM emp\n    WHERE name = 'Bill' OR name = 'Sam';\n\u003c/pre\u003e\n\u003cp\u003eUsing the version-1 calling conventions, we can define \u003ccode class=\"function\"\u003ec_overpaid\u003c/code\u003e as:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003e#include \"postgres.h\"\n#include \"executor/executor.h\"  /* for GetAttributeByName() */\n\nPG_MODULE_MAGIC;\n\nPG_FUNCTION_INFO_V1(c_overpaid);\n\nDatum\nc_overpaid(PG_FUNCTION_ARGS)\n{\n    HeapTupleHeader  t = PG_GETARG_HEAPTUPLEHEADER(0);\n    int32            limit = PG_GETARG_INT32(1);\n    bool isnull;\n    Datum salary;\n\n    salary = GetAttributeByName(t, \"salary\", \u0026amp;isnull);\n    if (isnull)\n        PG_RETURN_BOOL(false);\n    /* Alternatively, we might prefer to do PG_RETURN_NULL() for null salary. */\n\n    PG_RETURN_BOOL(DatumGetInt32(salary) \u0026gt; limit);\n}\n\n\u003c/pre\u003e\n\u003cp\u003e\u003ccode class=\"function\"\u003eGetAttributeByName\u003c/code\u003e is the \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e system function that returns attributes out of the specified row. It has three arguments: the argument of type \u003ccode class=\"type\"\u003eHeapTupleHeader\u003c/code\u003e passed into the function, the name of the desired attribute, and a return parameter that tells whether the attribute is null. \u003ccode class=\"function\"\u003eGetAttributeByName\u003c/code\u003e returns a \u003ccode class=\"type\"\u003eDatum\u003c/code\u003e value that you can convert to the proper data type by using the appropriate \u003ccode class=\"function\"\u003eDatumGet\u003cem class=\"replaceable\"\u003e\u003ccode\u003eXXX\u003c/code\u003e\u003c/em\u003e()\u003c/code\u003e function. Note that the return value is meaningless if the null flag is set; always check the null flag before trying to do anything with the result.\u003c/p\u003e\n\u003cp\u003eThere is also \u003ccode class=\"function\"\u003eGetAttributeByNum\u003c/code\u003e, which selects the target attribute by column number instead of name.\u003c/p\u003e\n\u003cp\u003eThe following command declares the function \u003ccode class=\"function\"\u003ec_overpaid\u003c/code\u003e in SQL:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003eCREATE FUNCTION c_overpaid(emp, integer) RETURNS boolean\n    AS '\u003cem class=\"replaceable\"\u003e\u003ccode\u003eDIRECTORY\u003c/code\u003e\u003c/em\u003e/funcs', 'c_overpaid'\n    LANGUAGE C STRICT;\n\u003c/pre\u003e\n\u003cp\u003eNotice we have used \u003ccode class=\"literal\"\u003eSTRICT\u003c/code\u003e so that we did not have to check whether the input arguments were NULL.\u003c/p\u003e\n\u003c/div\u003e\n\u003cdiv class=\"sect2\" id=\"XFUNC-C-RETURNING-ROWS\"\u003e\n\u003cdiv class=\"titlepage\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch3 class=\"title\"\u003e36.10.8. Returning Rows (Composite Types) \u003c/h3\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003eTo return a row or composite-type value from a C-language function, you can use a special API that provides macros and functions to hide most of the complexity of building composite data types. To use this API, the source file must include:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003e#include \"funcapi.h\"\n\u003c/pre\u003e\n\u003cp\u003eThere are two ways you can build a composite data value (henceforth a \u003cspan class=\"quote\"\u003e“\u003cspan class=\"quote\"\u003etuple\u003c/span\u003e”\u003c/span\u003e): you can build it from an array of Datum values, or from an array of C strings that can be passed to the input conversion functions of the tuple's column data types. In either case, you first need to obtain or construct a \u003ccode class=\"structname\"\u003eTupleDesc\u003c/code\u003e descriptor for the tuple structure. When working with Datums, you pass the \u003ccode class=\"structname\"\u003eTupleDesc\u003c/code\u003e to \u003ccode class=\"function\"\u003eBlessTupleDesc\u003c/code\u003e, and then call \u003ccode class=\"function\"\u003eheap_form_tuple\u003c/code\u003e for each row. When working with C strings, you pass the \u003ccode class=\"structname\"\u003eTupleDesc\u003c/code\u003e to \u003ccode class=\"function\"\u003eTupleDescGetAttInMetadata\u003c/code\u003e, and then call \u003ccode class=\"function\"\u003eBuildTupleFromCStrings\u003c/code\u003e for each row. In the case of a function returning a set of tuples, the setup steps can all be done once during the first call of the function.\u003c/p\u003e\n\u003cp\u003eSeveral helper functions are available for setting up the needed \u003ccode class=\"structname\"\u003eTupleDesc\u003c/code\u003e. The recommended way to do this in most functions returning composite values is to call:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003eTypeFuncClass get_call_result_type(FunctionCallInfo fcinfo,\n                                   Oid *resultTypeId,\n                                   TupleDesc *resultTupleDesc)\n\u003c/pre\u003e\n\u003cp\u003epassing the same \u003ccode class=\"literal\"\u003efcinfo\u003c/code\u003e struct passed to the calling function itself. (This of course requires that you use the version-1 calling conventions.) \u003ccode class=\"varname\"\u003eresultTypeId\u003c/code\u003e can be specified as \u003ccode class=\"literal\"\u003eNULL\u003c/code\u003e or as the address of a local variable to receive the function's result type OID. \u003ccode class=\"varname\"\u003eresultTupleDesc\u003c/code\u003e should be the address of a local \u003ccode class=\"structname\"\u003eTupleDesc\u003c/code\u003e variable. Check that the result is \u003ccode class=\"literal\"\u003eTYPEFUNC_COMPOSITE\u003c/code\u003e; if so, \u003ccode class=\"varname\"\u003eresultTupleDesc\u003c/code\u003e has been filled with the needed \u003ccode class=\"structname\"\u003eTupleDesc\u003c/code\u003e. (If it is not, you can report an error along the lines of \u003cspan class=\"quote\"\u003e“\u003cspan class=\"quote\"\u003efunction returning record called in context that cannot accept type record\u003c/span\u003e”\u003c/span\u003e.)\u003c/p\u003e\n\u003cdiv class=\"tip\"\u003e\n\u003ch3 class=\"title\"\u003eTip\u003c/h3\u003e\n\u003cp\u003e\u003ccode class=\"function\"\u003eget_call_result_type\u003c/code\u003e can resolve the actual type of a polymorphic function result; so it is useful in functions that return scalar polymorphic results, not only functions that return composites. The \u003ccode class=\"varname\"\u003eresultTypeId\u003c/code\u003e output is primarily useful for functions returning polymorphic scalars.\u003c/p\u003e\n\u003c/div\u003e\n\u003cdiv class=\"note\"\u003e\n\u003ch3 class=\"title\"\u003eNote\u003c/h3\u003e\n\u003cp\u003e\u003ccode class=\"function\"\u003eget_call_result_type\u003c/code\u003e has a sibling \u003ccode class=\"function\"\u003eget_expr_result_type\u003c/code\u003e, which can be used to resolve the expected output type for a function call represented by an expression tree. This can be used when trying to determine the result type from outside the function itself. There is also \u003ccode class=\"function\"\u003eget_func_result_type\u003c/code\u003e, which can be used when only the function's OID is available. However these functions are not able to deal with functions declared to return \u003ccode class=\"structname\"\u003erecord\u003c/code\u003e, and \u003ccode class=\"function\"\u003eget_func_result_type\u003c/code\u003e cannot resolve polymorphic types, so you should preferentially use \u003ccode class=\"function\"\u003eget_call_result_type\u003c/code\u003e.\u003c/p\u003e\n\u003c/div\u003e\n\u003cp\u003eOlder, now-deprecated functions for obtaining \u003ccode class=\"structname\"\u003eTupleDesc\u003c/code\u003es are:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003eTupleDesc RelationNameGetTupleDesc(const char *relname)\n\u003c/pre\u003e\n\u003cp\u003eto get a \u003ccode class=\"structname\"\u003eTupleDesc\u003c/code\u003e for the row type of a named relation, and:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003eTupleDesc TypeGetTupleDesc(Oid typeoid, List *colaliases)\n\u003c/pre\u003e\n\u003cp\u003eto get a \u003ccode class=\"structname\"\u003eTupleDesc\u003c/code\u003e based on a type OID. This can be used to get a \u003ccode class=\"structname\"\u003eTupleDesc\u003c/code\u003e for a base or composite type. It will not work for a function that returns \u003ccode class=\"structname\"\u003erecord\u003c/code\u003e, however, and it cannot resolve polymorphic types.\u003c/p\u003e\n\u003cp\u003eOnce you have a \u003ccode class=\"structname\"\u003eTupleDesc\u003c/code\u003e, call:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003eTupleDesc BlessTupleDesc(TupleDesc tupdesc)\n\u003c/pre\u003e\n\u003cp\u003eif you plan to work with Datums, or:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003eAttInMetadata *TupleDescGetAttInMetadata(TupleDesc tupdesc)\n\u003c/pre\u003e\n\u003cp\u003eif you plan to work with C strings. If you are writing a function returning set, you can save the results of these functions in the \u003ccode class=\"structname\"\u003eFuncCallContext\u003c/code\u003e structure — use the \u003ccode class=\"structfield\"\u003etuple_desc\u003c/code\u003e or \u003ccode class=\"structfield\"\u003eattinmeta\u003c/code\u003e field respectively.\u003c/p\u003e\n\u003cp\u003eWhen working with Datums, use:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003eHeapTuple heap_form_tuple(TupleDesc tupdesc, Datum *values, bool *isnull)\n\u003c/pre\u003e\n\u003cp\u003eto build a \u003ccode class=\"structname\"\u003eHeapTuple\u003c/code\u003e given user data in Datum form.\u003c/p\u003e\n\u003cp\u003eWhen working with C strings, use:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003eHeapTuple BuildTupleFromCStrings(AttInMetadata *attinmeta, char **values)\n\u003c/pre\u003e\n\u003cp\u003eto build a \u003ccode class=\"structname\"\u003eHeapTuple\u003c/code\u003e given user data in C string form. \u003cem class=\"parameter\"\u003e\u003ccode\u003evalues\u003c/code\u003e\u003c/em\u003e is an array of C strings, one for each attribute of the return row. Each C string should be in the form expected by the input function of the attribute data type. In order to return a null value for one of the attributes, the corresponding pointer in the \u003cem class=\"parameter\"\u003e\u003ccode\u003evalues\u003c/code\u003e\u003c/em\u003e array should be set to \u003ccode class=\"symbol\"\u003eNULL\u003c/code\u003e. This function will need to be called again for each row you return.\u003c/p\u003e\n\u003cp\u003eOnce you have built a tuple to return from your function, it must be converted into a \u003ccode class=\"type\"\u003eDatum\u003c/code\u003e. Use:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003eHeapTupleGetDatum(HeapTuple tuple)\n\u003c/pre\u003e\n\u003cp\u003eto convert a \u003ccode class=\"structname\"\u003eHeapTuple\u003c/code\u003e into a valid Datum. This \u003ccode class=\"type\"\u003eDatum\u003c/code\u003e can be returned directly if you intend to return just a single row, or it can be used as the current return value in a set-returning function.\u003c/p\u003e\n\u003cp\u003eAn example appears in the next section.\u003c/p\u003e\n\u003c/div\u003e\n\u003cdiv class=\"sect2\" id=\"XFUNC-C-RETURN-SET\"\u003e\n\u003cdiv class=\"titlepage\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch3 class=\"title\"\u003e36.10.9. Returning Sets \u003c/h3\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003eC-language functions have two options for returning sets (multiple rows). In one method, called \u003cem class=\"firstterm\"\u003eValuePerCall\u003c/em\u003e mode, a set-returning function is called repeatedly (passing the same arguments each time) and it returns one new row on each call, until it has no more rows to return and signals that by returning NULL. The set-returning function (SRF) must therefore save enough state across calls to remember what it was doing and return the correct next item on each call. In the other method, called \u003cem class=\"firstterm\"\u003eMaterialize\u003c/em\u003e mode, an SRF fills and returns a tuplestore object containing its entire result; then only one call occurs for the whole result, and no inter-call state is needed.\u003c/p\u003e\n\u003cp\u003eWhen using ValuePerCall mode, it is important to remember that the query is not guaranteed to be run to completion; that is, due to options such as \u003ccode class=\"literal\"\u003eLIMIT\u003c/code\u003e, the executor might stop making calls to the set-returning function before all rows have been fetched. This means it is not safe to perform cleanup activities in the last call, because that might not ever happen. It's recommended to use Materialize mode for functions that need access to external resources, such as file descriptors.\u003c/p\u003e\n\u003cp\u003eThe remainder of this section documents a set of helper macros that are commonly used (though not required to be used) for SRFs using ValuePerCall mode. Additional details about Materialize mode can be found in \u003ccode class=\"filename\"\u003esrc/backend/utils/fmgr/README\u003c/code\u003e. Also, the \u003ccode class=\"filename\"\u003econtrib\u003c/code\u003e modules in the \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e source distribution contain many examples of SRFs using both ValuePerCall and Materialize mode.\u003c/p\u003e\n\u003cp\u003eTo use the ValuePerCall support macros described here, include \u003ccode class=\"filename\"\u003efuncapi.h\u003c/code\u003e. These macros work with a structure \u003ccode class=\"structname\"\u003eFuncCallContext\u003c/code\u003e that contains the state that needs to be saved across calls. Within the calling SRF, \u003ccode class=\"literal\"\u003efcinfo-\u0026gt;flinfo-\u0026gt;fn_extra\u003c/code\u003e is used to hold a pointer to \u003ccode class=\"structname\"\u003eFuncCallContext\u003c/code\u003e across calls. The macros automatically fill that field on first use, and expect to find the same pointer there on subsequent uses.\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003etypedef struct FuncCallContext\n{\n    /*\n     * Number of times we've been called before\n     *\n     * call_cntr is initialized to 0 for you by SRF_FIRSTCALL_INIT(), and\n     * incremented for you every time SRF_RETURN_NEXT() is called.\n     */\n    uint64 call_cntr;\n\n    /*\n     * OPTIONAL maximum number of calls\n     *\n     * max_calls is here for convenience only and setting it is optional.\n     * If not set, you must provide alternative means to know when the\n     * function is done.\n     */\n    uint64 max_calls;\n\n    /*\n     * OPTIONAL pointer to miscellaneous user-provided context information\n     *\n     * user_fctx is for use as a pointer to your own data to retain\n     * arbitrary context information between calls of your function.\n     */\n    void *user_fctx;\n\n    /*\n     * OPTIONAL pointer to struct containing attribute type input metadata\n     *\n     * attinmeta is for use when returning tuples (i.e., composite data types)\n     * and is not used when returning base data types. It is only needed\n     * if you intend to use BuildTupleFromCStrings() to create the return\n     * tuple.\n     */\n    AttInMetadata *attinmeta;\n\n    /*\n     * memory context used for structures that must live for multiple calls\n     *\n     * multi_call_memory_ctx is set by SRF_FIRSTCALL_INIT() for you, and used\n     * by SRF_RETURN_DONE() for cleanup. It is the most appropriate memory\n     * context for any memory that is to be reused across multiple calls\n     * of the SRF.\n     */\n    MemoryContext multi_call_memory_ctx;\n\n    /*\n     * OPTIONAL pointer to struct containing tuple description\n     *\n     * tuple_desc is for use when returning tuples (i.e., composite data types)\n     * and is only needed if you are going to build the tuples with\n     * heap_form_tuple() rather than with BuildTupleFromCStrings().  Note that\n     * the TupleDesc pointer stored here should usually have been run through\n     * BlessTupleDesc() first.\n     */\n    TupleDesc tuple_desc;\n\n} FuncCallContext;\n\u003c/pre\u003e\n\u003cp\u003eThe macros to be used by an SRF using this infrastructure are:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003eSRF_IS_FIRSTCALL()\n\u003c/pre\u003e\n\u003cp\u003eUse this to determine if your function is being called for the first or a subsequent time. On the first call (only), call:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003eSRF_FIRSTCALL_INIT()\n\u003c/pre\u003e\n\u003cp\u003eto initialize the \u003ccode class=\"structname\"\u003eFuncCallContext\u003c/code\u003e. On every function call, including the first, call:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003eSRF_PERCALL_SETUP()\n\u003c/pre\u003e\n\u003cp\u003eto set up for using the \u003ccode class=\"structname\"\u003eFuncCallContext\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003eIf your function has data to return in the current call, use:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003eSRF_RETURN_NEXT(funcctx, result)\n\u003c/pre\u003e\n\u003cp\u003eto return it to the caller. (\u003ccode class=\"literal\"\u003eresult\u003c/code\u003e must be of type \u003ccode class=\"type\"\u003eDatum\u003c/code\u003e, either a single value or a tuple prepared as described above.) Finally, when your function is finished returning data, use:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003eSRF_RETURN_DONE(funcctx)\n\u003c/pre\u003e\n\u003cp\u003eto clean up and end the SRF.\u003c/p\u003e\n\u003cp\u003eThe memory context that is current when the SRF is called is a transient context that will be cleared between calls. This means that you do not need to call \u003ccode class=\"function\"\u003epfree\u003c/code\u003e on everything you allocated using \u003ccode class=\"function\"\u003epalloc\u003c/code\u003e; it will go away anyway. However, if you want to allocate any data structures to live across calls, you need to put them somewhere else. The memory context referenced by \u003ccode class=\"structfield\"\u003emulti_call_memory_ctx\u003c/code\u003e is a suitable location for any data that needs to survive until the SRF is finished running. In most cases, this means that you should switch into \u003ccode class=\"structfield\"\u003emulti_call_memory_ctx\u003c/code\u003e while doing the first-call setup. Use \u003ccode class=\"literal\"\u003efuncctx-\u0026gt;user_fctx\u003c/code\u003e to hold a pointer to any such cross-call data structures. (Data you allocate in \u003ccode class=\"structfield\"\u003emulti_call_memory_ctx\u003c/code\u003e will go away automatically when the query ends, so it is not necessary to free that data manually, either.)\u003c/p\u003e\n\u003cdiv class=\"warning\"\u003e\n\u003ch3 class=\"title\"\u003eWarning\u003c/h3\u003e\n\u003cp\u003eWhile the actual arguments to the function remain unchanged between calls, if you detoast the argument values (which is normally done transparently by the \u003ccode class=\"function\"\u003ePG_GETARG_\u003cem class=\"replaceable\"\u003e\u003ccode\u003exxx\u003c/code\u003e\u003c/em\u003e\u003c/code\u003e macro) in the transient context then the detoasted copies will be freed on each cycle. Accordingly, if you keep references to such values in your \u003ccode class=\"structfield\"\u003euser_fctx\u003c/code\u003e, you must either copy them into the \u003ccode class=\"structfield\"\u003emulti_call_memory_ctx\u003c/code\u003e after detoasting, or ensure that you detoast the values only in that context.\u003c/p\u003e\n\u003c/div\u003e\n\u003cp\u003eA complete pseudo-code example looks like the following:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003eDatum\nmy_set_returning_function(PG_FUNCTION_ARGS)\n{\n    FuncCallContext  *funcctx;\n    Datum             result;\n    \u003cem class=\"replaceable\"\u003e\u003ccode\u003efurther declarations as needed\u003c/code\u003e\u003c/em\u003e\n\n    if (SRF_IS_FIRSTCALL())\n    {\n        MemoryContext oldcontext;\n\n        funcctx = SRF_FIRSTCALL_INIT();\n        oldcontext = MemoryContextSwitchTo(funcctx-\u0026gt;multi_call_memory_ctx);\n        /* One-time setup code appears here: */\n        \u003cem class=\"replaceable\"\u003e\u003ccode\u003euser code\u003c/code\u003e\u003c/em\u003e\n        \u003cem class=\"replaceable\"\u003e\u003ccode\u003eif returning composite\u003c/code\u003e\u003c/em\u003e\n            \u003cem class=\"replaceable\"\u003e\u003ccode\u003ebuild TupleDesc, and perhaps AttInMetadata\u003c/code\u003e\u003c/em\u003e\n        \u003cem class=\"replaceable\"\u003e\u003ccode\u003eendif returning composite\u003c/code\u003e\u003c/em\u003e\n        \u003cem class=\"replaceable\"\u003e\u003ccode\u003euser code\u003c/code\u003e\u003c/em\u003e\n        MemoryContextSwitchTo(oldcontext);\n    }\n\n    /* Each-time setup code appears here: */\n    \u003cem class=\"replaceable\"\u003e\u003ccode\u003euser code\u003c/code\u003e\u003c/em\u003e\n    funcctx = SRF_PERCALL_SETUP();\n    \u003cem class=\"replaceable\"\u003e\u003ccode\u003euser code\u003c/code\u003e\u003c/em\u003e\n\n    /* this is just one way we might test whether we are done: */\n    if (funcctx-\u0026gt;call_cntr \u0026lt; funcctx-\u0026gt;max_calls)\n    {\n        /* Here we want to return another item: */\n        \u003cem class=\"replaceable\"\u003e\u003ccode\u003euser code\u003c/code\u003e\u003c/em\u003e\n        \u003cem class=\"replaceable\"\u003e\u003ccode\u003eobtain result Datum\u003c/code\u003e\u003c/em\u003e\n        SRF_RETURN_NEXT(funcctx, result);\n    }\n    else\n    {\n        /* Here we are done returning items, so just report that fact. */\n        /* (Resist the temptation to put cleanup code here.) */\n        SRF_RETURN_DONE(funcctx);\n    }\n}\n\u003c/pre\u003e\n\u003cp\u003eA complete example of a simple SRF returning a composite type looks like:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003ePG_FUNCTION_INFO_V1(retcomposite);\n\nDatum\nretcomposite(PG_FUNCTION_ARGS)\n{\n    FuncCallContext     *funcctx;\n    int                  call_cntr;\n    int                  max_calls;\n    TupleDesc            tupdesc;\n    AttInMetadata       *attinmeta;\n\n    /* stuff done only on the first call of the function */\n    if (SRF_IS_FIRSTCALL())\n    {\n        MemoryContext   oldcontext;\n\n        /* create a function context for cross-call persistence */\n        funcctx = SRF_FIRSTCALL_INIT();\n\n        /* switch to memory context appropriate for multiple function calls */\n        oldcontext = MemoryContextSwitchTo(funcctx-\u0026gt;multi_call_memory_ctx);\n\n        /* total number of tuples to be returned */\n        funcctx-\u0026gt;max_calls = PG_GETARG_INT32(0);\n\n        /* Build a tuple descriptor for our result type */\n        if (get_call_result_type(fcinfo, NULL, \u0026amp;tupdesc) != TYPEFUNC_COMPOSITE)\n            ereport(ERROR,\n                    (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),\n                     errmsg(\"function returning record called in context \"\n                            \"that cannot accept type record\")));\n\n        /*\n         * generate attribute metadata needed later to produce tuples from raw\n         * C strings\n         */\n        attinmeta = TupleDescGetAttInMetadata(tupdesc);\n        funcctx-\u0026gt;attinmeta = attinmeta;\n\n        MemoryContextSwitchTo(oldcontext);\n    }\n\n    /* stuff done on every call of the function */\n    funcctx = SRF_PERCALL_SETUP();\n\n    call_cntr = funcctx-\u0026gt;call_cntr;\n    max_calls = funcctx-\u0026gt;max_calls;\n    attinmeta = funcctx-\u0026gt;attinmeta;\n\n    if (call_cntr \u0026lt; max_calls)    /* do when there is more left to send */\n    {\n        char       **values;\n        HeapTuple    tuple;\n        Datum        result;\n\n        /*\n         * Prepare a values array for building the returned tuple.\n         * This should be an array of C strings which will\n         * be processed later by the type input functions.\n         */\n        values = (char **) palloc(3 * sizeof(char *));\n        values[0] = (char *) palloc(16 * sizeof(char));\n        values[1] = (char *) palloc(16 * sizeof(char));\n        values[2] = (char *) palloc(16 * sizeof(char));\n\n        snprintf(values[0], 16, \"%d\", 1 * PG_GETARG_INT32(1));\n        snprintf(values[1], 16, \"%d\", 2 * PG_GETARG_INT32(1));\n        snprintf(values[2], 16, \"%d\", 3 * PG_GETARG_INT32(1));\n\n        /* build a tuple */\n        tuple = BuildTupleFromCStrings(attinmeta, values);\n\n        /* make the tuple into a datum */\n        result = HeapTupleGetDatum(tuple);\n\n        /* clean up (this is not really necessary) */\n        pfree(values[0]);\n        pfree(values[1]);\n        pfree(values[2]);\n        pfree(values);\n\n        SRF_RETURN_NEXT(funcctx, result);\n    }\n    else    /* do when there is no more left */\n    {\n        SRF_RETURN_DONE(funcctx);\n    }\n}\n\n\u003c/pre\u003e\n\u003cp\u003eOne way to declare this function in SQL is:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003eCREATE TYPE __retcomposite AS (f1 integer, f2 integer, f3 integer);\n\nCREATE OR REPLACE FUNCTION retcomposite(integer, integer)\n    RETURNS SETOF __retcomposite\n    AS '\u003cem class=\"replaceable\"\u003e\u003ccode\u003efilename\u003c/code\u003e\u003c/em\u003e', 'retcomposite'\n    LANGUAGE C IMMUTABLE STRICT;\n\u003c/pre\u003e\n\u003cp\u003eA different way is to use OUT parameters:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003eCREATE OR REPLACE FUNCTION retcomposite(IN integer, IN integer,\n    OUT f1 integer, OUT f2 integer, OUT f3 integer)\n    RETURNS SETOF record\n    AS '\u003cem class=\"replaceable\"\u003e\u003ccode\u003efilename\u003c/code\u003e\u003c/em\u003e', 'retcomposite'\n    LANGUAGE C IMMUTABLE STRICT;\n\u003c/pre\u003e\n\u003cp\u003eNotice that in this method the output type of the function is formally an anonymous \u003ccode class=\"structname\"\u003erecord\u003c/code\u003e type.\u003c/p\u003e\n\u003c/div\u003e\n\u003cdiv class=\"sect2\" id=\"XFUNC-C-POLYMORPHIC\"\u003e\n\u003cdiv class=\"titlepage\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch3 class=\"title\"\u003e36.10.10. Polymorphic Arguments and Return Types \u003c/h3\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003eC-language functions can be declared to accept and return the polymorphic types described in \u003ca class=\"xref\" href=\"/docs/18/extend-type-system.html#EXTEND-TYPES-POLYMORPHIC\" title=\"36.2.5. Polymorphic Types\"\u003eSection 36.2.5\u003c/a\u003e. When a function's arguments or return types are defined as polymorphic types, the function author cannot know in advance what data type it will be called with, or need to return. There are two routines provided in \u003ccode class=\"filename\"\u003efmgr.h\u003c/code\u003e to allow a version-1 C function to discover the actual data types of its arguments and the type it is expected to return. The routines are called \u003ccode class=\"literal\"\u003eget_fn_expr_rettype(FmgrInfo *flinfo)\u003c/code\u003e and \u003ccode class=\"literal\"\u003eget_fn_expr_argtype(FmgrInfo *flinfo, int argnum)\u003c/code\u003e. They return the result or argument type OID, or \u003ccode class=\"symbol\"\u003eInvalidOid\u003c/code\u003e if the information is not available. The structure \u003ccode class=\"literal\"\u003eflinfo\u003c/code\u003e is normally accessed as \u003ccode class=\"literal\"\u003efcinfo-\u0026gt;flinfo\u003c/code\u003e. The parameter \u003ccode class=\"literal\"\u003eargnum\u003c/code\u003e is zero based. \u003ccode class=\"function\"\u003eget_call_result_type\u003c/code\u003e can also be used as an alternative to \u003ccode class=\"function\"\u003eget_fn_expr_rettype\u003c/code\u003e. There is also \u003ccode class=\"function\"\u003eget_fn_expr_variadic\u003c/code\u003e, which can be used to find out whether variadic arguments have been merged into an array. This is primarily useful for \u003ccode class=\"literal\"\u003eVARIADIC \"any\"\u003c/code\u003e functions, since such merging will always have occurred for variadic functions taking ordinary array types.\u003c/p\u003e\n\u003cp\u003eFor example, suppose we want to write a function to accept a single element of any type, and return a one-dimensional array of that type:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003ePG_FUNCTION_INFO_V1(make_array);\nDatum\nmake_array(PG_FUNCTION_ARGS)\n{\n    ArrayType  *result;\n    Oid         element_type = get_fn_expr_argtype(fcinfo-\u0026gt;flinfo, 0);\n    Datum       element;\n    bool        isnull;\n    int16       typlen;\n    bool        typbyval;\n    char        typalign;\n    int         ndims;\n    int         dims[MAXDIM];\n    int         lbs[MAXDIM];\n\n    if (!OidIsValid(element_type))\n        elog(ERROR, \"could not determine data type of input\");\n\n    /* get the provided element, being careful in case it's NULL */\n    isnull = PG_ARGISNULL(0);\n    if (isnull)\n        element = (Datum) 0;\n    else\n        element = PG_GETARG_DATUM(0);\n\n    /* we have one dimension */\n    ndims = 1;\n    /* and one element */\n    dims[0] = 1;\n    /* and lower bound is 1 */\n    lbs[0] = 1;\n\n    /* get required info about the element type */\n    get_typlenbyvalalign(element_type, \u0026amp;typlen, \u0026amp;typbyval, \u0026amp;typalign);\n\n    /* now build the array */\n    result = construct_md_array(\u0026amp;element, \u0026amp;isnull, ndims, dims, lbs,\n                                element_type, typlen, typbyval, typalign);\n\n    PG_RETURN_ARRAYTYPE_P(result);\n}\n\u003c/pre\u003e\n\u003cp\u003eThe following command declares the function \u003ccode class=\"function\"\u003emake_array\u003c/code\u003e in SQL:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003eCREATE FUNCTION make_array(anyelement) RETURNS anyarray\n    AS '\u003cem class=\"replaceable\"\u003e\u003ccode\u003eDIRECTORY\u003c/code\u003e\u003c/em\u003e/funcs', 'make_array'\n    LANGUAGE C IMMUTABLE;\n\u003c/pre\u003e\n\u003cp\u003eThere is a variant of polymorphism that is only available to C-language functions: they can be declared to take parameters of type \u003ccode class=\"literal\"\u003e\"any\"\u003c/code\u003e. (Note that this type name must be double-quoted, since it's also an SQL reserved word.) This works like \u003ccode class=\"type\"\u003eanyelement\u003c/code\u003e except that it does not constrain different \u003ccode class=\"literal\"\u003e\"any\"\u003c/code\u003e arguments to be the same type, nor do they help determine the function's result type. A C-language function can also declare its final parameter to be \u003ccode class=\"literal\"\u003eVARIADIC \"any\"\u003c/code\u003e. This will match one or more actual arguments of any type (not necessarily the same type). These arguments will \u003cspan class=\"emphasis\"\u003e\u003cem\u003enot\u003c/em\u003e\u003c/span\u003e be gathered into an array as happens with normal variadic functions; they will just be passed to the function separately. The \u003ccode class=\"function\"\u003ePG_NARGS()\u003c/code\u003e macro and the methods described above must be used to determine the number of actual arguments and their types when using this feature. Also, users of such a function might wish to use the \u003ccode class=\"literal\"\u003eVARIADIC\u003c/code\u003e keyword in their function call, with the expectation that the function would treat the array elements as separate arguments. The function itself must implement that behavior if wanted, after using \u003ccode class=\"function\"\u003eget_fn_expr_variadic\u003c/code\u003e to detect that the actual argument was marked with \u003ccode class=\"literal\"\u003eVARIADIC\u003c/code\u003e.\u003c/p\u003e\n\u003c/div\u003e\n\u003cdiv class=\"sect2\" id=\"XFUNC-SHARED-ADDIN\"\u003e\n\u003cdiv class=\"titlepage\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch3 class=\"title\"\u003e36.10.11. Shared Memory \u003c/h3\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cdiv class=\"sect3\" id=\"XFUNC-SHARED-ADDIN-AT-STARTUP\"\u003e\n\u003cdiv class=\"titlepage\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch4 class=\"title\"\u003e36.10.11.1. Requesting Shared Memory at Startup \u003c/h4\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003eAdd-ins can reserve shared memory on server startup. To do so, the add-in's shared library must be preloaded by specifying it in \u003ca class=\"xref\" href=\"/docs/18/runtime-config-client.html#GUC-SHARED-PRELOAD-LIBRARIES\"\u003eshared_preload_libraries\u003c/a\u003e. The shared library should also register a \u003ccode class=\"literal\"\u003eshmem_request_hook\u003c/code\u003e in its \u003ccode class=\"function\"\u003e_PG_init\u003c/code\u003e function. This \u003ccode class=\"literal\"\u003eshmem_request_hook\u003c/code\u003e can reserve shared memory by calling:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003evoid RequestAddinShmemSpace(Size size)\n\u003c/pre\u003e\n\u003cp\u003eEach backend should obtain a pointer to the reserved shared memory by calling:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003evoid *ShmemInitStruct(const char *name, Size size, bool *foundPtr)\n\u003c/pre\u003e\n\u003cp\u003eIf this function sets \u003ccode class=\"literal\"\u003efoundPtr\u003c/code\u003e to \u003ccode class=\"literal\"\u003efalse\u003c/code\u003e, the caller should proceed to initialize the contents of the reserved shared memory. If \u003ccode class=\"literal\"\u003efoundPtr\u003c/code\u003e is set to \u003ccode class=\"literal\"\u003etrue\u003c/code\u003e, the shared memory was already initialized by another backend, and the caller need not initialize further.\u003c/p\u003e\n\u003cp\u003eTo avoid race conditions, each backend should use the LWLock \u003ccode class=\"function\"\u003eAddinShmemInitLock\u003c/code\u003e when initializing its allocation of shared memory, as shown here:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003estatic mystruct *ptr = NULL;\nbool        found;\n\nLWLockAcquire(AddinShmemInitLock, LW_EXCLUSIVE);\nptr = ShmemInitStruct(\"my struct name\", size, \u0026amp;found);\nif (!found)\n{\n    ... initialize contents of shared memory ...\n    ptr-\u0026gt;locks = GetNamedLWLockTranche(\"my tranche name\");\n}\nLWLockRelease(AddinShmemInitLock);\n\u003c/pre\u003e\n\u003cp\u003e\u003ccode class=\"literal\"\u003eshmem_startup_hook\u003c/code\u003e provides a convenient place for the initialization code, but it is not strictly required that all such code be placed in this hook. On Windows (and anywhere else where \u003ccode class=\"literal\"\u003eEXEC_BACKEND\u003c/code\u003e is defined), each backend executes the registered \u003ccode class=\"literal\"\u003eshmem_startup_hook\u003c/code\u003e shortly after it attaches to shared memory, so add-ins should still acquire \u003ccode class=\"function\"\u003eAddinShmemInitLock\u003c/code\u003e within this hook, as shown in the example above. On other platforms, only the postmaster process executes the \u003ccode class=\"literal\"\u003eshmem_startup_hook\u003c/code\u003e, and each backend automatically inherits the pointers to shared memory.\u003c/p\u003e\n\u003cp\u003eAn example of a \u003ccode class=\"literal\"\u003eshmem_request_hook\u003c/code\u003e and \u003ccode class=\"literal\"\u003eshmem_startup_hook\u003c/code\u003e can be found in \u003ccode class=\"filename\"\u003econtrib/pg_stat_statements/pg_stat_statements.c\u003c/code\u003e in the \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e source tree.\u003c/p\u003e\n\u003c/div\u003e\n\u003cdiv class=\"sect3\" id=\"XFUNC-SHARED-ADDIN-AFTER-STARTUP\"\u003e\n\u003cdiv class=\"titlepage\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch4 class=\"title\"\u003e36.10.11.2. Requesting Shared Memory After Startup \u003c/h4\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003eThere is another, more flexible method of reserving shared memory that can be done after server startup and outside a \u003ccode class=\"literal\"\u003eshmem_request_hook\u003c/code\u003e. To do so, each backend that will use the shared memory should obtain a pointer to it by calling:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003evoid *GetNamedDSMSegment(const char *name, size_t size,\n                         void (*init_callback) (void *ptr),\n                         bool *found)\n\u003c/pre\u003e\n\u003cp\u003eIf a dynamic shared memory segment with the given name does not yet exist, this function will allocate it and initialize it with the provided \u003ccode class=\"function\"\u003einit_callback\u003c/code\u003e callback function. If the segment has already been allocated and initialized by another backend, this function simply attaches the existing dynamic shared memory segment to the current backend.\u003c/p\u003e\n\u003cp\u003eUnlike shared memory reserved at server startup, there is no need to acquire \u003ccode class=\"function\"\u003eAddinShmemInitLock\u003c/code\u003e or otherwise take action to avoid race conditions when reserving shared memory with \u003ccode class=\"function\"\u003eGetNamedDSMSegment\u003c/code\u003e. This function ensures that only one backend allocates and initializes the segment and that all other backends receive a pointer to the fully allocated and initialized segment.\u003c/p\u003e\n\u003cp\u003eA complete usage example of \u003ccode class=\"function\"\u003eGetNamedDSMSegment\u003c/code\u003e can be found in \u003ccode class=\"filename\"\u003esrc/test/modules/test_dsm_registry/test_dsm_registry.c\u003c/code\u003e in the \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e source tree.\u003c/p\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cdiv class=\"sect2\" id=\"XFUNC-ADDIN-LWLOCKS\"\u003e\n\u003cdiv class=\"titlepage\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch3 class=\"title\"\u003e36.10.12. LWLocks \u003c/h3\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cdiv class=\"sect3\" id=\"XFUNC-ADDIN-LWLOCKS-AT-STARTUP\"\u003e\n\u003cdiv class=\"titlepage\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch4 class=\"title\"\u003e36.10.12.1. Requesting LWLocks at Startup \u003c/h4\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003eAdd-ins can reserve LWLocks on server startup. As with shared memory reserved at server startup, the add-in's shared library must be preloaded by specifying it in \u003ca class=\"xref\" href=\"/docs/18/runtime-config-client.html#GUC-SHARED-PRELOAD-LIBRARIES\"\u003eshared_preload_libraries\u003c/a\u003e, and the shared library should register a \u003ccode class=\"literal\"\u003eshmem_request_hook\u003c/code\u003e in its \u003ccode class=\"function\"\u003e_PG_init\u003c/code\u003e function. This \u003ccode class=\"literal\"\u003eshmem_request_hook\u003c/code\u003e can reserve LWLocks by calling:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003evoid RequestNamedLWLockTranche(const char *tranche_name, int num_lwlocks)\n\u003c/pre\u003e\n\u003cp\u003eThis ensures that an array of \u003ccode class=\"literal\"\u003enum_lwlocks\u003c/code\u003e LWLocks is available under the name \u003ccode class=\"literal\"\u003etranche_name\u003c/code\u003e. A pointer to this array can be obtained by calling:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003eLWLockPadded *GetNamedLWLockTranche(const char *tranche_name)\n\u003c/pre\u003e\n\u003c/div\u003e\n\u003cdiv class=\"sect3\" id=\"XFUNC-ADDIN-LWLOCKS-AFTER-STARTUP\"\u003e\n\u003cdiv class=\"titlepage\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch4 class=\"title\"\u003e36.10.12.2. Requesting LWLocks After Startup \u003c/h4\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003eThere is another, more flexible method of obtaining LWLocks that can be done after server startup and outside a \u003ccode class=\"literal\"\u003eshmem_request_hook\u003c/code\u003e. To do so, first allocate a \u003ccode class=\"literal\"\u003etranche_id\u003c/code\u003e by calling:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003eint LWLockNewTrancheId(void)\n\u003c/pre\u003e\n\u003cp\u003eNext, initialize each LWLock, passing the new \u003ccode class=\"literal\"\u003etranche_id\u003c/code\u003e as an argument:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003evoid LWLockInitialize(LWLock *lock, int tranche_id)\n\u003c/pre\u003e\n\u003cp\u003eSimilar to shared memory, each backend should ensure that only one process allocates a new \u003ccode class=\"literal\"\u003etranche_id\u003c/code\u003e and initializes each new LWLock. One way to do this is to only call these functions in your shared memory initialization code with the \u003ccode class=\"function\"\u003eAddinShmemInitLock\u003c/code\u003e held exclusively. If using \u003ccode class=\"function\"\u003eGetNamedDSMSegment\u003c/code\u003e, calling these functions in the \u003ccode class=\"function\"\u003einit_callback\u003c/code\u003e callback function is sufficient to avoid race conditions.\u003c/p\u003e\n\u003cp\u003eFinally, each backend using the \u003ccode class=\"literal\"\u003etranche_id\u003c/code\u003e should associate it with a \u003ccode class=\"literal\"\u003etranche_name\u003c/code\u003e by calling:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003evoid LWLockRegisterTranche(int tranche_id, const char *tranche_name)\n\u003c/pre\u003e\n\u003cp\u003eA complete usage example of \u003ccode class=\"function\"\u003eLWLockNewTrancheId\u003c/code\u003e, \u003ccode class=\"function\"\u003eLWLockInitialize\u003c/code\u003e, and \u003ccode class=\"function\"\u003eLWLockRegisterTranche\u003c/code\u003e can be found in \u003ccode class=\"filename\"\u003econtrib/pg_prewarm/autoprewarm.c\u003c/code\u003e in the \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e source tree.\u003c/p\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cdiv class=\"sect2\" id=\"XFUNC-ADDIN-WAIT-EVENTS\"\u003e\n\u003cdiv class=\"titlepage\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch3 class=\"title\"\u003e36.10.13. Custom Wait Events \u003c/h3\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003eAdd-ins can define custom wait events under the wait event type \u003ccode class=\"literal\"\u003eExtension\u003c/code\u003e by calling:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003euint32 WaitEventExtensionNew(const char *wait_event_name)\n\u003c/pre\u003e\n\u003cp\u003eThe wait event is associated to a user-facing custom string. An example can be found in \u003ccode class=\"filename\"\u003esrc/test/modules/worker_spi\u003c/code\u003e in the PostgreSQL source tree.\u003c/p\u003e\n\u003cp\u003eCustom wait events can be viewed in \u003ca class=\"link\" href=\"/docs/18/monitoring-stats.html#MONITORING-PG-STAT-ACTIVITY-VIEW\" title=\"27.2.3. pg_stat_activity\"\u003e\u003ccode class=\"structname\"\u003epg_stat_activity\u003c/code\u003e\u003c/a\u003e:\u003c/p\u003e\n\u003cpre class=\"screen\"\u003e=# SELECT wait_event_type, wait_event FROM pg_stat_activity\n     WHERE backend_type ~ 'worker_spi';\n wait_event_type |  wait_event\n-----------------+---------------\n Extension       | WorkerSpiMain\n(1 row)\n\u003c/pre\u003e\n\u003c/div\u003e\n\u003cdiv class=\"sect2\" id=\"XFUNC-ADDIN-INJECTION-POINTS\"\u003e\n\u003cdiv class=\"titlepage\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch3 class=\"title\"\u003e36.10.14. Injection Points \u003c/h3\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003eAn injection point with a given \u003ccode class=\"literal\"\u003ename\u003c/code\u003e is declared using macro:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003eINJECTION_POINT(name, arg);\n\u003c/pre\u003e\n\u003cp\u003eThere are a few injection points already declared at strategic points within the server code. After adding a new injection point the code needs to be compiled in order for that injection point to be available in the binary. Add-ins written in C-language can declare injection points in their own code using the same macro. The injection point names should use lower-case characters, with terms separated by dashes. \u003ccode class=\"literal\"\u003earg\u003c/code\u003e is an optional argument value given to the callback at run-time.\u003c/p\u003e\n\u003cp\u003eExecuting an injection point can require allocating a small amount of memory, which can fail. If you need to have an injection point in a critical section where dynamic allocations are not allowed, you can use a two-step approach with the following macros:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003eINJECTION_POINT_LOAD(name);\nINJECTION_POINT_CACHED(name, arg);\n\u003c/pre\u003e\n\u003cp\u003eBefore entering the critical section, call \u003ccode class=\"function\"\u003eINJECTION_POINT_LOAD\u003c/code\u003e. It checks the shared memory state, and loads the callback into backend-private memory if it is active. Inside the critical section, use \u003ccode class=\"function\"\u003eINJECTION_POINT_CACHED\u003c/code\u003e to execute the callback.\u003c/p\u003e\n\u003cp\u003eAdd-ins can attach callbacks to an already-declared injection point by calling:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003eextern void InjectionPointAttach(const char *name,\n                                 const char *library,\n                                 const char *function,\n                                 const void *private_data,\n                                 int private_data_size);\n\u003c/pre\u003e\n\u003cp\u003e\u003ccode class=\"literal\"\u003ename\u003c/code\u003e is the name of the injection point, which when reached during execution will execute the \u003ccode class=\"literal\"\u003efunction\u003c/code\u003e loaded from \u003ccode class=\"literal\"\u003elibrary\u003c/code\u003e. \u003ccode class=\"literal\"\u003eprivate_data\u003c/code\u003e is a private area of data of size \u003ccode class=\"literal\"\u003eprivate_data_size\u003c/code\u003e given as argument to the callback when executed.\u003c/p\u003e\n\u003cp\u003eHere is an example of callback for \u003ccode class=\"literal\"\u003eInjectionPointCallback\u003c/code\u003e:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003estatic void\ncustom_injection_callback(const char *name,\n                          const void *private_data,\n                          void *arg)\n{\n    uint32 wait_event_info = WaitEventInjectionPointNew(name);\n\n    pgstat_report_wait_start(wait_event_info);\n    elog(NOTICE, \"%s: executed custom callback\", name);\n    pgstat_report_wait_end();\n}\n\u003c/pre\u003e\n\u003cp\u003eThis callback prints a message to server error log with severity \u003ccode class=\"literal\"\u003eNOTICE\u003c/code\u003e, but callbacks may implement more complex logic.\u003c/p\u003e\n\u003cp\u003eAn alternative way to define the action to take when an injection point is reached is to add the testing code alongside the normal source code. This can be useful if the action e.g. depends on local variables that are not accessible to loaded modules. The \u003ccode class=\"function\"\u003eIS_INJECTION_POINT_ATTACHED\u003c/code\u003e macro can then be used to check if an injection point is attached, for example:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003e#ifdef USE_INJECTION_POINTS\nif (IS_INJECTION_POINT_ATTACHED(\"before-foobar\"))\n{\n    /* change a local variable if injection point is attached */\n    local_var = 123;\n\n    /* also execute the callback */\n    INJECTION_POINT_CACHED(\"before-foobar\", NULL);\n}\n#endif\n\u003c/pre\u003e\n\u003cp\u003eNote that the callback attached to the injection point will not be executed by the \u003ccode class=\"function\"\u003eIS_INJECTION_POINT_ATTACHED\u003c/code\u003e macro. If you want to execute the callback, you must also call \u003ccode class=\"function\"\u003eINJECTION_POINT_CACHED\u003c/code\u003e like in the above example.\u003c/p\u003e\n\u003cp\u003eOptionally, it is possible to detach an injection point by calling:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003eextern bool InjectionPointDetach(const char *name);\n\u003c/pre\u003e\n\u003cp\u003eOn success, \u003ccode class=\"literal\"\u003etrue\u003c/code\u003e is returned, \u003ccode class=\"literal\"\u003efalse\u003c/code\u003e otherwise.\u003c/p\u003e\n\u003cp\u003eA callback attached to an injection point is available across all the backends including the backends started after \u003ccode class=\"literal\"\u003eInjectionPointAttach\u003c/code\u003e is called. It remains attached while the server is running or until the injection point is detached using \u003ccode class=\"literal\"\u003eInjectionPointDetach\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003eAn example can be found in \u003ccode class=\"filename\"\u003esrc/test/modules/injection_points\u003c/code\u003e in the PostgreSQL source tree.\u003c/p\u003e\n\u003cp\u003eEnabling injections points requires \u003ccode class=\"option\"\u003e--enable-injection-points\u003c/code\u003e with \u003ccode class=\"command\"\u003econfigure\u003c/code\u003e or \u003ccode class=\"option\"\u003e-Dinjection_points=true\u003c/code\u003e with \u003cspan class=\"application\"\u003eMeson\u003c/span\u003e.\u003c/p\u003e\n\u003c/div\u003e\n\u003cdiv class=\"sect2\" id=\"XFUNC-ADDIN-CUSTOM-CUMULATIVE-STATISTICS\"\u003e\n\u003cdiv class=\"titlepage\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch3 class=\"title\"\u003e36.10.15. Custom Cumulative Statistics \u003c/h3\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003eIt is possible for add-ins written in C-language to use custom types of cumulative statistics registered in the \u003ca class=\"link\" href=\"/docs/18/monitoring-stats.html#MONITORING-STATS-SETUP\" title=\"27.2.1. Statistics Collection Configuration\"\u003eCumulative Statistics System\u003c/a\u003e.\u003c/p\u003e\n\u003cp\u003eFirst, define a \u003ccode class=\"literal\"\u003ePgStat_KindInfo\u003c/code\u003e that includes all the information related to the custom type registered. For example:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003estatic const PgStat_KindInfo custom_stats = {\n    .name = \"custom_stats\",\n    .fixed_amount = false,\n    .shared_size = sizeof(PgStatShared_Custom),\n    .shared_data_off = offsetof(PgStatShared_Custom, stats),\n    .shared_data_len = sizeof(((PgStatShared_Custom *) 0)-\u0026gt;stats),\n    .pending_size = sizeof(PgStat_StatCustomEntry),\n}\n\u003c/pre\u003e\n\u003cp\u003eThen, each backend that needs to use this custom type needs to register it with \u003ccode class=\"literal\"\u003epgstat_register_kind\u003c/code\u003e and a unique ID used to store the entries related to this type of statistics:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003eextern PgStat_Kind pgstat_register_kind(PgStat_Kind kind,\n                                        const PgStat_KindInfo *kind_info);\n\u003c/pre\u003e\n\u003cp\u003eWhile developing a new extension, use \u003ccode class=\"literal\"\u003ePGSTAT_KIND_EXPERIMENTAL\u003c/code\u003e for \u003cem class=\"parameter\"\u003e\u003ccode\u003ekind\u003c/code\u003e\u003c/em\u003e. When you are ready to release the extension to users, reserve a kind ID at the \u003ca class=\"ulink\" href=\"https://wiki.postgresql.org/wiki/CustomCumulativeStats\"\u003eCustom Cumulative Statistics\u003c/a\u003e page.\u003c/p\u003e\n\u003cp\u003eThe details of the API for \u003ccode class=\"literal\"\u003ePgStat_KindInfo\u003c/code\u003e can be found in \u003ccode class=\"filename\"\u003esrc/include/utils/pgstat_internal.h\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003eThe type of statistics registered is associated with a name and a unique ID shared across the server in shared memory. Each backend using a custom type of statistics maintains a local cache storing the information of each custom \u003ccode class=\"literal\"\u003ePgStat_KindInfo\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003ePlace the extension module implementing the custom cumulative statistics type in \u003ca class=\"xref\" href=\"/docs/18/runtime-config-client.html#GUC-SHARED-PRELOAD-LIBRARIES\"\u003eshared_preload_libraries\u003c/a\u003e so that it will be loaded early during \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e startup.\u003c/p\u003e\n\u003cp\u003eAn example describing how to register and use custom statistics can be found in \u003ccode class=\"filename\"\u003esrc/test/modules/injection_points\u003c/code\u003e.\u003c/p\u003e\n\u003c/div\u003e\n\u003cdiv class=\"sect2\" id=\"EXTEND-CPP\"\u003e\n\u003cdiv class=\"titlepage\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch3 class=\"title\"\u003e36.10.16. Using C++ for Extensibility \u003c/h3\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003eAlthough the \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e backend is written in C, it is possible to write extensions in C++ if these guidelines are followed:\u003c/p\u003e\n\u003cdiv class=\"itemizedlist\"\u003e\n\u003cul class=\"itemizedlist\"\u003e\n\u003cli class=\"listitem\"\u003e\n\u003cp\u003eAll functions accessed by the backend must present a C interface to the backend; these C functions can then call C++ functions. For example, \u003ccode class=\"literal\"\u003eextern C\u003c/code\u003e linkage is required for backend-accessed functions. This is also necessary for any functions that are passed as pointers between the backend and C++ code.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli class=\"listitem\"\u003e\n\u003cp\u003eFree memory using the appropriate deallocation method. For example, most backend memory is allocated using \u003ccode class=\"function\"\u003epalloc()\u003c/code\u003e, so use \u003ccode class=\"function\"\u003epfree()\u003c/code\u003e to free it. Using C++ \u003ccode class=\"function\"\u003edelete\u003c/code\u003e in such cases will fail.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli class=\"listitem\"\u003e\n\u003cp\u003ePrevent exceptions from propagating into the C code (use a catch-all block at the top level of all \u003ccode class=\"literal\"\u003eextern C\u003c/code\u003e functions). This is necessary even if the C++ code does not explicitly throw any exceptions, because events like out-of-memory can still throw exceptions. Any exceptions must be caught and appropriate errors passed back to the C interface. If possible, compile C++ with \u003ccode class=\"option\"\u003e-fno-exceptions\u003c/code\u003e to eliminate exceptions entirely; in such cases, you must check for failures in your C++ code, e.g., check for NULL returned by \u003ccode class=\"function\"\u003enew()\u003c/code\u003e.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli class=\"listitem\"\u003e\n\u003cp\u003eIf calling backend functions from C++ code, be sure that the C++ call stack contains only plain old data structures (POD). This is necessary because backend errors generate a distant \u003ccode class=\"function\"\u003elongjmp()\u003c/code\u003e that does not properly unroll a C++ call stack with non-POD objects.\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/div\u003e\n\u003cp\u003eIn summary, it is best to place C++ code behind a wall of \u003ccode class=\"literal\"\u003eextern C\u003c/code\u003e functions that interface to the backend, and avoid exception, memory, and call stack leakage.\u003c/p\u003e\n\u003c/div\u003e\n\u003c/div\u003e","manual_path":"/docs/18/xfunc-c.html","related":[],"release":{"catalog_fingerprint":"65c93d6048ef30e61023a84f9680fa6a92b1c383b7eb226741170077eb078502","channel":"stable","label":"18.6","major":"18","ref":"https://ftp.postgresql.org/pub/source/v18.6/postgresql-18.6.tar.bz2","revision":"555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f","source_sha256":"555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f"},"sections":[],"signature":"","sources":[{"label":"Matching PostgreSQL source archive","sha256":"555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f","url":"https://ftp.postgresql.org/pub/source/v18.6/postgresql-18.6.tar.bz2"},{"label":"PostgreSQL 18 English manual","path":"xfunc-c.html","sha256":"d60592edc11f3240b19cecee91523a9a31f1caf68809fa7a39376360d957d68b","url":"/docs/18/xfunc-c.html"}],"tables":[]},"ManualEvidence":{"manual_path":"/docs/18/xfunc-c.html","release":{"catalog_fingerprint":"65c93d6048ef30e61023a84f9680fa6a92b1c383b7eb226741170077eb078502","channel":"stable","label":"18.6","major":"18","ref":"https://ftp.postgresql.org/pub/source/v18.6/postgresql-18.6.tar.bz2","revision":"555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f","source_sha256":"555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f"},"sources":[{"label":"Matching PostgreSQL source archive","sha256":"555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f","url":"https://ftp.postgresql.org/pub/source/v18.6/postgresql-18.6.tar.bz2"},{"label":"PostgreSQL 18 English manual","path":"xfunc-c.html","sha256":"d60592edc11f3240b19cecee91523a9a31f1caf68809fa7a39376360d957d68b","url":"/docs/18/xfunc-c.html"}]},"MeasuredEvidence":{}},"Text":{"Collection":"language","Key":"c","SourceDatabase":"center","Version":"18","Locale":"en","Title":"c","Summary":"dynamically-loaded C functions","BodyHTML":"\u003cdiv id=\"XFUNC-C\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch2\u003e36.10. C-Language Functions \u003c/h2\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\n\u003cp\u003eUser-defined functions can be written in C (or a language that can be made compatible with C, such as C++). Such functions are compiled into dynamically loadable objects (also called shared libraries) and are loaded by the server on demand. The dynamic loading feature is what distinguishes \u003cspan\u003e“\u003cspan\u003eC language\u003c/span\u003e”\u003c/span\u003e functions from \u003cspan\u003e“\u003cspan\u003einternal\u003c/span\u003e”\u003c/span\u003e functions — the actual coding conventions are essentially the same for both. (Hence, the standard internal function library is a rich source of coding examples for user-defined C functions.)\u003c/p\u003e\n\u003cp\u003eCurrently only one calling convention is used for C functions (\u003cspan\u003e“\u003cspan\u003eversion 1\u003c/span\u003e”\u003c/span\u003e). Support for that calling convention is indicated by writing a \u003ccode\u003ePG_FUNCTION_INFO_V1()\u003c/code\u003e macro call for the function, as illustrated below.\u003c/p\u003e\n\u003cdiv id=\"XFUNC-C-DYNLOAD\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch3\u003e36.10.1. Dynamic Loading \u003c/h3\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003eThe first time a user-defined function in a particular loadable object file is called in a session, the dynamic loader loads that object file into memory so that the function can be called. The \u003ccode\u003eCREATE FUNCTION\u003c/code\u003e for a user-defined C function must therefore specify two pieces of information for the function: the name of the loadable object file, and the C name (link symbol) of the specific function to call within that object file. If the C name is not explicitly specified then it is assumed to be the same as the SQL function name.\u003c/p\u003e\n\u003cp\u003eThe following algorithm is used to locate the shared object file based on the name given in the \u003ccode\u003eCREATE FUNCTION\u003c/code\u003e command:\u003c/p\u003e\n\u003cdiv\u003e\n\u003col\u003e\n\u003cli\u003e\n\u003cp\u003eIf the name is an absolute path, the given file is loaded.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eIf the name starts with the string \u003ccode\u003e$libdir\u003c/code\u003e, that part is replaced by the \u003cspan\u003ePostgreSQL\u003c/span\u003e package library directory name, which is determined at build time.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eIf the name does not contain a directory part, the file is searched for in the path specified by the configuration variable \u003ca href=\"/docs/18/runtime-config-client.html#GUC-DYNAMIC-LIBRARY-PATH\" rel=\"nofollow\"\u003edynamic_library_path\u003c/a\u003e.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eOtherwise (the file was not found in the path, or it contains a non-absolute directory part), the dynamic loader will try to take the name as given, which will most likely fail. (It is unreliable to depend on the current working directory.)\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/div\u003e\n\u003cp\u003eIf this sequence does not work, the platform-specific shared library file name extension (often \u003ccode\u003e.so\u003c/code\u003e) is appended to the given name and this sequence is tried again. If that fails as well, the load will fail.\u003c/p\u003e\n\u003cp\u003eIt is recommended to locate shared libraries either relative to \u003ccode\u003e$libdir\u003c/code\u003e or through the dynamic library path. This simplifies version upgrades if the new installation is at a different location. The actual directory that \u003ccode\u003e$libdir\u003c/code\u003e stands for can be found out with the command \u003ccode\u003epg_config --pkglibdir\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003eThe user ID the \u003cspan\u003ePostgreSQL\u003c/span\u003e server runs as must be able to traverse the path to the file you intend to load. Making the file or a higher-level directory not readable and/or not executable by the \u003cspan\u003epostgres\u003c/span\u003e user is a common mistake.\u003c/p\u003e\n\u003cp\u003eIn any case, the file name that is given in the \u003ccode\u003eCREATE FUNCTION\u003c/code\u003e command is recorded literally in the system catalogs, so if the file needs to be loaded again the same procedure is applied.\u003c/p\u003e\n\u003cdiv\u003e\n\u003ch3\u003eNote\u003c/h3\u003e\n\u003cp\u003e\u003cspan\u003ePostgreSQL\u003c/span\u003e will not compile a C function automatically. The object file must be compiled before it is referenced in a \u003ccode\u003eCREATE FUNCTION\u003c/code\u003e command. See \u003ca href=\"/docs/18/xfunc-c.html#DFUNC\" rel=\"nofollow\"\u003eSection 36.10.5\u003c/a\u003e for additional information.\u003c/p\u003e\n\u003c/div\u003e\n\u003cp\u003eTo ensure that a dynamically loaded object file is not loaded into an incompatible server, \u003cspan\u003ePostgreSQL\u003c/span\u003e checks that the file contains a \u003cspan\u003e“\u003cspan\u003emagic block\u003c/span\u003e”\u003c/span\u003e with the appropriate contents. This allows the server to detect obvious incompatibilities, such as code compiled for a different major version of \u003cspan\u003ePostgreSQL\u003c/span\u003e. To include a magic block, write this in one (and only one) of the module source files, after having included the header \u003ccode\u003efmgr.h\u003c/code\u003e:\u003c/p\u003e\n\u003cpre\u003ePG_MODULE_MAGIC;\n\u003c/pre\u003e\n\u003cp\u003eor\u003c/p\u003e\n\u003cpre\u003ePG_MODULE_MAGIC_EXT(\u003cem\u003e\u003ccode\u003eparameters\u003c/code\u003e\u003c/em\u003e);\n\u003c/pre\u003e\n\u003cp\u003eThe \u003ccode\u003ePG_MODULE_MAGIC_EXT\u003c/code\u003e variant allows the specification of additional information about the module; currently, a name and/or a version string can be added. (More fields might be allowed in future.) Write something like this:\u003c/p\u003e\n\u003cpre\u003ePG_MODULE_MAGIC_EXT(\n    .name = \u0026#34;my_module_name\u0026#34;,\n    .version = \u0026#34;1.2.3\u0026#34;\n);\n\u003c/pre\u003e\n\u003cp\u003eSubsequently the name and version can be examined via the \u003ccode\u003epg_get_loaded_modules()\u003c/code\u003e function. The meaning of the version string is not restricted by \u003cspan\u003ePostgreSQL\u003c/span\u003e, but use of semantic versioning rules is recommended.\u003c/p\u003e\n\u003cp\u003eAfter it is used for the first time, a dynamically loaded object file is retained in memory. Future calls in the same session to the function(s) in that file will only incur the small overhead of a symbol table lookup. If you need to force a reload of an object file, for example after recompiling it, begin a fresh session.\u003c/p\u003e\n\u003cp\u003eOptionally, a dynamically loaded file can contain an initialization function. If the file includes a function named \u003ccode\u003e_PG_init\u003c/code\u003e, that function will be called immediately after loading the file. The function receives no parameters and should return void. There is presently no way to unload a dynamically loaded file.\u003c/p\u003e\n\u003c/div\u003e\n\u003cdiv id=\"XFUNC-C-BASETYPE\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch3\u003e36.10.2. Base Types in C-Language Functions \u003c/h3\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003eTo know how to write C-language functions, you need to know how \u003cspan\u003ePostgreSQL\u003c/span\u003e internally represents base data types and how they can be passed to and from functions. Internally, \u003cspan\u003ePostgreSQL\u003c/span\u003e regards a base type as a \u003cspan\u003e“\u003cspan\u003eblob of memory\u003c/span\u003e”\u003c/span\u003e. The user-defined functions that you define over a type in turn define the way that \u003cspan\u003ePostgreSQL\u003c/span\u003e can operate on it. That is, \u003cspan\u003ePostgreSQL\u003c/span\u003e will only store and retrieve the data from disk and use your user-defined functions to input, process, and output the data.\u003c/p\u003e\n\u003cp\u003eBase types can have one of three internal formats:\u003c/p\u003e\n\u003cdiv\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003epass by value, fixed-length\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003epass by reference, fixed-length\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003epass by reference, variable-length\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/div\u003e\n\u003cp\u003eBy-value types can only be 1, 2, or 4 bytes in length (also 8 bytes, if \u003ccode\u003esizeof(Datum)\u003c/code\u003e is 8 on your machine). You should be careful to define your types such that they will be the same size (in bytes) on all architectures. For example, the \u003ccode\u003elong\u003c/code\u003e type is dangerous because it is 4 bytes on some machines and 8 bytes on others, whereas \u003ccode\u003eint\u003c/code\u003e type is 4 bytes on most Unix machines. A reasonable implementation of the \u003ccode\u003eint4\u003c/code\u003e type on Unix machines might be:\u003c/p\u003e\n\u003cpre\u003e/* 4-byte integer, passed by value */\ntypedef int int4;\n\u003c/pre\u003e\n\u003cp\u003e(The actual PostgreSQL C code calls this type \u003ccode\u003eint32\u003c/code\u003e, because it is a convention in C that \u003ccode\u003eint\u003cem\u003e\u003ccode\u003eXX\u003c/code\u003e\u003c/em\u003e\u003c/code\u003e means \u003cem\u003e\u003ccode\u003eXX\u003c/code\u003e\u003c/em\u003e \u003cspan\u003e\u003cem\u003ebits\u003c/em\u003e\u003c/span\u003e. Note therefore also that the C type \u003ccode\u003eint8\u003c/code\u003e is 1 byte in size. The SQL type \u003ccode\u003eint8\u003c/code\u003e is called \u003ccode\u003eint64\u003c/code\u003e in C. See also \u003ca href=\"/docs/18/xfunc-c.html#XFUNC-C-TYPE-TABLE\" rel=\"nofollow\"\u003eTable 36.2\u003c/a\u003e.)\u003c/p\u003e\n\u003cp\u003eOn the other hand, fixed-length types of any size can be passed by-reference. For example, here is a sample implementation of a \u003cspan\u003ePostgreSQL\u003c/span\u003e type:\u003c/p\u003e\n\u003cpre\u003e/* 16-byte structure, passed by reference */\ntypedef struct\n{\n    double  x, y;\n} Point;\n\u003c/pre\u003e\n\u003cp\u003eOnly pointers to such types can be used when passing them in and out of \u003cspan\u003ePostgreSQL\u003c/span\u003e functions. To return a value of such a type, allocate the right amount of memory with \u003ccode\u003epalloc\u003c/code\u003e, fill in the allocated memory, and return a pointer to it. (Also, if you just want to return the same value as one of your input arguments that\u0026#39;s of the same data type, you can skip the extra \u003ccode\u003epalloc\u003c/code\u003e and just return the pointer to the input value.)\u003c/p\u003e\n\u003cp\u003eFinally, all variable-length types must also be passed by reference. All variable-length types must begin with an opaque length field of exactly 4 bytes, which will be set by \u003ccode\u003eSET_VARSIZE\u003c/code\u003e; never set this field directly! All data to be stored within that type must be located in the memory immediately following that length field. The length field contains the total length of the structure, that is, it includes the size of the length field itself.\u003c/p\u003e\n\u003cp\u003eAnother important point is to avoid leaving any uninitialized bits within data type values; for example, take care to zero out any alignment padding bytes that might be present in structs. Without this, logically-equivalent constants of your data type might be seen as unequal by the planner, leading to inefficient (though not incorrect) plans.\u003c/p\u003e\n\u003cdiv\u003e\n\u003ch3\u003eWarning\u003c/h3\u003e\n\u003cp\u003e\u003cspan\u003e\u003cem\u003eNever\u003c/em\u003e\u003c/span\u003e modify the contents of a pass-by-reference input value. If you do so you are likely to corrupt on-disk data, since the pointer you are given might point directly into a disk buffer. The sole exception to this rule is explained in \u003ca href=\"/docs/18/xaggr.html\" rel=\"nofollow\"\u003eSection 36.12\u003c/a\u003e.\u003c/p\u003e\n\u003c/div\u003e\n\u003cp\u003eAs an example, we can define the type \u003ccode\u003etext\u003c/code\u003e as follows:\u003c/p\u003e\n\u003cpre\u003etypedef struct {\n    int32 length;\n    char data[FLEXIBLE_ARRAY_MEMBER];\n} text;\n\u003c/pre\u003e\n\u003cp\u003eThe \u003ccode\u003e[FLEXIBLE_ARRAY_MEMBER]\u003c/code\u003e notation means that the actual length of the data part is not specified by this declaration.\u003c/p\u003e\n\u003cp\u003eWhen manipulating variable-length types, we must be careful to allocate the correct amount of memory and set the length field correctly. For example, if we wanted to store 40 bytes in a \u003ccode\u003etext\u003c/code\u003e structure, we might use a code fragment like this:\u003c/p\u003e\n\u003cpre\u003e#include \u0026#34;postgres.h\u0026#34;\n...\nchar buffer[40]; /* our source data */\n...\ntext *destination = (text *) palloc(VARHDRSZ + 40);\nSET_VARSIZE(destination, VARHDRSZ + 40);\nmemcpy(destination-\u0026gt;data, buffer, 40);\n...\n\n\u003c/pre\u003e\n\u003cp\u003e\u003ccode\u003eVARHDRSZ\u003c/code\u003e is the same as \u003ccode\u003esizeof(int32)\u003c/code\u003e, but it\u0026#39;s considered good style to use the macro \u003ccode\u003eVARHDRSZ\u003c/code\u003e to refer to the size of the overhead for a variable-length type. Also, the length field \u003cspan\u003e\u003cem\u003emust\u003c/em\u003e\u003c/span\u003e be set using the \u003ccode\u003eSET_VARSIZE\u003c/code\u003e macro, not by simple assignment.\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"/docs/18/xfunc-c.html#XFUNC-C-TYPE-TABLE\" rel=\"nofollow\"\u003eTable 36.2\u003c/a\u003e shows the C types corresponding to many of the built-in SQL data types of \u003cspan\u003ePostgreSQL\u003c/span\u003e. The \u003cspan\u003e“\u003cspan\u003eDefined In\u003c/span\u003e”\u003c/span\u003e column gives the header file that needs to be included to get the type definition. (The actual definition might be in a different file that is included by the listed file. It is recommended that users stick to the defined interface.) Note that you should always include \u003ccode\u003epostgres.h\u003c/code\u003e first in any source file of server code, because it declares a number of things that you will need anyway, and because including other headers first can cause portability issues.\u003c/p\u003e\n\u003cdiv id=\"XFUNC-C-TYPE-TABLE\"\u003e\n\u003cp\u003e\u003cstrong\u003eTable 36.2. Equivalent C Types for Built-in SQL Types\u003c/strong\u003e\u003c/p\u003e\n\u003cdiv\u003e\n\u003ctable\u003e\n\n\n\n\n\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003eSQL Type\u003c/th\u003e\n\u003cth\u003eC Type\u003c/th\u003e\n\u003cth\u003eDefined In\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003eboolean\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003ebool\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003epostgres.h\u003c/code\u003e (maybe compiler built-in)\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003ebox\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003eBOX*\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003eutils/geo_decls.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003ebytea\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003ebytea*\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003epostgres.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e\u0026#34;char\u0026#34;\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003echar\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e(compiler built-in)\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003echaracter\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003eBpChar*\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003epostgres.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003ecid\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003eCommandId\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003epostgres.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003edate\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003eDateADT\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003eutils/date.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003efloat4\u003c/code\u003e (\u003ccode\u003ereal\u003c/code\u003e)\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003efloat4\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003epostgres.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003efloat8\u003c/code\u003e (\u003ccode\u003edouble precision\u003c/code\u003e)\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003efloat8\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003epostgres.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003eint2\u003c/code\u003e (\u003ccode\u003esmallint\u003c/code\u003e)\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003eint16\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003epostgres.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003eint4\u003c/code\u003e (\u003ccode\u003einteger\u003c/code\u003e)\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003eint32\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003epostgres.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003eint8\u003c/code\u003e (\u003ccode\u003ebigint\u003c/code\u003e)\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003eint64\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003epostgres.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003einterval\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003eInterval*\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003edatatype/timestamp.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003elseg\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003eLSEG*\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003eutils/geo_decls.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003ename\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003eName\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003epostgres.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003enumeric\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003eNumeric\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003eutils/numeric.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003eoid\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003eOid\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003epostgres.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003eoidvector\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003eoidvector*\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003epostgres.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003epath\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003ePATH*\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003eutils/geo_decls.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003epoint\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003ePOINT*\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003eutils/geo_decls.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003eregproc\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003eRegProcedure\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003epostgres.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003etext\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003etext*\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003epostgres.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003etid\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003eItemPointer\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003estorage/itemptr.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003etime\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003eTimeADT\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003eutils/date.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003etime with time zone\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003eTimeTzADT\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003eutils/date.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003etimestamp\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003eTimestamp\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003edatatype/timestamp.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003etimestamp with time zone\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003eTimestampTz\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003edatatype/timestamp.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003evarchar\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003eVarChar*\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003epostgres.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003exid\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003eTransactionId\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode\u003epostgres.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e\u003cbr\u003e\n\u003cp\u003eNow that we\u0026#39;ve gone over all of the possible structures for base types, we can show some examples of real functions.\u003c/p\u003e\n\u003c/div\u003e\n\u003cdiv id=\"XFUNC-C-V1-CALL-CONV\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch3\u003e36.10.3. Version 1 Calling Conventions \u003c/h3\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003eThe version-1 calling convention relies on macros to suppress most of the complexity of passing arguments and results. The C declaration of a version-1 function is always:\u003c/p\u003e\n\u003cpre\u003eDatum funcname(PG_FUNCTION_ARGS)\n\u003c/pre\u003e\n\u003cp\u003eIn addition, the macro call:\u003c/p\u003e\n\u003cpre\u003ePG_FUNCTION_INFO_V1(funcname);\n\u003c/pre\u003e\n\u003cp\u003emust appear in the same source file. (Conventionally, it\u0026#39;s written just before the function itself.) This macro call is not needed for \u003ccode\u003einternal\u003c/code\u003e-language functions, since \u003cspan\u003ePostgreSQL\u003c/span\u003e assumes that all internal functions use the version-1 convention. It is, however, required for dynamically-loaded functions.\u003c/p\u003e\n\u003cp\u003eIn a version-1 function, each actual argument is fetched using a \u003ccode\u003ePG_GETARG_\u003cem\u003e\u003ccode\u003exxx\u003c/code\u003e\u003c/em\u003e()\u003c/code\u003e macro that corresponds to the argument\u0026#39;s data type. (In non-strict functions there needs to be a previous check about argument null-ness using \u003ccode\u003ePG_ARGISNULL()\u003c/code\u003e; see below.) The result is returned using a \u003ccode\u003ePG_RETURN_\u003cem\u003e\u003ccode\u003exxx\u003c/code\u003e\u003c/em\u003e()\u003c/code\u003e macro for the return type. \u003ccode\u003ePG_GETARG_\u003cem\u003e\u003ccode\u003exxx\u003c/code\u003e\u003c/em\u003e()\u003c/code\u003e takes as its argument the number of the function argument to fetch, where the count starts at 0. \u003ccode\u003ePG_RETURN_\u003cem\u003e\u003ccode\u003exxx\u003c/code\u003e\u003c/em\u003e()\u003c/code\u003e takes as its argument the actual value to return.\u003c/p\u003e\n\u003cp\u003eTo call another version-1 function, you can use \u003ccode\u003eDirectFunctionCall\u003cem\u003e\u003ccode\u003en\u003c/code\u003e\u003c/em\u003e(func, arg1, ..., argn)\u003c/code\u003e. 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.\u003c/p\u003e\n\u003cp\u003eThese convenience functions and similar ones can be found in \u003ccode\u003efmgr.h\u003c/code\u003e. The \u003ccode\u003eDirectFunctionCall\u003cem\u003e\u003ccode\u003en\u003c/code\u003e\u003c/em\u003e\u003c/code\u003e family expect a C function name as their first argument. There are also \u003ccode\u003eOidFunctionCall\u003cem\u003e\u003ccode\u003en\u003c/code\u003e\u003c/em\u003e\u003c/code\u003e which take the OID of the target function, and some other variants. All of these expect the function\u0026#39;s arguments to be supplied as \u003ccode\u003eDatum\u003c/code\u003es, and likewise they return \u003ccode\u003eDatum\u003c/code\u003e. Note that neither arguments nor result are allowed to be NULL when using these convenience functions.\u003c/p\u003e\n\u003cp\u003eFor example, to call the \u003ccode\u003estarts_with(text, text)\u003c/code\u003e function from C, you can search through the catalog and find out that its C implementation is the \u003ccode\u003eDatum text_starts_with(PG_FUNCTION_ARGS)\u003c/code\u003e function. Typically you would use \u003ccode\u003eDirectFunctionCall2(text_starts_with, ...)\u003c/code\u003e to call such a function. However, \u003ccode\u003estarts_with(text, text)\u003c/code\u003e requires collation information, so it will fail with \u003cspan\u003e“\u003cspan\u003ecould not determine which collation to use for string comparison\u003c/span\u003e”\u003c/span\u003e if called that way. Instead you must use \u003ccode\u003eDirectFunctionCall2Coll(text_starts_with, ...)\u003c/code\u003e and provide the desired collation, which typically is just passed through from \u003ccode\u003ePG_GET_COLLATION()\u003c/code\u003e, as shown in the example below.\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003efmgr.h\u003c/code\u003e also supplies macros that facilitate conversions between C types and \u003ccode\u003eDatum\u003c/code\u003e. For example to turn \u003ccode\u003eDatum\u003c/code\u003e into \u003ccode\u003etext*\u003c/code\u003e, you can use \u003ccode\u003eDatumGetTextPP(X)\u003c/code\u003e. While some types have macros named like \u003ccode\u003eTypeGetDatum(X)\u003c/code\u003e for the reverse conversion, \u003ccode\u003etext*\u003c/code\u003e does not; it\u0026#39;s sufficient to use the generic macro \u003ccode\u003ePointerGetDatum(X)\u003c/code\u003e for that. If your extension defines additional types, it is usually convenient to define similar macros for your types too.\u003c/p\u003e\n\u003cp\u003eHere are some examples using the version-1 calling convention:\u003c/p\u003e\n\u003cpre\u003e#include \u0026#34;postgres.h\u0026#34;\n#include \u0026lt;string.h\u0026gt;\n#include \u0026#34;fmgr.h\u0026#34;\n#include \u0026#34;utils/geo_decls.h\u0026#34;\n#include \u0026#34;varatt.h\u0026#34;\n\nPG_MODULE_MAGIC;\n\n/* by value */\n\nPG_FUNCTION_INFO_V1(add_one);\n\nDatum\nadd_one(PG_FUNCTION_ARGS)\n{\n    int32   arg = PG_GETARG_INT32(0);\n\n    PG_RETURN_INT32(arg + 1);\n}\n\n/* by reference, fixed length */\n\nPG_FUNCTION_INFO_V1(add_one_float8);\n\nDatum\nadd_one_float8(PG_FUNCTION_ARGS)\n{\n    /* The macros for FLOAT8 hide its pass-by-reference nature. */\n    float8   arg = PG_GETARG_FLOAT8(0);\n\n    PG_RETURN_FLOAT8(arg + 1.0);\n}\n\nPG_FUNCTION_INFO_V1(makepoint);\n\nDatum\nmakepoint(PG_FUNCTION_ARGS)\n{\n    /* Here, the pass-by-reference nature of Point is not hidden. */\n    Point     *pointx = PG_GETARG_POINT_P(0);\n    Point     *pointy = PG_GETARG_POINT_P(1);\n    Point     *new_point = (Point *) palloc(sizeof(Point));\n\n    new_point-\u0026gt;x = pointx-\u0026gt;x;\n    new_point-\u0026gt;y = pointy-\u0026gt;y;\n\n    PG_RETURN_POINT_P(new_point);\n}\n\n/* by reference, variable length */\n\nPG_FUNCTION_INFO_V1(copytext);\n\nDatum\ncopytext(PG_FUNCTION_ARGS)\n{\n    text     *t = PG_GETARG_TEXT_PP(0);\n\n    /*\n     * VARSIZE_ANY_EXHDR is the size of the struct in bytes, minus the\n     * VARHDRSZ or VARHDRSZ_SHORT of its header.  Construct the copy with a\n     * full-length header.\n     */\n    text     *new_t = (text *) palloc(VARSIZE_ANY_EXHDR(t) + VARHDRSZ);\n    SET_VARSIZE(new_t, VARSIZE_ANY_EXHDR(t) + VARHDRSZ);\n\n    /*\n     * VARDATA is a pointer to the data region of the new struct.  The source\n     * could be a short datum, so retrieve its data through VARDATA_ANY.\n     */\n    memcpy(VARDATA(new_t),          /* destination */\n           VARDATA_ANY(t),          /* source */\n           VARSIZE_ANY_EXHDR(t));   /* how many bytes */\n    PG_RETURN_TEXT_P(new_t);\n}\n\nPG_FUNCTION_INFO_V1(concat_text);\n\nDatum\nconcat_text(PG_FUNCTION_ARGS)\n{\n    text  *arg1 = PG_GETARG_TEXT_PP(0);\n    text  *arg2 = PG_GETARG_TEXT_PP(1);\n    int32 arg1_size = VARSIZE_ANY_EXHDR(arg1);\n    int32 arg2_size = VARSIZE_ANY_EXHDR(arg2);\n    int32 new_text_size = arg1_size + arg2_size + VARHDRSZ;\n    text *new_text = (text *) palloc(new_text_size);\n\n    SET_VARSIZE(new_text, new_text_size);\n    memcpy(VARDATA(new_text), VARDATA_ANY(arg1), arg1_size);\n    memcpy(VARDATA(new_text) + arg1_size, VARDATA_ANY(arg2), arg2_size);\n    PG_RETURN_TEXT_P(new_text);\n}\n\n/* A wrapper around starts_with(text, text) */\n\nPG_FUNCTION_INFO_V1(t_starts_with);\n\nDatum\nt_starts_with(PG_FUNCTION_ARGS)\n{\n    text       *t1 = PG_GETARG_TEXT_PP(0);\n    text       *t2 = PG_GETARG_TEXT_PP(1);\n    Oid         collid = PG_GET_COLLATION();\n    bool        result;\n\n    result = DatumGetBool(DirectFunctionCall2Coll(text_starts_with,\n                                                  collid,\n                                                  PointerGetDatum(t1),\n                                                  PointerGetDatum(t2)));\n    PG_RETURN_BOOL(result);\n}\n\n\u003c/pre\u003e\n\u003cp\u003eSupposing that the above code has been prepared in file \u003ccode\u003efuncs.c\u003c/code\u003e and compiled into a shared object, we could define the functions to \u003cspan\u003ePostgreSQL\u003c/span\u003e with commands like this:\u003c/p\u003e\n\u003cpre\u003eCREATE FUNCTION add_one(integer) RETURNS integer\n     AS \u0026#39;\u003cem\u003e\u003ccode\u003eDIRECTORY\u003c/code\u003e\u003c/em\u003e/funcs\u0026#39;, \u0026#39;add_one\u0026#39;\n     LANGUAGE C STRICT;\n\n-- note overloading of SQL function name \u0026#34;add_one\u0026#34;\nCREATE FUNCTION add_one(double precision) RETURNS double precision\n     AS \u0026#39;\u003cem\u003e\u003ccode\u003eDIRECTORY\u003c/code\u003e\u003c/em\u003e/funcs\u0026#39;, \u0026#39;add_one_float8\u0026#39;\n     LANGUAGE C STRICT;\n\nCREATE FUNCTION makepoint(point, point) RETURNS point\n     AS \u0026#39;\u003cem\u003e\u003ccode\u003eDIRECTORY\u003c/code\u003e\u003c/em\u003e/funcs\u0026#39;, \u0026#39;makepoint\u0026#39;\n     LANGUAGE C STRICT;\n\nCREATE FUNCTION copytext(text) RETURNS text\n     AS \u0026#39;\u003cem\u003e\u003ccode\u003eDIRECTORY\u003c/code\u003e\u003c/em\u003e/funcs\u0026#39;, \u0026#39;copytext\u0026#39;\n     LANGUAGE C STRICT;\n\nCREATE FUNCTION concat_text(text, text) RETURNS text\n     AS \u0026#39;\u003cem\u003e\u003ccode\u003eDIRECTORY\u003c/code\u003e\u003c/em\u003e/funcs\u0026#39;, \u0026#39;concat_text\u0026#39;\n     LANGUAGE C STRICT;\n\nCREATE FUNCTION t_starts_with(text, text) RETURNS boolean\n     AS \u0026#39;\u003cem\u003e\u003ccode\u003eDIRECTORY\u003c/code\u003e\u003c/em\u003e/funcs\u0026#39;, \u0026#39;t_starts_with\u0026#39;\n     LANGUAGE C STRICT;\n\u003c/pre\u003e\n\u003cp\u003eHere, \u003cem\u003e\u003ccode\u003eDIRECTORY\u003c/code\u003e\u003c/em\u003e stands for the directory of the shared library file (for instance the \u003cspan\u003ePostgreSQL\u003c/span\u003e tutorial directory, which contains the code for the examples used in this section). (Better style would be to use just \u003ccode\u003e\u0026#39;funcs\u0026#39;\u003c/code\u003e in the \u003ccode\u003eAS\u003c/code\u003e clause, after having added \u003cem\u003e\u003ccode\u003eDIRECTORY\u003c/code\u003e\u003c/em\u003e to the search path. In any case, we can omit the system-specific extension for a shared library, commonly \u003ccode\u003e.so\u003c/code\u003e.)\u003c/p\u003e\n\u003cp\u003eNotice that we have specified the functions as \u003cspan\u003e“\u003cspan\u003estrict\u003c/span\u003e”\u003c/span\u003e, 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\u0026#39;d have to check for null values explicitly, using \u003ccode\u003ePG_ARGISNULL()\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003eThe macro \u003ccode\u003ePG_ARGISNULL(\u003cem\u003e\u003ccode\u003en\u003c/code\u003e\u003c/em\u003e)\u003c/code\u003e allows a function to test whether each input is null. (Of course, doing this is only necessary in functions not declared \u003cspan\u003e“\u003cspan\u003estrict\u003c/span\u003e”\u003c/span\u003e.) As with the \u003ccode\u003ePG_GETARG_\u003cem\u003e\u003ccode\u003exxx\u003c/code\u003e\u003c/em\u003e()\u003c/code\u003e macros, the input arguments are counted beginning at zero. Note that one should refrain from executing \u003ccode\u003ePG_GETARG_\u003cem\u003e\u003ccode\u003exxx\u003c/code\u003e\u003c/em\u003e()\u003c/code\u003e until one has verified that the argument isn\u0026#39;t null. To return a null result, execute \u003ccode\u003ePG_RETURN_NULL()\u003c/code\u003e; this works in both strict and nonstrict functions.\u003c/p\u003e\n\u003cp\u003eAt first glance, the version-1 coding conventions might appear to be just pointless obscurantism, compared to using plain \u003ccode\u003eC\u003c/code\u003e calling conventions. They do however allow us to deal with \u003ccode\u003eNULL\u003c/code\u003eable arguments/return values, and \u003cspan\u003e“\u003cspan\u003etoasted\u003c/span\u003e”\u003c/span\u003e (compressed or out-of-line) values.\u003c/p\u003e\n\u003cp\u003eOther options provided by the version-1 interface are two variants of the \u003ccode\u003ePG_GETARG_\u003cem\u003e\u003ccode\u003exxx\u003c/code\u003e\u003c/em\u003e()\u003c/code\u003e macros. The first of these, \u003ccode\u003ePG_GETARG_\u003cem\u003e\u003ccode\u003exxx\u003c/code\u003e\u003c/em\u003e_COPY()\u003c/code\u003e, guarantees to return a copy of the specified argument that is safe for writing into. (The normal macros will sometimes return a pointer to a value that is physically stored in a table, which must not be written to. Using the \u003ccode\u003ePG_GETARG_\u003cem\u003e\u003ccode\u003exxx\u003c/code\u003e\u003c/em\u003e_COPY()\u003c/code\u003e macros guarantees a writable result.) The second variant consists of the \u003ccode\u003ePG_GETARG_\u003cem\u003e\u003ccode\u003exxx\u003c/code\u003e\u003c/em\u003e_SLICE()\u003c/code\u003e macros which take three arguments. The first is the number of the function argument (as above). The second and third are the offset and length of the segment to be returned. Offsets are counted from zero, and a negative length requests that the remainder of the value be returned. These macros provide more efficient access to parts of large values in the case where they have storage type \u003cspan\u003e“\u003cspan\u003eexternal\u003c/span\u003e”\u003c/span\u003e. (The storage type of a column can be specified using \u003ccode\u003eALTER TABLE \u003cem\u003e\u003ccode\u003etablename\u003c/code\u003e\u003c/em\u003e ALTER COLUMN \u003cem\u003e\u003ccode\u003ecolname\u003c/code\u003e\u003c/em\u003e SET STORAGE \u003cem\u003e\u003ccode\u003estoragetype\u003c/code\u003e\u003c/em\u003e\u003c/code\u003e. \u003cem\u003e\u003ccode\u003estoragetype\u003c/code\u003e\u003c/em\u003e is one of \u003ccode\u003eplain\u003c/code\u003e, \u003ccode\u003eexternal\u003c/code\u003e, \u003ccode\u003eextended\u003c/code\u003e, or \u003ccode\u003emain\u003c/code\u003e.)\u003c/p\u003e\n\u003cp\u003eFinally, the version-1 function call conventions make it possible to return set results (\u003ca href=\"/docs/18/xfunc-c.html#XFUNC-C-RETURN-SET\" rel=\"nofollow\"\u003eSection 36.10.9\u003c/a\u003e) and implement trigger functions (\u003ca href=\"/docs/18/triggers.html\" rel=\"nofollow\"\u003eChapter 37\u003c/a\u003e) and procedural-language call handlers (\u003ca href=\"/docs/18/plhandler.html\" rel=\"nofollow\"\u003eChapter 57\u003c/a\u003e). For more details see \u003ccode\u003esrc/backend/utils/fmgr/README\u003c/code\u003e in the source distribution.\u003c/p\u003e\n\u003c/div\u003e\n\u003cdiv id=\"XFUNC-C-CODE\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch3\u003e36.10.4. Writing Code \u003c/h3\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003eBefore we turn to the more advanced topics, we should discuss some coding rules for \u003cspan\u003ePostgreSQL\u003c/span\u003e C-language functions. While it might be possible to load functions written in languages other than C into \u003cspan\u003ePostgreSQL\u003c/span\u003e, this is usually difficult (when it is possible at all) because other languages, such as C++, FORTRAN, or Pascal often do not follow the same calling convention as C. That is, other languages do not pass argument and return values between functions in the same way. For this reason, we will assume that your C-language functions are actually written in C.\u003c/p\u003e\n\u003cp\u003eThe basic rules for writing and building C functions are as follows:\u003c/p\u003e\n\u003cdiv\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003eUse \u003ccode\u003epg_config --includedir-server\u003c/code\u003e to find out where the \u003cspan\u003ePostgreSQL\u003c/span\u003e server header files are installed on your system (or the system that your users will be running on).\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eCompiling and linking your code so that it can be dynamically loaded into \u003cspan\u003ePostgreSQL\u003c/span\u003e always requires special flags. See \u003ca href=\"/docs/18/xfunc-c.html#DFUNC\" rel=\"nofollow\"\u003eSection 36.10.5\u003c/a\u003e for a detailed explanation of how to do it for your particular operating system.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eRemember to define a \u003cspan\u003e“\u003cspan\u003emagic block\u003c/span\u003e”\u003c/span\u003e for your shared library, as described in \u003ca href=\"/docs/18/xfunc-c.html#XFUNC-C-DYNLOAD\" rel=\"nofollow\"\u003eSection 36.10.1\u003c/a\u003e.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eWhen allocating memory, use the \u003cspan\u003ePostgreSQL\u003c/span\u003e functions \u003ccode\u003epalloc\u003c/code\u003e and \u003ccode\u003epfree\u003c/code\u003e instead of the corresponding C library functions \u003ccode\u003emalloc\u003c/code\u003e and \u003ccode\u003efree\u003c/code\u003e. The memory allocated by \u003ccode\u003epalloc\u003c/code\u003e will be freed automatically at the end of each transaction, preventing memory leaks.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eAlways zero the bytes of your structures using \u003ccode\u003ememset\u003c/code\u003e (or allocate them with \u003ccode\u003epalloc0\u003c/code\u003e in the first place). Even if you assign to each field of your structure, there might be alignment padding (holes in the structure) that contain garbage values. Without this, it\u0026#39;s difficult to support hash indexes or hash joins, as you must pick out only the significant bits of your data structure to compute a hash. The planner also sometimes relies on comparing constants via bitwise equality, so you can get undesirable planning results if logically-equivalent values aren\u0026#39;t bitwise equal.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eMost of the internal \u003cspan\u003ePostgreSQL\u003c/span\u003e types are declared in \u003ccode\u003epostgres.h\u003c/code\u003e, while the function manager interfaces (\u003ccode\u003ePG_FUNCTION_ARGS\u003c/code\u003e, etc.) are in \u003ccode\u003efmgr.h\u003c/code\u003e, so you will need to include at least these two files. For portability reasons it\u0026#39;s best to include \u003ccode\u003epostgres.h\u003c/code\u003e \u003cspan\u003e\u003cem\u003efirst\u003c/em\u003e\u003c/span\u003e, before any other system or user header files. Including \u003ccode\u003epostgres.h\u003c/code\u003e will also include \u003ccode\u003eelog.h\u003c/code\u003e and \u003ccode\u003epalloc.h\u003c/code\u003e for you.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eSymbol names defined within object files must not conflict with each other or with symbols defined in the \u003cspan\u003ePostgreSQL\u003c/span\u003e server executable. You will have to rename your functions or variables if you get error messages to this effect.\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cdiv id=\"DFUNC\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch3\u003e36.10.5. Compiling and Linking Dynamically-Loaded Functions \u003c/h3\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003eBefore you are able to use your \u003cspan\u003ePostgreSQL\u003c/span\u003e extension functions written in C, they must be compiled and linked in a special way to produce a file that can be dynamically loaded by the server. To be precise, a \u003cem\u003eshared library\u003c/em\u003e needs to be created.\u003c/p\u003e\n\u003cp\u003eFor information beyond what is contained in this section you should read the documentation of your operating system, in particular the manual pages for the C compiler, \u003ccode\u003ecc\u003c/code\u003e, and the link editor, \u003ccode\u003eld\u003c/code\u003e. In addition, the \u003cspan\u003ePostgreSQL\u003c/span\u003e source code contains several working examples in the \u003ccode\u003econtrib\u003c/code\u003e directory. If you rely on these examples you will make your modules dependent on the availability of the \u003cspan\u003ePostgreSQL\u003c/span\u003e source code, however.\u003c/p\u003e\n\u003cp\u003eCreating shared libraries is generally analogous to linking executables: first the source files are compiled into object files, then the object files are linked together. The object files need to be created as \u003cem\u003eposition-independent code\u003c/em\u003e (PIC), which conceptually means that they can be placed at an arbitrary location in memory when they are loaded by the executable. (Object files intended for executables are usually not compiled that way.) The command to link a shared library contains special flags to distinguish it from linking an executable (at least in theory — on some systems the practice is much uglier).\u003c/p\u003e\n\u003cp\u003eIn the following examples we assume that your source code is in a file \u003ccode\u003efoo.c\u003c/code\u003e and we will create a shared library \u003ccode\u003efoo.so\u003c/code\u003e. The intermediate object file will be called \u003ccode\u003efoo.o\u003c/code\u003e unless otherwise noted. A shared library can contain more than one object file, but we only use one here.\u003c/p\u003e\n\u003cdiv\u003e\n\u003cdl\u003e\n\u003cdt\u003e\u003cspan\u003e\u003cspan\u003eFreeBSD\u003c/span\u003e \u003c/span\u003e\u003c/dt\u003e\n\u003cdd\u003e\n\u003cp\u003eThe compiler flag to create PIC is \u003ccode\u003e-fPIC\u003c/code\u003e. To create shared libraries the compiler flag is \u003ccode\u003e-shared\u003c/code\u003e.\u003c/p\u003e\n\u003cpre\u003ecc -fPIC -c foo.c\ncc -shared -o foo.so foo.o\n\u003c/pre\u003e\n\u003cp\u003eThis is applicable as of version 13.0 of \u003cspan\u003eFreeBSD\u003c/span\u003e, older versions used the \u003ccode\u003egcc\u003c/code\u003e compiler.\u003c/p\u003e\n\u003c/dd\u003e\n\u003cdt\u003e\u003cspan\u003e\u003cspan\u003eLinux\u003c/span\u003e \u003c/span\u003e\u003c/dt\u003e\n\u003cdd\u003e\n\u003cp\u003eThe compiler flag to create PIC is \u003ccode\u003e-fPIC\u003c/code\u003e. The compiler flag to create a shared library is \u003ccode\u003e-shared\u003c/code\u003e. A complete example looks like this:\u003c/p\u003e\n\u003cpre\u003ecc -fPIC -c foo.c\ncc -shared -o foo.so foo.o\n\u003c/pre\u003e\n\u003c/dd\u003e\n\u003cdt\u003e\u003cspan\u003e\u003cspan\u003emacOS\u003c/span\u003e \u003c/span\u003e\u003c/dt\u003e\n\u003cdd\u003e\n\u003cp\u003eHere is an example. It assumes the developer tools are installed.\u003c/p\u003e\n\u003cpre\u003ecc -c foo.c\ncc -bundle -flat_namespace -undefined suppress -o foo.so foo.o\n\u003c/pre\u003e\n\u003c/dd\u003e\n\u003cdt\u003e\u003cspan\u003e\u003cspan\u003eNetBSD\u003c/span\u003e \u003c/span\u003e\u003c/dt\u003e\n\u003cdd\u003e\n\u003cp\u003eThe compiler flag to create PIC is \u003ccode\u003e-fPIC\u003c/code\u003e. For ELF systems, the compiler with the flag \u003ccode\u003e-shared\u003c/code\u003e is used to link shared libraries. On the older non-ELF systems, \u003ccode\u003eld -Bshareable\u003c/code\u003e is used.\u003c/p\u003e\n\u003cpre\u003egcc -fPIC -c foo.c\ngcc -shared -o foo.so foo.o\n\u003c/pre\u003e\n\u003c/dd\u003e\n\u003cdt\u003e\u003cspan\u003e\u003cspan\u003eOpenBSD\u003c/span\u003e \u003c/span\u003e\u003c/dt\u003e\n\u003cdd\u003e\n\u003cp\u003eThe compiler flag to create PIC is \u003ccode\u003e-fPIC\u003c/code\u003e. \u003ccode\u003eld -Bshareable\u003c/code\u003e is used to link shared libraries.\u003c/p\u003e\n\u003cpre\u003egcc -fPIC -c foo.c\nld -Bshareable -o foo.so foo.o\n\u003c/pre\u003e\n\u003c/dd\u003e\n\u003cdt\u003e\u003cspan\u003e\u003cspan\u003eSolaris\u003c/span\u003e \u003c/span\u003e\u003c/dt\u003e\n\u003cdd\u003e\n\u003cp\u003eThe compiler flag to create PIC is \u003ccode\u003e-KPIC\u003c/code\u003e with the Sun compiler and \u003ccode\u003e-fPIC\u003c/code\u003e with \u003cspan\u003eGCC\u003c/span\u003e. To link shared libraries, the compiler option is \u003ccode\u003e-G\u003c/code\u003e with either compiler or alternatively \u003ccode\u003e-shared\u003c/code\u003e with \u003cspan\u003eGCC\u003c/span\u003e.\u003c/p\u003e\n\u003cpre\u003ecc -KPIC -c foo.c\ncc -G -o foo.so foo.o\n\u003c/pre\u003e\n\u003cp\u003eor\u003c/p\u003e\n\u003cpre\u003egcc -fPIC -c foo.c\ngcc -G -o foo.so foo.o\n\u003c/pre\u003e\n\u003c/dd\u003e\n\u003c/dl\u003e\n\u003c/div\u003e\n\u003cdiv\u003e\n\u003ch3\u003eTip\u003c/h3\u003e\n\u003cp\u003eIf this is too complicated for you, you should consider using \u003ca href=\"https://www.gnu.org/software/libtool/\" rel=\"nofollow\"\u003e\u003cspan\u003eGNU Libtool\u003c/span\u003e\u003c/a\u003e, which hides the platform differences behind a uniform interface.\u003c/p\u003e\n\u003c/div\u003e\n\u003cp\u003eThe resulting shared library file can then be loaded into \u003cspan\u003ePostgreSQL\u003c/span\u003e. When specifying the file name to the \u003ccode\u003eCREATE FUNCTION\u003c/code\u003e command, one must give it the name of the shared library file, not the intermediate object file. Note that the system\u0026#39;s standard shared-library extension (usually \u003ccode\u003e.so\u003c/code\u003e or \u003ccode\u003e.sl\u003c/code\u003e) can be omitted from the \u003ccode\u003eCREATE FUNCTION\u003c/code\u003e command, and normally should be omitted for best portability.\u003c/p\u003e\n\u003cp\u003eRefer back to \u003ca href=\"/docs/18/xfunc-c.html#XFUNC-C-DYNLOAD\" rel=\"nofollow\"\u003eSection 36.10.1\u003c/a\u003e about where the server expects to find the shared library files.\u003c/p\u003e\n\u003c/div\u003e\n\u003cdiv id=\"XFUNC-API-ABI-STABILITY-GUIDANCE\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch3\u003e36.10.6. Server API and ABI Stability Guidance \u003c/h3\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003eThis section contains guidance to authors of extensions and other server plugins about API and ABI stability in the \u003cspan\u003ePostgreSQL\u003c/span\u003e server.\u003c/p\u003e\n\u003cdiv id=\"XFUNC-GUIDANCE-GENERAL\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch4\u003e36.10.6.1. General \u003c/h4\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003eThe \u003cspan\u003ePostgreSQL\u003c/span\u003e server contains several well-demarcated APIs for server plugins, such as the function manager (fmgr, described in this chapter), SPI (\u003ca href=\"/docs/18/spi.html\" rel=\"nofollow\"\u003eChapter 45\u003c/a\u003e), and various hooks specifically designed for extensions. These interfaces are carefully managed for long-term stability and compatibility. However, the entire set of global functions and variables in the server effectively constitutes the publicly usable API, and most of it was not designed with extensibility and long-term stability in mind.\u003c/p\u003e\n\u003cp\u003eTherefore, while taking advantage of these interfaces is valid, the further one strays from the well-trodden path, the likelier it will be that one might encounter API or ABI compatibility issues at some point. Extension authors are encouraged to provide feedback about their requirements, so that over time, as new use patterns arise, certain interfaces can be considered more stabilized or new, better-designed interfaces can be added.\u003c/p\u003e\n\u003c/div\u003e\n\u003cdiv id=\"XFUNC-GUIDANCE-API-COMPATIBILITY\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch4\u003e36.10.6.2. API Compatibility \u003c/h4\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003eThe API, or application programming interface, is the interface used at compile time.\u003c/p\u003e\n\u003cdiv id=\"XFUNC-GUIDANCE-API-MAJOR-VERSIONS\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch5\u003e36.10.6.2.1. Major Versions \u003c/h5\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003eThere is \u003cspan\u003e\u003cem\u003eno\u003c/em\u003e\u003c/span\u003e promise of API compatibility between \u003cspan\u003ePostgreSQL\u003c/span\u003e major versions. Extension code therefore might require source code changes to work with multiple major versions. These can usually be managed with preprocessor conditions such as \u003ccode\u003e#if PG_VERSION_NUM \u0026gt;= 160000\u003c/code\u003e. Sophisticated extensions that use interfaces beyond the well-demarcated ones usually require a few such changes for each major server version.\u003c/p\u003e\n\u003c/div\u003e\n\u003cdiv id=\"XFUNC-GUIDANCE-API-MNINOR-VERSIONS\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch5\u003e36.10.6.2.2. Minor Versions \u003c/h5\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003e\u003cspan\u003ePostgreSQL\u003c/span\u003e makes an effort to avoid server API breaks in minor releases. In general, extension code that compiles and works with a minor release should also compile and work with any other minor release of the same major version, past or future.\u003c/p\u003e\n\u003cp\u003eWhen a change \u003cspan\u003e\u003cem\u003eis\u003c/em\u003e\u003c/span\u003e required, it will be carefully managed, taking the requirements of extensions into account. Such changes will be communicated in the release notes (\u003ca href=\"/docs/18/release.html\" rel=\"nofollow\"\u003eAppendix E\u003c/a\u003e).\u003c/p\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cdiv id=\"XFUNC-GUIDANCE-ABI-COMPATIBILITY\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch4\u003e36.10.6.3. ABI Compatibility \u003c/h4\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003eThe ABI, or application binary interface, is the interface used at run time.\u003c/p\u003e\n\u003cdiv id=\"XFUNC-GUIDANCE-ABI-MAJOR-VERSIONS\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch5\u003e36.10.6.3.1. Major Versions \u003c/h5\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003eServers of different major versions have intentionally incompatible ABIs. Extensions that use server APIs must therefore be re-compiled for each major release. The inclusion of \u003ccode\u003ePG_MODULE_MAGIC\u003c/code\u003e (see \u003ca href=\"/docs/18/xfunc-c.html#XFUNC-C-DYNLOAD\" rel=\"nofollow\"\u003eSection 36.10.1\u003c/a\u003e) ensures that code compiled for one major version will be rejected by other major versions.\u003c/p\u003e\n\u003c/div\u003e\n\u003cdiv id=\"XFUNC-GUIDANCE-ABI-MNINOR-VERSIONS\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch5\u003e36.10.6.3.2. Minor Versions \u003c/h5\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003e\u003cspan\u003ePostgreSQL\u003c/span\u003e makes an effort to avoid server ABI breaks in minor releases. In general, an extension compiled against any minor release should work with any other minor release of the same major version, past or future.\u003c/p\u003e\n\u003cp\u003eWhen a change \u003cspan\u003e\u003cem\u003eis\u003c/em\u003e\u003c/span\u003e required, \u003cspan\u003ePostgreSQL\u003c/span\u003e will choose the least invasive change possible, for example by squeezing a new field into padding space or appending it to the end of a struct. These sorts of changes should not impact extensions unless they use very unusual code patterns.\u003c/p\u003e\n\u003cp\u003eIn rare cases, however, even such non-invasive changes may be impractical or impossible. In such an event, the change will be carefully managed, taking the requirements of extensions into account. Such changes will also be documented in the release notes (\u003ca href=\"/docs/18/release.html\" rel=\"nofollow\"\u003eAppendix E\u003c/a\u003e).\u003c/p\u003e\n\u003cp\u003eNote, however, that many parts of the server are not designed or maintained as publicly-consumable APIs (and that, in most cases, the actual boundary is also not well-defined). If urgent needs arise, changes in those parts will naturally be made with less consideration for extension code than changes in well-defined and widely used interfaces.\u003c/p\u003e\n\u003cp\u003eAlso, in the absence of automated detection of such changes, this is not a guarantee, but historically such breaking changes have been extremely rare.\u003c/p\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cdiv id=\"XFUNC-C-COMPOSITE-TYPE-ARGS\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch3\u003e36.10.7. Composite-Type Arguments \u003c/h3\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003eComposite types do not have a fixed layout like C structures. Instances of a composite type can contain null fields. In addition, composite types that are part of an inheritance hierarchy can have different fields than other members of the same inheritance hierarchy. Therefore, \u003cspan\u003ePostgreSQL\u003c/span\u003e provides a function interface for accessing fields of composite types from C.\u003c/p\u003e\n\u003cp\u003eSuppose we want to write a function to answer the query:\u003c/p\u003e\n\u003cpre\u003eSELECT name, c_overpaid(emp, 1500) AS overpaid\n    FROM emp\n    WHERE name = \u0026#39;Bill\u0026#39; OR name = \u0026#39;Sam\u0026#39;;\n\u003c/pre\u003e\n\u003cp\u003eUsing the version-1 calling conventions, we can define \u003ccode\u003ec_overpaid\u003c/code\u003e as:\u003c/p\u003e\n\u003cpre\u003e#include \u0026#34;postgres.h\u0026#34;\n#include \u0026#34;executor/executor.h\u0026#34;  /* for GetAttributeByName() */\n\nPG_MODULE_MAGIC;\n\nPG_FUNCTION_INFO_V1(c_overpaid);\n\nDatum\nc_overpaid(PG_FUNCTION_ARGS)\n{\n    HeapTupleHeader  t = PG_GETARG_HEAPTUPLEHEADER(0);\n    int32            limit = PG_GETARG_INT32(1);\n    bool isnull;\n    Datum salary;\n\n    salary = GetAttributeByName(t, \u0026#34;salary\u0026#34;, \u0026amp;isnull);\n    if (isnull)\n        PG_RETURN_BOOL(false);\n    /* Alternatively, we might prefer to do PG_RETURN_NULL() for null salary. */\n\n    PG_RETURN_BOOL(DatumGetInt32(salary) \u0026gt; limit);\n}\n\n\u003c/pre\u003e\n\u003cp\u003e\u003ccode\u003eGetAttributeByName\u003c/code\u003e is the \u003cspan\u003ePostgreSQL\u003c/span\u003e system function that returns attributes out of the specified row. It has three arguments: the argument of type \u003ccode\u003eHeapTupleHeader\u003c/code\u003e passed into the function, the name of the desired attribute, and a return parameter that tells whether the attribute is null. \u003ccode\u003eGetAttributeByName\u003c/code\u003e returns a \u003ccode\u003eDatum\u003c/code\u003e value that you can convert to the proper data type by using the appropriate \u003ccode\u003eDatumGet\u003cem\u003e\u003ccode\u003eXXX\u003c/code\u003e\u003c/em\u003e()\u003c/code\u003e function. Note that the return value is meaningless if the null flag is set; always check the null flag before trying to do anything with the result.\u003c/p\u003e\n\u003cp\u003eThere is also \u003ccode\u003eGetAttributeByNum\u003c/code\u003e, which selects the target attribute by column number instead of name.\u003c/p\u003e\n\u003cp\u003eThe following command declares the function \u003ccode\u003ec_overpaid\u003c/code\u003e in SQL:\u003c/p\u003e\n\u003cpre\u003eCREATE FUNCTION c_overpaid(emp, integer) RETURNS boolean\n    AS \u0026#39;\u003cem\u003e\u003ccode\u003eDIRECTORY\u003c/code\u003e\u003c/em\u003e/funcs\u0026#39;, \u0026#39;c_overpaid\u0026#39;\n    LANGUAGE C STRICT;\n\u003c/pre\u003e\n\u003cp\u003eNotice we have used \u003ccode\u003eSTRICT\u003c/code\u003e so that we did not have to check whether the input arguments were NULL.\u003c/p\u003e\n\u003c/div\u003e\n\u003cdiv id=\"XFUNC-C-RETURNING-ROWS\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch3\u003e36.10.8. Returning Rows (Composite Types) \u003c/h3\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003eTo return a row or composite-type value from a C-language function, you can use a special API that provides macros and functions to hide most of the complexity of building composite data types. To use this API, the source file must include:\u003c/p\u003e\n\u003cpre\u003e#include \u0026#34;funcapi.h\u0026#34;\n\u003c/pre\u003e\n\u003cp\u003eThere are two ways you can build a composite data value (henceforth a \u003cspan\u003e“\u003cspan\u003etuple\u003c/span\u003e”\u003c/span\u003e): you can build it from an array of Datum values, or from an array of C strings that can be passed to the input conversion functions of the tuple\u0026#39;s column data types. In either case, you first need to obtain or construct a \u003ccode\u003eTupleDesc\u003c/code\u003e descriptor for the tuple structure. When working with Datums, you pass the \u003ccode\u003eTupleDesc\u003c/code\u003e to \u003ccode\u003eBlessTupleDesc\u003c/code\u003e, and then call \u003ccode\u003eheap_form_tuple\u003c/code\u003e for each row. When working with C strings, you pass the \u003ccode\u003eTupleDesc\u003c/code\u003e to \u003ccode\u003eTupleDescGetAttInMetadata\u003c/code\u003e, and then call \u003ccode\u003eBuildTupleFromCStrings\u003c/code\u003e for each row. In the case of a function returning a set of tuples, the setup steps can all be done once during the first call of the function.\u003c/p\u003e\n\u003cp\u003eSeveral helper functions are available for setting up the needed \u003ccode\u003eTupleDesc\u003c/code\u003e. The recommended way to do this in most functions returning composite values is to call:\u003c/p\u003e\n\u003cpre\u003eTypeFuncClass get_call_result_type(FunctionCallInfo fcinfo,\n                                   Oid *resultTypeId,\n                                   TupleDesc *resultTupleDesc)\n\u003c/pre\u003e\n\u003cp\u003epassing the same \u003ccode\u003efcinfo\u003c/code\u003e struct passed to the calling function itself. (This of course requires that you use the version-1 calling conventions.) \u003ccode\u003eresultTypeId\u003c/code\u003e can be specified as \u003ccode\u003eNULL\u003c/code\u003e or as the address of a local variable to receive the function\u0026#39;s result type OID. \u003ccode\u003eresultTupleDesc\u003c/code\u003e should be the address of a local \u003ccode\u003eTupleDesc\u003c/code\u003e variable. Check that the result is \u003ccode\u003eTYPEFUNC_COMPOSITE\u003c/code\u003e; if so, \u003ccode\u003eresultTupleDesc\u003c/code\u003e has been filled with the needed \u003ccode\u003eTupleDesc\u003c/code\u003e. (If it is not, you can report an error along the lines of \u003cspan\u003e“\u003cspan\u003efunction returning record called in context that cannot accept type record\u003c/span\u003e”\u003c/span\u003e.)\u003c/p\u003e\n\u003cdiv\u003e\n\u003ch3\u003eTip\u003c/h3\u003e\n\u003cp\u003e\u003ccode\u003eget_call_result_type\u003c/code\u003e can resolve the actual type of a polymorphic function result; so it is useful in functions that return scalar polymorphic results, not only functions that return composites. The \u003ccode\u003eresultTypeId\u003c/code\u003e output is primarily useful for functions returning polymorphic scalars.\u003c/p\u003e\n\u003c/div\u003e\n\u003cdiv\u003e\n\u003ch3\u003eNote\u003c/h3\u003e\n\u003cp\u003e\u003ccode\u003eget_call_result_type\u003c/code\u003e has a sibling \u003ccode\u003eget_expr_result_type\u003c/code\u003e, which can be used to resolve the expected output type for a function call represented by an expression tree. This can be used when trying to determine the result type from outside the function itself. There is also \u003ccode\u003eget_func_result_type\u003c/code\u003e, which can be used when only the function\u0026#39;s OID is available. However these functions are not able to deal with functions declared to return \u003ccode\u003erecord\u003c/code\u003e, and \u003ccode\u003eget_func_result_type\u003c/code\u003e cannot resolve polymorphic types, so you should preferentially use \u003ccode\u003eget_call_result_type\u003c/code\u003e.\u003c/p\u003e\n\u003c/div\u003e\n\u003cp\u003eOlder, now-deprecated functions for obtaining \u003ccode\u003eTupleDesc\u003c/code\u003es are:\u003c/p\u003e\n\u003cpre\u003eTupleDesc RelationNameGetTupleDesc(const char *relname)\n\u003c/pre\u003e\n\u003cp\u003eto get a \u003ccode\u003eTupleDesc\u003c/code\u003e for the row type of a named relation, and:\u003c/p\u003e\n\u003cpre\u003eTupleDesc TypeGetTupleDesc(Oid typeoid, List *colaliases)\n\u003c/pre\u003e\n\u003cp\u003eto get a \u003ccode\u003eTupleDesc\u003c/code\u003e based on a type OID. This can be used to get a \u003ccode\u003eTupleDesc\u003c/code\u003e for a base or composite type. It will not work for a function that returns \u003ccode\u003erecord\u003c/code\u003e, however, and it cannot resolve polymorphic types.\u003c/p\u003e\n\u003cp\u003eOnce you have a \u003ccode\u003eTupleDesc\u003c/code\u003e, call:\u003c/p\u003e\n\u003cpre\u003eTupleDesc BlessTupleDesc(TupleDesc tupdesc)\n\u003c/pre\u003e\n\u003cp\u003eif you plan to work with Datums, or:\u003c/p\u003e\n\u003cpre\u003eAttInMetadata *TupleDescGetAttInMetadata(TupleDesc tupdesc)\n\u003c/pre\u003e\n\u003cp\u003eif you plan to work with C strings. If you are writing a function returning set, you can save the results of these functions in the \u003ccode\u003eFuncCallContext\u003c/code\u003e structure — use the \u003ccode\u003etuple_desc\u003c/code\u003e or \u003ccode\u003eattinmeta\u003c/code\u003e field respectively.\u003c/p\u003e\n\u003cp\u003eWhen working with Datums, use:\u003c/p\u003e\n\u003cpre\u003eHeapTuple heap_form_tuple(TupleDesc tupdesc, Datum *values, bool *isnull)\n\u003c/pre\u003e\n\u003cp\u003eto build a \u003ccode\u003eHeapTuple\u003c/code\u003e given user data in Datum form.\u003c/p\u003e\n\u003cp\u003eWhen working with C strings, use:\u003c/p\u003e\n\u003cpre\u003eHeapTuple BuildTupleFromCStrings(AttInMetadata *attinmeta, char **values)\n\u003c/pre\u003e\n\u003cp\u003eto build a \u003ccode\u003eHeapTuple\u003c/code\u003e given user data in C string form. \u003cem\u003e\u003ccode\u003evalues\u003c/code\u003e\u003c/em\u003e is an array of C strings, one for each attribute of the return row. Each C string should be in the form expected by the input function of the attribute data type. In order to return a null value for one of the attributes, the corresponding pointer in the \u003cem\u003e\u003ccode\u003evalues\u003c/code\u003e\u003c/em\u003e array should be set to \u003ccode\u003eNULL\u003c/code\u003e. This function will need to be called again for each row you return.\u003c/p\u003e\n\u003cp\u003eOnce you have built a tuple to return from your function, it must be converted into a \u003ccode\u003eDatum\u003c/code\u003e. Use:\u003c/p\u003e\n\u003cpre\u003eHeapTupleGetDatum(HeapTuple tuple)\n\u003c/pre\u003e\n\u003cp\u003eto convert a \u003ccode\u003eHeapTuple\u003c/code\u003e into a valid Datum. This \u003ccode\u003eDatum\u003c/code\u003e can be returned directly if you intend to return just a single row, or it can be used as the current return value in a set-returning function.\u003c/p\u003e\n\u003cp\u003eAn example appears in the next section.\u003c/p\u003e\n\u003c/div\u003e\n\u003cdiv id=\"XFUNC-C-RETURN-SET\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch3\u003e36.10.9. Returning Sets \u003c/h3\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003eC-language functions have two options for returning sets (multiple rows). In one method, called \u003cem\u003eValuePerCall\u003c/em\u003e mode, a set-returning function is called repeatedly (passing the same arguments each time) and it returns one new row on each call, until it has no more rows to return and signals that by returning NULL. The set-returning function (SRF) must therefore save enough state across calls to remember what it was doing and return the correct next item on each call. In the other method, called \u003cem\u003eMaterialize\u003c/em\u003e mode, an SRF fills and returns a tuplestore object containing its entire result; then only one call occurs for the whole result, and no inter-call state is needed.\u003c/p\u003e\n\u003cp\u003eWhen using ValuePerCall mode, it is important to remember that the query is not guaranteed to be run to completion; that is, due to options such as \u003ccode\u003eLIMIT\u003c/code\u003e, the executor might stop making calls to the set-returning function before all rows have been fetched. This means it is not safe to perform cleanup activities in the last call, because that might not ever happen. It\u0026#39;s recommended to use Materialize mode for functions that need access to external resources, such as file descriptors.\u003c/p\u003e\n\u003cp\u003eThe remainder of this section documents a set of helper macros that are commonly used (though not required to be used) for SRFs using ValuePerCall mode. Additional details about Materialize mode can be found in \u003ccode\u003esrc/backend/utils/fmgr/README\u003c/code\u003e. Also, the \u003ccode\u003econtrib\u003c/code\u003e modules in the \u003cspan\u003ePostgreSQL\u003c/span\u003e source distribution contain many examples of SRFs using both ValuePerCall and Materialize mode.\u003c/p\u003e\n\u003cp\u003eTo use the ValuePerCall support macros described here, include \u003ccode\u003efuncapi.h\u003c/code\u003e. These macros work with a structure \u003ccode\u003eFuncCallContext\u003c/code\u003e that contains the state that needs to be saved across calls. Within the calling SRF, \u003ccode\u003efcinfo-\u0026gt;flinfo-\u0026gt;fn_extra\u003c/code\u003e is used to hold a pointer to \u003ccode\u003eFuncCallContext\u003c/code\u003e across calls. The macros automatically fill that field on first use, and expect to find the same pointer there on subsequent uses.\u003c/p\u003e\n\u003cpre\u003etypedef struct FuncCallContext\n{\n    /*\n     * Number of times we\u0026#39;ve been called before\n     *\n     * call_cntr is initialized to 0 for you by SRF_FIRSTCALL_INIT(), and\n     * incremented for you every time SRF_RETURN_NEXT() is called.\n     */\n    uint64 call_cntr;\n\n    /*\n     * OPTIONAL maximum number of calls\n     *\n     * max_calls is here for convenience only and setting it is optional.\n     * If not set, you must provide alternative means to know when the\n     * function is done.\n     */\n    uint64 max_calls;\n\n    /*\n     * OPTIONAL pointer to miscellaneous user-provided context information\n     *\n     * user_fctx is for use as a pointer to your own data to retain\n     * arbitrary context information between calls of your function.\n     */\n    void *user_fctx;\n\n    /*\n     * OPTIONAL pointer to struct containing attribute type input metadata\n     *\n     * attinmeta is for use when returning tuples (i.e., composite data types)\n     * and is not used when returning base data types. It is only needed\n     * if you intend to use BuildTupleFromCStrings() to create the return\n     * tuple.\n     */\n    AttInMetadata *attinmeta;\n\n    /*\n     * memory context used for structures that must live for multiple calls\n     *\n     * multi_call_memory_ctx is set by SRF_FIRSTCALL_INIT() for you, and used\n     * by SRF_RETURN_DONE() for cleanup. It is the most appropriate memory\n     * context for any memory that is to be reused across multiple calls\n     * of the SRF.\n     */\n    MemoryContext multi_call_memory_ctx;\n\n    /*\n     * OPTIONAL pointer to struct containing tuple description\n     *\n     * tuple_desc is for use when returning tuples (i.e., composite data types)\n     * and is only needed if you are going to build the tuples with\n     * heap_form_tuple() rather than with BuildTupleFromCStrings().  Note that\n     * the TupleDesc pointer stored here should usually have been run through\n     * BlessTupleDesc() first.\n     */\n    TupleDesc tuple_desc;\n\n} FuncCallContext;\n\u003c/pre\u003e\n\u003cp\u003eThe macros to be used by an SRF using this infrastructure are:\u003c/p\u003e\n\u003cpre\u003eSRF_IS_FIRSTCALL()\n\u003c/pre\u003e\n\u003cp\u003eUse this to determine if your function is being called for the first or a subsequent time. On the first call (only), call:\u003c/p\u003e\n\u003cpre\u003eSRF_FIRSTCALL_INIT()\n\u003c/pre\u003e\n\u003cp\u003eto initialize the \u003ccode\u003eFuncCallContext\u003c/code\u003e. On every function call, including the first, call:\u003c/p\u003e\n\u003cpre\u003eSRF_PERCALL_SETUP()\n\u003c/pre\u003e\n\u003cp\u003eto set up for using the \u003ccode\u003eFuncCallContext\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003eIf your function has data to return in the current call, use:\u003c/p\u003e\n\u003cpre\u003eSRF_RETURN_NEXT(funcctx, result)\n\u003c/pre\u003e\n\u003cp\u003eto return it to the caller. (\u003ccode\u003eresult\u003c/code\u003e must be of type \u003ccode\u003eDatum\u003c/code\u003e, either a single value or a tuple prepared as described above.) Finally, when your function is finished returning data, use:\u003c/p\u003e\n\u003cpre\u003eSRF_RETURN_DONE(funcctx)\n\u003c/pre\u003e\n\u003cp\u003eto clean up and end the SRF.\u003c/p\u003e\n\u003cp\u003eThe memory context that is current when the SRF is called is a transient context that will be cleared between calls. This means that you do not need to call \u003ccode\u003epfree\u003c/code\u003e on everything you allocated using \u003ccode\u003epalloc\u003c/code\u003e; it will go away anyway. However, if you want to allocate any data structures to live across calls, you need to put them somewhere else. The memory context referenced by \u003ccode\u003emulti_call_memory_ctx\u003c/code\u003e is a suitable location for any data that needs to survive until the SRF is finished running. In most cases, this means that you should switch into \u003ccode\u003emulti_call_memory_ctx\u003c/code\u003e while doing the first-call setup. Use \u003ccode\u003efuncctx-\u0026gt;user_fctx\u003c/code\u003e to hold a pointer to any such cross-call data structures. (Data you allocate in \u003ccode\u003emulti_call_memory_ctx\u003c/code\u003e will go away automatically when the query ends, so it is not necessary to free that data manually, either.)\u003c/p\u003e\n\u003cdiv\u003e\n\u003ch3\u003eWarning\u003c/h3\u003e\n\u003cp\u003eWhile the actual arguments to the function remain unchanged between calls, if you detoast the argument values (which is normally done transparently by the \u003ccode\u003ePG_GETARG_\u003cem\u003e\u003ccode\u003exxx\u003c/code\u003e\u003c/em\u003e\u003c/code\u003e macro) in the transient context then the detoasted copies will be freed on each cycle. Accordingly, if you keep references to such values in your \u003ccode\u003euser_fctx\u003c/code\u003e, you must either copy them into the \u003ccode\u003emulti_call_memory_ctx\u003c/code\u003e after detoasting, or ensure that you detoast the values only in that context.\u003c/p\u003e\n\u003c/div\u003e\n\u003cp\u003eA complete pseudo-code example looks like the following:\u003c/p\u003e\n\u003cpre\u003eDatum\nmy_set_returning_function(PG_FUNCTION_ARGS)\n{\n    FuncCallContext  *funcctx;\n    Datum             result;\n    \u003cem\u003e\u003ccode\u003efurther declarations as needed\u003c/code\u003e\u003c/em\u003e\n\n    if (SRF_IS_FIRSTCALL())\n    {\n        MemoryContext oldcontext;\n\n        funcctx = SRF_FIRSTCALL_INIT();\n        oldcontext = MemoryContextSwitchTo(funcctx-\u0026gt;multi_call_memory_ctx);\n        /* One-time setup code appears here: */\n        \u003cem\u003e\u003ccode\u003euser code\u003c/code\u003e\u003c/em\u003e\n        \u003cem\u003e\u003ccode\u003eif returning composite\u003c/code\u003e\u003c/em\u003e\n            \u003cem\u003e\u003ccode\u003ebuild TupleDesc, and perhaps AttInMetadata\u003c/code\u003e\u003c/em\u003e\n        \u003cem\u003e\u003ccode\u003eendif returning composite\u003c/code\u003e\u003c/em\u003e\n        \u003cem\u003e\u003ccode\u003euser code\u003c/code\u003e\u003c/em\u003e\n        MemoryContextSwitchTo(oldcontext);\n    }\n\n    /* Each-time setup code appears here: */\n    \u003cem\u003e\u003ccode\u003euser code\u003c/code\u003e\u003c/em\u003e\n    funcctx = SRF_PERCALL_SETUP();\n    \u003cem\u003e\u003ccode\u003euser code\u003c/code\u003e\u003c/em\u003e\n\n    /* this is just one way we might test whether we are done: */\n    if (funcctx-\u0026gt;call_cntr \u0026lt; funcctx-\u0026gt;max_calls)\n    {\n        /* Here we want to return another item: */\n        \u003cem\u003e\u003ccode\u003euser code\u003c/code\u003e\u003c/em\u003e\n        \u003cem\u003e\u003ccode\u003eobtain result Datum\u003c/code\u003e\u003c/em\u003e\n        SRF_RETURN_NEXT(funcctx, result);\n    }\n    else\n    {\n        /* Here we are done returning items, so just report that fact. */\n        /* (Resist the temptation to put cleanup code here.) */\n        SRF_RETURN_DONE(funcctx);\n    }\n}\n\u003c/pre\u003e\n\u003cp\u003eA complete example of a simple SRF returning a composite type looks like:\u003c/p\u003e\n\u003cpre\u003ePG_FUNCTION_INFO_V1(retcomposite);\n\nDatum\nretcomposite(PG_FUNCTION_ARGS)\n{\n    FuncCallContext     *funcctx;\n    int                  call_cntr;\n    int                  max_calls;\n    TupleDesc            tupdesc;\n    AttInMetadata       *attinmeta;\n\n    /* stuff done only on the first call of the function */\n    if (SRF_IS_FIRSTCALL())\n    {\n        MemoryContext   oldcontext;\n\n        /* create a function context for cross-call persistence */\n        funcctx = SRF_FIRSTCALL_INIT();\n\n        /* switch to memory context appropriate for multiple function calls */\n        oldcontext = MemoryContextSwitchTo(funcctx-\u0026gt;multi_call_memory_ctx);\n\n        /* total number of tuples to be returned */\n        funcctx-\u0026gt;max_calls = PG_GETARG_INT32(0);\n\n        /* Build a tuple descriptor for our result type */\n        if (get_call_result_type(fcinfo, NULL, \u0026amp;tupdesc) != TYPEFUNC_COMPOSITE)\n            ereport(ERROR,\n                    (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),\n                     errmsg(\u0026#34;function returning record called in context \u0026#34;\n                            \u0026#34;that cannot accept type record\u0026#34;)));\n\n        /*\n         * generate attribute metadata needed later to produce tuples from raw\n         * C strings\n         */\n        attinmeta = TupleDescGetAttInMetadata(tupdesc);\n        funcctx-\u0026gt;attinmeta = attinmeta;\n\n        MemoryContextSwitchTo(oldcontext);\n    }\n\n    /* stuff done on every call of the function */\n    funcctx = SRF_PERCALL_SETUP();\n\n    call_cntr = funcctx-\u0026gt;call_cntr;\n    max_calls = funcctx-\u0026gt;max_calls;\n    attinmeta = funcctx-\u0026gt;attinmeta;\n\n    if (call_cntr \u0026lt; max_calls)    /* do when there is more left to send */\n    {\n        char       **values;\n        HeapTuple    tuple;\n        Datum        result;\n\n        /*\n         * Prepare a values array for building the returned tuple.\n         * This should be an array of C strings which will\n         * be processed later by the type input functions.\n         */\n        values = (char **) palloc(3 * sizeof(char *));\n        values[0] = (char *) palloc(16 * sizeof(char));\n        values[1] = (char *) palloc(16 * sizeof(char));\n        values[2] = (char *) palloc(16 * sizeof(char));\n\n        snprintf(values[0], 16, \u0026#34;%d\u0026#34;, 1 * PG_GETARG_INT32(1));\n        snprintf(values[1], 16, \u0026#34;%d\u0026#34;, 2 * PG_GETARG_INT32(1));\n        snprintf(values[2], 16, \u0026#34;%d\u0026#34;, 3 * PG_GETARG_INT32(1));\n\n        /* build a tuple */\n        tuple = BuildTupleFromCStrings(attinmeta, values);\n\n        /* make the tuple into a datum */\n        result = HeapTupleGetDatum(tuple);\n\n        /* clean up (this is not really necessary) */\n        pfree(values[0]);\n        pfree(values[1]);\n        pfree(values[2]);\n        pfree(values);\n\n        SRF_RETURN_NEXT(funcctx, result);\n    }\n    else    /* do when there is no more left */\n    {\n        SRF_RETURN_DONE(funcctx);\n    }\n}\n\n\u003c/pre\u003e\n\u003cp\u003eOne way to declare this function in SQL is:\u003c/p\u003e\n\u003cpre\u003eCREATE TYPE __retcomposite AS (f1 integer, f2 integer, f3 integer);\n\nCREATE OR REPLACE FUNCTION retcomposite(integer, integer)\n    RETURNS SETOF __retcomposite\n    AS \u0026#39;\u003cem\u003e\u003ccode\u003efilename\u003c/code\u003e\u003c/em\u003e\u0026#39;, \u0026#39;retcomposite\u0026#39;\n    LANGUAGE C IMMUTABLE STRICT;\n\u003c/pre\u003e\n\u003cp\u003eA different way is to use OUT parameters:\u003c/p\u003e\n\u003cpre\u003eCREATE OR REPLACE FUNCTION retcomposite(IN integer, IN integer,\n    OUT f1 integer, OUT f2 integer, OUT f3 integer)\n    RETURNS SETOF record\n    AS \u0026#39;\u003cem\u003e\u003ccode\u003efilename\u003c/code\u003e\u003c/em\u003e\u0026#39;, \u0026#39;retcomposite\u0026#39;\n    LANGUAGE C IMMUTABLE STRICT;\n\u003c/pre\u003e\n\u003cp\u003eNotice that in this method the output type of the function is formally an anonymous \u003ccode\u003erecord\u003c/code\u003e type.\u003c/p\u003e\n\u003c/div\u003e\n\u003cdiv id=\"XFUNC-C-POLYMORPHIC\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch3\u003e36.10.10. Polymorphic Arguments and Return Types \u003c/h3\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003eC-language functions can be declared to accept and return the polymorphic types described in \u003ca href=\"/docs/18/extend-type-system.html#EXTEND-TYPES-POLYMORPHIC\" rel=\"nofollow\"\u003eSection 36.2.5\u003c/a\u003e. When a function\u0026#39;s arguments or return types are defined as polymorphic types, the function author cannot know in advance what data type it will be called with, or need to return. There are two routines provided in \u003ccode\u003efmgr.h\u003c/code\u003e to allow a version-1 C function to discover the actual data types of its arguments and the type it is expected to return. The routines are called \u003ccode\u003eget_fn_expr_rettype(FmgrInfo *flinfo)\u003c/code\u003e and \u003ccode\u003eget_fn_expr_argtype(FmgrInfo *flinfo, int argnum)\u003c/code\u003e. They return the result or argument type OID, or \u003ccode\u003eInvalidOid\u003c/code\u003e if the information is not available. The structure \u003ccode\u003eflinfo\u003c/code\u003e is normally accessed as \u003ccode\u003efcinfo-\u0026gt;flinfo\u003c/code\u003e. The parameter \u003ccode\u003eargnum\u003c/code\u003e is zero based. \u003ccode\u003eget_call_result_type\u003c/code\u003e can also be used as an alternative to \u003ccode\u003eget_fn_expr_rettype\u003c/code\u003e. There is also \u003ccode\u003eget_fn_expr_variadic\u003c/code\u003e, which can be used to find out whether variadic arguments have been merged into an array. This is primarily useful for \u003ccode\u003eVARIADIC \u0026#34;any\u0026#34;\u003c/code\u003e functions, since such merging will always have occurred for variadic functions taking ordinary array types.\u003c/p\u003e\n\u003cp\u003eFor example, suppose we want to write a function to accept a single element of any type, and return a one-dimensional array of that type:\u003c/p\u003e\n\u003cpre\u003ePG_FUNCTION_INFO_V1(make_array);\nDatum\nmake_array(PG_FUNCTION_ARGS)\n{\n    ArrayType  *result;\n    Oid         element_type = get_fn_expr_argtype(fcinfo-\u0026gt;flinfo, 0);\n    Datum       element;\n    bool        isnull;\n    int16       typlen;\n    bool        typbyval;\n    char        typalign;\n    int         ndims;\n    int         dims[MAXDIM];\n    int         lbs[MAXDIM];\n\n    if (!OidIsValid(element_type))\n        elog(ERROR, \u0026#34;could not determine data type of input\u0026#34;);\n\n    /* get the provided element, being careful in case it\u0026#39;s NULL */\n    isnull = PG_ARGISNULL(0);\n    if (isnull)\n        element = (Datum) 0;\n    else\n        element = PG_GETARG_DATUM(0);\n\n    /* we have one dimension */\n    ndims = 1;\n    /* and one element */\n    dims[0] = 1;\n    /* and lower bound is 1 */\n    lbs[0] = 1;\n\n    /* get required info about the element type */\n    get_typlenbyvalalign(element_type, \u0026amp;typlen, \u0026amp;typbyval, \u0026amp;typalign);\n\n    /* now build the array */\n    result = construct_md_array(\u0026amp;element, \u0026amp;isnull, ndims, dims, lbs,\n                                element_type, typlen, typbyval, typalign);\n\n    PG_RETURN_ARRAYTYPE_P(result);\n}\n\u003c/pre\u003e\n\u003cp\u003eThe following command declares the function \u003ccode\u003emake_array\u003c/code\u003e in SQL:\u003c/p\u003e\n\u003cpre\u003eCREATE FUNCTION make_array(anyelement) RETURNS anyarray\n    AS \u0026#39;\u003cem\u003e\u003ccode\u003eDIRECTORY\u003c/code\u003e\u003c/em\u003e/funcs\u0026#39;, \u0026#39;make_array\u0026#39;\n    LANGUAGE C IMMUTABLE;\n\u003c/pre\u003e\n\u003cp\u003eThere is a variant of polymorphism that is only available to C-language functions: they can be declared to take parameters of type \u003ccode\u003e\u0026#34;any\u0026#34;\u003c/code\u003e. (Note that this type name must be double-quoted, since it\u0026#39;s also an SQL reserved word.) This works like \u003ccode\u003eanyelement\u003c/code\u003e except that it does not constrain different \u003ccode\u003e\u0026#34;any\u0026#34;\u003c/code\u003e arguments to be the same type, nor do they help determine the function\u0026#39;s result type. A C-language function can also declare its final parameter to be \u003ccode\u003eVARIADIC \u0026#34;any\u0026#34;\u003c/code\u003e. This will match one or more actual arguments of any type (not necessarily the same type). These arguments will \u003cspan\u003e\u003cem\u003enot\u003c/em\u003e\u003c/span\u003e be gathered into an array as happens with normal variadic functions; they will just be passed to the function separately. The \u003ccode\u003ePG_NARGS()\u003c/code\u003e macro and the methods described above must be used to determine the number of actual arguments and their types when using this feature. Also, users of such a function might wish to use the \u003ccode\u003eVARIADIC\u003c/code\u003e keyword in their function call, with the expectation that the function would treat the array elements as separate arguments. The function itself must implement that behavior if wanted, after using \u003ccode\u003eget_fn_expr_variadic\u003c/code\u003e to detect that the actual argument was marked with \u003ccode\u003eVARIADIC\u003c/code\u003e.\u003c/p\u003e\n\u003c/div\u003e\n\u003cdiv id=\"XFUNC-SHARED-ADDIN\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch3\u003e36.10.11. Shared Memory \u003c/h3\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cdiv id=\"XFUNC-SHARED-ADDIN-AT-STARTUP\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch4\u003e36.10.11.1. Requesting Shared Memory at Startup \u003c/h4\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003eAdd-ins can reserve shared memory on server startup. To do so, the add-in\u0026#39;s shared library must be preloaded by specifying it in \u003ca href=\"/docs/18/runtime-config-client.html#GUC-SHARED-PRELOAD-LIBRARIES\" rel=\"nofollow\"\u003eshared_preload_libraries\u003c/a\u003e. The shared library should also register a \u003ccode\u003eshmem_request_hook\u003c/code\u003e in its \u003ccode\u003e_PG_init\u003c/code\u003e function. This \u003ccode\u003eshmem_request_hook\u003c/code\u003e can reserve shared memory by calling:\u003c/p\u003e\n\u003cpre\u003evoid RequestAddinShmemSpace(Size size)\n\u003c/pre\u003e\n\u003cp\u003eEach backend should obtain a pointer to the reserved shared memory by calling:\u003c/p\u003e\n\u003cpre\u003evoid *ShmemInitStruct(const char *name, Size size, bool *foundPtr)\n\u003c/pre\u003e\n\u003cp\u003eIf this function sets \u003ccode\u003efoundPtr\u003c/code\u003e to \u003ccode\u003efalse\u003c/code\u003e, the caller should proceed to initialize the contents of the reserved shared memory. If \u003ccode\u003efoundPtr\u003c/code\u003e is set to \u003ccode\u003etrue\u003c/code\u003e, the shared memory was already initialized by another backend, and the caller need not initialize further.\u003c/p\u003e\n\u003cp\u003eTo avoid race conditions, each backend should use the LWLock \u003ccode\u003eAddinShmemInitLock\u003c/code\u003e when initializing its allocation of shared memory, as shown here:\u003c/p\u003e\n\u003cpre\u003estatic mystruct *ptr = NULL;\nbool        found;\n\nLWLockAcquire(AddinShmemInitLock, LW_EXCLUSIVE);\nptr = ShmemInitStruct(\u0026#34;my struct name\u0026#34;, size, \u0026amp;found);\nif (!found)\n{\n    ... initialize contents of shared memory ...\n    ptr-\u0026gt;locks = GetNamedLWLockTranche(\u0026#34;my tranche name\u0026#34;);\n}\nLWLockRelease(AddinShmemInitLock);\n\u003c/pre\u003e\n\u003cp\u003e\u003ccode\u003eshmem_startup_hook\u003c/code\u003e provides a convenient place for the initialization code, but it is not strictly required that all such code be placed in this hook. On Windows (and anywhere else where \u003ccode\u003eEXEC_BACKEND\u003c/code\u003e is defined), each backend executes the registered \u003ccode\u003eshmem_startup_hook\u003c/code\u003e shortly after it attaches to shared memory, so add-ins should still acquire \u003ccode\u003eAddinShmemInitLock\u003c/code\u003e within this hook, as shown in the example above. On other platforms, only the postmaster process executes the \u003ccode\u003eshmem_startup_hook\u003c/code\u003e, and each backend automatically inherits the pointers to shared memory.\u003c/p\u003e\n\u003cp\u003eAn example of a \u003ccode\u003eshmem_request_hook\u003c/code\u003e and \u003ccode\u003eshmem_startup_hook\u003c/code\u003e can be found in \u003ccode\u003econtrib/pg_stat_statements/pg_stat_statements.c\u003c/code\u003e in the \u003cspan\u003ePostgreSQL\u003c/span\u003e source tree.\u003c/p\u003e\n\u003c/div\u003e\n\u003cdiv id=\"XFUNC-SHARED-ADDIN-AFTER-STARTUP\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch4\u003e36.10.11.2. Requesting Shared Memory After Startup \u003c/h4\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003eThere is another, more flexible method of reserving shared memory that can be done after server startup and outside a \u003ccode\u003eshmem_request_hook\u003c/code\u003e. To do so, each backend that will use the shared memory should obtain a pointer to it by calling:\u003c/p\u003e\n\u003cpre\u003evoid *GetNamedDSMSegment(const char *name, size_t size,\n                         void (*init_callback) (void *ptr),\n                         bool *found)\n\u003c/pre\u003e\n\u003cp\u003eIf a dynamic shared memory segment with the given name does not yet exist, this function will allocate it and initialize it with the provided \u003ccode\u003einit_callback\u003c/code\u003e callback function. If the segment has already been allocated and initialized by another backend, this function simply attaches the existing dynamic shared memory segment to the current backend.\u003c/p\u003e\n\u003cp\u003eUnlike shared memory reserved at server startup, there is no need to acquire \u003ccode\u003eAddinShmemInitLock\u003c/code\u003e or otherwise take action to avoid race conditions when reserving shared memory with \u003ccode\u003eGetNamedDSMSegment\u003c/code\u003e. This function ensures that only one backend allocates and initializes the segment and that all other backends receive a pointer to the fully allocated and initialized segment.\u003c/p\u003e\n\u003cp\u003eA complete usage example of \u003ccode\u003eGetNamedDSMSegment\u003c/code\u003e can be found in \u003ccode\u003esrc/test/modules/test_dsm_registry/test_dsm_registry.c\u003c/code\u003e in the \u003cspan\u003ePostgreSQL\u003c/span\u003e source tree.\u003c/p\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cdiv id=\"XFUNC-ADDIN-LWLOCKS\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch3\u003e36.10.12. LWLocks \u003c/h3\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cdiv id=\"XFUNC-ADDIN-LWLOCKS-AT-STARTUP\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch4\u003e36.10.12.1. Requesting LWLocks at Startup \u003c/h4\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003eAdd-ins can reserve LWLocks on server startup. As with shared memory reserved at server startup, the add-in\u0026#39;s shared library must be preloaded by specifying it in \u003ca href=\"/docs/18/runtime-config-client.html#GUC-SHARED-PRELOAD-LIBRARIES\" rel=\"nofollow\"\u003eshared_preload_libraries\u003c/a\u003e, and the shared library should register a \u003ccode\u003eshmem_request_hook\u003c/code\u003e in its \u003ccode\u003e_PG_init\u003c/code\u003e function. This \u003ccode\u003eshmem_request_hook\u003c/code\u003e can reserve LWLocks by calling:\u003c/p\u003e\n\u003cpre\u003evoid RequestNamedLWLockTranche(const char *tranche_name, int num_lwlocks)\n\u003c/pre\u003e\n\u003cp\u003eThis ensures that an array of \u003ccode\u003enum_lwlocks\u003c/code\u003e LWLocks is available under the name \u003ccode\u003etranche_name\u003c/code\u003e. A pointer to this array can be obtained by calling:\u003c/p\u003e\n\u003cpre\u003eLWLockPadded *GetNamedLWLockTranche(const char *tranche_name)\n\u003c/pre\u003e\n\u003c/div\u003e\n\u003cdiv id=\"XFUNC-ADDIN-LWLOCKS-AFTER-STARTUP\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch4\u003e36.10.12.2. Requesting LWLocks After Startup \u003c/h4\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003eThere is another, more flexible method of obtaining LWLocks that can be done after server startup and outside a \u003ccode\u003eshmem_request_hook\u003c/code\u003e. To do so, first allocate a \u003ccode\u003etranche_id\u003c/code\u003e by calling:\u003c/p\u003e\n\u003cpre\u003eint LWLockNewTrancheId(void)\n\u003c/pre\u003e\n\u003cp\u003eNext, initialize each LWLock, passing the new \u003ccode\u003etranche_id\u003c/code\u003e as an argument:\u003c/p\u003e\n\u003cpre\u003evoid LWLockInitialize(LWLock *lock, int tranche_id)\n\u003c/pre\u003e\n\u003cp\u003eSimilar to shared memory, each backend should ensure that only one process allocates a new \u003ccode\u003etranche_id\u003c/code\u003e and initializes each new LWLock. One way to do this is to only call these functions in your shared memory initialization code with the \u003ccode\u003eAddinShmemInitLock\u003c/code\u003e held exclusively. If using \u003ccode\u003eGetNamedDSMSegment\u003c/code\u003e, calling these functions in the \u003ccode\u003einit_callback\u003c/code\u003e callback function is sufficient to avoid race conditions.\u003c/p\u003e\n\u003cp\u003eFinally, each backend using the \u003ccode\u003etranche_id\u003c/code\u003e should associate it with a \u003ccode\u003etranche_name\u003c/code\u003e by calling:\u003c/p\u003e\n\u003cpre\u003evoid LWLockRegisterTranche(int tranche_id, const char *tranche_name)\n\u003c/pre\u003e\n\u003cp\u003eA complete usage example of \u003ccode\u003eLWLockNewTrancheId\u003c/code\u003e, \u003ccode\u003eLWLockInitialize\u003c/code\u003e, and \u003ccode\u003eLWLockRegisterTranche\u003c/code\u003e can be found in \u003ccode\u003econtrib/pg_prewarm/autoprewarm.c\u003c/code\u003e in the \u003cspan\u003ePostgreSQL\u003c/span\u003e source tree.\u003c/p\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cdiv id=\"XFUNC-ADDIN-WAIT-EVENTS\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch3\u003e36.10.13. Custom Wait Events \u003c/h3\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003eAdd-ins can define custom wait events under the wait event type \u003ccode\u003eExtension\u003c/code\u003e by calling:\u003c/p\u003e\n\u003cpre\u003euint32 WaitEventExtensionNew(const char *wait_event_name)\n\u003c/pre\u003e\n\u003cp\u003eThe wait event is associated to a user-facing custom string. An example can be found in \u003ccode\u003esrc/test/modules/worker_spi\u003c/code\u003e in the PostgreSQL source tree.\u003c/p\u003e\n\u003cp\u003eCustom wait events can be viewed in \u003ca href=\"/docs/18/monitoring-stats.html#MONITORING-PG-STAT-ACTIVITY-VIEW\" rel=\"nofollow\"\u003e\u003ccode\u003epg_stat_activity\u003c/code\u003e\u003c/a\u003e:\u003c/p\u003e\n\u003cpre\u003e=# SELECT wait_event_type, wait_event FROM pg_stat_activity\n     WHERE backend_type ~ \u0026#39;worker_spi\u0026#39;;\n wait_event_type |  wait_event\n-----------------+---------------\n Extension       | WorkerSpiMain\n(1 row)\n\u003c/pre\u003e\n\u003c/div\u003e\n\u003cdiv id=\"XFUNC-ADDIN-INJECTION-POINTS\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch3\u003e36.10.14. Injection Points \u003c/h3\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003eAn injection point with a given \u003ccode\u003ename\u003c/code\u003e is declared using macro:\u003c/p\u003e\n\u003cpre\u003eINJECTION_POINT(name, arg);\n\u003c/pre\u003e\n\u003cp\u003eThere are a few injection points already declared at strategic points within the server code. After adding a new injection point the code needs to be compiled in order for that injection point to be available in the binary. Add-ins written in C-language can declare injection points in their own code using the same macro. The injection point names should use lower-case characters, with terms separated by dashes. \u003ccode\u003earg\u003c/code\u003e is an optional argument value given to the callback at run-time.\u003c/p\u003e\n\u003cp\u003eExecuting an injection point can require allocating a small amount of memory, which can fail. If you need to have an injection point in a critical section where dynamic allocations are not allowed, you can use a two-step approach with the following macros:\u003c/p\u003e\n\u003cpre\u003eINJECTION_POINT_LOAD(name);\nINJECTION_POINT_CACHED(name, arg);\n\u003c/pre\u003e\n\u003cp\u003eBefore entering the critical section, call \u003ccode\u003eINJECTION_POINT_LOAD\u003c/code\u003e. It checks the shared memory state, and loads the callback into backend-private memory if it is active. Inside the critical section, use \u003ccode\u003eINJECTION_POINT_CACHED\u003c/code\u003e to execute the callback.\u003c/p\u003e\n\u003cp\u003eAdd-ins can attach callbacks to an already-declared injection point by calling:\u003c/p\u003e\n\u003cpre\u003eextern void InjectionPointAttach(const char *name,\n                                 const char *library,\n                                 const char *function,\n                                 const void *private_data,\n                                 int private_data_size);\n\u003c/pre\u003e\n\u003cp\u003e\u003ccode\u003ename\u003c/code\u003e is the name of the injection point, which when reached during execution will execute the \u003ccode\u003efunction\u003c/code\u003e loaded from \u003ccode\u003elibrary\u003c/code\u003e. \u003ccode\u003eprivate_data\u003c/code\u003e is a private area of data of size \u003ccode\u003eprivate_data_size\u003c/code\u003e given as argument to the callback when executed.\u003c/p\u003e\n\u003cp\u003eHere is an example of callback for \u003ccode\u003eInjectionPointCallback\u003c/code\u003e:\u003c/p\u003e\n\u003cpre\u003estatic void\ncustom_injection_callback(const char *name,\n                          const void *private_data,\n                          void *arg)\n{\n    uint32 wait_event_info = WaitEventInjectionPointNew(name);\n\n    pgstat_report_wait_start(wait_event_info);\n    elog(NOTICE, \u0026#34;%s: executed custom callback\u0026#34;, name);\n    pgstat_report_wait_end();\n}\n\u003c/pre\u003e\n\u003cp\u003eThis callback prints a message to server error log with severity \u003ccode\u003eNOTICE\u003c/code\u003e, but callbacks may implement more complex logic.\u003c/p\u003e\n\u003cp\u003eAn alternative way to define the action to take when an injection point is reached is to add the testing code alongside the normal source code. This can be useful if the action e.g. depends on local variables that are not accessible to loaded modules. The \u003ccode\u003eIS_INJECTION_POINT_ATTACHED\u003c/code\u003e macro can then be used to check if an injection point is attached, for example:\u003c/p\u003e\n\u003cpre\u003e#ifdef USE_INJECTION_POINTS\nif (IS_INJECTION_POINT_ATTACHED(\u0026#34;before-foobar\u0026#34;))\n{\n    /* change a local variable if injection point is attached */\n    local_var = 123;\n\n    /* also execute the callback */\n    INJECTION_POINT_CACHED(\u0026#34;before-foobar\u0026#34;, NULL);\n}\n#endif\n\u003c/pre\u003e\n\u003cp\u003eNote that the callback attached to the injection point will not be executed by the \u003ccode\u003eIS_INJECTION_POINT_ATTACHED\u003c/code\u003e macro. If you want to execute the callback, you must also call \u003ccode\u003eINJECTION_POINT_CACHED\u003c/code\u003e like in the above example.\u003c/p\u003e\n\u003cp\u003eOptionally, it is possible to detach an injection point by calling:\u003c/p\u003e\n\u003cpre\u003eextern bool InjectionPointDetach(const char *name);\n\u003c/pre\u003e\n\u003cp\u003eOn success, \u003ccode\u003etrue\u003c/code\u003e is returned, \u003ccode\u003efalse\u003c/code\u003e otherwise.\u003c/p\u003e\n\u003cp\u003eA callback attached to an injection point is available across all the backends including the backends started after \u003ccode\u003eInjectionPointAttach\u003c/code\u003e is called. It remains attached while the server is running or until the injection point is detached using \u003ccode\u003eInjectionPointDetach\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003eAn example can be found in \u003ccode\u003esrc/test/modules/injection_points\u003c/code\u003e in the PostgreSQL source tree.\u003c/p\u003e\n\u003cp\u003eEnabling injections points requires \u003ccode\u003e--enable-injection-points\u003c/code\u003e with \u003ccode\u003econfigure\u003c/code\u003e or \u003ccode\u003e-Dinjection_points=true\u003c/code\u003e with \u003cspan\u003eMeson\u003c/span\u003e.\u003c/p\u003e\n\u003c/div\u003e\n\u003cdiv id=\"XFUNC-ADDIN-CUSTOM-CUMULATIVE-STATISTICS\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch3\u003e36.10.15. Custom Cumulative Statistics \u003c/h3\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003eIt is possible for add-ins written in C-language to use custom types of cumulative statistics registered in the \u003ca href=\"/docs/18/monitoring-stats.html#MONITORING-STATS-SETUP\" rel=\"nofollow\"\u003eCumulative Statistics System\u003c/a\u003e.\u003c/p\u003e\n\u003cp\u003eFirst, define a \u003ccode\u003ePgStat_KindInfo\u003c/code\u003e that includes all the information related to the custom type registered. For example:\u003c/p\u003e\n\u003cpre\u003estatic const PgStat_KindInfo custom_stats = {\n    .name = \u0026#34;custom_stats\u0026#34;,\n    .fixed_amount = false,\n    .shared_size = sizeof(PgStatShared_Custom),\n    .shared_data_off = offsetof(PgStatShared_Custom, stats),\n    .shared_data_len = sizeof(((PgStatShared_Custom *) 0)-\u0026gt;stats),\n    .pending_size = sizeof(PgStat_StatCustomEntry),\n}\n\u003c/pre\u003e\n\u003cp\u003eThen, each backend that needs to use this custom type needs to register it with \u003ccode\u003epgstat_register_kind\u003c/code\u003e and a unique ID used to store the entries related to this type of statistics:\u003c/p\u003e\n\u003cpre\u003eextern PgStat_Kind pgstat_register_kind(PgStat_Kind kind,\n                                        const PgStat_KindInfo *kind_info);\n\u003c/pre\u003e\n\u003cp\u003eWhile developing a new extension, use \u003ccode\u003ePGSTAT_KIND_EXPERIMENTAL\u003c/code\u003e for \u003cem\u003e\u003ccode\u003ekind\u003c/code\u003e\u003c/em\u003e. When you are ready to release the extension to users, reserve a kind ID at the \u003ca href=\"https://wiki.postgresql.org/wiki/CustomCumulativeStats\" rel=\"nofollow\"\u003eCustom Cumulative Statistics\u003c/a\u003e page.\u003c/p\u003e\n\u003cp\u003eThe details of the API for \u003ccode\u003ePgStat_KindInfo\u003c/code\u003e can be found in \u003ccode\u003esrc/include/utils/pgstat_internal.h\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003eThe type of statistics registered is associated with a name and a unique ID shared across the server in shared memory. Each backend using a custom type of statistics maintains a local cache storing the information of each custom \u003ccode\u003ePgStat_KindInfo\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003ePlace the extension module implementing the custom cumulative statistics type in \u003ca href=\"/docs/18/runtime-config-client.html#GUC-SHARED-PRELOAD-LIBRARIES\" rel=\"nofollow\"\u003eshared_preload_libraries\u003c/a\u003e so that it will be loaded early during \u003cspan\u003ePostgreSQL\u003c/span\u003e startup.\u003c/p\u003e\n\u003cp\u003eAn example describing how to register and use custom statistics can be found in \u003ccode\u003esrc/test/modules/injection_points\u003c/code\u003e.\u003c/p\u003e\n\u003c/div\u003e\n\u003cdiv id=\"EXTEND-CPP\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch3\u003e36.10.16. Using C++ for Extensibility \u003c/h3\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003eAlthough the \u003cspan\u003ePostgreSQL\u003c/span\u003e backend is written in C, it is possible to write extensions in C++ if these guidelines are followed:\u003c/p\u003e\n\u003cdiv\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003eAll functions accessed by the backend must present a C interface to the backend; these C functions can then call C++ functions. For example, \u003ccode\u003eextern C\u003c/code\u003e linkage is required for backend-accessed functions. This is also necessary for any functions that are passed as pointers between the backend and C++ code.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eFree memory using the appropriate deallocation method. For example, most backend memory is allocated using \u003ccode\u003epalloc()\u003c/code\u003e, so use \u003ccode\u003epfree()\u003c/code\u003e to free it. Using C++ \u003ccode\u003edelete\u003c/code\u003e in such cases will fail.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003ePrevent exceptions from propagating into the C code (use a catch-all block at the top level of all \u003ccode\u003eextern C\u003c/code\u003e functions). This is necessary even if the C++ code does not explicitly throw any exceptions, because events like out-of-memory can still throw exceptions. Any exceptions must be caught and appropriate errors passed back to the C interface. If possible, compile C++ with \u003ccode\u003e-fno-exceptions\u003c/code\u003e to eliminate exceptions entirely; in such cases, you must check for failures in your C++ code, e.g., check for NULL returned by \u003ccode\u003enew()\u003c/code\u003e.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eIf calling backend functions from C++ code, be sure that the C++ call stack contains only plain old data structures (POD). This is necessary because backend errors generate a distant \u003ccode\u003elongjmp()\u003c/code\u003e that does not properly unroll a C++ call stack with non-POD objects.\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/div\u003e\n\u003cp\u003eIn summary, it is best to place C++ code behind a wall of \u003ccode\u003eextern C\u003c/code\u003e functions that interface to the backend, and avoid exception, memory, and call stack leakage.\u003c/p\u003e\n\u003c/div\u003e\n\u003c/div\u003e","SourceRevision":"555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f","ContentHash":"078707456b3fe309d355d32009b5eff64f5cf0fbb08d035747e6d3ae321a2bf2","Payload":{"description":["dynamically-loaded C functions"],"manual_html":"\u003cdiv class=\"sect1\" id=\"XFUNC-C\"\u003e\n\u003cdiv class=\"titlepage\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch2 class=\"title\"\u003e36.10. C-Language Functions \u003c/h2\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\n\u003cp\u003eUser-defined functions can be written in C (or a language that can be made compatible with C, such as C++). Such functions are compiled into dynamically loadable objects (also called shared libraries) and are loaded by the server on demand. The dynamic loading feature is what distinguishes \u003cspan class=\"quote\"\u003e“\u003cspan class=\"quote\"\u003eC language\u003c/span\u003e”\u003c/span\u003e functions from \u003cspan class=\"quote\"\u003e“\u003cspan class=\"quote\"\u003einternal\u003c/span\u003e”\u003c/span\u003e functions — the actual coding conventions are essentially the same for both. (Hence, the standard internal function library is a rich source of coding examples for user-defined C functions.)\u003c/p\u003e\n\u003cp\u003eCurrently only one calling convention is used for C functions (\u003cspan class=\"quote\"\u003e“\u003cspan class=\"quote\"\u003eversion 1\u003c/span\u003e”\u003c/span\u003e). Support for that calling convention is indicated by writing a \u003ccode class=\"literal\"\u003ePG_FUNCTION_INFO_V1()\u003c/code\u003e macro call for the function, as illustrated below.\u003c/p\u003e\n\u003cdiv class=\"sect2\" id=\"XFUNC-C-DYNLOAD\"\u003e\n\u003cdiv class=\"titlepage\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch3 class=\"title\"\u003e36.10.1. Dynamic Loading \u003c/h3\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003eThe first time a user-defined function in a particular loadable object file is called in a session, the dynamic loader loads that object file into memory so that the function can be called. The \u003ccode class=\"command\"\u003eCREATE FUNCTION\u003c/code\u003e for a user-defined C function must therefore specify two pieces of information for the function: the name of the loadable object file, and the C name (link symbol) of the specific function to call within that object file. If the C name is not explicitly specified then it is assumed to be the same as the SQL function name.\u003c/p\u003e\n\u003cp\u003eThe following algorithm is used to locate the shared object file based on the name given in the \u003ccode class=\"command\"\u003eCREATE FUNCTION\u003c/code\u003e command:\u003c/p\u003e\n\u003cdiv class=\"orderedlist\"\u003e\n\u003col class=\"orderedlist\"\u003e\n\u003cli class=\"listitem\"\u003e\n\u003cp\u003eIf the name is an absolute path, the given file is loaded.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli class=\"listitem\"\u003e\n\u003cp\u003eIf the name starts with the string \u003ccode class=\"literal\"\u003e$libdir\u003c/code\u003e, that part is replaced by the \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e package library directory name, which is determined at build time.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli class=\"listitem\"\u003e\n\u003cp\u003eIf the name does not contain a directory part, the file is searched for in the path specified by the configuration variable \u003ca class=\"xref\" href=\"/docs/18/runtime-config-client.html#GUC-DYNAMIC-LIBRARY-PATH\"\u003edynamic_library_path\u003c/a\u003e.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli class=\"listitem\"\u003e\n\u003cp\u003eOtherwise (the file was not found in the path, or it contains a non-absolute directory part), the dynamic loader will try to take the name as given, which will most likely fail. (It is unreliable to depend on the current working directory.)\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/div\u003e\n\u003cp\u003eIf this sequence does not work, the platform-specific shared library file name extension (often \u003ccode class=\"filename\"\u003e.so\u003c/code\u003e) is appended to the given name and this sequence is tried again. If that fails as well, the load will fail.\u003c/p\u003e\n\u003cp\u003eIt is recommended to locate shared libraries either relative to \u003ccode class=\"literal\"\u003e$libdir\u003c/code\u003e or through the dynamic library path. This simplifies version upgrades if the new installation is at a different location. The actual directory that \u003ccode class=\"literal\"\u003e$libdir\u003c/code\u003e stands for can be found out with the command \u003ccode class=\"literal\"\u003epg_config --pkglibdir\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003eThe user ID the \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e server runs as must be able to traverse the path to the file you intend to load. Making the file or a higher-level directory not readable and/or not executable by the \u003cspan class=\"systemitem\"\u003epostgres\u003c/span\u003e user is a common mistake.\u003c/p\u003e\n\u003cp\u003eIn any case, the file name that is given in the \u003ccode class=\"command\"\u003eCREATE FUNCTION\u003c/code\u003e command is recorded literally in the system catalogs, so if the file needs to be loaded again the same procedure is applied.\u003c/p\u003e\n\u003cdiv class=\"note\"\u003e\n\u003ch3 class=\"title\"\u003eNote\u003c/h3\u003e\n\u003cp\u003e\u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e will not compile a C function automatically. The object file must be compiled before it is referenced in a \u003ccode class=\"command\"\u003eCREATE FUNCTION\u003c/code\u003e command. See \u003ca class=\"xref\" href=\"/docs/18/xfunc-c.html#DFUNC\" title=\"36.10.5. Compiling and Linking Dynamically-Loaded Functions\"\u003eSection 36.10.5\u003c/a\u003e for additional information.\u003c/p\u003e\n\u003c/div\u003e\n\u003cp\u003eTo ensure that a dynamically loaded object file is not loaded into an incompatible server, \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e checks that the file contains a \u003cspan class=\"quote\"\u003e“\u003cspan class=\"quote\"\u003emagic block\u003c/span\u003e”\u003c/span\u003e with the appropriate contents. This allows the server to detect obvious incompatibilities, such as code compiled for a different major version of \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e. To include a magic block, write this in one (and only one) of the module source files, after having included the header \u003ccode class=\"filename\"\u003efmgr.h\u003c/code\u003e:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003ePG_MODULE_MAGIC;\n\u003c/pre\u003e\n\u003cp\u003eor\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003ePG_MODULE_MAGIC_EXT(\u003cem class=\"replaceable\"\u003e\u003ccode\u003eparameters\u003c/code\u003e\u003c/em\u003e);\n\u003c/pre\u003e\n\u003cp\u003eThe \u003ccode class=\"literal\"\u003ePG_MODULE_MAGIC_EXT\u003c/code\u003e variant allows the specification of additional information about the module; currently, a name and/or a version string can be added. (More fields might be allowed in future.) Write something like this:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003ePG_MODULE_MAGIC_EXT(\n    .name = \"my_module_name\",\n    .version = \"1.2.3\"\n);\n\u003c/pre\u003e\n\u003cp\u003eSubsequently the name and version can be examined via the \u003ccode class=\"function\"\u003epg_get_loaded_modules()\u003c/code\u003e function. The meaning of the version string is not restricted by \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e, but use of semantic versioning rules is recommended.\u003c/p\u003e\n\u003cp\u003eAfter it is used for the first time, a dynamically loaded object file is retained in memory. Future calls in the same session to the function(s) in that file will only incur the small overhead of a symbol table lookup. If you need to force a reload of an object file, for example after recompiling it, begin a fresh session.\u003c/p\u003e\n\u003cp\u003eOptionally, a dynamically loaded file can contain an initialization function. If the file includes a function named \u003ccode class=\"function\"\u003e_PG_init\u003c/code\u003e, that function will be called immediately after loading the file. The function receives no parameters and should return void. There is presently no way to unload a dynamically loaded file.\u003c/p\u003e\n\u003c/div\u003e\n\u003cdiv class=\"sect2\" id=\"XFUNC-C-BASETYPE\"\u003e\n\u003cdiv class=\"titlepage\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch3 class=\"title\"\u003e36.10.2. Base Types in C-Language Functions \u003c/h3\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003eTo know how to write C-language functions, you need to know how \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e internally represents base data types and how they can be passed to and from functions. Internally, \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e regards a base type as a \u003cspan class=\"quote\"\u003e“\u003cspan class=\"quote\"\u003eblob of memory\u003c/span\u003e”\u003c/span\u003e. The user-defined functions that you define over a type in turn define the way that \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e can operate on it. That is, \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e will only store and retrieve the data from disk and use your user-defined functions to input, process, and output the data.\u003c/p\u003e\n\u003cp\u003eBase types can have one of three internal formats:\u003c/p\u003e\n\u003cdiv class=\"itemizedlist\"\u003e\n\u003cul class=\"itemizedlist\"\u003e\n\u003cli class=\"listitem\"\u003e\n\u003cp\u003epass by value, fixed-length\u003c/p\u003e\n\u003c/li\u003e\n\u003cli class=\"listitem\"\u003e\n\u003cp\u003epass by reference, fixed-length\u003c/p\u003e\n\u003c/li\u003e\n\u003cli class=\"listitem\"\u003e\n\u003cp\u003epass by reference, variable-length\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/div\u003e\n\u003cp\u003eBy-value types can only be 1, 2, or 4 bytes in length (also 8 bytes, if \u003ccode class=\"literal\"\u003esizeof(Datum)\u003c/code\u003e is 8 on your machine). You should be careful to define your types such that they will be the same size (in bytes) on all architectures. For example, the \u003ccode class=\"literal\"\u003elong\u003c/code\u003e type is dangerous because it is 4 bytes on some machines and 8 bytes on others, whereas \u003ccode class=\"type\"\u003eint\u003c/code\u003e type is 4 bytes on most Unix machines. A reasonable implementation of the \u003ccode class=\"type\"\u003eint4\u003c/code\u003e type on Unix machines might be:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003e/* 4-byte integer, passed by value */\ntypedef int int4;\n\u003c/pre\u003e\n\u003cp\u003e(The actual PostgreSQL C code calls this type \u003ccode class=\"type\"\u003eint32\u003c/code\u003e, because it is a convention in C that \u003ccode class=\"type\"\u003eint\u003cem class=\"replaceable\"\u003e\u003ccode\u003eXX\u003c/code\u003e\u003c/em\u003e\u003c/code\u003e means \u003cem class=\"replaceable\"\u003e\u003ccode\u003eXX\u003c/code\u003e\u003c/em\u003e \u003cspan class=\"emphasis\"\u003e\u003cem\u003ebits\u003c/em\u003e\u003c/span\u003e. Note therefore also that the C type \u003ccode class=\"type\"\u003eint8\u003c/code\u003e is 1 byte in size. The SQL type \u003ccode class=\"type\"\u003eint8\u003c/code\u003e is called \u003ccode class=\"type\"\u003eint64\u003c/code\u003e in C. See also \u003ca class=\"xref\" href=\"/docs/18/xfunc-c.html#XFUNC-C-TYPE-TABLE\" title=\"Table 36.2. Equivalent C Types for Built-in SQL Types\"\u003eTable 36.2\u003c/a\u003e.)\u003c/p\u003e\n\u003cp\u003eOn the other hand, fixed-length types of any size can be passed by-reference. For example, here is a sample implementation of a \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e type:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003e/* 16-byte structure, passed by reference */\ntypedef struct\n{\n    double  x, y;\n} Point;\n\u003c/pre\u003e\n\u003cp\u003eOnly pointers to such types can be used when passing them in and out of \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e functions. To return a value of such a type, allocate the right amount of memory with \u003ccode class=\"literal\"\u003epalloc\u003c/code\u003e, fill in the allocated memory, and return a pointer to it. (Also, if you just want to return the same value as one of your input arguments that's of the same data type, you can skip the extra \u003ccode class=\"literal\"\u003epalloc\u003c/code\u003e and just return the pointer to the input value.)\u003c/p\u003e\n\u003cp\u003eFinally, all variable-length types must also be passed by reference. All variable-length types must begin with an opaque length field of exactly 4 bytes, which will be set by \u003ccode class=\"symbol\"\u003eSET_VARSIZE\u003c/code\u003e; never set this field directly! All data to be stored within that type must be located in the memory immediately following that length field. The length field contains the total length of the structure, that is, it includes the size of the length field itself.\u003c/p\u003e\n\u003cp\u003eAnother important point is to avoid leaving any uninitialized bits within data type values; for example, take care to zero out any alignment padding bytes that might be present in structs. Without this, logically-equivalent constants of your data type might be seen as unequal by the planner, leading to inefficient (though not incorrect) plans.\u003c/p\u003e\n\u003cdiv class=\"warning\"\u003e\n\u003ch3 class=\"title\"\u003eWarning\u003c/h3\u003e\n\u003cp\u003e\u003cspan class=\"emphasis\"\u003e\u003cem\u003eNever\u003c/em\u003e\u003c/span\u003e modify the contents of a pass-by-reference input value. If you do so you are likely to corrupt on-disk data, since the pointer you are given might point directly into a disk buffer. The sole exception to this rule is explained in \u003ca class=\"xref\" href=\"/docs/18/xaggr.html\" title=\"36.12. User-Defined Aggregates\"\u003eSection 36.12\u003c/a\u003e.\u003c/p\u003e\n\u003c/div\u003e\n\u003cp\u003eAs an example, we can define the type \u003ccode class=\"type\"\u003etext\u003c/code\u003e as follows:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003etypedef struct {\n    int32 length;\n    char data[FLEXIBLE_ARRAY_MEMBER];\n} text;\n\u003c/pre\u003e\n\u003cp\u003eThe \u003ccode class=\"literal\"\u003e[FLEXIBLE_ARRAY_MEMBER]\u003c/code\u003e notation means that the actual length of the data part is not specified by this declaration.\u003c/p\u003e\n\u003cp\u003eWhen manipulating variable-length types, we must be careful to allocate the correct amount of memory and set the length field correctly. For example, if we wanted to store 40 bytes in a \u003ccode class=\"structname\"\u003etext\u003c/code\u003e structure, we might use a code fragment like this:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003e#include \"postgres.h\"\n...\nchar buffer[40]; /* our source data */\n...\ntext *destination = (text *) palloc(VARHDRSZ + 40);\nSET_VARSIZE(destination, VARHDRSZ + 40);\nmemcpy(destination-\u0026gt;data, buffer, 40);\n...\n\n\u003c/pre\u003e\n\u003cp\u003e\u003ccode class=\"literal\"\u003eVARHDRSZ\u003c/code\u003e is the same as \u003ccode class=\"literal\"\u003esizeof(int32)\u003c/code\u003e, but it's considered good style to use the macro \u003ccode class=\"literal\"\u003eVARHDRSZ\u003c/code\u003e to refer to the size of the overhead for a variable-length type. Also, the length field \u003cspan class=\"emphasis\"\u003e\u003cem\u003emust\u003c/em\u003e\u003c/span\u003e be set using the \u003ccode class=\"literal\"\u003eSET_VARSIZE\u003c/code\u003e macro, not by simple assignment.\u003c/p\u003e\n\u003cp\u003e\u003ca class=\"xref\" href=\"/docs/18/xfunc-c.html#XFUNC-C-TYPE-TABLE\" title=\"Table 36.2. Equivalent C Types for Built-in SQL Types\"\u003eTable 36.2\u003c/a\u003e shows the C types corresponding to many of the built-in SQL data types of \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e. The \u003cspan class=\"quote\"\u003e“\u003cspan class=\"quote\"\u003eDefined In\u003c/span\u003e”\u003c/span\u003e column gives the header file that needs to be included to get the type definition. (The actual definition might be in a different file that is included by the listed file. It is recommended that users stick to the defined interface.) Note that you should always include \u003ccode class=\"filename\"\u003epostgres.h\u003c/code\u003e first in any source file of server code, because it declares a number of things that you will need anyway, and because including other headers first can cause portability issues.\u003c/p\u003e\n\u003cdiv class=\"table\" id=\"XFUNC-C-TYPE-TABLE\"\u003e\n\u003cp class=\"title\"\u003e\u003cstrong\u003eTable 36.2. Equivalent C Types for Built-in SQL Types\u003c/strong\u003e\u003c/p\u003e\n\u003cdiv class=\"table-contents\"\u003e\n\u003ctable class=\"table\"\u003e\n\n\n\n\n\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003eSQL Type\u003c/th\u003e\n\u003cth\u003eC Type\u003c/th\u003e\n\u003cth\u003eDefined In\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003eboolean\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003ebool\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"filename\"\u003epostgres.h\u003c/code\u003e (maybe compiler built-in)\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003ebox\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003eBOX*\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"filename\"\u003eutils/geo_decls.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003ebytea\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003ebytea*\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"filename\"\u003epostgres.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003e\"char\"\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003echar\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e(compiler built-in)\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003echaracter\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003eBpChar*\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"filename\"\u003epostgres.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003ecid\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003eCommandId\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"filename\"\u003epostgres.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003edate\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003eDateADT\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"filename\"\u003eutils/date.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003efloat4\u003c/code\u003e (\u003ccode class=\"type\"\u003ereal\u003c/code\u003e)\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003efloat4\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"filename\"\u003epostgres.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003efloat8\u003c/code\u003e (\u003ccode class=\"type\"\u003edouble precision\u003c/code\u003e)\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003efloat8\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"filename\"\u003epostgres.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003eint2\u003c/code\u003e (\u003ccode class=\"type\"\u003esmallint\u003c/code\u003e)\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003eint16\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"filename\"\u003epostgres.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003eint4\u003c/code\u003e (\u003ccode class=\"type\"\u003einteger\u003c/code\u003e)\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003eint32\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"filename\"\u003epostgres.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003eint8\u003c/code\u003e (\u003ccode class=\"type\"\u003ebigint\u003c/code\u003e)\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003eint64\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"filename\"\u003epostgres.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003einterval\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003eInterval*\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"filename\"\u003edatatype/timestamp.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003elseg\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003eLSEG*\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"filename\"\u003eutils/geo_decls.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003ename\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003eName\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"filename\"\u003epostgres.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003enumeric\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003eNumeric\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"filename\"\u003eutils/numeric.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003eoid\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003eOid\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"filename\"\u003epostgres.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003eoidvector\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003eoidvector*\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"filename\"\u003epostgres.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003epath\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003ePATH*\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"filename\"\u003eutils/geo_decls.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003epoint\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003ePOINT*\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"filename\"\u003eutils/geo_decls.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003eregproc\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003eRegProcedure\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"filename\"\u003epostgres.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003etext\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003etext*\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"filename\"\u003epostgres.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003etid\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003eItemPointer\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"filename\"\u003estorage/itemptr.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003etime\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003eTimeADT\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"filename\"\u003eutils/date.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003etime with time zone\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003eTimeTzADT\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"filename\"\u003eutils/date.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003etimestamp\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003eTimestamp\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"filename\"\u003edatatype/timestamp.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003etimestamp with time zone\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003eTimestampTz\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"filename\"\u003edatatype/timestamp.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003evarchar\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003eVarChar*\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"filename\"\u003epostgres.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003exid\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"type\"\u003eTransactionId\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ccode class=\"filename\"\u003epostgres.h\u003c/code\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e\u003cbr class=\"table-break\"\u003e\n\u003cp\u003eNow that we've gone over all of the possible structures for base types, we can show some examples of real functions.\u003c/p\u003e\n\u003c/div\u003e\n\u003cdiv class=\"sect2\" id=\"XFUNC-C-V1-CALL-CONV\"\u003e\n\u003cdiv class=\"titlepage\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch3 class=\"title\"\u003e36.10.3. Version 1 Calling Conventions \u003c/h3\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003eThe version-1 calling convention relies on macros to suppress most of the complexity of passing arguments and results. The C declaration of a version-1 function is always:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003eDatum funcname(PG_FUNCTION_ARGS)\n\u003c/pre\u003e\n\u003cp\u003eIn addition, the macro call:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003ePG_FUNCTION_INFO_V1(funcname);\n\u003c/pre\u003e\n\u003cp\u003emust appear in the same source file. (Conventionally, it's written just before the function itself.) This macro call is not needed for \u003ccode class=\"literal\"\u003einternal\u003c/code\u003e-language functions, since \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e assumes that all internal functions use the version-1 convention. It is, however, required for dynamically-loaded functions.\u003c/p\u003e\n\u003cp\u003eIn a version-1 function, each actual argument is fetched using a \u003ccode class=\"function\"\u003ePG_GETARG_\u003cem class=\"replaceable\"\u003e\u003ccode\u003exxx\u003c/code\u003e\u003c/em\u003e()\u003c/code\u003e macro that corresponds to the argument's data type. (In non-strict functions there needs to be a previous check about argument null-ness using \u003ccode class=\"function\"\u003ePG_ARGISNULL()\u003c/code\u003e; see below.) The result is returned using a \u003ccode class=\"function\"\u003ePG_RETURN_\u003cem class=\"replaceable\"\u003e\u003ccode\u003exxx\u003c/code\u003e\u003c/em\u003e()\u003c/code\u003e macro for the return type. \u003ccode class=\"function\"\u003ePG_GETARG_\u003cem class=\"replaceable\"\u003e\u003ccode\u003exxx\u003c/code\u003e\u003c/em\u003e()\u003c/code\u003e takes as its argument the number of the function argument to fetch, where the count starts at 0. \u003ccode class=\"function\"\u003ePG_RETURN_\u003cem class=\"replaceable\"\u003e\u003ccode\u003exxx\u003c/code\u003e\u003c/em\u003e()\u003c/code\u003e takes as its argument the actual value to return.\u003c/p\u003e\n\u003cp\u003eTo call another version-1 function, you can use \u003ccode class=\"function\"\u003eDirectFunctionCall\u003cem class=\"replaceable\"\u003e\u003ccode\u003en\u003c/code\u003e\u003c/em\u003e(func, arg1, ..., argn)\u003c/code\u003e. 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.\u003c/p\u003e\n\u003cp\u003eThese convenience functions and similar ones can be found in \u003ccode class=\"filename\"\u003efmgr.h\u003c/code\u003e. The \u003ccode class=\"function\"\u003eDirectFunctionCall\u003cem class=\"replaceable\"\u003e\u003ccode\u003en\u003c/code\u003e\u003c/em\u003e\u003c/code\u003e family expect a C function name as their first argument. There are also \u003ccode class=\"function\"\u003eOidFunctionCall\u003cem class=\"replaceable\"\u003e\u003ccode\u003en\u003c/code\u003e\u003c/em\u003e\u003c/code\u003e which take the OID of the target function, and some other variants. All of these expect the function's arguments to be supplied as \u003ccode class=\"type\"\u003eDatum\u003c/code\u003es, and likewise they return \u003ccode class=\"type\"\u003eDatum\u003c/code\u003e. Note that neither arguments nor result are allowed to be NULL when using these convenience functions.\u003c/p\u003e\n\u003cp\u003eFor example, to call the \u003ccode class=\"function\"\u003estarts_with(text, text)\u003c/code\u003e function from C, you can search through the catalog and find out that its C implementation is the \u003ccode class=\"function\"\u003eDatum text_starts_with(PG_FUNCTION_ARGS)\u003c/code\u003e function. Typically you would use \u003ccode class=\"literal\"\u003eDirectFunctionCall2(text_starts_with, ...)\u003c/code\u003e to call such a function. However, \u003ccode class=\"function\"\u003estarts_with(text, text)\u003c/code\u003e requires collation information, so it will fail with \u003cspan class=\"quote\"\u003e“\u003cspan class=\"quote\"\u003ecould not determine which collation to use for string comparison\u003c/span\u003e”\u003c/span\u003e if called that way. Instead you must use \u003ccode class=\"literal\"\u003eDirectFunctionCall2Coll(text_starts_with, ...)\u003c/code\u003e and provide the desired collation, which typically is just passed through from \u003ccode class=\"function\"\u003ePG_GET_COLLATION()\u003c/code\u003e, as shown in the example below.\u003c/p\u003e\n\u003cp\u003e\u003ccode class=\"filename\"\u003efmgr.h\u003c/code\u003e also supplies macros that facilitate conversions between C types and \u003ccode class=\"type\"\u003eDatum\u003c/code\u003e. For example to turn \u003ccode class=\"type\"\u003eDatum\u003c/code\u003e into \u003ccode class=\"type\"\u003etext*\u003c/code\u003e, you can use \u003ccode class=\"function\"\u003eDatumGetTextPP(X)\u003c/code\u003e. While some types have macros named like \u003ccode class=\"function\"\u003eTypeGetDatum(X)\u003c/code\u003e for the reverse conversion, \u003ccode class=\"type\"\u003etext*\u003c/code\u003e does not; it's sufficient to use the generic macro \u003ccode class=\"function\"\u003ePointerGetDatum(X)\u003c/code\u003e for that. If your extension defines additional types, it is usually convenient to define similar macros for your types too.\u003c/p\u003e\n\u003cp\u003eHere are some examples using the version-1 calling convention:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003e#include \"postgres.h\"\n#include \u0026lt;string.h\u0026gt;\n#include \"fmgr.h\"\n#include \"utils/geo_decls.h\"\n#include \"varatt.h\"\n\nPG_MODULE_MAGIC;\n\n/* by value */\n\nPG_FUNCTION_INFO_V1(add_one);\n\nDatum\nadd_one(PG_FUNCTION_ARGS)\n{\n    int32   arg = PG_GETARG_INT32(0);\n\n    PG_RETURN_INT32(arg + 1);\n}\n\n/* by reference, fixed length */\n\nPG_FUNCTION_INFO_V1(add_one_float8);\n\nDatum\nadd_one_float8(PG_FUNCTION_ARGS)\n{\n    /* The macros for FLOAT8 hide its pass-by-reference nature. */\n    float8   arg = PG_GETARG_FLOAT8(0);\n\n    PG_RETURN_FLOAT8(arg + 1.0);\n}\n\nPG_FUNCTION_INFO_V1(makepoint);\n\nDatum\nmakepoint(PG_FUNCTION_ARGS)\n{\n    /* Here, the pass-by-reference nature of Point is not hidden. */\n    Point     *pointx = PG_GETARG_POINT_P(0);\n    Point     *pointy = PG_GETARG_POINT_P(1);\n    Point     *new_point = (Point *) palloc(sizeof(Point));\n\n    new_point-\u0026gt;x = pointx-\u0026gt;x;\n    new_point-\u0026gt;y = pointy-\u0026gt;y;\n\n    PG_RETURN_POINT_P(new_point);\n}\n\n/* by reference, variable length */\n\nPG_FUNCTION_INFO_V1(copytext);\n\nDatum\ncopytext(PG_FUNCTION_ARGS)\n{\n    text     *t = PG_GETARG_TEXT_PP(0);\n\n    /*\n     * VARSIZE_ANY_EXHDR is the size of the struct in bytes, minus the\n     * VARHDRSZ or VARHDRSZ_SHORT of its header.  Construct the copy with a\n     * full-length header.\n     */\n    text     *new_t = (text *) palloc(VARSIZE_ANY_EXHDR(t) + VARHDRSZ);\n    SET_VARSIZE(new_t, VARSIZE_ANY_EXHDR(t) + VARHDRSZ);\n\n    /*\n     * VARDATA is a pointer to the data region of the new struct.  The source\n     * could be a short datum, so retrieve its data through VARDATA_ANY.\n     */\n    memcpy(VARDATA(new_t),          /* destination */\n           VARDATA_ANY(t),          /* source */\n           VARSIZE_ANY_EXHDR(t));   /* how many bytes */\n    PG_RETURN_TEXT_P(new_t);\n}\n\nPG_FUNCTION_INFO_V1(concat_text);\n\nDatum\nconcat_text(PG_FUNCTION_ARGS)\n{\n    text  *arg1 = PG_GETARG_TEXT_PP(0);\n    text  *arg2 = PG_GETARG_TEXT_PP(1);\n    int32 arg1_size = VARSIZE_ANY_EXHDR(arg1);\n    int32 arg2_size = VARSIZE_ANY_EXHDR(arg2);\n    int32 new_text_size = arg1_size + arg2_size + VARHDRSZ;\n    text *new_text = (text *) palloc(new_text_size);\n\n    SET_VARSIZE(new_text, new_text_size);\n    memcpy(VARDATA(new_text), VARDATA_ANY(arg1), arg1_size);\n    memcpy(VARDATA(new_text) + arg1_size, VARDATA_ANY(arg2), arg2_size);\n    PG_RETURN_TEXT_P(new_text);\n}\n\n/* A wrapper around starts_with(text, text) */\n\nPG_FUNCTION_INFO_V1(t_starts_with);\n\nDatum\nt_starts_with(PG_FUNCTION_ARGS)\n{\n    text       *t1 = PG_GETARG_TEXT_PP(0);\n    text       *t2 = PG_GETARG_TEXT_PP(1);\n    Oid         collid = PG_GET_COLLATION();\n    bool        result;\n\n    result = DatumGetBool(DirectFunctionCall2Coll(text_starts_with,\n                                                  collid,\n                                                  PointerGetDatum(t1),\n                                                  PointerGetDatum(t2)));\n    PG_RETURN_BOOL(result);\n}\n\n\u003c/pre\u003e\n\u003cp\u003eSupposing that the above code has been prepared in file \u003ccode class=\"filename\"\u003efuncs.c\u003c/code\u003e and compiled into a shared object, we could define the functions to \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e with commands like this:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003eCREATE FUNCTION add_one(integer) RETURNS integer\n     AS '\u003cem class=\"replaceable\"\u003e\u003ccode\u003eDIRECTORY\u003c/code\u003e\u003c/em\u003e/funcs', 'add_one'\n     LANGUAGE C STRICT;\n\n-- note overloading of SQL function name \"add_one\"\nCREATE FUNCTION add_one(double precision) RETURNS double precision\n     AS '\u003cem class=\"replaceable\"\u003e\u003ccode\u003eDIRECTORY\u003c/code\u003e\u003c/em\u003e/funcs', 'add_one_float8'\n     LANGUAGE C STRICT;\n\nCREATE FUNCTION makepoint(point, point) RETURNS point\n     AS '\u003cem class=\"replaceable\"\u003e\u003ccode\u003eDIRECTORY\u003c/code\u003e\u003c/em\u003e/funcs', 'makepoint'\n     LANGUAGE C STRICT;\n\nCREATE FUNCTION copytext(text) RETURNS text\n     AS '\u003cem class=\"replaceable\"\u003e\u003ccode\u003eDIRECTORY\u003c/code\u003e\u003c/em\u003e/funcs', 'copytext'\n     LANGUAGE C STRICT;\n\nCREATE FUNCTION concat_text(text, text) RETURNS text\n     AS '\u003cem class=\"replaceable\"\u003e\u003ccode\u003eDIRECTORY\u003c/code\u003e\u003c/em\u003e/funcs', 'concat_text'\n     LANGUAGE C STRICT;\n\nCREATE FUNCTION t_starts_with(text, text) RETURNS boolean\n     AS '\u003cem class=\"replaceable\"\u003e\u003ccode\u003eDIRECTORY\u003c/code\u003e\u003c/em\u003e/funcs', 't_starts_with'\n     LANGUAGE C STRICT;\n\u003c/pre\u003e\n\u003cp\u003eHere, \u003cem class=\"replaceable\"\u003e\u003ccode\u003eDIRECTORY\u003c/code\u003e\u003c/em\u003e stands for the directory of the shared library file (for instance the \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e tutorial directory, which contains the code for the examples used in this section). (Better style would be to use just \u003ccode class=\"literal\"\u003e'funcs'\u003c/code\u003e in the \u003ccode class=\"literal\"\u003eAS\u003c/code\u003e clause, after having added \u003cem class=\"replaceable\"\u003e\u003ccode\u003eDIRECTORY\u003c/code\u003e\u003c/em\u003e to the search path. In any case, we can omit the system-specific extension for a shared library, commonly \u003ccode class=\"literal\"\u003e.so\u003c/code\u003e.)\u003c/p\u003e\n\u003cp\u003eNotice that we have specified the functions as \u003cspan class=\"quote\"\u003e“\u003cspan class=\"quote\"\u003estrict\u003c/span\u003e”\u003c/span\u003e, 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 \u003ccode class=\"function\"\u003ePG_ARGISNULL()\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003eThe macro \u003ccode class=\"function\"\u003ePG_ARGISNULL(\u003cem class=\"replaceable\"\u003e\u003ccode\u003en\u003c/code\u003e\u003c/em\u003e)\u003c/code\u003e allows a function to test whether each input is null. (Of course, doing this is only necessary in functions not declared \u003cspan class=\"quote\"\u003e“\u003cspan class=\"quote\"\u003estrict\u003c/span\u003e”\u003c/span\u003e.) As with the \u003ccode class=\"function\"\u003ePG_GETARG_\u003cem class=\"replaceable\"\u003e\u003ccode\u003exxx\u003c/code\u003e\u003c/em\u003e()\u003c/code\u003e macros, the input arguments are counted beginning at zero. Note that one should refrain from executing \u003ccode class=\"function\"\u003ePG_GETARG_\u003cem class=\"replaceable\"\u003e\u003ccode\u003exxx\u003c/code\u003e\u003c/em\u003e()\u003c/code\u003e until one has verified that the argument isn't null. To return a null result, execute \u003ccode class=\"function\"\u003ePG_RETURN_NULL()\u003c/code\u003e; this works in both strict and nonstrict functions.\u003c/p\u003e\n\u003cp\u003eAt first glance, the version-1 coding conventions might appear to be just pointless obscurantism, compared to using plain \u003ccode class=\"literal\"\u003eC\u003c/code\u003e calling conventions. They do however allow us to deal with \u003ccode class=\"literal\"\u003eNULL\u003c/code\u003eable arguments/return values, and \u003cspan class=\"quote\"\u003e“\u003cspan class=\"quote\"\u003etoasted\u003c/span\u003e”\u003c/span\u003e (compressed or out-of-line) values.\u003c/p\u003e\n\u003cp\u003eOther options provided by the version-1 interface are two variants of the \u003ccode class=\"function\"\u003ePG_GETARG_\u003cem class=\"replaceable\"\u003e\u003ccode\u003exxx\u003c/code\u003e\u003c/em\u003e()\u003c/code\u003e macros. The first of these, \u003ccode class=\"function\"\u003ePG_GETARG_\u003cem class=\"replaceable\"\u003e\u003ccode\u003exxx\u003c/code\u003e\u003c/em\u003e_COPY()\u003c/code\u003e, guarantees to return a copy of the specified argument that is safe for writing into. (The normal macros will sometimes return a pointer to a value that is physically stored in a table, which must not be written to. Using the \u003ccode class=\"function\"\u003ePG_GETARG_\u003cem class=\"replaceable\"\u003e\u003ccode\u003exxx\u003c/code\u003e\u003c/em\u003e_COPY()\u003c/code\u003e macros guarantees a writable result.) The second variant consists of the \u003ccode class=\"function\"\u003ePG_GETARG_\u003cem class=\"replaceable\"\u003e\u003ccode\u003exxx\u003c/code\u003e\u003c/em\u003e_SLICE()\u003c/code\u003e macros which take three arguments. The first is the number of the function argument (as above). The second and third are the offset and length of the segment to be returned. Offsets are counted from zero, and a negative length requests that the remainder of the value be returned. These macros provide more efficient access to parts of large values in the case where they have storage type \u003cspan class=\"quote\"\u003e“\u003cspan class=\"quote\"\u003eexternal\u003c/span\u003e”\u003c/span\u003e. (The storage type of a column can be specified using \u003ccode class=\"literal\"\u003eALTER TABLE \u003cem class=\"replaceable\"\u003e\u003ccode\u003etablename\u003c/code\u003e\u003c/em\u003e ALTER COLUMN \u003cem class=\"replaceable\"\u003e\u003ccode\u003ecolname\u003c/code\u003e\u003c/em\u003e SET STORAGE \u003cem class=\"replaceable\"\u003e\u003ccode\u003estoragetype\u003c/code\u003e\u003c/em\u003e\u003c/code\u003e. \u003cem class=\"replaceable\"\u003e\u003ccode\u003estoragetype\u003c/code\u003e\u003c/em\u003e is one of \u003ccode class=\"literal\"\u003eplain\u003c/code\u003e, \u003ccode class=\"literal\"\u003eexternal\u003c/code\u003e, \u003ccode class=\"literal\"\u003eextended\u003c/code\u003e, or \u003ccode class=\"literal\"\u003emain\u003c/code\u003e.)\u003c/p\u003e\n\u003cp\u003eFinally, the version-1 function call conventions make it possible to return set results (\u003ca class=\"xref\" href=\"/docs/18/xfunc-c.html#XFUNC-C-RETURN-SET\" title=\"36.10.9. Returning Sets\"\u003eSection 36.10.9\u003c/a\u003e) and implement trigger functions (\u003ca class=\"xref\" href=\"/docs/18/triggers.html\" title=\"Chapter 37. Triggers\"\u003eChapter 37\u003c/a\u003e) and procedural-language call handlers (\u003ca class=\"xref\" href=\"/docs/18/plhandler.html\" title=\"Chapter 57. Writing a Procedural Language Handler\"\u003eChapter 57\u003c/a\u003e). For more details see \u003ccode class=\"filename\"\u003esrc/backend/utils/fmgr/README\u003c/code\u003e in the source distribution.\u003c/p\u003e\n\u003c/div\u003e\n\u003cdiv class=\"sect2\" id=\"XFUNC-C-CODE\"\u003e\n\u003cdiv class=\"titlepage\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch3 class=\"title\"\u003e36.10.4. Writing Code \u003c/h3\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003eBefore we turn to the more advanced topics, we should discuss some coding rules for \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e C-language functions. While it might be possible to load functions written in languages other than C into \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e, this is usually difficult (when it is possible at all) because other languages, such as C++, FORTRAN, or Pascal often do not follow the same calling convention as C. That is, other languages do not pass argument and return values between functions in the same way. For this reason, we will assume that your C-language functions are actually written in C.\u003c/p\u003e\n\u003cp\u003eThe basic rules for writing and building C functions are as follows:\u003c/p\u003e\n\u003cdiv class=\"itemizedlist\"\u003e\n\u003cul class=\"itemizedlist\"\u003e\n\u003cli class=\"listitem\"\u003e\n\u003cp\u003eUse \u003ccode class=\"literal\"\u003epg_config --includedir-server\u003c/code\u003e to find out where the \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e server header files are installed on your system (or the system that your users will be running on).\u003c/p\u003e\n\u003c/li\u003e\n\u003cli class=\"listitem\"\u003e\n\u003cp\u003eCompiling and linking your code so that it can be dynamically loaded into \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e always requires special flags. See \u003ca class=\"xref\" href=\"/docs/18/xfunc-c.html#DFUNC\" title=\"36.10.5. Compiling and Linking Dynamically-Loaded Functions\"\u003eSection 36.10.5\u003c/a\u003e for a detailed explanation of how to do it for your particular operating system.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli class=\"listitem\"\u003e\n\u003cp\u003eRemember to define a \u003cspan class=\"quote\"\u003e“\u003cspan class=\"quote\"\u003emagic block\u003c/span\u003e”\u003c/span\u003e for your shared library, as described in \u003ca class=\"xref\" href=\"/docs/18/xfunc-c.html#XFUNC-C-DYNLOAD\" title=\"36.10.1. Dynamic Loading\"\u003eSection 36.10.1\u003c/a\u003e.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli class=\"listitem\"\u003e\n\u003cp\u003eWhen allocating memory, use the \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e functions \u003ccode class=\"function\"\u003epalloc\u003c/code\u003e and \u003ccode class=\"function\"\u003epfree\u003c/code\u003e instead of the corresponding C library functions \u003ccode class=\"function\"\u003emalloc\u003c/code\u003e and \u003ccode class=\"function\"\u003efree\u003c/code\u003e. The memory allocated by \u003ccode class=\"function\"\u003epalloc\u003c/code\u003e will be freed automatically at the end of each transaction, preventing memory leaks.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli class=\"listitem\"\u003e\n\u003cp\u003eAlways zero the bytes of your structures using \u003ccode class=\"function\"\u003ememset\u003c/code\u003e (or allocate them with \u003ccode class=\"function\"\u003epalloc0\u003c/code\u003e in the first place). Even if you assign to each field of your structure, there might be alignment padding (holes in the structure) that contain garbage values. Without this, it's difficult to support hash indexes or hash joins, as you must pick out only the significant bits of your data structure to compute a hash. The planner also sometimes relies on comparing constants via bitwise equality, so you can get undesirable planning results if logically-equivalent values aren't bitwise equal.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli class=\"listitem\"\u003e\n\u003cp\u003eMost of the internal \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e types are declared in \u003ccode class=\"filename\"\u003epostgres.h\u003c/code\u003e, while the function manager interfaces (\u003ccode class=\"symbol\"\u003ePG_FUNCTION_ARGS\u003c/code\u003e, etc.) are in \u003ccode class=\"filename\"\u003efmgr.h\u003c/code\u003e, so you will need to include at least these two files. For portability reasons it's best to include \u003ccode class=\"filename\"\u003epostgres.h\u003c/code\u003e \u003cspan class=\"emphasis\"\u003e\u003cem\u003efirst\u003c/em\u003e\u003c/span\u003e, before any other system or user header files. Including \u003ccode class=\"filename\"\u003epostgres.h\u003c/code\u003e will also include \u003ccode class=\"filename\"\u003eelog.h\u003c/code\u003e and \u003ccode class=\"filename\"\u003epalloc.h\u003c/code\u003e for you.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli class=\"listitem\"\u003e\n\u003cp\u003eSymbol names defined within object files must not conflict with each other or with symbols defined in the \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e server executable. You will have to rename your functions or variables if you get error messages to this effect.\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cdiv class=\"sect2\" id=\"DFUNC\"\u003e\n\u003cdiv class=\"titlepage\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch3 class=\"title\"\u003e36.10.5. Compiling and Linking Dynamically-Loaded Functions \u003c/h3\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003eBefore you are able to use your \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e extension functions written in C, they must be compiled and linked in a special way to produce a file that can be dynamically loaded by the server. To be precise, a \u003cem class=\"firstterm\"\u003eshared library\u003c/em\u003e needs to be created.\u003c/p\u003e\n\u003cp\u003eFor information beyond what is contained in this section you should read the documentation of your operating system, in particular the manual pages for the C compiler, \u003ccode class=\"command\"\u003ecc\u003c/code\u003e, and the link editor, \u003ccode class=\"command\"\u003eld\u003c/code\u003e. In addition, the \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e source code contains several working examples in the \u003ccode class=\"filename\"\u003econtrib\u003c/code\u003e directory. If you rely on these examples you will make your modules dependent on the availability of the \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e source code, however.\u003c/p\u003e\n\u003cp\u003eCreating shared libraries is generally analogous to linking executables: first the source files are compiled into object files, then the object files are linked together. The object files need to be created as \u003cem class=\"firstterm\"\u003eposition-independent code\u003c/em\u003e (PIC), which conceptually means that they can be placed at an arbitrary location in memory when they are loaded by the executable. (Object files intended for executables are usually not compiled that way.) The command to link a shared library contains special flags to distinguish it from linking an executable (at least in theory — on some systems the practice is much uglier).\u003c/p\u003e\n\u003cp\u003eIn the following examples we assume that your source code is in a file \u003ccode class=\"filename\"\u003efoo.c\u003c/code\u003e and we will create a shared library \u003ccode class=\"filename\"\u003efoo.so\u003c/code\u003e. The intermediate object file will be called \u003ccode class=\"filename\"\u003efoo.o\u003c/code\u003e unless otherwise noted. A shared library can contain more than one object file, but we only use one here.\u003c/p\u003e\n\u003cdiv class=\"variablelist\"\u003e\n\u003cdl class=\"variablelist\"\u003e\n\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003cspan class=\"systemitem\"\u003eFreeBSD\u003c/span\u003e \u003c/span\u003e\u003c/dt\u003e\n\u003cdd\u003e\n\u003cp\u003eThe compiler flag to create PIC is \u003ccode class=\"option\"\u003e-fPIC\u003c/code\u003e. To create shared libraries the compiler flag is \u003ccode class=\"option\"\u003e-shared\u003c/code\u003e.\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003ecc -fPIC -c foo.c\ncc -shared -o foo.so foo.o\n\u003c/pre\u003e\n\u003cp\u003eThis is applicable as of version 13.0 of \u003cspan class=\"systemitem\"\u003eFreeBSD\u003c/span\u003e, older versions used the \u003ccode class=\"filename\"\u003egcc\u003c/code\u003e compiler.\u003c/p\u003e\n\u003c/dd\u003e\n\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003cspan class=\"systemitem\"\u003eLinux\u003c/span\u003e \u003c/span\u003e\u003c/dt\u003e\n\u003cdd\u003e\n\u003cp\u003eThe compiler flag to create PIC is \u003ccode class=\"option\"\u003e-fPIC\u003c/code\u003e. The compiler flag to create a shared library is \u003ccode class=\"option\"\u003e-shared\u003c/code\u003e. A complete example looks like this:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003ecc -fPIC -c foo.c\ncc -shared -o foo.so foo.o\n\u003c/pre\u003e\n\u003c/dd\u003e\n\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003cspan class=\"systemitem\"\u003emacOS\u003c/span\u003e \u003c/span\u003e\u003c/dt\u003e\n\u003cdd\u003e\n\u003cp\u003eHere is an example. It assumes the developer tools are installed.\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003ecc -c foo.c\ncc -bundle -flat_namespace -undefined suppress -o foo.so foo.o\n\u003c/pre\u003e\n\u003c/dd\u003e\n\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003cspan class=\"systemitem\"\u003eNetBSD\u003c/span\u003e \u003c/span\u003e\u003c/dt\u003e\n\u003cdd\u003e\n\u003cp\u003eThe compiler flag to create PIC is \u003ccode class=\"option\"\u003e-fPIC\u003c/code\u003e. For ELF systems, the compiler with the flag \u003ccode class=\"option\"\u003e-shared\u003c/code\u003e is used to link shared libraries. On the older non-ELF systems, \u003ccode class=\"literal\"\u003eld -Bshareable\u003c/code\u003e is used.\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003egcc -fPIC -c foo.c\ngcc -shared -o foo.so foo.o\n\u003c/pre\u003e\n\u003c/dd\u003e\n\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003cspan class=\"systemitem\"\u003eOpenBSD\u003c/span\u003e \u003c/span\u003e\u003c/dt\u003e\n\u003cdd\u003e\n\u003cp\u003eThe compiler flag to create PIC is \u003ccode class=\"option\"\u003e-fPIC\u003c/code\u003e. \u003ccode class=\"literal\"\u003eld -Bshareable\u003c/code\u003e is used to link shared libraries.\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003egcc -fPIC -c foo.c\nld -Bshareable -o foo.so foo.o\n\u003c/pre\u003e\n\u003c/dd\u003e\n\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003cspan class=\"systemitem\"\u003eSolaris\u003c/span\u003e \u003c/span\u003e\u003c/dt\u003e\n\u003cdd\u003e\n\u003cp\u003eThe compiler flag to create PIC is \u003ccode class=\"option\"\u003e-KPIC\u003c/code\u003e with the Sun compiler and \u003ccode class=\"option\"\u003e-fPIC\u003c/code\u003e with \u003cspan class=\"application\"\u003eGCC\u003c/span\u003e. To link shared libraries, the compiler option is \u003ccode class=\"option\"\u003e-G\u003c/code\u003e with either compiler or alternatively \u003ccode class=\"option\"\u003e-shared\u003c/code\u003e with \u003cspan class=\"application\"\u003eGCC\u003c/span\u003e.\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003ecc -KPIC -c foo.c\ncc -G -o foo.so foo.o\n\u003c/pre\u003e\n\u003cp\u003eor\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003egcc -fPIC -c foo.c\ngcc -G -o foo.so foo.o\n\u003c/pre\u003e\n\u003c/dd\u003e\n\u003c/dl\u003e\n\u003c/div\u003e\n\u003cdiv class=\"tip\"\u003e\n\u003ch3 class=\"title\"\u003eTip\u003c/h3\u003e\n\u003cp\u003eIf this is too complicated for you, you should consider using \u003ca class=\"ulink\" href=\"https://www.gnu.org/software/libtool/\"\u003e\u003cspan class=\"productname\"\u003eGNU Libtool\u003c/span\u003e\u003c/a\u003e, which hides the platform differences behind a uniform interface.\u003c/p\u003e\n\u003c/div\u003e\n\u003cp\u003eThe resulting shared library file can then be loaded into \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e. When specifying the file name to the \u003ccode class=\"command\"\u003eCREATE FUNCTION\u003c/code\u003e command, one must give it the name of the shared library file, not the intermediate object file. Note that the system's standard shared-library extension (usually \u003ccode class=\"literal\"\u003e.so\u003c/code\u003e or \u003ccode class=\"literal\"\u003e.sl\u003c/code\u003e) can be omitted from the \u003ccode class=\"command\"\u003eCREATE FUNCTION\u003c/code\u003e command, and normally should be omitted for best portability.\u003c/p\u003e\n\u003cp\u003eRefer back to \u003ca class=\"xref\" href=\"/docs/18/xfunc-c.html#XFUNC-C-DYNLOAD\" title=\"36.10.1. Dynamic Loading\"\u003eSection 36.10.1\u003c/a\u003e about where the server expects to find the shared library files.\u003c/p\u003e\n\u003c/div\u003e\n\u003cdiv class=\"sect2\" id=\"XFUNC-API-ABI-STABILITY-GUIDANCE\"\u003e\n\u003cdiv class=\"titlepage\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch3 class=\"title\"\u003e36.10.6. Server API and ABI Stability Guidance \u003c/h3\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003eThis section contains guidance to authors of extensions and other server plugins about API and ABI stability in the \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e server.\u003c/p\u003e\n\u003cdiv class=\"sect3\" id=\"XFUNC-GUIDANCE-GENERAL\"\u003e\n\u003cdiv class=\"titlepage\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch4 class=\"title\"\u003e36.10.6.1. General \u003c/h4\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003eThe \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e server contains several well-demarcated APIs for server plugins, such as the function manager (fmgr, described in this chapter), SPI (\u003ca class=\"xref\" href=\"/docs/18/spi.html\" title=\"Chapter 45. Server Programming Interface\"\u003eChapter 45\u003c/a\u003e), and various hooks specifically designed for extensions. These interfaces are carefully managed for long-term stability and compatibility. However, the entire set of global functions and variables in the server effectively constitutes the publicly usable API, and most of it was not designed with extensibility and long-term stability in mind.\u003c/p\u003e\n\u003cp\u003eTherefore, while taking advantage of these interfaces is valid, the further one strays from the well-trodden path, the likelier it will be that one might encounter API or ABI compatibility issues at some point. Extension authors are encouraged to provide feedback about their requirements, so that over time, as new use patterns arise, certain interfaces can be considered more stabilized or new, better-designed interfaces can be added.\u003c/p\u003e\n\u003c/div\u003e\n\u003cdiv class=\"sect3\" id=\"XFUNC-GUIDANCE-API-COMPATIBILITY\"\u003e\n\u003cdiv class=\"titlepage\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch4 class=\"title\"\u003e36.10.6.2. API Compatibility \u003c/h4\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003eThe API, or application programming interface, is the interface used at compile time.\u003c/p\u003e\n\u003cdiv class=\"sect4\" id=\"XFUNC-GUIDANCE-API-MAJOR-VERSIONS\"\u003e\n\u003cdiv class=\"titlepage\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch5 class=\"title\"\u003e36.10.6.2.1. Major Versions \u003c/h5\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003eThere is \u003cspan class=\"emphasis\"\u003e\u003cem\u003eno\u003c/em\u003e\u003c/span\u003e promise of API compatibility between \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e major versions. Extension code therefore might require source code changes to work with multiple major versions. These can usually be managed with preprocessor conditions such as \u003ccode class=\"literal\"\u003e#if PG_VERSION_NUM \u0026gt;= 160000\u003c/code\u003e. Sophisticated extensions that use interfaces beyond the well-demarcated ones usually require a few such changes for each major server version.\u003c/p\u003e\n\u003c/div\u003e\n\u003cdiv class=\"sect4\" id=\"XFUNC-GUIDANCE-API-MNINOR-VERSIONS\"\u003e\n\u003cdiv class=\"titlepage\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch5 class=\"title\"\u003e36.10.6.2.2. Minor Versions \u003c/h5\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003e\u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e makes an effort to avoid server API breaks in minor releases. In general, extension code that compiles and works with a minor release should also compile and work with any other minor release of the same major version, past or future.\u003c/p\u003e\n\u003cp\u003eWhen a change \u003cspan class=\"emphasis\"\u003e\u003cem\u003eis\u003c/em\u003e\u003c/span\u003e required, it will be carefully managed, taking the requirements of extensions into account. Such changes will be communicated in the release notes (\u003ca class=\"xref\" href=\"/docs/18/release.html\" title=\"Appendix E. Release Notes\"\u003eAppendix E\u003c/a\u003e).\u003c/p\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cdiv class=\"sect3\" id=\"XFUNC-GUIDANCE-ABI-COMPATIBILITY\"\u003e\n\u003cdiv class=\"titlepage\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch4 class=\"title\"\u003e36.10.6.3. ABI Compatibility \u003c/h4\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003eThe ABI, or application binary interface, is the interface used at run time.\u003c/p\u003e\n\u003cdiv class=\"sect4\" id=\"XFUNC-GUIDANCE-ABI-MAJOR-VERSIONS\"\u003e\n\u003cdiv class=\"titlepage\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch5 class=\"title\"\u003e36.10.6.3.1. Major Versions \u003c/h5\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003eServers of different major versions have intentionally incompatible ABIs. Extensions that use server APIs must therefore be re-compiled for each major release. The inclusion of \u003ccode class=\"literal\"\u003ePG_MODULE_MAGIC\u003c/code\u003e (see \u003ca class=\"xref\" href=\"/docs/18/xfunc-c.html#XFUNC-C-DYNLOAD\" title=\"36.10.1. Dynamic Loading\"\u003eSection 36.10.1\u003c/a\u003e) ensures that code compiled for one major version will be rejected by other major versions.\u003c/p\u003e\n\u003c/div\u003e\n\u003cdiv class=\"sect4\" id=\"XFUNC-GUIDANCE-ABI-MNINOR-VERSIONS\"\u003e\n\u003cdiv class=\"titlepage\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch5 class=\"title\"\u003e36.10.6.3.2. Minor Versions \u003c/h5\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003e\u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e makes an effort to avoid server ABI breaks in minor releases. In general, an extension compiled against any minor release should work with any other minor release of the same major version, past or future.\u003c/p\u003e\n\u003cp\u003eWhen a change \u003cspan class=\"emphasis\"\u003e\u003cem\u003eis\u003c/em\u003e\u003c/span\u003e required, \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e will choose the least invasive change possible, for example by squeezing a new field into padding space or appending it to the end of a struct. These sorts of changes should not impact extensions unless they use very unusual code patterns.\u003c/p\u003e\n\u003cp\u003eIn rare cases, however, even such non-invasive changes may be impractical or impossible. In such an event, the change will be carefully managed, taking the requirements of extensions into account. Such changes will also be documented in the release notes (\u003ca class=\"xref\" href=\"/docs/18/release.html\" title=\"Appendix E. Release Notes\"\u003eAppendix E\u003c/a\u003e).\u003c/p\u003e\n\u003cp\u003eNote, however, that many parts of the server are not designed or maintained as publicly-consumable APIs (and that, in most cases, the actual boundary is also not well-defined). If urgent needs arise, changes in those parts will naturally be made with less consideration for extension code than changes in well-defined and widely used interfaces.\u003c/p\u003e\n\u003cp\u003eAlso, in the absence of automated detection of such changes, this is not a guarantee, but historically such breaking changes have been extremely rare.\u003c/p\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cdiv class=\"sect2\" id=\"XFUNC-C-COMPOSITE-TYPE-ARGS\"\u003e\n\u003cdiv class=\"titlepage\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch3 class=\"title\"\u003e36.10.7. Composite-Type Arguments \u003c/h3\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003eComposite types do not have a fixed layout like C structures. Instances of a composite type can contain null fields. In addition, composite types that are part of an inheritance hierarchy can have different fields than other members of the same inheritance hierarchy. Therefore, \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e provides a function interface for accessing fields of composite types from C.\u003c/p\u003e\n\u003cp\u003eSuppose we want to write a function to answer the query:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003eSELECT name, c_overpaid(emp, 1500) AS overpaid\n    FROM emp\n    WHERE name = 'Bill' OR name = 'Sam';\n\u003c/pre\u003e\n\u003cp\u003eUsing the version-1 calling conventions, we can define \u003ccode class=\"function\"\u003ec_overpaid\u003c/code\u003e as:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003e#include \"postgres.h\"\n#include \"executor/executor.h\"  /* for GetAttributeByName() */\n\nPG_MODULE_MAGIC;\n\nPG_FUNCTION_INFO_V1(c_overpaid);\n\nDatum\nc_overpaid(PG_FUNCTION_ARGS)\n{\n    HeapTupleHeader  t = PG_GETARG_HEAPTUPLEHEADER(0);\n    int32            limit = PG_GETARG_INT32(1);\n    bool isnull;\n    Datum salary;\n\n    salary = GetAttributeByName(t, \"salary\", \u0026amp;isnull);\n    if (isnull)\n        PG_RETURN_BOOL(false);\n    /* Alternatively, we might prefer to do PG_RETURN_NULL() for null salary. */\n\n    PG_RETURN_BOOL(DatumGetInt32(salary) \u0026gt; limit);\n}\n\n\u003c/pre\u003e\n\u003cp\u003e\u003ccode class=\"function\"\u003eGetAttributeByName\u003c/code\u003e is the \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e system function that returns attributes out of the specified row. It has three arguments: the argument of type \u003ccode class=\"type\"\u003eHeapTupleHeader\u003c/code\u003e passed into the function, the name of the desired attribute, and a return parameter that tells whether the attribute is null. \u003ccode class=\"function\"\u003eGetAttributeByName\u003c/code\u003e returns a \u003ccode class=\"type\"\u003eDatum\u003c/code\u003e value that you can convert to the proper data type by using the appropriate \u003ccode class=\"function\"\u003eDatumGet\u003cem class=\"replaceable\"\u003e\u003ccode\u003eXXX\u003c/code\u003e\u003c/em\u003e()\u003c/code\u003e function. Note that the return value is meaningless if the null flag is set; always check the null flag before trying to do anything with the result.\u003c/p\u003e\n\u003cp\u003eThere is also \u003ccode class=\"function\"\u003eGetAttributeByNum\u003c/code\u003e, which selects the target attribute by column number instead of name.\u003c/p\u003e\n\u003cp\u003eThe following command declares the function \u003ccode class=\"function\"\u003ec_overpaid\u003c/code\u003e in SQL:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003eCREATE FUNCTION c_overpaid(emp, integer) RETURNS boolean\n    AS '\u003cem class=\"replaceable\"\u003e\u003ccode\u003eDIRECTORY\u003c/code\u003e\u003c/em\u003e/funcs', 'c_overpaid'\n    LANGUAGE C STRICT;\n\u003c/pre\u003e\n\u003cp\u003eNotice we have used \u003ccode class=\"literal\"\u003eSTRICT\u003c/code\u003e so that we did not have to check whether the input arguments were NULL.\u003c/p\u003e\n\u003c/div\u003e\n\u003cdiv class=\"sect2\" id=\"XFUNC-C-RETURNING-ROWS\"\u003e\n\u003cdiv class=\"titlepage\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch3 class=\"title\"\u003e36.10.8. Returning Rows (Composite Types) \u003c/h3\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003eTo return a row or composite-type value from a C-language function, you can use a special API that provides macros and functions to hide most of the complexity of building composite data types. To use this API, the source file must include:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003e#include \"funcapi.h\"\n\u003c/pre\u003e\n\u003cp\u003eThere are two ways you can build a composite data value (henceforth a \u003cspan class=\"quote\"\u003e“\u003cspan class=\"quote\"\u003etuple\u003c/span\u003e”\u003c/span\u003e): you can build it from an array of Datum values, or from an array of C strings that can be passed to the input conversion functions of the tuple's column data types. In either case, you first need to obtain or construct a \u003ccode class=\"structname\"\u003eTupleDesc\u003c/code\u003e descriptor for the tuple structure. When working with Datums, you pass the \u003ccode class=\"structname\"\u003eTupleDesc\u003c/code\u003e to \u003ccode class=\"function\"\u003eBlessTupleDesc\u003c/code\u003e, and then call \u003ccode class=\"function\"\u003eheap_form_tuple\u003c/code\u003e for each row. When working with C strings, you pass the \u003ccode class=\"structname\"\u003eTupleDesc\u003c/code\u003e to \u003ccode class=\"function\"\u003eTupleDescGetAttInMetadata\u003c/code\u003e, and then call \u003ccode class=\"function\"\u003eBuildTupleFromCStrings\u003c/code\u003e for each row. In the case of a function returning a set of tuples, the setup steps can all be done once during the first call of the function.\u003c/p\u003e\n\u003cp\u003eSeveral helper functions are available for setting up the needed \u003ccode class=\"structname\"\u003eTupleDesc\u003c/code\u003e. The recommended way to do this in most functions returning composite values is to call:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003eTypeFuncClass get_call_result_type(FunctionCallInfo fcinfo,\n                                   Oid *resultTypeId,\n                                   TupleDesc *resultTupleDesc)\n\u003c/pre\u003e\n\u003cp\u003epassing the same \u003ccode class=\"literal\"\u003efcinfo\u003c/code\u003e struct passed to the calling function itself. (This of course requires that you use the version-1 calling conventions.) \u003ccode class=\"varname\"\u003eresultTypeId\u003c/code\u003e can be specified as \u003ccode class=\"literal\"\u003eNULL\u003c/code\u003e or as the address of a local variable to receive the function's result type OID. \u003ccode class=\"varname\"\u003eresultTupleDesc\u003c/code\u003e should be the address of a local \u003ccode class=\"structname\"\u003eTupleDesc\u003c/code\u003e variable. Check that the result is \u003ccode class=\"literal\"\u003eTYPEFUNC_COMPOSITE\u003c/code\u003e; if so, \u003ccode class=\"varname\"\u003eresultTupleDesc\u003c/code\u003e has been filled with the needed \u003ccode class=\"structname\"\u003eTupleDesc\u003c/code\u003e. (If it is not, you can report an error along the lines of \u003cspan class=\"quote\"\u003e“\u003cspan class=\"quote\"\u003efunction returning record called in context that cannot accept type record\u003c/span\u003e”\u003c/span\u003e.)\u003c/p\u003e\n\u003cdiv class=\"tip\"\u003e\n\u003ch3 class=\"title\"\u003eTip\u003c/h3\u003e\n\u003cp\u003e\u003ccode class=\"function\"\u003eget_call_result_type\u003c/code\u003e can resolve the actual type of a polymorphic function result; so it is useful in functions that return scalar polymorphic results, not only functions that return composites. The \u003ccode class=\"varname\"\u003eresultTypeId\u003c/code\u003e output is primarily useful for functions returning polymorphic scalars.\u003c/p\u003e\n\u003c/div\u003e\n\u003cdiv class=\"note\"\u003e\n\u003ch3 class=\"title\"\u003eNote\u003c/h3\u003e\n\u003cp\u003e\u003ccode class=\"function\"\u003eget_call_result_type\u003c/code\u003e has a sibling \u003ccode class=\"function\"\u003eget_expr_result_type\u003c/code\u003e, which can be used to resolve the expected output type for a function call represented by an expression tree. This can be used when trying to determine the result type from outside the function itself. There is also \u003ccode class=\"function\"\u003eget_func_result_type\u003c/code\u003e, which can be used when only the function's OID is available. However these functions are not able to deal with functions declared to return \u003ccode class=\"structname\"\u003erecord\u003c/code\u003e, and \u003ccode class=\"function\"\u003eget_func_result_type\u003c/code\u003e cannot resolve polymorphic types, so you should preferentially use \u003ccode class=\"function\"\u003eget_call_result_type\u003c/code\u003e.\u003c/p\u003e\n\u003c/div\u003e\n\u003cp\u003eOlder, now-deprecated functions for obtaining \u003ccode class=\"structname\"\u003eTupleDesc\u003c/code\u003es are:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003eTupleDesc RelationNameGetTupleDesc(const char *relname)\n\u003c/pre\u003e\n\u003cp\u003eto get a \u003ccode class=\"structname\"\u003eTupleDesc\u003c/code\u003e for the row type of a named relation, and:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003eTupleDesc TypeGetTupleDesc(Oid typeoid, List *colaliases)\n\u003c/pre\u003e\n\u003cp\u003eto get a \u003ccode class=\"structname\"\u003eTupleDesc\u003c/code\u003e based on a type OID. This can be used to get a \u003ccode class=\"structname\"\u003eTupleDesc\u003c/code\u003e for a base or composite type. It will not work for a function that returns \u003ccode class=\"structname\"\u003erecord\u003c/code\u003e, however, and it cannot resolve polymorphic types.\u003c/p\u003e\n\u003cp\u003eOnce you have a \u003ccode class=\"structname\"\u003eTupleDesc\u003c/code\u003e, call:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003eTupleDesc BlessTupleDesc(TupleDesc tupdesc)\n\u003c/pre\u003e\n\u003cp\u003eif you plan to work with Datums, or:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003eAttInMetadata *TupleDescGetAttInMetadata(TupleDesc tupdesc)\n\u003c/pre\u003e\n\u003cp\u003eif you plan to work with C strings. If you are writing a function returning set, you can save the results of these functions in the \u003ccode class=\"structname\"\u003eFuncCallContext\u003c/code\u003e structure — use the \u003ccode class=\"structfield\"\u003etuple_desc\u003c/code\u003e or \u003ccode class=\"structfield\"\u003eattinmeta\u003c/code\u003e field respectively.\u003c/p\u003e\n\u003cp\u003eWhen working with Datums, use:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003eHeapTuple heap_form_tuple(TupleDesc tupdesc, Datum *values, bool *isnull)\n\u003c/pre\u003e\n\u003cp\u003eto build a \u003ccode class=\"structname\"\u003eHeapTuple\u003c/code\u003e given user data in Datum form.\u003c/p\u003e\n\u003cp\u003eWhen working with C strings, use:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003eHeapTuple BuildTupleFromCStrings(AttInMetadata *attinmeta, char **values)\n\u003c/pre\u003e\n\u003cp\u003eto build a \u003ccode class=\"structname\"\u003eHeapTuple\u003c/code\u003e given user data in C string form. \u003cem class=\"parameter\"\u003e\u003ccode\u003evalues\u003c/code\u003e\u003c/em\u003e is an array of C strings, one for each attribute of the return row. Each C string should be in the form expected by the input function of the attribute data type. In order to return a null value for one of the attributes, the corresponding pointer in the \u003cem class=\"parameter\"\u003e\u003ccode\u003evalues\u003c/code\u003e\u003c/em\u003e array should be set to \u003ccode class=\"symbol\"\u003eNULL\u003c/code\u003e. This function will need to be called again for each row you return.\u003c/p\u003e\n\u003cp\u003eOnce you have built a tuple to return from your function, it must be converted into a \u003ccode class=\"type\"\u003eDatum\u003c/code\u003e. Use:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003eHeapTupleGetDatum(HeapTuple tuple)\n\u003c/pre\u003e\n\u003cp\u003eto convert a \u003ccode class=\"structname\"\u003eHeapTuple\u003c/code\u003e into a valid Datum. This \u003ccode class=\"type\"\u003eDatum\u003c/code\u003e can be returned directly if you intend to return just a single row, or it can be used as the current return value in a set-returning function.\u003c/p\u003e\n\u003cp\u003eAn example appears in the next section.\u003c/p\u003e\n\u003c/div\u003e\n\u003cdiv class=\"sect2\" id=\"XFUNC-C-RETURN-SET\"\u003e\n\u003cdiv class=\"titlepage\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch3 class=\"title\"\u003e36.10.9. Returning Sets \u003c/h3\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003eC-language functions have two options for returning sets (multiple rows). In one method, called \u003cem class=\"firstterm\"\u003eValuePerCall\u003c/em\u003e mode, a set-returning function is called repeatedly (passing the same arguments each time) and it returns one new row on each call, until it has no more rows to return and signals that by returning NULL. The set-returning function (SRF) must therefore save enough state across calls to remember what it was doing and return the correct next item on each call. In the other method, called \u003cem class=\"firstterm\"\u003eMaterialize\u003c/em\u003e mode, an SRF fills and returns a tuplestore object containing its entire result; then only one call occurs for the whole result, and no inter-call state is needed.\u003c/p\u003e\n\u003cp\u003eWhen using ValuePerCall mode, it is important to remember that the query is not guaranteed to be run to completion; that is, due to options such as \u003ccode class=\"literal\"\u003eLIMIT\u003c/code\u003e, the executor might stop making calls to the set-returning function before all rows have been fetched. This means it is not safe to perform cleanup activities in the last call, because that might not ever happen. It's recommended to use Materialize mode for functions that need access to external resources, such as file descriptors.\u003c/p\u003e\n\u003cp\u003eThe remainder of this section documents a set of helper macros that are commonly used (though not required to be used) for SRFs using ValuePerCall mode. Additional details about Materialize mode can be found in \u003ccode class=\"filename\"\u003esrc/backend/utils/fmgr/README\u003c/code\u003e. Also, the \u003ccode class=\"filename\"\u003econtrib\u003c/code\u003e modules in the \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e source distribution contain many examples of SRFs using both ValuePerCall and Materialize mode.\u003c/p\u003e\n\u003cp\u003eTo use the ValuePerCall support macros described here, include \u003ccode class=\"filename\"\u003efuncapi.h\u003c/code\u003e. These macros work with a structure \u003ccode class=\"structname\"\u003eFuncCallContext\u003c/code\u003e that contains the state that needs to be saved across calls. Within the calling SRF, \u003ccode class=\"literal\"\u003efcinfo-\u0026gt;flinfo-\u0026gt;fn_extra\u003c/code\u003e is used to hold a pointer to \u003ccode class=\"structname\"\u003eFuncCallContext\u003c/code\u003e across calls. The macros automatically fill that field on first use, and expect to find the same pointer there on subsequent uses.\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003etypedef struct FuncCallContext\n{\n    /*\n     * Number of times we've been called before\n     *\n     * call_cntr is initialized to 0 for you by SRF_FIRSTCALL_INIT(), and\n     * incremented for you every time SRF_RETURN_NEXT() is called.\n     */\n    uint64 call_cntr;\n\n    /*\n     * OPTIONAL maximum number of calls\n     *\n     * max_calls is here for convenience only and setting it is optional.\n     * If not set, you must provide alternative means to know when the\n     * function is done.\n     */\n    uint64 max_calls;\n\n    /*\n     * OPTIONAL pointer to miscellaneous user-provided context information\n     *\n     * user_fctx is for use as a pointer to your own data to retain\n     * arbitrary context information between calls of your function.\n     */\n    void *user_fctx;\n\n    /*\n     * OPTIONAL pointer to struct containing attribute type input metadata\n     *\n     * attinmeta is for use when returning tuples (i.e., composite data types)\n     * and is not used when returning base data types. It is only needed\n     * if you intend to use BuildTupleFromCStrings() to create the return\n     * tuple.\n     */\n    AttInMetadata *attinmeta;\n\n    /*\n     * memory context used for structures that must live for multiple calls\n     *\n     * multi_call_memory_ctx is set by SRF_FIRSTCALL_INIT() for you, and used\n     * by SRF_RETURN_DONE() for cleanup. It is the most appropriate memory\n     * context for any memory that is to be reused across multiple calls\n     * of the SRF.\n     */\n    MemoryContext multi_call_memory_ctx;\n\n    /*\n     * OPTIONAL pointer to struct containing tuple description\n     *\n     * tuple_desc is for use when returning tuples (i.e., composite data types)\n     * and is only needed if you are going to build the tuples with\n     * heap_form_tuple() rather than with BuildTupleFromCStrings().  Note that\n     * the TupleDesc pointer stored here should usually have been run through\n     * BlessTupleDesc() first.\n     */\n    TupleDesc tuple_desc;\n\n} FuncCallContext;\n\u003c/pre\u003e\n\u003cp\u003eThe macros to be used by an SRF using this infrastructure are:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003eSRF_IS_FIRSTCALL()\n\u003c/pre\u003e\n\u003cp\u003eUse this to determine if your function is being called for the first or a subsequent time. On the first call (only), call:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003eSRF_FIRSTCALL_INIT()\n\u003c/pre\u003e\n\u003cp\u003eto initialize the \u003ccode class=\"structname\"\u003eFuncCallContext\u003c/code\u003e. On every function call, including the first, call:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003eSRF_PERCALL_SETUP()\n\u003c/pre\u003e\n\u003cp\u003eto set up for using the \u003ccode class=\"structname\"\u003eFuncCallContext\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003eIf your function has data to return in the current call, use:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003eSRF_RETURN_NEXT(funcctx, result)\n\u003c/pre\u003e\n\u003cp\u003eto return it to the caller. (\u003ccode class=\"literal\"\u003eresult\u003c/code\u003e must be of type \u003ccode class=\"type\"\u003eDatum\u003c/code\u003e, either a single value or a tuple prepared as described above.) Finally, when your function is finished returning data, use:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003eSRF_RETURN_DONE(funcctx)\n\u003c/pre\u003e\n\u003cp\u003eto clean up and end the SRF.\u003c/p\u003e\n\u003cp\u003eThe memory context that is current when the SRF is called is a transient context that will be cleared between calls. This means that you do not need to call \u003ccode class=\"function\"\u003epfree\u003c/code\u003e on everything you allocated using \u003ccode class=\"function\"\u003epalloc\u003c/code\u003e; it will go away anyway. However, if you want to allocate any data structures to live across calls, you need to put them somewhere else. The memory context referenced by \u003ccode class=\"structfield\"\u003emulti_call_memory_ctx\u003c/code\u003e is a suitable location for any data that needs to survive until the SRF is finished running. In most cases, this means that you should switch into \u003ccode class=\"structfield\"\u003emulti_call_memory_ctx\u003c/code\u003e while doing the first-call setup. Use \u003ccode class=\"literal\"\u003efuncctx-\u0026gt;user_fctx\u003c/code\u003e to hold a pointer to any such cross-call data structures. (Data you allocate in \u003ccode class=\"structfield\"\u003emulti_call_memory_ctx\u003c/code\u003e will go away automatically when the query ends, so it is not necessary to free that data manually, either.)\u003c/p\u003e\n\u003cdiv class=\"warning\"\u003e\n\u003ch3 class=\"title\"\u003eWarning\u003c/h3\u003e\n\u003cp\u003eWhile the actual arguments to the function remain unchanged between calls, if you detoast the argument values (which is normally done transparently by the \u003ccode class=\"function\"\u003ePG_GETARG_\u003cem class=\"replaceable\"\u003e\u003ccode\u003exxx\u003c/code\u003e\u003c/em\u003e\u003c/code\u003e macro) in the transient context then the detoasted copies will be freed on each cycle. Accordingly, if you keep references to such values in your \u003ccode class=\"structfield\"\u003euser_fctx\u003c/code\u003e, you must either copy them into the \u003ccode class=\"structfield\"\u003emulti_call_memory_ctx\u003c/code\u003e after detoasting, or ensure that you detoast the values only in that context.\u003c/p\u003e\n\u003c/div\u003e\n\u003cp\u003eA complete pseudo-code example looks like the following:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003eDatum\nmy_set_returning_function(PG_FUNCTION_ARGS)\n{\n    FuncCallContext  *funcctx;\n    Datum             result;\n    \u003cem class=\"replaceable\"\u003e\u003ccode\u003efurther declarations as needed\u003c/code\u003e\u003c/em\u003e\n\n    if (SRF_IS_FIRSTCALL())\n    {\n        MemoryContext oldcontext;\n\n        funcctx = SRF_FIRSTCALL_INIT();\n        oldcontext = MemoryContextSwitchTo(funcctx-\u0026gt;multi_call_memory_ctx);\n        /* One-time setup code appears here: */\n        \u003cem class=\"replaceable\"\u003e\u003ccode\u003euser code\u003c/code\u003e\u003c/em\u003e\n        \u003cem class=\"replaceable\"\u003e\u003ccode\u003eif returning composite\u003c/code\u003e\u003c/em\u003e\n            \u003cem class=\"replaceable\"\u003e\u003ccode\u003ebuild TupleDesc, and perhaps AttInMetadata\u003c/code\u003e\u003c/em\u003e\n        \u003cem class=\"replaceable\"\u003e\u003ccode\u003eendif returning composite\u003c/code\u003e\u003c/em\u003e\n        \u003cem class=\"replaceable\"\u003e\u003ccode\u003euser code\u003c/code\u003e\u003c/em\u003e\n        MemoryContextSwitchTo(oldcontext);\n    }\n\n    /* Each-time setup code appears here: */\n    \u003cem class=\"replaceable\"\u003e\u003ccode\u003euser code\u003c/code\u003e\u003c/em\u003e\n    funcctx = SRF_PERCALL_SETUP();\n    \u003cem class=\"replaceable\"\u003e\u003ccode\u003euser code\u003c/code\u003e\u003c/em\u003e\n\n    /* this is just one way we might test whether we are done: */\n    if (funcctx-\u0026gt;call_cntr \u0026lt; funcctx-\u0026gt;max_calls)\n    {\n        /* Here we want to return another item: */\n        \u003cem class=\"replaceable\"\u003e\u003ccode\u003euser code\u003c/code\u003e\u003c/em\u003e\n        \u003cem class=\"replaceable\"\u003e\u003ccode\u003eobtain result Datum\u003c/code\u003e\u003c/em\u003e\n        SRF_RETURN_NEXT(funcctx, result);\n    }\n    else\n    {\n        /* Here we are done returning items, so just report that fact. */\n        /* (Resist the temptation to put cleanup code here.) */\n        SRF_RETURN_DONE(funcctx);\n    }\n}\n\u003c/pre\u003e\n\u003cp\u003eA complete example of a simple SRF returning a composite type looks like:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003ePG_FUNCTION_INFO_V1(retcomposite);\n\nDatum\nretcomposite(PG_FUNCTION_ARGS)\n{\n    FuncCallContext     *funcctx;\n    int                  call_cntr;\n    int                  max_calls;\n    TupleDesc            tupdesc;\n    AttInMetadata       *attinmeta;\n\n    /* stuff done only on the first call of the function */\n    if (SRF_IS_FIRSTCALL())\n    {\n        MemoryContext   oldcontext;\n\n        /* create a function context for cross-call persistence */\n        funcctx = SRF_FIRSTCALL_INIT();\n\n        /* switch to memory context appropriate for multiple function calls */\n        oldcontext = MemoryContextSwitchTo(funcctx-\u0026gt;multi_call_memory_ctx);\n\n        /* total number of tuples to be returned */\n        funcctx-\u0026gt;max_calls = PG_GETARG_INT32(0);\n\n        /* Build a tuple descriptor for our result type */\n        if (get_call_result_type(fcinfo, NULL, \u0026amp;tupdesc) != TYPEFUNC_COMPOSITE)\n            ereport(ERROR,\n                    (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),\n                     errmsg(\"function returning record called in context \"\n                            \"that cannot accept type record\")));\n\n        /*\n         * generate attribute metadata needed later to produce tuples from raw\n         * C strings\n         */\n        attinmeta = TupleDescGetAttInMetadata(tupdesc);\n        funcctx-\u0026gt;attinmeta = attinmeta;\n\n        MemoryContextSwitchTo(oldcontext);\n    }\n\n    /* stuff done on every call of the function */\n    funcctx = SRF_PERCALL_SETUP();\n\n    call_cntr = funcctx-\u0026gt;call_cntr;\n    max_calls = funcctx-\u0026gt;max_calls;\n    attinmeta = funcctx-\u0026gt;attinmeta;\n\n    if (call_cntr \u0026lt; max_calls)    /* do when there is more left to send */\n    {\n        char       **values;\n        HeapTuple    tuple;\n        Datum        result;\n\n        /*\n         * Prepare a values array for building the returned tuple.\n         * This should be an array of C strings which will\n         * be processed later by the type input functions.\n         */\n        values = (char **) palloc(3 * sizeof(char *));\n        values[0] = (char *) palloc(16 * sizeof(char));\n        values[1] = (char *) palloc(16 * sizeof(char));\n        values[2] = (char *) palloc(16 * sizeof(char));\n\n        snprintf(values[0], 16, \"%d\", 1 * PG_GETARG_INT32(1));\n        snprintf(values[1], 16, \"%d\", 2 * PG_GETARG_INT32(1));\n        snprintf(values[2], 16, \"%d\", 3 * PG_GETARG_INT32(1));\n\n        /* build a tuple */\n        tuple = BuildTupleFromCStrings(attinmeta, values);\n\n        /* make the tuple into a datum */\n        result = HeapTupleGetDatum(tuple);\n\n        /* clean up (this is not really necessary) */\n        pfree(values[0]);\n        pfree(values[1]);\n        pfree(values[2]);\n        pfree(values);\n\n        SRF_RETURN_NEXT(funcctx, result);\n    }\n    else    /* do when there is no more left */\n    {\n        SRF_RETURN_DONE(funcctx);\n    }\n}\n\n\u003c/pre\u003e\n\u003cp\u003eOne way to declare this function in SQL is:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003eCREATE TYPE __retcomposite AS (f1 integer, f2 integer, f3 integer);\n\nCREATE OR REPLACE FUNCTION retcomposite(integer, integer)\n    RETURNS SETOF __retcomposite\n    AS '\u003cem class=\"replaceable\"\u003e\u003ccode\u003efilename\u003c/code\u003e\u003c/em\u003e', 'retcomposite'\n    LANGUAGE C IMMUTABLE STRICT;\n\u003c/pre\u003e\n\u003cp\u003eA different way is to use OUT parameters:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003eCREATE OR REPLACE FUNCTION retcomposite(IN integer, IN integer,\n    OUT f1 integer, OUT f2 integer, OUT f3 integer)\n    RETURNS SETOF record\n    AS '\u003cem class=\"replaceable\"\u003e\u003ccode\u003efilename\u003c/code\u003e\u003c/em\u003e', 'retcomposite'\n    LANGUAGE C IMMUTABLE STRICT;\n\u003c/pre\u003e\n\u003cp\u003eNotice that in this method the output type of the function is formally an anonymous \u003ccode class=\"structname\"\u003erecord\u003c/code\u003e type.\u003c/p\u003e\n\u003c/div\u003e\n\u003cdiv class=\"sect2\" id=\"XFUNC-C-POLYMORPHIC\"\u003e\n\u003cdiv class=\"titlepage\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch3 class=\"title\"\u003e36.10.10. Polymorphic Arguments and Return Types \u003c/h3\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003eC-language functions can be declared to accept and return the polymorphic types described in \u003ca class=\"xref\" href=\"/docs/18/extend-type-system.html#EXTEND-TYPES-POLYMORPHIC\" title=\"36.2.5. Polymorphic Types\"\u003eSection 36.2.5\u003c/a\u003e. When a function's arguments or return types are defined as polymorphic types, the function author cannot know in advance what data type it will be called with, or need to return. There are two routines provided in \u003ccode class=\"filename\"\u003efmgr.h\u003c/code\u003e to allow a version-1 C function to discover the actual data types of its arguments and the type it is expected to return. The routines are called \u003ccode class=\"literal\"\u003eget_fn_expr_rettype(FmgrInfo *flinfo)\u003c/code\u003e and \u003ccode class=\"literal\"\u003eget_fn_expr_argtype(FmgrInfo *flinfo, int argnum)\u003c/code\u003e. They return the result or argument type OID, or \u003ccode class=\"symbol\"\u003eInvalidOid\u003c/code\u003e if the information is not available. The structure \u003ccode class=\"literal\"\u003eflinfo\u003c/code\u003e is normally accessed as \u003ccode class=\"literal\"\u003efcinfo-\u0026gt;flinfo\u003c/code\u003e. The parameter \u003ccode class=\"literal\"\u003eargnum\u003c/code\u003e is zero based. \u003ccode class=\"function\"\u003eget_call_result_type\u003c/code\u003e can also be used as an alternative to \u003ccode class=\"function\"\u003eget_fn_expr_rettype\u003c/code\u003e. There is also \u003ccode class=\"function\"\u003eget_fn_expr_variadic\u003c/code\u003e, which can be used to find out whether variadic arguments have been merged into an array. This is primarily useful for \u003ccode class=\"literal\"\u003eVARIADIC \"any\"\u003c/code\u003e functions, since such merging will always have occurred for variadic functions taking ordinary array types.\u003c/p\u003e\n\u003cp\u003eFor example, suppose we want to write a function to accept a single element of any type, and return a one-dimensional array of that type:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003ePG_FUNCTION_INFO_V1(make_array);\nDatum\nmake_array(PG_FUNCTION_ARGS)\n{\n    ArrayType  *result;\n    Oid         element_type = get_fn_expr_argtype(fcinfo-\u0026gt;flinfo, 0);\n    Datum       element;\n    bool        isnull;\n    int16       typlen;\n    bool        typbyval;\n    char        typalign;\n    int         ndims;\n    int         dims[MAXDIM];\n    int         lbs[MAXDIM];\n\n    if (!OidIsValid(element_type))\n        elog(ERROR, \"could not determine data type of input\");\n\n    /* get the provided element, being careful in case it's NULL */\n    isnull = PG_ARGISNULL(0);\n    if (isnull)\n        element = (Datum) 0;\n    else\n        element = PG_GETARG_DATUM(0);\n\n    /* we have one dimension */\n    ndims = 1;\n    /* and one element */\n    dims[0] = 1;\n    /* and lower bound is 1 */\n    lbs[0] = 1;\n\n    /* get required info about the element type */\n    get_typlenbyvalalign(element_type, \u0026amp;typlen, \u0026amp;typbyval, \u0026amp;typalign);\n\n    /* now build the array */\n    result = construct_md_array(\u0026amp;element, \u0026amp;isnull, ndims, dims, lbs,\n                                element_type, typlen, typbyval, typalign);\n\n    PG_RETURN_ARRAYTYPE_P(result);\n}\n\u003c/pre\u003e\n\u003cp\u003eThe following command declares the function \u003ccode class=\"function\"\u003emake_array\u003c/code\u003e in SQL:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003eCREATE FUNCTION make_array(anyelement) RETURNS anyarray\n    AS '\u003cem class=\"replaceable\"\u003e\u003ccode\u003eDIRECTORY\u003c/code\u003e\u003c/em\u003e/funcs', 'make_array'\n    LANGUAGE C IMMUTABLE;\n\u003c/pre\u003e\n\u003cp\u003eThere is a variant of polymorphism that is only available to C-language functions: they can be declared to take parameters of type \u003ccode class=\"literal\"\u003e\"any\"\u003c/code\u003e. (Note that this type name must be double-quoted, since it's also an SQL reserved word.) This works like \u003ccode class=\"type\"\u003eanyelement\u003c/code\u003e except that it does not constrain different \u003ccode class=\"literal\"\u003e\"any\"\u003c/code\u003e arguments to be the same type, nor do they help determine the function's result type. A C-language function can also declare its final parameter to be \u003ccode class=\"literal\"\u003eVARIADIC \"any\"\u003c/code\u003e. This will match one or more actual arguments of any type (not necessarily the same type). These arguments will \u003cspan class=\"emphasis\"\u003e\u003cem\u003enot\u003c/em\u003e\u003c/span\u003e be gathered into an array as happens with normal variadic functions; they will just be passed to the function separately. The \u003ccode class=\"function\"\u003ePG_NARGS()\u003c/code\u003e macro and the methods described above must be used to determine the number of actual arguments and their types when using this feature. Also, users of such a function might wish to use the \u003ccode class=\"literal\"\u003eVARIADIC\u003c/code\u003e keyword in their function call, with the expectation that the function would treat the array elements as separate arguments. The function itself must implement that behavior if wanted, after using \u003ccode class=\"function\"\u003eget_fn_expr_variadic\u003c/code\u003e to detect that the actual argument was marked with \u003ccode class=\"literal\"\u003eVARIADIC\u003c/code\u003e.\u003c/p\u003e\n\u003c/div\u003e\n\u003cdiv class=\"sect2\" id=\"XFUNC-SHARED-ADDIN\"\u003e\n\u003cdiv class=\"titlepage\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch3 class=\"title\"\u003e36.10.11. Shared Memory \u003c/h3\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cdiv class=\"sect3\" id=\"XFUNC-SHARED-ADDIN-AT-STARTUP\"\u003e\n\u003cdiv class=\"titlepage\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch4 class=\"title\"\u003e36.10.11.1. Requesting Shared Memory at Startup \u003c/h4\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003eAdd-ins can reserve shared memory on server startup. To do so, the add-in's shared library must be preloaded by specifying it in \u003ca class=\"xref\" href=\"/docs/18/runtime-config-client.html#GUC-SHARED-PRELOAD-LIBRARIES\"\u003eshared_preload_libraries\u003c/a\u003e. The shared library should also register a \u003ccode class=\"literal\"\u003eshmem_request_hook\u003c/code\u003e in its \u003ccode class=\"function\"\u003e_PG_init\u003c/code\u003e function. This \u003ccode class=\"literal\"\u003eshmem_request_hook\u003c/code\u003e can reserve shared memory by calling:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003evoid RequestAddinShmemSpace(Size size)\n\u003c/pre\u003e\n\u003cp\u003eEach backend should obtain a pointer to the reserved shared memory by calling:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003evoid *ShmemInitStruct(const char *name, Size size, bool *foundPtr)\n\u003c/pre\u003e\n\u003cp\u003eIf this function sets \u003ccode class=\"literal\"\u003efoundPtr\u003c/code\u003e to \u003ccode class=\"literal\"\u003efalse\u003c/code\u003e, the caller should proceed to initialize the contents of the reserved shared memory. If \u003ccode class=\"literal\"\u003efoundPtr\u003c/code\u003e is set to \u003ccode class=\"literal\"\u003etrue\u003c/code\u003e, the shared memory was already initialized by another backend, and the caller need not initialize further.\u003c/p\u003e\n\u003cp\u003eTo avoid race conditions, each backend should use the LWLock \u003ccode class=\"function\"\u003eAddinShmemInitLock\u003c/code\u003e when initializing its allocation of shared memory, as shown here:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003estatic mystruct *ptr = NULL;\nbool        found;\n\nLWLockAcquire(AddinShmemInitLock, LW_EXCLUSIVE);\nptr = ShmemInitStruct(\"my struct name\", size, \u0026amp;found);\nif (!found)\n{\n    ... initialize contents of shared memory ...\n    ptr-\u0026gt;locks = GetNamedLWLockTranche(\"my tranche name\");\n}\nLWLockRelease(AddinShmemInitLock);\n\u003c/pre\u003e\n\u003cp\u003e\u003ccode class=\"literal\"\u003eshmem_startup_hook\u003c/code\u003e provides a convenient place for the initialization code, but it is not strictly required that all such code be placed in this hook. On Windows (and anywhere else where \u003ccode class=\"literal\"\u003eEXEC_BACKEND\u003c/code\u003e is defined), each backend executes the registered \u003ccode class=\"literal\"\u003eshmem_startup_hook\u003c/code\u003e shortly after it attaches to shared memory, so add-ins should still acquire \u003ccode class=\"function\"\u003eAddinShmemInitLock\u003c/code\u003e within this hook, as shown in the example above. On other platforms, only the postmaster process executes the \u003ccode class=\"literal\"\u003eshmem_startup_hook\u003c/code\u003e, and each backend automatically inherits the pointers to shared memory.\u003c/p\u003e\n\u003cp\u003eAn example of a \u003ccode class=\"literal\"\u003eshmem_request_hook\u003c/code\u003e and \u003ccode class=\"literal\"\u003eshmem_startup_hook\u003c/code\u003e can be found in \u003ccode class=\"filename\"\u003econtrib/pg_stat_statements/pg_stat_statements.c\u003c/code\u003e in the \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e source tree.\u003c/p\u003e\n\u003c/div\u003e\n\u003cdiv class=\"sect3\" id=\"XFUNC-SHARED-ADDIN-AFTER-STARTUP\"\u003e\n\u003cdiv class=\"titlepage\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch4 class=\"title\"\u003e36.10.11.2. Requesting Shared Memory After Startup \u003c/h4\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003eThere is another, more flexible method of reserving shared memory that can be done after server startup and outside a \u003ccode class=\"literal\"\u003eshmem_request_hook\u003c/code\u003e. To do so, each backend that will use the shared memory should obtain a pointer to it by calling:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003evoid *GetNamedDSMSegment(const char *name, size_t size,\n                         void (*init_callback) (void *ptr),\n                         bool *found)\n\u003c/pre\u003e\n\u003cp\u003eIf a dynamic shared memory segment with the given name does not yet exist, this function will allocate it and initialize it with the provided \u003ccode class=\"function\"\u003einit_callback\u003c/code\u003e callback function. If the segment has already been allocated and initialized by another backend, this function simply attaches the existing dynamic shared memory segment to the current backend.\u003c/p\u003e\n\u003cp\u003eUnlike shared memory reserved at server startup, there is no need to acquire \u003ccode class=\"function\"\u003eAddinShmemInitLock\u003c/code\u003e or otherwise take action to avoid race conditions when reserving shared memory with \u003ccode class=\"function\"\u003eGetNamedDSMSegment\u003c/code\u003e. This function ensures that only one backend allocates and initializes the segment and that all other backends receive a pointer to the fully allocated and initialized segment.\u003c/p\u003e\n\u003cp\u003eA complete usage example of \u003ccode class=\"function\"\u003eGetNamedDSMSegment\u003c/code\u003e can be found in \u003ccode class=\"filename\"\u003esrc/test/modules/test_dsm_registry/test_dsm_registry.c\u003c/code\u003e in the \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e source tree.\u003c/p\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cdiv class=\"sect2\" id=\"XFUNC-ADDIN-LWLOCKS\"\u003e\n\u003cdiv class=\"titlepage\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch3 class=\"title\"\u003e36.10.12. LWLocks \u003c/h3\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cdiv class=\"sect3\" id=\"XFUNC-ADDIN-LWLOCKS-AT-STARTUP\"\u003e\n\u003cdiv class=\"titlepage\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch4 class=\"title\"\u003e36.10.12.1. Requesting LWLocks at Startup \u003c/h4\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003eAdd-ins can reserve LWLocks on server startup. As with shared memory reserved at server startup, the add-in's shared library must be preloaded by specifying it in \u003ca class=\"xref\" href=\"/docs/18/runtime-config-client.html#GUC-SHARED-PRELOAD-LIBRARIES\"\u003eshared_preload_libraries\u003c/a\u003e, and the shared library should register a \u003ccode class=\"literal\"\u003eshmem_request_hook\u003c/code\u003e in its \u003ccode class=\"function\"\u003e_PG_init\u003c/code\u003e function. This \u003ccode class=\"literal\"\u003eshmem_request_hook\u003c/code\u003e can reserve LWLocks by calling:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003evoid RequestNamedLWLockTranche(const char *tranche_name, int num_lwlocks)\n\u003c/pre\u003e\n\u003cp\u003eThis ensures that an array of \u003ccode class=\"literal\"\u003enum_lwlocks\u003c/code\u003e LWLocks is available under the name \u003ccode class=\"literal\"\u003etranche_name\u003c/code\u003e. A pointer to this array can be obtained by calling:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003eLWLockPadded *GetNamedLWLockTranche(const char *tranche_name)\n\u003c/pre\u003e\n\u003c/div\u003e\n\u003cdiv class=\"sect3\" id=\"XFUNC-ADDIN-LWLOCKS-AFTER-STARTUP\"\u003e\n\u003cdiv class=\"titlepage\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch4 class=\"title\"\u003e36.10.12.2. Requesting LWLocks After Startup \u003c/h4\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003eThere is another, more flexible method of obtaining LWLocks that can be done after server startup and outside a \u003ccode class=\"literal\"\u003eshmem_request_hook\u003c/code\u003e. To do so, first allocate a \u003ccode class=\"literal\"\u003etranche_id\u003c/code\u003e by calling:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003eint LWLockNewTrancheId(void)\n\u003c/pre\u003e\n\u003cp\u003eNext, initialize each LWLock, passing the new \u003ccode class=\"literal\"\u003etranche_id\u003c/code\u003e as an argument:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003evoid LWLockInitialize(LWLock *lock, int tranche_id)\n\u003c/pre\u003e\n\u003cp\u003eSimilar to shared memory, each backend should ensure that only one process allocates a new \u003ccode class=\"literal\"\u003etranche_id\u003c/code\u003e and initializes each new LWLock. One way to do this is to only call these functions in your shared memory initialization code with the \u003ccode class=\"function\"\u003eAddinShmemInitLock\u003c/code\u003e held exclusively. If using \u003ccode class=\"function\"\u003eGetNamedDSMSegment\u003c/code\u003e, calling these functions in the \u003ccode class=\"function\"\u003einit_callback\u003c/code\u003e callback function is sufficient to avoid race conditions.\u003c/p\u003e\n\u003cp\u003eFinally, each backend using the \u003ccode class=\"literal\"\u003etranche_id\u003c/code\u003e should associate it with a \u003ccode class=\"literal\"\u003etranche_name\u003c/code\u003e by calling:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003evoid LWLockRegisterTranche(int tranche_id, const char *tranche_name)\n\u003c/pre\u003e\n\u003cp\u003eA complete usage example of \u003ccode class=\"function\"\u003eLWLockNewTrancheId\u003c/code\u003e, \u003ccode class=\"function\"\u003eLWLockInitialize\u003c/code\u003e, and \u003ccode class=\"function\"\u003eLWLockRegisterTranche\u003c/code\u003e can be found in \u003ccode class=\"filename\"\u003econtrib/pg_prewarm/autoprewarm.c\u003c/code\u003e in the \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e source tree.\u003c/p\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cdiv class=\"sect2\" id=\"XFUNC-ADDIN-WAIT-EVENTS\"\u003e\n\u003cdiv class=\"titlepage\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch3 class=\"title\"\u003e36.10.13. Custom Wait Events \u003c/h3\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003eAdd-ins can define custom wait events under the wait event type \u003ccode class=\"literal\"\u003eExtension\u003c/code\u003e by calling:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003euint32 WaitEventExtensionNew(const char *wait_event_name)\n\u003c/pre\u003e\n\u003cp\u003eThe wait event is associated to a user-facing custom string. An example can be found in \u003ccode class=\"filename\"\u003esrc/test/modules/worker_spi\u003c/code\u003e in the PostgreSQL source tree.\u003c/p\u003e\n\u003cp\u003eCustom wait events can be viewed in \u003ca class=\"link\" href=\"/docs/18/monitoring-stats.html#MONITORING-PG-STAT-ACTIVITY-VIEW\" title=\"27.2.3. pg_stat_activity\"\u003e\u003ccode class=\"structname\"\u003epg_stat_activity\u003c/code\u003e\u003c/a\u003e:\u003c/p\u003e\n\u003cpre class=\"screen\"\u003e=# SELECT wait_event_type, wait_event FROM pg_stat_activity\n     WHERE backend_type ~ 'worker_spi';\n wait_event_type |  wait_event\n-----------------+---------------\n Extension       | WorkerSpiMain\n(1 row)\n\u003c/pre\u003e\n\u003c/div\u003e\n\u003cdiv class=\"sect2\" id=\"XFUNC-ADDIN-INJECTION-POINTS\"\u003e\n\u003cdiv class=\"titlepage\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch3 class=\"title\"\u003e36.10.14. Injection Points \u003c/h3\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003eAn injection point with a given \u003ccode class=\"literal\"\u003ename\u003c/code\u003e is declared using macro:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003eINJECTION_POINT(name, arg);\n\u003c/pre\u003e\n\u003cp\u003eThere are a few injection points already declared at strategic points within the server code. After adding a new injection point the code needs to be compiled in order for that injection point to be available in the binary. Add-ins written in C-language can declare injection points in their own code using the same macro. The injection point names should use lower-case characters, with terms separated by dashes. \u003ccode class=\"literal\"\u003earg\u003c/code\u003e is an optional argument value given to the callback at run-time.\u003c/p\u003e\n\u003cp\u003eExecuting an injection point can require allocating a small amount of memory, which can fail. If you need to have an injection point in a critical section where dynamic allocations are not allowed, you can use a two-step approach with the following macros:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003eINJECTION_POINT_LOAD(name);\nINJECTION_POINT_CACHED(name, arg);\n\u003c/pre\u003e\n\u003cp\u003eBefore entering the critical section, call \u003ccode class=\"function\"\u003eINJECTION_POINT_LOAD\u003c/code\u003e. It checks the shared memory state, and loads the callback into backend-private memory if it is active. Inside the critical section, use \u003ccode class=\"function\"\u003eINJECTION_POINT_CACHED\u003c/code\u003e to execute the callback.\u003c/p\u003e\n\u003cp\u003eAdd-ins can attach callbacks to an already-declared injection point by calling:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003eextern void InjectionPointAttach(const char *name,\n                                 const char *library,\n                                 const char *function,\n                                 const void *private_data,\n                                 int private_data_size);\n\u003c/pre\u003e\n\u003cp\u003e\u003ccode class=\"literal\"\u003ename\u003c/code\u003e is the name of the injection point, which when reached during execution will execute the \u003ccode class=\"literal\"\u003efunction\u003c/code\u003e loaded from \u003ccode class=\"literal\"\u003elibrary\u003c/code\u003e. \u003ccode class=\"literal\"\u003eprivate_data\u003c/code\u003e is a private area of data of size \u003ccode class=\"literal\"\u003eprivate_data_size\u003c/code\u003e given as argument to the callback when executed.\u003c/p\u003e\n\u003cp\u003eHere is an example of callback for \u003ccode class=\"literal\"\u003eInjectionPointCallback\u003c/code\u003e:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003estatic void\ncustom_injection_callback(const char *name,\n                          const void *private_data,\n                          void *arg)\n{\n    uint32 wait_event_info = WaitEventInjectionPointNew(name);\n\n    pgstat_report_wait_start(wait_event_info);\n    elog(NOTICE, \"%s: executed custom callback\", name);\n    pgstat_report_wait_end();\n}\n\u003c/pre\u003e\n\u003cp\u003eThis callback prints a message to server error log with severity \u003ccode class=\"literal\"\u003eNOTICE\u003c/code\u003e, but callbacks may implement more complex logic.\u003c/p\u003e\n\u003cp\u003eAn alternative way to define the action to take when an injection point is reached is to add the testing code alongside the normal source code. This can be useful if the action e.g. depends on local variables that are not accessible to loaded modules. The \u003ccode class=\"function\"\u003eIS_INJECTION_POINT_ATTACHED\u003c/code\u003e macro can then be used to check if an injection point is attached, for example:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003e#ifdef USE_INJECTION_POINTS\nif (IS_INJECTION_POINT_ATTACHED(\"before-foobar\"))\n{\n    /* change a local variable if injection point is attached */\n    local_var = 123;\n\n    /* also execute the callback */\n    INJECTION_POINT_CACHED(\"before-foobar\", NULL);\n}\n#endif\n\u003c/pre\u003e\n\u003cp\u003eNote that the callback attached to the injection point will not be executed by the \u003ccode class=\"function\"\u003eIS_INJECTION_POINT_ATTACHED\u003c/code\u003e macro. If you want to execute the callback, you must also call \u003ccode class=\"function\"\u003eINJECTION_POINT_CACHED\u003c/code\u003e like in the above example.\u003c/p\u003e\n\u003cp\u003eOptionally, it is possible to detach an injection point by calling:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003eextern bool InjectionPointDetach(const char *name);\n\u003c/pre\u003e\n\u003cp\u003eOn success, \u003ccode class=\"literal\"\u003etrue\u003c/code\u003e is returned, \u003ccode class=\"literal\"\u003efalse\u003c/code\u003e otherwise.\u003c/p\u003e\n\u003cp\u003eA callback attached to an injection point is available across all the backends including the backends started after \u003ccode class=\"literal\"\u003eInjectionPointAttach\u003c/code\u003e is called. It remains attached while the server is running or until the injection point is detached using \u003ccode class=\"literal\"\u003eInjectionPointDetach\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003eAn example can be found in \u003ccode class=\"filename\"\u003esrc/test/modules/injection_points\u003c/code\u003e in the PostgreSQL source tree.\u003c/p\u003e\n\u003cp\u003eEnabling injections points requires \u003ccode class=\"option\"\u003e--enable-injection-points\u003c/code\u003e with \u003ccode class=\"command\"\u003econfigure\u003c/code\u003e or \u003ccode class=\"option\"\u003e-Dinjection_points=true\u003c/code\u003e with \u003cspan class=\"application\"\u003eMeson\u003c/span\u003e.\u003c/p\u003e\n\u003c/div\u003e\n\u003cdiv class=\"sect2\" id=\"XFUNC-ADDIN-CUSTOM-CUMULATIVE-STATISTICS\"\u003e\n\u003cdiv class=\"titlepage\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch3 class=\"title\"\u003e36.10.15. Custom Cumulative Statistics \u003c/h3\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003eIt is possible for add-ins written in C-language to use custom types of cumulative statistics registered in the \u003ca class=\"link\" href=\"/docs/18/monitoring-stats.html#MONITORING-STATS-SETUP\" title=\"27.2.1. Statistics Collection Configuration\"\u003eCumulative Statistics System\u003c/a\u003e.\u003c/p\u003e\n\u003cp\u003eFirst, define a \u003ccode class=\"literal\"\u003ePgStat_KindInfo\u003c/code\u003e that includes all the information related to the custom type registered. For example:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003estatic const PgStat_KindInfo custom_stats = {\n    .name = \"custom_stats\",\n    .fixed_amount = false,\n    .shared_size = sizeof(PgStatShared_Custom),\n    .shared_data_off = offsetof(PgStatShared_Custom, stats),\n    .shared_data_len = sizeof(((PgStatShared_Custom *) 0)-\u0026gt;stats),\n    .pending_size = sizeof(PgStat_StatCustomEntry),\n}\n\u003c/pre\u003e\n\u003cp\u003eThen, each backend that needs to use this custom type needs to register it with \u003ccode class=\"literal\"\u003epgstat_register_kind\u003c/code\u003e and a unique ID used to store the entries related to this type of statistics:\u003c/p\u003e\n\u003cpre class=\"programlisting\"\u003eextern PgStat_Kind pgstat_register_kind(PgStat_Kind kind,\n                                        const PgStat_KindInfo *kind_info);\n\u003c/pre\u003e\n\u003cp\u003eWhile developing a new extension, use \u003ccode class=\"literal\"\u003ePGSTAT_KIND_EXPERIMENTAL\u003c/code\u003e for \u003cem class=\"parameter\"\u003e\u003ccode\u003ekind\u003c/code\u003e\u003c/em\u003e. When you are ready to release the extension to users, reserve a kind ID at the \u003ca class=\"ulink\" href=\"https://wiki.postgresql.org/wiki/CustomCumulativeStats\"\u003eCustom Cumulative Statistics\u003c/a\u003e page.\u003c/p\u003e\n\u003cp\u003eThe details of the API for \u003ccode class=\"literal\"\u003ePgStat_KindInfo\u003c/code\u003e can be found in \u003ccode class=\"filename\"\u003esrc/include/utils/pgstat_internal.h\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003eThe type of statistics registered is associated with a name and a unique ID shared across the server in shared memory. Each backend using a custom type of statistics maintains a local cache storing the information of each custom \u003ccode class=\"literal\"\u003ePgStat_KindInfo\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003ePlace the extension module implementing the custom cumulative statistics type in \u003ca class=\"xref\" href=\"/docs/18/runtime-config-client.html#GUC-SHARED-PRELOAD-LIBRARIES\"\u003eshared_preload_libraries\u003c/a\u003e so that it will be loaded early during \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e startup.\u003c/p\u003e\n\u003cp\u003eAn example describing how to register and use custom statistics can be found in \u003ccode class=\"filename\"\u003esrc/test/modules/injection_points\u003c/code\u003e.\u003c/p\u003e\n\u003c/div\u003e\n\u003cdiv class=\"sect2\" id=\"EXTEND-CPP\"\u003e\n\u003cdiv class=\"titlepage\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch3 class=\"title\"\u003e36.10.16. Using C++ for Extensibility \u003c/h3\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003eAlthough the \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e backend is written in C, it is possible to write extensions in C++ if these guidelines are followed:\u003c/p\u003e\n\u003cdiv class=\"itemizedlist\"\u003e\n\u003cul class=\"itemizedlist\"\u003e\n\u003cli class=\"listitem\"\u003e\n\u003cp\u003eAll functions accessed by the backend must present a C interface to the backend; these C functions can then call C++ functions. For example, \u003ccode class=\"literal\"\u003eextern C\u003c/code\u003e linkage is required for backend-accessed functions. This is also necessary for any functions that are passed as pointers between the backend and C++ code.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli class=\"listitem\"\u003e\n\u003cp\u003eFree memory using the appropriate deallocation method. For example, most backend memory is allocated using \u003ccode class=\"function\"\u003epalloc()\u003c/code\u003e, so use \u003ccode class=\"function\"\u003epfree()\u003c/code\u003e to free it. Using C++ \u003ccode class=\"function\"\u003edelete\u003c/code\u003e in such cases will fail.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli class=\"listitem\"\u003e\n\u003cp\u003ePrevent exceptions from propagating into the C code (use a catch-all block at the top level of all \u003ccode class=\"literal\"\u003eextern C\u003c/code\u003e functions). This is necessary even if the C++ code does not explicitly throw any exceptions, because events like out-of-memory can still throw exceptions. Any exceptions must be caught and appropriate errors passed back to the C interface. If possible, compile C++ with \u003ccode class=\"option\"\u003e-fno-exceptions\u003c/code\u003e to eliminate exceptions entirely; in such cases, you must check for failures in your C++ code, e.g., check for NULL returned by \u003ccode class=\"function\"\u003enew()\u003c/code\u003e.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli class=\"listitem\"\u003e\n\u003cp\u003eIf calling backend functions from C++ code, be sure that the C++ call stack contains only plain old data structures (POD). This is necessary because backend errors generate a distant \u003ccode class=\"function\"\u003elongjmp()\u003c/code\u003e that does not properly unroll a C++ call stack with non-POD objects.\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/div\u003e\n\u003cp\u003eIn summary, it is best to place C++ code behind a wall of \u003ccode class=\"literal\"\u003eextern C\u003c/code\u003e functions that interface to the backend, and avoid exception, memory, and call stack leakage.\u003c/p\u003e\n\u003c/div\u003e\n\u003c/div\u003e","related":[],"sections":[],"tables":[]}},"RequestedLocale":"zh-Hans","Fallback":true,"Versions":["10","11","12","13","14","15","16","17","18","19","20"],"Locales":["en"],"Signatures":null,"Spellings":null,"SQLState":null,"Evidence":null}
