Skip to content

Commit b605edd

Browse files
committed
1 parent c963933 commit b605edd

File tree

1 file changed

+42
-10
lines changed

1 file changed

+42
-10
lines changed

src/utility_stmt_hooking.c

Lines changed: 42 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -499,7 +499,7 @@ PathmanCopyFrom(CopyState cstate, Relation parent_rel,
499499
/* Initialize ResultPartsStorage */
500500
init_result_parts_storage(&parts_storage, estate, false,
501501
ResultPartsStorageStandard,
502-
prepare_rri_for_copy, NULL);
502+
prepare_rri_for_copy, cstate);
503503
parts_storage.saved_rel_info = parent_result_rel;
504504

505505
/* Set up a tuple slot too */
@@ -634,13 +634,20 @@ PathmanCopyFrom(CopyState cstate, Relation parent_rel,
634634
/* Check the constraints of the tuple */
635635
if (child_result_rel->ri_RelationDesc->rd_att->constr)
636636
ExecConstraints(child_result_rel, slot, estate);
637+
if (!child_result_rel->ri_FdwRoutine)
638+
{
639+
/* OK, store the tuple and create index entries for it */
640+
simple_heap_insert(child_result_rel->ri_RelationDesc, tuple);
637641

638-
/* OK, store the tuple and create index entries for it */
639-
simple_heap_insert(child_result_rel->ri_RelationDesc, tuple);
640-
641-
if (child_result_rel->ri_NumIndices > 0)
642-
recheckIndexes = ExecInsertIndexTuples(slot, &(tuple->t_self),
643-
estate, false, NULL, NIL);
642+
if (child_result_rel->ri_NumIndices > 0)
643+
recheckIndexes = ExecInsertIndexTuples(slot, &(tuple->t_self),
644+
estate, false, NULL, NIL);
645+
}
646+
else /* FDW table */
647+
{
648+
child_result_rel->ri_FdwRoutine->ForeignNextCopyFrom(
649+
estate, child_result_rel, cstate);
650+
}
644651

645652
/* AFTER ROW INSERT Triggers (FIXME: NULL transition) */
646653
ExecARInsertTriggersCompat(estate, child_result_rel, tuple,
@@ -677,6 +684,24 @@ PathmanCopyFrom(CopyState cstate, Relation parent_rel,
677684

678685
ExecResetTupleTable(estate->es_tupleTable, false);
679686

687+
{
688+
/* Shut down FDWs. TODO: make hook in fini_result_parts_storage? */
689+
HASH_SEQ_STATUS stat;
690+
ResultRelInfoHolder *rri_holder; /* ResultRelInfo holder */
691+
692+
hash_seq_init(&stat, parts_storage.result_rels_table);
693+
while ((rri_holder = (ResultRelInfoHolder *) hash_seq_search(&stat)) != NULL)
694+
{
695+
ResultRelInfo *resultRelInfo = rri_holder->result_rel_info;
696+
697+
if (resultRelInfo->ri_FdwRoutine)
698+
{
699+
resultRelInfo->ri_FdwRoutine->EndForeignCopyFrom(
700+
estate, resultRelInfo);
701+
}
702+
}
703+
}
704+
680705
/* Close partitions and destroy hash table */
681706
fini_result_parts_storage(&parts_storage, true);
682707

@@ -689,7 +714,7 @@ PathmanCopyFrom(CopyState cstate, Relation parent_rel,
689714
}
690715

691716
/*
692-
* COPY FROM does not support FDWs, emit ERROR.
717+
* Init COPY FROM, if supported.
693718
*/
694719
static void
695720
prepare_rri_for_copy(EState *estate,
@@ -699,10 +724,17 @@ prepare_rri_for_copy(EState *estate,
699724
{
700725
ResultRelInfo *rri = rri_holder->result_rel_info;
701726
FdwRoutine *fdw_routine = rri->ri_FdwRoutine;
727+
CopyState cstate = (CopyState) arg;
702728

703729
if (fdw_routine != NULL)
704-
elog(ERROR, "cannot copy to foreign partition \"%s\"",
705-
get_rel_name(RelationGetRelid(rri->ri_RelationDesc)));
730+
{
731+
if (!FdwCopyFromIsSupported(fdw_routine))
732+
ereport(ERROR,
733+
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
734+
errmsg("FDW adapter for relation \"%s\" doesn't support COPY FROM",
735+
RelationGetRelationName(rri->ri_RelationDesc))));
736+
rri->ri_FdwRoutine->BeginForeignCopyFrom(estate, rri, cstate);
737+
}
706738
}
707739

708740
/*

0 commit comments

Comments
 (0)