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.
pull/8162/head^2
Colm 2025-08-27 12:00:27 +01:00 committed by GitHub
parent 62e5fcfe09
commit 0a5cae19ed
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 62 additions and 0 deletions

View File

@ -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);