diff options
Diffstat (limited to 'src/backend/utils/adt/array_userfuncs.c')
-rw-r--r-- | src/backend/utils/adt/array_userfuncs.c | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/src/backend/utils/adt/array_userfuncs.c b/src/backend/utils/adt/array_userfuncs.c index 0b02fe37445..2aae2f8ed93 100644 --- a/src/backend/utils/adt/array_userfuncs.c +++ b/src/backend/utils/adt/array_userfuncs.c @@ -16,6 +16,7 @@ #include "common/int.h" #include "common/pg_prng.h" #include "libpq/pqformat.h" +#include "nodes/supportnodes.h" #include "port/pg_bitutils.h" #include "utils/array.h" #include "utils/builtins.h" @@ -167,6 +168,36 @@ array_append(PG_FUNCTION_ARGS) PG_RETURN_DATUM(result); } +/* + * array_append_support() + * + * Planner support function for array_append() + */ +Datum +array_append_support(PG_FUNCTION_ARGS) +{ + Node *rawreq = (Node *) PG_GETARG_POINTER(0); + Node *ret = NULL; + + if (IsA(rawreq, SupportRequestModifyInPlace)) + { + /* + * We can optimize in-place appends if the function's array argument + * is the array being assigned to. We don't need to worry about array + * references within the other argument. + */ + SupportRequestModifyInPlace *req = (SupportRequestModifyInPlace *) rawreq; + Param *arg = (Param *) linitial(req->args); + + if (arg && IsA(arg, Param) && + arg->paramkind == PARAM_EXTERN && + arg->paramid == req->paramid) + ret = (Node *) arg; + } + + PG_RETURN_POINTER(ret); +} + /*----------------------------------------------------------------------------- * array_prepend : * push an element onto the front of a one-dimensional array @@ -230,6 +261,36 @@ array_prepend(PG_FUNCTION_ARGS) PG_RETURN_DATUM(result); } +/* + * array_prepend_support() + * + * Planner support function for array_prepend() + */ +Datum +array_prepend_support(PG_FUNCTION_ARGS) +{ + Node *rawreq = (Node *) PG_GETARG_POINTER(0); + Node *ret = NULL; + + if (IsA(rawreq, SupportRequestModifyInPlace)) + { + /* + * We can optimize in-place prepends if the function's array argument + * is the array being assigned to. We don't need to worry about array + * references within the other argument. + */ + SupportRequestModifyInPlace *req = (SupportRequestModifyInPlace *) rawreq; + Param *arg = (Param *) lsecond(req->args); + + if (arg && IsA(arg, Param) && + arg->paramkind == PARAM_EXTERN && + arg->paramid == req->paramid) + ret = (Node *) arg; + } + + PG_RETURN_POINTER(ret); +} + /*----------------------------------------------------------------------------- * array_cat : * concatenate two nD arrays to form an nD array, or |