.\" /usr/local/devel/postgres-v4r2/src/doc/implementation/RCS/fmgr.me,v 1.3 1993/07/30 23:51:09 sunita Exp .ps 12 .\" The following macros are copied from mao's am.me: .\" BEGIN MACRO DEFS .fo ''%'' .ds PG "\\s-2POSTGRES\\s0 .ds PQ "\\s-2POSTQUEL\\s0 .de RN \\fC\\$1\\fP\\$2 .. .de (E .in +0.5i .sp .nf .na .ft C .ta 0.5i 1i 1.5i 2i 2.5i 3i 3.5i 4i 4.5i 5i 5.5i .. .de )E .in .sp .fi .ad .ft R .. .\" END MACRO DEFS .\" .uh "The Function Manager" .sh 1 General .pp The abstraction of functions is provided by the Function Manager layer. A function in \*(PG falls into one of the following categories: built-in functions, C functions or \*(PQ functions. Each function is represented by its unique Object ID (also known as a Procedure ID). .pp The built-in functions are a set of selected C procedures compiled into the backend. They are used by built-in operators, access methods, etc. User-defined functions yield either C functions (when declared with .RN language="C" ) or \*(PQ functions (when declared with .RN language="postquel" ). .pp This layer is intended to provide uniform access to a function regardless of its type and bindings (ie. static or dynamic). Unfortunately, invoking \*(PQ functions requires more sophistication. (Note that function and procedure is used interchangeably to mean the same thing in this document.) .sh 1 "The Internals" .sh 2 "The System Catalog pg_proc" .pp Each function has an entry in the system catalog, .RN pg_proc . The structure and declaration of an entry is as follows: .(b .ft C CATALOG(pg_proc) BOOTSTRAP { char16 proname; /* procedure name */ oid proowner; /* procedure owner */ oid prolang; /* procedure language */ bool proisinh; /* is procedure inheritable? */ bool proistrusted; /* is procedure spawned or called? */ bool proiscachable;/* is value precomputable? */ int2 pronargs; /* number of arguments */ bool proretset; /* does procedure return set of tuples */ oid prorettype; /* procedure return type */ oid8 proargtypes; /* argument types */ int4 probyte_pct; /* percentage of size of input */ int4 properbyte_cpu; /* cost per byte of operand */ int4 propercall_cpu; /* CPU time per call */ int4 prooutin_ratio; /* ratio of output to input sizes */ text prosrc; /* query string for postquel functions */ bytea probin; /* object file name for C procedures */ } FormData_pg_proc; typedef FormData_pg_proc *Form_pg_proc; .ft .)b .pp The .RN prolang field specifies the category of the function. It contains the Object ID of the ``language'' the function is written in. Valid values are listed in the table below. .TS center allbox; cfI cfI lfC l. Language description INTERNALlanguageId a built-in function ClanguageId a C function POSTQUELlanguageId a \*(PQ function .TE The fields .RN probyte_pct, .RN properbyte_cpu, .RN propercall_cpu, and .RN prooutin_ratio are used by the optimizer for estimating the cost of a procedure invocation. They are described in greater detail in the \*(PG reference manual. The field .RN proistrusted indicates if the procedure is trusted or not. If the procedure is trusted it is invoked in the same address space as the \*(PG backend, otherwise, it is run as a seperate process. .sh 2 "The Function Cache" .pp For faster access, information about the functions is cached in a function cache. .RN lib/fcache.c contains code which handles the function cache. .sh 2 "Built-in Functions" .pp Built-in functions are collected at compile time from the source code to produce a table of entry points. The table is generated by the shell script .RN utils/Gen_fmgrtab.sh . It generates .RN fmgrtab.c and .RN fmgr.h from .RN catalog/pg_proc.h . .pp Each entry in the table contains the following structure (defined in .RN utils/fmgrtab.h ). .(E typedef struct { ObjectId proid; /* procedure Id */ uint16 nargs; /* number of arguments */ func_ptr func; /* entry point */ } FmgrCall; .)E The table is sorted by proid. The following is an excerpt of the table. For instance, the two entries specify the Procedure Id's and number of arguments for the .RN textin and .RN textout procedures. .(E static FmgrCall fmgr_builtins[] = { ... { 46, 1, textin }, { 47, 1, textout }, ... } .)E The directory .RN utils/adt contains the source code for all built-in functions. .sh 2 "Functions with Dynamic Bindings" .pp User-defined functions are dynamically loaded into the backend on demand. The \*(PQ .RN "define function" command registers the procedure in the system catalog, .RN pg_proc . The function is loaded into the running backend when either the \*(PQ .RN load command is encountered or the first time the function is invoked. .pp The code which handles dynamic loading is in .RN util/fmgr/dfmgr.c . Details of dynamic loading is beyond the scope of this section. .sh 1 "Interface Routines" .pp Routines for invoking C functions are defined in .RN utils/fmgr/fmgr.c. The following interface routines can be used: .pp .(E char * fmgr(procedureId [, ... ] ) ObjectId procedureId; .)E .pp .RN fmgr() takes the object ID of a procedure and its arguments. Note that you can only have eight arguments for user-defined C functions while at most nine for internal functions. .RN fmgr() invokes the function and returns the result if successful and 0 if unsuccessful. For example, the following code segment taken from .RN catalog/index.c illustrates how the text-in procedure, .RN textin() , is invoked through .RN fmgr() . .(E if (predicate != LispNil) { predString = lispOut(predicate); predText = (text *)fmgr(F_TEXTIN, predString); pfree(predString); } else { predText = (text *)fmgr(F_TEXTIN, ""); } .)E .(E char * fmgr_c(user_fn, func_id, n_arguments, values, isNull) func_ptr user_fn; /* function entry point */ ObjectId func_id; /* OID of function */ int n_arguments; /* number of arguments to the function */ FmgrValues *values; /* array of function arguments */ Boolean *isNull; .)E This routine is called by .RN fmgr() for invoking a C function. It is also called directly by the executor for invoking C functions. For untrusted C functions the function pointer .RN user_fn is set to null. Functions defined in the same address space (builtin functions and trusted user-defined functions) are called directly from this routine whereas functions in a different address space (untrusted functions) are handled by the routine .RN fmgr_ufp() defined in .RN utils/fmgr/ufp.c. If the function needs to be dynamically loaded into the backend, it will be done automatically. .pp \*(PQ functions are invoked with .RN postquel_function (defined in .RN executor/functions.c ). Its declaration is as follows. .(E Datum postquel_function(funcNode, args, isNull, isDone) Func funcNode; char *args[]; bool *isNull; bool *isDone; .)E This routine is used only by the executor. .pp To appreciate how the function manager works, one might look at the executor. In the executor .RN (executor/ex_qual.c), .RN ExecEvalExpr evaluates operators and function clauses with .RN ExecEvalOper and .RN ExecEvalFunction. Both of them invokes .RN ExecMakeFunctionResult which in turn invokes .RN fmgr_c() and .RN postquel_function() accordingly to evaluate the results. .pp Another useful interface routine is .RN fmgr_info() (defined in .RN fmgr/fmgr.c). It can be used to obtain information about any built-in or user-defined function and is declared as follows: .(E void fmgr_info(procedureId, function, nargs) ObjectId procedureId; func_ptr *function; int *nargs; .)E It takes the procedure ID of a function and returns its entry point in .RN function and the number of arguments it takes in .RN nargs. .pp For example, the following code segment also taken from .RN catalog/index.c illustrates how to obtain the entry point (ie. the function pointer) of the procedure testing equality of ObjectId's, .RN oideq(), through .RN fmgr_info() . It stores the entry point in the index key for later use. .(E fmgr_info(ObjectIdEqualRegProcedure, &indexKey[0].func, &indexKey[0].nargs); .)E To use the above interfaces, you may need the following include file: .(E .ft C #include "fmgr.h" .ft .)E