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)