diff options
Diffstat (limited to 'src/include')
-rw-r--r-- | src/include/catalog/catversion.h | 2 | ||||
-rw-r--r-- | src/include/catalog/pg_proc.dat | 20 | ||||
-rw-r--r-- | src/include/nodes/supportnodes.h | 55 |
3 files changed, 67 insertions, 10 deletions
diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index eddbd298091..f7226b8e439 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -57,6 +57,6 @@ */ /* yyyymmddN */ -#define CATALOG_VERSION_NO 202502071 +#define CATALOG_VERSION_NO 202502111 #endif diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 5b8c2ad2a54..9e803d610d7 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -1598,14 +1598,20 @@ proname => 'cardinality', prorettype => 'int4', proargtypes => 'anyarray', prosrc => 'array_cardinality' }, { oid => '378', descr => 'append element onto end of array', - proname => 'array_append', proisstrict => 'f', - prorettype => 'anycompatiblearray', + proname => 'array_append', prosupport => 'array_append_support', + proisstrict => 'f', prorettype => 'anycompatiblearray', proargtypes => 'anycompatiblearray anycompatible', prosrc => 'array_append' }, +{ oid => '8680', descr => 'planner support for array_append', + proname => 'array_append_support', prorettype => 'internal', + proargtypes => 'internal', prosrc => 'array_append_support' }, { oid => '379', descr => 'prepend element onto front of array', - proname => 'array_prepend', proisstrict => 'f', - prorettype => 'anycompatiblearray', + proname => 'array_prepend', prosupport => 'array_prepend_support', + proisstrict => 'f', prorettype => 'anycompatiblearray', proargtypes => 'anycompatible anycompatiblearray', prosrc => 'array_prepend' }, +{ oid => '8681', descr => 'planner support for array_prepend', + proname => 'array_prepend_support', prorettype => 'internal', + proargtypes => 'internal', prosrc => 'array_prepend_support' }, { oid => '383', proname => 'array_cat', proisstrict => 'f', prorettype => 'anycompatiblearray', @@ -12207,8 +12213,12 @@ # subscripting support for built-in types { oid => '6179', descr => 'standard array subscripting support', - proname => 'array_subscript_handler', prorettype => 'internal', + proname => 'array_subscript_handler', + prosupport => 'array_subscript_handler_support', prorettype => 'internal', proargtypes => 'internal', prosrc => 'array_subscript_handler' }, +{ oid => '8682', descr => 'planner support for array_subscript_handler', + proname => 'array_subscript_handler_support', prorettype => 'internal', + proargtypes => 'internal', prosrc => 'array_subscript_handler_support' }, { oid => '6180', descr => 'raw array subscripting support', proname => 'raw_array_subscript_handler', prorettype => 'internal', proargtypes => 'internal', prosrc => 'raw_array_subscript_handler' }, diff --git a/src/include/nodes/supportnodes.h b/src/include/nodes/supportnodes.h index ad5d43a2a70..9c047cc401b 100644 --- a/src/include/nodes/supportnodes.h +++ b/src/include/nodes/supportnodes.h @@ -6,10 +6,10 @@ * This file defines the API for "planner support functions", which * are SQL functions (normally written in C) that can be attached to * another "target" function to give the system additional knowledge - * about the target function. All the current capabilities have to do - * with planning queries that use the target function, though it is - * possible that future extensions will add functionality to be invoked - * by the parser or executor. + * about the target function. The name is now something of a misnomer, + * since some of the call sites are in the executor not the planner, + * but "function support function" would be a confusing name so we + * stick with "planner support function". * * A support function must have the SQL signature * supportfn(internal) returns internal @@ -343,4 +343,51 @@ typedef struct SupportRequestOptimizeWindowClause * optimizations are possible. */ } SupportRequestOptimizeWindowClause; +/* + * The ModifyInPlace request allows the support function to detect whether + * a call to its target function can be allowed to modify a read/write + * expanded object in-place. The context is that we are considering a + * PL/pgSQL (or similar PL) assignment of the form "x := f(x, ...)" where + * the variable x is of a type that can be represented as an expanded object + * (see utils/expandeddatum.h). If f() can usefully optimize by modifying + * the passed-in object in-place, then this request can be implemented to + * instruct PL/pgSQL to pass a read-write expanded pointer to the variable's + * value. (Note that there is no guarantee that later calls to f() will + * actually do so. If f() receives a read-only pointer, or a pointer to a + * non-expanded object, it must follow the usual convention of not modifying + * the pointed-to object.) There are two requirements that must be met + * to make this safe: + * 1. f() must guarantee that it will not have modified the object if it + * fails. Otherwise the variable's value might change unexpectedly. + * 2. If the other arguments to f() ("..." in the above example) contain + * references to x, f() must be able to cope with that; or if that's not + * safe, the support function must scan the other arguments to verify that + * there are no other references to x. An example of the concern here is + * that in "arr := array_append(arr, arr[1])", if the array element type + * is pass-by-reference then array_append would receive a second argument + * that points into the array object it intends to modify. array_append is + * coded to make that safe, but other functions might not be able to cope. + * + * "args" is a node tree list representing the function's arguments. + * One or more nodes within the node tree will be PARAM_EXTERN Params + * with ID "paramid", which represent the assignment target variable. + * (Note that such references are not necessarily at top level in the list, + * for example we might have "x := f(x, g(x))". Generally it's only safe + * to optimize a reference that is at top level, else we're making promises + * about the behavior of g() as well as f().) + * + * If modify-in-place is safe, the support function should return the + * address of the Param node that is to return a read-write pointer. + * (At most one of the references is allowed to do so.) Otherwise, + * return NULL. + */ +typedef struct SupportRequestModifyInPlace +{ + NodeTag type; + + Oid funcid; /* PG_PROC OID of the target function */ + List *args; /* Arguments to the function */ + int paramid; /* ID of Param(s) representing variable */ +} SupportRequestModifyInPlace; + #endif /* SUPPORTNODES_H */ |