@@ -354,7 +354,8 @@ static void postgresGetForeignUpperPaths(PlannerInfo *root,
354354 RelOptInfo * output_rel );
355355static void postgresBeginForeignCopyFrom (EState * estate ,
356356 ResultRelInfo * rinfo ,
357- CopyState cstate );
357+ CopyState cstate ,
358+ const char * dest_relname );
358359static void postgresForeignNextCopyFrom (EState * estate ,
359360 ResultRelInfo * rinfo ,
360361 CopyState cstate );
@@ -5225,7 +5226,7 @@ _PG_init(void)
52255226/* Begin COPY FROM to foreign table */
52265227static void
52275228postgresBeginForeignCopyFrom (EState * estate , ResultRelInfo * rinfo ,
5228- CopyState cstate )
5229+ CopyState cstate , const char * dest_relname )
52295230{
52305231 Relation rel = rinfo -> ri_RelationDesc ;
52315232 RangeTblEntry * rte ;
@@ -5235,6 +5236,7 @@ postgresBeginForeignCopyFrom(EState *estate, ResultRelInfo *rinfo,
52355236 StringInfoData sql ;
52365237 PGconn * conn ;
52375238 PGresult * res ;
5239+ bool * copy_from_started ;
52385240
52395241 /*
52405242 * Identify which user to do the remote access as. This should match what
@@ -5246,30 +5248,38 @@ postgresBeginForeignCopyFrom(EState *estate, ResultRelInfo *rinfo,
52465248 /* Get info about foreign table. */
52475249 table = GetForeignTable (RelationGetRelid (rel ));
52485250 user = GetUserMapping (userid , table -> serverid );
5251+ rinfo -> ri_FdwState = user ;
52495252
5250- /* Open connection */
5251- conn = GetConnection (user , false);
5252- rinfo -> ri_FdwState = conn ;
5253+ /* Get (open, if not yet) connection */
5254+ conn = GetConnectionCopyFrom (user , false, & copy_from_started );
5255+ /* We already did COPY FROM to this server */
5256+ if (* copy_from_started )
5257+ return ;
52535258
52545259 /* deparse COPY stmt */
52555260 initStringInfo (& sql );
5256- deparseCopyFromSql (& sql , rel , cstate );
5261+ deparseCopyFromSql (& sql , rel , cstate , dest_relname );
52575262
52585263 res = PQexec (conn , sql .data );
52595264 if (PQresultStatus (res ) != PGRES_COPY_IN )
52605265 {
52615266 pgfdw_report_error (ERROR , res , conn , true, sql .data );
52625267 }
52635268 PQclear (res );
5269+
5270+ * copy_from_started = true;
52645271}
52655272
52665273/* COPY FROM next row to foreign table */
52675274static void
52685275postgresForeignNextCopyFrom (EState * estate , ResultRelInfo * rinfo ,
52695276 CopyState cstate )
52705277{
5271- PGconn * conn = (PGconn * ) rinfo -> ri_FdwState ;
5278+ bool * copy_from_started ;
5279+ UserMapping * user = (UserMapping * ) rinfo -> ri_FdwState ;
5280+ PGconn * conn = GetConnectionCopyFrom (user , false, & copy_from_started );
52725281
5282+ Assert (copy_from_started );
52735283 Assert (!cstate -> binary );
52745284 /* TODO: distinuish failure and nonblocking-send EAGAIN */
52755285 if (PQputline (conn , cstate -> line_buf .data ) || PQputnbytes (conn , "\n" , 1 ))
@@ -5282,19 +5292,24 @@ postgresForeignNextCopyFrom(EState *estate, ResultRelInfo *rinfo,
52825292static void
52835293postgresEndForeignCopyFrom (EState * estate , ResultRelInfo * rinfo )
52845294{
5285- PGconn * conn = (PGconn * ) rinfo -> ri_FdwState ;
5286- PGresult * res ;
5295+ bool * copy_from_started ;
5296+ UserMapping * user = (UserMapping * ) rinfo -> ri_FdwState ;
5297+ PGconn * conn = GetConnectionCopyFrom (user , false, & copy_from_started );
5298+ PGresult * res ;
52875299
5288- /* TODO: PQgetResult? */
5289- if (PQendcopy (conn ))
5300+ if (* copy_from_started )
52905301 {
5291- pgfdw_report_error (ERROR , NULL , conn , false, "end postgres_fdw copy from" );
5292- }
5293- while ((res = PQgetResult (conn )) != NULL )
5294- {
5295- /* TODO: get error? */
5296- PQclear (res );
5302+ /* TODO: PQgetResult? */
5303+ if (PQendcopy (conn ))
5304+ {
5305+ pgfdw_report_error (ERROR , NULL , conn , false, "end postgres_fdw copy from" );
5306+ }
5307+ while ((res = PQgetResult (conn )) != NULL )
5308+ {
5309+ /* TODO: get error? */
5310+ PQclear (res );
5311+ }
5312+ * copy_from_started = false;
5313+ ReleaseConnection (conn );
52975314 }
5298-
5299- ReleaseConnection (conn );
53005315}
0 commit comments