mirror of https://github.com/citusdata/citus.git
Refactor AddInsertSelectCasts function to improve clarity and organization of type casting logic in insert select planner
parent
693eb29cbe
commit
153901fc86
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue