2 * psql - the PostgreSQL interactive terminal
4 * Copyright (c) 2000-2008, PostgreSQL Global Development Group
8 #include "postgres_fe.h"
14 #include <unistd.h> /* for write() */
16 #include <io.h> /* for _write() */
20 #include "portability/instr_time.h"
31 static bool ExecQueryUsingCursor(const char *query
, double *elapsed_msec
);
32 static bool command_no_begin(const char *query
);
33 static bool is_select_command(const char *query
);
36 * "Safe" wrapper around strdup()
39 pg_strdup(const char *string
)
45 fprintf(stderr
, _("%s: pg_strdup: cannot duplicate null pointer (internal error)\n"),
52 psql_error("out of memory\n");
59 pg_malloc(size_t size
)
66 psql_error("out of memory\n");
73 pg_malloc_zero(size_t size
)
77 tmp
= pg_malloc(size
);
83 pg_calloc(size_t nmemb
, size_t size
)
87 tmp
= calloc(nmemb
, size
);
90 psql_error("out of memory");
98 * -- handler for -o command line option and \o command
100 * Tries to open file fname (or pipe if fname starts with '|')
101 * and stores the file handle in pset)
102 * Upon failure, sets stdout and returns false.
105 setQFout(const char *fname
)
109 /* Close old file/pipe */
110 if (pset
.queryFout
&& pset
.queryFout
!= stdout
&& pset
.queryFout
!= stderr
)
112 if (pset
.queryFoutPipe
)
113 pclose(pset
.queryFout
);
115 fclose(pset
.queryFout
);
118 /* If no filename, set stdout */
119 if (!fname
|| fname
[0] == '\0')
121 pset
.queryFout
= stdout
;
122 pset
.queryFoutPipe
= false;
124 else if (*fname
== '|')
126 pset
.queryFout
= popen(fname
+ 1, "w");
127 pset
.queryFoutPipe
= true;
131 pset
.queryFout
= fopen(fname
, "w");
132 pset
.queryFoutPipe
= false;
135 if (!(pset
.queryFout
))
137 psql_error("%s: %s\n", fname
, strerror(errno
));
138 pset
.queryFout
= stdout
;
139 pset
.queryFoutPipe
= false;
145 pqsignal(SIGPIPE
, pset
.queryFoutPipe
? SIG_IGN
: SIG_DFL
);
154 * Error reporting for scripts. Errors should look like
155 * psql:filename:lineno: message
159 psql_error(const char *fmt
,...)
164 if (pset
.queryFout
!= stdout
)
165 fflush(pset
.queryFout
);
168 fprintf(stderr
, "%s:%s:" UINT64_FORMAT
": ", pset
.progname
, pset
.inputfile
, pset
.lineno
);
170 vfprintf(stderr
, _(fmt
), ap
);
177 * for backend Notice messages (INFO, WARNING, etc)
180 NoticeProcessor(void *arg
, const char *message
)
182 (void) arg
; /* not used */
183 psql_error("%s", message
);
189 * Code to support query cancellation
191 * Before we start a query, we enable the SIGINT signal catcher to send a
192 * cancel request to the backend. Note that sending the cancel directly from
193 * the signal handler is safe because PQcancel() is written to make it
194 * so. We use write() to report to stderr because it's better to use simple
195 * facilities in a signal handler.
197 * On win32, the signal cancelling happens on a separate thread, because
198 * that's how SetConsoleCtrlHandler works. The PQcancel function is safe
199 * for this (unlike PQrequestCancel). However, a CRITICAL_SECTION is required
200 * to protect the PGcancel structure against being changed while the signal
201 * thread is using it.
203 * SIGINT is supposed to abort all long-running psql operations, not only
204 * database queries. In most places, this is accomplished by checking
205 * cancel_pressed during long-running loops. However, that won't work when
206 * blocked on user input (in readline() or fgets()). In those places, we
207 * set sigint_interrupt_enabled TRUE while blocked, instructing the signal
208 * catcher to longjmp through sigint_interrupt_jmp. We assume readline and
209 * fgets are coded to handle possible interruption. (XXX currently this does
210 * not work on win32, so control-C is less useful there)
212 volatile bool sigint_interrupt_enabled
= false;
214 sigjmp_buf sigint_interrupt_jmp
;
216 static PGcancel
*volatile cancelConn
= NULL
;
219 static CRITICAL_SECTION cancelConnLock
;
222 #define write_stderr(str) write(fileno(stderr), str, strlen(str))
228 handle_sigint(SIGNAL_ARGS
)
230 int save_errno
= errno
;
233 /* if we are waiting for input, longjmp out of it */
234 if (sigint_interrupt_enabled
)
236 sigint_interrupt_enabled
= false;
237 siglongjmp(sigint_interrupt_jmp
, 1);
240 /* else, set cancel flag to stop any long-running loops */
241 cancel_pressed
= true;
243 /* and send QueryCancel if we are processing a database query */
244 if (cancelConn
!= NULL
)
246 if (PQcancel(cancelConn
, errbuf
, sizeof(errbuf
)))
247 write_stderr("Cancel request sent\n");
250 write_stderr("Could not send cancel request: ");
251 write_stderr(errbuf
);
255 errno
= save_errno
; /* just in case the write changed it */
259 setup_cancel_handler(void)
261 pqsignal(SIGINT
, handle_sigint
);
266 consoleHandler(DWORD dwCtrlType
)
270 if (dwCtrlType
== CTRL_C_EVENT
||
271 dwCtrlType
== CTRL_BREAK_EVENT
)
274 * Can't longjmp here, because we are in wrong thread :-(
277 /* set cancel flag to stop any long-running loops */
278 cancel_pressed
= true;
280 /* and send QueryCancel if we are processing a database query */
281 EnterCriticalSection(&cancelConnLock
);
282 if (cancelConn
!= NULL
)
284 if (PQcancel(cancelConn
, errbuf
, sizeof(errbuf
)))
285 write_stderr("Cancel request sent\n");
288 write_stderr("Could not send cancel request: ");
289 write_stderr(errbuf
);
292 LeaveCriticalSection(&cancelConnLock
);
297 /* Return FALSE for any signals not being handled */
302 setup_cancel_handler(void)
304 InitializeCriticalSection(&cancelConnLock
);
306 SetConsoleCtrlHandler(consoleHandler
, TRUE
);
313 * Returns whether our backend connection is still there.
318 return PQstatus(pset
.db
) != CONNECTION_BAD
;
325 * Verify that we still have a good connection to the backend, and if not,
326 * see if it can be restored.
328 * Returns true if either the connection was still there, or it could be
329 * restored successfully; false otherwise. If, however, there was no
330 * connection and the session is non-interactive, this will exit the program
331 * with a code of EXIT_BADCONN.
334 CheckConnection(void)
341 if (!pset
.cur_cmd_interactive
)
343 psql_error("connection to server was lost\n");
347 fputs(_("The connection to the server was lost. Attempting reset: "), stderr
);
352 fputs(_("Failed.\n"), stderr
);
359 fputs(_("Succeeded.\n"), stderr
);
370 * Set cancelConn to point to the current database connection.
375 PGcancel
*oldCancelConn
;
378 EnterCriticalSection(&cancelConnLock
);
381 /* Free the old one if we have one */
382 oldCancelConn
= cancelConn
;
383 /* be sure handle_sigint doesn't use pointer while freeing */
386 if (oldCancelConn
!= NULL
)
387 PQfreeCancel(oldCancelConn
);
389 cancelConn
= PQgetCancel(pset
.db
);
392 LeaveCriticalSection(&cancelConnLock
);
400 * Free the current cancel connection, if any, and set to NULL.
403 ResetCancelConn(void)
405 PGcancel
*oldCancelConn
;
408 EnterCriticalSection(&cancelConnLock
);
411 oldCancelConn
= cancelConn
;
412 /* be sure handle_sigint doesn't use pointer while freeing */
415 if (oldCancelConn
!= NULL
)
416 PQfreeCancel(oldCancelConn
);
419 LeaveCriticalSection(&cancelConnLock
);
427 * Checks whether a result is valid, giving an error message if necessary;
428 * and ensures that the connection to the backend is still up.
430 * Returns true for valid result, false for error state.
433 AcceptResult(const PGresult
*result
)
440 switch (PQresultStatus(result
))
442 case PGRES_COMMAND_OK
:
443 case PGRES_TUPLES_OK
:
444 case PGRES_EMPTY_QUERY
:
447 /* Fine, do nothing */
457 const char *error
= PQerrorMessage(pset
.db
);
460 psql_error("%s", error
);
473 * This is the way to send "backdoor" queries (those not directly entered
474 * by the user). It is subject to -E but not -e.
476 * In autocommit-off mode, a new transaction block is started if start_xact
477 * is true; nothing special is done when start_xact is false. Typically,
478 * start_xact = false is used for SELECTs and explicit BEGIN/COMMIT commands.
480 * Caller is responsible for handling the ensuing processing if a COPY
483 * Note: we don't bother to check PQclientEncoding; it is assumed that no
484 * caller uses this path to issue "SET CLIENT_ENCODING".
487 PSQLexec(const char *query
, bool start_xact
)
493 psql_error("You are currently not connected to a database.\n");
497 if (pset
.echo_hidden
!= PSQL_ECHO_HIDDEN_OFF
)
499 printf(_("********* QUERY **********\n"
501 "**************************\n\n"), query
);
505 fprintf(pset
.logfile
,
506 _("********* QUERY **********\n"
508 "**************************\n\n"), query
);
509 fflush(pset
.logfile
);
512 if (pset
.echo_hidden
== PSQL_ECHO_HIDDEN_NOEXEC
)
520 PQtransactionStatus(pset
.db
) == PQTRANS_IDLE
)
522 res
= PQexec(pset
.db
, "BEGIN");
523 if (PQresultStatus(res
) != PGRES_COMMAND_OK
)
525 psql_error("%s", PQerrorMessage(pset
.db
));
533 res
= PQexec(pset
.db
, query
);
537 if (!AcceptResult(res
))
549 * PrintNotifications: check for asynchronous notifications, and print them out
552 PrintNotifications(void)
556 while ((notify
= PQnotifies(pset
.db
)))
558 fprintf(pset
.queryFout
, _("Asynchronous notification \"%s\" received from server process with PID %d.\n"),
559 notify
->relname
, notify
->be_pid
);
560 fflush(pset
.queryFout
);
567 * PrintQueryTuples: assuming query result is OK, print its tuples
569 * Returns true if successful, false otherwise.
572 PrintQueryTuples(const PGresult
*results
)
574 printQueryOpt my_popt
= pset
.popt
;
576 /* write output to \g argument, if any */
579 /* keep this code in sync with ExecQueryUsingCursor */
580 FILE *queryFout_copy
= pset
.queryFout
;
581 bool queryFoutPipe_copy
= pset
.queryFoutPipe
;
583 pset
.queryFout
= stdout
; /* so it doesn't get closed */
586 if (!setQFout(pset
.gfname
))
588 pset
.queryFout
= queryFout_copy
;
589 pset
.queryFoutPipe
= queryFoutPipe_copy
;
593 printQuery(results
, &my_popt
, pset
.queryFout
, pset
.logfile
);
595 /* close file/pipe, restore old setting */
598 pset
.queryFout
= queryFout_copy
;
599 pset
.queryFoutPipe
= queryFoutPipe_copy
;
605 printQuery(results
, &my_popt
, pset
.queryFout
, pset
.logfile
);
612 * ProcessCopyResult: if command was a COPY FROM STDIN/TO STDOUT, handle it
614 * Note: Utility function for use by SendQuery() only.
616 * Returns true if the query executed successfully, false otherwise.
619 ProcessCopyResult(PGresult
*results
)
621 bool success
= false;
626 switch (PQresultStatus(results
))
628 case PGRES_TUPLES_OK
:
629 case PGRES_COMMAND_OK
:
630 case PGRES_EMPTY_QUERY
:
631 /* nothing to do here */
637 success
= handleCopyOut(pset
.db
, pset
.queryFout
);
643 success
= handleCopyIn(pset
.db
, pset
.cur_cmd_source
,
644 PQbinaryTuples(results
));
652 /* may need this to recover from conn loss during COPY */
653 if (!CheckConnection())
661 * PrintQueryStatus: report command status as required
663 * Note: Utility function for use by PrintQueryResults() only.
666 PrintQueryStatus(PGresult
*results
)
672 if (pset
.popt
.topt
.format
== PRINT_HTML
)
674 fputs("<p>", pset
.queryFout
);
675 html_escaped_print(PQcmdStatus(results
), pset
.queryFout
);
676 fputs("</p>\n", pset
.queryFout
);
679 fprintf(pset
.queryFout
, "%s\n", PQcmdStatus(results
));
683 fprintf(pset
.logfile
, "%s\n", PQcmdStatus(results
));
685 snprintf(buf
, sizeof(buf
), "%u", (unsigned int) PQoidValue(results
));
686 SetVariable(pset
.vars
, "LASTOID", buf
);
691 * PrintQueryResults: print out query results as required
693 * Note: Utility function for use by SendQuery() only.
695 * Returns true if the query executed successfully, false otherwise.
698 PrintQueryResults(PGresult
*results
)
700 bool success
= false;
701 const char *cmdstatus
;
706 switch (PQresultStatus(results
))
708 case PGRES_TUPLES_OK
:
709 /* print the data ... */
710 success
= PrintQueryTuples(results
);
711 /* if it's INSERT/UPDATE/DELETE RETURNING, also print status */
712 cmdstatus
= PQcmdStatus(results
);
713 if (strncmp(cmdstatus
, "INSERT", 6) == 0 ||
714 strncmp(cmdstatus
, "UPDATE", 6) == 0 ||
715 strncmp(cmdstatus
, "DELETE", 6) == 0)
716 PrintQueryStatus(results
);
719 case PGRES_COMMAND_OK
:
720 PrintQueryStatus(results
);
724 case PGRES_EMPTY_QUERY
:
730 /* nothing to do here */
738 fflush(pset
.queryFout
);
745 * SendQuery: send the query string to the backend
746 * (and print out results)
748 * Note: This is the "front door" way to send a query. That is, use it to
749 * send queries actually entered by the user. These queries will be subject to
751 * To send "back door" queries (generated by slash commands, etc.) in a
752 * controlled way, use PSQLexec().
754 * Returns true if the query executed successfully, false otherwise.
757 SendQuery(const char *query
)
760 PGTransactionStatusType transaction_status
;
761 double elapsed_msec
= 0;
763 on_error_rollback_savepoint
= false;
764 static bool on_error_rollback_warning
= false;
768 psql_error("You are currently not connected to a database.\n");
776 printf(_("***(Single step mode: verify command)*******************************************\n"
778 "***(press return to proceed or enter x and return to cancel)********************\n"),
781 if (fgets(buf
, sizeof(buf
), stdin
) != NULL
)
785 else if (pset
.echo
== PSQL_ECHO_QUERIES
)
793 fprintf(pset
.logfile
,
794 _("********* QUERY **********\n"
796 "**************************\n\n"), query
);
797 fflush(pset
.logfile
);
802 transaction_status
= PQtransactionStatus(pset
.db
);
804 if (transaction_status
== PQTRANS_IDLE
&&
806 !command_no_begin(query
))
808 results
= PQexec(pset
.db
, "BEGIN");
809 if (PQresultStatus(results
) != PGRES_COMMAND_OK
)
811 psql_error("%s", PQerrorMessage(pset
.db
));
817 transaction_status
= PQtransactionStatus(pset
.db
);
820 if (transaction_status
== PQTRANS_INTRANS
&&
821 pset
.on_error_rollback
!= PSQL_ERROR_ROLLBACK_OFF
&&
822 (pset
.cur_cmd_interactive
||
823 pset
.on_error_rollback
== PSQL_ERROR_ROLLBACK_ON
))
825 if (on_error_rollback_warning
== false && pset
.sversion
< 80000)
827 fprintf(stderr
, _("The server version (%d) does not support savepoints for ON_ERROR_ROLLBACK.\n"),
829 on_error_rollback_warning
= true;
833 results
= PQexec(pset
.db
, "SAVEPOINT pg_psql_temporary_savepoint");
834 if (PQresultStatus(results
) != PGRES_COMMAND_OK
)
836 psql_error("%s", PQerrorMessage(pset
.db
));
842 on_error_rollback_savepoint
= true;
846 if (pset
.fetch_count
<= 0 || !is_select_command(query
))
848 /* Default fetch-it-all-and-print mode */
853 INSTR_TIME_SET_CURRENT(before
);
855 results
= PQexec(pset
.db
, query
);
857 /* these operations are included in the timing result: */
859 OK
= (AcceptResult(results
) && ProcessCopyResult(results
));
863 INSTR_TIME_SET_CURRENT(after
);
864 INSTR_TIME_SUBTRACT(after
, before
);
865 elapsed_msec
= INSTR_TIME_GET_MILLISEC(after
);
868 /* but printing results isn't: */
870 OK
= PrintQueryResults(results
);
874 /* Fetch-in-segments mode */
875 OK
= ExecQueryUsingCursor(query
, &elapsed_msec
);
877 results
= NULL
; /* PQclear(NULL) does nothing */
880 /* If we made a temporary savepoint, possibly release/rollback */
881 if (on_error_rollback_savepoint
)
885 transaction_status
= PQtransactionStatus(pset
.db
);
887 if (transaction_status
== PQTRANS_INERROR
)
889 /* We always rollback on an error */
890 svptcmd
= "ROLLBACK TO pg_psql_temporary_savepoint";
892 else if (transaction_status
!= PQTRANS_INTRANS
)
894 /* If they are no longer in a transaction, then do nothing */
900 * Do nothing if they are messing with savepoints themselves: If
901 * the user did RELEASE or ROLLBACK, our savepoint is gone. If
902 * they issued a SAVEPOINT, releasing ours would remove theirs.
905 (strcmp(PQcmdStatus(results
), "SAVEPOINT") == 0 ||
906 strcmp(PQcmdStatus(results
), "RELEASE") == 0 ||
907 strcmp(PQcmdStatus(results
), "ROLLBACK") == 0))
910 svptcmd
= "RELEASE pg_psql_temporary_savepoint";
917 svptres
= PQexec(pset
.db
, svptcmd
);
918 if (PQresultStatus(svptres
) != PGRES_COMMAND_OK
)
920 psql_error("%s", PQerrorMessage(pset
.db
));
933 /* Possible microtiming output */
934 if (OK
&& pset
.timing
&& !pset
.quiet
)
935 printf(_("Time: %.3f ms\n"), elapsed_msec
);
937 /* check for events that may occur during query execution */
939 if (pset
.encoding
!= PQclientEncoding(pset
.db
) &&
940 PQclientEncoding(pset
.db
) >= 0)
942 /* track effects of SET CLIENT_ENCODING */
943 pset
.encoding
= PQclientEncoding(pset
.db
);
944 pset
.popt
.topt
.encoding
= pset
.encoding
;
945 SetVariable(pset
.vars
, "ENCODING",
946 pg_encoding_to_char(pset
.encoding
));
949 PrintNotifications();
956 * ExecQueryUsingCursor: run a SELECT-like query using a cursor
958 * This feature allows result sets larger than RAM to be dealt with.
960 * Returns true if the query executed successfully, false otherwise.
962 * If pset.timing is on, total query time (exclusive of result-printing) is
963 * stored into *elapsed_msec.
966 ExecQueryUsingCursor(const char *query
, double *elapsed_msec
)
971 printQueryOpt my_popt
= pset
.popt
;
972 FILE *queryFout_copy
= pset
.queryFout
;
973 bool queryFoutPipe_copy
= pset
.queryFoutPipe
;
974 bool started_txn
= false;
975 bool did_pager
= false;
983 /* initialize print options for partial table output */
984 my_popt
.topt
.start_table
= true;
985 my_popt
.topt
.stop_table
= false;
986 my_popt
.topt
.prior_records
= 0;
989 INSTR_TIME_SET_CURRENT(before
);
991 /* if we're not in a transaction, start one */
992 if (PQtransactionStatus(pset
.db
) == PQTRANS_IDLE
)
994 results
= PQexec(pset
.db
, "BEGIN");
995 OK
= AcceptResult(results
) &&
996 (PQresultStatus(results
) == PGRES_COMMAND_OK
);
1003 /* Send DECLARE CURSOR */
1004 initPQExpBuffer(&buf
);
1005 appendPQExpBuffer(&buf
, "DECLARE _psql_cursor NO SCROLL CURSOR FOR\n%s",
1008 results
= PQexec(pset
.db
, buf
.data
);
1009 OK
= AcceptResult(results
) &&
1010 (PQresultStatus(results
) == PGRES_COMMAND_OK
);
1012 termPQExpBuffer(&buf
);
1018 INSTR_TIME_SET_CURRENT(after
);
1019 INSTR_TIME_SUBTRACT(after
, before
);
1020 *elapsed_msec
+= INSTR_TIME_GET_MILLISEC(after
);
1023 snprintf(fetch_cmd
, sizeof(fetch_cmd
),
1024 "FETCH FORWARD %d FROM _psql_cursor",
1027 /* prepare to write output to \g argument, if any */
1030 /* keep this code in sync with PrintQueryTuples */
1031 pset
.queryFout
= stdout
; /* so it doesn't get closed */
1033 /* open file/pipe */
1034 if (!setQFout(pset
.gfname
))
1036 pset
.queryFout
= queryFout_copy
;
1037 pset
.queryFoutPipe
= queryFoutPipe_copy
;
1046 INSTR_TIME_SET_CURRENT(before
);
1048 /* get FETCH_COUNT tuples at a time */
1049 results
= PQexec(pset
.db
, fetch_cmd
);
1053 INSTR_TIME_SET_CURRENT(after
);
1054 INSTR_TIME_SUBTRACT(after
, before
);
1055 *elapsed_msec
+= INSTR_TIME_GET_MILLISEC(after
);
1058 if (PQresultStatus(results
) != PGRES_TUPLES_OK
)
1060 /* shut down pager before printing error message */
1063 ClosePager(pset
.queryFout
);
1064 pset
.queryFout
= queryFout_copy
;
1065 pset
.queryFoutPipe
= queryFoutPipe_copy
;
1069 OK
= AcceptResult(results
);
1075 ntuples
= PQntuples(results
);
1077 if (ntuples
< pset
.fetch_count
)
1079 /* this is the last result set, so allow footer decoration */
1080 my_popt
.topt
.stop_table
= true;
1082 else if (pset
.queryFout
== stdout
&& !did_pager
)
1085 * If query requires multiple result sets, hack to ensure that
1086 * only one pager instance is used for the whole mess
1088 pset
.queryFout
= PageOutput(100000, my_popt
.topt
.pager
);
1092 printQuery(results
, &my_popt
, pset
.queryFout
, pset
.logfile
);
1095 * Make sure to flush the output stream, so intermediate results are
1096 * visible to the client immediately.
1098 fflush(pset
.queryFout
);
1100 /* after the first result set, disallow header decoration */
1101 my_popt
.topt
.start_table
= false;
1102 my_popt
.topt
.prior_records
+= ntuples
;
1106 if (ntuples
< pset
.fetch_count
|| cancel_pressed
)
1110 /* close \g argument file/pipe, restore old setting */
1113 /* keep this code in sync with PrintQueryTuples */
1116 pset
.queryFout
= queryFout_copy
;
1117 pset
.queryFoutPipe
= queryFoutPipe_copy
;
1124 ClosePager(pset
.queryFout
);
1125 pset
.queryFout
= queryFout_copy
;
1126 pset
.queryFoutPipe
= queryFoutPipe_copy
;
1131 INSTR_TIME_SET_CURRENT(before
);
1134 * We try to close the cursor on either success or failure, but on failure
1135 * ignore the result (it's probably just a bleat about being in an aborted
1138 results
= PQexec(pset
.db
, "CLOSE _psql_cursor");
1141 OK
= AcceptResult(results
) &&
1142 (PQresultStatus(results
) == PGRES_COMMAND_OK
);
1148 results
= PQexec(pset
.db
, OK
? "COMMIT" : "ROLLBACK");
1149 OK
&= AcceptResult(results
) &&
1150 (PQresultStatus(results
) == PGRES_COMMAND_OK
);
1156 INSTR_TIME_SET_CURRENT(after
);
1157 INSTR_TIME_SUBTRACT(after
, before
);
1158 *elapsed_msec
+= INSTR_TIME_GET_MILLISEC(after
);
1166 * Advance the given char pointer over white space and SQL comments.
1169 skip_white_space(const char *query
)
1171 int cnestlevel
= 0; /* slash-star comment nest level */
1175 int mblen
= PQmblen(query
, pset
.encoding
);
1178 * Note: we assume the encoding is a superset of ASCII, so that for
1179 * example "query[0] == '/'" is meaningful. However, we do NOT assume
1180 * that the second and subsequent bytes of a multibyte character
1181 * couldn't look like ASCII characters; so it is critical to advance
1182 * by mblen, not 1, whenever we haven't exactly identified the
1183 * character we are skipping over.
1185 if (isspace((unsigned char) *query
))
1187 else if (query
[0] == '/' && query
[1] == '*')
1192 else if (cnestlevel
> 0 && query
[0] == '*' && query
[1] == '/')
1197 else if (cnestlevel
== 0 && query
[0] == '-' && query
[1] == '-')
1202 * We have to skip to end of line since any slash-star inside the
1203 * -- comment does NOT start a slash-star comment.
1212 query
+= PQmblen(query
, pset
.encoding
);
1215 else if (cnestlevel
> 0)
1218 break; /* found first token */
1226 * Check whether a command is one of those for which we should NOT start
1227 * a new transaction block (ie, send a preceding BEGIN).
1229 * These include the transaction control statements themselves, plus
1230 * certain statements that the backend disallows inside transaction blocks.
1233 command_no_begin(const char *query
)
1238 * First we must advance over any whitespace and comments.
1240 query
= skip_white_space(query
);
1243 * Check word length (since "beginx" is not "begin").
1246 while (isalpha((unsigned char) query
[wordlen
]))
1247 wordlen
+= PQmblen(&query
[wordlen
], pset
.encoding
);
1250 * Transaction control commands. These should include every keyword that
1251 * gives rise to a TransactionStmt in the backend grammar, except for the
1252 * savepoint-related commands.
1254 * (We assume that START must be START TRANSACTION, since there is
1255 * presently no other "START foo" command.)
1257 if (wordlen
== 5 && pg_strncasecmp(query
, "abort", 5) == 0)
1259 if (wordlen
== 5 && pg_strncasecmp(query
, "begin", 5) == 0)
1261 if (wordlen
== 5 && pg_strncasecmp(query
, "start", 5) == 0)
1263 if (wordlen
== 6 && pg_strncasecmp(query
, "commit", 6) == 0)
1265 if (wordlen
== 3 && pg_strncasecmp(query
, "end", 3) == 0)
1267 if (wordlen
== 8 && pg_strncasecmp(query
, "rollback", 8) == 0)
1269 if (wordlen
== 7 && pg_strncasecmp(query
, "prepare", 7) == 0)
1271 /* PREPARE TRANSACTION is a TC command, PREPARE foo is not */
1274 query
= skip_white_space(query
);
1277 while (isalpha((unsigned char) query
[wordlen
]))
1278 wordlen
+= PQmblen(&query
[wordlen
], pset
.encoding
);
1280 if (wordlen
== 11 && pg_strncasecmp(query
, "transaction", 11) == 0)
1286 * Commands not allowed within transactions. The statements checked for
1287 * here should be exactly those that call PreventTransactionChain() in the
1290 if (wordlen
== 6 && pg_strncasecmp(query
, "vacuum", 6) == 0)
1292 if (wordlen
== 7 && pg_strncasecmp(query
, "cluster", 7) == 0)
1294 /* CLUSTER with any arguments is allowed in transactions */
1297 query
= skip_white_space(query
);
1299 if (isalpha((unsigned char) query
[0]))
1300 return false; /* has additional words */
1301 return true; /* it's CLUSTER without arguments */
1304 if (wordlen
== 6 && pg_strncasecmp(query
, "create", 6) == 0)
1308 query
= skip_white_space(query
);
1311 while (isalpha((unsigned char) query
[wordlen
]))
1312 wordlen
+= PQmblen(&query
[wordlen
], pset
.encoding
);
1314 if (wordlen
== 8 && pg_strncasecmp(query
, "database", 8) == 0)
1316 if (wordlen
== 10 && pg_strncasecmp(query
, "tablespace", 10) == 0)
1319 /* CREATE [UNIQUE] INDEX CONCURRENTLY isn't allowed in xacts */
1320 if (wordlen
== 6 && pg_strncasecmp(query
, "unique", 6) == 0)
1324 query
= skip_white_space(query
);
1327 while (isalpha((unsigned char) query
[wordlen
]))
1328 wordlen
+= PQmblen(&query
[wordlen
], pset
.encoding
);
1331 if (wordlen
== 5 && pg_strncasecmp(query
, "index", 5) == 0)
1335 query
= skip_white_space(query
);
1338 while (isalpha((unsigned char) query
[wordlen
]))
1339 wordlen
+= PQmblen(&query
[wordlen
], pset
.encoding
);
1341 if (wordlen
== 12 && pg_strncasecmp(query
, "concurrently", 12) == 0)
1349 * Note: these tests will match DROP SYSTEM and REINDEX TABLESPACE, which
1350 * aren't really valid commands so we don't care much. The other four
1351 * possible matches are correct.
1353 if ((wordlen
== 4 && pg_strncasecmp(query
, "drop", 4) == 0) ||
1354 (wordlen
== 7 && pg_strncasecmp(query
, "reindex", 7) == 0))
1358 query
= skip_white_space(query
);
1361 while (isalpha((unsigned char) query
[wordlen
]))
1362 wordlen
+= PQmblen(&query
[wordlen
], pset
.encoding
);
1364 if (wordlen
== 8 && pg_strncasecmp(query
, "database", 8) == 0)
1366 if (wordlen
== 6 && pg_strncasecmp(query
, "system", 6) == 0)
1368 if (wordlen
== 10 && pg_strncasecmp(query
, "tablespace", 10) == 0)
1377 * Check whether the specified command is a SELECT (or VALUES).
1380 is_select_command(const char *query
)
1385 * First advance over any whitespace, comments and left parentheses.
1389 query
= skip_white_space(query
);
1390 if (query
[0] == '(')
1397 * Check word length (since "selectx" is not "select").
1400 while (isalpha((unsigned char) query
[wordlen
]))
1401 wordlen
+= PQmblen(&query
[wordlen
], pset
.encoding
);
1403 if (wordlen
== 6 && pg_strncasecmp(query
, "select", 6) == 0)
1406 if (wordlen
== 6 && pg_strncasecmp(query
, "values", 6) == 0)
1414 * Test if the current user is a database superuser.
1416 * Note: this will correctly detect superuserness only with a protocol-3.0
1417 * or newer backend; otherwise it will always say "false".
1427 val
= PQparameterStatus(pset
.db
, "is_superuser");
1429 if (val
&& strcmp(val
, "on") == 0)
1437 * Test if the current session uses standard string literals.
1439 * Note: With a pre-protocol-3.0 connection this will always say "false",
1440 * which should be the right answer.
1443 standard_strings(void)
1450 val
= PQparameterStatus(pset
.db
, "standard_conforming_strings");
1452 if (val
&& strcmp(val
, "on") == 0)
1460 * Return the session user of the current connection.
1462 * Note: this will correctly detect the session user only with a
1463 * protocol-3.0 or newer backend; otherwise it will return the
1467 session_username(void)
1474 val
= PQparameterStatus(pset
.db
, "session_authorization");
1478 return PQuser(pset
.db
);
1484 * substitute '~' with HOME or '~username' with username's home dir
1488 expand_tilde(char **filename
)
1490 if (!filename
|| !(*filename
))
1494 * WIN32 doesn't use tilde expansion for file names. Also, it uses tilde
1495 * for short versions of long file names, though the tilde is usually
1496 * toward the end, not at the beginning.
1500 /* try tilde expansion */
1501 if (**filename
== '~')
1507 char home
[MAXPGPATH
];
1513 while (*p
!= '/' && *p
!= '\0')
1519 if (*(fn
+ 1) == '\0')
1520 get_home_path(home
); /* ~ or ~/ only */
1521 else if ((pw
= getpwnam(fn
+ 1)) != NULL
)
1522 strlcpy(home
, pw
->pw_dir
, sizeof(home
)); /* ~user */
1525 if (strlen(home
) != 0)
1529 newfn
= pg_malloc(strlen(home
) + strlen(p
) + 1);
1530 strcpy(newfn
, home
);