Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit f6f654f

Browse files
committed
Allow \watch to display query execution time if \timing is enabled.
Previously \watch could not display the query execution time even when \timing was enabled because it used PSQLexec instead of SendQuery and that function didn't support \timing. This patch introduces PSQLexecWatch and changes \watch so as to use it, instead. PSQLexecWatch is the function to run the query, print its results and display how long it took (only when \timing is enabled). This patch also changes --echo-hidden so that it doesn't print the query that \watch executes. Since \watch cannot execute backslash command queries, they should not be printed even when --echo-hidden is set. Patch by me, review by Heikki Linnakangas and Michael Paquier
1 parent 4b91ade commit f6f654f

File tree

3 files changed

+109
-53
lines changed

3 files changed

+109
-53
lines changed

src/bin/psql/command.c

+10-53
Original file line numberDiff line numberDiff line change
@@ -2687,7 +2687,7 @@ do_watch(PQExpBuffer query_buf, long sleep)
26872687

26882688
for (;;)
26892689
{
2690-
PGresult *res;
2690+
int res;
26912691
time_t timer;
26922692
long i;
26932693

@@ -2700,65 +2700,22 @@ do_watch(PQExpBuffer query_buf, long sleep)
27002700
sleep, asctime(localtime(&timer)));
27012701
myopt.title = title;
27022702

2703-
/*
2704-
* Run the query. We use PSQLexec, which is kind of cheating, but
2705-
* SendQuery doesn't let us suppress autocommit behavior.
2706-
*/
2707-
res = PSQLexec(query_buf->data, false);
2708-
2709-
/* PSQLexec handles failure results and returns NULL */
2710-
if (res == NULL)
2711-
break;
2703+
/* Run the query and print out the results */
2704+
res = PSQLexecWatch(query_buf->data, &myopt);
27122705

27132706
/*
2714-
* If SIGINT is sent while the query is processing, PSQLexec will
2715-
* consume the interrupt. The user's intention, though, is to cancel
2716-
* the entire watch process, so detect a sent cancellation request and
2717-
* exit in this case.
2707+
* PSQLexecWatch handles the case where we can no longer
2708+
* repeat the query, and returns 0 or -1.
27182709
*/
2719-
if (cancel_pressed)
2720-
{
2721-
PQclear(res);
2710+
if (res == 0)
27222711
break;
2723-
}
2724-
2725-
switch (PQresultStatus(res))
2726-
{
2727-
case PGRES_TUPLES_OK:
2728-
printQuery(res, &myopt, pset.queryFout, pset.logfile);
2729-
break;
2730-
2731-
case PGRES_COMMAND_OK:
2732-
fprintf(pset.queryFout, "%s\n%s\n\n", title, PQcmdStatus(res));
2733-
break;
2734-
2735-
case PGRES_EMPTY_QUERY:
2736-
psql_error(_("\\watch cannot be used with an empty query\n"));
2737-
PQclear(res);
2738-
return false;
2739-
2740-
case PGRES_COPY_OUT:
2741-
case PGRES_COPY_IN:
2742-
case PGRES_COPY_BOTH:
2743-
psql_error(_("\\watch cannot be used with COPY\n"));
2744-
PQclear(res);
2745-
return false;
2746-
2747-
default:
2748-
/* other cases should have been handled by PSQLexec */
2749-
psql_error(_("unexpected result status for \\watch\n"));
2750-
PQclear(res);
2751-
return false;
2752-
}
2753-
2754-
PQclear(res);
2755-
2756-
fflush(pset.queryFout);
2712+
if (res == -1)
2713+
return false;
27572714

27582715
/*
27592716
* Set up cancellation of 'watch' via SIGINT. We redo this each time
2760-
* through the loop since it's conceivable something inside PSQLexec
2761-
* could change sigint_interrupt_jmp.
2717+
* through the loop since it's conceivable something inside
2718+
* PSQLexecWatch could change sigint_interrupt_jmp.
27622719
*/
27632720
if (sigsetjmp(sigint_interrupt_jmp, 1) != 0)
27642721
break;

src/bin/psql/common.c

+96
Original file line numberDiff line numberDiff line change
@@ -497,6 +497,102 @@ PSQLexec(const char *query, bool start_xact)
497497
}
498498

499499

500+
/*
501+
* PSQLexecWatch
502+
*
503+
* This function is used for \watch command to send the query to
504+
* the server and print out the results.
505+
*
506+
* Returns 1 if the query executed successfully, 0 if it cannot be repeated,
507+
* e.g., because of the interrupt, -1 on error.
508+
*/
509+
int
510+
PSQLexecWatch(const char *query, const printQueryOpt *opt)
511+
{
512+
PGresult *res;
513+
double elapsed_msec = 0;
514+
instr_time before;
515+
instr_time after;
516+
517+
if (!pset.db)
518+
{
519+
psql_error("You are currently not connected to a database.\n");
520+
return 0;
521+
}
522+
523+
SetCancelConn();
524+
525+
if (pset.timing)
526+
INSTR_TIME_SET_CURRENT(before);
527+
528+
res = PQexec(pset.db, query);
529+
530+
ResetCancelConn();
531+
532+
if (!AcceptResult(res))
533+
{
534+
PQclear(res);
535+
return 0;
536+
}
537+
538+
if (pset.timing)
539+
{
540+
INSTR_TIME_SET_CURRENT(after);
541+
INSTR_TIME_SUBTRACT(after, before);
542+
elapsed_msec = INSTR_TIME_GET_MILLISEC(after);
543+
}
544+
545+
/*
546+
* If SIGINT is sent while the query is processing, the interrupt
547+
* will be consumed. The user's intention, though, is to cancel
548+
* the entire watch process, so detect a sent cancellation request and
549+
* exit in this case.
550+
*/
551+
if (cancel_pressed)
552+
{
553+
PQclear(res);
554+
return 0;
555+
}
556+
557+
switch (PQresultStatus(res))
558+
{
559+
case PGRES_TUPLES_OK:
560+
printQuery(res, opt, pset.queryFout, pset.logfile);
561+
break;
562+
563+
case PGRES_COMMAND_OK:
564+
fprintf(pset.queryFout, "%s\n%s\n\n", opt->title, PQcmdStatus(res));
565+
break;
566+
567+
case PGRES_EMPTY_QUERY:
568+
psql_error(_("\\watch cannot be used with an empty query\n"));
569+
PQclear(res);
570+
return -1;
571+
572+
case PGRES_COPY_OUT:
573+
case PGRES_COPY_IN:
574+
case PGRES_COPY_BOTH:
575+
psql_error(_("\\watch cannot be used with COPY\n"));
576+
PQclear(res);
577+
return -1;
578+
579+
default:
580+
psql_error(_("unexpected result status for \\watch\n"));
581+
PQclear(res);
582+
return -1;
583+
}
584+
585+
PQclear(res);
586+
587+
fflush(pset.queryFout);
588+
589+
/* Possible microtiming output */
590+
if (pset.timing)
591+
printf(_("Time: %.3f ms\n"), elapsed_msec);
592+
593+
return 1;
594+
}
595+
500596

501597
/*
502598
* PrintNotifications: check for asynchronous notifications, and print them out

src/bin/psql/common.h

+3
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
#include <setjmp.h>
1313
#include "libpq-fe.h"
1414

15+
#include "print.h"
16+
1517
#define atooid(x) ((Oid) strtoul((x), NULL, 10))
1618

1719
extern bool setQFout(const char *fname);
@@ -37,6 +39,7 @@ extern void SetCancelConn(void);
3739
extern void ResetCancelConn(void);
3840

3941
extern PGresult *PSQLexec(const char *query, bool start_xact);
42+
extern int PSQLexecWatch(const char *query, const printQueryOpt *opt);
4043

4144
extern bool SendQuery(const char *query);
4245

0 commit comments

Comments
 (0)