Skip to content

Commit 8910a25

Browse files
committed
psql: Refactor SendQuery()
This breaks out the fetch-it-all-and-print case in SendQuery() into a separate function. This makes the code more similar to the other cases \gdesc and run query with FETCH_COUNT, and makes SendQuery() itself a bit smaller. Extracted from a larger patch with more changes in this area to follow. Author: Fabien COELHO <coelho@cri.ensmp.fr> Discussion: https://www.postgresql.org/message-id/flat/alpine.DEB.2.21.1904132231510.8961@lancre
1 parent 878e64d commit 8910a25

File tree

1 file changed

+64
-40
lines changed

1 file changed

+64
-40
lines changed

src/bin/psql/common.c

Lines changed: 64 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232

3333
static bool DescribeQuery(const char *query, double *elapsed_msec);
3434
static bool ExecQueryUsingCursor(const char *query, double *elapsed_msec);
35+
static bool ExecQueryAndProcessResult(const char *query, double *elapsed_msec, bool *svpt_gone_p);
3536
static bool command_no_begin(const char *query);
3637
static bool is_select_command(const char *query);
3738

@@ -1195,12 +1196,12 @@ bool
11951196
SendQuery(const char *query)
11961197
{
11971198
bool timing = pset.timing;
1198-
PGresult *result;
11991199
PGTransactionStatusType transaction_status;
12001200
double elapsed_msec = 0;
12011201
bool OK = false;
12021202
int i;
12031203
bool on_error_rollback_savepoint = false;
1204+
bool svpt_gone = false;
12041205

12051206
if (!pset.db)
12061207
{
@@ -1247,6 +1248,8 @@ SendQuery(const char *query)
12471248
!pset.autocommit &&
12481249
!command_no_begin(query))
12491250
{
1251+
PGresult *result;
1252+
12501253
result = PQexec(pset.db, "BEGIN");
12511254
if (PQresultStatus(result) != PGRES_COMMAND_OK)
12521255
{
@@ -1264,6 +1267,8 @@ SendQuery(const char *query)
12641267
(pset.cur_cmd_interactive ||
12651268
pset.on_error_rollback == PSQL_ERROR_ROLLBACK_ON))
12661269
{
1270+
PGresult *result;
1271+
12671272
result = PQexec(pset.db, "SAVEPOINT pg_psql_temporary_savepoint");
12681273
if (PQresultStatus(result) != PGRES_COMMAND_OK)
12691274
{
@@ -1281,41 +1286,18 @@ SendQuery(const char *query)
12811286
/* Describe query's result columns, without executing it */
12821287
OK = DescribeQuery(query, &elapsed_msec);
12831288
ResetCancelConn();
1284-
result = NULL; /* PQclear(NULL) does nothing */
12851289
}
12861290
else if (pset.fetch_count <= 0 || pset.gexec_flag ||
12871291
pset.crosstab_flag || !is_select_command(query))
12881292
{
12891293
/* Default fetch-it-all-and-print mode */
1290-
instr_time before,
1291-
after;
1292-
1293-
if (timing)
1294-
INSTR_TIME_SET_CURRENT(before);
1295-
1296-
result = PQexec(pset.db, query);
1297-
1298-
/* these operations are included in the timing result: */
1299-
ResetCancelConn();
1300-
OK = ProcessResult(&result);
1301-
1302-
if (timing)
1303-
{
1304-
INSTR_TIME_SET_CURRENT(after);
1305-
INSTR_TIME_SUBTRACT(after, before);
1306-
elapsed_msec = INSTR_TIME_GET_MILLISEC(after);
1307-
}
1308-
1309-
/* but printing result isn't: */
1310-
if (OK && result)
1311-
OK = PrintQueryResult(result);
1294+
OK = ExecQueryAndProcessResult(query, &elapsed_msec, &svpt_gone);
13121295
}
13131296
else
13141297
{
13151298
/* Fetch-in-segments mode */
13161299
OK = ExecQueryUsingCursor(query, &elapsed_msec);
13171300
ResetCancelConn();
1318-
result = NULL; /* PQclear(NULL) does nothing */
13191301
}
13201302

13211303
if (!OK && pset.echo == PSQL_ECHO_ERRORS)
@@ -1340,20 +1322,11 @@ SendQuery(const char *query)
13401322
break;
13411323

13421324
case PQTRANS_INTRANS:
1343-
13441325
/*
1345-
* Do nothing if they are messing with savepoints themselves:
1346-
* If the user did COMMIT AND CHAIN, RELEASE or ROLLBACK, our
1347-
* savepoint is gone. If they issued a SAVEPOINT, releasing
1348-
* ours would remove theirs.
1326+
* Release our savepoint, but do nothing if they are messing
1327+
* with savepoints themselves
13491328
*/
1350-
if (result &&
1351-
(strcmp(PQcmdStatus(result), "COMMIT") == 0 ||
1352-
strcmp(PQcmdStatus(result), "SAVEPOINT") == 0 ||
1353-
strcmp(PQcmdStatus(result), "RELEASE") == 0 ||
1354-
strcmp(PQcmdStatus(result), "ROLLBACK") == 0))
1355-
svptcmd = NULL;
1356-
else
1329+
if (!svpt_gone)
13571330
svptcmd = "RELEASE pg_psql_temporary_savepoint";
13581331
break;
13591332

@@ -1379,16 +1352,13 @@ SendQuery(const char *query)
13791352
ClearOrSaveResult(svptres);
13801353
OK = false;
13811354

1382-
PQclear(result);
13831355
ResetCancelConn();
13841356
goto sendquery_cleanup;
13851357
}
13861358
PQclear(svptres);
13871359
}
13881360
}
13891361

