aboutsummaryrefslogtreecommitdiff
path: root/src/include
diff options
context:
space:
mode:
Diffstat (limited to 'src/include')
-rw-r--r--src/include/catalog/catversion.h2
-rw-r--r--src/include/catalog/pg_proc.dat20
-rw-r--r--src/include/nodes/supportnodes.h55
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 */