From 3f8d7bdb785c0a124b11f3131d9c5323717e0b83 Mon Sep 17 00:00:00 2001 From: Chapman Flack Date: Mon, 21 Feb 2022 21:21:51 -0500 Subject: [PATCH v2 3/4] Reindent and wrap between added sect1 tags A whitespace-only commit. --- doc/src/sgml/plhandler.sgml | 638 ++++++++++++++++++++++---------------------- 1 file changed, 321 insertions(+), 317 deletions(-) diff --git a/doc/src/sgml/plhandler.sgml b/doc/src/sgml/plhandler.sgml index 95e8515..003a6c9 100644 --- a/doc/src/sgml/plhandler.sgml +++ b/doc/src/sgml/plhandler.sgml @@ -57,385 +57,389 @@ Call handler function - - Every routine defined with a language name other than - internal (as defined in ) - or c () will be called by - invoking the procedural language's call handler. - - - This is true even of routines with language name sql, - though, as a special case, that call handler has no entry in the system - catalogs. - - - It is the responsibility of - the call handler to execute the routine in a meaningful way, such - as by interpreting the supplied source text. - - - - The call handler is a normal user-defined function that must - be declared to PostgreSQL as taking no arguments - and returning the type language_handler. This - special pseudo-type identifies the function as a call handler and - prevents it from being called directly in SQL commands. - This handler must not require a call handler of its own, which makes - the predefined languages internal or c - the only choices for the handler's own declaration. - Typically, it will be a loadable function in language - c, as described in . - - - It may be implemented in a language other than C, as long as it can be - built into a loadable object with compatible calling conventions. - - - - - - The call handler is called in the same way as any other function: - It receives a pointer to a - FunctionCallInfoBaseData struct containing - argument values and information about the called routine, and it - is expected to return a Datum result (and possibly - set the isnull field of the - FunctionCallInfoBaseData structure, if it wishes - to return an SQL null result). The difference between a call - handler and an ordinary callee is that the - flinfo->fn_oid field of the - FunctionCallInfoBaseData structure will contain - the OID of the actual routine to be called, not of the call - handler itself. The call handler must use this field to determine - which routine to execute. Also, the passed argument list has - been set up according to the declaration of the target routine, - not of the call handler. - - - - It's up to the call handler to fetch the routine's defining - pg_proc row from the system catalog cache - to determine what to execute, what parameter and return types are expected, - and so on. - The AS clause from the - CREATE FUNCTION or CREATE PROCEDURE - command for the routine will be found - in the prosrc column of the - pg_proc row. This is commonly source - text in the procedural language, but in theory it could be something else, - such as a path name to a file, or anything else that tells the call handler - what to do in detail. - - - - The handler may also examine the passed - FunctionCallInfoBaseData structure for information - on the context of the call. If the procedural language will support - returning sets, the structure may contain a pointer to a - ReturnSetInfo structure for use as described in - . If the language will support triggers - or event triggers, the structure may hold a pointer to one of the structures - described in or - , and the procedural language - should provide some way for the called function to use the information - they carry. - - - - Parameter and return type resolution - - A routine's statically-declared parameter types (and, for a function, - return type) are found in the proargtypes and - prorettype columns of the pg_proc - row. - If a routine has OUT parameters, those types are - included in the proallargtypes column, and their names - in proargnames. - Convenience functions declared in funcapi.h are - available for extracting that information. + Every routine defined with a language name other than + internal (as defined in + ) + or c () will be called by + invoking the procedural language's call handler. + + + This is true even of routines with language name sql, + though, as a special case, that call handler has no entry in the system + catalogs. + + + It is the responsibility of + the call handler to execute the routine in a meaningful way, such + as by interpreting the supplied source text. - The statically-declared types may include polymorphic types that need - to be resolved according to the actual types present at the call site, - as described in . + The call handler is a normal user-defined function that must + be declared to PostgreSQL as taking no arguments + and returning the type language_handler. This + special pseudo-type identifies the function as a call handler and + prevents it from being called directly in SQL commands. + This handler must not require a call handler of its own, which makes + the predefined languages internal or + c the only choices for the handler's own declaration. + Typically, it will be a loadable function in language + c, as described in . + + + It may be implemented in a language other than C, as long as it can be + built into a loadable object with compatible calling conventions. + + - - - - Mapping to procedural language types + + The call handler is called in the same way as any other function: + It receives a pointer to a + FunctionCallInfoBaseData struct + containing argument values and information about the called routine, and it + is expected to return a Datum result (and possibly + set the isnull field of the + FunctionCallInfoBaseData structure, if it wishes + to return an SQL null result). The difference between a call + handler and an ordinary callee is that the + flinfo->fn_oid field of the + FunctionCallInfoBaseData structure will contain + the OID of the actual routine to be called, not of the call + handler itself. The call handler must use this field to determine + which routine to execute. Also, the passed argument list has + been set up according to the declaration of the target routine, + not of the call handler. + - Once the PostgreSQL types of any parameters - and results have been resolved, the handler must determine how it will - map their values to and from suitable types that exist in the procedural - language. + It's up to the call handler to fetch the routine's defining + pg_proc row from the system catalog cache + to determine what to execute, what parameter and return types are expected, + and so on. + The AS clause from the + CREATE FUNCTION or CREATE PROCEDURE + command for the routine will be found + in the prosrc column of the + pg_proc row. This is commonly source + text in the procedural language, but in theory it could be something else, + such as a path name to a file, or anything else that tells the call handler + what to do in detail. - The designer of a procedural language will typically document what types - will be supported and how they will be mapped, which could be as simple - as using every type's text input/output format to map it to the target - language's string type, or could directly map many types to corresponding - ones the target language provides. The handler function will implement - those rules. + The handler may also examine the passed + FunctionCallInfoBaseData structure for information + on the context of the call. If the procedural language will support + returning sets, the structure may contain a pointer to a + ReturnSetInfo structure for use as described in + . If the language will support triggers + or event triggers, the structure may hold a pointer to one of + the structures described in or + , and the procedural language + should provide some way for the called function to use the information + they carry. - - Type transforms + + Parameter and return type resolution - Because PostgreSQL is extensible, and - an extension can easily supply new types, a procedural language handler - may encounter types it has no predefined mappings for, or only an awkward - default mapping such as to a text string. A procedural language can be - designed so that its type mappings are also extensible, and an extension - can add mappings between new PostgreSQL types - and suitable types in the target language. + A routine's statically-declared parameter types (and, for a function, + return type) are found in the proargtypes and + prorettype columns of the + pg_proc row. + If a routine has OUT parameters, those types are + included in the proallargtypes column, and their names + in proargnames. + Convenience functions declared in funcapi.h are + available for extracting that information. - One mechanism PostgreSQL provides that may be - used for that purpose is . - The command associates a PostgreSQL type and - a specific procedural language with a pair of functions to handle the - mapping of that type to a corresponding procedural language type and back. + The statically-declared types may include polymorphic types that need + to be resolved according to the actual types present at the call site, + as described in . - - For a procedural language to support transforms, its call handler is - responsible for consulting the protrftypes column of - a routine's pg_proc row to determine which types - should have transforms applied. - A convenience function get_call_trftypes is - available. - The call handler must then resolve the from SQL function - for each affected parameter type, and the to SQL function - for any affected result. - It may use the get_transform_fromsql and - get_transform_tosql functions for that. - + - - The handler must then apply the proper from SQL functions - to all affected inputs (including elements within array or composite - types) and, after calling the target routine, apply the proper - to SQL functions similarly to any results. - If the target routine might interact with the database using SPI, - the handler may arrange for the requested transforms to be applied - in those operations as well. - + + Mapping to procedural language types - Because the procedural language implementation, and not - PostgreSQL itself, is responsible for calling - the transform functions, it is free to define what it will pass as the - parameter to each function (declared as internal for both), - and how it will interpret the result (also declared internal) - of the from SQL function. Effectively, each procedural - language's implementation defines the API that must be adhered to - by any author of transforms for that language. + Once the PostgreSQL types of any parameters + and results have been resolved, the handler must determine how it will + map their values to and from suitable types that exist in the procedural + language. - A procedural language might impose limits on where and how it will apply - transforms (such as on array or domain types). The - get_transform_fromsql and - get_transform_tosql functions mentioned above - consider each type only shallowly, and will not, for example, return - a transform function for a domain type if only its base type was listed in - the TRANSFORM clause. - If a procedural language's call handler does not implement transforms - at all, no TRANSFORM clause will have any effect - for routines declared in that language. - The language's validator function can be used to give immediate feedback - if a routine is declared with TRANSFORM clauses - the implementation cannot support. + The designer of a procedural language will typically document what types + will be supported and how they will be mapped, which could be as simple + as using every type's text input/output format to map it to the target + language's string type, or could directly map many types to corresponding + ones the target language provides. The handler function will implement + those rules. - - - - - - Caching resolved routine information + + Type transforms + + + Because PostgreSQL is extensible, and + an extension can easily supply new types, a procedural language handler + may encounter types it has no predefined mappings for, or only an awkward + default mapping such as to a text string. A procedural language can be + designed so that its type mappings are also extensible, and an extension + can add mappings between new PostgreSQL types + and suitable types in the target language. + + + + One mechanism PostgreSQL provides that may be + used for that purpose is . + The command associates a PostgreSQL type and + a specific procedural language with a pair of functions to handle the + mapping of that type to a corresponding procedural language type + and back. + + + + For a procedural language to support transforms, its call handler is + responsible for consulting the protrftypes column of + a routine's pg_proc row to determine which types + should have transforms applied. + A convenience function get_call_trftypes is + available. + The call handler must then resolve the from SQL function + for each affected parameter type, and the to SQL function + for any affected result. + It may use the get_transform_fromsql and + get_transform_tosql functions for that. + + + + The handler must then apply the proper from SQL functions + to all affected inputs (including elements within array or composite + types) and, after calling the target routine, apply the proper + to SQL functions similarly to any results. + If the target routine might interact with the database using SPI, + the handler may arrange for the requested transforms to be applied + in those operations as well. + + + + Because the procedural language implementation, and not + PostgreSQL itself, is responsible for calling + the transform functions, it is free to define what it will pass as the + parameter to each function (declared as internal for both), + and how it will interpret the result (also declared + internal) of the from SQL function. + Effectively, each procedural language's implementation defines the API + that must be adhered to by any author of transforms for that language. + + + + A procedural language might impose limits on where and how it will apply + transforms (such as on array or domain types). The + get_transform_fromsql and + get_transform_tosql functions mentioned above + consider each type only shallowly, and will not, for example, return + a transform function for a domain type if only its base type was listed + in the TRANSFORM clause. + If a procedural language's call handler does not implement transforms + at all, no TRANSFORM clause will have any effect + for routines declared in that language. + The language's validator function can be used to give immediate feedback + if a routine is declared with TRANSFORM clauses + the implementation cannot support. + + + + + + + + Caching resolved routine information - - Often, the same routine is called many times per SQL statement. - A call handler can avoid repeated lookups of information about the - called routine by using the - flinfo->fn_extra field. This will - initially be NULL, but can be set by the call handler to point at - information about the called routine. On subsequent calls, if - flinfo->fn_extra is already non-NULL - then it can be used and the information lookup step skipped. The - call handler must make sure that - flinfo->fn_extra is made to point at - memory that will live at least until the end of the current query, - since an FmgrInfo data structure could be - kept that long. One way to do this is to allocate the extra data - in the memory context specified by - flinfo->fn_mcxt; such data will - normally have the same lifespan as the - FmgrInfo itself. But the handler could - also choose to use a longer-lived memory context so that it can cache - routine definition information across queries. - + + Often, the same routine is called many times per SQL statement. + A call handler can avoid repeated lookups of information about the + called routine by using the + flinfo->fn_extra field. This will + initially be NULL, but can be set by the call handler + to point at information about the called routine. On subsequent calls, + if flinfo->fn_extra is already + non-NULL then it can be used and the information lookup + step skipped. The call handler must make sure that + flinfo->fn_extra is made to point at + memory that will live at least until the end of the current query, + since an FmgrInfo data structure could be + kept that long. One way to do this is to allocate the extra data + in the memory context specified by + flinfo->fn_mcxt; such data will + normally have the same lifespan as the + FmgrInfo itself. But the handler could + also choose to use a longer-lived memory context so that it can cache + routine definition information across queries. + - - If the handler supports returning sets, and uses the ValuePerCall mode - helper macros described in , it must - not use fn_extra during set-returning calls. - The helper macros use that field for their own purposes. After - SRF_FIRSTCALL_INIT has been called, the field will point - to a FuncCallContext structure, which has - a user_fctx field that can be used similarly, - but only through the sequence of calls returning one set result. - + + If the handler supports returning sets, and uses the ValuePerCall mode + helper macros described in , it must + not use fn_extra during set-returning calls. + The helper macros use that field for their own purposes. After + SRF_FIRSTCALL_INIT has been called, the field will point + to a FuncCallContext structure, which has + a user_fctx field that can be used similarly, + but only through the sequence of calls returning one set result. + - + Validator function - - If a validator is provided by a procedural language, it - must be declared as a function taking a single parameter of type - oid. The validator's result is ignored, so it is customarily - declared to return void. - The validator itself may be written in any procedural language able to - receive an oid-typed parameter and query system catalogs. - + + If a validator is provided by a procedural language, it + must be declared as a function taking a single parameter of type + oid. The validator's result is ignored, so it is customarily + declared to return void. + The validator itself may be written in any procedural language able to + receive an oid-typed parameter and query system catalogs. + - - The validator will be called at - the end of a CREATE FUNCTION or - CREATE PROCEDURE command that has created - or updated a routine written in the procedural language. - The passed-in OID is the OID of the routine's pg_proc - row. The validator must fetch this row in the usual way, and do - whatever checking is appropriate. - + + The validator will be called at + the end of a CREATE FUNCTION or + CREATE PROCEDURE command that has created + or updated a routine written in the procedural language. + The passed-in OID is the OID of the routine's + pg_proc row. The validator must fetch this row + in the usual way, and do whatever checking is appropriate. + - - First, call CheckFunctionValidatorAccess() to diagnose - explicit calls to the validator that the user could not achieve through - CREATE FUNCTION or CREATE PROCEDURE. - Typical checks then include verifying - that the routine's argument and result types are supported by the - language, and that the routine's body is syntactically correct - in the language. If the validator finds the routine to be okay, - it should just return. If it finds an error, it should report that - via the normal ereport() error reporting mechanism. - Throwing an error will force a transaction rollback and thus prevent - the incorrect routine definition from being committed. - + + First, call CheckFunctionValidatorAccess() + to diagnose explicit calls to the validator that the user could not achieve + through CREATE FUNCTION or + CREATE PROCEDURE. + Typical checks then include verifying + that the routine's argument and result types are supported by the + language, and that the routine's body is syntactically correct + in the language. If the validator finds the routine to be okay, + it should just return. If it finds an error, it should report that + via the normal ereport() error reporting mechanism. + Throwing an error will force a transaction rollback and thus prevent + the incorrect routine definition from being committed. + - - Validator functions should typically honor the parameter: if it is turned off then - any expensive or context-sensitive checking should be skipped. If the - language provides for code execution at compilation time, the validator - must suppress checks that would induce such execution. In particular, - this parameter is turned off by pg_dump so that it can - load procedural language routines without worrying about side effects or - dependencies of the routine bodies on other database objects. - (Because of this requirement, the call handler should avoid - assuming that the validator has fully checked the routine. The point - of having a validator is not to let the call handler omit checks, but - to notify the user immediately if there are obvious errors in a - CREATE FUNCTION or CREATE PROCEDURE - command.) - + + Validator functions should typically honor the parameter: if it is turned off then + any expensive or context-sensitive checking should be skipped. If the + language provides for code execution at compilation time, the validator + must suppress checks that would induce such execution. In particular, + this parameter is turned off by pg_dump so that + it can load procedural language routines without worrying about + side effects or dependencies of the routine bodies on other database + objects. + (Because of this requirement, the call handler should avoid + assuming that the validator has fully checked the routine. The point + of having a validator is not to let the call handler omit checks, but + to notify the user immediately if there are obvious errors in a + CREATE FUNCTION or CREATE PROCEDURE + command.) + - - While the choice of exactly what to check is mostly left to the - discretion of the validator function, note that the core - CREATE FUNCTION and CREATE PROCEDURE - code only executes SET clauses - attached to a routine when check_function_bodies is on. - Therefore, checks whose results might be affected by GUC parameters - definitely should be skipped when check_function_bodies is - off, to avoid false failures when reloading a dump. - + + While the choice of exactly what to check is mostly left to the + discretion of the validator function, note that the core + CREATE FUNCTION and CREATE PROCEDURE + code only executes SET clauses + attached to a routine when check_function_bodies is on. + Therefore, checks whose results might be affected by GUC parameters + definitely should be skipped when check_function_bodies + is off, to avoid false failures when reloading a dump. + - - If a language's call handler does not apply parameter and return type - transforms, then no TRANSFORM clause in a routine - declaration will have any effect. To provide immediate feedback if a - declaration contains such a clause, the validator can report a suitable - error whenever the protrftypes column of the routine's - pg_proc row is non-null. - + + If a language's call handler does not apply parameter and return type + transforms, then no TRANSFORM clause in a routine + declaration will have any effect. To provide immediate feedback if a + declaration contains such a clause, the validator can report a suitable + error whenever the protrftypes column of the routine's + pg_proc row is non-null. + Inline handler function - - If this handler is provided by a procedural language, it - must be declared as a function taking a single parameter of type - internal, which will be a pointer - to an InlineCodeBlock struct when the handler - is called. The result is ignored, so the return type is customarily - declared as void. - The inline handler itself may be written in any procedural language that - permits declaring an internal parameter with a suitable - language binding for accessing it as an - InlineCodeBlock struct. - + + If this handler is provided by a procedural language, it + must be declared as a function taking a single parameter of type + internal, which will be a pointer + to an InlineCodeBlock struct when the handler + is called. The result is ignored, so the return type is customarily + declared as void. + The inline handler itself may be written in any procedural language that + permits declaring an internal parameter with a suitable + language binding for accessing it as an + InlineCodeBlock struct. + - - The inline handler - will be called when a DO statement is executed specifying - the procedural language. The InlineCodeBlock - struct contains information - about the DO statement's parameters, in particular the - text of the anonymous code block to be executed. - It also contains the OID of the intended procedural language and whether - that procedural language is declared as TRUSTED, useful - if a single inline handler is supporting more than one procedural language. - The inline handler should execute the code block and return. - + + The inline handler + will be called when a DO statement is executed + specifying the procedural language. + The InlineCodeBlock struct contains information + about the DO statement's parameters, in particular the + text of the anonymous code block to be executed. + It also contains the OID of the intended procedural language and whether + that procedural language is declared as TRUSTED, useful + if a single inline handler is supporting more than one procedural language. + The inline handler should execute the code block and return. + Packaging the language handlers - - It's recommended that you wrap all these function declarations, - as well as the CREATE LANGUAGE command itself, into - an extension so that a simple CREATE EXTENSION - command is sufficient to install the language. See - for information about writing - extensions. - + + It's recommended that you wrap all these function declarations, + as well as the CREATE LANGUAGE command itself, into + an extension so that a simple + CREATE EXTENSION command is sufficient to install + the language. See for information + about writing extensions. + Example code - - A template for a procedural-language handler written as a C extension is - provided in src/test/modules/plsample. This is a - working sample demonstrating one way to create a procedural-language - handler, process parameters, and return a value. - + + A template for a procedural-language handler written as a C extension is + provided in src/test/modules/plsample. This is a + working sample demonstrating one way to create a procedural-language + handler, process parameters, and return a value. + - - The procedural languages included in the standard distribution - are good references when trying to write your own language handler. - Look into the src/pl subdirectory of the source tree. - The - reference page also has some useful details. - + + The procedural languages included in the standard distribution + are good references when trying to write your own language handler. + Look into the src/pl subdirectory of the source tree. + The + reference page also has some useful details. + -- 2.7.3