From b25138fce2b9c4be66e5e6b5541eecdc675c50b6 Mon Sep 17 00:00:00 2001 From: Dmitrii Dolgov Date: Tue, 30 Jan 2018 16:13:36 +0100 Subject: [PATCH 1/5] Renaming for new subscripting mechanism --- contrib/pg_stat_statements/pg_stat_statements.c | 12 +-- contrib/postgres_fdw/deparse.c | 28 +++---- src/backend/executor/execExpr.c | 105 ++++++++++++------------ src/backend/executor/execExprInterp.c | 32 ++++---- src/backend/nodes/copyfuncs.c | 14 ++-- src/backend/nodes/equalfuncs.c | 8 +- src/backend/nodes/nodeFuncs.c | 58 ++++++------- src/backend/nodes/outfuncs.c | 10 +-- src/backend/nodes/readfuncs.c | 14 ++-- src/backend/optimizer/util/clauses.c | 14 ++-- src/backend/parser/analyze.c | 9 +- src/backend/parser/parse_target.c | 6 +- src/backend/rewrite/rewriteHandler.c | 26 +++--- src/backend/utils/adt/ruleutils.c | 75 +++++++++-------- src/include/executor/execExpr.h | 55 ++++++------- src/include/nodes/nodes.h | 2 +- src/include/nodes/parsenodes.h | 2 +- src/include/nodes/primnodes.h | 2 +- src/pl/plpgsql/src/pl_exec.c | 2 +- 19 files changed, 243 insertions(+), 231 deletions(-) diff --git a/contrib/pg_stat_statements/pg_stat_statements.c b/contrib/pg_stat_statements/pg_stat_statements.c index 9286734..0d42eb4 100644 --- a/contrib/pg_stat_statements/pg_stat_statements.c +++ b/contrib/pg_stat_statements/pg_stat_statements.c @@ -2504,14 +2504,14 @@ JumbleExpr(pgssJumbleState *jstate, Node *node) JumbleExpr(jstate, (Node *) expr->aggfilter); } break; - case T_ArrayRef: + case T_SubscriptingRef: { - ArrayRef *aref = (ArrayRef *) node; + SubscriptingRef *sbsref = (SubscriptingRef *) node; - JumbleExpr(jstate, (Node *) aref->refupperindexpr); - JumbleExpr(jstate, (Node *) aref->reflowerindexpr); - JumbleExpr(jstate, (Node *) aref->refexpr); - JumbleExpr(jstate, (Node *) aref->refassgnexpr); + JumbleExpr(jstate, (Node *) sbsref->refupperindexpr); + JumbleExpr(jstate, (Node *) sbsref->reflowerindexpr); + JumbleExpr(jstate, (Node *) sbsref->refexpr); + JumbleExpr(jstate, (Node *) sbsref->refassgnexpr); } break; case T_FuncExpr: diff --git a/contrib/postgres_fdw/deparse.c b/contrib/postgres_fdw/deparse.c index e111b09..519eecc 100644 --- a/contrib/postgres_fdw/deparse.c +++ b/contrib/postgres_fdw/deparse.c @@ -147,7 +147,7 @@ static void deparseExpr(Expr *expr, deparse_expr_cxt *context); static void deparseVar(Var *node, deparse_expr_cxt *context); static void deparseConst(Const *node, deparse_expr_cxt *context, int showtype); static void deparseParam(Param *node, deparse_expr_cxt *context); -static void deparseArrayRef(ArrayRef *node, deparse_expr_cxt *context); +static void deparseSubscriptingRef(SubscriptingRef *node, deparse_expr_cxt *context); static void deparseFuncExpr(FuncExpr *node, deparse_expr_cxt *context); static void deparseOpExpr(OpExpr *node, deparse_expr_cxt *context); static void deparseOperatorName(StringInfo buf, Form_pg_operator opform); @@ -398,34 +398,34 @@ foreign_expr_walker(Node *node, state = FDW_COLLATE_UNSAFE; } break; - case T_ArrayRef: + case T_SubscriptingRef: { - ArrayRef *ar = (ArrayRef *) node; + SubscriptingRef *sr = (SubscriptingRef *) node; /* Assignment should not be in restrictions. */ - if (ar->refassgnexpr != NULL) + if (sr->refassgnexpr != NULL) return false; /* - * Recurse to remaining subexpressions. Since the array + * Recurse to remaining subexpressions. Since the container * subscripts must yield (noncollatable) integers, they won't * affect the inner_cxt state. */ - if (!foreign_expr_walker((Node *) ar->refupperindexpr, + if (!foreign_expr_walker((Node *) sr->refupperindexpr, glob_cxt, &inner_cxt)) return false; - if (!foreign_expr_walker((Node *) ar->reflowerindexpr, + if (!foreign_expr_walker((Node *) sr->reflowerindexpr, glob_cxt, &inner_cxt)) return false; - if (!foreign_expr_walker((Node *) ar->refexpr, + if (!foreign_expr_walker((Node *) sr->refexpr, glob_cxt, &inner_cxt)) return false; /* - * Array subscripting should yield same collation as input, + * Container subscripting should yield same collation as input, * but for safety use same logic as for function nodes. */ - collation = ar->refcollid; + collation = sr->refcollid; if (collation == InvalidOid) state = FDW_COLLATE_NONE; else if (inner_cxt.state == FDW_COLLATE_SAFE && @@ -2132,8 +2132,8 @@ deparseExpr(Expr *node, deparse_expr_cxt *context) case T_Param: deparseParam((Param *) node, context); break; - case T_ArrayRef: - deparseArrayRef((ArrayRef *) node, context); + case T_SubscriptingRef: + deparseSubscriptingRef((SubscriptingRef *) node, context); break; case T_FuncExpr: deparseFuncExpr((FuncExpr *) node, context); @@ -2379,10 +2379,10 @@ deparseParam(Param *node, deparse_expr_cxt *context) } /* - * Deparse an array subscript expression. + * Deparse a container subscript expression. */ static void -deparseArrayRef(ArrayRef *node, deparse_expr_cxt *context) +deparseSubscriptingRef(SubscriptingRef *node, deparse_expr_cxt *context) { StringInfo buf = context->buf; ListCell *lowlist_item; diff --git a/src/backend/executor/execExpr.c b/src/backend/executor/execExpr.c index c6eb3eb..ed3f68f 100644 --- a/src/backend/executor/execExpr.c +++ b/src/backend/executor/execExpr.c @@ -66,7 +66,8 @@ static void ExecPushExprSlots(ExprState *state, LastAttnumInfo *info); static bool get_last_attnums_walker(Node *node, LastAttnumInfo *info); static void ExecInitWholeRowVar(ExprEvalStep *scratch, Var *variable, ExprState *state); -static void ExecInitArrayRef(ExprEvalStep *scratch, ArrayRef *aref, +static void ExecInitSubscriptingRef(ExprEvalStep *scratch, + SubscriptingRef *sbsref, ExprState *state, Datum *resv, bool *resnull); static bool isAssignmentIndirectionExpr(Expr *expr); @@ -863,11 +864,11 @@ ExecInitExprRec(Expr *node, ExprState *state, break; } - case T_ArrayRef: + case T_SubscriptingRef: { - ArrayRef *aref = (ArrayRef *) node; + SubscriptingRef *sbsref = (SubscriptingRef *) node; - ExecInitArrayRef(&scratch, aref, state, resv, resnull); + ExecInitSubscriptingRef(&scratch, sbsref, state, resv, resnull); break; } @@ -1182,7 +1183,7 @@ ExecInitExprRec(Expr *node, ExprState *state, /* * Use the CaseTestExpr mechanism to pass down the old * value of the field being replaced; this is needed in - * case the newval is itself a FieldStore or ArrayRef that + * case the newval is itself a FieldStore or SubscriptingRef that * has to obtain and modify the old value. It's safe to * reuse the CASE mechanism because there cannot be a CASE * between here and where the value would be needed, and a @@ -2480,73 +2481,73 @@ ExecInitArrayRef(ExprEvalStep *scratch, ArrayRef *aref, /* Evaluate upper subscripts */ i = 0; - foreach(lc, aref->refupperindexpr) + foreach(lc, sbsref->refupperindexpr) { Expr *e = (Expr *) lfirst(lc); /* When slicing, individual subscript bounds can be omitted */ if (!e) { - arefstate->upperprovided[i] = false; + sbsrefstate->upperprovided[i] = false; i++; continue; } - arefstate->upperprovided[i] = true; + sbsrefstate->upperprovided[i] = true; /* Each subscript is evaluated into subscriptvalue/subscriptnull */ ExecInitExprRec(e, state, - &arefstate->subscriptvalue, &arefstate->subscriptnull); - - /* ... and then ARRAYREF_SUBSCRIPT saves it into step's workspace */ - scratch->opcode = EEOP_ARRAYREF_SUBSCRIPT; - scratch->d.arrayref_subscript.state = arefstate; - scratch->d.arrayref_subscript.off = i; - scratch->d.arrayref_subscript.isupper = true; - scratch->d.arrayref_subscript.jumpdone = -1; /* adjust later */ + &sbsrefstate->subscriptvalue, &sbsrefstate->subscriptnull); + + /* ... and then SBSREF_SUBSCRIPT saves it into step's workspace */ + scratch->opcode = EEOP_SBSREF_SUBSCRIPT; + scratch->d.sbsref_subscript.state = sbsrefstate; + scratch->d.sbsref_subscript.off = i; + scratch->d.sbsref_subscript.isupper = true; + scratch->d.sbsref_subscript.jumpdone = -1; /* adjust later */ ExprEvalPushStep(state, scratch); adjust_jumps = lappend_int(adjust_jumps, state->steps_len - 1); i++; } - arefstate->numupper = i; + sbsrefstate->numupper = i; /* Evaluate lower subscripts similarly */ i = 0; - foreach(lc, aref->reflowerindexpr) + foreach(lc, sbsref->reflowerindexpr) { Expr *e = (Expr *) lfirst(lc); /* When slicing, individual subscript bounds can be omitted */ if (!e) { - arefstate->lowerprovided[i] = false; + sbsrefstate->lowerprovided[i] = false; i++; continue; } - arefstate->lowerprovided[i] = true; + sbsrefstate->lowerprovided[i] = true; /* Each subscript is evaluated into subscriptvalue/subscriptnull */ ExecInitExprRec(e, state, - &arefstate->subscriptvalue, &arefstate->subscriptnull); - - /* ... and then ARRAYREF_SUBSCRIPT saves it into step's workspace */ - scratch->opcode = EEOP_ARRAYREF_SUBSCRIPT; - scratch->d.arrayref_subscript.state = arefstate; - scratch->d.arrayref_subscript.off = i; - scratch->d.arrayref_subscript.isupper = false; - scratch->d.arrayref_subscript.jumpdone = -1; /* adjust later */ + &sbsrefstate->subscriptvalue, &sbsrefstate->subscriptnull); + + /* ... and then SBSREF_SUBSCRIPT saves it into step's workspace */ + scratch->opcode = EEOP_SBSREF_SUBSCRIPT; + scratch->d.sbsref_subscript.state = sbsrefstate; + scratch->d.sbsref_subscript.off = i; + scratch->d.sbsref_subscript.isupper = false; + scratch->d.sbsref_subscript.jumpdone = -1; /* adjust later */ ExprEvalPushStep(state, scratch); adjust_jumps = lappend_int(adjust_jumps, state->steps_len - 1); i++; } - arefstate->numlower = i; + sbsrefstate->numlower = i; /* Should be impossible if parser is sane, but check anyway: */ - if (arefstate->numlower != 0 && - arefstate->numupper != arefstate->numlower) + if (sbsrefstate->numlower != 0 && + sbsrefstate->numupper != sbsrefstate->numlower) elog(ERROR, "upper and lower index lists are not same length"); if (isAssignment) @@ -2556,7 +2557,7 @@ ExecInitArrayRef(ExprEvalStep *scratch, ArrayRef *aref, /* * We might have a nested-assignment situation, in which the - * refassgnexpr is itself a FieldStore or ArrayRef that needs to + * refassgnexpr is itself a FieldStore or SubscriptingRef that needs to * obtain and modify the previous value of the array element or slice * being replaced. If so, we have to extract that value from the * array and pass it down via the CaseTestExpr mechanism. It's safe @@ -2568,36 +2569,36 @@ ExecInitArrayRef(ExprEvalStep *scratch, ArrayRef *aref, * Since fetching the old element might be a nontrivial expense, do it * only if the argument actually needs it. */ - if (isAssignmentIndirectionExpr(aref->refassgnexpr)) + if (isAssignmentIndirectionExpr(sbsref->refassgnexpr)) { - scratch->opcode = EEOP_ARRAYREF_OLD; - scratch->d.arrayref.state = arefstate; + scratch->opcode = EEOP_SBSREF_OLD; + scratch->d.sbsref.state = sbsrefstate; ExprEvalPushStep(state, scratch); } - /* ARRAYREF_OLD puts extracted value into prevvalue/prevnull */ + /* SBSREF_OLD puts extracted value into prevvalue/prevnull */ save_innermost_caseval = state->innermost_caseval; save_innermost_casenull = state->innermost_casenull; - state->innermost_caseval = &arefstate->prevvalue; - state->innermost_casenull = &arefstate->prevnull; + state->innermost_caseval = &sbsrefstate->prevvalue; + state->innermost_casenull = &sbsrefstate->prevnull; /* evaluate replacement value into replacevalue/replacenull */ - ExecInitExprRec(aref->refassgnexpr, state, - &arefstate->replacevalue, &arefstate->replacenull); + ExecInitExprRec(sbsref->refassgnexpr, state, + &sbsrefstate->replacevalue, &sbsrefstate->replacenull); state->innermost_caseval = save_innermost_caseval; state->innermost_casenull = save_innermost_casenull; /* and perform the assignment */ - scratch->opcode = EEOP_ARRAYREF_ASSIGN; - scratch->d.arrayref.state = arefstate; + scratch->opcode = EEOP_SBSREF_ASSIGN; + scratch->d.sbsref.state = sbsrefstate; ExprEvalPushStep(state, scratch); } else { /* array fetch is much simpler */ - scratch->opcode = EEOP_ARRAYREF_FETCH; - scratch->d.arrayref.state = arefstate; + scratch->opcode = EEOP_SBSREF_FETCH; + scratch->d.sbsref.state = sbsrefstate; ExprEvalPushStep(state, scratch); } @@ -2606,10 +2607,10 @@ ExecInitArrayRef(ExprEvalStep *scratch, ArrayRef *aref, { ExprEvalStep *as = &state->steps[lfirst_int(lc)]; - if (as->opcode == EEOP_ARRAYREF_SUBSCRIPT) + if (as->opcode == EEOP_SBSREF_SUBSCRIPT) { - Assert(as->d.arrayref_subscript.jumpdone == -1); - as->d.arrayref_subscript.jumpdone = state->steps_len; + Assert(as->d.sbsref_subscript.jumpdone == -1); + as->d.sbsref_subscript.jumpdone = state->steps_len; } else { @@ -2621,8 +2622,8 @@ ExecInitArrayRef(ExprEvalStep *scratch, ArrayRef *aref, } /* - * Helper for preparing ArrayRef expressions for evaluation: is expr a nested - * FieldStore or ArrayRef that needs the old element value passed down? + * Helper for preparing SubscriptingRef expressions for evaluation: is expr a nested + * FieldStore or SubscriptingRef that needs the old element value passed down? * * (We could use this in FieldStore too, but in that case passing the old * value is so cheap there's no need.) @@ -2645,11 +2646,11 @@ isAssignmentIndirectionExpr(Expr *expr) if (fstore->arg && IsA(fstore->arg, CaseTestExpr)) return true; } - else if (IsA(expr, ArrayRef)) + else if (IsA(expr, SubscriptingRef)) { - ArrayRef *arrayRef = (ArrayRef *) expr; + SubscriptingRef *sbsRef = (SubscriptingRef *) expr; - if (arrayRef->refexpr && IsA(arrayRef->refexpr, CaseTestExpr)) + if (sbsRef->refexpr && IsA(sbsRef->refexpr, CaseTestExpr)) return true; } return false; diff --git a/src/backend/executor/execExprInterp.c b/src/backend/executor/execExprInterp.c index f646fd9..6bcbf0e 100644 --- a/src/backend/executor/execExprInterp.c +++ b/src/backend/executor/execExprInterp.c @@ -367,10 +367,10 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull) &&CASE_EEOP_FIELDSELECT, &&CASE_EEOP_FIELDSTORE_DEFORM, &&CASE_EEOP_FIELDSTORE_FORM, - &&CASE_EEOP_ARRAYREF_SUBSCRIPT, - &&CASE_EEOP_ARRAYREF_OLD, - &&CASE_EEOP_ARRAYREF_ASSIGN, - &&CASE_EEOP_ARRAYREF_FETCH, + &&CASE_EEOP_SBSREF_SUBSCRIPT, + &&CASE_EEOP_SBSREF_OLD, + &&CASE_EEOP_SBSREF_ASSIGN, + &&CASE_EEOP_SBSREF_FETCH, &&CASE_EEOP_DOMAIN_TESTVAL, &&CASE_EEOP_DOMAIN_NOTNULL, &&CASE_EEOP_DOMAIN_CHECK, @@ -1379,43 +1379,43 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull) EEO_NEXT(); } - EEO_CASE(EEOP_ARRAYREF_SUBSCRIPT) + EEO_CASE(EEOP_SBSREF_SUBSCRIPT) { /* Process an array subscript */ /* too complex for an inline implementation */ - if (ExecEvalArrayRefSubscript(state, op)) + if (ExecEvalSubscriptingRef(state, op)) { EEO_NEXT(); } else { - /* Subscript is null, short-circuit ArrayRef to NULL */ - EEO_JUMP(op->d.arrayref_subscript.jumpdone); + /* Subscript is null, short-circuit SubscriptingRef to NULL */ + EEO_JUMP(op->d.sbsref_subscript.jumpdone); } } - EEO_CASE(EEOP_ARRAYREF_OLD) + EEO_CASE(EEOP_SBSREF_OLD) { /* - * Fetch the old value in an arrayref assignment, in case it's + * Fetch the old value in an sbsref assignment, in case it's * referenced (via a CaseTestExpr) inside the assignment * expression. */ /* too complex for an inline implementation */ - ExecEvalArrayRefOld(state, op); + ExecEvalSubscriptingRefOld(state, op); EEO_NEXT(); } /* - * Perform ArrayRef assignment + * Perform SubscriptingRef assignment */ - EEO_CASE(EEOP_ARRAYREF_ASSIGN) + EEO_CASE(EEOP_SBSREF_ASSIGN) { /* too complex for an inline implementation */ - ExecEvalArrayRefAssign(state, op); + ExecEvalSubscriptingRefAssign(state, op); EEO_NEXT(); } @@ -1423,10 +1423,10 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull) /* * Fetch subset of an array. */ - EEO_CASE(EEOP_ARRAYREF_FETCH) + EEO_CASE(EEOP_SBSREF_FETCH) { /* too complex for an inline implementation */ - ExecEvalArrayRefFetch(state, op); + ExecEvalSubscriptingRefFetch(state, op); EEO_NEXT(); } diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c index fd3001c..2e8702b 100644 --- a/src/backend/nodes/copyfuncs.c +++ b/src/backend/nodes/copyfuncs.c @@ -1418,14 +1418,14 @@ _copyWindowFunc(const WindowFunc *from) } /* - * _copyArrayRef + * _copySubscriptingRef */ -static ArrayRef * -_copyArrayRef(const ArrayRef *from) +static SubscriptingRef * +_copySubscriptingRef(const SubscriptingRef *from) { - ArrayRef *newnode = makeNode(ArrayRef); + SubscriptingRef *newnode = makeNode(SubscriptingRef); - COPY_SCALAR_FIELD(refarraytype); + COPY_SCALAR_FIELD(refcontainertype); COPY_SCALAR_FIELD(refelemtype); COPY_SCALAR_FIELD(reftypmod); COPY_SCALAR_FIELD(refcollid); @@ -4886,8 +4886,8 @@ copyObjectImpl(const void *from) case T_WindowFunc: retval = _copyWindowFunc(from); break; - case T_ArrayRef: - retval = _copyArrayRef(from); + case T_SubscriptingRef: + retval = _copySubscriptingRef(from); break; case T_FuncExpr: retval = _copyFuncExpr(from); diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c index 7d2aa1a..f206a7d 100644 --- a/src/backend/nodes/equalfuncs.c +++ b/src/backend/nodes/equalfuncs.c @@ -264,9 +264,9 @@ _equalWindowFunc(const WindowFunc *a, const WindowFunc *b) } static bool -_equalArrayRef(const ArrayRef *a, const ArrayRef *b) +_equalSubscriptingRef(const SubscriptingRef *a, const SubscriptingRef *b) { - COMPARE_SCALAR_FIELD(refarraytype); + COMPARE_SCALAR_FIELD(refcontainertype); COMPARE_SCALAR_FIELD(refelemtype); COMPARE_SCALAR_FIELD(reftypmod); COMPARE_SCALAR_FIELD(refcollid); @@ -3036,8 +3036,8 @@ equal(const void *a, const void *b) case T_WindowFunc: retval = _equalWindowFunc(a, b); break; - case T_ArrayRef: - retval = _equalArrayRef(a, b); + case T_SubscriptingRef: + retval = _equalSubscriptingRef(a, b); break; case T_FuncExpr: retval = _equalFuncExpr(a, b); diff --git a/src/backend/nodes/nodeFuncs.c b/src/backend/nodes/nodeFuncs.c index 6c76c41..ab3b021 100644 --- a/src/backend/nodes/nodeFuncs.c +++ b/src/backend/nodes/nodeFuncs.c @@ -66,15 +66,15 @@ exprType(const Node *expr) case T_WindowFunc: type = ((const WindowFunc *) expr)->wintype; break; - case T_ArrayRef: + case T_SubscriptingRef: { - const ArrayRef *arrayref = (const ArrayRef *) expr; + const SubscriptingRef *sbsref = (const SubscriptingRef *) expr; /* slice and/or store operations yield the array type */ if (arrayref->reflowerindexpr || arrayref->refassgnexpr) type = arrayref->refarraytype; else - type = arrayref->refelemtype; + type = sbsref->refelemtype; } break; case T_FuncExpr: @@ -286,9 +286,9 @@ exprTypmod(const Node *expr) return ((const Const *) expr)->consttypmod; case T_Param: return ((const Param *) expr)->paramtypmod; - case T_ArrayRef: - /* typmod is the same for array or element */ - return ((const ArrayRef *) expr)->reftypmod; + case T_SubscriptingRef: + /* typmod is the same for container or element */ + return ((const SubscriptingRef *) expr)->reftypmod; case T_FuncExpr: { int32 coercedTypmod; @@ -744,8 +744,8 @@ exprCollation(const Node *expr) case T_WindowFunc: coll = ((const WindowFunc *) expr)->wincollid; break; - case T_ArrayRef: - coll = ((const ArrayRef *) expr)->refcollid; + case T_SubscriptingRef: + coll = ((const SubscriptingRef *) expr)->refcollid; break; case T_FuncExpr: coll = ((const FuncExpr *) expr)->funccollid; @@ -988,8 +988,8 @@ exprSetCollation(Node *expr, Oid collation) case T_WindowFunc: ((WindowFunc *) expr)->wincollid = collation; break; - case T_ArrayRef: - ((ArrayRef *) expr)->refcollid = collation; + case T_SubscriptingRef: + ((SubscriptingRef *) expr)->refcollid = collation; break; case T_FuncExpr: ((FuncExpr *) expr)->funccollid = collation; @@ -1217,9 +1217,9 @@ exprLocation(const Node *expr) /* function name should always be the first thing */ loc = ((const WindowFunc *) expr)->location; break; - case T_ArrayRef: - /* just use array argument's location */ - loc = exprLocation((Node *) ((const ArrayRef *) expr)->refexpr); + case T_SubscriptingRef: + /* just use container argument's location */ + loc = exprLocation((Node *) ((const SubscriptingRef *) expr)->refexpr); break; case T_FuncExpr: { @@ -1910,21 +1910,22 @@ expression_tree_walker(Node *node, return true; } break; - case T_ArrayRef: + case T_SubscriptingRef: { - ArrayRef *aref = (ArrayRef *) node; + SubscriptingRef *sbsref = (SubscriptingRef *) node; - /* recurse directly for upper/lower array index lists */ - if (expression_tree_walker((Node *) aref->refupperindexpr, + /* recurse directly for upper/lower container index lists */ + if (expression_tree_walker((Node *) sbsref->refupperindexpr, walker, context)) return true; - if (expression_tree_walker((Node *) aref->reflowerindexpr, + if (expression_tree_walker((Node *) sbsref->reflowerindexpr, walker, context)) return true; /* walker must see the refexpr and refassgnexpr, however */ - if (walker(aref->refexpr, context)) + if (walker(sbsref->refexpr, context)) return true; - if (walker(aref->refassgnexpr, context)) + + if (walker(sbsref->refassgnexpr, context)) return true; } break; @@ -2528,20 +2529,21 @@ expression_tree_mutator(Node *node, return (Node *) newnode; } break; - case T_ArrayRef: + case T_SubscriptingRef: { - ArrayRef *arrayref = (ArrayRef *) node; - ArrayRef *newnode; + SubscriptingRef *sbsref = (SubscriptingRef *) node; + SubscriptingRef *newnode; - FLATCOPY(newnode, arrayref, ArrayRef); - MUTATE(newnode->refupperindexpr, arrayref->refupperindexpr, + FLATCOPY(newnode, sbsref, SubscriptingRef); + MUTATE(newnode->refupperindexpr, sbsref->refupperindexpr, List *); - MUTATE(newnode->reflowerindexpr, arrayref->reflowerindexpr, + MUTATE(newnode->reflowerindexpr, sbsref->reflowerindexpr, List *); - MUTATE(newnode->refexpr, arrayref->refexpr, + MUTATE(newnode->refexpr, sbsref->refexpr, Expr *); - MUTATE(newnode->refassgnexpr, arrayref->refassgnexpr, + MUTATE(newnode->refassgnexpr, sbsref->refassgnexpr, Expr *); + return (Node *) newnode; } break; diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c index e0f4bef..3cb0576 100644 --- a/src/backend/nodes/outfuncs.c +++ b/src/backend/nodes/outfuncs.c @@ -1181,11 +1181,11 @@ _outWindowFunc(StringInfo str, const WindowFunc *node) } static void -_outArrayRef(StringInfo str, const ArrayRef *node) +_outSubscriptingRef(StringInfo str, const SubscriptingRef *node) { - WRITE_NODE_TYPE("ARRAYREF"); + WRITE_NODE_TYPE("SUBSCRIPTINGREF"); - WRITE_OID_FIELD(refarraytype); + WRITE_OID_FIELD(refcontainertype); WRITE_OID_FIELD(refelemtype); WRITE_INT_FIELD(reftypmod); WRITE_OID_FIELD(refcollid); @@ -3797,8 +3797,8 @@ outNode(StringInfo str, const void *obj) case T_WindowFunc: _outWindowFunc(str, obj); break; - case T_ArrayRef: - _outArrayRef(str, obj); + case T_SubscriptingRef: + _outSubscriptingRef(str, obj); break; case T_FuncExpr: _outFuncExpr(str, obj); diff --git a/src/backend/nodes/readfuncs.c b/src/backend/nodes/readfuncs.c index 22d8b9d..99c63ad 100644 --- a/src/backend/nodes/readfuncs.c +++ b/src/backend/nodes/readfuncs.c @@ -640,14 +640,14 @@ _readWindowFunc(void) } /* - * _readArrayRef + * _readSubscriptingRef */ -static ArrayRef * -_readArrayRef(void) +static SubscriptingRef * +_readSubscriptingRef(void) { - READ_LOCALS(ArrayRef); + READ_LOCALS(SubscriptingRef); - READ_OID_FIELD(refarraytype); + READ_OID_FIELD(refcontainertype); READ_OID_FIELD(refelemtype); READ_INT_FIELD(reftypmod); READ_OID_FIELD(refcollid); @@ -2483,8 +2483,8 @@ parseNodeString(void) return_value = _readGroupingFunc(); else if (MATCH("WINDOWFUNC", 10)) return_value = _readWindowFunc(); - else if (MATCH("ARRAYREF", 8)) - return_value = _readArrayRef(); + else if (MATCH("SUBSCRIPTINGREF", 15)) + return_value = _readSubscriptingRef(); else if (MATCH("FUNCEXPR", 8)) return_value = _readFuncExpr(); else if (MATCH("NAMEDARGEXPR", 12)) diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c index 89f27ce..2b01856 100644 --- a/src/backend/optimizer/util/clauses.c +++ b/src/backend/optimizer/util/clauses.c @@ -1348,11 +1348,15 @@ contain_nonstrict_functions_walker(Node *node, void *context) /* a window function could return non-null with null input */ return true; } - if (IsA(node, ArrayRef)) + if (IsA(node, SubscriptingRef)) { - /* array assignment is nonstrict, but subscripting is strict */ - if (((ArrayRef *) node)->refassgnexpr != NULL) + /* + * subscripting assignment is nonstrict, + * but subscripting itself is strict + */ + if (((SubscriptingRef *) node)->refassgnexpr != NULL) return true; + /* else fall through to check args */ } if (IsA(node, DistinctExpr)) @@ -1537,7 +1541,6 @@ contain_leaked_vars_walker(Node *node, void *context) case T_Var: case T_Const: case T_Param: - case T_ArrayRef: case T_ArrayExpr: case T_FieldSelect: case T_FieldStore: @@ -1568,6 +1571,7 @@ contain_leaked_vars_walker(Node *node, void *context) case T_ScalarArrayOpExpr: case T_CoerceViaIO: case T_ArrayCoerceExpr: + case T_SubscriptingRef: /* * If node contains a leaky function call, and there's any Var @@ -3316,7 +3320,7 @@ eval_const_expressions_mutator(Node *node, else return copyObject(node); } - case T_ArrayRef: + case T_SubscriptingRef: case T_ArrayExpr: case T_RowExpr: { diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c index e7b2bc7..ae88a41 100644 --- a/src/backend/parser/analyze.c +++ b/src/backend/parser/analyze.c @@ -965,13 +965,14 @@ transformInsertRow(ParseState *pstate, List *exprlist, expr = (Expr *) linitial(fstore->newvals); } - else if (IsA(expr, ArrayRef)) + else if (IsA(expr, SubscriptingRef)) { - ArrayRef *aref = (ArrayRef *) expr; + SubscriptingRef *sbsref = (SubscriptingRef *) expr; - if (aref->refassgnexpr == NULL) + if (sbsref->refassgnexpr == NULL) break; - expr = aref->refassgnexpr; + + expr = sbsref->refassgnexpr; } else break; diff --git a/src/backend/parser/parse_target.c b/src/backend/parser/parse_target.c index ea209cd..e4c8a83 100644 --- a/src/backend/parser/parse_target.c +++ b/src/backend/parser/parse_target.c @@ -654,7 +654,7 @@ updateTargetListEntry(ParseState *pstate, * needed. * * targetName is the name of the field or subfield we're assigning to, and - * targetIsArray is true if we're subscripting it. These are just for + * targetIsSubscripting is true if we're subscripting it. These are just for * error reporting. * * targetTypeId, targetTypMod, targetCollation indicate the datatype and @@ -676,7 +676,7 @@ static Node * transformAssignmentIndirection(ParseState *pstate, Node *basenode, const char *targetName, - bool targetIsArray, + bool targetIsSubscripting, Oid targetTypeId, int32 targetTypMod, Oid targetCollation, @@ -874,7 +874,7 @@ transformAssignmentIndirection(ParseState *pstate, } /* - * helper for transformAssignmentIndirection: process array assignment + * helper for transformAssignmentIndirection: process container assignment */ static Node * transformAssignmentSubscripts(ParseState *pstate, diff --git a/src/backend/rewrite/rewriteHandler.c b/src/backend/rewrite/rewriteHandler.c index 32e3798..9715fe9 100644 --- a/src/backend/rewrite/rewriteHandler.c +++ b/src/backend/rewrite/rewriteHandler.c @@ -957,7 +957,7 @@ process_matched_tle(TargetEntry *src_tle, /*---------- * Multiple assignments to same attribute. Allow only if all are - * FieldStore or ArrayRef assignment operations. This is a bit + * FieldStore or SubscriptingRef assignment operations. This is a bit * tricky because what we may actually be looking at is a nest of * such nodes; consider * UPDATE tab SET col.fld1.subfld1 = x, col.fld2.subfld2 = y @@ -965,7 +965,7 @@ process_matched_tle(TargetEntry *src_tle, * FieldStore(col, fld1, FieldStore(placeholder, subfld1, x)) * FieldStore(col, fld2, FieldStore(placeholder, subfld2, y)) * However, we can ignore the substructure and just consider the top - * FieldStore or ArrayRef from each assignment, because it works to + * FieldStore or SubscriptingRef from each assignment, because it works to * combine these as * FieldStore(FieldStore(col, fld1, * FieldStore(placeholder, subfld1, x)), @@ -975,7 +975,7 @@ process_matched_tle(TargetEntry *src_tle, * * For FieldStore, instead of nesting we can generate a single * FieldStore with multiple target fields. We must nest when - * ArrayRefs are involved though. + * SubscriptingRefs are involved though. * * As a further complication, the destination column might be a domain, * resulting in each assignment containing a CoerceToDomain node over a @@ -1054,13 +1054,13 @@ process_matched_tle(TargetEntry *src_tle, } newexpr = (Node *) fstore; } - else if (IsA(src_expr, ArrayRef)) + else if (IsA(src_expr, SubscriptingRef)) { - ArrayRef *aref = makeNode(ArrayRef); + SubscriptingRef *sbsref = makeNode(SubscriptingRef); - memcpy(aref, src_expr, sizeof(ArrayRef)); - aref->refexpr = (Expr *) prior_expr; - newexpr = (Node *) aref; + memcpy(sbsref, src_expr, sizeof(SubscriptingRef)); + sbsref->refexpr = (Expr *) prior_expr; + newexpr = (Node *) sbsref; } else { @@ -1097,14 +1097,16 @@ get_assignment_input(Node *node) return (Node *) fstore->arg; } - else if (IsA(node, ArrayRef)) + else if (IsA(node, SubscriptingRef)) { - ArrayRef *aref = (ArrayRef *) node; + SubscriptingRef *sbsref = (SubscriptingRef *) node; - if (aref->refassgnexpr == NULL) + if (sbsref->refassgnexpr == NULL) return NULL; - return (Node *) aref->refexpr; + + return (Node *) sbsref->refexpr; } + return NULL; } diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index c5f5a1c..1333608 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -451,7 +451,7 @@ static void get_tablesample_def(TableSampleClause *tablesample, static void get_opclass_name(Oid opclass, Oid actual_datatype, StringInfo buf); static Node *processIndirection(Node *node, deparse_context *context); -static void printSubscripts(ArrayRef *aref, deparse_context *context); +static void printSubscripts(SubscriptingRef *sbsref, deparse_context *context); static char *get_relation_name(Oid relid); static char *generate_relation_name(Oid relid, List *namespaces); static char *generate_qualified_relation_name(Oid relid); @@ -6256,7 +6256,7 @@ get_update_query_targetlist_def(Query *query, List *targetList, { /* * We must dig down into the expr to see if it's a PARAM_MULTIEXPR - * Param. That could be buried under FieldStores and ArrayRefs + * Param. That could be buried under FieldStores and SubscriptingRefs * and CoerceToDomains (cf processIndirection()), and underneath * those there could be an implicit type coercion. Because we * would ignore implicit type coercions anyway, we don't need to @@ -6272,13 +6272,14 @@ get_update_query_targetlist_def(Query *query, List *targetList, expr = (Node *) linitial(fstore->newvals); } - else if (IsA(expr, ArrayRef)) + else if (IsA(expr, SubscriptingRef)) { - ArrayRef *aref = (ArrayRef *) expr; + SubscriptingRef *sbsref = (SubscriptingRef *) expr; - if (aref->refassgnexpr == NULL) + if (sbsref->refassgnexpr == NULL) break; - expr = (Node *) aref->refassgnexpr; + + expr = (Node *) sbsref->refassgnexpr; } else if (IsA(expr, CoerceToDomain)) { @@ -7310,7 +7311,7 @@ isSimpleNode(Node *node, Node *parentNode, int prettyFlags) /* single words: always simple */ return true; - case T_ArrayRef: + case T_SubscriptingRef: case T_ArrayExpr: case T_RowExpr: case T_CoalesceExpr: @@ -7427,10 +7428,10 @@ isSimpleNode(Node *node, Node *parentNode, int prettyFlags) return false; return true; /* own parentheses */ } - case T_BoolExpr: /* lower precedence */ - case T_ArrayRef: /* other separators */ - case T_ArrayExpr: /* other separators */ - case T_RowExpr: /* other separators */ + case T_BoolExpr: /* lower precedence */ + case T_SubscriptingRef: /* other separators */ + case T_ArrayExpr: /* other separators */ + case T_RowExpr: /* other separators */ case T_CoalesceExpr: /* own parentheses */ case T_MinMaxExpr: /* own parentheses */ case T_XmlExpr: /* own parentheses */ @@ -7478,9 +7479,9 @@ isSimpleNode(Node *node, Node *parentNode, int prettyFlags) return false; return true; /* own parentheses */ } - case T_ArrayRef: /* other separators */ - case T_ArrayExpr: /* other separators */ - case T_RowExpr: /* other separators */ + case T_SubscriptingRef: /* other separators */ + case T_ArrayExpr: /* other separators */ + case T_RowExpr: /* other separators */ case T_CoalesceExpr: /* own parentheses */ case T_MinMaxExpr: /* own parentheses */ case T_XmlExpr: /* own parentheses */ @@ -7664,9 +7665,9 @@ get_rule_expr(Node *node, deparse_context *context, get_windowfunc_expr((WindowFunc *) node, context); break; - case T_ArrayRef: + case T_SubscriptingRef: { - ArrayRef *aref = (ArrayRef *) node; + SubscriptingRef *sbsref = (SubscriptingRef *) node; bool need_parens; /* @@ -7677,24 +7678,24 @@ get_rule_expr(Node *node, deparse_context *context, * here too, and display only the assignment source * expression. */ - if (IsA(aref->refexpr, CaseTestExpr)) + if (IsA(sbsref->refexpr, CaseTestExpr)) { - Assert(aref->refassgnexpr); - get_rule_expr((Node *) aref->refassgnexpr, + Assert(sbsref->refassgnexpr); + get_rule_expr((Node *) sbsref->refassgnexpr, context, showimplicit); break; } /* * Parenthesize the argument unless it's a simple Var or a - * FieldSelect. (In particular, if it's another ArrayRef, we + * FieldSelect. (In particular, if it's another SubscriptingRef, we * *must* parenthesize to avoid confusion.) */ - need_parens = !IsA(aref->refexpr, Var) && - !IsA(aref->refexpr, FieldSelect); + need_parens = !IsA(sbsref->refexpr, Var) && + !IsA(sbsref->refexpr, FieldSelect); if (need_parens) appendStringInfoChar(buf, '('); - get_rule_expr((Node *) aref->refexpr, context, showimplicit); + get_rule_expr((Node *) sbsref->refexpr, context, showimplicit); if (need_parens) appendStringInfoChar(buf, ')'); @@ -7723,8 +7724,8 @@ get_rule_expr(Node *node, deparse_context *context, } else { - /* Just an ordinary array fetch, so print subscripts */ - printSubscripts(aref, context); + /* Just an ordinary container fetch, so print subscripts */ + printSubscripts(sbsref, context); } } break; @@ -7922,12 +7923,13 @@ get_rule_expr(Node *node, deparse_context *context, bool need_parens; /* - * Parenthesize the argument unless it's an ArrayRef or + * Parenthesize the argument unless it's an SubscriptingRef or * another FieldSelect. Note in particular that it would be * WRONG to not parenthesize a Var argument; simplicity is not * the issue here, having the right number of names is. */ - need_parens = !IsA(arg, ArrayRef) &&!IsA(arg, FieldSelect); + need_parens = !IsA(arg, SubscriptingRef) && + !IsA(arg, FieldSelect); if (need_parens) appendStringInfoChar(buf, '('); get_rule_expr(arg, context, true); @@ -10296,7 +10298,7 @@ get_opclass_name(Oid opclass, Oid actual_datatype, /* * processIndirection - take care of array and subfield assignment * - * We strip any top-level FieldStore or assignment ArrayRef nodes that + * We strip any top-level FieldStore or assignment SubscriptingRef nodes that * appear in the input, printing them as decoration for the base column * name (which we assume the caller just printed). We might also need to * strip CoerceToDomain nodes, but only ones that appear above assignment @@ -10342,19 +10344,20 @@ processIndirection(Node *node, deparse_context *context) */ node = (Node *) linitial(fstore->newvals); } - else if (IsA(node, ArrayRef)) + else if (IsA(node, SubscriptingRef)) { - ArrayRef *aref = (ArrayRef *) node; + SubscriptingRef *sbsref = (SubscriptingRef *) node; - if (aref->refassgnexpr == NULL) + if (sbsref->refassgnexpr == NULL) break; - printSubscripts(aref, context); + + printSubscripts(sbsref, context); /* * We ignore refexpr since it should be an uninteresting reference * to the target column or subcolumn. */ - node = (Node *) aref->refassgnexpr; + node = (Node *) sbsref->refassgnexpr; } else if (IsA(node, CoerceToDomain)) { @@ -10382,14 +10385,14 @@ processIndirection(Node *node, deparse_context *context) } static void -printSubscripts(ArrayRef *aref, deparse_context *context) +printSubscripts(SubscriptingRef *sbsref, deparse_context *context) { StringInfo buf = context->buf; ListCell *lowlist_item; ListCell *uplist_item; - lowlist_item = list_head(aref->reflowerindexpr); /* could be NULL */ - foreach(uplist_item, aref->refupperindexpr) + lowlist_item = list_head(sbsref->reflowerindexpr); /* could be NULL */ + foreach(uplist_item, sbsref->refupperindexpr) { appendStringInfoChar(buf, '['); if (lowlist_item) diff --git a/src/include/executor/execExpr.h b/src/include/executor/execExpr.h index 117fc89..05f2abf 100644 --- a/src/include/executor/execExpr.h +++ b/src/include/executor/execExpr.h @@ -184,21 +184,21 @@ typedef enum ExprEvalOp */ EEOP_FIELDSTORE_FORM, - /* Process an array subscript; short-circuit expression to NULL if NULL */ - EEOP_ARRAYREF_SUBSCRIPT, + /* Process a container subscript; short-circuit expression to NULL if NULL */ + EEOP_SBSREF_SUBSCRIPT, /* - * Compute old array element/slice when an ArrayRef assignment expression - * contains ArrayRef/FieldStore subexpressions. Value is accessed using - * the CaseTest mechanism. + * Compute old container element/slice when a SubscriptingRef assignment + * expression contains SubscriptingRef/FieldStore subexpressions. Value is + * accessed using the CaseTest mechanism. */ - EEOP_ARRAYREF_OLD, + EEOP_SBSREF_OLD, - /* compute new value for ArrayRef assignment expression */ - EEOP_ARRAYREF_ASSIGN, + /* compute new value for SubscriptingRef assignment expression */ + EEOP_SBSREF_ASSIGN, - /* compute element/slice for ArrayRef fetch expression */ - EEOP_ARRAYREF_FETCH, + /* compute element/slice for SubscriptingRef fetch expression */ + EEOP_SBSREF_FETCH, /* evaluate value for CoerceToDomainValue */ EEOP_DOMAIN_TESTVAL, @@ -484,22 +484,22 @@ typedef struct ExprEvalStep int ncolumns; } fieldstore; - /* for EEOP_ARRAYREF_SUBSCRIPT */ + /* for EEOP_SBSREF_SUBSCRIPT */ struct { /* too big to have inline */ - struct ArrayRefState *state; + struct SubscriptingRefState *state; int off; /* 0-based index of this subscript */ bool isupper; /* is it upper or lower subscript? */ int jumpdone; /* jump here on null */ - } arrayref_subscript; + } sbsref_subscript; - /* for EEOP_ARRAYREF_OLD / ASSIGN / FETCH */ + /* for EEOP_SBSREF_OLD / ASSIGN / FETCH */ struct { /* too big to have inline */ - struct ArrayRefState *state; - } arrayref; + struct SubscriptingRefState *state; + } sbsref; /* for EEOP_DOMAIN_NOTNULL / DOMAIN_CHECK */ struct @@ -637,15 +637,14 @@ typedef struct ExprEvalStep } d; } ExprEvalStep; - -/* Non-inline data for array operations */ -typedef struct ArrayRefState +/* Non-inline data for container operations */ +typedef struct SubscriptingRefState { bool isassignment; /* is it assignment, or just fetch? */ - Oid refelemtype; /* OID of the array element type */ - int16 refattrlength; /* typlen of array type */ - int16 refelemlength; /* typlen of the array element type */ + Oid refelemtype; /* OID of the container element type */ + int16 refattrlength; /* typlen of container type */ + int16 refelemlength; /* typlen of the container element type */ bool refelembyval; /* is the element type pass-by-value? */ char refelemalign; /* typalign of the element type */ @@ -668,11 +667,11 @@ typedef struct ArrayRefState Datum replacevalue; bool replacenull; - /* if we have a nested assignment, ARRAYREF_OLD puts old value here */ + /* if we have a nested assignment, SBSREF_OLD puts old value here */ Datum prevvalue; bool prevnull; -} ArrayRefState; +} SubscriptingRefState; /* functions in execExpr.c */ extern void ExprEvalPushStep(ExprState *es, const ExprEvalStep *s); @@ -712,10 +711,10 @@ extern void ExecEvalFieldStoreDeForm(ExprState *state, ExprEvalStep *op, ExprContext *econtext); extern void ExecEvalFieldStoreForm(ExprState *state, ExprEvalStep *op, ExprContext *econtext); -extern bool ExecEvalArrayRefSubscript(ExprState *state, ExprEvalStep *op); -extern void ExecEvalArrayRefFetch(ExprState *state, ExprEvalStep *op); -extern void ExecEvalArrayRefOld(ExprState *state, ExprEvalStep *op); -extern void ExecEvalArrayRefAssign(ExprState *state, ExprEvalStep *op); +extern bool ExecEvalSubscriptingRef(ExprState *state, ExprEvalStep *op); +extern void ExecEvalSubscriptingRefFetch(ExprState *state, ExprEvalStep *op); +extern void ExecEvalSubscriptingRefOld(ExprState *state, ExprEvalStep *op); +extern void ExecEvalSubscriptingRefAssign(ExprState *state, ExprEvalStep *op); extern void ExecEvalConvertRowtype(ExprState *state, ExprEvalStep *op, ExprContext *econtext); extern void ExecEvalScalarArrayOp(ExprState *state, ExprEvalStep *op); diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h index 74b094a..9cbfb3c 100644 --- a/src/include/nodes/nodes.h +++ b/src/include/nodes/nodes.h @@ -149,7 +149,7 @@ typedef enum NodeTag T_Aggref, T_GroupingFunc, T_WindowFunc, - T_ArrayRef, + T_SubscriptingRef, T_FuncExpr, T_NamedArgExpr, T_OpExpr, diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index 76a73b2..a17935d 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -223,7 +223,7 @@ typedef struct TypeName * Currently, A_Star must appear only as the last list element --- the grammar * is responsible for enforcing this! * - * Note: any array subscripting or selection of fields from composite columns + * Note: any container subscripting or selection of fields from composite columns * is represented by an A_Indirection node above the ColumnRef. However, * for simplicity in the normal case, initial field selection from a table * name is represented within ColumnRef and not by adding A_Indirection. diff --git a/src/include/nodes/primnodes.h b/src/include/nodes/primnodes.h index 1b4b0d7..93719ad 100644 --- a/src/include/nodes/primnodes.h +++ b/src/include/nodes/primnodes.h @@ -752,7 +752,7 @@ typedef struct FieldSelect * * FieldStore represents the operation of modifying one field in a tuple * value, yielding a new tuple value (the input is not touched!). Like - * the assign case of ArrayRef, this is used to implement UPDATE of a + * the assign case of SubscriptingRef, this is used to implement UPDATE of a * portion of a column. * * resulttype is always a named composite type (not a domain). To update diff --git a/src/pl/plpgsql/src/pl_exec.c b/src/pl/plpgsql/src/pl_exec.c index 4478c53..6f980c4 100644 --- a/src/pl/plpgsql/src/pl_exec.c +++ b/src/pl/plpgsql/src/pl_exec.c @@ -4697,7 +4697,7 @@ exec_assign_value(PLpgSQL_execstate *estate, /* * Evaluate the subscripts, switch into left-to-right order. - * Like the expression built by ExecInitArrayRef(), complain + * Like the expression built by ExecInitSubscriptingRef(), complain * if any subscript is null. */ for (i = 0; i < nsubscripts; i++) -- 2.7.4