2 * psql - the PostgreSQL interactive terminal
4 * Copyright (c) 2000-2025, PostgreSQL Global Development Group
6 * src/bin/psql/common.c
18#include <io.h> /* for _write() */
33static bool DescribeQuery(
const char *query,
double *elapsed_msec);
40 FILE *printQueryFout);
45 * openQueryOutputFile --- attempt to open a query output file
47 * fname == NULL selects stdout, else an initial '|' selects a pipe,
50 * Returns output file pointer into *fout, and is-a-pipe flag into *is_pipe.
51 * Caller is responsible for adjusting SIGPIPE state if it's a pipe.
53 * On error, reports suitable error message and returns false.
58 if (!fname || fname[0] ==
'0円')
63 else if (*fname ==
'|')
66 *fout = popen(fname + 1,
"w");
71 *fout = fopen(fname,
"w");
85 * Check if an output stream for \g needs to be opened, and if yes,
86 * open it and update the caller's gfile_fout and is_pipe state variables.
87 * Return true if OK, false if an error occurred.
92 /* If there is a \g file or program, and it's not already open, open it */
93 if (
pset.
gfname != NULL && *gfile_fout == NULL)
107 * Close the output stream for \g, if we opened it.
125 * Reset pset pipeline state
138 * -- handler for -o command line option and \o command
140 * On success, updates pset with the new output file and returns true.
141 * On failure, returns false without changing pset state.
149 /* First make sure we can open the new output file/pipe */
153 /* Close old file/pipe */
165 /* Adjust SIGPIPE handling appropriately: ignore signal if is_pipe */
174 * Variable-fetching callback for flex lexer
176 * If the specified variable exists, return its value as a string (malloc'd
177 * and expected to be freed by the caller); else return NULL.
179 * If "quote" isn't PQUOTE_PLAIN, then return the value suitably quoted and
180 * escaped for the specified quoting requirement. (Failure in escaping
181 * should lead to printing an error and returning NULL.)
183 * "passthrough" is the pointer previously given to psql_scan_set_passthrough.
184 * In psql, passthrough points to a ConditionalStack, which we check to
185 * determine whether variable expansion is allowed.
194 /* In an inactive \if branch, suppress all variable substitutions */
211 * For these cases, we use libpq's quoting functions, which
212 * assume the string is in the connection's client encoding.
218 pg_log_error(
"cannot escape without active connection");
229 if (escaped_value == NULL)
238 * Rather than complicate the lexer's API with a notion of
239 * which free() routine to use, just pay the price of an extra
249 * For this we use appendShellStringNoError, which is
250 * encoding-agnostic, which is fine since the shell probably
251 * is too. In any case, the only special character is "'",
252 * which is not known to appear in valid multibyte characters.
259 pg_log_error(
"shell command argument contains a newline or carriage return: \"%s\"",
268 /* No default: we want a compiler warning for missing cases */
276 * for backend Notice messages (INFO, WARNING, etc)
281 (void)
arg;
/* not used */
288 * Code to support query cancellation
290 * Before we start a query, we enable the SIGINT signal catcher to send a
291 * cancel request to the backend.
293 * SIGINT is supposed to abort all long-running psql operations, not only
294 * database queries. In most places, this is accomplished by checking
295 * cancel_pressed during long-running loops. However, that won't work when
296 * blocked on user input (in readline() or fgets()). In those places, we
297 * set sigint_interrupt_enabled true while blocked, instructing the signal
298 * catcher to longjmp through sigint_interrupt_jmp. We assume readline and
299 * fgets are coded to handle possible interruption.
301 * On Windows, currently this does not work, so control-C is less useful
312 /* if we are waiting for input, longjmp out of it */
320 /* else, set cancel flag to stop any long-running loops */
333 * Returns whether our backend connection is still there.
345 * Verify that we still have a good connection to the backend, and if not,
346 * see if it can be restored.
348 * Returns true if either the connection was still there, or it could be
349 * restored successfully; false otherwise. If, however, there was no
350 * connection and the session is non-interactive, this will exit the program
351 * with a code of EXIT_BADCONN.
367 fprintf(stderr,
_(
"The connection to the server was lost. Attempting reset: "));
376 * Transition to having no connection; but stash away the failed
377 * connection so that we can still refer to its parameters in a
378 * later \connect attempt. Keep the state cleanup here in sync
393 * Re-sync, just in case anything changed. Keep this in sync with
410 * Checks whether a result is valid, giving an error message if necessary;
411 * and ensures that the connection to the backend is still up.
413 * Returns true for valid result, false for error state.
432 /* Fine, do nothing */
450 if (!OK && show_error)
465 * Set special variables from a query result
466 * - ERROR: true/false, whether an error occurred on this query
467 * - SQLSTATE: code of error, or "00000" if no error, or "" if unknown
468 * - ROW_COUNT: how many rows were returned or affected, or "0"
469 * - LAST_ERROR_SQLSTATE: same for last error
470 * - LAST_ERROR_MESSAGE: message of last error
472 * Note: current policy is to apply this only to the results of queries
473 * entered by the user, not queries generated by slash commands.
494 * If there is no SQLSTATE code, use an empty string. This can happen
495 * for libpq-detected errors (e.g., lost connection, ENOMEM).
508 * Set special variables from a shell command result
509 * - SHELL_ERROR: true/false, whether command returned exit code 0
510 * - SHELL_EXIT_CODE: exit code according to shell conventions
512 * The argument is a wait status as returned by wait(2) or waitpid(2),
513 * which also applies to pclose(3) and system(3).
521 (wait_result == 0) ?
"false" :
"true");
528 * Set special pipeline variables
529 * - PIPELINE_SYNC_COUNT: The number of piped syncs
530 * - PIPELINE_COMMAND_COUNT: The number of piped commands
531 * - PIPELINE_RESULT_COUNT: The number of results available to read
550 * If the result represents an error, remember it for possible display by
551 * \errverbose. Otherwise, just PQclear() it.
553 * Note: current policy is to apply this to the results of all queries,
554 * including "back door" queries, for debugging's sake. It's OK to use
555 * PQclear() directly on results known to not be error results, however.
579 * Consume all results
592 * Print microtiming output. Always print raw milliseconds; if the interval
593 * is >= 1 second, also break it down into days/hours/minutes/seconds.
603 if (elapsed_msec < 1000.0)
605 /* This is the traditional (pre-v10) output format */
606 printf(
_(
"Time: %.3f ms\n"), elapsed_msec);
611 * Note: we could print just seconds, in a format like %06.3f, when the
612 * total is less than 1min. But that's hard to interpret unless we tack
613 * on "s" or otherwise annotate it. Forcing the display to include
614 * minutes seems like a better solution.
616 seconds = elapsed_msec / 1000.0;
617 minutes = floor(seconds / 60.0);
618 seconds -= 60.0 * minutes;
621 printf(
_(
"Time: %.3f ms (%02d:%06.3f)\n"),
622 elapsed_msec, (
int) minutes, seconds);
626 hours = floor(minutes / 60.0);
627 minutes -= 60.0 * hours;
630 printf(
_(
"Time: %.3f ms (%02d:%02d:%06.3f)\n"),
631 elapsed_msec, (
int) hours, (
int) minutes, seconds);
635 days = floor(hours / 24.0);
636 hours -= 24.0 *
days;
637 printf(
_(
"Time: %.3f ms (%.0f d %02d:%02d:%06.3f)\n"),
638 elapsed_msec,
days, (
int) hours, (
int) minutes, seconds);
645 * This is the way to send "backdoor" queries (those not directly entered
646 * by the user). It is subject to -E but not -e.
648 * Caller is responsible for handling the ensuing processing if a COPY
651 * Note: we don't bother to check PQclientEncoding; it is assumed that no
652 * caller uses this path to issue "SET CLIENT_ENCODING".
661 pg_log_error(
"You are currently not connected to a database.");
667 printf(
_(
"/******** QUERY *********/\n"
669 "/************************/\n\n"), query);
674 _(
"/******** QUERY *********/\n"
676 "/************************/\n\n"), query);
703 * This function is used for \watch command to send the query to
704 * the server and print out the result.
706 * Returns 1 if the query executed successfully, 0 if it cannot be repeated,
707 * e.g., because of the interrupt, -1 on error.
713 double elapsed_msec = 0;
718 pg_log_error(
"You are currently not connected to a database.");
728 /* Possible microtiming output */
737 * PrintNotifications: check for asynchronous notifications, and print them out
747 /* for backward compatibility, only show payload if nonempty */
748 if (notify->
extra[0])
749 fprintf(
pset.
queryFout,
_(
"Asynchronous notification \"%s\" with payload \"%s\" received from server process with PID %d.\n"),
752 fprintf(
pset.
queryFout,
_(
"Asynchronous notification \"%s\" received from server process with PID %d.\n"),
762 * PrintQueryTuples: assuming query result is OK, print its tuples
764 * We use the options given by opt unless that's NULL, in which case
767 * Output is to printQueryFout unless that's NULL, in which case
768 * we use pset.queryFout.
770 * Returns true if successful, false otherwise.
774 FILE *printQueryFout)
777 FILE *fout = printQueryFout ? printQueryFout :
pset.
queryFout;
792 * StoreQueryTuple: assuming query result is OK, save data into variables
794 * Returns true if successful, false otherwise.
821 /* concatenate prefix and column name */
826 pg_log_warning(
"attempt to \\gset into specially treated variable \"%s\" ignored",
835 /* for NULL value, unset rather than set the variable */
855 * ExecQueryTuples: assuming query result is OK, execute each query
856 * result field as a SQL statement
858 * Returns true if successful, false otherwise.
870 * We must turn off gexec_flag to avoid infinite recursion.
874 for (r = 0; r < nrows; r++)
876 for (
c = 0;
c < ncolumns;
c++)
882 /* Abandon execution if cancel_pressed */
887 * ECHO_ALL mode should echo these queries, but SendQuery
888 * assumes that MainLoop did that, so we have to do it here.
898 /* Error - abandon execution if ON_ERROR_STOP */
910 * Restore state. We know gexec_flag was on, else we'd not be here. (We
911 * also know it'll get turned off at end of command, but that's not ours
916 /* Return true if all queries were successful */
922 * Marshal the COPY data. Either path will get the
923 * connection out of its COPY state, then call PQresultStatus()
924 * once and report any error. Return whether all was ok.
926 * For COPY OUT, direct the output to copystream, or discard if that's NULL.
927 * For COPY IN, use pset.copyStream as data source if it's set,
928 * otherwise cur_cmd_source.
930 * Update *resultp if further processing is necessary; set to NULL otherwise.
931 * Return a result when queryFout can safely output a result status: on COPY
932 * IN, or on COPY OUT if written to something other than pset.queryFout.
933 * Returning NULL prevents the command status from being printed, which we
934 * want if the status line doesn't get taken as part of the COPY data.
953 && (copystream != NULL);
956 * Suppress status printing if the report would go to the same place
957 * as the COPY data just went. Note this doesn't prevent error
958 * reporting, since handleCopyOut did that.
969 /* Ignore the copystream argument passed to the function */
979 * Replace the PGRES_COPY_OUT/IN result with COPY command's exit status,
980 * or with NULL if we want to suppress printing anything.
983 *resultp = copy_result;
989 * PrintQueryStatus: report command status as required
996 FILE *fout = printQueryFout ? printQueryFout :
pset.
queryFout;
998 /* Do nothing if it's a TUPLES_OK result that isn't from RETURNING */
1001 if (!(strncmp(cmdstatus,
"INSERT", 6) == 0 ||
1002 strncmp(cmdstatus,
"UPDATE", 6) == 0 ||
1003 strncmp(cmdstatus,
"DELETE", 6) == 0 ||
1004 strncmp(cmdstatus,
"MERGE", 5) == 0))
1014 fputs(
"</p>\n", fout);
1017 fprintf(fout,
"%s\n", cmdstatus);
1030 * PrintQueryResult: print out (or store or execute) query result as required
1032 * last is true if this is the last result of a command string.
1033 * opt and printQueryFout are defined as for PrintQueryTuples.
1034 * printStatusFout is where to send command status; NULL means pset.queryFout.
1036 * Returns true if the query executed successfully, false otherwise.
1041 FILE *printStatusFout)
1051 /* store or execute or print the data ... */
1064 * If it's INSERT/UPDATE/DELETE/MERGE RETURNING, also print
1084 /* nothing to do here: already processed */
1106 * SendQuery: send the query string to the backend
1107 * (and print out result)
1109 * Note: This is the "front door" way to send a query. That is, use it to
1110 * send queries actually entered by the user. These queries will be subject to
1112 * To send "back door" queries (generated by slash commands, etc.) in a
1113 * controlled way, use PSQLexec().
1115 * Returns true if the query executed successfully, false otherwise.
1122 double elapsed_msec = 0;
1125 bool on_error_rollback_savepoint =
false;
1126 bool svpt_gone =
false;
1130 pg_log_error(
"You are currently not connected to a database.");
1131 goto sendquery_cleanup;
1139 printf(
_(
"/**(Single step mode: verify command)******************************************/\n"
1141 "/**(press return to proceed or enter x and return to cancel)*******************/\n"),
1144 if (fgets(
buf,
sizeof(
buf), stdin) != NULL)
1146 goto sendquery_cleanup;
1148 goto sendquery_cleanup;
1159 _(
"/******** QUERY *********/\n"
1161 "/************************/\n\n"), query);
1180 goto sendquery_cleanup;
1193 result =
PQexec(
pset.
db,
"SAVEPOINT pg_psql_temporary_savepoint");
1198 goto sendquery_cleanup;
1201 on_error_rollback_savepoint =
true;
1206 /* Describe query's result columns, without executing it */
1211 /* Default fetch-and-print mode */
1218 /* If we made a temporary savepoint, possibly release/rollback */
1219 if (on_error_rollback_savepoint)
1221 const char *svptcmd = NULL;
1225 switch (transaction_status)
1228 /* We always rollback on an error */
1229 svptcmd =
"ROLLBACK TO pg_psql_temporary_savepoint";
1233 /* If they are no longer in a transaction, then do nothing */
1239 * Release our savepoint, but do nothing if they are messing
1240 * with savepoints themselves
1243 svptcmd =
"RELEASE pg_psql_temporary_savepoint";
1250 /* PQTRANS_UNKNOWN is expected given a broken connection. */
1253 transaction_status);
1268 goto sendquery_cleanup;
1274 /* Possible microtiming output */
1278 /* check for events that may occur during query execution */
1283 /* track effects of SET CLIENT_ENCODING */
1292 /* perform cleanup that should occur after any attempted query */
1296 /* global cancellation reset */
1299 /* reset \g's output-to-filename trigger */
1306 /* restore print settings if \g changed them */
1313 /* clean up after extended protocol queries */
1316 /* reset \gset trigger */
1323 /* reset \gdesc trigger */
1326 /* reset \gexec trigger */
1329 /* reset \crosstabview trigger */
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.
1366 * To parse the query but not execute it, we prepare it, using the unnamed
1367 * prepared statement. This is invisible to psql users, since there's no
1368 * way to access the unnamed prepared statement from psql user space. The
1369 * next Parse or Query protocol message would overwrite the statement
1370 * anyway. (So there's no great need to clear it when done, which is a
1371 * good thing because libpq provides no easy way to do that.)
1396 "SELECT name AS \"%s\", pg_catalog.format_type(tp, tpm) AS \"%s\"\n"
1412 if (escname == NULL)
1448 _(
"The command has no result, or the result has no columns.\n"));
1458 * Read and discard all results in an aborted pipeline.
1460 * If a synchronisation point is found, we can stop discarding results as
1461 * the pipeline will switch back to a clean state. If no synchronisation
1462 * point is available, we need to stop when there are no more pending
1463 * results, otherwise, calling PQgetResult() would block.
1476 * Found a synchronisation point. The sync counter is decremented
1484 * Found a FATAL error sent by the backend, and we cannot recover
1485 * from this state. Instead, return the last result and let the
1486 * outer loop handle it.
1491 * Fetch result to consume the end of the current query being
1495 Assert(fatal_res == NULL);
1498 else if (res == NULL)
1500 /* A query was processed, decrement the counters */
1509 /* We have read all the requested results, leave */
1516 * There are no more results to get and there is no
1517 * synchronisation point to stop at. This will leave the pipeline
1518 * in an aborted state.
1524 * An aborted pipeline will have either NULL results or results in an
1525 * PGRES_PIPELINE_ABORTED status.
1533 * ExecQueryAndProcessResults: utility function for use by SendQuery()
1534 * and PSQLexecWatch().
1536 * Sends query and cycles through PGresult objects.
1538 * If our command string contained a COPY FROM STDIN or COPY TO STDOUT, the
1539 * PGresult associated with these commands must be processed by providing an
1540 * input or output stream. In that event, we'll marshal data for the COPY.
1542 * For other commands, the results are processed normally, depending on their
1543 * status and the status of a pipeline.
1545 * When invoked from \watch, is_watch is true and min_rows is the value
1546 * of that option, or 0 if it wasn't set.
1548 * Returns 1 on complete success, 0 on interrupt and -1 or errors. Possible
1549 * failure modes include purely client-side problems; check the transaction
1550 * status for the server-side opinion.
1552 * Note that on a combined query, failure does not mean that nothing was
1557 double *elapsed_msec,
bool *svpt_gone_p,
1558 bool is_watch,
int min_rows,
1563 bool return_early =
false;
1564 bool end_pipeline =
false;
1568 FILE *gfile_fout = NULL;
1569 bool gfile_is_pipe =
false;
1614 * End of the pipeline, all queued commands need to be
1617 end_pipeline =
true;
1621 * The server will send a ReadyForQuery after a Sync is
1622 * processed, flushing all the results back to the client.
1627 /* We want to read all results */
1638 * The server will send a ReadyForQuery after a Sync is
1639 * processed, flushing all the results back to the client.
1653 * With the flush request, all commands in the pipeline are
1654 * pushed and the server will flush the results back to the
1655 * client, making them available.
1665 * If no sync or flush request were sent, PQgetResult() would
1666 * block as there are no results available. Forbid any
1667 * attempt to get pending results should we try to reach this
1679 * Cap requested_results to the maximum number of known
1691 0, NULL, NULL, NULL, NULL, 0);
1718 * We are in a pipeline and have not reached the pipeline end, or
1719 * there was no request to read pipeline results. Update the psql
1720 * variables tracking the pipeline activity and exit.
1727 * Fetch the result in chunks if FETCH_COUNT is set, except when:
1729 * * SHOW_ALL_RESULTS is false, since that requires us to complete the
1730 * query before we can tell if its results should be displayed.
1732 * * We're doing \crosstab, which likewise needs to see all the rows at
1735 * * We're doing \gexec: we must complete the data fetch to make the
1736 * connection free for issuing the resulting commands.
1738 * * We're doing \gset: only one result row is allowed anyway.
1740 * * We're doing \watch: users probably don't want us to force use of the
1741 * pager for that, plus chunking could break the min_rows check.
1752 * If SIGINT is sent while the query is processing, the interrupt will be
1753 * consumed. The user's intention, though, is to cancel the entire watch
1754 * process, so detect a sent cancellation request and exit in this case.
1764 if (min_rows > 0 &&
PQntuples(result) < min_rows)
1766 return_early =
true;
1769 while (result != NULL)
1772 bool is_chunked_result =
false;
1779 * Some error occurred, either a server-side failure or a failure
1780 * to submit the command string. Record that.
1791 /* keep the result status before clearing it */
1797 pg_log_info(
"Pipeline aborted, command did not run");
1800 * switch to next result
1807 * For some obscure reason PQgetResult does *not* return a
1808 * NULL in copy cases despite the result having been cleared,
1809 * but keeps returning an "empty" result that we have to
1818 * Error within a pipeline. All commands are aborted until
1819 * the next synchronisation point. We need to consume all the
1820 * results until this synchronisation point, or stop when
1821 * there are no more result to discard.
1823 * Checking the pipeline status is necessary for the case
1824 * where the connection was reset. The new connection is not
1825 * in any kind of pipeline state and thus has no result to
1834 * Get current timing measure in case an error occurs
1845 else if (svpt_gone_p && !*svpt_gone_p)
1848 * Check if the user ran any command that would destroy our
1849 * internal savepoint: If the user did COMMIT AND CHAIN, RELEASE
1850 * or ROLLBACK, our savepoint is gone. If they issued a SAVEPOINT,
1851 * releasing ours would remove theirs.
1855 *svpt_gone_p = (strcmp(cmd,
"COMMIT") == 0 ||
1856 strcmp(cmd,
"SAVEPOINT") == 0 ||
1857 strcmp(cmd,
"RELEASE") == 0 ||
1858 strcmp(cmd,
"ROLLBACK") == 0);
1863 /* must handle COPY before changing the current result */
1868 FILE *copy_stream = NULL;
1873 * Running COPY within a pipeline can break the protocol
1874 * synchronisation in multiple ways, and psql shows its limits
1875 * when it comes to tracking this information.
1877 * While in COPY mode, the backend process ignores additional
1878 * Sync messages and will not send the matching ReadyForQuery
1879 * expected by the frontend.
1881 * Additionally, libpq automatically sends a Sync with the
1882 * Copy message, creating an unexpected synchronisation point.
1883 * A failure during COPY would leave the pipeline in an
1884 * aborted state while the backend would be in a clean state,
1885 * ready to process commands.
1887 * Improving those issues would require modifications in how
1888 * libpq handles pipelines and COPY. Hence, for the time
1889 * being, we forbid the use of COPY within a pipeline,
1890 * aborting the connection to avoid an inconsistent state on
1891 * psql side if trying to use a COPY command.
1893 pg_log_info(
"COPY in a pipeline is not supported, aborting connection");
1898 * For COPY OUT, direct the output to the default place (probably
1899 * a pager pipe) for \watch, or to pset.copyStream for \copy,
1900 * otherwise to pset.gfname if that's set, otherwise to
1907 /* invoked by \watch */
1908 copy_stream = printQueryFout ? printQueryFout :
pset.
queryFout;
1912 /* invoked by \copy */
1917 /* COPY followed by \g filename or \g |program */
1920 copy_stream = gfile_fout;
1924 /* fall back to the generic query output stream */
1930 * Even if the output stream could not be opened, we call
1931 * HandleCopyResult() with a NULL output stream to collect and
1932 * discard the COPY data.
1937 /* If we have a chunked result, collect and print all chunks */
1940 FILE *tuples_fout = printQueryFout ? printQueryFout :
pset.
queryFout;
1942 int64 total_tuples = 0;
1943 bool is_pager =
false;
1944 int flush_error = 0;
1946 /* initialize print options for partial table output */
1951 /* open \g file if needed */
1954 tuples_fout = gfile_fout;
1956 /* force use of pager for any chunked resultset going to stdout */
1966 * Display the current chunk of results, unless the output
1967 * stream stopped working or we got canceled. We skip use of
1968 * PrintQueryResult and go directly to printQuery, so that we
1969 * can pass the correct is_pager value and because we don't
1970 * want PrintQueryStatus to happen yet. Above, we rejected
1971 * use of chunking for all cases in which PrintQueryResult
1972 * would send the result to someplace other than printQuery.
1977 flush_error = fflush(tuples_fout);
1980 /* after the first result set, disallow header decoration */
1983 /* count tuples before dropping the result */
1989 /* get the next result, loop if it's PGRES_TUPLES_CHUNK */
1993 /* We expect an empty PGRES_TUPLES_OK, else there's a problem */
2000 /* Display the footer using the empty result */
2005 fflush(tuples_fout);
2012 * It's possible the data is from a RETURNING clause, in which
2013 * case we need to print query status.
2018 * We must do a fake SetResultVariables(), since we don't have
2019 * a PGresult corresponding to the whole query.
2025 /* Prevent SetResultVariables call below */
2026 is_chunked_result =
true;
2028 /* Clear the empty result so it isn't printed below */
2034 /* Probably an error report, so close the pager and print it */
2039 /* SetResultVariables and ClearOrSaveResult happen below */
2048 * Sync response, decrease the sync and requested_results
2055 * After a synchronisation point, reset success state to print
2056 * possible successful results that will be processed after this.
2061 * If all syncs were processed and pipeline end was requested,
2062 * exit pipeline mode.
2071 * In a pipeline with a non-sync response? Decrease the result
2079 * Check PQgetResult() again. In the typical case of a single-command
2080 * string, it will return NULL. Otherwise, we'll have other results
2081 * to process. We need to do that to check whether this is the last.
2088 * In pipeline mode, a NULL result indicates the end of the
2089 * current query being processed. Call PQgetResult() once to
2090 * consume this state.
2095 Assert(next_result == NULL);
2098 /* Now, we can get the next result in the pipeline. */
2103 last = (next_result == NULL);
2106 * Update current timing measure.
2108 * It will include the display of previous results, if any. This
2109 * cannot be helped because the server goes on processing further
2110 * queries anyway while the previous ones are being displayed. The
2111 * parallel execution of the client display hides the server time when
2114 * With combined queries, timing must be understood as an upper bound
2115 * of the time spent processing them.
2125 * This may or may not print something depending on settings.
2127 * A pipeline sync will have a non-NULL result but does not have
2128 * anything to print, thus ignore results in this case.
2133 * If results need to be printed into the file specified by \g,
2134 * open it, unless we already did. Note that when pset.gfname is
2135 * set, the passed-in value of printQueryFout is not used for
2136 * tuple output, but it's still used for status output.
2138 FILE *tuples_fout = printQueryFout;
2143 tuples_fout = gfile_fout;
2146 tuples_fout, printQueryFout);
2149 /* set variables from last result, unless dealt with elsewhere */
2150 if (last && !is_watch && !is_chunked_result)
2154 result = next_result;
2159 * Outside of a pipeline, drop the next result, as well as any
2160 * others not yet read.
2162 * Within a pipeline, we can let the outer loop handle this as an
2163 * aborted pipeline, which will discard then all the results.
2171 /* close \g file if we opened it */
2176 /* after a pipeline is processed, pipeline piped_syncs should be 0 */
2178 /* all commands have been processed */
2180 /* all results were read */
2186 /* may need this to recover from conn loss during COPY */
2198 * Advance the given char pointer over white space and SQL comments.
2203 int cnestlevel = 0;
/* slash-star comment nest level */
2210 * Note: we assume the encoding is a superset of ASCII, so that for
2211 * example "query[0] == '/'" is meaningful. However, we do NOT assume
2212 * that the second and subsequent bytes of a multibyte character
2213 * couldn't look like ASCII characters; so it is critical to advance
2214 * by mblen, not 1, whenever we haven't exactly identified the
2215 * character we are skipping over.
2217 if (isspace((
unsigned char) *query))
2219 else if (query[0] ==
'/' && query[1] ==
'*')
2224 else if (cnestlevel > 0 && query[0] ==
'*' && query[1] ==
'/')
2229 else if (cnestlevel == 0 && query[0] ==
'-' && query[1] ==
'-')
2234 * We have to skip to end of line since any slash-star inside the
2235 * -- comment does NOT start a slash-star comment.
2247 else if (cnestlevel > 0)
2250 break;
/* found first token */
2258 * Check whether a command is one of those for which we should NOT start
2259 * a new transaction block (ie, send a preceding BEGIN).
2261 * These include the transaction control statements themselves, plus
2262 * certain statements that the backend disallows inside transaction blocks.
2270 * First we must advance over any whitespace and comments.
2275 * Check word length (since "beginx" is not "begin").
2278 while (isalpha((
unsigned char) query[wordlen]))
2282 * Transaction control commands. These should include every keyword that
2283 * gives rise to a TransactionStmt in the backend grammar, except for the
2284 * savepoint-related commands.
2286 * (We assume that START must be START TRANSACTION, since there is
2287 * presently no other "START foo" command.)
2303 /* PREPARE TRANSACTION is a TC command, PREPARE foo is not */
2309 while (isalpha((
unsigned char) query[wordlen]))
2312 if (wordlen == 11 &&
pg_strncasecmp(query,
"transaction", 11) == 0)
2318 * Commands not allowed within transactions. The statements checked for
2319 * here should be exactly those that call PreventInTransactionBlock() in
2326 /* CLUSTER with any arguments is allowed in transactions */
2331 if (isalpha((
unsigned char) query[0]))
2332 return false;
/* has additional words */
2333 return true;
/* it's CLUSTER without arguments */
2343 while (isalpha((
unsigned char) query[wordlen]))
2348 if (wordlen == 10 &&
pg_strncasecmp(query,
"tablespace", 10) == 0)
2351 /* CREATE [UNIQUE] INDEX CONCURRENTLY isn't allowed in xacts */
2359 while (isalpha((
unsigned char) query[wordlen]))
2370 while (isalpha((
unsigned char) query[wordlen]))
2373 if (wordlen == 12 &&
pg_strncasecmp(query,
"concurrently", 12) == 0)
2387 while (isalpha((
unsigned char) query[wordlen]))
2390 /* ALTER SYSTEM isn't allowed in xacts */
2398 * Note: these tests will match DROP SYSTEM and REINDEX TABLESPACE, which
2399 * aren't really valid commands so we don't care much. The other four
2400 * possible matches are correct.
2410 while (isalpha((
unsigned char) query[wordlen]))
2417 if (wordlen == 10 &&
pg_strncasecmp(query,
"tablespace", 10) == 0)
2425 while (isalpha((
unsigned char) query[wordlen]))
2429 * REINDEX [ TABLE | INDEX ] CONCURRENTLY are not allowed in
2432 if (wordlen == 12 &&
pg_strncasecmp(query,
"concurrently", 12) == 0)
2436 /* DROP INDEX CONCURRENTLY isn't allowed in xacts */
2444 while (isalpha((
unsigned char) query[wordlen]))
2447 if (wordlen == 12 &&
pg_strncasecmp(query,
"concurrently", 12) == 0)
2456 /* DISCARD ALL isn't allowed in xacts, but other variants are allowed. */
2464 while (isalpha((
unsigned char) query[wordlen]))
2477 * Test if the current user is a database superuser.
2489 if (
val && strcmp(
val,
"on") == 0)
2497 * Test if the current session uses standard string literals.
2509 if (
val && strcmp(
val,
"on") == 0)
2517 * Return the session user of the current connection.
2535 * Return the value of option for keyword in the current connection.
2537 * The caller is responsible for freeing the result value allocated.
2555 if (strcmp(opt->keyword, keyword) == 0)
2562 /* Take a copy of the value, as it is freed by PQconninfoFree(). */
2563 if (serviceopt && serviceopt->
val != NULL)
2572 * substitute '~' with HOME or '~username' with username's home dir
2582 * WIN32 doesn't use tilde expansion for file names. Also, it uses tilde
2583 * for short versions of long file names, though the tilde is usually
2584 * toward the end, not at the beginning.
2588 /* try tilde expansion */
2601 while (*p !=
'/' && *p !=
'0円')
2607 if (*(
fn + 1) ==
'0円')
2609 else if ((pw = getpwnam(
fn + 1)) != NULL)
2610 strlcpy(home, pw->pw_dir,
sizeof(home));
/* ~user */
2613 if (strlen(home) != 0)
2626 * Checks if connection string starts with either of the valid URI prefix
2629 * Returns the URI prefix length, 0 if the string doesn't contain a URI prefix.
2631 * XXX This is a duplicate of the eponymous libpq function.
2636 /* The connection URI must start with either of the following designators: */
2652 * Reset state related to extended query protocol
2654 * Clean up any state related to bind parameters, statement name and
2655 * PSQL_SEND_MODE. This needs to be called after processing a query or when
2656 * running a new meta-command that uses the extended query protocol, like
2657 * \parse, \bind, etc.
2695 * Recognized connection string either starts with a valid URI prefix or
2696 * contains a "=" in it.
2698 * Must be consistent with parse_connection_string: anything for which this
2699 * returns true should at least look like it's parseable by that routine.
2701 * XXX This is a duplicate of the eponymous libpq function.
void expand_tilde(char **filename)
PGresult * PSQLexec(const char *query)
void psql_setup_cancel_handler(void)
volatile sig_atomic_t sigint_interrupt_enabled
static bool PrintQueryResult(PGresult *result, bool last, const printQueryOpt *opt, FILE *printQueryFout, FILE *printStatusFout)
static bool CheckConnection(void)
const char * session_username(void)
static void PrintQueryStatus(PGresult *result, FILE *printQueryFout)
static int uri_prefix_length(const char *connstr)
static bool DescribeQuery(const char *query, double *elapsed_msec)
static void ClearOrSaveAllResults(void)
static PGresult * discardAbortedPipelineResults(void)
char * get_conninfo_value(const char *keyword)
static bool ExecQueryTuples(const PGresult *result)
static void PrintNotifications(void)
static void SetResultVariables(PGresult *result, bool success)
char * psql_get_variable(const char *varname, PsqlScanQuoteType quote, void *passthrough)
sigjmp_buf sigint_interrupt_jmp
static void ClearOrSaveResult(PGresult *result)
static bool SetupGOutput(FILE **gfile_fout, bool *is_pipe)
static void psql_cancel_callback(void)
static bool AcceptResult(const PGresult *result, bool show_error)
static bool HandleCopyResult(PGresult **resultp, FILE *copystream)
int PSQLexecWatch(const char *query, const printQueryOpt *opt, FILE *printQueryFout, int min_rows)
void SetShellResultVariables(int wait_result)
void NoticeProcessor(void *arg, const char *message)
void clean_extended_state(void)
static bool StoreQueryTuple(const PGresult *result)
static void CloseGOutput(FILE *gfile_fout, bool is_pipe)
static const char * skip_white_space(const char *query)
bool standard_strings(void)
static void SetPipelineVariables(void)
static bool PrintQueryTuples(const PGresult *result, const printQueryOpt *opt, FILE *printQueryFout)
static void pipelineReset(void)
static bool ConnectionUp(void)
bool setQFout(const char *fname)
static int ExecQueryAndProcessResults(const char *query, double *elapsed_msec, bool *svpt_gone_p, bool is_watch, int min_rows, const printQueryOpt *opt, FILE *printQueryFout)
bool openQueryOutputFile(const char *fname, FILE **fout, bool *is_pipe)
bool recognized_connection_string(const char *connstr)
static void PrintTiming(double elapsed_msec)
bool SendQuery(const char *query)
static bool command_no_begin(const char *query)
bool handleCopyOut(PGconn *conn, FILE *copystream, PGresult **res)
bool handleCopyIn(PGconn *conn, FILE *copystream, bool isbinary, PGresult **res)
#define PG_USED_FOR_ASSERTS_ONLY
void ResetCancelConn(void)
void SetCancelConn(PGconn *conn)
void setup_cancel_handler(void(*query_cancel_callback)(void))
void restorePsetInfo(printQueryOpt *popt, printQueryOpt *save)
void UnsyncVariables(void)
void connection_warnings(bool in_startup)
bool conditional_active(ConditionalStack cstack)
bool PrintResultInCrosstab(const PGresult *res)
#define fprintf(file, fmt, msg)
void PQreset(PGconn *conn)
static const char short_uri_designator[]
PGTransactionStatusType PQtransactionStatus(const PGconn *conn)
PQconninfoOption * PQconninfo(PGconn *conn)
void PQconninfoFree(PQconninfoOption *connOptions)
static const char uri_designator[]
const char * PQparameterStatus(const PGconn *conn, const char *paramName)
ConnStatusType PQstatus(const PGconn *conn)
int PQclientEncoding(const PGconn *conn)
void PQfinish(PGconn *conn)
char * PQuser(const PGconn *conn)
PGpipelineStatus PQpipelineStatus(const PGconn *conn)
char * PQerrorMessage(const PGconn *conn)
int PQsendQueryParams(PGconn *conn, const char *command, int nParams, const Oid *paramTypes, const char *const *paramValues, const int *paramLengths, const int *paramFormats, int resultFormat)
int PQbinaryTuples(const PGresult *res)
int PQflush(PGconn *conn)
void PQfreemem(void *ptr)
Oid PQftype(const PGresult *res, int field_num)
PGresult * PQdescribePrepared(PGconn *conn, const char *stmt)
int PQexitPipelineMode(PGconn *conn)
int PQenterPipelineMode(PGconn *conn)
int PQsendClosePrepared(PGconn *conn, const char *stmt)
int PQsendPipelineSync(PGconn *conn)
PGresult * PQprepare(PGconn *conn, const char *stmtName, const char *query, int nParams, const Oid *paramTypes)
int PQconsumeInput(PGconn *conn)
char * PQescapeLiteral(PGconn *conn, const char *str, size_t len)
int PQsendPrepare(PGconn *conn, const char *stmtName, const char *query, int nParams, const Oid *paramTypes)
int PQfmod(const PGresult *res, int field_num)
int PQsetChunkedRowsMode(PGconn *conn, int chunkSize)
int PQsendQuery(PGconn *conn, const char *query)
int PQpipelineSync(PGconn *conn)
PGresult * PQexec(PGconn *conn, const char *query)
int PQsendQueryPrepared(PGconn *conn, const char *stmtName, int nParams, const char *const *paramValues, const int *paramLengths, const int *paramFormats, int resultFormat)
char * PQescapeIdentifier(PGconn *conn, const char *str, size_t len)
int PQsendFlushRequest(PGconn *conn)
Oid PQoidValue(const PGresult *res)
PGnotify * PQnotifies(PGconn *conn)
int PQmblenBounded(const char *s, int encoding)
char * pg_strdup(const char *in)
void restore_sigpipe_trap(void)
void printQuery(const PGresult *result, const printQueryOpt *opt, FILE *fout, bool is_pager, FILE *flog)
FILE * PageOutput(int lines, const printTableOpt *topt)
void ClosePager(FILE *pagerpipe)
void disable_sigpipe_trap(void)
void html_escaped_print(const char *in, FILE *fout)
void set_sigpipe_trap_state(bool ignore)
volatile sig_atomic_t cancel_pressed
Assert(PointerIsAligned(start, uint64))
#define INSTR_TIME_SET_CURRENT(t)
#define INSTR_TIME_SUBTRACT(x, y)
#define INSTR_TIME_GET_MILLISEC(t)
#define INSTR_TIME_SET_ZERO(t)
#define PQresultErrorMessage
#define PQresultErrorField
#define pg_log_error(...)
static AmcheckOptions opts
static const char * connstr
#define pg_encoding_to_char
#define pg_log_warning(...)
bool get_home_path(char *ret_path)
size_t strlcpy(char *dst, const char *src, size_t siz)
int pg_strncasecmp(const char *s1, const char *s2, size_t n)
#define PG_DIAG_MESSAGE_PRIMARY
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
void initPQExpBuffer(PQExpBuffer str)
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
void appendPQExpBufferChar(PQExpBuffer str, char ch)
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
void termPQExpBuffer(PQExpBuffer str)
char * psprintf(const char *fmt,...)
static int before(chr x, chr y)
@ PSQL_ERROR_ROLLBACK_OFF
@ PSQL_ECHO_HIDDEN_NOEXEC
@ PSQL_SEND_PIPELINE_SYNC
@ PSQL_SEND_FLUSH_REQUEST
@ PSQL_SEND_START_PIPELINE_MODE
@ PSQL_SEND_EXTENDED_QUERY_PARAMS
@ PSQL_SEND_EXTENDED_PARSE
@ PSQL_SEND_END_PIPELINE_MODE
@ PSQL_SEND_EXTENDED_CLOSE
@ PSQL_SEND_EXTENDED_QUERY_PREPARED
bool appendShellStringNoError(PQExpBuffer buf, const char *str)
PSQL_ERROR_ROLLBACK on_error_rollback
PGresult * last_error_result
PSQL_ECHO_HIDDEN echo_hidden
printQueryOpt * gsavepopt
unsigned long prior_records
static void * fn(void *arg)
bool VariableHasHook(VariableSpace space, const char *name)
bool SetVariable(VariableSpace space, const char *name, const char *value)
const char * GetVariable(VariableSpace space, const char *name)
int wait_result_to_exit_code(int exit_status)