1390-
ClearOrSaveResult(result);
1391-
13921362
/* Possible microtiming output */
13931363
if (timing)
13941364
PrintTiming(elapsed_msec);
@@ -1565,6 +1535,60 @@ DescribeQuery(const char *query, double *elapsed_msec)
15651535
}
15661536

15671537

1538+
/*
1539+
* ExecQueryAndProcessResults: SendQuery() subroutine for the normal way to
1540+
* send a query
1541+
*/
1542+
static bool
1543+
ExecQueryAndProcessResult(const char *query, double *elapsed_msec, bool *svpt_gone_p)
1544+
{
1545+
bool timing = pset.timing;
1546+
bool OK;
1547+
instr_time before,
1548+
after;
1549+
PGresult *result;
1550+
1551+
if (timing)
1552+
INSTR_TIME_SET_CURRENT(before);
1553+
1554+
result = PQexec(pset.db, query);
1555+
1556+
/* these operations are included in the timing result: */
1557+
ResetCancelConn();
1558+
OK = ProcessResult(&result);
1559+
1560+
if (timing)
1561+
{
1562+
INSTR_TIME_SET_CURRENT(after);
1563+
INSTR_TIME_SUBTRACT(after, before);
1564+
*elapsed_msec = INSTR_TIME_GET_MILLISEC(after);
1565+
}
1566+
1567+
/* but printing result isn't: */
1568+
if (OK && result)
1569+
OK = PrintQueryResult(result);
1570+
1571+
/*
1572+
* Check if the user ran any command that would destroy our internal
1573+
* savepoint: If the user did COMMIT AND CHAIN, RELEASE or ROLLBACK, our
1574+
* savepoint is gone. If they issued a SAVEPOINT, releasing ours would
1575+
* remove theirs.
1576+
*/
1577+
if (result && svpt_gone_p)
1578+
{
1579+
const char *cmd = PQcmdStatus(result);
1580+
*svpt_gone_p = (strcmp(cmd, "COMMIT") == 0 ||
1581+
strcmp(cmd, "SAVEPOINT") == 0 ||
1582+
strcmp(cmd, "RELEASE") == 0 ||
1583+
strcmp(cmd, "ROLLBACK") == 0);
1584+
}
1585+
1586+
ClearOrSaveResult(result);
1587+
1588+
return OK;
1589+
}
1590+
1591+
15681592
/*
15691593
* ExecQueryUsingCursor: run a SELECT-like query using a cursor
15701594
*

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