MCPcopy Create free account
hub / github.com/apache/cloudberry / exec_check_rw_parameter

Function exec_check_rw_parameter

src/pl/plpgsql/src/pl_exec.c:8111–8215  ·  view source on GitHub ↗

* exec_check_rw_parameter --- can we pass expanded object as read/write param? * * If we have an assignment like "x := array_append(x, foo)" in which the * top-level function is trusted not to corrupt its argument in case of an * error, then when x has an expanded object as value, it is safe to pass the * value as a read/write pointer and let the function modify the value * in-place. * * T

Source from the content-addressed store, hash-verified

8109 * shakier in the general case.
8110 */
8111static void
8112exec_check_rw_parameter(PLpgSQL_expr *expr)
8113{
8114 int target_dno;
8115 Oid funcid;
8116 List *fargs;
8117 ListCell *lc;
8118
8119 /* Assume unsafe */
8120 expr->expr_rw_param = NULL;
8121
8122 /* Done if expression isn't an assignment source */
8123 target_dno = expr->target_param;
8124 if (target_dno < 0)
8125 return;
8126
8127 /*
8128 * If target variable isn't referenced by expression, no need to look
8129 * further.
8130 */
8131 if (!bms_is_member(target_dno, expr->paramnos))
8132 return;
8133
8134 /* Shouldn't be here for non-simple expression */
8135 Assert(expr->expr_simple_expr != NULL);
8136
8137 /*
8138 * Top level of expression must be a simple FuncExpr, OpExpr, or
8139 * SubscriptingRef, else we can't optimize.
8140 */
8141 if (IsA(expr->expr_simple_expr, FuncExpr))
8142 {
8143 FuncExpr *fexpr = (FuncExpr *) expr->expr_simple_expr;
8144
8145 funcid = fexpr->funcid;
8146 fargs = fexpr->args;
8147 }
8148 else if (IsA(expr->expr_simple_expr, OpExpr))
8149 {
8150 OpExpr *opexpr = (OpExpr *) expr->expr_simple_expr;
8151
8152 funcid = opexpr->opfuncid;
8153 fargs = opexpr->args;
8154 }
8155 else if (IsA(expr->expr_simple_expr, SubscriptingRef))
8156 {
8157 SubscriptingRef *sbsref = (SubscriptingRef *) expr->expr_simple_expr;
8158
8159 /* We only trust standard varlena arrays to be safe */
8160 if (get_typsubscript(sbsref->refcontainertype, NULL) !=
8161 F_ARRAY_SUBSCRIPT_HANDLER)
8162 return;
8163
8164 /* We can optimize the refexpr if it's the target, otherwise not */
8165 if (sbsref->refexpr && IsA(sbsref->refexpr, Param))
8166 {
8167 Param *param = (Param *) sbsref->refexpr;
8168

Callers 1

exec_save_simple_exprFunction · 0.85

Calls 3

bms_is_memberFunction · 0.85
get_typsubscriptFunction · 0.85
foreachFunction · 0.50

Tested by

no test coverage detected