aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlvaro Herrera <alvherre@alvh.no-ip.org>2019-02-01 12:50:32 -0300
committerAlvaro Herrera <alvherre@alvh.no-ip.org>2019-02-01 12:50:32 -0300
commit558d77f20e4e9ed18101d5d057b770ae22ece855 (patch)
treec65b6dff674f7f6a46a391683e281a51839162c1
parentf831d4accda00b9144bc647ede2e2f848b59f39d (diff)
downloadpostgresql-558d77f20e4e9ed18101d5d057b770ae22ece855.tar.gz
postgresql-558d77f20e4e9ed18101d5d057b770ae22ece855.zip
Renaming for new subscripting mechanism
Over at patch https://commitfest.postgresql.org/21/1062/ Dmitry wants to introduce a more generic subscription mechanism, which allows subscripting not only arrays but also other object types such as JSONB. That functionality is introduced in a largish invasive patch, out of which this internal renaming patch was extracted. Author: Dmitry Dolgov Reviewed-by: Tom Lane, Arthur Zakirov Discussion: https://postgr.es/m/CA+q6zcUK4EqPAu7XRRO5CCjMwhz5zvg+rfWuLzVoxp_5sKS6=w@mail.gmail.com
-rw-r--r--contrib/pg_stat_statements/pg_stat_statements.c12
-rw-r--r--contrib/postgres_fdw/deparse.c30
-rw-r--r--src/backend/executor/execExpr.c175
-rw-r--r--src/backend/executor/execExprInterp.c214
-rw-r--r--src/backend/jit/llvm/llvmjit.c4
-rw-r--r--src/backend/jit/llvm/llvmjit_expr.c18
-rw-r--r--src/backend/jit/llvm/llvmjit_types.c2
-rw-r--r--src/backend/nodes/copyfuncs.c14
-rw-r--r--src/backend/nodes/equalfuncs.c8
-rw-r--r--src/backend/nodes/nodeFuncs.c64
-rw-r--r--src/backend/nodes/outfuncs.c10
-rw-r--r--src/backend/nodes/readfuncs.c14
-rw-r--r--src/backend/optimizer/util/clauses.c14
-rw-r--r--src/backend/parser/analyze.c9
-rw-r--r--src/backend/parser/parse_expr.c28
-rw-r--r--src/backend/parser/parse_node.c167
-rw-r--r--src/backend/parser/parse_target.c52
-rw-r--r--src/backend/rewrite/rewriteHandler.c26
-rw-r--r--src/backend/utils/adt/ruleutils.c88
-rw-r--r--src/include/executor/execExpr.h56
-rw-r--r--src/include/jit/llvmjit.h2
-rw-r--r--src/include/nodes/nodes.h2
-rw-r--r--src/include/nodes/parsenodes.h2
-rw-r--r--src/include/nodes/primnodes.h54
-rw-r--r--src/include/parser/parse_node.h17
-rw-r--r--src/pl/plpgsql/src/pl_exec.c4
26 files changed, 559 insertions, 527 deletions
diff --git a/contrib/pg_stat_statements/pg_stat_statements.c b/contrib/pg_stat_statements/pg_stat_statements.c
index 96d98285fd4..ea2e4bc2425 100644
--- a/contrib/pg_stat_statements/pg_stat_statements.c
+++ b/contrib/pg_stat_statements/pg_stat_statements.c
@@ -2579,14 +2579,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 b0e44e5562f..92a0ab6da5a 100644
--- a/contrib/postgres_fdw/deparse.c
+++ b/contrib/postgres_fdw/deparse.c
@@ -149,7 +149,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);
@@ -401,34 +401,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,
- * but for safety use same logic as for function nodes.
+ * 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 &&
@@ -2270,8 +2270,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);
@@ -2518,10 +2518,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 e52b8063728..db3777d15ef 100644
--- a/src/backend/executor/execExpr.c
+++ b/src/backend/executor/execExpr.c
@@ -67,9 +67,10 @@ static bool get_last_attnums_walker(Node *node, LastAttnumInfo *info);
static void ExecComputeSlotInfo(ExprState *state, ExprEvalStep *op);
static void ExecInitWholeRowVar(ExprEvalStep *scratch, Var *variable,
ExprState *state);
-static void ExecInitArrayRef(ExprEvalStep *scratch, ArrayRef *aref,
- ExprState *state,
- Datum *resv, bool *resnull);
+static void ExecInitSubscriptingRef(ExprEvalStep *scratch,
+ SubscriptingRef *sbsref,
+ ExprState *state,
+ Datum *resv, bool *resnull);
static bool isAssignmentIndirectionExpr(Expr *expr);
static void ExecInitCoerceToDomain(ExprEvalStep *scratch, CoerceToDomain *ctest,
ExprState *state,
@@ -867,11 +868,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;
}
@@ -1186,13 +1187,14 @@ 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
- * 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
- * field assignment can't be within a CASE either. (So
- * saving and restoring innermost_caseval is just
- * paranoia, but let's do it anyway.)
+ * 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 field assignment can't be within
+ * a CASE either. (So saving and restoring
+ * innermost_caseval is just paranoia, but let's do it
+ * anyway.)
*
* Another non-obvious point is that it's safe to use the
* field's values[]/nulls[] entries as both the caseval
@@ -2528,34 +2530,34 @@ ExecInitWholeRowVar(ExprEvalStep *scratch, Var *variable, ExprState *state)
}
/*
- * Prepare evaluation of an ArrayRef expression.
+ * Prepare evaluation of a SubscriptingRef expression.
*/
static void
-ExecInitArrayRef(ExprEvalStep *scratch, ArrayRef *aref,
- ExprState *state, Datum *resv, bool *resnull)
+ExecInitSubscriptingRef(ExprEvalStep *scratch, SubscriptingRef *sbsref,
+ ExprState *state, Datum *resv, bool *resnull)
{
- bool isAssignment = (aref->refassgnexpr != NULL);
- ArrayRefState *arefstate = palloc0(sizeof(ArrayRefState));
+ bool isAssignment = (sbsref->refassgnexpr != NULL);
+ SubscriptingRefState *sbsrefstate = palloc0(sizeof(SubscriptingRefState));
List *adjust_jumps = NIL;
ListCell *lc;
int i;
- /* Fill constant fields of ArrayRefState */
- arefstate->isassignment = isAssignment;
- arefstate->refelemtype = aref->refelemtype;
- arefstate->refattrlength = get_typlen(aref->refarraytype);
- get_typlenbyvalalign(aref->refelemtype,
- &arefstate->refelemlength,
- &arefstate->refelembyval,
- &arefstate->refelemalign);
+ /* Fill constant fields of SubscriptingRefState */
+ sbsrefstate->isassignment = isAssignment;
+ sbsrefstate->refelemtype = sbsref->refelemtype;
+ sbsrefstate->refattrlength = get_typlen(sbsref->refcontainertype);
+ get_typlenbyvalalign(sbsref->refelemtype,
+ &sbsrefstate->refelemlength,
+ &sbsrefstate->refelembyval,
+ &sbsrefstate->refelemalign);
/*
* Evaluate array input. It's safe to do so into resv/resnull, because we
* won't use that as target for any of the other subexpressions, and it'll
- * be overwritten by the final EEOP_ARRAYREF_FETCH/ASSIGN step, which is
+ * be overwritten by the final EEOP_SBSREF_FETCH/ASSIGN step, which is
* pushed last.
*/
- ExecInitExprRec(aref->refexpr, state, resv, resnull);
+ ExecInitExprRec(sbsref->refexpr, state, resv, resnull);
/*
* If refexpr yields NULL, and it's a fetch, then result is NULL. We can
@@ -2572,87 +2574,87 @@ ExecInitArrayRef(ExprEvalStep *scratch, ArrayRef *aref,
}
/* Verify subscript list lengths are within limit */
- if (list_length(aref->refupperindexpr) > MAXDIM)
+ if (list_length(sbsref->refupperindexpr) > MAXDIM)
ereport(ERROR,
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
errmsg("number of array dimensions (%d) exceeds the maximum allowed (%d)",
- list_length(aref->refupperindexpr), MAXDIM)));
+ list_length(sbsref->refupperindexpr), MAXDIM)));
- if (list_length(aref->reflowerindexpr) > MAXDIM)
+ if (list_length(sbsref->reflowerindexpr) > MAXDIM)
ereport(ERROR,
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
errmsg("number of array dimensions (%d) exceeds the maximum allowed (%d)",
- list_length(aref->reflowerindexpr), MAXDIM)));
+ list_length(sbsref->reflowerindexpr), MAXDIM)));
/* 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)
@@ -2662,49 +2664,51 @@ 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
- * 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
- * to reuse the CASE mechanism because there cannot be a CASE between
- * here and where the value would be needed, and an array assignment
- * can't be within a CASE either. (So saving and restoring
+ * 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 to reuse the CASE mechanism because there cannot be a CASE
+ * between here and where the value would be needed, and an array
+ * assignment can't be within a CASE either. (So saving and restoring
* innermost_caseval is just paranoia, but let's do it anyway.)
*
* 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);
+
}
/* adjust jump targets */
@@ -2712,10 +2716,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
{
@@ -2727,8 +2731,9 @@ 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.)
@@ -2751,11 +2756,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 5c5f655645d..a018925d4ed 100644
--- a/src/backend/executor/execExprInterp.c
+++ b/src/backend/executor/execExprInterp.c
@@ -370,10 +370,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,
@@ -1347,43 +1347,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();
}
@@ -1391,10 +1391,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();
}
@@ -3044,27 +3044,27 @@ ExecEvalFieldStoreForm(ExprState *state, ExprEvalStep *op, ExprContext *econtext
}
/*
- * Process a subscript in an ArrayRef expression.
+ * Process a subscript in a SubscriptingRef expression.
*
* If subscript is NULL, throw error in assignment case, or in fetch case
* set result to NULL and return false (instructing caller to skip the rest
- * of the ArrayRef sequence).
+ * of the SubscriptingRef sequence).
*
* Subscript expression result is in subscriptvalue/subscriptnull.
* On success, integer subscript value has been saved in upperindex[] or
* lowerindex[] for use later.
*/
bool
-ExecEvalArrayRefSubscript(ExprState *state, ExprEvalStep *op)
+ExecEvalSubscriptingRef(ExprState *state, ExprEvalStep *op)
{
- ArrayRefState *arefstate = op->d.arrayref_subscript.state;
+ SubscriptingRefState *sbsrefstate = op->d.sbsref_subscript.state;
int *indexes;
int off;
/* If any index expr yields NULL, result is NULL or error */
- if (arefstate->subscriptnull)
+ if (sbsrefstate->subscriptnull)
{
- if (arefstate->isassignment)
+ if (sbsrefstate->isassignment)
ereport(ERROR,
(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
errmsg("array subscript in assignment must not be null")));
@@ -3073,124 +3073,124 @@ ExecEvalArrayRefSubscript(ExprState *state, ExprEvalStep *op)
}
/* Convert datum to int, save in appropriate place */
- if (op->d.arrayref_subscript.isupper)
- indexes = arefstate->upperindex;
+ if (op->d.sbsref_subscript.isupper)
+ indexes = sbsrefstate->upperindex;
else
- indexes = arefstate->lowerindex;
- off = op->d.arrayref_subscript.off;
+ indexes = sbsrefstate->lowerindex;
+ off = op->d.sbsref_subscript.off;
- indexes[off] = DatumGetInt32(arefstate->subscriptvalue);
+ indexes[off] = DatumGetInt32(sbsrefstate->subscriptvalue);
return true;
}
/*
- * Evaluate ArrayRef fetch.
+ * Evaluate SubscriptingRef fetch.
*
- * Source array is in step's result variable.
+ * Source container is in step's result variable.
*/
void
-ExecEvalArrayRefFetch(ExprState *state, ExprEvalStep *op)
+ExecEvalSubscriptingRefFetch(ExprState *state, ExprEvalStep *op)
{
- ArrayRefState *arefstate = op->d.arrayref.state;
+ SubscriptingRefState *sbsrefstate = op->d.sbsref.state;
- /* Should not get here if source array (or any subscript) is null */
+ /* Should not get here if source container (or any subscript) is null */
Assert(!(*op->resnull));
- if (arefstate->numlower == 0)
+ if (sbsrefstate->numlower == 0)
{
/* Scalar case */
*op->resvalue = array_get_element(*op->resvalue,
- arefstate->numupper,
- arefstate->upperindex,
- arefstate->refattrlength,
- arefstate->refelemlength,
- arefstate->refelembyval,
- arefstate->refelemalign,
+ sbsrefstate->numupper,
+ sbsrefstate->upperindex,
+ sbsrefstate->refattrlength,
+ sbsrefstate->refelemlength,
+ sbsrefstate->refelembyval,
+ sbsrefstate->refelemalign,
op->resnull);
}
else
{
/* Slice case */
*op->resvalue = array_get_slice(*op->resvalue,
- arefstate->numupper,
- arefstate->upperindex,
- arefstate->lowerindex,
- arefstate->upperprovided,
- arefstate->lowerprovided,
- arefstate->refattrlength,
- arefstate->refelemlength,
- arefstate->refelembyval,
- arefstate->refelemalign);
+ sbsrefstate->numupper,
+ sbsrefstate->upperindex,
+ sbsrefstate->lowerindex,
+ sbsrefstate->upperprovided,
+ sbsrefstate->lowerprovided,
+ sbsrefstate->refattrlength,
+ sbsrefstate->refelemlength,
+ sbsrefstate->refelembyval,
+ sbsrefstate->refelemalign);
}
}
/*
- * Compute old array element/slice value for an ArrayRef assignment
- * expression. Will only be generated if the new-value subexpression
- * contains ArrayRef or FieldStore. The value is stored into the
- * ArrayRefState's prevvalue/prevnull fields.
+ * Compute old container element/slice value for a SubscriptingRef assignment
+ * expression. Will only be generated if the new-value subexpression
+ * contains SubscriptingRef or FieldStore. The value is stored into the
+ * SubscriptingRefState's prevvalue/prevnull fields.
*/
void
-ExecEvalArrayRefOld(ExprState *state, ExprEvalStep *op)
+ExecEvalSubscriptingRefOld(ExprState *state, ExprEvalStep *op)
{
- ArrayRefState *arefstate = op->d.arrayref.state;
+ SubscriptingRefState *sbsrefstate = op->d.sbsref.state;
if (*op->resnull)
{
/* whole array is null, so any element or slice is too */
- arefstate->prevvalue = (Datum) 0;
- arefstate->prevnull = true;
+ sbsrefstate->prevvalue = (Datum) 0;
+ sbsrefstate->prevnull = true;
}
- else if (arefstate->numlower == 0)
+ else if (sbsrefstate->numlower == 0)
{
/* Scalar case */
- arefstate->prevvalue = array_get_element(*op->resvalue,
- arefstate->numupper,
- arefstate->upperindex,
- arefstate->refattrlength,
- arefstate->refelemlength,
- arefstate->refelembyval,
- arefstate->refelemalign,
- &arefstate->prevnull);
+ sbsrefstate->prevvalue = array_get_element(*op->resvalue,
+ sbsrefstate->numupper,
+ sbsrefstate->upperindex,
+ sbsrefstate->refattrlength,
+ sbsrefstate->refelemlength,
+ sbsrefstate->refelembyval,
+ sbsrefstate->refelemalign,
+ &sbsrefstate->prevnull);
}
else
{
/* Slice case */
/* this is currently unreachable */
- arefstate->prevvalue = array_get_slice(*op->resvalue,
- arefstate->numupper,
- arefstate->upperindex,
- arefstate->lowerindex,
- arefstate->upperprovided,
- arefstate->lowerprovided,
- arefstate->refattrlength,
- arefstate->refelemlength,
- arefstate->refelembyval,
- arefstate->refelemalign);
- arefstate->prevnull = false;
+ sbsrefstate->prevvalue = array_get_slice(*op->resvalue,
+ sbsrefstate->numupper,
+ sbsrefstate->upperindex,
+ sbsrefstate->lowerindex,
+ sbsrefstate->upperprovided,
+ sbsrefstate->lowerprovided,
+ sbsrefstate->refattrlength,
+ sbsrefstate->refelemlength,
+ sbsrefstate->refelembyval,
+ sbsrefstate->refelemalign);
+ sbsrefstate->prevnull = false;
}
}
/*
- * Evaluate ArrayRef assignment.
+ * Evaluate SubscriptingRef assignment.
*
- * Input array (possibly null) is in result area, replacement value is in
- * ArrayRefState's replacevalue/replacenull.
+ * Input container (possibly null) is in result area, replacement value is in
+ * SubscriptingRefState's replacevalue/replacenull.
*/
void
-ExecEvalArrayRefAssign(ExprState *state, ExprEvalStep *op)
+ExecEvalSubscriptingRefAssign(ExprState *state, ExprEvalStep *op)
{
- ArrayRefState *arefstate = op->d.arrayref.state;
+ SubscriptingRefState *sbsrefstate = op->d.sbsref_subscript.state;
/*
- * For an assignment to a fixed-length array type, both the original array
- * and the value to be assigned into it must be non-NULL, else we punt and
- * return the original array.
+ * For an assignment to a fixed-length container type, both the original
+ * container and the value to be assigned into it must be non-NULL, else
+ * we punt and return the original container.
*/
- if (arefstate->refattrlength > 0) /* fixed-length array? */
+ if (sbsrefstate->refattrlength > 0)
{
- if (*op->resnull || arefstate->replacenull)
+ if (*op->resnull || sbsrefstate->replacenull)
return;
}
@@ -3202,38 +3202,38 @@ ExecEvalArrayRefAssign(ExprState *state, ExprEvalStep *op)
*/
if (*op->resnull)
{
- *op->resvalue = PointerGetDatum(construct_empty_array(arefstate->refelemtype));
+ *op->resvalue = PointerGetDatum(construct_empty_array(sbsrefstate->refelemtype));
*op->resnull = false;
}
- if (arefstate->numlower == 0)
+ if (sbsrefstate->numlower == 0)
{
/* Scalar case */
*op->resvalue = array_set_element(*op->resvalue,
- arefstate->numupper,
- arefstate->upperindex,
- arefstate->replacevalue,
- arefstate->replacenull,
- arefstate->refattrlength,
- arefstate->refelemlength,
- arefstate->refelembyval,
- arefstate->refelemalign);
+ sbsrefstate->numupper,
+ sbsrefstate->upperindex,
+ sbsrefstate->replacevalue,
+ sbsrefstate->replacenull,
+ sbsrefstate->refattrlength,
+ sbsrefstate->refelemlength,
+ sbsrefstate->refelembyval,
+ sbsrefstate->refelemalign);
}
else
{
/* Slice case */
*op->resvalue = array_set_slice(*op->resvalue,
- arefstate->numupper,
- arefstate->upperindex,
- arefstate->lowerindex,
- arefstate->upperprovided,
- arefstate->lowerprovided,
- arefstate->replacevalue,
- arefstate->replacenull,
- arefstate->refattrlength,
- arefstate->refelemlength,
- arefstate->refelembyval,
- arefstate->refelemalign);
+ sbsrefstate->numupper,
+ sbsrefstate->upperindex,
+ sbsrefstate->lowerindex,
+ sbsrefstate->upperprovided,
+ sbsrefstate->lowerprovided,
+ sbsrefstate->replacevalue,
+ sbsrefstate->replacenull,
+ sbsrefstate->refattrlength,
+ sbsrefstate->refelemlength,
+ sbsrefstate->refelembyval,
+ sbsrefstate->refelemalign);
}
}
diff --git a/src/backend/jit/llvm/llvmjit.c b/src/backend/jit/llvm/llvmjit.c
index c4d38a64a44..82c4afb7011 100644
--- a/src/backend/jit/llvm/llvmjit.c
+++ b/src/backend/jit/llvm/llvmjit.c
@@ -85,7 +85,7 @@ LLVMValueRef FuncVarsizeAny;
LLVMValueRef FuncSlotGetsomeattrsInt;
LLVMValueRef FuncSlotGetmissingattrs;
LLVMValueRef FuncMakeExpandedObjectReadOnlyInternal;
-LLVMValueRef FuncExecEvalArrayRefSubscript;
+LLVMValueRef FuncExecEvalSubscriptingRef;
LLVMValueRef FuncExecEvalSysVar;
LLVMValueRef FuncExecAggTransReparent;
LLVMValueRef FuncExecAggInitGroup;
@@ -829,7 +829,7 @@ llvm_create_types(void)
FuncSlotGetsomeattrsInt = LLVMGetNamedFunction(mod, "slot_getsomeattrs_int");
FuncSlotGetmissingattrs = LLVMGetNamedFunction(mod, "slot_getmissingattrs");
FuncMakeExpandedObjectReadOnlyInternal = LLVMGetNamedFunction(mod, "MakeExpandedObjectReadOnlyInternal");
- FuncExecEvalArrayRefSubscript = LLVMGetNamedFunction(mod, "ExecEvalArrayRefSubscript");
+ FuncExecEvalSubscriptingRef = LLVMGetNamedFunction(mod, "ExecEvalSubscriptingRef");
FuncExecEvalSysVar = LLVMGetNamedFunction(mod, "ExecEvalSysVar");
FuncExecAggTransReparent = LLVMGetNamedFunction(mod, "ExecAggTransReparent");
FuncExecAggInitGroup = LLVMGetNamedFunction(mod, "ExecAggInitGroup");
diff --git a/src/backend/jit/llvm/llvmjit_expr.c b/src/backend/jit/llvm/llvmjit_expr.c
index df7e620da71..1bb58e3e61a 100644
--- a/src/backend/jit/llvm/llvmjit_expr.c
+++ b/src/backend/jit/llvm/llvmjit_expr.c
@@ -1144,20 +1144,20 @@ llvm_compile_expr(ExprState *state)
break;
}
- case EEOP_ARRAYREF_OLD:
- build_EvalXFunc(b, mod, "ExecEvalArrayRefOld",
+ case EEOP_SBSREF_OLD:
+ build_EvalXFunc(b, mod, "ExecEvalSubscriptingRefOld",
v_state, v_econtext, op);
LLVMBuildBr(b, opblocks[i + 1]);
break;
- case EEOP_ARRAYREF_ASSIGN:
- build_EvalXFunc(b, mod, "ExecEvalArrayRefAssign",
+ case EEOP_SBSREF_ASSIGN:
+ build_EvalXFunc(b, mod, "ExecEvalSubscriptingRefAssign",
v_state, v_econtext, op);
LLVMBuildBr(b, opblocks[i + 1]);
break;
- case EEOP_ARRAYREF_FETCH:
- build_EvalXFunc(b, mod, "ExecEvalArrayRefFetch",
+ case EEOP_SBSREF_FETCH:
+ build_EvalXFunc(b, mod, "ExecEvalSubscriptingRefFetch",
v_state, v_econtext, op);
LLVMBuildBr(b, opblocks[i + 1]);
break;
@@ -1775,14 +1775,14 @@ llvm_compile_expr(ExprState *state)
LLVMBuildBr(b, opblocks[i + 1]);
break;
- case EEOP_ARRAYREF_SUBSCRIPT:
+ case EEOP_SBSREF_SUBSCRIPT:
{
LLVMValueRef v_fn;
- int jumpdone = op->d.arrayref_subscript.jumpdone;
+ int jumpdone = op->d.sbsref_subscript.jumpdone;
LLVMValueRef v_params[2];
LLVMValueRef v_ret;
- v_fn = llvm_get_decl(mod, FuncExecEvalArrayRefSubscript);
+ v_fn = llvm_get_decl(mod, FuncExecEvalSubscriptingRef);
v_params[0] = v_state;
v_params[1] = l_ptr_const(op, l_ptr(StructExprEvalStep));
diff --git a/src/backend/jit/llvm/llvmjit_types.c b/src/backend/jit/llvm/llvmjit_types.c
index c814bc7b3ee..9522b972c1a 100644
--- a/src/backend/jit/llvm/llvmjit_types.c
+++ b/src/backend/jit/llvm/llvmjit_types.c
@@ -103,7 +103,7 @@ void *referenced_functions[] =
slot_getsomeattrs_int,
slot_getmissingattrs,
MakeExpandedObjectReadOnlyInternal,
- ExecEvalArrayRefSubscript,
+ ExecEvalSubscriptingRef,
ExecEvalSysVar,
ExecAggTransReparent,
ExecAggInitGroup
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index 807393dfaa4..b44ead269f6 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -1486,14 +1486,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);
@@ -4963,8 +4963,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 a397de155eb..1e169e0b9c9 100644
--- a/src/backend/nodes/equalfuncs.c
+++ b/src/backend/nodes/equalfuncs.c
@@ -265,9 +265,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);
@@ -3041,8 +3041,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 1275c7168fe..2385d026026 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;
+ /* slice and/or store operations yield the container type */
+ if (sbsref->reflowerindexpr || sbsref->refassgnexpr)
+ type = sbsref->refcontainertype;
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;
@@ -992,8 +992,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;
@@ -1223,9 +1223,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:
{
@@ -1916,21 +1916,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;
@@ -2554,20 +2555,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 9d44e3e4c63..f97cf37f1f8 100644
--- a/src/backend/nodes/outfuncs.c
+++ b/src/backend/nodes/outfuncs.c
@@ -1153,11 +1153,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);
@@ -3789,8 +3789,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 43491e297b0..3b002778ad0 100644
--- a/src/backend/nodes/readfuncs.c
+++ b/src/backend/nodes/readfuncs.c
@@ -657,14 +657,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);
@@ -2597,8 +2597,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 86c346bc389..663fa7cd339 100644
--- a/src/backend/optimizer/util/clauses.c
+++ b/src/backend/optimizer/util/clauses.c
@@ -1120,11 +1120,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))
@@ -1328,7 +1332,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:
@@ -1358,6 +1361,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
@@ -3181,7 +3185,7 @@ eval_const_expressions_mutator(Node *node,
else
return copyObject(node);
}
- case T_ArrayRef:
+ case T_SubscriptingRef:
case T_ArrayExpr:
case T_RowExpr:
case T_MinMaxExpr:
diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c
index 125ee5d84b2..7f5773582b0 100644
--- a/src/backend/parser/analyze.c
+++ b/src/backend/parser/analyze.c
@@ -976,13 +976,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_expr.c b/src/backend/parser/parse_expr.c
index 7fc8d63ff0e..e5593535292 100644
--- a/src/backend/parser/parse_expr.c
+++ b/src/backend/parser/parse_expr.c
@@ -465,13 +465,13 @@ transformIndirection(ParseState *pstate, A_Indirection *ind)
/* process subscripts before this field selection */
if (subscripts)
- result = (Node *) transformArraySubscripts(pstate,
- result,
- exprType(result),
- InvalidOid,
- exprTypmod(result),
- subscripts,
- NULL);
+ result = (Node *) transformContainerSubscripts(pstate,
+ result,
+ exprType(result),
+ InvalidOid,
+ exprTypmod(result),
+ subscripts,
+ NULL);
subscripts = NIL;
newresult = ParseFuncOrColumn(pstate,
@@ -488,13 +488,13 @@ transformIndirection(ParseState *pstate, A_Indirection *ind)
}
/* process trailing subscripts, if any */
if (subscripts)
- result = (Node *) transformArraySubscripts(pstate,
- result,
- exprType(result),
- InvalidOid,
- exprTypmod(result),
- subscripts,
- NULL);
+ result = (Node *) transformContainerSubscripts(pstate,
+ result,
+ exprType(result),
+ InvalidOid,
+ exprTypmod(result),
+ subscripts,
+ NULL);
return result;
}
diff --git a/src/backend/parser/parse_node.c b/src/backend/parser/parse_node.c
index ece81697e6a..3a7a858e3ad 100644
--- a/src/backend/parser/parse_node.c
+++ b/src/backend/parser/parse_node.c
@@ -203,121 +203,126 @@ make_var(ParseState *pstate, RangeTblEntry *rte, int attrno, int location)
}
/*
- * transformArrayType()
- * Identify the types involved in a subscripting operation
+ * transformContainerType()
+ * Identify the types involved in a subscripting operation for container
*
- * On entry, arrayType/arrayTypmod identify the type of the input value
- * to be subscripted (which could be a domain type). These are modified
- * if necessary to identify the actual array type and typmod, and the
- * array's element type is returned. An error is thrown if the input isn't
+ *
+ * On entry, containerType/containerTypmod identify the type of the input value
+ * to be subscripted (which could be a domain type). These are modified if
+ * necessary to identify the actual container type and typmod, and the
+ * container's element type is returned. An error is thrown if the input isn't
* an array type.
*/
Oid
-transformArrayType(Oid *arrayType, int32 *arrayTypmod)
+transformContainerType(Oid *containerType, int32 *containerTypmod)
{
- Oid origArrayType = *arrayType;
+ Oid origContainerType = *containerType;
Oid elementType;
- HeapTuple type_tuple_array;
- Form_pg_type type_struct_array;
+ HeapTuple type_tuple_container;
+ Form_pg_type type_struct_container;
/*
* If the input is a domain, smash to base type, and extract the actual
- * typmod to be applied to the base type. Subscripting a domain is an
- * operation that necessarily works on the base array type, not the domain
- * itself. (Note that we provide no method whereby the creator of a
- * domain over an array type could hide its ability to be subscripted.)
+ * typmod to be applied to the base type. Subscripting a domain is an
+ * operation that necessarily works on the base container type, not the
+ * domain itself. (Note that we provide no method whereby the creator of a
+ * domain over a container type could hide its ability to be subscripted.)
*/
- *arrayType = getBaseTypeAndTypmod(*arrayType, arrayTypmod);
+ *containerType = getBaseTypeAndTypmod(*containerType, containerTypmod);
/*
- * We treat int2vector and oidvector as though they were domains over
- * int2[] and oid[]. This is needed because array slicing could create an
- * array that doesn't satisfy the dimensionality constraints of the
- * xxxvector type; so we want the result of a slice operation to be
- * considered to be of the more general type.
+ * Here is an array specific code. We treat int2vector and oidvector as
+ * though they were domains over int2[] and oid[]. This is needed because
+ * array slicing could create an array that doesn't satisfy the
+ * dimensionality constraints of the xxxvector type; so we want the result
+ * of a slice operation to be considered to be of the more general type.
*/
- if (*arrayType == INT2VECTOROID)
- *arrayType = INT2ARRAYOID;
- else if (*arrayType == OIDVECTOROID)
- *arrayType = OIDARRAYOID;
+ if (*containerType == INT2VECTOROID)
+ *containerType = INT2ARRAYOID;
+ else if (*containerType == OIDVECTOROID)
+ *containerType = OIDARRAYOID;
- /* Get the type tuple for the array */
- type_tuple_array = SearchSysCache1(TYPEOID, ObjectIdGetDatum(*arrayType));
- if (!HeapTupleIsValid(type_tuple_array))
- elog(ERROR, "cache lookup failed for type %u", *arrayType);
- type_struct_array = (Form_pg_type) GETSTRUCT(type_tuple_array);
+ /* Get the type tuple for the container */
+ type_tuple_container = SearchSysCache1(TYPEOID, ObjectIdGetDatum(*containerType));
+ if (!HeapTupleIsValid(type_tuple_container))
+ elog(ERROR, "cache lookup failed for type %u", *containerType);
+ type_struct_container = (Form_pg_type) GETSTRUCT(type_tuple_container);
/* needn't check typisdefined since this will fail anyway */
- elementType = type_struct_array->typelem;
+ elementType = type_struct_container->typelem;
if (elementType == InvalidOid)
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg("cannot subscript type %s because it is not an array",
- format_type_be(origArrayType))));
+ format_type_be(origContainerType))));
- ReleaseSysCache(type_tuple_array);
+ ReleaseSysCache(type_tuple_container);
return elementType;
}
/*
- * transformArraySubscripts()
- * Transform array subscripting. This is used for both
- * array fetch and array assignment.
+ * transformContainerSubscripts()
+ * Transform container (array, etc) subscripting. This is used for both
+ * container fetch and container assignment.
*
- * In an array fetch, we are given a source array value and we produce an
- * expression that represents the result of extracting a single array element
- * or an array slice.
+ * In a container fetch, we are given a source container value and we produce
+ * an expression that represents the result of extracting a single container
+ * element or a container slice.
*
- * In an array assignment, we are given a destination array value plus a
- * source value that is to be assigned to a single element or a slice of
- * that array. We produce an expression that represents the new array value
- * with the source data inserted into the right part of the array.
+ * In a container assignment, we are given a destination container value plus a
+ * source value that is to be assigned to a single element or a slice of that
+ * container. We produce an expression that represents the new container value
+ * with the source data inserted into the right part of the container.
*
- * For both cases, if the source array is of a domain-over-array type,
+ * For both cases, if the source container is of a domain-over-array type,
* the result is of the base array type or its element type; essentially,
* we must fold a domain to its base type before applying subscripting.
* (Note that int2vector and oidvector are treated as domains here.)
*
- * pstate Parse state
- * arrayBase Already-transformed expression for the array as a whole
- * arrayType OID of array's datatype (should match type of arrayBase,
- * or be the base type of arrayBase's domain type)
- * elementType OID of array's element type (fetch with transformArrayType,
- * or pass InvalidOid to do it here)
- * arrayTypMod typmod for the array (which is also typmod for the elements)
- * indirection Untransformed list of subscripts (must not be NIL)
- * assignFrom NULL for array fetch, else transformed expression for source.
+ * pstate Parse state
+ * containerBase Already-transformed expression for the container as a whole
+ * containerType OID of container's datatype (should match type of
+ * containerBase, or be the base type of containerBase's
+ * domain type)
+ * elementType OID of container's element type (fetch with
+ * transformContainerType, or pass InvalidOid to do it here)
+ * containerTypMod typmod for the container (which is also typmod for the
+ * elements)
+ * indirection Untransformed list of subscripts (must not be NIL)
+ * assignFrom NULL for container fetch, else transformed expression for
+ * source.
*/
-ArrayRef *
-transformArraySubscripts(ParseState *pstate,
- Node *arrayBase,
- Oid arrayType,
- Oid elementType,
- int32 arrayTypMod,
- List *indirection,
- Node *assignFrom)
+SubscriptingRef *
+transformContainerSubscripts(ParseState *pstate,
+ Node *containerBase,
+ Oid containerType,
+ Oid elementType,
+ int32 containerTypMod,
+ List *indirection,
+ Node *assignFrom)
{
bool isSlice = false;
List *upperIndexpr = NIL;
List *lowerIndexpr = NIL;
+ List *indexprSlice = NIL;
ListCell *idx;
- ArrayRef *aref;
+ SubscriptingRef *sbsref;
/*
* Caller may or may not have bothered to determine elementType. Note
- * that if the caller did do so, arrayType/arrayTypMod must be as modified
- * by transformArrayType, ie, smash domain to base type.
+ * that if the caller did do so, containerType/containerTypMod must be as
+ * modified by transformContainerType, ie, smash domain to base type.
*/
if (!OidIsValid(elementType))
- elementType = transformArrayType(&arrayType, &arrayTypMod);
+ elementType = transformContainerType(&containerType, &containerTypMod);
/*
- * A list containing only simple subscripts refers to a single array
+ * A list containing only simple subscripts refers to a single container
* element. If any of the items are slice specifiers (lower:upper), then
- * the subscript expression means an array slice operation. In this case,
- * we convert any non-slice items to slices by treating the single
+ * the subscript expression means a container slice operation. In this
+ * case, we convert any non-slice items to slices by treating the single
* subscript as the upper bound and supplying an assumed lower bound of 1.
* We have to prescan the list to see if there are any slice items.
*/
@@ -411,12 +416,12 @@ transformArraySubscripts(ParseState *pstate,
if (assignFrom != NULL)
{
Oid typesource = exprType(assignFrom);
- Oid typeneeded = isSlice ? arrayType : elementType;
+ Oid typeneeded = isSlice ? containerType : elementType;
Node *newFrom;
newFrom = coerce_to_target_type(pstate,
assignFrom, typesource,
- typeneeded, arrayTypMod,
+ typeneeded, containerTypMod,
COERCION_ASSIGNMENT,
COERCE_IMPLICIT_CAST,
-1);
@@ -433,19 +438,23 @@ transformArraySubscripts(ParseState *pstate,
}
/*
- * Ready to build the ArrayRef node.
+ * Ready to build the SubscriptingRef node.
*/
- aref = makeNode(ArrayRef);
- aref->refarraytype = arrayType;
- aref->refelemtype = elementType;
- aref->reftypmod = arrayTypMod;
+ sbsref = (SubscriptingRef *) makeNode(SubscriptingRef);
+ if (assignFrom != NULL)
+ sbsref->refassgnexpr = (Expr *) assignFrom;
+
+ sbsref->refcontainertype = containerType;
+ sbsref->refelemtype = elementType;
+ sbsref->reftypmod = containerTypMod;
/* refcollid will be set by parse_collate.c */
- aref->refupperindexpr = upperIndexpr;
- aref->reflowerindexpr = lowerIndexpr;
- aref->refexpr = (Expr *) arrayBase;
- aref->refassgnexpr = (Expr *) assignFrom;
+ sbsref->refupperindexpr = upperIndexpr;
+ sbsref->reflowerindexpr = lowerIndexpr;
+ sbsref->refindexprslice = indexprSlice;
+ sbsref->refexpr = (Expr *) containerBase;
+ sbsref->refassgnexpr = (Expr *) assignFrom;
- return aref;
+ return sbsref;
}
/*
diff --git a/src/backend/parser/parse_target.c b/src/backend/parser/parse_target.c
index 561d8774f47..0e9598ebfe4 100644
--- a/src/backend/parser/parse_target.c
+++ b/src/backend/parser/parse_target.c
@@ -655,7 +655,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
@@ -677,7 +677,7 @@ static Node *
transformAssignmentIndirection(ParseState *pstate,
Node *basenode,
const char *targetName,
- bool targetIsArray,
+ bool targetIsSubscripting,
Oid targetTypeId,
int32 targetTypMod,
Oid targetCollation,
@@ -855,7 +855,7 @@ transformAssignmentIndirection(ParseState *pstate,
-1);
if (result == NULL)
{
- if (targetIsArray)
+ if (targetIsSubscripting)
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg("array assignment to \"%s\" requires type %s"
@@ -881,7 +881,7 @@ transformAssignmentIndirection(ParseState *pstate,
}
/*
- * helper for transformAssignmentIndirection: process array assignment
+ * helper for transformAssignmentIndirection: process container assignment
*/
static Node *
transformAssignmentSubscripts(ParseState *pstate,
@@ -897,8 +897,8 @@ transformAssignmentSubscripts(ParseState *pstate,
int location)
{
Node *result;
- Oid arrayType;
- int32 arrayTypMod;
+ Oid containerType;
+ int32 containerTypMod;
Oid elementTypeId;
Oid typeNeeded;
Oid collationNeeded;
@@ -906,46 +906,46 @@ transformAssignmentSubscripts(ParseState *pstate,
Assert(subscripts != NIL);
/* Identify the actual array type and element type involved */
- arrayType = targetTypeId;
- arrayTypMod = targetTypMod;
- elementTypeId = transformArrayType(&arrayType, &arrayTypMod);
+ containerType = targetTypeId;
+ containerTypMod = targetTypMod;
+ elementTypeId = transformContainerType(&containerType, &containerTypMod);
/* Identify type that RHS must provide */
- typeNeeded = isSlice ? arrayType : elementTypeId;
+ typeNeeded = isSlice ? containerType : elementTypeId;
/*
- * Array normally has same collation as elements, but there's an
- * exception: we might be subscripting a domain over an array type. In
+ * container normally has same collation as elements, but there's an
+ * exception: we might be subscripting a domain over a container type. In
* that case use collation of the base type.
*/
- if (arrayType == targetTypeId)
+ if (containerType == targetTypeId)
collationNeeded = targetCollation;
else
- collationNeeded = get_typcollation(arrayType);
+ collationNeeded = get_typcollation(containerType);
- /* recurse to create appropriate RHS for array assign */
+ /* recurse to create appropriate RHS for container assign */
rhs = transformAssignmentIndirection(pstate,
NULL,
targetName,
true,
typeNeeded,
- arrayTypMod,
+ containerTypMod,
collationNeeded,
next_indirection,
rhs,
location);
/* process subscripts */
- result = (Node *) transformArraySubscripts(pstate,
- basenode,
- arrayType,
- elementTypeId,
- arrayTypMod,
- subscripts,
- rhs);
-
- /* If target was a domain over array, need to coerce up to the domain */
- if (arrayType != targetTypeId)
+ result = (Node *) transformContainerSubscripts(pstate,
+ basenode,
+ containerType,
+ elementTypeId,
+ containerTypMod,
+ subscripts,
+ rhs);
+
+ /* If target was a domain over container, need to coerce up to the domain */
+ if (containerType != targetTypeId)
{
Oid resulttype = exprType(result);
diff --git a/src/backend/rewrite/rewriteHandler.c b/src/backend/rewrite/rewriteHandler.c
index 1eca69873b2..0338e4e1ad0 100644
--- a/src/backend/rewrite/rewriteHandler.c
+++ b/src/backend/rewrite/rewriteHandler.c
@@ -951,7 +951,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
@@ -959,7 +959,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)),
@@ -969,7 +969,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
@@ -1048,13 +1048,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
{
@@ -1091,14 +1091,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 51e4c275ab0..17a28c26517 100644
--- a/src/backend/utils/adt/ruleutils.c
+++ b/src/backend/utils/adt/ruleutils.c
@@ -456,7 +456,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);
@@ -6400,12 +6400,12 @@ 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
- * 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
- * be as careful as processIndirection() is about descending past
- * implicit CoerceToDomains.
+ * 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 be as careful as processIndirection() is about
+ * descending past implicit CoerceToDomains.
*/
expr = (Node *) tle->expr;
while (expr)
@@ -6416,13 +6416,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))
{
@@ -7456,7 +7457,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:
@@ -7574,7 +7575,7 @@ isSimpleNode(Node *node, Node *parentNode, int prettyFlags)
return true; /* own parentheses */
}
case T_BoolExpr: /* lower precedence */
- case T_ArrayRef: /* other separators */
+ case T_SubscriptingRef: /* other separators */
case T_ArrayExpr: /* other separators */
case T_RowExpr: /* other separators */
case T_CoalesceExpr: /* own parentheses */
@@ -7624,7 +7625,7 @@ isSimpleNode(Node *node, Node *parentNode, int prettyFlags)
return false;
return true; /* own parentheses */
}
- case T_ArrayRef: /* other separators */
+ case T_SubscriptingRef: /* other separators */
case T_ArrayExpr: /* other separators */
case T_RowExpr: /* other separators */
case T_CoalesceExpr: /* own parentheses */
@@ -7810,9 +7811,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;
/*
@@ -7823,37 +7824,38 @@ 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
- * *must* parenthesize to avoid confusion.)
+ * 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, ')');
/*
* If there's a refassgnexpr, we want to print the node in the
- * format "array[subscripts] := refassgnexpr". This is not
- * legal SQL, so decompilation of INSERT or UPDATE statements
- * should always use processIndirection as part of the
- * statement-level syntax. We should only see this when
+ * format "container[subscripts] := refassgnexpr". This is
+ * not legal SQL, so decompilation of INSERT or UPDATE
+ * statements should always use processIndirection as part of
+ * the statement-level syntax. We should only see this when
* EXPLAIN tries to print the targetlist of a plan resulting
* from such a statement.
*/
- if (aref->refassgnexpr)
+ if (sbsref->refassgnexpr)
{
Node *refassgnexpr;
@@ -7869,8 +7871,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;
@@ -8068,12 +8070,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);
@@ -10437,7 +10440,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
@@ -10483,19 +10486,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))
{
@@ -10523,14 +10527,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 2c1697dd766..7aacdc5d049 100644
--- a/src/include/executor/execExpr.h
+++ b/src/include/executor/execExpr.h
@@ -19,7 +19,7 @@
/* forward references to avoid circularity */
struct ExprEvalStep;
-struct ArrayRefState;
+struct SubscriptingRefState;
/* Bits in ExprState->flags (see also execnodes.h for public flag bits): */
/* expression's interpreter has been initialized */
@@ -185,21 +185,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,
@@ -492,22 +492,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
@@ -658,14 +658,14 @@ typedef struct ExprEvalStep
} 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 */
@@ -688,10 +688,10 @@ 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 */
@@ -735,10 +735,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/jit/llvmjit.h b/src/include/jit/llvmjit.h
index 726ec99130b..6178864b2e6 100644
--- a/src/include/jit/llvmjit.h
+++ b/src/include/jit/llvmjit.h
@@ -85,7 +85,7 @@ extern LLVMValueRef FuncVarsizeAny;
extern LLVMValueRef FuncSlotGetmissingattrs;
extern LLVMValueRef FuncSlotGetsomeattrsInt;
extern LLVMValueRef FuncMakeExpandedObjectReadOnlyInternal;
-extern LLVMValueRef FuncExecEvalArrayRefSubscript;
+extern LLVMValueRef FuncExecEvalSubscriptingRef;
extern LLVMValueRef FuncExecEvalSysVar;
extern LLVMValueRef FuncExecAggTransReparent;
extern LLVMValueRef FuncExecAggInitGroup;
diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h
index fbe2dc14a7d..e215ad4978a 100644
--- a/src/include/nodes/nodes.h
+++ b/src/include/nodes/nodes.h
@@ -154,7 +154,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 4ec8a835417..2fe14d7db20 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -224,7 +224,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 78fb0e414e3..a7efae70381 100644
--- a/src/include/nodes/primnodes.h
+++ b/src/include/nodes/primnodes.h
@@ -368,18 +368,19 @@ typedef struct WindowFunc
} WindowFunc;
/* ----------------
- * ArrayRef: describes an array subscripting operation
- *
- * An ArrayRef can describe fetching a single element from an array,
- * fetching a subarray (array slice), storing a single element into
- * an array, or storing a slice. The "store" cases work with an
- * initial array value and a source value that is inserted into the
- * appropriate part of the array; the result of the operation is an
- * entire new modified array value.
- *
- * If reflowerindexpr = NIL, then we are fetching or storing a single array
- * element at the subscripts given by refupperindexpr. Otherwise we are
- * fetching or storing an array slice, that is a rectangular subarray
+ * SubscriptingRef: describes a subscripting operation over a container
+ * (array, etc).
+ *
+ * A SubscriptingRef can describe fetching a single element from a container,
+ * fetching a part of container (e.g. array slice), storing a single element into
+ * a container, or storing a slice. The "store" cases work with an
+ * initial container value and a source value that is inserted into the
+ * appropriate part of the container; the result of the operation is an
+ * entire new modified container value.
+ *
+ * If reflowerindexpr = NIL, then we are fetching or storing a single container
+ * element at the subscripts given by refupperindexpr. Otherwise we are
+ * fetching or storing a container slice, that is a rectangular subcontainer
* with lower and upper bounds given by the index expressions.
* reflowerindexpr must be the same length as refupperindexpr when it
* is not NIL.
@@ -391,28 +392,31 @@ typedef struct WindowFunc
* element; but it is the array type when doing subarray fetch or either
* type of store.
*
- * Note: for the cases where an array is returned, if refexpr yields a R/W
- * expanded array, then the implementation is allowed to modify that object
+ * Note: for the cases where a container is returned, if refexpr yields a R/W
+ * expanded container, then the implementation is allowed to modify that object
* in-place and return the same object.)
* ----------------
*/
-typedef struct ArrayRef
+typedef struct SubscriptingRef
{
Expr xpr;
- Oid refarraytype; /* type of the array proper */
- Oid refelemtype; /* type of the array elements */
- int32 reftypmod; /* typmod of the array (and elements too) */
+ Oid refcontainertype; /* type of the container proper */
+ Oid refelemtype; /* type of the container elements */
+ int32 reftypmod; /* typmod of the container (and elements too) */
Oid refcollid; /* OID of collation, or InvalidOid if none */
List *refupperindexpr; /* expressions that evaluate to upper
- * array indexes */
+ * container indexes */
List *reflowerindexpr; /* expressions that evaluate to lower
- * array indexes, or NIL for single array
- * element */
- Expr *refexpr; /* the expression that evaluates to an array
- * value */
+ * container indexes, or NIL for single
+ * container element */
+ List *refindexprslice; /* whether or not related indexpr from
+ * reflowerindexpr is a slice */
+ Expr *refexpr; /* the expression that evaluates to a
+ * container value */
+
Expr *refassgnexpr; /* expression for the source value, or NULL if
* fetch */
-} ArrayRef;
+} SubscriptingRef;
/*
* CoercionContext - distinguishes the allowed set of type casts
@@ -755,7 +759,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/include/parser/parse_node.h b/src/include/parser/parse_node.h
index b95489379c5..ea99a0954ba 100644
--- a/src/include/parser/parse_node.h
+++ b/src/include/parser/parse_node.h
@@ -273,14 +273,15 @@ extern void cancel_parser_errposition_callback(ParseCallbackState *pcbstate);
extern Var *make_var(ParseState *pstate, RangeTblEntry *rte, int attrno,
int location);
-extern Oid transformArrayType(Oid *arrayType, int32 *arrayTypmod);
-extern ArrayRef *transformArraySubscripts(ParseState *pstate,
- Node *arrayBase,
- Oid arrayType,
- Oid elementType,
- int32 arrayTypMod,
- List *indirection,
- Node *assignFrom);
+extern Oid transformContainerType(Oid *containerType, int32 *containerTypmod);
+
+extern SubscriptingRef *transformContainerSubscripts(ParseState *pstate,
+ Node *containerBase,
+ Oid containerType,
+ Oid elementType,
+ int32 containerTypMod,
+ List *indirection,
+ Node *assignFrom);
extern Const *make_const(ParseState *pstate, Value *value, int location);
#endif /* PARSE_NODE_H */
diff --git a/src/pl/plpgsql/src/pl_exec.c b/src/pl/plpgsql/src/pl_exec.c
index 85aa61371d6..a5aafa8c09f 100644
--- a/src/pl/plpgsql/src/pl_exec.c
+++ b/src/pl/plpgsql/src/pl_exec.c
@@ -5207,8 +5207,8 @@ exec_assign_value(PLpgSQL_execstate *estate,
/*
* Evaluate the subscripts, switch into left-to-right order.
- * Like the expression built by ExecInitArrayRef(), complain
- * if any subscript is null.
+ * Like the expression built by ExecInitSubscriptingRef(),
+ * complain if any subscript is null.
*/
for (i = 0; i < nsubscripts; i++)
{