Refactor AddInsertSelectCasts function to improve clarity and organization of type casting logic in insert select planner

pull/7920/head
Mehmet Yilmaz 2025-03-10 07:17:52 +00:00
parent 693eb29cbe
commit 153901fc86
1 changed files with 72 additions and 72 deletions

View File

@ -1627,6 +1627,68 @@ RelabelTargetEntryList(List *selectTargetList, List *insertTargetList)
}
/*
* AddInsertSelectCasts ensures that the columns in the given target lists
* have the same type as the corresponding columns of the target relation.
* It adds casts when necessary.
*
* Returns the updated selectTargetList.
*/
static List *
AddInsertSelectCasts(List *insertTargetList, List *selectTargetList,
Oid targetRelationId)
{
List *projectedEntries = NIL;
List *nonProjectedEntries = NIL;
/*
* ReorderInsertSelectTargetLists() ensures that the first few columns of the
* SELECT query match the insert targets. It might also include additional
* items (for GROUP BY, etc.), so the insertTargetList is shorter.
*/
Assert(list_length(insertTargetList) <= list_length(selectTargetList));
Relation distributedRelation = table_open(targetRelationId, RowExclusiveLock);
TupleDesc destTupleDescriptor = RelationGetDescr(distributedRelation);
int targetEntryIndex = 0;
TargetEntry *insertEntry = NULL;
TargetEntry *selectEntry = NULL;
forboth_ptr(insertEntry, insertTargetList, selectEntry, selectTargetList)
{
/*
* Retrieve the target attribute corresponding to the insert entry.
* The attribute is located at (resno - 1) in the tuple descriptor.
*/
Form_pg_attribute attr = TupleDescAttr(destTupleDescriptor,
insertEntry->resno - 1);
process_entry_pair(insertEntry, selectEntry, attr, targetEntryIndex,
&projectedEntries, &nonProjectedEntries);
targetEntryIndex++;
}
/* Append any additional non-projected entries from selectTargetList */
for (int entryIndex = list_length(insertTargetList);
entryIndex < list_length(selectTargetList);
entryIndex++)
{
nonProjectedEntries = lappend(nonProjectedEntries, list_nth(selectTargetList,
entryIndex));
}
/* Concatenate projected and non-projected entries and reset resno numbering */
selectTargetList = list_concat(projectedEntries, nonProjectedEntries);
reset_target_entry_resno(selectTargetList);
table_close(distributedRelation, NoLock);
return selectTargetList;
}
/*
* Processes a single pair of insert and select target entries.
* It compares the source and target types and appends either the
@ -1703,68 +1765,6 @@ reset_target_entry_resno(List *targetList)
}
/*
* AddInsertSelectCasts ensures that the columns in the given target lists
* have the same type as the corresponding columns of the target relation.
* It adds casts when necessary.
*
* Returns the updated selectTargetList.
*/
static List *
AddInsertSelectCasts(List *insertTargetList, List *selectTargetList,
Oid targetRelationId)
{
List *projectedEntries = NIL;
List *nonProjectedEntries = NIL;
/*
* ReorderInsertSelectTargetLists() ensures that the first few columns of the
* SELECT query match the insert targets. It might also include additional
* items (for GROUP BY, etc.), so the insertTargetList is shorter.
*/
Assert(list_length(insertTargetList) <= list_length(selectTargetList));
Relation distributedRelation = table_open(targetRelationId, RowExclusiveLock);
TupleDesc destTupleDescriptor = RelationGetDescr(distributedRelation);
int targetEntryIndex = 0;
TargetEntry *insertEntry = NULL;
TargetEntry *selectEntry = NULL;
forboth_ptr(insertEntry, insertTargetList, selectEntry, selectTargetList)
{
/*
* Retrieve the target attribute corresponding to the insert entry.
* The attribute is located at (resno - 1) in the tuple descriptor.
*/
Form_pg_attribute attr = TupleDescAttr(destTupleDescriptor,
insertEntry->resno - 1);
process_entry_pair(insertEntry, selectEntry, attr, targetEntryIndex,
&projectedEntries, &nonProjectedEntries);
targetEntryIndex++;
}
/* Append any additional non-projected entries from selectTargetList */
for (int entryIndex = list_length(insertTargetList);
entryIndex < list_length(selectTargetList);
entryIndex++)
{
nonProjectedEntries = lappend(nonProjectedEntries, list_nth(selectTargetList,
entryIndex));
}
/* Concatenate projected and non-projected entries and reset resno numbering */
selectTargetList = list_concat(projectedEntries, nonProjectedEntries);
reset_target_entry_resno(selectTargetList);
table_close(distributedRelation, NoLock);
return selectTargetList;
}
/*
* Looks up the nextval(regclass) function in pg_proc, returning its actual
* rettype. In a standard build, that will be INT8OID, but this is more robust.
@ -1795,16 +1795,6 @@ GetNextvalReturnTypeCatalog(void)
}
/* Helper function to set the target entry name using a formatted string */
static void
set_target_entry_name(TargetEntry *tle, const char *format, int index)
{
StringInfo resnameString = makeStringInfo();
appendStringInfo(resnameString, format, index);
tle->resname = resnameString->data;
}
/**
* Modifies the given insert entry to match the target column's type and typmod,
* then creates and appends a new target entry containing a casted expression
@ -1932,6 +1922,16 @@ CastExpr(Expr *expr, Oid sourceType, Oid targetType, Oid targetCollation,
}
/* Helper function to set the target entry name using a formatted string */
static void
set_target_entry_name(TargetEntry *tle, const char *format, int index)
{
StringInfo resnameString = makeStringInfo();
appendStringInfo(resnameString, format, index);
tle->resname = resnameString->data;
}
/* PlanningInsertSelect returns true if we are planning an INSERT ...SELECT query */
bool
PlanningInsertSelect(void)