Commit 558d77f2 authored by Alvaro Herrera's avatar Alvaro Herrera

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
parent f831d4ac
......@@ -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:
......
......@@ -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;
......
This diff is collapsed.
This diff is collapsed.
......@@ -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");
......
......@@ -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));
......
......@@ -103,7 +103,7 @@ void *referenced_functions[] =
slot_getsomeattrs_int,
slot_getmissingattrs,
MakeExpandedObjectReadOnlyInternal,
ExecEvalArrayRefSubscript,
ExecEvalSubscriptingRef,
ExecEvalSysVar,
ExecAggTransReparent,
ExecAggInitGroup
......
......@@ -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);
......
......@@ -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);
......
......@@ -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;
......
......@@ -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);
......
......@@ -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))
......
......@@ -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:
......
......@@ -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;
......
......@@ -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;
}
......
This diff is collapsed.
......@@ -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);
......
......@@ -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;
}
......
......@@ -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)
......
......@@ -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);
......
......@@ -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;
......
......@@ -154,7 +154,7 @@ typedef enum NodeTag
T_Aggref,
T_GroupingFunc,
T_WindowFunc,
T_ArrayRef,
T_SubscriptingRef,
T_FuncExpr,
T_NamedArgExpr,
T_OpExpr,
......
......@@ -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.
......
......@@ -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
......
......@@ -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 */
......@@ -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++)
{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment