2 * psql - the PostgreSQL interactive terminal
4 * Copyright (c) 2000-2022, PostgreSQL Global Development Group
6 * src/bin/psql/common.c
8 #include "postgres_fe.h"
16 #include <unistd.h> /* for write() */
18 #include <io.h> /* for _write() */
24 #include "common/logging.h"
26 #include "crosstabview.h"
27 #include "fe_utils/cancel.h"
28 #include "fe_utils/mbprint.h"
29 #include "fe_utils/string_utils.h"
30 #include "portability/instr_time.h"
33 static bool DescribeQuery(const char *query
, double *elapsed_msec
);
34 static bool ExecQueryUsingCursor(const char *query
, double *elapsed_msec
);
35 static int ExecQueryAndProcessResults(const char *query
, double *elapsed_msec
, bool *svpt_gone_p
,
36 bool is_watch
, const printQueryOpt
*opt
, FILE *printQueryFout
);
37 static bool command_no_begin(const char *query
);
38 static bool is_select_command(const char *query
);
42 * openQueryOutputFile --- attempt to open a query output file
44 * fname == NULL selects stdout, else an initial '|' selects a pipe,
47 * Returns output file pointer into *fout, and is-a-pipe flag into *is_pipe.
48 * Caller is responsible for adjusting SIGPIPE state if it's a pipe.
50 * On error, reports suitable error message and returns false.
53 openQueryOutputFile(const char *fname
, FILE **fout
, bool *is_pipe
)
55 if (!fname
|| fname
[0] == '\0')
60 else if (*fname
== '|')
62 *fout
= popen(fname
+ 1, "w");
67 *fout
= fopen(fname
, "w");
73 pg_log_error("%s: %m", fname
);
82 * -- handler for -o command line option and \o command
84 * On success, updates pset with the new output file and returns true.
85 * On failure, returns false without changing pset state.
88 setQFout(const char *fname
)
93 /* First make sure we can open the new output file/pipe */
94 if (!openQueryOutputFile(fname
, &fout
, &is_pipe
))
97 /* Close old file/pipe */
98 if (pset
.queryFout
&& pset
.queryFout
!= stdout
&& pset
.queryFout
!= stderr
)
100 if (pset
.queryFoutPipe
)
101 pclose(pset
.queryFout
);
103 fclose(pset
.queryFout
);
106 pset
.queryFout
= fout
;
107 pset
.queryFoutPipe
= is_pipe
;
109 /* Adjust SIGPIPE handling appropriately: ignore signal if is_pipe */
110 set_sigpipe_trap_state(is_pipe
);
111 restore_sigpipe_trap();
118 * Variable-fetching callback for flex lexer
120 * If the specified variable exists, return its value as a string (malloc'd
121 * and expected to be freed by the caller); else return NULL.
123 * If "quote" isn't PQUOTE_PLAIN, then return the value suitably quoted and
124 * escaped for the specified quoting requirement. (Failure in escaping
125 * should lead to printing an error and returning NULL.)
127 * "passthrough" is the pointer previously given to psql_scan_set_passthrough.
128 * In psql, passthrough points to a ConditionalStack, which we check to
129 * determine whether variable expansion is allowed.
132 psql_get_variable(const char *varname
, PsqlScanQuoteType quote
,
138 /* In an inactive \if branch, suppress all variable substitutions */
139 if (passthrough
&& !conditional_active((ConditionalStack
) passthrough
))
142 value
= GetVariable(pset
.vars
, varname
);
149 result
= pg_strdup(value
);
151 case PQUOTE_SQL_LITERAL
:
152 case PQUOTE_SQL_IDENT
:
155 * For these cases, we use libpq's quoting functions, which
156 * assume the string is in the connection's client encoding.
162 pg_log_error("cannot escape without active connection");
166 if (quote
== PQUOTE_SQL_LITERAL
)
168 PQescapeLiteral(pset
.db
, value
, strlen(value
));
171 PQescapeIdentifier(pset
.db
, value
, strlen(value
));
173 if (escaped_value
== NULL
)
175 const char *error
= PQerrorMessage(pset
.db
);
177 pg_log_info("%s", error
);
182 * Rather than complicate the lexer's API with a notion of
183 * which free() routine to use, just pay the price of an extra
186 result
= pg_strdup(escaped_value
);
187 PQfreemem(escaped_value
);
190 case PQUOTE_SHELL_ARG
:
193 * For this we use appendShellStringNoError, which is
194 * encoding-agnostic, which is fine since the shell probably
195 * is too. In any case, the only special character is "'",
196 * which is not known to appear in valid multibyte characters.
200 initPQExpBuffer(&buf
);
201 if (!appendShellStringNoError(&buf
, value
))
203 pg_log_error("shell command argument contains a newline or carriage return: \"%s\"",
212 /* No default: we want a compiler warning for missing cases */
220 * for backend Notice messages (INFO, WARNING, etc)
223 NoticeProcessor(void *arg
, const char *message
)
225 (void) arg
; /* not used */
226 pg_log_info("%s", message
);
232 * Code to support query cancellation
234 * Before we start a query, we enable the SIGINT signal catcher to send a
235 * cancel request to the backend.
237 * SIGINT is supposed to abort all long-running psql operations, not only
238 * database queries. In most places, this is accomplished by checking
239 * cancel_pressed during long-running loops. However, that won't work when
240 * blocked on user input (in readline() or fgets()). In those places, we
241 * set sigint_interrupt_enabled true while blocked, instructing the signal
242 * catcher to longjmp through sigint_interrupt_jmp. We assume readline and
243 * fgets are coded to handle possible interruption.
245 * On Windows, currently this does not work, so control-C is less useful
248 volatile bool sigint_interrupt_enabled
= false;
250 sigjmp_buf sigint_interrupt_jmp
;
253 psql_cancel_callback(void)
256 /* if we are waiting for input, longjmp out of it */
257 if (sigint_interrupt_enabled
)
259 sigint_interrupt_enabled
= false;
260 siglongjmp(sigint_interrupt_jmp
, 1);
264 /* else, set cancel flag to stop any long-running loops */
265 cancel_pressed
= true;
269 psql_setup_cancel_handler(void)
271 setup_cancel_handler(psql_cancel_callback
);
277 * Returns whether our backend connection is still there.
282 return PQstatus(pset
.db
) != CONNECTION_BAD
;
289 * Verify that we still have a good connection to the backend, and if not,
290 * see if it can be restored.
292 * Returns true if either the connection was still there, or it could be
293 * restored successfully; false otherwise. If, however, there was no
294 * connection and the session is non-interactive, this will exit the program
295 * with a code of EXIT_BADCONN.
298 CheckConnection(void)
305 if (!pset
.cur_cmd_interactive
)
307 pg_log_error("connection to server was lost");
311 fprintf(stderr
, _("The connection to the server was lost. Attempting reset: "));
316 fprintf(stderr
, _("Failed.\n"));
319 * Transition to having no connection; but stash away the failed
320 * connection so that we can still refer to its parameters in a
321 * later \connect attempt. Keep the state cleanup here in sync
325 PQfinish(pset
.dead_conn
);
326 pset
.dead_conn
= pset
.db
;
333 fprintf(stderr
, _("Succeeded.\n"));
336 * Re-sync, just in case anything changed. Keep this in sync with
340 connection_warnings(false); /* Must be after SyncVariables */
353 * Checks whether a result is valid, giving an error message if necessary;
354 * and ensures that the connection to the backend is still up.
356 * Returns true for valid result, false for error state.
359 AcceptResult(const PGresult
*result
, bool show_error
)
366 switch (PQresultStatus(result
))
368 case PGRES_COMMAND_OK
:
369 case PGRES_TUPLES_OK
:
370 case PGRES_EMPTY_QUERY
:
373 /* Fine, do nothing */
377 case PGRES_BAD_RESPONSE
:
378 case PGRES_NONFATAL_ERROR
:
379 case PGRES_FATAL_ERROR
:
385 pg_log_error("unexpected PQresultStatus: %d",
386 PQresultStatus(result
));
390 if (!OK
&& show_error
)
392 const char *error
= PQerrorMessage(pset
.db
);
395 pg_log_info("%s", error
);
405 * Set special variables from a query result
406 * - ERROR: true/false, whether an error occurred on this query
407 * - SQLSTATE: code of error, or "00000" if no error, or "" if unknown
408 * - ROW_COUNT: how many rows were returned or affected, or "0"
409 * - LAST_ERROR_SQLSTATE: same for last error
410 * - LAST_ERROR_MESSAGE: message of last error
412 * Note: current policy is to apply this only to the results of queries
413 * entered by the user, not queries generated by slash commands.
416 SetResultVariables(PGresult
*result
, bool success
)
420 const char *ntuples
= PQcmdTuples(result
);
422 SetVariable(pset
.vars
, "ERROR", "false");
423 SetVariable(pset
.vars
, "SQLSTATE", "00000");
424 SetVariable(pset
.vars
, "ROW_COUNT", *ntuples
? ntuples
: "0");
428 const char *code
= PQresultErrorField(result
, PG_DIAG_SQLSTATE
);
429 const char *mesg
= PQresultErrorField(result
, PG_DIAG_MESSAGE_PRIMARY
);
431 SetVariable(pset
.vars
, "ERROR", "true");
434 * If there is no SQLSTATE code, use an empty string. This can happen
435 * for libpq-detected errors (e.g., lost connection, ENOMEM).
439 SetVariable(pset
.vars
, "SQLSTATE", code
);
440 SetVariable(pset
.vars
, "ROW_COUNT", "0");
441 SetVariable(pset
.vars
, "LAST_ERROR_SQLSTATE", code
);
442 SetVariable(pset
.vars
, "LAST_ERROR_MESSAGE", mesg
? mesg
: "");
450 * If the result represents an error, remember it for possible display by
451 * \errverbose. Otherwise, just PQclear() it.
453 * Note: current policy is to apply this to the results of all queries,
454 * including "back door" queries, for debugging's sake. It's OK to use
455 * PQclear() directly on results known to not be error results, however.
458 ClearOrSaveResult(PGresult
*result
)
462 switch (PQresultStatus(result
))
464 case PGRES_NONFATAL_ERROR
:
465 case PGRES_FATAL_ERROR
:
466 if (pset
.last_error_result
)
467 PQclear(pset
.last_error_result
);
468 pset
.last_error_result
= result
;
480 * Consume all results
483 ClearOrSaveAllResults(void)
487 while ((result
= PQgetResult(pset
.db
)) != NULL
)
488 ClearOrSaveResult(result
);
493 * Print microtiming output. Always print raw milliseconds; if the interval
494 * is >= 1 second, also break it down into days/hours/minutes/seconds.
497 PrintTiming(double elapsed_msec
)
504 if (elapsed_msec
< 1000.0)
506 /* This is the traditional (pre-v10) output format */
507 printf(_("Time: %.3f ms\n"), elapsed_msec
);
512 * Note: we could print just seconds, in a format like %06.3f, when the
513 * total is less than 1min. But that's hard to interpret unless we tack
514 * on "s" or otherwise annotate it. Forcing the display to include
515 * minutes seems like a better solution.
517 seconds
= elapsed_msec
/ 1000.0;
518 minutes
= floor(seconds
/ 60.0);
519 seconds
-= 60.0 * minutes
;
522 printf(_("Time: %.3f ms (%02d:%06.3f)\n"),
523 elapsed_msec
, (int) minutes
, seconds
);
527 hours
= floor(minutes
/ 60.0);
528 minutes
-= 60.0 * hours
;
531 printf(_("Time: %.3f ms (%02d:%02d:%06.3f)\n"),
532 elapsed_msec
, (int) hours
, (int) minutes
, seconds
);
536 days
= floor(hours
/ 24.0);
537 hours
-= 24.0 * days
;
538 printf(_("Time: %.3f ms (%.0f d %02d:%02d:%06.3f)\n"),
539 elapsed_msec
, days
, (int) hours
, (int) minutes
, seconds
);
546 * This is the way to send "backdoor" queries (those not directly entered
547 * by the user). It is subject to -E but not -e.
549 * Caller is responsible for handling the ensuing processing if a COPY
552 * Note: we don't bother to check PQclientEncoding; it is assumed that no
553 * caller uses this path to issue "SET CLIENT_ENCODING".
556 PSQLexec(const char *query
)
562 pg_log_error("You are currently not connected to a database.");
566 if (pset
.echo_hidden
!= PSQL_ECHO_HIDDEN_OFF
)
568 printf(_("********* QUERY **********\n"
570 "**************************\n\n"), query
);
574 fprintf(pset
.logfile
,
575 _("********* QUERY **********\n"
577 "**************************\n\n"), query
);
578 fflush(pset
.logfile
);
581 if (pset
.echo_hidden
== PSQL_ECHO_HIDDEN_NOEXEC
)
585 SetCancelConn(pset
.db
);
587 res
= PQexec(pset
.db
, query
);
591 if (!AcceptResult(res
, true))
593 ClearOrSaveResult(res
);
604 * This function is used for \watch command to send the query to
605 * the server and print out the result.
607 * Returns 1 if the query executed successfully, 0 if it cannot be repeated,
608 * e.g., because of the interrupt, -1 on error.
611 PSQLexecWatch(const char *query
, const printQueryOpt
*opt
, FILE *printQueryFout
)
613 bool timing
= pset
.timing
;
614 double elapsed_msec
= 0;
619 pg_log_error("You are currently not connected to a database.");
623 SetCancelConn(pset
.db
);
625 res
= ExecQueryAndProcessResults(query
, &elapsed_msec
, NULL
, true, opt
, printQueryFout
);
629 /* Possible microtiming output */
631 PrintTiming(elapsed_msec
);
638 * PrintNotifications: check for asynchronous notifications, and print them out
641 PrintNotifications(void)
645 PQconsumeInput(pset
.db
);
646 while ((notify
= PQnotifies(pset
.db
)) != NULL
)
648 /* for backward compatibility, only show payload if nonempty */
649 if (notify
->extra
[0])
650 fprintf(pset
.queryFout
, _("Asynchronous notification \"%s\" with payload \"%s\" received from server process with PID %d.\n"),
651 notify
->relname
, notify
->extra
, notify
->be_pid
);
653 fprintf(pset
.queryFout
, _("Asynchronous notification \"%s\" received from server process with PID %d.\n"),
654 notify
->relname
, notify
->be_pid
);
655 fflush(pset
.queryFout
);
657 PQconsumeInput(pset
.db
);
663 * PrintQueryTuples: assuming query result is OK, print its tuples
665 * Returns true if successful, false otherwise.
668 PrintQueryTuples(const PGresult
*result
, const printQueryOpt
*opt
, FILE *printQueryFout
)
672 /* write output to \g argument, if any */
678 if (!openQueryOutputFile(pset
.gfname
, &fout
, &is_pipe
))
681 disable_sigpipe_trap();
683 printQuery(result
, &pset
.popt
, fout
, false, pset
.logfile
);
686 pg_log_error("could not print result table: %m");
693 restore_sigpipe_trap();
700 FILE *fout
= printQueryFout
? printQueryFout
: pset
.queryFout
;
702 printQuery(result
, opt
? opt
: &pset
.popt
, fout
, false, pset
.logfile
);
705 pg_log_error("could not print result table: %m");
715 * StoreQueryTuple: assuming query result is OK, save data into variables
717 * Returns true if successful, false otherwise.
720 StoreQueryTuple(const PGresult
*result
)
724 if (PQntuples(result
) < 1)
726 pg_log_error("no rows returned for \\gset");
729 else if (PQntuples(result
) > 1)
731 pg_log_error("more than one row returned for \\gset");
738 for (i
= 0; i
< PQnfields(result
); i
++)
740 char *colname
= PQfname(result
, i
);
744 /* concatenate prefix and column name */
745 varname
= psprintf("%s%s", pset
.gset_prefix
, colname
);
747 if (VariableHasHook(pset
.vars
, varname
))
749 pg_log_warning("attempt to \\gset into specially treated variable \"%s\" ignored",
754 if (!PQgetisnull(result
, 0, i
))
755 value
= PQgetvalue(result
, 0, i
);
758 /* for NULL value, unset rather than set the variable */
762 if (!SetVariable(pset
.vars
, varname
, value
))
778 * ExecQueryTuples: assuming query result is OK, execute each query
779 * result field as a SQL statement
781 * Returns true if successful, false otherwise.
784 ExecQueryTuples(const PGresult
*result
)
787 int nrows
= PQntuples(result
);
788 int ncolumns
= PQnfields(result
);
793 * We must turn off gexec_flag to avoid infinite recursion. Note that
794 * this allows ExecQueryUsingCursor to be applied to the individual query
795 * results. SendQuery prevents it from being applied when fetching the
796 * queries-to-execute, because it can't handle recursion either.
798 pset
.gexec_flag
= false;
800 for (r
= 0; r
< nrows
; r
++)
802 for (c
= 0; c
< ncolumns
; c
++)
804 if (!PQgetisnull(result
, r
, c
))
806 const char *query
= PQgetvalue(result
, r
, c
);
808 /* Abandon execution if cancel_pressed */
813 * ECHO_ALL mode should echo these queries, but SendQuery
814 * assumes that MainLoop did that, so we have to do it here.
816 if (pset
.echo
== PSQL_ECHO_ALL
&& !pset
.singlestep
)
822 if (!SendQuery(query
))
824 /* Error - abandon execution if ON_ERROR_STOP */
826 if (pset
.on_error_stop
)
836 * Restore state. We know gexec_flag was on, else we'd not be here. (We
837 * also know it'll get turned off at end of command, but that's not ours
840 pset
.gexec_flag
= true;
842 /* Return true if all queries were successful */
848 * Marshal the COPY data. Either subroutine will get the
849 * connection out of its COPY state, then call PQresultStatus()
850 * once and report any error. Return whether all was ok.
852 * For COPY OUT, direct the output to pset.copyStream if it's set,
853 * otherwise to pset.gfname if it's set, otherwise to queryFout.
854 * For COPY IN, use pset.copyStream as data source if it's set,
855 * otherwise cur_cmd_source.
857 * Update result if further processing is necessary, or NULL otherwise.
858 * Return a result when queryFout can safely output a result status: on COPY
859 * IN, or on COPY OUT if written to something other than pset.queryFout.
860 * Returning NULL prevents the command status from being printed, which we
861 * want if the status line doesn't get taken as part of the COPY data.
864 HandleCopyResult(PGresult
**resultp
)
868 PGresult
*copy_result
;
869 ExecStatusType result_status
= PQresultStatus(*resultp
);
871 Assert(result_status
== PGRES_COPY_OUT
||
872 result_status
== PGRES_COPY_IN
);
874 SetCancelConn(pset
.db
);
876 if (result_status
== PGRES_COPY_OUT
)
878 bool need_close
= false;
879 bool is_pipe
= false;
883 /* invoked by \copy */
884 copystream
= pset
.copyStream
;
886 else if (pset
.gfname
)
889 if (openQueryOutputFile(pset
.gfname
,
890 ©stream
, &is_pipe
))
894 disable_sigpipe_trap();
897 copystream
= NULL
; /* discard COPY data entirely */
901 /* fall back to the generic query output stream */
902 copystream
= pset
.queryFout
;
905 success
= handleCopyOut(pset
.db
,
908 && (copystream
!= NULL
);
911 * Suppress status printing if the report would go to the same place
912 * as the COPY data just went. Note this doesn't prevent error
913 * reporting, since handleCopyOut did that.
915 if (copystream
== pset
.queryFout
)
917 PQclear(copy_result
);
923 /* close \g argument file/pipe */
927 restore_sigpipe_trap();
938 copystream
= pset
.copyStream
? pset
.copyStream
: pset
.cur_cmd_source
;
939 success
= handleCopyIn(pset
.db
,
941 PQbinaryTuples(*resultp
),
947 * Replace the PGRES_COPY_OUT/IN result with COPY command's exit status,
948 * or with NULL if we want to suppress printing anything.
951 *resultp
= copy_result
;
957 * PrintQueryStatus: report command status as required
959 * Note: Utility function for use by PrintQueryResult() only.
962 PrintQueryStatus(PGresult
*result
, FILE *printQueryFout
)
965 FILE *fout
= printQueryFout
? printQueryFout
: pset
.queryFout
;
969 if (pset
.popt
.topt
.format
== PRINT_HTML
)
972 html_escaped_print(PQcmdStatus(result
), fout
);
973 fputs("</p>\n", fout
);
976 fprintf(fout
, "%s\n", PQcmdStatus(result
));
980 fprintf(pset
.logfile
, "%s\n", PQcmdStatus(result
));
982 snprintf(buf
, sizeof(buf
), "%u", (unsigned int) PQoidValue(result
));
983 SetVariable(pset
.vars
, "LASTOID", buf
);
988 * PrintQueryResult: print out (or store or execute) query result as required
990 * Note: Utility function for use by SendQuery() only.
992 * Returns true if the query executed successfully, false otherwise.
995 PrintQueryResult(PGresult
*result
, bool last
, bool is_watch
, const printQueryOpt
*opt
, FILE *printQueryFout
)
998 const char *cmdstatus
;
1003 switch (PQresultStatus(result
))
1005 case PGRES_TUPLES_OK
:
1006 /* store or execute or print the data ... */
1007 if (last
&& pset
.gset_prefix
)
1008 success
= StoreQueryTuple(result
);
1009 else if (last
&& pset
.gexec_flag
)
1010 success
= ExecQueryTuples(result
);
1011 else if (last
&& pset
.crosstab_flag
)
1012 success
= PrintResultInCrosstab(result
);
1013 else if (last
|| pset
.show_all_results
)
1014 success
= PrintQueryTuples(result
, opt
, printQueryFout
);
1018 /* if it's INSERT/UPDATE/DELETE RETURNING, also print status */
1019 if (last
|| pset
.show_all_results
)
1021 cmdstatus
= PQcmdStatus(result
);
1022 if (strncmp(cmdstatus
, "INSERT", 6) == 0 ||
1023 strncmp(cmdstatus
, "UPDATE", 6) == 0 ||
1024 strncmp(cmdstatus
, "DELETE", 6) == 0)
1025 PrintQueryStatus(result
, printQueryFout
);
1030 case PGRES_COMMAND_OK
:
1031 if (last
|| pset
.show_all_results
)
1032 PrintQueryStatus(result
, printQueryFout
);
1036 case PGRES_EMPTY_QUERY
:
1040 case PGRES_COPY_OUT
:
1042 /* nothing to do here: already processed */
1046 case PGRES_BAD_RESPONSE
:
1047 case PGRES_NONFATAL_ERROR
:
1048 case PGRES_FATAL_ERROR
:
1054 pg_log_error("unexpected PQresultStatus: %d",
1055 PQresultStatus(result
));
1059 fflush(printQueryFout
? printQueryFout
: pset
.queryFout
);
1065 * Data structure and functions to record notices while they are
1066 * emitted, so that they can be shown later.
1068 * We need to know which result is last, which requires to extract
1069 * one result in advance, hence two buffers are needed.
1071 struct t_notice_messages
1073 PQExpBufferData messages
[2];
1078 * Store notices in appropriate buffer, for later display.
1081 AppendNoticeMessage(void *arg
, const char *msg
)
1083 struct t_notice_messages
*notices
= arg
;
1085 appendPQExpBufferStr(¬ices
->messages
[notices
->current
], msg
);
1089 * Show notices stored in buffer, which is then reset.
1092 ShowNoticeMessage(struct t_notice_messages
*notices
)
1094 PQExpBufferData
*current
= ¬ices
->messages
[notices
->current
];
1096 if (*current
->data
!= '\0')
1097 pg_log_info("%s", current
->data
);
1098 resetPQExpBuffer(current
);
1103 * SendQuery: send the query string to the backend
1104 * (and print out result)
1106 * Note: This is the "front door" way to send a query. That is, use it to
1107 * send queries actually entered by the user. These queries will be subject to
1109 * To send "back door" queries (generated by slash commands, etc.) in a
1110 * controlled way, use PSQLexec().
1112 * Returns true if the query executed successfully, false otherwise.
1115 SendQuery(const char *query
)
1117 bool timing
= pset
.timing
;
1118 PGTransactionStatusType transaction_status
;
1119 double elapsed_msec
= 0;
1122 bool on_error_rollback_savepoint
= false;
1123 bool svpt_gone
= false;
1127 pg_log_error("You are currently not connected to a database.");
1128 goto sendquery_cleanup
;
1131 if (pset
.singlestep
)
1136 printf(_("***(Single step mode: verify command)*******************************************\n"
1138 "***(press return to proceed or enter x and return to cancel)********************\n"),
1141 if (fgets(buf
, sizeof(buf
), stdin
) != NULL
)
1143 goto sendquery_cleanup
;
1145 goto sendquery_cleanup
;
1147 else if (pset
.echo
== PSQL_ECHO_QUERIES
)
1155 fprintf(pset
.logfile
,
1156 _("********* QUERY **********\n"
1158 "**************************\n\n"), query
);
1159 fflush(pset
.logfile
);
1162 SetCancelConn(pset
.db
);
1164 transaction_status
= PQtransactionStatus(pset
.db
);
1166 if (transaction_status
== PQTRANS_IDLE
&&
1168 !command_no_begin(query
))
1172 result
= PQexec(pset
.db
, "BEGIN");
1173 if (PQresultStatus(result
) != PGRES_COMMAND_OK
)
1175 pg_log_info("%s", PQerrorMessage(pset
.db
));
1176 ClearOrSaveResult(result
);
1177 goto sendquery_cleanup
;
1179 ClearOrSaveResult(result
);
1180 transaction_status
= PQtransactionStatus(pset
.db
);
1183 if (transaction_status
== PQTRANS_INTRANS
&&
1184 pset
.on_error_rollback
!= PSQL_ERROR_ROLLBACK_OFF
&&
1185 (pset
.cur_cmd_interactive
||
1186 pset
.on_error_rollback
== PSQL_ERROR_ROLLBACK_ON
))
1190 result
= PQexec(pset
.db
, "SAVEPOINT pg_psql_temporary_savepoint");
1191 if (PQresultStatus(result
) != PGRES_COMMAND_OK
)
1193 pg_log_info("%s", PQerrorMessage(pset
.db
));
1194 ClearOrSaveResult(result
);
1195 goto sendquery_cleanup
;
1197 ClearOrSaveResult(result
);
1198 on_error_rollback_savepoint
= true;
1201 if (pset
.gdesc_flag
)
1203 /* Describe query's result columns, without executing it */
1204 OK
= DescribeQuery(query
, &elapsed_msec
);
1206 else if (pset
.fetch_count
<= 0 || pset
.gexec_flag
||
1207 pset
.crosstab_flag
|| !is_select_command(query
))
1209 /* Default fetch-it-all-and-print mode */
1210 OK
= (ExecQueryAndProcessResults(query
, &elapsed_msec
, &svpt_gone
, false, NULL
, NULL
) >= 0);
1214 /* Fetch-in-segments mode */
1215 OK
= ExecQueryUsingCursor(query
, &elapsed_msec
);
1218 if (!OK
&& pset
.echo
== PSQL_ECHO_ERRORS
)
1219 pg_log_info("STATEMENT: %s", query
);
1221 /* If we made a temporary savepoint, possibly release/rollback */
1222 if (on_error_rollback_savepoint
)
1224 const char *svptcmd
= NULL
;
1226 transaction_status
= PQtransactionStatus(pset
.db
);
1228 switch (transaction_status
)
1230 case PQTRANS_INERROR
:
1231 /* We always rollback on an error */
1232 svptcmd
= "ROLLBACK TO pg_psql_temporary_savepoint";
1236 /* If they are no longer in a transaction, then do nothing */
1239 case PQTRANS_INTRANS
:
1242 * Release our savepoint, but do nothing if they are messing
1243 * with savepoints themselves
1246 svptcmd
= "RELEASE pg_psql_temporary_savepoint";
1249 case PQTRANS_ACTIVE
:
1250 case PQTRANS_UNKNOWN
:
1253 /* PQTRANS_UNKNOWN is expected given a broken connection. */
1254 if (transaction_status
!= PQTRANS_UNKNOWN
|| ConnectionUp())
1255 pg_log_error("unexpected transaction status (%d)",
1256 transaction_status
);
1264 svptres
= PQexec(pset
.db
, svptcmd
);
1265 if (PQresultStatus(svptres
) != PGRES_COMMAND_OK
)
1267 pg_log_info("%s", PQerrorMessage(pset
.db
));
1268 ClearOrSaveResult(svptres
);
1271 goto sendquery_cleanup
;
1277 /* Possible microtiming output */
1279 PrintTiming(elapsed_msec
);
1281 /* check for events that may occur during query execution */
1283 if (pset
.encoding
!= PQclientEncoding(pset
.db
) &&
1284 PQclientEncoding(pset
.db
) >= 0)
1286 /* track effects of SET CLIENT_ENCODING */
1287 pset
.encoding
= PQclientEncoding(pset
.db
);
1288 pset
.popt
.topt
.encoding
= pset
.encoding
;
1289 SetVariable(pset
.vars
, "ENCODING",
1290 pg_encoding_to_char(pset
.encoding
));
1293 PrintNotifications();
1295 /* perform cleanup that should occur after any attempted query */
1299 /* global cancellation reset */
1302 /* reset \g's output-to-filename trigger */
1309 /* restore print settings if \g changed them */
1312 restorePsetInfo(&pset
.popt
, pset
.gsavepopt
);
1313 pset
.gsavepopt
= NULL
;
1316 /* reset \gset trigger */
1317 if (pset
.gset_prefix
)
1319 free(pset
.gset_prefix
);
1320 pset
.gset_prefix
= NULL
;
1323 /* reset \gdesc trigger */
1324 pset
.gdesc_flag
= false;
1326 /* reset \gexec trigger */
1327 pset
.gexec_flag
= false;
1329 /* reset \crosstabview trigger */
1330 pset
.crosstab_flag
= false;
1331 for (i
= 0; i
< lengthof(pset
.ctv_args
); i
++)
1333 pg_free(pset
.ctv_args
[i
]);
1334 pset
.ctv_args
[i
] = NULL
;
1342 * DescribeQuery: describe the result columns of a query, without executing it
1344 * Returns true if the operation executed successfully, false otherwise.
1346 * If pset.timing is on, total query time (exclusive of result-printing) is
1347 * stored into *elapsed_msec.
1350 DescribeQuery(const char *query
, double *elapsed_msec
)
1352 bool timing
= pset
.timing
;
1361 INSTR_TIME_SET_CURRENT(before
);
1364 * To parse the query but not execute it, we prepare it, using the unnamed
1365 * prepared statement. This is invisible to psql users, since there's no
1366 * way to access the unnamed prepared statement from psql user space. The
1367 * next Parse or Query protocol message would overwrite the statement
1368 * anyway. (So there's no great need to clear it when done, which is a
1369 * good thing because libpq provides no easy way to do that.)
1371 result
= PQprepare(pset
.db
, "", query
, 0, NULL
);
1372 if (PQresultStatus(result
) != PGRES_COMMAND_OK
)
1374 pg_log_info("%s", PQerrorMessage(pset
.db
));
1375 SetResultVariables(result
, false);
1376 ClearOrSaveResult(result
);
1381 result
= PQdescribePrepared(pset
.db
, "");
1382 OK
= AcceptResult(result
, true) &&
1383 (PQresultStatus(result
) == PGRES_COMMAND_OK
);
1386 if (PQnfields(result
) > 0)
1388 PQExpBufferData buf
;
1391 initPQExpBuffer(&buf
);
1393 printfPQExpBuffer(&buf
,
1394 "SELECT name AS \"%s\", pg_catalog.format_type(tp, tpm) AS \"%s\"\n"
1396 gettext_noop("Column"),
1397 gettext_noop("Type"));
1399 for (i
= 0; i
< PQnfields(result
); i
++)
1405 appendPQExpBufferStr(&buf
, ",");
1407 name
= PQfname(result
, i
);
1408 escname
= PQescapeLiteral(pset
.db
, name
, strlen(name
));
1410 if (escname
== NULL
)
1412 pg_log_info("%s", PQerrorMessage(pset
.db
));
1414 termPQExpBuffer(&buf
);
1418 appendPQExpBuffer(&buf
, "(%s, '%u'::pg_catalog.oid, %d)",
1426 appendPQExpBufferStr(&buf
, ") s(name, tp, tpm)");
1429 result
= PQexec(pset
.db
, buf
.data
);
1430 OK
= AcceptResult(result
, true);
1434 INSTR_TIME_SET_CURRENT(after
);
1435 INSTR_TIME_SUBTRACT(after
, before
);
1436 *elapsed_msec
+= INSTR_TIME_GET_MILLISEC(after
);
1440 OK
= PrintQueryResult(result
, true, false, NULL
, NULL
);
1442 termPQExpBuffer(&buf
);
1445 fprintf(pset
.queryFout
,
1446 _("The command has no result, or the result has no columns.\n"));
1449 SetResultVariables(result
, OK
);
1450 ClearOrSaveResult(result
);
1457 * ExecQueryAndProcessResults: utility function for use by SendQuery()
1458 * and PSQLexecWatch().
1460 * Sends query and cycles through PGresult objects.
1462 * When not under \watch and if our command string contained a COPY FROM STDIN
1463 * or COPY TO STDOUT, the PGresult associated with these commands must be
1464 * processed by providing an input or output stream. In that event, we'll
1465 * marshal data for the COPY.
1467 * For other commands, the results are processed normally, depending on their
1470 * Returns 1 on complete success, 0 on interrupt and -1 or errors. Possible
1471 * failure modes include purely client-side problems; check the transaction
1472 * status for the server-side opinion.
1474 * Note that on a combined query, failure does not mean that nothing was
1478 ExecQueryAndProcessResults(const char *query
, double *elapsed_msec
, bool *svpt_gone_p
,
1479 bool is_watch
, const printQueryOpt
*opt
, FILE *printQueryFout
)
1481 bool timing
= pset
.timing
;
1486 struct t_notice_messages notices
;
1489 INSTR_TIME_SET_CURRENT(before
);
1491 success
= PQsendQuery(pset
.db
, query
);
1495 const char *error
= PQerrorMessage(pset
.db
);
1498 pg_log_info("%s", error
);
1506 * If SIGINT is sent while the query is processing, the interrupt will be
1507 * consumed. The user's intention, though, is to cancel the entire watch
1508 * process, so detect a sent cancellation request and exit in this case.
1510 if (is_watch
&& cancel_pressed
)
1512 ClearOrSaveAllResults();
1516 /* intercept notices */
1517 notices
.current
= 0;
1518 initPQExpBuffer(¬ices
.messages
[0]);
1519 initPQExpBuffer(¬ices
.messages
[1]);
1520 PQsetNoticeProcessor(pset
.db
, AppendNoticeMessage
, ¬ices
);
1523 result
= PQgetResult(pset
.db
);
1525 while (result
!= NULL
)
1527 ExecStatusType result_status
;
1528 PGresult
*next_result
;
1531 if (!AcceptResult(result
, false))
1534 * Some error occured, either a server-side failure or a failure
1535 * to submit the command string. Record that.
1537 const char *error
= PQresultErrorMessage(result
);
1539 ShowNoticeMessage(¬ices
);
1541 pg_log_info("%s", error
);
1545 SetResultVariables(result
, false);
1547 /* keep the result status before clearing it */
1548 result_status
= PQresultStatus(result
);
1549 ClearOrSaveResult(result
);
1553 * switch to next result
1555 if (result_status
== PGRES_COPY_BOTH
||
1556 result_status
== PGRES_COPY_OUT
||
1557 result_status
== PGRES_COPY_IN
)
1560 * For some obscure reason PQgetResult does *not* return a
1561 * NULL in copy cases despite the result having been cleared,
1562 * but keeps returning an "empty" result that we have to
1567 result
= PQgetResult(pset
.db
);
1570 * Get current timing measure in case an error occurs
1574 INSTR_TIME_SET_CURRENT(after
);
1575 INSTR_TIME_SUBTRACT(after
, before
);
1576 *elapsed_msec
= INSTR_TIME_GET_MILLISEC(after
);
1581 else if (svpt_gone_p
&& !*svpt_gone_p
)
1584 * Check if the user ran any command that would destroy our
1585 * internal savepoint: If the user did COMMIT AND CHAIN, RELEASE
1586 * or ROLLBACK, our savepoint is gone. If they issued a SAVEPOINT,
1587 * releasing ours would remove theirs.
1589 const char *cmd
= PQcmdStatus(result
);
1591 *svpt_gone_p
= (strcmp(cmd
, "COMMIT") == 0 ||
1592 strcmp(cmd
, "SAVEPOINT") == 0 ||
1593 strcmp(cmd
, "RELEASE") == 0 ||
1594 strcmp(cmd
, "ROLLBACK") == 0);
1597 result_status
= PQresultStatus(result
);
1599 /* must handle COPY before changing the current result */
1600 Assert(result_status
!= PGRES_COPY_BOTH
);
1601 if (result_status
== PGRES_COPY_IN
||
1602 result_status
== PGRES_COPY_OUT
)
1604 ShowNoticeMessage(¬ices
);
1608 ClearOrSaveAllResults();
1609 pg_log_error("\\watch cannot be used with COPY");
1613 /* use normal notice processor during COPY */
1614 PQsetNoticeProcessor(pset
.db
, NoticeProcessor
, NULL
);
1616 success
&= HandleCopyResult(&result
);
1618 PQsetNoticeProcessor(pset
.db
, AppendNoticeMessage
, ¬ices
);
1622 * Check PQgetResult() again. In the typical case of a single-command
1623 * string, it will return NULL. Otherwise, we'll have other results
1624 * to process. We need to do that to check whether this is the last.
1626 notices
.current
^= 1;
1627 next_result
= PQgetResult(pset
.db
);
1628 notices
.current
^= 1;
1629 last
= (next_result
== NULL
);
1632 * Update current timing measure.
1634 * It will include the display of previous results, if any. This
1635 * cannot be helped because the server goes on processing further
1636 * queries anyway while the previous ones are being displayed. The
1637 * parallel execution of the client display hides the server time when
1640 * With combined queries, timing must be understood as an upper bound
1641 * of the time spent processing them.
1645 INSTR_TIME_SET_CURRENT(after
);
1646 INSTR_TIME_SUBTRACT(after
, before
);
1647 *elapsed_msec
= INSTR_TIME_GET_MILLISEC(after
);
1650 /* notices already shown above for copy */
1651 ShowNoticeMessage(¬ices
);
1653 /* this may or may not print something depending on settings */
1655 success
&= PrintQueryResult(result
, last
, false, opt
, printQueryFout
);
1657 /* set variables on last result if all went well */
1658 if (!is_watch
&& last
&& success
)
1659 SetResultVariables(result
, true);
1661 ClearOrSaveResult(result
);
1662 notices
.current
^= 1;
1663 result
= next_result
;
1667 ClearOrSaveAllResults();
1672 /* reset notice hook */
1673 PQsetNoticeProcessor(pset
.db
, NoticeProcessor
, NULL
);
1674 termPQExpBuffer(¬ices
.messages
[0]);
1675 termPQExpBuffer(¬ices
.messages
[1]);
1677 /* may need this to recover from conn loss during COPY */
1678 if (!CheckConnection())
1681 return cancel_pressed
? 0 : success
? 1 : -1;
1686 * ExecQueryUsingCursor: run a SELECT-like query using a cursor
1688 * This feature allows result sets larger than RAM to be dealt with.
1690 * Returns true if the query executed successfully, false otherwise.
1692 * If pset.timing is on, total query time (exclusive of result-printing) is
1693 * stored into *elapsed_msec.
1696 ExecQueryUsingCursor(const char *query
, double *elapsed_msec
)
1700 PQExpBufferData buf
;
1701 printQueryOpt my_popt
= pset
.popt
;
1702 bool timing
= pset
.timing
;
1705 bool is_pager
= false;
1706 bool started_txn
= false;
1707 int64 total_tuples
= 0;
1717 /* initialize print options for partial table output */
1718 my_popt
.topt
.start_table
= true;
1719 my_popt
.topt
.stop_table
= false;
1720 my_popt
.topt
.prior_records
= 0;
1723 INSTR_TIME_SET_CURRENT(before
);
1725 /* if we're not in a transaction, start one */
1726 if (PQtransactionStatus(pset
.db
) == PQTRANS_IDLE
)
1728 result
= PQexec(pset
.db
, "BEGIN");
1729 OK
= AcceptResult(result
, true) &&
1730 (PQresultStatus(result
) == PGRES_COMMAND_OK
);
1731 ClearOrSaveResult(result
);
1737 /* Send DECLARE CURSOR */
1738 initPQExpBuffer(&buf
);
1739 appendPQExpBuffer(&buf
, "DECLARE _psql_cursor NO SCROLL CURSOR FOR\n%s",
1742 result
= PQexec(pset
.db
, buf
.data
);
1743 OK
= AcceptResult(result
, true) &&
1744 (PQresultStatus(result
) == PGRES_COMMAND_OK
);
1746 SetResultVariables(result
, OK
);
1747 ClearOrSaveResult(result
);
1748 termPQExpBuffer(&buf
);
1754 INSTR_TIME_SET_CURRENT(after
);
1755 INSTR_TIME_SUBTRACT(after
, before
);
1756 *elapsed_msec
+= INSTR_TIME_GET_MILLISEC(after
);
1760 * In \gset mode, we force the fetch count to be 2, so that we will throw
1761 * the appropriate error if the query returns more than one row.
1763 if (pset
.gset_prefix
)
1766 fetch_count
= pset
.fetch_count
;
1768 snprintf(fetch_cmd
, sizeof(fetch_cmd
),
1769 "FETCH FORWARD %d FROM _psql_cursor",
1772 /* prepare to write output to \g argument, if any */
1775 if (!openQueryOutputFile(pset
.gfname
, &fout
, &is_pipe
))
1781 disable_sigpipe_trap();
1785 fout
= pset
.queryFout
;
1786 is_pipe
= false; /* doesn't matter */
1789 /* clear any pre-existing error indication on the output stream */
1795 INSTR_TIME_SET_CURRENT(before
);
1797 /* get fetch_count tuples at a time */
1798 result
= PQexec(pset
.db
, fetch_cmd
);
1802 INSTR_TIME_SET_CURRENT(after
);
1803 INSTR_TIME_SUBTRACT(after
, before
);
1804 *elapsed_msec
+= INSTR_TIME_GET_MILLISEC(after
);
1807 if (PQresultStatus(result
) != PGRES_TUPLES_OK
)
1809 /* shut down pager before printing error message */
1816 OK
= AcceptResult(result
, true);
1818 SetResultVariables(result
, OK
);
1819 ClearOrSaveResult(result
);
1823 if (pset
.gset_prefix
)
1825 /* StoreQueryTuple will complain if not exactly one row */
1826 OK
= StoreQueryTuple(result
);
1827 ClearOrSaveResult(result
);
1832 * Note we do not deal with \gdesc, \gexec or \crosstabview modes here
1835 ntuples
= PQntuples(result
);
1836 total_tuples
+= ntuples
;
1838 if (ntuples
< fetch_count
)
1840 /* this is the last result set, so allow footer decoration */
1841 my_popt
.topt
.stop_table
= true;
1843 else if (fout
== stdout
&& !is_pager
)
1846 * If query requires multiple result sets, hack to ensure that
1847 * only one pager instance is used for the whole mess
1849 fout
= PageOutput(INT_MAX
, &(my_popt
.topt
));
1853 printQuery(result
, &my_popt
, fout
, is_pager
, pset
.logfile
);
1855 ClearOrSaveResult(result
);
1857 /* after the first result set, disallow header decoration */
1858 my_popt
.topt
.start_table
= false;
1859 my_popt
.topt
.prior_records
+= ntuples
;
1862 * Make sure to flush the output stream, so intermediate results are
1863 * visible to the client immediately. We check the results because if
1864 * the pager dies/exits/etc, there's no sense throwing more data at
1867 flush_error
= fflush(fout
);
1870 * Check if we are at the end, if a cancel was pressed, or if there
1871 * were any errors either trying to flush out the results, or more
1872 * generally on the output stream at all. If we hit any errors
1873 * writing things to the stream, we presume $PAGER has disappeared and
1874 * stop bothering to pull down more data.
1876 if (ntuples
< fetch_count
|| cancel_pressed
|| flush_error
||
1883 /* close \g argument file/pipe */
1887 restore_sigpipe_trap();
1894 /* close transient pager */
1901 * We don't have a PGresult here, and even if we did it wouldn't have
1902 * the right row count, so fake SetResultVariables(). In error cases,
1903 * we already set the result variables above.
1907 SetVariable(pset
.vars
, "ERROR", "false");
1908 SetVariable(pset
.vars
, "SQLSTATE", "00000");
1909 snprintf(buf
, sizeof(buf
), INT64_FORMAT
, total_tuples
);
1910 SetVariable(pset
.vars
, "ROW_COUNT", buf
);
1915 INSTR_TIME_SET_CURRENT(before
);
1918 * We try to close the cursor on either success or failure, but on failure
1919 * ignore the result (it's probably just a bleat about being in an aborted
1922 result
= PQexec(pset
.db
, "CLOSE _psql_cursor");
1925 OK
= AcceptResult(result
, true) &&
1926 (PQresultStatus(result
) == PGRES_COMMAND_OK
);
1927 ClearOrSaveResult(result
);
1934 result
= PQexec(pset
.db
, OK
? "COMMIT" : "ROLLBACK");
1935 OK
&= AcceptResult(result
, true) &&
1936 (PQresultStatus(result
) == PGRES_COMMAND_OK
);
1937 ClearOrSaveResult(result
);
1942 INSTR_TIME_SET_CURRENT(after
);
1943 INSTR_TIME_SUBTRACT(after
, before
);
1944 *elapsed_msec
+= INSTR_TIME_GET_MILLISEC(after
);
1952 * Advance the given char pointer over white space and SQL comments.
1955 skip_white_space(const char *query
)
1957 int cnestlevel
= 0; /* slash-star comment nest level */
1961 int mblen
= PQmblenBounded(query
, pset
.encoding
);
1964 * Note: we assume the encoding is a superset of ASCII, so that for
1965 * example "query[0] == '/'" is meaningful. However, we do NOT assume
1966 * that the second and subsequent bytes of a multibyte character
1967 * couldn't look like ASCII characters; so it is critical to advance
1968 * by mblen, not 1, whenever we haven't exactly identified the
1969 * character we are skipping over.
1971 if (isspace((unsigned char) *query
))
1973 else if (query
[0] == '/' && query
[1] == '*')
1978 else if (cnestlevel
> 0 && query
[0] == '*' && query
[1] == '/')
1983 else if (cnestlevel
== 0 && query
[0] == '-' && query
[1] == '-')
1988 * We have to skip to end of line since any slash-star inside the
1989 * -- comment does NOT start a slash-star comment.
1998 query
+= PQmblenBounded(query
, pset
.encoding
);
2001 else if (cnestlevel
> 0)
2004 break; /* found first token */
2012 * Check whether a command is one of those for which we should NOT start
2013 * a new transaction block (ie, send a preceding BEGIN).
2015 * These include the transaction control statements themselves, plus
2016 * certain statements that the backend disallows inside transaction blocks.
2019 command_no_begin(const char *query
)
2024 * First we must advance over any whitespace and comments.
2026 query
= skip_white_space(query
);
2029 * Check word length (since "beginx" is not "begin").
2032 while (isalpha((unsigned char) query
[wordlen
]))
2033 wordlen
+= PQmblenBounded(&query
[wordlen
], pset
.encoding
);
2036 * Transaction control commands. These should include every keyword that
2037 * gives rise to a TransactionStmt in the backend grammar, except for the
2038 * savepoint-related commands.
2040 * (We assume that START must be START TRANSACTION, since there is
2041 * presently no other "START foo" command.)
2043 if (wordlen
== 5 && pg_strncasecmp(query
, "abort", 5) == 0)
2045 if (wordlen
== 5 && pg_strncasecmp(query
, "begin", 5) == 0)
2047 if (wordlen
== 5 && pg_strncasecmp(query
, "start", 5) == 0)
2049 if (wordlen
== 6 && pg_strncasecmp(query
, "commit", 6) == 0)
2051 if (wordlen
== 3 && pg_strncasecmp(query
, "end", 3) == 0)
2053 if (wordlen
== 8 && pg_strncasecmp(query
, "rollback", 8) == 0)
2055 if (wordlen
== 7 && pg_strncasecmp(query
, "prepare", 7) == 0)
2057 /* PREPARE TRANSACTION is a TC command, PREPARE foo is not */
2060 query
= skip_white_space(query
);
2063 while (isalpha((unsigned char) query
[wordlen
]))
2064 wordlen
+= PQmblenBounded(&query
[wordlen
], pset
.encoding
);
2066 if (wordlen
== 11 && pg_strncasecmp(query
, "transaction", 11) == 0)
2072 * Commands not allowed within transactions. The statements checked for
2073 * here should be exactly those that call PreventInTransactionBlock() in
2076 if (wordlen
== 6 && pg_strncasecmp(query
, "vacuum", 6) == 0)
2078 if (wordlen
== 7 && pg_strncasecmp(query
, "cluster", 7) == 0)
2080 /* CLUSTER with any arguments is allowed in transactions */
2083 query
= skip_white_space(query
);
2085 if (isalpha((unsigned char) query
[0]))
2086 return false; /* has additional words */
2087 return true; /* it's CLUSTER without arguments */
2090 if (wordlen
== 6 && pg_strncasecmp(query
, "create", 6) == 0)
2094 query
= skip_white_space(query
);
2097 while (isalpha((unsigned char) query
[wordlen
]))
2098 wordlen
+= PQmblenBounded(&query
[wordlen
], pset
.encoding
);
2100 if (wordlen
== 8 && pg_strncasecmp(query
, "database", 8) == 0)
2102 if (wordlen
== 10 && pg_strncasecmp(query
, "tablespace", 10) == 0)
2105 /* CREATE [UNIQUE] INDEX CONCURRENTLY isn't allowed in xacts */
2106 if (wordlen
== 6 && pg_strncasecmp(query
, "unique", 6) == 0)
2110 query
= skip_white_space(query
);
2113 while (isalpha((unsigned char) query
[wordlen
]))
2114 wordlen
+= PQmblenBounded(&query
[wordlen
], pset
.encoding
);
2117 if (wordlen
== 5 && pg_strncasecmp(query
, "index", 5) == 0)
2121 query
= skip_white_space(query
);
2124 while (isalpha((unsigned char) query
[wordlen
]))
2125 wordlen
+= PQmblenBounded(&query
[wordlen
], pset
.encoding
);
2127 if (wordlen
== 12 && pg_strncasecmp(query
, "concurrently", 12) == 0)
2134 if (wordlen
== 5 && pg_strncasecmp(query
, "alter", 5) == 0)
2138 query
= skip_white_space(query
);
2141 while (isalpha((unsigned char) query
[wordlen
]))
2142 wordlen
+= PQmblenBounded(&query
[wordlen
], pset
.encoding
);
2144 /* ALTER SYSTEM isn't allowed in xacts */
2145 if (wordlen
== 6 && pg_strncasecmp(query
, "system", 6) == 0)
2152 * Note: these tests will match DROP SYSTEM and REINDEX TABLESPACE, which
2153 * aren't really valid commands so we don't care much. The other four
2154 * possible matches are correct.
2156 if ((wordlen
== 4 && pg_strncasecmp(query
, "drop", 4) == 0) ||
2157 (wordlen
== 7 && pg_strncasecmp(query
, "reindex", 7) == 0))
2161 query
= skip_white_space(query
);
2164 while (isalpha((unsigned char) query
[wordlen
]))
2165 wordlen
+= PQmblenBounded(&query
[wordlen
], pset
.encoding
);
2167 if (wordlen
== 8 && pg_strncasecmp(query
, "database", 8) == 0)
2169 if (wordlen
== 6 && pg_strncasecmp(query
, "system", 6) == 0)
2171 if (wordlen
== 10 && pg_strncasecmp(query
, "tablespace", 10) == 0)
2173 if (wordlen
== 5 && (pg_strncasecmp(query
, "index", 5) == 0 ||
2174 pg_strncasecmp(query
, "table", 5) == 0))
2177 query
= skip_white_space(query
);
2179 while (isalpha((unsigned char) query
[wordlen
]))
2180 wordlen
+= PQmblenBounded(&query
[wordlen
], pset
.encoding
);
2183 * REINDEX [ TABLE | INDEX ] CONCURRENTLY are not allowed in
2186 if (wordlen
== 12 && pg_strncasecmp(query
, "concurrently", 12) == 0)
2190 /* DROP INDEX CONCURRENTLY isn't allowed in xacts */
2191 if (wordlen
== 5 && pg_strncasecmp(query
, "index", 5) == 0)
2195 query
= skip_white_space(query
);
2198 while (isalpha((unsigned char) query
[wordlen
]))
2199 wordlen
+= PQmblenBounded(&query
[wordlen
], pset
.encoding
);
2201 if (wordlen
== 12 && pg_strncasecmp(query
, "concurrently", 12) == 0)
2210 /* DISCARD ALL isn't allowed in xacts, but other variants are allowed. */
2211 if (wordlen
== 7 && pg_strncasecmp(query
, "discard", 7) == 0)
2215 query
= skip_white_space(query
);
2218 while (isalpha((unsigned char) query
[wordlen
]))
2219 wordlen
+= PQmblenBounded(&query
[wordlen
], pset
.encoding
);
2221 if (wordlen
== 3 && pg_strncasecmp(query
, "all", 3) == 0)
2231 * Check whether the specified command is a SELECT (or VALUES).
2234 is_select_command(const char *query
)
2239 * First advance over any whitespace, comments and left parentheses.
2243 query
= skip_white_space(query
);
2244 if (query
[0] == '(')
2251 * Check word length (since "selectx" is not "select").
2254 while (isalpha((unsigned char) query
[wordlen
]))
2255 wordlen
+= PQmblenBounded(&query
[wordlen
], pset
.encoding
);
2257 if (wordlen
== 6 && pg_strncasecmp(query
, "select", 6) == 0)
2260 if (wordlen
== 6 && pg_strncasecmp(query
, "values", 6) == 0)
2268 * Test if the current user is a database superuser.
2278 val
= PQparameterStatus(pset
.db
, "is_superuser");
2280 if (val
&& strcmp(val
, "on") == 0)
2288 * Test if the current session uses standard string literals.
2291 standard_strings(void)
2298 val
= PQparameterStatus(pset
.db
, "standard_conforming_strings");
2300 if (val
&& strcmp(val
, "on") == 0)
2308 * Return the session user of the current connection.
2311 session_username(void)
2318 val
= PQparameterStatus(pset
.db
, "session_authorization");
2322 return PQuser(pset
.db
);
2328 * substitute '~' with HOME or '~username' with username's home dir
2332 expand_tilde(char **filename
)
2334 if (!filename
|| !(*filename
))
2338 * WIN32 doesn't use tilde expansion for file names. Also, it uses tilde
2339 * for short versions of long file names, though the tilde is usually
2340 * toward the end, not at the beginning.
2344 /* try tilde expansion */
2345 if (**filename
== '~')
2351 char home
[MAXPGPATH
];
2357 while (*p
!= '/' && *p
!= '\0')
2363 if (*(fn
+ 1) == '\0')
2364 get_home_path(home
); /* ~ or ~/ only */
2365 else if ((pw
= getpwnam(fn
+ 1)) != NULL
)
2366 strlcpy(home
, pw
->pw_dir
, sizeof(home
)); /* ~user */
2369 if (strlen(home
) != 0)
2373 newfn
= psprintf("%s%s", home
, p
);
2382 * Checks if connection string starts with either of the valid URI prefix
2385 * Returns the URI prefix length, 0 if the string doesn't contain a URI prefix.
2387 * XXX This is a duplicate of the eponymous libpq function.
2390 uri_prefix_length(const char *connstr
)
2392 /* The connection URI must start with either of the following designators: */
2393 static const char uri_designator
[] = "postgresql://";
2394 static const char short_uri_designator
[] = "postgres://";
2396 if (strncmp(connstr
, uri_designator
,
2397 sizeof(uri_designator
) - 1) == 0)
2398 return sizeof(uri_designator
) - 1;
2400 if (strncmp(connstr
, short_uri_designator
,
2401 sizeof(short_uri_designator
) - 1) == 0)
2402 return sizeof(short_uri_designator
) - 1;
2408 * Recognized connection string either starts with a valid URI prefix or
2409 * contains a "=" in it.
2411 * Must be consistent with parse_connection_string: anything for which this
2412 * returns true should at least look like it's parseable by that routine.
2414 * XXX This is a duplicate of the eponymous libpq function.
2417 recognized_connection_string(const char *connstr
)
2419 return uri_prefix_length(connstr
) != 0 || strchr(connstr
, '=') != NULL
;