Skip to content

Commit 5519d5a

Browse files
committed
psql: Refactor ProcessResult()
Separate HandleCopyResult() from ProcessResult() in preparation for a subsequent patch. Author: Fabien COELHO <coelho@cri.ensmp.fr> Discussion: https://www.postgresql.org/message-id/flat/alpine.DEB.2.21.1904132231510.8961@lancre
1 parent d16773c commit 5519d5a

File tree

1 file changed

+111
-93
lines changed

1 file changed

+111
-93
lines changed

src/bin/psql/common.c

Lines changed: 111 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -892,6 +892,116 @@ ExecQueryTuples(const PGresult *result)
892892
}
893893

894894

895+
/*
896+
* Marshal the COPY data. Either subroutine will get the
897+
* connection out of its COPY state, then call PQresultStatus()
898+
* once and report any error. Return whether all was ok.
899+
*
900+
* For COPY OUT, direct the output to pset.copyStream if it's set,
901+
* otherwise to pset.gfname if it's set, otherwise to queryFout.
902+
* For COPY IN, use pset.copyStream as data source if it's set,
903+
* otherwise cur_cmd_source.
904+
*
905+
* Update result if further processing is necessary, or NULL otherwise.
906+
* Return a result when queryFout can safely output a result status: on COPY
907+
* IN, or on COPY OUT if written to something other than pset.queryFout.
908+
* Returning NULL prevents the command status from being printed, which we
909+
* want if the status line doesn't get taken as part of the COPY data.
910+
*/
911+
static bool
912+
HandleCopyResult(PGresult **resultp)
913+
{
914+
bool success;
915+
FILE *copystream;
916+
PGresult *copy_result;
917+
ExecStatusType result_status = PQresultStatus(*resultp);
918+
919+
Assert(result_status == PGRES_COPY_OUT ||
920+
result_status == PGRES_COPY_IN);
921+
922+
SetCancelConn(pset.db);
923+
924+
if (result_status == PGRES_COPY_OUT)
925+
{
926+
bool need_close = false;
927+
bool is_pipe = false;
928+
929+
if (pset.copyStream)
930+
{
931+
/* invoked by \copy */
932+
copystream = pset.copyStream;
933+
}
934+
else if (pset.gfname)
935+
{
936+
/* invoked by \g */
937+
if (openQueryOutputFile(pset.gfname,
938+
&copystream, &is_pipe))
939+
{
940+
need_close = true;
941+
if (is_pipe)
942+
disable_sigpipe_trap();
943+
}
944+
else
945+
copystream = NULL; /* discard COPY data entirely */
946+
}
947+
else
948+
{
949+
/* fall back to the generic query output stream */
950+
copystream = pset.queryFout;
951+
}
952+
953+
success = handleCopyOut(pset.db,
954+
copystream,
955+
&copy_result)
956+
&& (copystream != NULL);
957+
958+
/*
959+
* Suppress status printing if the report would go to the same
960+
* place as the COPY data just went. Note this doesn't
961+
* prevent error reporting, since handleCopyOut did that.
962+
*/
963+
if (copystream == pset.queryFout)
964+
{
965+
PQclear(copy_result);
966+
copy_result = NULL;
967+
}
968+
969+
if (need_close)
970+
{
971+
/* close \g argument file/pipe */
972+
if (is_pipe)
973+
{
974+
pclose(copystream);
975+
restore_sigpipe_trap();
976+
}
977+
else
978+
{
979+
fclose(copystream);
980+
}
981+
}
982+
}
983+
else
984+
{
985+
/* COPY IN */
986+
copystream = pset.copyStream ? pset.copyStream : pset.cur_cmd_source;
987+
success = handleCopyIn(pset.db,
988+
copystream,
989+
PQbinaryTuples(*resultp),
990+
&copy_result);
991+
}
992+
ResetCancelConn();
993+
994+
/*
995+
* Replace the PGRES_COPY_OUT/IN result with COPY command's exit
996+
* status, or with NULL if we want to suppress printing anything.
997+
*/
998+
PQclear(*resultp);
999+
*resultp = copy_result;
1000+
1001+
return success;
1002+
}
1003+
1004+
8951005
/*
8961006
* ProcessResult: utility function for use by SendQuery() only
8971007
*
@@ -957,99 +1067,7 @@ ProcessResult(PGresult **resultp)
9571067
}
9581068

9591069
if (is_copy)
960-
{
961-
/*
962-
* Marshal the COPY data. Either subroutine will get the
963-
* connection out of its COPY state, then call PQresultStatus()
964-
* once and report any error.
965-
*
966-
* For COPY OUT, direct the output to pset.copyStream if it's set,
967-
* otherwise to pset.gfname if it's set, otherwise to queryFout.
968-
* For COPY IN, use pset.copyStream as data source if it's set,
969-
* otherwise cur_cmd_source.
970-
*/
971-
FILE *copystream;
972-
PGresult *copy_result;
973-
974-
SetCancelConn(pset.db);
975-
if (result_status == PGRES_COPY_OUT)
976-
{
977-
bool need_close = false;
978-
bool is_pipe = false;
979-
980-
if (pset.copyStream)
981-
{
982-
/* invoked by \copy */
983-
copystream = pset.copyStream;
984-
}
985-
else if (pset.gfname)
986-
{
987-
/* invoked by \g */
988-
if (openQueryOutputFile(pset.gfname,
989-
&copystream, &is_pipe))
990-
{
991-
need_close = true;
992-
if (is_pipe)
993-
disable_sigpipe_trap();
994-
}
995-
else
996-
copystream = NULL; /* discard COPY data entirely */
997-
}
998-
else
999-
{
1000-
/* fall back to the generic query output stream */
1001-
copystream = pset.queryFout;
1002-
}
1003-
1004-
success = handleCopyOut(pset.db,
1005-
copystream,
1006-
&copy_result)
1007-
&& success
1008-
&& (copystream != NULL);
1009-
1010-
/*
1011-
* Suppress status printing if the report would go to the same
1012-
* place as the COPY data just went. Note this doesn't
1013-
* prevent error reporting, since handleCopyOut did that.
1014-
*/
1015-
if (copystream == pset.queryFout)
1016-
{
1017-
PQclear(copy_result);
1018-
copy_result = NULL;
1019-
}
1020-
1021-
if (need_close)
1022-
{
1023-
/* close \g argument file/pipe */
1024-
if (is_pipe)
1025-
{
1026-
pclose(copystream);
1027-
restore_sigpipe_trap();
1028-
}
1029-
else
1030-
{
1031-
fclose(copystream);
1032-
}
1033-
}
1034-
}
1035-
else
1036-
{
1037-
/* COPY IN */
1038-
copystream = pset.copyStream ? pset.copyStream : pset.cur_cmd_source;
1039-
success = handleCopyIn(pset.db,
1040-
copystream,
1041-
PQbinaryTuples(*resultp),
1042-
&copy_result) && success;
1043-
}
1044-
ResetCancelConn();
1045-
1046-
/*
1047-
* Replace the PGRES_COPY_OUT/IN result with COPY command's exit
1048-
* status, or with NULL if we want to suppress printing anything.
1049-
*/
1050-
PQclear(*resultp);
1051-
*resultp = copy_result;
1052-
}
1070+
success = HandleCopyResult(resultp);
10531071
else if (first_cycle)
10541072
{
10551073
/* fast path: no COPY commands; PQexec visited all results */

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy