mirror of https://github.com/citusdata/citus.git
In UPDATE deparse, check for a subscript before processing the targets. (#8155)
DESCRIPTION: Checking first for the presence of subscript ops avoids a
shallow copy of the target list for target lists where there are no
array or json subscripts.
Commit 0c1b31c fixed a bug in UPDATE statements with array or json
subscripting in the target list. This commit modifies that to first
check that the target list has a subscript and avoid a shallow copy of
the target list for UPDATE statements with no array/json subscripting.
release-13.2-colm
parent
91cae1fb29
commit
c39df81f69
|
|
@ -1837,6 +1837,62 @@ ensure_update_targetlist_in_param_order(List *targetList)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* isSubsRef checks if a given node is a SubscriptingRef or can be
|
||||||
|
* reached through an implicit coercion.
|
||||||
|
*/
|
||||||
|
static
|
||||||
|
bool
|
||||||
|
isSubsRef(Node *node)
|
||||||
|
{
|
||||||
|
if (node == NULL)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsA(node, CoerceToDomain))
|
||||||
|
{
|
||||||
|
CoerceToDomain *coerceToDomain = (CoerceToDomain *) node;
|
||||||
|
if (coerceToDomain->coercionformat != COERCE_IMPLICIT_CAST)
|
||||||
|
{
|
||||||
|
/* not an implicit coercion, cannot reach to a SubscriptingRef */
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
node = (Node *) coerceToDomain->arg;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (IsA(node, SubscriptingRef));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* checkTlistForSubsRef - checks if any target entry in the list contains a
|
||||||
|
* SubscriptingRef or can be reached through an implicit coercion. Used by
|
||||||
|
* ExpandMergedSubscriptingRefEntries() to identify if any target entries
|
||||||
|
* need to be expanded - if not the original target list is preserved.
|
||||||
|
*/
|
||||||
|
static
|
||||||
|
bool
|
||||||
|
checkTlistForSubsRef(List *targetEntryList)
|
||||||
|
{
|
||||||
|
ListCell *tgtCell = NULL;
|
||||||
|
|
||||||
|
foreach(tgtCell, targetEntryList)
|
||||||
|
{
|
||||||
|
TargetEntry *targetEntry = (TargetEntry *) lfirst(tgtCell);
|
||||||
|
Expr *expr = targetEntry->expr;
|
||||||
|
|
||||||
|
if (isSubsRef((Node *) expr))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ExpandMergedSubscriptingRefEntries takes a list of target entries and expands
|
* ExpandMergedSubscriptingRefEntries takes a list of target entries and expands
|
||||||
* each one that references a SubscriptingRef node that indicates multiple (field)
|
* each one that references a SubscriptingRef node that indicates multiple (field)
|
||||||
|
|
@ -1848,6 +1904,12 @@ ExpandMergedSubscriptingRefEntries(List *targetEntryList)
|
||||||
List *newTargetEntryList = NIL;
|
List *newTargetEntryList = NIL;
|
||||||
ListCell *tgtCell = NULL;
|
ListCell *tgtCell = NULL;
|
||||||
|
|
||||||
|
if (!checkTlistForSubsRef(targetEntryList))
|
||||||
|
{
|
||||||
|
/* No subscripting refs found, return original list */
|
||||||
|
return targetEntryList;
|
||||||
|
}
|
||||||
|
|
||||||
foreach(tgtCell, targetEntryList)
|
foreach(tgtCell, targetEntryList)
|
||||||
{
|
{
|
||||||
TargetEntry *targetEntry = (TargetEntry *) lfirst(tgtCell);
|
TargetEntry *targetEntry = (TargetEntry *) lfirst(tgtCell);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue