PostgreSQL Source Code  git master
command.c File Reference
#include "postgres_fe.h"
#include <ctype.h>
#include <time.h>
#include <pwd.h>
#include <utime.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include "catalog/pg_class_d.h"
#include "command.h"
#include "common.h"
#include "common/logging.h"
#include "common/string.h"
#include "copy.h"
#include "crosstabview.h"
#include "describe.h"
#include "fe_utils/cancel.h"
#include "fe_utils/print.h"
#include "fe_utils/string_utils.h"
#include "help.h"
#include "input.h"
#include "large_obj.h"
#include "libpq-fe.h"
#include "libpq/pqcomm.h"
#include "mainloop.h"
#include "portability/instr_time.h"
#include "pqexpbuffer.h"
#include "psqlscanslash.h"
#include "settings.h"
#include "variables.h"
Include dependency graph for command.c:

Go to the source code of this file.

Macros

#define DEFAULT_SHELL   "/bin/sh"
 

Typedefs

typedef enum EditableObjectType EditableObjectType
 

Enumerations

enum  EditableObjectType { EditableFunction , EditableView }
 

Functions

static backslashResult exec_command (const char *cmd, PsqlScanState scan_state, ConditionalStack cstack, PQExpBuffer query_buf, PQExpBuffer previous_buf)
 
static backslashResult exec_command_a (PsqlScanState scan_state, bool active_branch)
 
static backslashResult exec_command_bind (PsqlScanState scan_state, bool active_branch)
 
static backslashResult exec_command_C (PsqlScanState scan_state, bool active_branch)
 
static backslashResult exec_command_connect (PsqlScanState scan_state, bool active_branch)
 
static backslashResult exec_command_cd (PsqlScanState scan_state, bool active_branch, const char *cmd)
 
static backslashResult exec_command_conninfo (PsqlScanState scan_state, bool active_branch)
 
static backslashResult exec_command_copy (PsqlScanState scan_state, bool active_branch)
 
static backslashResult exec_command_copyright (PsqlScanState scan_state, bool active_branch)
 
static backslashResult exec_command_crosstabview (PsqlScanState scan_state, bool active_branch)
 
static backslashResult exec_command_d (PsqlScanState scan_state, bool active_branch, const char *cmd)
 
static bool exec_command_dfo (PsqlScanState scan_state, const char *cmd, const char *pattern, bool show_verbose, bool show_system)
 
static backslashResult exec_command_edit (PsqlScanState scan_state, bool active_branch, PQExpBuffer query_buf, PQExpBuffer previous_buf)
 
static backslashResult exec_command_ef_ev (PsqlScanState scan_state, bool active_branch, PQExpBuffer query_buf, bool is_func)
 
static backslashResult exec_command_echo (PsqlScanState scan_state, bool active_branch, const char *cmd)
 
static backslashResult exec_command_elif (PsqlScanState scan_state, ConditionalStack cstack, PQExpBuffer query_buf)
 
static backslashResult exec_command_else (PsqlScanState scan_state, ConditionalStack cstack, PQExpBuffer query_buf)
 
static backslashResult exec_command_endif (PsqlScanState scan_state, ConditionalStack cstack, PQExpBuffer query_buf)
 
static backslashResult exec_command_encoding (PsqlScanState scan_state, bool active_branch)
 
static backslashResult exec_command_errverbose (PsqlScanState scan_state, bool active_branch)
 
static backslashResult exec_command_f (PsqlScanState scan_state, bool active_branch)
 
static backslashResult exec_command_g (PsqlScanState scan_state, bool active_branch, const char *cmd)
 
static backslashResult process_command_g_options (char *first_option, PsqlScanState scan_state, bool active_branch, const char *cmd)
 
static backslashResult exec_command_gdesc (PsqlScanState scan_state, bool active_branch)
 
static backslashResult exec_command_getenv (PsqlScanState scan_state, bool active_branch, const char *cmd)
 
static backslashResult exec_command_gexec (PsqlScanState scan_state, bool active_branch)
 
static backslashResult exec_command_gset (PsqlScanState scan_state, bool active_branch)
 
static backslashResult exec_command_help (PsqlScanState scan_state, bool active_branch)
 
static backslashResult exec_command_html (PsqlScanState scan_state, bool active_branch)
 
static backslashResult exec_command_include (PsqlScanState scan_state, bool active_branch, const char *cmd)
 
static backslashResult exec_command_if (PsqlScanState scan_state, ConditionalStack cstack, PQExpBuffer query_buf)
 
static backslashResult exec_command_list (PsqlScanState scan_state, bool active_branch, const char *cmd)
 
static backslashResult exec_command_lo (PsqlScanState scan_state, bool active_branch, const char *cmd)
 
static backslashResult exec_command_out (PsqlScanState scan_state, bool active_branch)
 
static backslashResult exec_command_print (PsqlScanState scan_state, bool active_branch, PQExpBuffer query_buf, PQExpBuffer previous_buf)
 
static backslashResult exec_command_password (PsqlScanState scan_state, bool active_branch)
 
static backslashResult exec_command_prompt (PsqlScanState scan_state, bool active_branch, const char *cmd)
 
static backslashResult exec_command_pset (PsqlScanState scan_state, bool active_branch)
 
static backslashResult exec_command_quit (PsqlScanState scan_state, bool active_branch)
 
static backslashResult exec_command_reset (PsqlScanState scan_state, bool active_branch, PQExpBuffer query_buf)
 
static backslashResult exec_command_s (PsqlScanState scan_state, bool active_branch)
 
static backslashResult exec_command_set (PsqlScanState scan_state, bool active_branch)
 
static backslashResult exec_command_setenv (PsqlScanState scan_state, bool active_branch, const char *cmd)
 
static backslashResult exec_command_sf_sv (PsqlScanState scan_state, bool active_branch, const char *cmd, bool is_func)
 
static backslashResult exec_command_t (PsqlScanState scan_state, bool active_branch)
 
static backslashResult exec_command_T (PsqlScanState scan_state, bool active_branch)
 
static backslashResult exec_command_timing (PsqlScanState scan_state, bool active_branch)
 
static backslashResult exec_command_unset (PsqlScanState scan_state, bool active_branch, const char *cmd)
 
static backslashResult exec_command_write (PsqlScanState scan_state, bool active_branch, const char *cmd, PQExpBuffer query_buf, PQExpBuffer previous_buf)
 
static backslashResult exec_command_watch (PsqlScanState scan_state, bool active_branch, PQExpBuffer query_buf, PQExpBuffer previous_buf)
 
static backslashResult exec_command_x (PsqlScanState scan_state, bool active_branch)
 
static backslashResult exec_command_z (PsqlScanState scan_state, bool active_branch, const char *cmd)
 
static backslashResult exec_command_shell_escape (PsqlScanState scan_state, bool active_branch)
 
static backslashResult exec_command_slash_command_help (PsqlScanState scan_state, bool active_branch)
 
static char * read_connect_arg (PsqlScanState scan_state)
 
static PQExpBuffer gather_boolean_expression (PsqlScanState scan_state)
 
static bool is_true_boolean_expression (PsqlScanState scan_state, const char *name)
 
static void ignore_boolean_expression (PsqlScanState scan_state)
 
static void ignore_slash_options (PsqlScanState scan_state)
 
static void ignore_slash_filepipe (PsqlScanState scan_state)
 
static void ignore_slash_whole_line (PsqlScanState scan_state)
 
static bool is_branching_command (const char *cmd)
 
static void save_query_text_state (PsqlScanState scan_state, ConditionalStack cstack, PQExpBuffer query_buf)
 
static void discard_query_text (PsqlScanState scan_state, ConditionalStack cstack, PQExpBuffer query_buf)
 
static bool copy_previous_query (PQExpBuffer query_buf, PQExpBuffer previous_buf)
 
static bool do_connect (enum trivalue reuse_previous_specification, char *dbname, char *user, char *host, char *port)
 
static bool do_edit (const char *filename_arg, PQExpBuffer query_buf, int lineno, bool discard_on_quit, bool *edited)
 
static bool do_shell (const char *command)
 
static bool do_watch (PQExpBuffer query_buf, double sleep, int iter, int min_rows)
 
static bool lookup_object_oid (EditableObjectType obj_type, const char *desc, Oid *obj_oid)
 
static bool get_create_object_cmd (EditableObjectType obj_type, Oid oid, PQExpBuffer buf)
 
static int strip_lineno_from_objdesc (char *obj)
 
static int count_lines_in_buf (PQExpBuffer buf)
 
static void print_with_linenumbers (FILE *output, char *lines, bool is_func)
 
static void minimal_error_message (PGresult *res)
 
static void printSSLInfo (void)
 
static void printGSSInfo (void)
 
static bool printPsetInfo (const char *param, printQueryOpt *popt)
 
static char * pset_value_string (const char *param, printQueryOpt *popt)
 
backslashResult HandleSlashCmds (PsqlScanState scan_state, ConditionalStack cstack, PQExpBuffer query_buf, PQExpBuffer previous_buf)
 
static char * prompt_for_password (const char *username, bool *canceled)
 
static bool param_is_newly_set (const char *old_val, const char *new_val)
 
void connection_warnings (bool in_startup)
 
void SyncVariables (void)
 
void UnsyncVariables (void)
 
static bool editFile (const char *fname, int lineno)
 
int process_file (char *filename, bool use_relative_path)
 
static const char * _align2string (enum printFormat in)
 
static bool set_unicode_line_style (const char *value, size_t vallen, unicode_linestyle *linestyle)
 
static const char * _unicode_linestyle2string (int linestyle)
 
bool do_pset (const char *param, const char *value, printQueryOpt *popt, bool quiet)
 
printQueryOptsavePsetInfo (const printQueryOpt *popt)
 
void restorePsetInfo (printQueryOpt *popt, printQueryOpt *save)
 
static const char * pset_bool_string (bool val)
 
static char * pset_quoted_string (const char *str)
 
static bool echo_hidden_command (const char *query)
 

Macro Definition Documentation

◆ DEFAULT_SHELL

#define DEFAULT_SHELL   "/bin/sh"

Definition at line 5108 of file command.c.

Typedef Documentation

◆ EditableObjectType

Enumeration Type Documentation

◆ EditableObjectType

Enumerator
EditableFunction 
EditableView 

Definition at line 53 of file command.c.

54 {
EditableObjectType
Definition: command.c:54
@ EditableFunction
Definition: command.c:55
@ EditableView
Definition: command.c:56

Function Documentation

◆ _align2string()

static const char* _align2string ( enum printFormat  in)
static

Definition at line 4283 of file command.c.

4284 {
4285  switch (in)
4286  {
4287  case PRINT_NOTHING:
4288  return "nothing";
4289  break;
4290  case PRINT_ALIGNED:
4291  return "aligned";
4292  break;
4293  case PRINT_ASCIIDOC:
4294  return "asciidoc";
4295  break;
4296  case PRINT_CSV:
4297  return "csv";
4298  break;
4299  case PRINT_HTML:
4300  return "html";
4301  break;
4302  case PRINT_LATEX:
4303  return "latex";
4304  break;
4305  case PRINT_LATEX_LONGTABLE:
4306  return "latex-longtable";
4307  break;
4308  case PRINT_TROFF_MS:
4309  return "troff-ms";
4310  break;
4311  case PRINT_UNALIGNED:
4312  return "unaligned";
4313  break;
4314  case PRINT_WRAPPED:
4315  return "wrapped";
4316  break;
4317  }
4318  return "unknown";
4319 }
@ PRINT_LATEX_LONGTABLE
Definition: print.h:36
@ PRINT_CSV
Definition: print.h:33
@ PRINT_UNALIGNED
Definition: print.h:38
@ PRINT_ALIGNED
Definition: print.h:31
@ PRINT_TROFF_MS
Definition: print.h:37
@ PRINT_ASCIIDOC
Definition: print.h:32
@ PRINT_NOTHING
Definition: print.h:30
@ PRINT_LATEX
Definition: print.h:35
@ PRINT_HTML
Definition: print.h:34
@ PRINT_WRAPPED
Definition: print.h:39

References PRINT_ALIGNED, PRINT_ASCIIDOC, PRINT_CSV, PRINT_HTML, PRINT_LATEX, PRINT_LATEX_LONGTABLE, PRINT_NOTHING, PRINT_TROFF_MS, PRINT_UNALIGNED, and PRINT_WRAPPED.

Referenced by printPsetInfo(), and pset_value_string().

◆ _unicode_linestyle2string()

static const char* _unicode_linestyle2string ( int  linestyle)
static

Definition at line 4339 of file command.c.

4340 {
4341  switch (linestyle)
4342  {
4344  return "single";
4345  break;
4347  return "double";
4348  break;
4349  }
4350  return "unknown";
4351 }
@ UNICODE_LINESTYLE_SINGLE
Definition: print.h:101
@ UNICODE_LINESTYLE_DOUBLE
Definition: print.h:102

References UNICODE_LINESTYLE_DOUBLE, and UNICODE_LINESTYLE_SINGLE.

Referenced by printPsetInfo(), and pset_value_string().

◆ connection_warnings()

void connection_warnings ( bool  in_startup)

Definition at line 3753 of file command.c.

3754 {
3755  if (!pset.quiet && !pset.notty)
3756  {
3757  int client_ver = PG_VERSION_NUM;
3758  char cverbuf[32];
3759  char sverbuf[32];
3760 
3761  if (pset.sversion != client_ver)
3762  {
3763  const char *server_version;
3764 
3765  /* Try to get full text form, might include "devel" etc */
3766  server_version = PQparameterStatus(pset.db, "server_version");
3767  /* Otherwise fall back on pset.sversion */
3768  if (!server_version)
3769  {
3771  sverbuf, sizeof(sverbuf));
3772  server_version = sverbuf;
3773  }
3774 
3775  printf(_("%s (%s, server %s)\n"),
3776  pset.progname, PG_VERSION, server_version);
3777  }
3778  /* For version match, only print psql banner on startup. */
3779  else if (in_startup)
3780  printf("%s (%s)\n", pset.progname, PG_VERSION);
3781 
3782  /*
3783  * Warn if server's major version is newer than ours, or if server
3784  * predates our support cutoff (currently 9.2).
3785  */
3786  if (pset.sversion / 100 > client_ver / 100 ||
3787  pset.sversion < 90200)
3788  printf(_("WARNING: %s major version %s, server major version %s.\n"
3789  " Some psql features might not work.\n"),
3790  pset.progname,
3791  formatPGVersionNumber(client_ver, false,
3792  cverbuf, sizeof(cverbuf)),
3794  sverbuf, sizeof(sverbuf)));
3795 
3796 #ifdef WIN32
3797  if (in_startup)
3798  checkWin32Codepage();
3799 #endif
3800  printSSLInfo();
3801  printGSSInfo();
3802  }
3803 }
static void printSSLInfo(void)
Definition: command.c:3812
static void printGSSInfo(void)
Definition: command.c:3837
#define _(x)
Definition: elog.c:90
const char * PQparameterStatus(const PGconn *conn, const char *paramName)
Definition: fe-connect.c:6913
static int server_version
Definition: pg_dumpall.c:112
#define printf(...)
Definition: port.h:244
PsqlSettings pset
Definition: startup.c:32
char * formatPGVersionNumber(int version_number, bool include_minor, char *buf, size_t buflen)
Definition: string_utils.c:177
PGconn * db
Definition: settings.h:82
const char * progname
Definition: settings.h:113

References _, _psqlSettings::db, formatPGVersionNumber(), _psqlSettings::notty, PQparameterStatus(), printf, printGSSInfo(), printSSLInfo(), _psqlSettings::progname, pset, _psqlSettings::quiet, server_version, and _psqlSettings::sversion.

Referenced by CheckConnection(), do_connect(), and main().

◆ copy_previous_query()

static bool copy_previous_query ( PQExpBuffer  query_buf,
PQExpBuffer  previous_buf 
)
static

Definition at line 3225 of file command.c.

3226 {
3227  if (query_buf && query_buf->len == 0)
3228  {
3229  appendPQExpBufferStr(query_buf, previous_buf->data);
3230  return true;
3231  }
3232  return false;
3233 }
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:367

References appendPQExpBufferStr(), PQExpBufferData::data, and PQExpBufferData::len.

Referenced by exec_command(), exec_command_edit(), and exec_command_watch().

◆ count_lines_in_buf()

static int count_lines_in_buf ( PQExpBuffer  buf)
static

Definition at line 5715 of file command.c.

5716 {
5717  int lineno = 0;
5718  const char *lines = buf->data;
5719 
5720  while (*lines != '\0')
5721  {
5722  lineno++;
5723  /* find start of next line */
5724  lines = strchr(lines, '\n');
5725  if (!lines)
5726  break;
5727  lines++;
5728  }
5729 
5730  return lineno;
5731 }
static char * buf
Definition: pg_test_fsync.c:73

References buf.

Referenced by exec_command_sf_sv().

◆ discard_query_text()

static void discard_query_text ( PsqlScanState  scan_state,
ConditionalStack  cstack,
PQExpBuffer  query_buf 
)
static

Definition at line 3199 of file command.c.

3201 {
3202  if (query_buf)
3203  {
3204  int new_len = conditional_stack_get_query_len(cstack);
3205 
3206  Assert(new_len >= 0 && new_len <= query_buf->len);
3207  query_buf->len = new_len;
3208  query_buf->data[new_len] = '\0';
3209  }
3210  psql_scan_set_paren_depth(scan_state,
3212 }
int conditional_stack_get_query_len(ConditionalStack cstack)
Definition: conditional.c:162
int conditional_stack_get_paren_depth(ConditionalStack cstack)
Definition: conditional.c:184
Assert(fmt[strlen(fmt) - 1] !='\n')
const void size_t len
void psql_scan_set_paren_depth(PsqlScanState state, int depth)

References Assert(), conditional_stack_get_paren_depth(), conditional_stack_get_query_len(), PQExpBufferData::data, PQExpBufferData::len, len, and psql_scan_set_paren_depth().

Referenced by exec_command_elif(), exec_command_else(), and exec_command_endif().

◆ do_connect()

static bool do_connect ( enum trivalue  reuse_previous_specification,
char *  dbname,
char *  user,
char *  host,
char *  port 
)
static

Definition at line 3294 of file command.c.

3296 {
3297  PGconn *o_conn = pset.db,
3298  *n_conn = NULL;
3299  PQconninfoOption *cinfo;
3300  int nconnopts = 0;
3301  bool same_host = false;
3302  char *password = NULL;
3303  char *client_encoding;
3304  bool success = true;
3305  bool keep_password = true;
3306  bool has_connection_string;
3307  bool reuse_previous;
3308 
3309  has_connection_string = dbname ?
3311 
3312  /* Complain if we have additional arguments after a connection string. */
3313  if (has_connection_string && (user || host || port))
3314  {
3315  pg_log_error("Do not give user, host, or port separately when using a connection string");
3316  return false;
3317  }
3318 
3319  switch (reuse_previous_specification)
3320  {
3321  case TRI_YES:
3322  reuse_previous = true;
3323  break;
3324  case TRI_NO:
3325  reuse_previous = false;
3326  break;
3327  default:
3328  reuse_previous = !has_connection_string;
3329  break;
3330  }
3331 
3332  /*
3333  * If we intend to re-use connection parameters, collect them out of the
3334  * old connection, then replace individual values as necessary. (We may
3335  * need to resort to looking at pset.dead_conn, if the connection died
3336  * previously.) Otherwise, obtain a PQconninfoOption array containing
3337  * libpq's defaults, and modify that. Note this function assumes that
3338  * PQconninfo, PQconndefaults, and PQconninfoParse will all produce arrays
3339  * containing the same options in the same order.
3340  */
3341  if (reuse_previous)
3342  {
3343  if (o_conn)
3344  cinfo = PQconninfo(o_conn);
3345  else if (pset.dead_conn)
3346  cinfo = PQconninfo(pset.dead_conn);
3347  else
3348  {
3349  /* This is reachable after a non-interactive \connect failure */
3350  pg_log_error("No database connection exists to re-use parameters from");
3351  return false;
3352  }
3353  }
3354  else
3355  cinfo = PQconndefaults();
3356 
3357  if (cinfo)
3358  {
3359  if (has_connection_string)
3360  {
3361  /* Parse the connstring and insert values into cinfo */
3362  PQconninfoOption *replcinfo;
3363  char *errmsg;
3364 
3365  replcinfo = PQconninfoParse(dbname, &errmsg);
3366  if (replcinfo)
3367  {
3368  PQconninfoOption *ci;
3369  PQconninfoOption *replci;
3370  bool have_password = false;
3371 
3372  for (ci = cinfo, replci = replcinfo;
3373  ci->keyword && replci->keyword;
3374  ci++, replci++)
3375  {
3376  Assert(strcmp(ci->keyword, replci->keyword) == 0);
3377  /* Insert value from connstring if one was provided */
3378  if (replci->val)
3379  {
3380  /*
3381  * We know that both val strings were allocated by
3382  * libpq, so the least messy way to avoid memory leaks
3383  * is to swap them.
3384  */
3385  char *swap = replci->val;
3386 
3387  replci->val = ci->val;
3388  ci->val = swap;
3389 
3390  /*
3391  * Check whether connstring provides options affecting
3392  * password re-use. While any change in user, host,
3393  * hostaddr, or port causes us to ignore the old
3394  * connection's password, we don't force that for
3395  * dbname, since passwords aren't database-specific.
3396  */
3397  if (replci->val == NULL ||
3398  strcmp(ci->val, replci->val) != 0)
3399  {
3400  if (strcmp(replci->keyword, "user") == 0 ||
3401  strcmp(replci->keyword, "host") == 0 ||
3402  strcmp(replci->keyword, "hostaddr") == 0 ||
3403  strcmp(replci->keyword, "port") == 0)
3404  keep_password = false;
3405  }
3406  /* Also note whether connstring contains a password. */
3407  if (strcmp(replci->keyword, "password") == 0)
3408  have_password = true;
3409  }
3410  else if (!reuse_previous)
3411  {
3412  /*
3413  * When we have a connstring and are not re-using
3414  * parameters, swap *all* entries, even those not set
3415  * by the connstring. This avoids absorbing
3416  * environment-dependent defaults from the result of
3417  * PQconndefaults(). We don't want to do that because
3418  * they'd override service-file entries if the
3419  * connstring specifies a service parameter, whereas
3420  * the priority should be the other way around. libpq
3421  * can certainly recompute any defaults we don't pass
3422  * here. (In this situation, it's a bit wasteful to
3423  * have called PQconndefaults() at all, but not doing
3424  * so would require yet another major code path here.)
3425  */
3426  replci->val = ci->val;
3427  ci->val = NULL;
3428  }
3429  }
3430  Assert(ci->keyword == NULL && replci->keyword == NULL);
3431 
3432  /* While here, determine how many option slots there are */
3433  nconnopts = ci - cinfo;
3434 
3435  PQconninfoFree(replcinfo);
3436 
3437  /*
3438  * If the connstring contains a password, tell the loop below
3439  * that we may use it, regardless of other settings (i.e.,
3440  * cinfo's password is no longer an "old" password).
3441  */
3442  if (have_password)
3443  keep_password = true;
3444 
3445  /* Don't let code below try to inject dbname into params. */
3446  dbname = NULL;
3447  }
3448  else
3449  {
3450  /* PQconninfoParse failed */
3451  if (errmsg)
3452  {
3453  pg_log_error("%s", errmsg);
3454  PQfreemem(errmsg);
3455  }
3456  else
3457  pg_log_error("out of memory");
3458  success = false;
3459  }
3460  }
3461  else
3462  {
3463  /*
3464  * If dbname isn't a connection string, then we'll inject it and
3465  * the other parameters into the keyword array below. (We can't
3466  * easily insert them into the cinfo array because of memory
3467  * management issues: PQconninfoFree would misbehave on Windows.)
3468  * However, to avoid dependencies on the order in which parameters
3469  * appear in the array, make a preliminary scan to set
3470  * keep_password and same_host correctly.
3471  *
3472  * While any change in user, host, or port causes us to ignore the
3473  * old connection's password, we don't force that for dbname,
3474  * since passwords aren't database-specific.
3475  */
3476  PQconninfoOption *ci;
3477 
3478  for (ci = cinfo; ci->keyword; ci++)
3479  {
3480  if (user && strcmp(ci->keyword, "user") == 0)
3481  {
3482  if (!(ci->val && strcmp(user, ci->val) == 0))
3483  keep_password = false;
3484  }
3485  else if (host && strcmp(ci->keyword, "host") == 0)
3486  {
3487  if (ci->val && strcmp(host, ci->val) == 0)
3488  same_host = true;
3489  else
3490  keep_password = false;
3491  }
3492  else if (port && strcmp(ci->keyword, "port") == 0)
3493  {
3494  if (!(ci->val && strcmp(port, ci->val) == 0))
3495  keep_password = false;
3496  }
3497  }
3498 
3499  /* While here, determine how many option slots there are */
3500  nconnopts = ci - cinfo;
3501  }
3502  }
3503  else
3504  {
3505  /* We failed to create the cinfo structure */
3506  pg_log_error("out of memory");
3507  success = false;
3508  }
3509 
3510  /*
3511  * If the user asked to be prompted for a password, ask for one now. If
3512  * not, use the password from the old connection, provided the username
3513  * etc have not changed. Otherwise, try to connect without a password
3514  * first, and then ask for a password if needed.
3515  *
3516  * XXX: this behavior leads to spurious connection attempts recorded in
3517  * the postmaster's log. But libpq offers no API that would let us obtain
3518  * a password and then continue with the first connection attempt.
3519  */
3520  if (pset.getPassword == TRI_YES && success)
3521  {
3522  bool canceled = false;
3523 
3524  /*
3525  * If a connstring or URI is provided, we don't know which username
3526  * will be used, since we haven't dug that out of the connstring.
3527  * Don't risk issuing a misleading prompt. As in startup.c, it does
3528  * not seem worth working harder, since this getPassword setting is
3529  * normally only used in noninteractive cases.
3530  */
3531  password = prompt_for_password(has_connection_string ? NULL : user,
3532  &canceled);
3533  success = !canceled;
3534  }
3535 
3536  /*
3537  * Consider whether to force client_encoding to "auto" (overriding
3538  * anything in the connection string). We do so if we have a terminal
3539  * connection and there is no PGCLIENTENCODING environment setting.
3540  */
3541  if (pset.notty || getenv("PGCLIENTENCODING"))
3542  client_encoding = NULL;
3543  else
3544  client_encoding = "auto";
3545 
3546  /* Loop till we have a connection or fail, which we might've already */
3547  while (success)
3548  {
3549  const char **keywords = pg_malloc((nconnopts + 1) * sizeof(*keywords));
3550  const char **values = pg_malloc((nconnopts + 1) * sizeof(*values));
3551  int paramnum = 0;
3552  PQconninfoOption *ci;
3553 
3554  /*
3555  * Copy non-default settings into the PQconnectdbParams parameter
3556  * arrays; but inject any values specified old-style, as well as any
3557  * interactively-obtained password, and a couple of fields we want to
3558  * set forcibly.
3559  *
3560  * If you change this code, see also the initial-connection code in
3561  * main().
3562  */
3563  for (ci = cinfo; ci->keyword; ci++)
3564  {
3565  keywords[paramnum] = ci->keyword;
3566 
3567  if (dbname && strcmp(ci->keyword, "dbname") == 0)
3568  values[paramnum++] = dbname;
3569  else if (user && strcmp(ci->keyword, "user") == 0)
3570  values[paramnum++] = user;
3571  else if (host && strcmp(ci->keyword, "host") == 0)
3572  values[paramnum++] = host;
3573  else if (host && !same_host && strcmp(ci->keyword, "hostaddr") == 0)
3574  {
3575  /* If we're changing the host value, drop any old hostaddr */
3576  values[paramnum++] = NULL;
3577  }
3578  else if (port && strcmp(ci->keyword, "port") == 0)
3579  values[paramnum++] = port;
3580  /* If !keep_password, we unconditionally drop old password */
3581  else if ((password || !keep_password) &&
3582  strcmp(ci->keyword, "password") == 0)
3583  values[paramnum++] = password;
3584  else if (strcmp(ci->keyword, "fallback_application_name") == 0)
3585  values[paramnum++] = pset.progname;
3586  else if (client_encoding &&
3587  strcmp(ci->keyword, "client_encoding") == 0)
3588  values[paramnum++] = client_encoding;
3589  else if (ci->val)
3590  values[paramnum++] = ci->val;
3591  /* else, don't bother making libpq parse this keyword */
3592  }
3593  /* add array terminator */
3594  keywords[paramnum] = NULL;
3595  values[paramnum] = NULL;
3596 
3597  /* Note we do not want libpq to re-expand the dbname parameter */
3598  n_conn = PQconnectdbParams(keywords, values, false);
3599 
3600  pg_free(keywords);
3601  pg_free(values);
3602 
3603  if (PQstatus(n_conn) == CONNECTION_OK)
3604  break;
3605 
3606  /*
3607  * Connection attempt failed; either retry the connection attempt with
3608  * a new password, or give up.
3609  */
3611  {
3612  bool canceled = false;
3613 
3614  /*
3615  * Prompt for password using the username we actually connected
3616  * with --- it might've come out of "dbname" rather than "user".
3617  */
3618  password = prompt_for_password(PQuser(n_conn), &canceled);
3619  PQfinish(n_conn);
3620  n_conn = NULL;
3621  success = !canceled;
3622  continue;
3623  }
3624 
3625  /*
3626  * We'll report the error below ... unless n_conn is NULL, indicating
3627  * that libpq didn't have enough memory to make a PGconn.
3628  */
3629  if (n_conn == NULL)
3630  pg_log_error("out of memory");
3631 
3632  success = false;
3633  } /* end retry loop */
3634 
3635  /* Release locally allocated data, whether we succeeded or not */
3636  pg_free(password);
3637  PQconninfoFree(cinfo);
3638 
3639  if (!success)
3640  {
3641  /*
3642  * Failed to connect to the database. In interactive mode, keep the
3643  * previous connection to the DB; in scripting mode, close our
3644  * previous connection as well.
3645  */
3647  {
3648  if (n_conn)
3649  {
3650  pg_log_info("%s", PQerrorMessage(n_conn));
3651  PQfinish(n_conn);
3652  }
3653 
3654  /* pset.db is left unmodified */
3655  if (o_conn)
3656  pg_log_info("Previous connection kept");
3657  }
3658  else
3659  {
3660  if (n_conn)
3661  {
3662  pg_log_error("\\connect: %s", PQerrorMessage(n_conn));
3663  PQfinish(n_conn);
3664  }
3665 
3666  if (o_conn)
3667  {
3668  /*
3669  * Transition to having no connection.
3670  *
3671  * Unlike CheckConnection(), we close the old connection
3672  * immediately to prevent its parameters from being re-used.
3673  * This is so that a script cannot accidentally reuse
3674  * parameters it did not expect to. Otherwise, the state
3675  * cleanup should be the same as in CheckConnection().
3676  */
3677  PQfinish(o_conn);
3678  pset.db = NULL;
3679  ResetCancelConn();
3680  UnsyncVariables();
3681  }
3682 
3683  /* On the same reasoning, release any dead_conn to prevent reuse */
3684  if (pset.dead_conn)
3685  {
3687  pset.dead_conn = NULL;
3688  }
3689  }
3690 
3691  return false;
3692  }
3693 
3694  /*
3695  * Replace the old connection with the new one, and update
3696  * connection-dependent variables. Keep the resynchronization logic in
3697  * sync with CheckConnection().
3698  */
3699  PQsetNoticeProcessor(n_conn, NoticeProcessor, NULL);
3700  pset.db = n_conn;
3701  SyncVariables();
3702  connection_warnings(false); /* Must be after SyncVariables */
3703 
3704  /* Tell the user about the new connection */
3705  if (!pset.quiet)
3706  {
3707  if (!o_conn ||
3708  param_is_newly_set(PQhost(o_conn), PQhost(pset.db)) ||
3709  param_is_newly_set(PQport(o_conn), PQport(pset.db)))
3710  {
3711  char *connhost = PQhost(pset.db);
3712  char *hostaddr = PQhostaddr(pset.db);
3713 
3714  if (is_unixsock_path(connhost))
3715  {
3716  /* hostaddr overrides connhost */
3717  if (hostaddr && *hostaddr)
3718  printf(_("You are now connected to database \"%s\" as user \"%s\" on address \"%s\" at port \"%s\".\n"),
3719  PQdb(pset.db), PQuser(pset.db), hostaddr, PQport(pset.db));
3720  else
3721  printf(_("You are now connected to database \"%s\" as user \"%s\" via socket in \"%s\" at port \"%s\".\n"),
3722  PQdb(pset.db), PQuser(pset.db), connhost, PQport(pset.db));
3723  }
3724  else
3725  {
3726  if (hostaddr && *hostaddr && strcmp(connhost, hostaddr) != 0)
3727  printf(_("You are now connected to database \"%s\" as user \"%s\" on host \"%s\" (address \"%s\") at port \"%s\".\n"),
3728  PQdb(pset.db), PQuser(pset.db), connhost, hostaddr, PQport(pset.db));
3729  else
3730  printf(_("You are now connected to database \"%s\" as user \"%s\" on host \"%s\" at port \"%s\".\n"),
3731  PQdb(pset.db), PQuser(pset.db), connhost, PQport(pset.db));
3732  }
3733  }
3734  else
3735  printf(_("You are now connected to database \"%s\" as user \"%s\".\n"),
3736  PQdb(pset.db), PQuser(pset.db));
3737  }
3738 
3739  /* Drop no-longer-needed connection(s) */
3740  if (o_conn)
3741  PQfinish(o_conn);
3742  if (pset.dead_conn)
3743  {
3745  pset.dead_conn = NULL;
3746  }
3747 
3748  return true;
3749 }
void NoticeProcessor(void *arg, const char *message)
Definition: common.c:229
bool recognized_connection_string(const char *connstr)
Definition: common.c:2437
static Datum values[MAXATTR]
Definition: bootstrap.c:152
void ResetCancelConn(void)
Definition: cancel.c:107
static char * prompt_for_password(const char *username, bool *canceled)
Definition: command.c:3243
static bool param_is_newly_set(const char *old_val, const char *new_val)
Definition: command.c:3271
void UnsyncVariables(void)
Definition: command.c:3919
void SyncVariables(void)
Definition: command.c:3878
void connection_warnings(bool in_startup)
Definition: command.c:3753
int errmsg(const char *fmt,...)
Definition: elog.c:1072
PQconninfoOption * PQconninfoParse(const char *conninfo, char **errmsg)
Definition: fe-connect.c:5529
char * PQhost(const PGconn *conn)
Definition: fe-connect.c:6827
PGconn * PQconnectdbParams(const char *const *keywords, const char *const *values, int expand_dbname)
Definition: fe-connect.c:678
char * PQdb(const PGconn *conn)
Definition: fe-connect.c:6794
PQconninfoOption * PQconndefaults(void)
Definition: fe-connect.c:1819
char * PQhostaddr(const PGconn *conn)
Definition: fe-connect.c:6850
void PQconninfoFree(PQconninfoOption *connOptions)
Definition: fe-connect.c:6781
PQconninfoOption * PQconninfo(PGconn *conn)
Definition: fe-connect.c:6737
int PQconnectionNeedsPassword(const PGconn *conn)
Definition: fe-connect.c:6999
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6948
ConnStatusType PQstatus(const PGconn *conn)
Definition: fe-connect.c:6895
void PQfinish(PGconn *conn)
Definition: fe-connect.c:4669
char * PQuser(const PGconn *conn)
Definition: fe-connect.c:6802
char * PQport(const PGconn *conn)
Definition: fe-connect.c:6863
PQnoticeProcessor PQsetNoticeProcessor(PGconn *conn, PQnoticeProcessor proc, void *arg)
Definition: fe-connect.c:7127
void PQfreemem(void *ptr)
Definition: fe-exec.c:3992
void pg_free(void *ptr)
Definition: fe_memutils.c:105
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
static bool success
Definition: initdb.c:186
return false
Definition: isn.c:131
@ CONNECTION_OK
Definition: libpq-fe.h:60
#define pg_log_error(...)
Definition: logging.h:106
#define pg_log_info(...)
Definition: logging.h:124
static char * user
Definition: pg_regress.c:120
static int port
Definition: pg_regress.c:116
static bool is_unixsock_path(const char *path)
Definition: pqcomm.h:67
static char * password
Definition: streamutil.c:54
char * dbname
Definition: streamutil.c:52
PGconn * dead_conn
Definition: settings.h:129
enum trivalue getPassword
Definition: settings.h:108
bool cur_cmd_interactive
Definition: settings.h:111
@ TRI_YES
Definition: vacuumlo.c:38
@ TRI_NO
Definition: vacuumlo.c:37

References _, Assert(), CONNECTION_OK, connection_warnings(), _psqlSettings::cur_cmd_interactive, _psqlSettings::db, dbname, _psqlSettings::dead_conn, errmsg(), _psqlSettings::getPassword, is_unixsock_path(), _PQconninfoOption::keyword, NoticeProcessor(), _psqlSettings::notty, param_is_newly_set(), password, pg_free(), pg_log_error, pg_log_info, pg_malloc(), port, PQconndefaults(), PQconnectdbParams(), PQconnectionNeedsPassword(), PQconninfo(), PQconninfoFree(), PQconninfoParse(), PQdb(), PQerrorMessage(), PQfinish(), PQfreemem(), PQhost(), PQhostaddr(), PQport(), PQsetNoticeProcessor(), PQstatus(), PQuser(), printf, _psqlSettings::progname, prompt_for_password(), pset, _psqlSettings::quiet, recognized_connection_string(), ResetCancelConn(), success, SyncVariables(), TRI_NO, TRI_YES, UnsyncVariables(), user, _PQconninfoOption::val, and values.

Referenced by exec_command_connect().

◆ do_edit()

static bool do_edit ( const char *  filename_arg,
PQExpBuffer  query_buf,
int  lineno,
bool  discard_on_quit,
bool edited 
)
static

Definition at line 4021 of file command.c.

4023 {
4024  char fnametmp[MAXPGPATH];
4025  FILE *stream = NULL;
4026  const char *fname;
4027  bool error = false;
4028  int fd;
4029  struct stat before,
4030  after;
4031 
4032  if (filename_arg)
4033  fname = filename_arg;
4034  else
4035  {
4036  /* make a temp file to edit */
4037 #ifndef WIN32
4038  const char *tmpdir = getenv("TMPDIR");
4039 
4040  if (!tmpdir)
4041  tmpdir = "/tmp";
4042 #else
4043  char tmpdir[MAXPGPATH];
4044  int ret;
4045 
4046  ret = GetTempPath(MAXPGPATH, tmpdir);
4047  if (ret == 0 || ret > MAXPGPATH)
4048  {
4049  pg_log_error("could not locate temporary directory: %s",
4050  !ret ? strerror(errno) : "");
4051  return false;
4052  }
4053 #endif
4054 
4055  /*
4056  * No canonicalize_path() here. EDIT.EXE run from CMD.EXE prepends the
4057  * current directory to the supplied path unless we use only
4058  * backslashes, so we do that.
4059  */
4060 #ifndef WIN32
4061  snprintf(fnametmp, sizeof(fnametmp), "%s%spsql.edit.%d.sql", tmpdir,
4062  "/", (int) getpid());
4063 #else
4064  snprintf(fnametmp, sizeof(fnametmp), "%s%spsql.edit.%d.sql", tmpdir,
4065  "" /* trailing separator already present */ , (int) getpid());
4066 #endif
4067 
4068  fname = (const char *) fnametmp;
4069 
4070  fd = open(fname, O_WRONLY | O_CREAT | O_EXCL, 0600);
4071  if (fd != -1)
4072  stream = fdopen(fd, "w");
4073 
4074  if (fd == -1 || !stream)
4075  {
4076  pg_log_error("could not open temporary file \"%s\": %m", fname);
4077  error = true;
4078  }
4079  else
4080  {
4081  unsigned int ql = query_buf->len;
4082 
4083  /* force newline-termination of what we send to editor */
4084  if (ql > 0 && query_buf->data[ql - 1] != '\n')
4085  {
4086  appendPQExpBufferChar(query_buf, '\n');
4087  ql++;
4088  }
4089 
4090  if (fwrite(query_buf->data, 1, ql, stream) != ql)
4091  {
4092  pg_log_error("%s: %m", fname);
4093 
4094  if (fclose(stream) != 0)
4095  pg_log_error("%s: %m", fname);
4096 
4097  if (remove(fname) != 0)
4098  pg_log_error("%s: %m", fname);
4099 
4100  error = true;
4101  }
4102  else if (fclose(stream) != 0)
4103  {
4104  pg_log_error("%s: %m", fname);
4105  if (remove(fname) != 0)
4106  pg_log_error("%s: %m", fname);
4107  error = true;
4108  }
4109  else
4110  {
4111  struct utimbuf ut;
4112 
4113  /*
4114  * Try to set the file modification time of the temporary file
4115  * a few seconds in the past. Otherwise, the low granularity
4116  * (one second, or even worse on some filesystems) that we can
4117  * portably measure with stat(2) could lead us to not
4118  * recognize a modification, if the user typed very quickly.
4119  *
4120  * This is a rather unlikely race condition, so don't error
4121  * out if the utime(2) call fails --- that would make the cure
4122  * worse than the disease.
4123  */
4124  ut.modtime = ut.actime = time(NULL) - 2;
4125  (void) utime(fname, &ut);
4126  }
4127  }
4128  }
4129 
4130  if (!error && stat(fname, &before) != 0)
4131  {
4132  pg_log_error("%s: %m", fname);
4133  error = true;
4134  }
4135 
4136  /* call editor */
4137  if (!error)
4138  error = !editFile(fname, lineno);
4139 
4140  if (!error && stat(fname, &after) != 0)
4141  {
4142  pg_log_error("%s: %m", fname);
4143  error = true;
4144  }
4145 
4146  /* file was edited if the size or modification time has changed */
4147  if (!error &&
4148  (before.st_size != after.st_size ||
4149  before.st_mtime != after.st_mtime))
4150  {
4151  stream = fopen(fname, PG_BINARY_R);
4152  if (!stream)
4153  {
4154  pg_log_error("%s: %m", fname);
4155  error = true;
4156  }
4157  else
4158  {
4159  /* read file back into query_buf */
4160  char line[1024];
4161 
4162  resetPQExpBuffer(query_buf);
4163  while (fgets(line, sizeof(line), stream) != NULL)
4164  appendPQExpBufferStr(query_buf, line);
4165 
4166  if (ferror(stream))
4167  {
4168  pg_log_error("%s: %m", fname);
4169  error = true;
4170  resetPQExpBuffer(query_buf);
4171  }
4172  else if (edited)
4173  {
4174  *edited = true;
4175  }
4176 
4177  fclose(stream);
4178  }
4179  }
4180  else
4181  {
4182  /*
4183  * If the file was not modified, and the caller requested it, discard
4184  * the query buffer.
4185  */
4186  if (discard_on_quit)
4187  resetPQExpBuffer(query_buf);
4188  }
4189 
4190  /* remove temp file */
4191  if (!filename_arg)
4192  {
4193  if (remove(fname) == -1)
4194  {
4195  pg_log_error("%s: %m", fname);
4196  error = true;
4197  }
4198  }
4199 
4200  return !error;
4201 }
#define PG_BINARY_R
Definition: c.h:1262
static bool editFile(const char *fname, int lineno)
Definition: command.c:3939
#define MAXPGPATH
#define strerror
Definition: port.h:251
#define snprintf
Definition: port.h:238
void resetPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:146
void appendPQExpBufferChar(PQExpBuffer str, char ch)
Definition: pqexpbuffer.c:378
static int fd(const char *x, int i)
Definition: preproc-init.c:105
static int before(chr x, chr y)
Definition: regc_locale.c:488
static void error(void)
Definition: sql-dyntest.c:147
#define stat
Definition: win32_port.h:284

References appendPQExpBufferChar(), appendPQExpBufferStr(), before(), PQExpBufferData::data, editFile(), error(), fd(), PQExpBufferData::len, MAXPGPATH, PG_BINARY_R, pg_log_error, resetPQExpBuffer(), snprintf, stat::st_mtime, stat::st_size, stat, and strerror.

Referenced by exec_command_edit(), and exec_command_ef_ev().

◆ do_pset()

bool do_pset ( const char *  param,
const char *  value,
printQueryOpt popt,
bool  quiet 
)

Definition at line 4369 of file command.c.

4370 {
4371  size_t vallen = 0;
4372 
4373  Assert(param != NULL);
4374 
4375  if (value)
4376  vallen = strlen(value);
4377 
4378  /* set format */
4379  if (strcmp(param, "format") == 0)
4380  {
4381  static const struct fmt
4382  {
4383  const char *name;
4384  enum printFormat number;
4385  } formats[] =
4386  {
4387  /* remember to update error message below when adding more */
4388  {"aligned", PRINT_ALIGNED},
4389  {"asciidoc", PRINT_ASCIIDOC},
4390  {"csv", PRINT_CSV},
4391  {"html", PRINT_HTML},
4392  {"latex", PRINT_LATEX},
4393  {"troff-ms", PRINT_TROFF_MS},
4394  {"unaligned", PRINT_UNALIGNED},
4395  {"wrapped", PRINT_WRAPPED}
4396  };
4397 
4398  if (!value)
4399  ;
4400  else
4401  {
4402  int match_pos = -1;
4403 
4404  for (int i = 0; i < lengthof(formats); i++)
4405  {
4406  if (pg_strncasecmp(formats[i].name, value, vallen) == 0)
4407  {
4408  if (match_pos < 0)
4409  match_pos = i;
4410  else
4411  {
4412  pg_log_error("\\pset: ambiguous abbreviation \"%s\" matches both \"%s\" and \"%s\"",
4413  value,
4414  formats[match_pos].name, formats[i].name);
4415  return false;
4416  }
4417  }
4418  }
4419  if (match_pos >= 0)
4420  popt->topt.format = formats[match_pos].number;
4421  else if (pg_strncasecmp("latex-longtable", value, vallen) == 0)
4422  {
4423  /*
4424  * We must treat latex-longtable specially because latex is a
4425  * prefix of it; if both were in the table above, we'd think
4426  * "latex" is ambiguous.
4427  */
4429  }
4430  else
4431  {
4432  pg_log_error("\\pset: allowed formats are aligned, asciidoc, csv, html, latex, latex-longtable, troff-ms, unaligned, wrapped");
4433  return false;
4434  }
4435  }
4436  }
4437 
4438  /* set table line style */
4439  else if (strcmp(param, "linestyle") == 0)
4440  {
4441  if (!value)
4442  ;
4443  else if (pg_strncasecmp("ascii", value, vallen) == 0)
4444  popt->topt.line_style = &pg_asciiformat;
4445  else if (pg_strncasecmp("old-ascii", value, vallen) == 0)
4447  else if (pg_strncasecmp("unicode", value, vallen) == 0)
4448  popt->topt.line_style = &pg_utf8format;
4449  else
4450  {
4451  pg_log_error("\\pset: allowed line styles are ascii, old-ascii, unicode");
4452  return false;
4453  }
4454  }
4455 
4456  /* set unicode border line style */
4457  else if (strcmp(param, "unicode_border_linestyle") == 0)
4458  {
4459  if (!value)
4460  ;
4461  else if (set_unicode_line_style(value, vallen,
4463  refresh_utf8format(&(popt->topt));
4464  else
4465  {
4466  pg_log_error("\\pset: allowed Unicode border line styles are single, double");
4467  return false;
4468  }
4469  }
4470 
4471  /* set unicode column line style */
4472  else if (strcmp(param, "unicode_column_linestyle") == 0)
4473  {
4474  if (!value)
4475  ;
4476  else if (set_unicode_line_style(value, vallen,
4478  refresh_utf8format(&(popt->topt));
4479  else
4480  {
4481  pg_log_error("\\pset: allowed Unicode column line styles are single, double");
4482  return false;
4483  }
4484  }
4485 
4486  /* set unicode header line style */
4487  else if (strcmp(param, "unicode_header_linestyle") == 0)
4488  {
4489  if (!value)
4490  ;
4491  else if (set_unicode_line_style(value, vallen,
4493  refresh_utf8format(&(popt->topt));
4494  else
4495  {
4496  pg_log_error("\\pset: allowed Unicode header line styles are single, double");
4497  return false;
4498  }
4499  }
4500 
4501  /* set border style/width */
4502  else if (strcmp(param, "border") == 0)
4503  {
4504  if (value)
4505  popt->topt.border = atoi(value);
4506  }
4507 
4508  /* set expanded/vertical mode */
4509  else if (strcmp(param, "x") == 0 ||
4510  strcmp(param, "expanded") == 0 ||
4511  strcmp(param, "vertical") == 0)
4512  {
4513  if (value && pg_strcasecmp(value, "auto") == 0)
4514  popt->topt.expanded = 2;
4515  else if (value)
4516  {
4517  bool on_off;
4518 
4519  if (ParseVariableBool(value, NULL, &on_off))
4520  popt->topt.expanded = on_off ? 1 : 0;
4521  else
4522  {
4523  PsqlVarEnumError(param, value, "on, off, auto");
4524  return false;
4525  }
4526  }
4527  else
4528  popt->topt.expanded = !popt->topt.expanded;
4529  }
4530 
4531  /* header line width in expanded mode */
4532  else if (strcmp(param, "xheader_width") == 0)
4533  {
4534  if (!value)
4535  ;
4536  else if (pg_strcasecmp(value, "full") == 0)
4538  else if (pg_strcasecmp(value, "column") == 0)
4540  else if (pg_strcasecmp(value, "page") == 0)
4542  else
4543  {
4544  int intval = atoi(value);
4545 
4546  if (intval == 0)
4547  {
4548  pg_log_error("\\pset: allowed xheader_width values are \"%s\" (default), \"%s\", \"%s\", or a number specifying the exact width", "full", "column", "page");
4549  return false;
4550  }
4551 
4553  popt->topt.expanded_header_exact_width = intval;
4554  }
4555  }
4556 
4557  /* field separator for CSV format */
4558  else if (strcmp(param, "csv_fieldsep") == 0)
4559  {
4560  if (value)
4561  {
4562  /* CSV separator has to be a one-byte character */
4563  if (strlen(value) != 1)
4564  {
4565  pg_log_error("\\pset: csv_fieldsep must be a single one-byte character");
4566  return false;
4567  }
4568  if (value[0] == '"' || value[0] == '\n' || value[0] == '\r')
4569  {
4570  pg_log_error("\\pset: csv_fieldsep cannot be a double quote, a newline, or a carriage return");
4571  return false;
4572  }
4573  popt->topt.csvFieldSep[0] = value[0];
4574  }
4575  }
4576 
4577  /* locale-aware numeric output */
4578  else if (strcmp(param, "numericlocale") == 0)
4579  {
4580  if (value)
4581  return ParseVariableBool(value, param, &popt->topt.numericLocale);
4582  else
4583  popt->topt.numericLocale = !popt->topt.numericLocale;
4584  }
4585 
4586  /* null display */
4587  else if (strcmp(param, "null") == 0)
4588  {
4589  if (value)
4590  {
4591  free(popt->nullPrint);
4592  popt->nullPrint = pg_strdup(value);
4593  }
4594  }
4595 
4596  /* field separator for unaligned text */
4597  else if (strcmp(param, "fieldsep") == 0)
4598  {
4599  if (value)
4600  {
4601  free(popt->topt.fieldSep.separator);
4603  popt->topt.fieldSep.separator_zero = false;
4604  }
4605  }
4606 
4607  else if (strcmp(param, "fieldsep_zero") == 0)
4608  {
4609  free(popt->topt.fieldSep.separator);
4610  popt->topt.fieldSep.separator = NULL;
4611  popt->topt.fieldSep.separator_zero = true;
4612  }
4613 
4614  /* record separator for unaligned text */
4615  else if (strcmp(param, "recordsep") == 0)
4616  {
4617  if (value)
4618  {
4619  free(popt->topt.recordSep.separator);
4621  popt->topt.recordSep.separator_zero = false;
4622  }
4623  }
4624 
4625  else if (strcmp(param, "recordsep_zero") == 0)
4626  {
4627  free(popt->topt.recordSep.separator);
4628  popt->topt.recordSep.separator = NULL;
4629  popt->topt.recordSep.separator_zero = true;
4630  }
4631 
4632  /* toggle between full and tuples-only format */
4633  else if (strcmp(param, "t") == 0 || strcmp(param, "tuples_only") == 0)
4634  {
4635  if (value)
4636  return ParseVariableBool(value, param, &popt->topt.tuples_only);
4637  else
4638  popt->topt.tuples_only = !popt->topt.tuples_only;
4639  }
4640 
4641  /* set title override */
4642  else if (strcmp(param, "C") == 0 || strcmp(param, "title") == 0)
4643  {
4644  free(popt->title);
4645  if (!value)
4646  popt->title = NULL;
4647  else
4648  popt->title = pg_strdup(value);
4649  }
4650 
4651  /* set HTML table tag options */
4652  else if (strcmp(param, "T") == 0 || strcmp(param, "tableattr") == 0)
4653  {
4654  free(popt->topt.tableAttr);
4655  if (!value)
4656  popt->topt.tableAttr = NULL;
4657  else
4658  popt->topt.tableAttr = pg_strdup(value);
4659  }
4660 
4661  /* toggle use of pager */
4662  else if (strcmp(param, "pager") == 0)
4663  {
4664  if (value && pg_strcasecmp(value, "always") == 0)
4665  popt->topt.pager = 2;
4666  else if (value)
4667  {
4668  bool on_off;
4669 
4670  if (!ParseVariableBool(value, NULL, &on_off))
4671  {
4672  PsqlVarEnumError(param, value, "on, off, always");
4673  return false;
4674  }
4675  popt->topt.pager = on_off ? 1 : 0;
4676  }
4677  else if (popt->topt.pager == 1)
4678  popt->topt.pager = 0;
4679  else
4680  popt->topt.pager = 1;
4681  }
4682 
4683  /* set minimum lines for pager use */
4684  else if (strcmp(param, "pager_min_lines") == 0)
4685  {
4686  if (value &&
4687  !ParseVariableNum(value, "pager_min_lines", &popt->topt.pager_min_lines))
4688  return false;
4689  }
4690 
4691  /* disable "(x rows)" footer */
4692  else if (strcmp(param, "footer") == 0)
4693  {
4694  if (value)
4695  return ParseVariableBool(value, param, &popt->topt.default_footer);
4696  else
4697  popt->topt.default_footer = !popt->topt.default_footer;
4698  }
4699 
4700  /* set border style/width */
4701  else if (strcmp(param, "columns") == 0)
4702  {
4703  if (value)
4704  popt->topt.columns = atoi(value);
4705  }
4706  else
4707  {
4708  pg_log_error("\\pset: unknown option: %s", param);
4709  return false;
4710  }
4711 
4712  if (!quiet)
4713  printPsetInfo(param, &pset.popt);
4714 
4715  return true;
4716 }
#define lengthof(array)
Definition: c.h:775
static bool set_unicode_line_style(const char *value, size_t vallen, unicode_linestyle *linestyle)
Definition: command.c:4326
static bool printPsetInfo(const char *param, printQueryOpt *popt)
Definition: command.c:4722
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
void refresh_utf8format(const printTableOpt *opt)
Definition: print.c:3691
const printTextFormat pg_asciiformat
Definition: print.c:56
const printTextFormat pg_asciiformat_old
Definition: print.c:77
printTextFormat pg_utf8format
Definition: print.c:99
@ PRINT_XHEADER_EXACT_WIDTH
Definition: print.h:78
@ PRINT_XHEADER_PAGE
Definition: print.h:76
@ PRINT_XHEADER_COLUMN
Definition: print.h:74
@ PRINT_XHEADER_FULL
Definition: print.h:72
printFormat
Definition: print.h:29
#define free(a)
Definition: header.h:65
static struct @154 value
int i
Definition: isn.c:73
static void const char * fmt
int pg_strcasecmp(const char *s1, const char *s2)
Definition: pgstrcasecmp.c:36
int pg_strncasecmp(const char *s1, const char *s2, size_t n)
Definition: pgstrcasecmp.c:69
printQueryOpt popt
Definition: settings.h:91
printTableOpt topt
Definition: print.h:185
char * nullPrint
Definition: print.h:186
char * title
Definition: print.h:187
unsigned short int expanded
Definition: print.h:114
unicode_linestyle unicode_border_linestyle
Definition: print.h:141
bool tuples_only
Definition: print.h:126
int columns
Definition: print.h:140
enum printFormat format
Definition: print.h:113
struct separator fieldSep
Definition: print.h:132
int expanded_header_exact_width
Definition: print.h:118
struct separator recordSep
Definition: print.h:133
printXheaderWidthType expanded_header_width_type
Definition: print.h:116
char csvFieldSep[2]
Definition: print.h:134
const printTextFormat * line_style
Definition: print.h:131
bool default_footer
Definition: print.h:129
int pager_min_lines
Definition: print.h:124
unsigned short int pager
Definition: print.h:122
char * tableAttr
Definition: print.h:137
bool numericLocale
Definition: print.h:135
unsigned short int border
Definition: print.h:120
unicode_linestyle unicode_header_linestyle
Definition: print.h:143
unicode_linestyle unicode_column_linestyle
Definition: print.h:142
bool separator_zero
Definition: print.h:108
char * separator
Definition: print.h:107
void PsqlVarEnumError(const char *name, const char *value, const char *suggestions)
Definition: variables.c:416
bool ParseVariableBool(const char *value, const char *name, bool *result)
Definition: variables.c:107
bool ParseVariableNum(const char *value, const char *name, int *result)
Definition: variables.c:156
const char * name

References Assert(), printTableOpt::border, printTableOpt::columns, printTableOpt::csvFieldSep, printTableOpt::default_footer, printTableOpt::expanded, printTableOpt::expanded_header_exact_width, printTableOpt::expanded_header_width_type, printTableOpt::fieldSep, fmt, printTableOpt::format, free, i, lengthof, printTableOpt::line_style, name, printQueryOpt::nullPrint, printTableOpt::numericLocale, printTableOpt::pager, printTableOpt::pager_min_lines, ParseVariableBool(), ParseVariableNum(), pg_asciiformat, pg_asciiformat_old, pg_log_error, pg_strcasecmp(), pg_strdup(), pg_strncasecmp(), pg_utf8format, _psqlSettings::popt, PRINT_ALIGNED, PRINT_ASCIIDOC, PRINT_CSV, PRINT_HTML, PRINT_LATEX, PRINT_LATEX_LONGTABLE, PRINT_TROFF_MS, PRINT_UNALIGNED, PRINT_WRAPPED, PRINT_XHEADER_COLUMN, PRINT_XHEADER_EXACT_WIDTH, PRINT_XHEADER_FULL, PRINT_XHEADER_PAGE, printPsetInfo(), pset, PsqlVarEnumError(), printTableOpt::recordSep, refresh_utf8format(), separator::separator, separator::separator_zero, set_unicode_line_style(), printTableOpt::tableAttr, printQueryOpt::title, printQueryOpt::topt, printTableOpt::tuples_only, printTableOpt::unicode_border_linestyle, printTableOpt::unicode_column_linestyle, printTableOpt::unicode_header_linestyle, and value.

Referenced by exec_command_a(), exec_command_C(), exec_command_f(), exec_command_html(), exec_command_pset(), exec_command_t(), exec_command_T(), exec_command_x(), parse_psql_options(), and process_command_g_options().

◆ do_shell()

static bool do_shell ( const char *  command)
static

Definition at line 5118 of file command.c.

5119 {
5120  int result;
5121 
5122  fflush(NULL);
5123  if (!command)
5124  {
5125  char *sys;
5126  const char *shellName;
5127 
5128  shellName = getenv("SHELL");
5129 #ifdef WIN32
5130  if (shellName == NULL)
5131  shellName = getenv("COMSPEC");
5132 #endif
5133  if (shellName == NULL)
5134  shellName = DEFAULT_SHELL;
5135 
5136  /* See EDITOR handling comment for an explanation */
5137 #ifndef WIN32
5138  sys = psprintf("exec %s", shellName);
5139 #else
5140  sys = psprintf("\"%s\"", shellName);
5141 #endif
5142  result = system(sys);
5143  free(sys);
5144  }
5145  else
5146  result = system(command);
5147 
5148  SetShellResultVariables(result);
5149 
5150  if (result == 127 || result == -1)
5151  {
5152  pg_log_error("\\!: failed");
5153  return false;
5154  }
5155  return true;
5156 }
void SetShellResultVariables(int wait_result)
Definition: common.c:462
#define DEFAULT_SHELL
Definition: command.c:5108
static void const char fflush(stdout)
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46

References DEFAULT_SHELL, fflush(), free, pg_log_error, psprintf(), and SetShellResultVariables().

Referenced by exec_command_shell_escape().

◆ do_watch()

static bool do_watch ( PQExpBuffer  query_buf,
double  sleep,
int  iter,
int  min_rows 
)
static

Definition at line 5165 of file command.c.

5166 {
5167  long sleep_ms = (long) (sleep * 1000);
5168  printQueryOpt myopt = pset.popt;
5169  const char *strftime_fmt;
5170  const char *user_title;
5171  char *title;
5172  const char *pagerprog = NULL;
5173  FILE *pagerpipe = NULL;
5174  int title_len;
5175  int res = 0;
5176  bool done = false;
5177 #ifndef WIN32
5178  sigset_t sigalrm_sigchld_sigint;
5179  sigset_t sigalrm_sigchld;
5180  sigset_t sigint;
5181  struct itimerval interval;
5182 #endif
5183 
5184  if (!query_buf || query_buf->len <= 0)
5185  {
5186  pg_log_error("\\watch cannot be used with an empty query");
5187  return false;
5188  }
5189 
5190 #ifndef WIN32
5191  sigemptyset(&sigalrm_sigchld_sigint);
5192  sigaddset(&sigalrm_sigchld_sigint, SIGCHLD);
5193  sigaddset(&sigalrm_sigchld_sigint, SIGALRM);
5194  sigaddset(&sigalrm_sigchld_sigint, SIGINT);
5195 
5196  sigemptyset(&sigalrm_sigchld);
5197  sigaddset(&sigalrm_sigchld, SIGCHLD);
5198  sigaddset(&sigalrm_sigchld, SIGALRM);
5199 
5200  sigemptyset(&sigint);
5201  sigaddset(&sigint, SIGINT);
5202 
5203  /*
5204  * Block SIGALRM and SIGCHLD before we start the timer and the pager (if
5205  * configured), to avoid races. sigwait() will receive them.
5206  */
5207  sigprocmask(SIG_BLOCK, &sigalrm_sigchld, NULL);
5208 
5209  /*
5210  * Set a timer to interrupt sigwait() so we can run the query at the
5211  * requested intervals.
5212  */
5213  interval.it_value.tv_sec = sleep_ms / 1000;
5214  interval.it_value.tv_usec = (sleep_ms % 1000) * 1000;
5215  interval.it_interval = interval.it_value;
5216  if (setitimer(ITIMER_REAL, &interval, NULL) < 0)
5217  {
5218  pg_log_error("could not set timer: %m");
5219  done = true;
5220  }
5221 #endif
5222 
5223  /*
5224  * For \watch, we ignore the size of the result and always use the pager
5225  * as long as we're talking to a terminal and "\pset pager" is enabled.
5226  * However, we'll only use the pager identified by PSQL_WATCH_PAGER. We
5227  * ignore the regular PSQL_PAGER or PAGER environment variables, because
5228  * traditional pagers probably won't be very useful for showing a stream
5229  * of results.
5230  */
5231 #ifndef WIN32
5232  pagerprog = getenv("PSQL_WATCH_PAGER");
5233  /* if variable is empty or all-white-space, don't use pager */
5234  if (pagerprog && strspn(pagerprog, " \t\r\n") == strlen(pagerprog))
5235  pagerprog = NULL;
5236 #endif
5237  if (pagerprog && myopt.topt.pager &&
5238  isatty(fileno(stdin)) && isatty(fileno(stdout)))
5239  {
5240  fflush(NULL);
5242  pagerpipe = popen(pagerprog, "w");
5243 
5244  if (!pagerpipe)
5245  /* silently proceed without pager */
5247  }
5248 
5249  /*
5250  * Choose format for timestamps. We might eventually make this a \pset
5251  * option. In the meantime, using a variable for the format suppresses
5252  * overly-anal-retentive gcc warnings about %c being Y2K sensitive.
5253  */
5254  strftime_fmt = "%c";
5255 
5256  /*
5257  * Set up rendering options, in particular, disable the pager unless
5258  * PSQL_WATCH_PAGER was successfully launched.
5259  */
5260  if (!pagerpipe)
5261  myopt.topt.pager = 0;
5262 
5263  /*
5264  * If there's a title in the user configuration, make sure we have room
5265  * for it in the title buffer. Allow 128 bytes for the timestamp plus 128
5266  * bytes for the rest.
5267  */
5268  user_title = myopt.title;
5269  title_len = (user_title ? strlen(user_title) : 0) + 256;
5270  title = pg_malloc(title_len);
5271 
5272  /* Loop to run query and then sleep awhile */
5273  while (!done)
5274  {
5275  time_t timer;
5276  char timebuf[128];
5277 
5278  /*
5279  * Prepare title for output. Note that we intentionally include a
5280  * newline at the end of the title; this is somewhat historical but it
5281  * makes for reasonably nicely formatted output in simple cases.
5282  */
5283  timer = time(NULL);
5284  strftime(timebuf, sizeof(timebuf), strftime_fmt, localtime(&timer));
5285 
5286  if (user_title)
5287  snprintf(title, title_len, _("%s\t%s (every %gs)\n"),
5288  user_title, timebuf, sleep);
5289  else
5290  snprintf(title, title_len, _("%s (every %gs)\n"),
5291  timebuf, sleep);
5292  myopt.title = title;
5293 
5294  /* Run the query and print out the result */
5295  res = PSQLexecWatch(query_buf->data, &myopt, pagerpipe, min_rows);
5296 
5297  /*
5298  * PSQLexecWatch handles the case where we can no longer repeat the
5299  * query, and returns 0 or -1.
5300  */
5301  if (res <= 0)
5302  break;
5303 
5304  /* If we have iteration count, check that it's not exceeded yet */
5305  if (iter && (--iter <= 0))
5306  break;
5307 
5308  /* Quit if error on pager pipe (probably pager has quit) */
5309  if (pagerpipe && ferror(pagerpipe))
5310  break;
5311 
5312  if (sleep == 0)
5313  continue;
5314 
5315 #ifdef WIN32
5316 
5317  /*
5318  * Wait a while before running the query again. Break the sleep into
5319  * short intervals (at most 1s); that's probably unnecessary since
5320  * pg_usleep is interruptible on Windows, but it's cheap insurance.
5321  */
5322  for (long i = sleep_ms; i > 0;)
5323  {
5324  long s = Min(i, 1000L);
5325 
5326  pg_usleep(s * 1000L);
5327  if (cancel_pressed)
5328  {
5329  done = true;
5330  break;
5331  }
5332  i -= s;
5333  }
5334 #else
5335  /* sigwait() will handle SIGINT. */
5336  sigprocmask(SIG_BLOCK, &sigint, NULL);
5337  if (cancel_pressed)
5338  done = true;
5339 
5340  /* Wait for SIGINT, SIGCHLD or SIGALRM. */
5341  while (!done)
5342  {
5343  int signal_received;
5344 
5345  errno = sigwait(&sigalrm_sigchld_sigint, &signal_received);
5346  if (errno != 0)
5347  {
5348  /* Some other signal arrived? */
5349  if (errno == EINTR)
5350  continue;
5351  else
5352  {
5353  pg_log_error("could not wait for signals: %m");
5354  done = true;
5355  break;
5356  }
5357  }
5358  /* On ^C or pager exit, it's time to stop running the query. */
5359  if (signal_received == SIGINT || signal_received == SIGCHLD)
5360  done = true;
5361  /* Otherwise, we must have SIGALRM. Time to run the query again. */
5362  break;
5363  }
5364 
5365  /* Unblock SIGINT so that slow queries can be interrupted. */
5366  sigprocmask(SIG_UNBLOCK, &sigint, NULL);
5367 #endif
5368  }
5369 
5370  if (pagerpipe)
5371  {
5372  pclose(pagerpipe);
5374  }
5375  else
5376  {
5377  /*
5378  * If the terminal driver echoed "^C", libedit/libreadline might be
5379  * confused about the cursor position. Therefore, inject a newline
5380  * before the next prompt is displayed. We only do this when not
5381  * using a pager, because pagers are expected to restore the screen to
5382  * a sane state on exit.
5383  */
5384  fprintf(stdout, "\n");
5385  fflush(stdout);
5386  }
5387 
5388 #ifndef WIN32
5389  /* Disable the interval timer. */
5390  memset(&interval, 0, sizeof(interval));
5391  setitimer(ITIMER_REAL, &interval, NULL);
5392  /* Unblock SIGINT, SIGCHLD and SIGALRM. */
5393  sigprocmask(SIG_UNBLOCK, &sigalrm_sigchld_sigint, NULL);
5394 #endif
5395 
5396  pg_free(title);
5397  return (res >= 0);
5398 }
int PSQLexecWatch(const char *query, const printQueryOpt *opt, FILE *printQueryFout, int min_rows)
Definition: common.c:636
#define Min(x, y)
Definition: c.h:991
void restore_sigpipe_trap(void)
Definition: print.c:3062
void disable_sigpipe_trap(void)
Definition: print.c:3039
volatile sig_atomic_t cancel_pressed
Definition: print.c:43
#define fprintf
Definition: port.h:242
void pg_usleep(long microsec)
Definition: signal.c:53
static long sleep_ms
Definition: slotsync.c:111
int setitimer(int which, const struct itimerval *value, struct itimerval *ovalue)
Definition: timer.c:86
#define SIGCHLD
Definition: win32_port.h:178
#define EINTR
Definition: win32_port.h:374
#define SIGALRM
Definition: win32_port.h:174
#define ITIMER_REAL
Definition: win32_port.h:190

References _, cancel_pressed, PQExpBufferData::data, disable_sigpipe_trap(), EINTR, fflush(), fprintf, i, ITIMER_REAL, PQExpBufferData::len, Min, printTableOpt::pager, pg_free(), pg_log_error, pg_malloc(), pg_usleep(), _psqlSettings::popt, pset, PSQLexecWatch(), res, restore_sigpipe_trap(), setitimer(), SIGALRM, SIGCHLD, sleep_ms, snprintf, generate_unaccent_rules::stdout, printQueryOpt::title, and printQueryOpt::topt.

Referenced by exec_command_watch().

◆ echo_hidden_command()

static bool echo_hidden_command ( const char *  query)
static

Definition at line 5405 of file command.c.

5406 {
5408  {
5409  printf(_("/******** QUERY *********/\n"
5410  "%s\n"
5411  "/************************/\n\n"), query);
5412  fflush(stdout);
5413  if (pset.logfile)
5414  {
5416  _("/******** QUERY *********/\n"
5417  "%s\n"
5418  "/************************/\n\n"), query);
5419  fflush(pset.logfile);
5420  }
5421 
5423  return false;
5424  }
5425  return true;
5426 }
@ PSQL_ECHO_HIDDEN_NOEXEC
Definition: settings.h:47
@ PSQL_ECHO_HIDDEN_OFF
Definition: settings.h:45
FILE * logfile
Definition: settings.h:120
PSQL_ECHO_HIDDEN echo_hidden
Definition: settings.h:147

References _, _psqlSettings::echo_hidden, fflush(), fprintf, _psqlSettings::logfile, printf, pset, PSQL_ECHO_HIDDEN_NOEXEC, PSQL_ECHO_HIDDEN_OFF, and generate_unaccent_rules::stdout.

Referenced by get_create_object_cmd(), and lookup_object_oid().

◆ editFile()

static bool editFile ( const char *  fname,
int  lineno 
)
static

Definition at line 3939 of file command.c.

3940 {
3941  const char *editorName;
3942  const char *editor_lineno_arg = NULL;
3943  char *sys;
3944  int result;
3945 
3946  Assert(fname != NULL);
3947 
3948  /* Find an editor to use */
3949  editorName = getenv("PSQL_EDITOR");
3950  if (!editorName)
3951  editorName = getenv("EDITOR");
3952  if (!editorName)
3953  editorName = getenv("VISUAL");
3954  if (!editorName)
3955  editorName = DEFAULT_EDITOR;
3956 
3957  /* Get line number argument, if we need it. */
3958  if (lineno > 0)
3959  {
3960  editor_lineno_arg = getenv("PSQL_EDITOR_LINENUMBER_ARG");
3961 #ifdef DEFAULT_EDITOR_LINENUMBER_ARG
3962  if (!editor_lineno_arg)
3963  editor_lineno_arg = DEFAULT_EDITOR_LINENUMBER_ARG;
3964 #endif
3965  if (!editor_lineno_arg)
3966  {
3967  pg_log_error("environment variable PSQL_EDITOR_LINENUMBER_ARG must be set to specify a line number");
3968  return false;
3969  }
3970  }
3971 
3972  /*
3973  * On Unix the EDITOR value should *not* be quoted, since it might include
3974  * switches, eg, EDITOR="pico -t"; it's up to the user to put quotes in it
3975  * if necessary. But this policy is not very workable on Windows, due to
3976  * severe brain damage in their command shell plus the fact that standard
3977  * program paths include spaces.
3978  */
3979 #ifndef WIN32
3980  if (lineno > 0)
3981  sys = psprintf("exec %s %s%d '%s'",
3982  editorName, editor_lineno_arg, lineno, fname);
3983  else
3984  sys = psprintf("exec %s '%s'",
3985  editorName, fname);
3986 #else
3987  if (lineno > 0)
3988  sys = psprintf("\"%s\" %s%d \"%s\"",
3989  editorName, editor_lineno_arg, lineno, fname);
3990  else
3991  sys = psprintf("\"%s\" \"%s\"",
3992  editorName, fname);
3993 #endif
3994  fflush(NULL);
3995  result = system(sys);
3996  if (result == -1)
3997  pg_log_error("could not start editor \"%s\"", editorName);
3998  else if (result == 127)
3999  pg_log_error("could not start /bin/sh");
4000  free(sys);
4001 
4002  return result == 0;
4003 }
#define DEFAULT_EDITOR_LINENUMBER_ARG
Definition: settings.h:23
#define DEFAULT_EDITOR
Definition: settings.h:22

References Assert(), DEFAULT_EDITOR, DEFAULT_EDITOR_LINENUMBER_ARG, fflush(), free, pg_log_error, and psprintf().

Referenced by do_edit().

◆ exec_command()

static backslashResult exec_command ( const char *  cmd,
PsqlScanState  scan_state,
ConditionalStack  cstack,
PQExpBuffer  query_buf,
PQExpBuffer  previous_buf 
)
static

Definition at line 287 of file command.c.

292 {
293  backslashResult status;
294  bool active_branch = conditional_active(cstack);
295 
296  /*
297  * In interactive mode, warn when we're ignoring a command within a false
298  * \if-branch. But we continue on, so as to parse and discard the right
299  * amount of parameter text. Each individual backslash command subroutine
300  * is responsible for doing nothing after discarding appropriate
301  * arguments, if !active_branch.
302  */
303  if (pset.cur_cmd_interactive && !active_branch &&
304  !is_branching_command(cmd))
305  {
306  pg_log_warning("\\%s command ignored; use \\endif or Ctrl-C to exit current \\if block",
307  cmd);
308  }
309 
310  if (strcmp(cmd, "a") == 0)
311  status = exec_command_a(scan_state, active_branch);
312  else if (strcmp(cmd, "bind") == 0)
313  status = exec_command_bind(scan_state, active_branch);
314  else if (strcmp(cmd, "C") == 0)
315  status = exec_command_C(scan_state, active_branch);
316  else if (strcmp(cmd, "c") == 0 || strcmp(cmd, "connect") == 0)
317  status = exec_command_connect(scan_state, active_branch);
318  else if (strcmp(cmd, "cd") == 0)
319  status = exec_command_cd(scan_state, active_branch, cmd);
320  else if (strcmp(cmd, "conninfo") == 0)
321  status = exec_command_conninfo(scan_state, active_branch);
322  else if (pg_strcasecmp(cmd, "copy") == 0)
323  status = exec_command_copy(scan_state, active_branch);
324  else if (strcmp(cmd, "copyright") == 0)
325  status = exec_command_copyright(scan_state, active_branch);
326  else if (strcmp(cmd, "crosstabview") == 0)
327  status = exec_command_crosstabview(scan_state, active_branch);
328  else if (cmd[0] == 'd')
329  status = exec_command_d(scan_state, active_branch, cmd);
330  else if (strcmp(cmd, "e") == 0 || strcmp(cmd, "edit") == 0)
331  status = exec_command_edit(scan_state, active_branch,
332  query_buf, previous_buf);
333  else if (strcmp(cmd, "ef") == 0)
334  status = exec_command_ef_ev(scan_state, active_branch, query_buf, true);
335  else if (strcmp(cmd, "ev") == 0)
336  status = exec_command_ef_ev(scan_state, active_branch, query_buf, false);
337  else if (strcmp(cmd, "echo") == 0 || strcmp(cmd, "qecho") == 0 ||
338  strcmp(cmd, "warn") == 0)
339  status = exec_command_echo(scan_state, active_branch, cmd);
340  else if (strcmp(cmd, "elif") == 0)
341  status = exec_command_elif(scan_state, cstack, query_buf);
342  else if (strcmp(cmd, "else") == 0)
343  status = exec_command_else(scan_state, cstack, query_buf);
344  else if (strcmp(cmd, "endif") == 0)
345  status = exec_command_endif(scan_state, cstack, query_buf);
346  else if (strcmp(cmd, "encoding") == 0)
347  status = exec_command_encoding(scan_state, active_branch);
348  else if (strcmp(cmd, "errverbose") == 0)
349  status = exec_command_errverbose(scan_state, active_branch);
350  else if (strcmp(cmd, "f") == 0)
351  status = exec_command_f(scan_state, active_branch);
352  else if (strcmp(cmd, "g") == 0 || strcmp(cmd, "gx") == 0)
353  status = exec_command_g(scan_state, active_branch, cmd);
354  else if (strcmp(cmd, "gdesc") == 0)
355  status = exec_command_gdesc(scan_state, active_branch);
356  else if (strcmp(cmd, "getenv") == 0)
357  status = exec_command_getenv(scan_state, active_branch, cmd);
358  else if (strcmp(cmd, "gexec") == 0)
359  status = exec_command_gexec(scan_state, active_branch);
360  else if (strcmp(cmd, "gset") == 0)
361  status = exec_command_gset(scan_state, active_branch);
362  else if (strcmp(cmd, "h") == 0 || strcmp(cmd, "help") == 0)
363  status = exec_command_help(scan_state, active_branch);
364  else if (strcmp(cmd, "H") == 0 || strcmp(cmd, "html") == 0)
365  status = exec_command_html(scan_state, active_branch);
366  else if (strcmp(cmd, "i") == 0 || strcmp(cmd, "include") == 0 ||
367  strcmp(cmd, "ir") == 0 || strcmp(cmd, "include_relative") == 0)
368  status = exec_command_include(scan_state, active_branch, cmd);
369  else if (strcmp(cmd, "if") == 0)
370  status = exec_command_if(scan_state, cstack, query_buf);
371  else if (strcmp(cmd, "l") == 0 || strcmp(cmd, "list") == 0 ||
372  strcmp(cmd, "l+") == 0 || strcmp(cmd, "list+") == 0)
373  status = exec_command_list(scan_state, active_branch, cmd);
374  else if (strncmp(cmd, "lo_", 3) == 0)
375  status = exec_command_lo(scan_state, active_branch, cmd);
376  else if (strcmp(cmd, "o") == 0 || strcmp(cmd, "out") == 0)
377  status = exec_command_out(scan_state, active_branch);
378  else if (strcmp(cmd, "p") == 0 || strcmp(cmd, "print") == 0)
379  status = exec_command_print(scan_state, active_branch,
380  query_buf, previous_buf);
381  else if (strcmp(cmd, "password") == 0)
382  status = exec_command_password(scan_state, active_branch);
383  else if (strcmp(cmd, "prompt") == 0)
384  status = exec_command_prompt(scan_state, active_branch, cmd);
385  else if (strcmp(cmd, "pset") == 0)
386  status = exec_command_pset(scan_state, active_branch);
387  else if (strcmp(cmd, "q") == 0 || strcmp(cmd, "quit") == 0)
388  status = exec_command_quit(scan_state, active_branch);
389  else if (strcmp(cmd, "r") == 0 || strcmp(cmd, "reset") == 0)
390  status = exec_command_reset(scan_state, active_branch, query_buf);
391  else if (strcmp(cmd, "s") == 0)
392  status = exec_command_s(scan_state, active_branch);
393  else if (strcmp(cmd, "set") == 0)
394  status = exec_command_set(scan_state, active_branch);
395  else if (strcmp(cmd, "setenv") == 0)
396  status = exec_command_setenv(scan_state, active_branch, cmd);
397  else if (strcmp(cmd, "sf") == 0 || strcmp(cmd, "sf+") == 0)
398  status = exec_command_sf_sv(scan_state, active_branch, cmd, true);
399  else if (strcmp(cmd, "sv") == 0 || strcmp(cmd, "sv+") == 0)
400  status = exec_command_sf_sv(scan_state, active_branch, cmd, false);
401  else if (strcmp(cmd, "t") == 0)
402  status = exec_command_t(scan_state, active_branch);
403  else if (strcmp(cmd, "T") == 0)
404  status = exec_command_T(scan_state, active_branch);
405  else if (strcmp(cmd, "timing") == 0)
406  status = exec_command_timing(scan_state, active_branch);
407  else if (strcmp(cmd, "unset") == 0)
408  status = exec_command_unset(scan_state, active_branch, cmd);
409  else if (strcmp(cmd, "w") == 0 || strcmp(cmd, "write") == 0)
410  status = exec_command_write(scan_state, active_branch, cmd,
411  query_buf, previous_buf);
412  else if (strcmp(cmd, "watch") == 0)
413  status = exec_command_watch(scan_state, active_branch,
414  query_buf, previous_buf);
415  else if (strcmp(cmd, "x") == 0)
416  status = exec_command_x(scan_state, active_branch);
417  else if (strcmp(cmd, "z") == 0 || strcmp(cmd, "zS") == 0)
418  status = exec_command_z(scan_state, active_branch, cmd);
419  else if (strcmp(cmd, "!") == 0)
420  status = exec_command_shell_escape(scan_state, active_branch);
421  else if (strcmp(cmd, "?") == 0)
422  status = exec_command_slash_command_help(scan_state, active_branch);
423  else
424  status = PSQL_CMD_UNKNOWN;
425 
426  /*
427  * All the commands that return PSQL_CMD_SEND want to execute previous_buf
428  * if query_buf is empty. For convenience we implement that here, not in
429  * the individual command subroutines.
430  */
431  if (status == PSQL_CMD_SEND)
432  (void) copy_previous_query(query_buf, previous_buf);
433 
434  return status;
435 }
static backslashResult exec_command_endif(PsqlScanState scan_state, ConditionalStack cstack, PQExpBuffer query_buf)
Definition: command.c:1907
static backslashResult exec_command_copyright(PsqlScanState scan_state, bool active_branch)
Definition: command.c:715
static backslashResult exec_command_errverbose(PsqlScanState scan_state, bool active_branch)
Definition: command.c:1354
static backslashResult exec_command_print(PsqlScanState scan_state, bool active_branch, PQExpBuffer query_buf, PQExpBuffer previous_buf)
Definition: command.c:2076
static backslashResult exec_command_html(PsqlScanState scan_state, bool active_branch)
Definition: command.c:1660
static bool copy_previous_query(PQExpBuffer query_buf, PQExpBuffer previous_buf)
Definition: command.c:3225
static backslashResult exec_command_g(PsqlScanState scan_state, bool active_branch, const char *cmd)
Definition: command.c:1412
static backslashResult exec_command_T(PsqlScanState scan_state, bool active_branch)
Definition: command.c:2575
static backslashResult exec_command_gdesc(PsqlScanState scan_state, bool active_branch)
Definition: command.c:1540
static backslashResult exec_command_help(PsqlScanState scan_state, bool active_branch)
Definition: command.c:1640
static backslashResult exec_command_a(PsqlScanState scan_state, bool active_branch)
Definition: command.c:444
static backslashResult exec_command_bind(PsqlScanState scan_state, bool active_branch)
Definition: command.c:463
static backslashResult exec_command_password(PsqlScanState scan_state, bool active_branch)
Definition: command.c:2102
static backslashResult exec_command_x(PsqlScanState scan_state, bool active_branch)
Definition: command.c:2908
static backslashResult exec_command_if(PsqlScanState scan_state, ConditionalStack cstack, PQExpBuffer query_buf)
Definition: command.c:1720
static backslashResult exec_command_elif(PsqlScanState scan_state, ConditionalStack cstack, PQExpBuffer query_buf)
Definition: command.c:1766
static backslashResult exec_command_f(PsqlScanState scan_state, bool active_branch)
Definition: command.c:1384
static backslashResult exec_command_reset(PsqlScanState scan_state, bool active_branch, PQExpBuffer query_buf)
Definition: command.c:2324
static backslashResult exec_command_out(PsqlScanState scan_state, bool active_branch)
Definition: command.c:2053
static backslashResult exec_command_echo(PsqlScanState scan_state, bool active_branch, const char *cmd)
Definition: command.c:1271
static backslashResult exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
Definition: command.c:751
static backslashResult exec_command_shell_escape(PsqlScanState scan_state, bool active_branch)
Definition: command.c:2958
static backslashResult exec_command_cd(PsqlScanState scan_state, bool active_branch, const char *cmd)
Definition: command.c:585
static backslashResult exec_command_gset(PsqlScanState scan_state, bool active_branch)
Definition: command.c:1611
static backslashResult exec_command_ef_ev(PsqlScanState scan_state, bool active_branch, PQExpBuffer query_buf, bool is_func)
Definition: command.c:1155
static backslashResult exec_command_unset(PsqlScanState scan_state, bool active_branch, const char *cmd)
Definition: command.c:2629
static backslashResult exec_command_set(PsqlScanState scan_state, bool active_branch)
Definition: command.c:2369
static backslashResult exec_command_s(PsqlScanState scan_state, bool active_branch)
Definition: command.c:2342
static backslashResult exec_command_prompt(PsqlScanState scan_state, bool active_branch, const char *cmd)
Definition: command.c:2178
static backslashResult exec_command_watch(PsqlScanState scan_state, bool active_branch, PQExpBuffer query_buf, PQExpBuffer previous_buf)
Definition: command.c:2761
static backslashResult exec_command_include(PsqlScanState scan_state, bool active_branch, const char *cmd)
Definition: command.c:1679
static backslashResult exec_command_list(PsqlScanState scan_state, bool active_branch, const char *cmd)
Definition: command.c:1947
static backslashResult exec_command_timing(PsqlScanState scan_state, bool active_branch)
Definition: command.c:2597
static backslashResult exec_command_C(PsqlScanState scan_state, bool active_branch)
Definition: command.c:499
static backslashResult exec_command_encoding(PsqlScanState scan_state, bool active_branch)
Definition: command.c:1316
static backslashResult exec_command_edit(PsqlScanState scan_state, bool active_branch, PQExpBuffer query_buf, PQExpBuffer previous_buf)
Definition: command.c:1059
static backslashResult exec_command_else(PsqlScanState scan_state, ConditionalStack cstack, PQExpBuffer query_buf)
Definition: command.c:1842
static backslashResult exec_command_conninfo(PsqlScanState scan_state, bool active_branch)
Definition: command.c:649
static backslashResult exec_command_copy(PsqlScanState scan_state, bool active_branch)
Definition: command.c:693
static backslashResult exec_command_slash_command_help(PsqlScanState scan_state, bool active_branch)
Definition: command.c:2980
static backslashResult exec_command_crosstabview(PsqlScanState scan_state, bool active_branch)
Definition: command.c:727
static backslashResult exec_command_pset(PsqlScanState scan_state, bool active_branch)
Definition: command.c:2255
static backslashResult exec_command_t(PsqlScanState scan_state, bool active_branch)
Definition: command.c:2553
static backslashResult exec_command_write(PsqlScanState scan_state, bool active_branch, const char *cmd, PQExpBuffer query_buf, PQExpBuffer previous_buf)
Definition: command.c:2659
static backslashResult exec_command_sf_sv(PsqlScanState scan_state, bool active_branch, const char *cmd, bool is_func)
Definition: command.c:2470
static bool is_branching_command(const char *cmd)
Definition: command.c:3163
static backslashResult exec_command_connect(PsqlScanState scan_state, bool active_branch)
Definition: command.c:532
static backslashResult exec_command_gexec(PsqlScanState scan_state, bool active_branch)
Definition: command.c:1594
static backslashResult exec_command_z(PsqlScanState scan_state, bool active_branch, const char *cmd)
Definition: command.c:2930
static backslashResult exec_command_lo(PsqlScanState scan_state, bool active_branch, const char *cmd)
Definition: command.c:1975
static backslashResult exec_command_getenv(PsqlScanState scan_state, bool active_branch, const char *cmd)
Definition: command.c:1557
static backslashResult exec_command_quit(PsqlScanState scan_state, bool active_branch)
Definition: command.c:2310
static backslashResult exec_command_setenv(PsqlScanState scan_state, bool active_branch, const char *cmd)
Definition: command.c:2422
@ PSQL_CMD_UNKNOWN
Definition: command.h:17
@ PSQL_CMD_SEND
Definition: command.h:18
enum _backslashResult backslashResult
bool conditional_active(ConditionalStack cstack)
Definition: conditional.c:140
#define pg_log_warning(...)
Definition: pgfnames.c:24

References conditional_active(), copy_previous_query(), _psqlSettings::cur_cmd_interactive, exec_command_a(), exec_command_bind(), exec_command_C(), exec_command_cd(), exec_command_connect(), exec_command_conninfo(), exec_command_copy(), exec_command_copyright(), exec_command_crosstabview(), exec_command_d(), exec_command_echo(), exec_command_edit(), exec_command_ef_ev(), exec_command_elif(), exec_command_else(), exec_command_encoding(), exec_command_endif(), exec_command_errverbose(), exec_command_f(), exec_command_g(), exec_command_gdesc(), exec_command_getenv(), exec_command_gexec(), exec_command_gset(), exec_command_help(), exec_command_html(), exec_command_if(), exec_command_include(), exec_command_list(), exec_command_lo(), exec_command_out(), exec_command_password(), exec_command_print(), exec_command_prompt(), exec_command_pset(), exec_command_quit(), exec_command_reset(), exec_command_s(), exec_command_set(), exec_command_setenv(), exec_command_sf_sv(), exec_command_shell_escape(), exec_command_slash_command_help(), exec_command_t(), exec_command_T(), exec_command_timing(), exec_command_unset(), exec_command_watch(), exec_command_write(), exec_command_x(), exec_command_z(), is_branching_command(), pg_log_warning, pg_strcasecmp(), pset, PSQL_CMD_SEND, and PSQL_CMD_UNKNOWN.

Referenced by HandleSlashCmds().

◆ exec_command_a()

static backslashResult exec_command_a ( PsqlScanState  scan_state,
bool  active_branch 
)
static

Definition at line 444 of file command.c.

445 {
446  bool success = true;
447 
448  if (active_branch)
449  {
451  success = do_pset("format", "aligned", &pset.popt, pset.quiet);
452  else
453  success = do_pset("format", "unaligned", &pset.popt, pset.quiet);
454  }
455 
457 }
bool do_pset(const char *param, const char *value, printQueryOpt *popt, bool quiet)
Definition: command.c:4369
@ PSQL_CMD_ERROR
Definition: command.h:22
@ PSQL_CMD_SKIP_LINE
Definition: command.h:19

References do_pset(), printTableOpt::format, _psqlSettings::popt, PRINT_ALIGNED, pset, PSQL_CMD_ERROR, PSQL_CMD_SKIP_LINE, _psqlSettings::quiet, success, and printQueryOpt::topt.

Referenced by exec_command().

◆ exec_command_bind()

static backslashResult exec_command_bind ( PsqlScanState  scan_state,
bool  active_branch 
)
static

Definition at line 463 of file command.c.

464 {
466 
467  if (active_branch)
468  {
469  char *opt;
470  int nparams = 0;
471  int nalloc = 0;
472 
473  pset.bind_params = NULL;
474 
475  while ((opt = psql_scan_slash_option(scan_state, OT_NORMAL, NULL, false)))
476  {
477  nparams++;
478  if (nparams > nalloc)
479  {
480  nalloc = nalloc ? nalloc * 2 : 1;
481  pset.bind_params = pg_realloc_array(pset.bind_params, char *, nalloc);
482  }
483  pset.bind_params[nparams - 1] = opt;
484  }
485 
486  pset.bind_nparams = nparams;
487  pset.bind_flag = true;
488  }
489  else
490  ignore_slash_options(scan_state);
491 
492  return status;
493 }
static void ignore_slash_options(PsqlScanState scan_state)
Definition: command.c:3114
#define pg_realloc_array(pointer, type, count)
Definition: fe_memutils.h:51
@ OT_NORMAL
Definition: psqlscanslash.h:17
char * psql_scan_slash_option(PsqlScanState state, enum slash_option_type type, char *quote, bool semicolon)
bool bind_flag
Definition: settings.h:99
char ** bind_params
Definition: settings.h:102
int bind_nparams
Definition: settings.h:101

References _psqlSettings::bind_flag, _psqlSettings::bind_nparams, _psqlSettings::bind_params, ignore_slash_options(), OT_NORMAL, pg_realloc_array, pset, PSQL_CMD_SKIP_LINE, and psql_scan_slash_option().

Referenced by exec_command().

◆ exec_command_C()

static backslashResult exec_command_C ( PsqlScanState  scan_state,
bool  active_branch 
)
static

Definition at line 499 of file command.c.

500 {
501  bool success = true;
502 
503  if (active_branch)
504  {
505  char *opt = psql_scan_slash_option(scan_state,
506  OT_NORMAL, NULL, true);
507 
508  success = do_pset("title", opt, &pset.popt, pset.quiet);
509  free(opt);
510  }
511  else
512  ignore_slash_options(scan_state);
513 
515 }

References do_pset(), free, ignore_slash_options(), OT_NORMAL, _psqlSettings::popt, pset, PSQL_CMD_ERROR, PSQL_CMD_SKIP_LINE, psql_scan_slash_option(), _psqlSettings::quiet, and success.

Referenced by exec_command().

◆ exec_command_cd()

static backslashResult exec_command_cd ( PsqlScanState  scan_state,
bool  active_branch,
const char *  cmd 
)
static

Definition at line 585 of file command.c.

586 {
587  bool success = true;
588 
589  if (active_branch)
590  {
591  char *opt = psql_scan_slash_option(scan_state,
592  OT_NORMAL, NULL, true);
593  char *dir;
594 
595  if (opt)
596  dir = opt;
597  else
598  {
599 #ifndef WIN32
600  /* This should match get_home_path() */
601  dir = getenv("HOME");
602  if (dir == NULL || dir[0] == '\0')
603  {
604  uid_t user_id = geteuid();
605  struct passwd *pw;
606 
607  errno = 0; /* clear errno before call */
608  pw = getpwuid(user_id);
609  if (pw)
610  dir = pw->pw_dir;
611  else
612  {
613  pg_log_error("could not get home directory for user ID %ld: %s",
614  (long) user_id,
615  errno ? strerror(errno) : _("user does not exist"));
616  success = false;
617  }
618  }
619 #else /* WIN32 */
620 
621  /*
622  * On Windows, 'cd' without arguments prints the current
623  * directory, so if someone wants to code this here instead...
624  */
625  dir = "/";
626 #endif /* WIN32 */
627  }
628 
629  if (success &&
630  chdir(dir) < 0)
631  {
632  pg_log_error("\\%s: could not change directory to \"%s\": %m",
633  cmd, dir);
634  success = false;
635  }
636 
637  free(opt);
638  }
639  else
640  ignore_slash_options(scan_state);
641 
643 }
int uid_t
Definition: win32_port.h:244

References _, free, ignore_slash_options(), OT_NORMAL, pg_log_error, PSQL_CMD_ERROR, PSQL_CMD_SKIP_LINE, psql_scan_slash_option(), strerror, and success.

Referenced by exec_command().

◆ exec_command_connect()

static backslashResult exec_command_connect ( PsqlScanState  scan_state,
bool  active_branch 
)
static

Definition at line 532 of file command.c.

533 {
534  bool success = true;
535 
536  if (active_branch)
537  {
538  static const char prefix[] = "-reuse-previous=";
539  char *opt1,
540  *opt2,
541  *opt3,
542  *opt4;
543  enum trivalue reuse_previous = TRI_DEFAULT;
544 
545  opt1 = read_connect_arg(scan_state);
546  if (opt1 != NULL && strncmp(opt1, prefix, sizeof(prefix) - 1) == 0)
547  {
548  bool on_off;
549 
550  success = ParseVariableBool(opt1 + sizeof(prefix) - 1,
551  "-reuse-previous",
552  &on_off);
553  if (success)
554  {
555  reuse_previous = on_off ? TRI_YES : TRI_NO;
556  free(opt1);
557  opt1 = read_connect_arg(scan_state);
558  }
559  }
560 
561  if (success) /* give up if reuse_previous was invalid */
562  {
563  opt2 = read_connect_arg(scan_state);
564  opt3 = read_connect_arg(scan_state);
565  opt4 = read_connect_arg(scan_state);
566 
567  success = do_connect(reuse_previous, opt1, opt2, opt3, opt4);
568 
569  free(opt2);
570  free(opt3);
571  free(opt4);
572  }
573  free(opt1);
574  }
575  else
576  ignore_slash_options(scan_state);
577 
579 }
static bool do_connect(enum trivalue reuse_previous_specification, char *dbname, char *user, char *host, char *port)
Definition: command.c:3294
static char * read_connect_arg(PsqlScanState scan_state)
Definition: command.c:3011
trivalue
Definition: vacuumlo.c:35
@ TRI_DEFAULT
Definition: vacuumlo.c:36

References do_connect(), free, ignore_slash_options(), ParseVariableBool(), PSQL_CMD_ERROR, PSQL_CMD_SKIP_LINE, read_connect_arg(), success, TRI_DEFAULT, TRI_NO, and TRI_YES.

Referenced by exec_command().

◆ exec_command_conninfo()

static backslashResult exec_command_conninfo ( PsqlScanState  scan_state,
bool  active_branch 
)
static

Definition at line 649 of file command.c.

650 {
651  if (active_branch)
652  {
653  char *db = PQdb(pset.db);
654 
655  if (db == NULL)
656  printf(_("You are currently not connected to a database.\n"));
657  else
658  {
659  char *host = PQhost(pset.db);
660  char *hostaddr = PQhostaddr(pset.db);
661 
662  if (is_unixsock_path(host))
663  {
664  /* hostaddr overrides host */
665  if (hostaddr && *hostaddr)
666  printf(_("You are connected to database \"%s\" as user \"%s\" on address \"%s\" at port \"%s\".\n"),
667  db, PQuser(pset.db), hostaddr, PQport(pset.db));
668  else
669  printf(_("You are connected to database \"%s\" as user \"%s\" via socket in \"%s\" at port \"%s\".\n"),
670  db, PQuser(pset.db), host, PQport(pset.db));
671  }
672  else
673  {
674  if (hostaddr && *hostaddr && strcmp(host, hostaddr) != 0)
675  printf(_("You are connected to database \"%s\" as user \"%s\" on host \"%s\" (address \"%s\") at port \"%s\".\n"),
676  db, PQuser(pset.db), host, hostaddr, PQport(pset.db));
677  else
678  printf(_("You are connected to database \"%s\" as user \"%s\" on host \"%s\" at port \"%s\".\n"),
679  db, PQuser(pset.db), host, PQport(pset.db));
680  }
681  printSSLInfo();
682  printGSSInfo();
683  }
684  }
685 
686  return PSQL_CMD_SKIP_LINE;
687 }

References _, _psqlSettings::db, is_unixsock_path(), PQdb(), PQhost(), PQhostaddr(), PQport(), PQuser(), printf, printGSSInfo(), printSSLInfo(), pset, and PSQL_CMD_SKIP_LINE.

Referenced by exec_command().

◆ exec_command_copy()

static backslashResult exec_command_copy ( PsqlScanState  scan_state,
bool  active_branch 
)
static

Definition at line 693 of file command.c.

694 {
695  bool success = true;
696 
697  if (active_branch)
698  {
699  char *opt = psql_scan_slash_option(scan_state,
700  OT_WHOLE_LINE, NULL, false);
701 
702  success = do_copy(opt);
703  free(opt);
704  }
705  else
706  ignore_slash_whole_line(scan_state);
707 
709 }
bool do_copy(const char *args)
Definition: copy.c:268
static void ignore_slash_whole_line(PsqlScanState scan_state)
Definition: command.c:3151
@ OT_WHOLE_LINE
Definition: psqlscanslash.h:21

References do_copy(), free, ignore_slash_whole_line(), OT_WHOLE_LINE, PSQL_CMD_ERROR, PSQL_CMD_SKIP_LINE, psql_scan_slash_option(), and success.

Referenced by exec_command().

◆ exec_command_copyright()

static backslashResult exec_command_copyright ( PsqlScanState  scan_state,
bool  active_branch 
)
static

Definition at line 715 of file command.c.

716 {
717  if (active_branch)
718  print_copyright();
719 
720  return PSQL_CMD_SKIP_LINE;
721 }
void print_copyright(void)

References print_copyright(), and PSQL_CMD_SKIP_LINE.

Referenced by exec_command().

◆ exec_command_crosstabview()

static backslashResult exec_command_crosstabview ( PsqlScanState  scan_state,
bool  active_branch 
)
static

Definition at line 727 of file command.c.

728 {
730 
731  if (active_branch)
732  {
733  int i;
734 
735  for (i = 0; i < lengthof(pset.ctv_args); i++)
736  pset.ctv_args[i] = psql_scan_slash_option(scan_state,
737  OT_NORMAL, NULL, true);
738  pset.crosstab_flag = true;
739  status = PSQL_CMD_SEND;
740  }
741  else
742  ignore_slash_options(scan_state);
743 
744  return status;
745 }
char * ctv_args[4]
Definition: settings.h:104
bool crosstab_flag
Definition: settings.h:103

References _psqlSettings::crosstab_flag, _psqlSettings::ctv_args, i, ignore_slash_options(), lengthof, OT_NORMAL, pset, PSQL_CMD_SEND, PSQL_CMD_SKIP_LINE, and psql_scan_slash_option().

Referenced by exec_command().

◆ exec_command_d()

static backslashResult exec_command_d ( PsqlScanState  scan_state,
bool  active_branch,
const char *  cmd 
)
static

Definition at line 751 of file command.c.

752 {
754  bool success = true;
755 
756  if (active_branch)
757  {
758  char *pattern;
759  bool show_verbose,
760  show_system;
761 
762  /* We don't do SQLID reduction on the pattern yet */
763  pattern = psql_scan_slash_option(scan_state,
764  OT_NORMAL, NULL, true);
765 
766  show_verbose = strchr(cmd, '+') ? true : false;
767  show_system = strchr(cmd, 'S') ? true : false;
768 
769  switch (cmd[1])
770  {
771  case '\0':
772  case '+':
773  case 'S':
774  if (pattern)
775  success = describeTableDetails(pattern, show_verbose, show_system);
776  else
777  /* standard listing of interesting things */
778  success = listTables("tvmsE", NULL, show_verbose, show_system);
779  break;
780  case 'A':
781  {
782  char *pattern2 = NULL;
783 
784  if (pattern && cmd[2] != '\0' && cmd[2] != '+')
785  pattern2 = psql_scan_slash_option(scan_state, OT_NORMAL, NULL, true);
786 
787  switch (cmd[2])
788  {
789  case '\0':
790  case '+':
791  success = describeAccessMethods(pattern, show_verbose);
792  break;
793  case 'c':
794  success = listOperatorClasses(pattern, pattern2, show_verbose);
795  break;
796  case 'f':
797  success = listOperatorFamilies(pattern, pattern2, show_verbose);
798  break;
799  case 'o':
800  success = listOpFamilyOperators(pattern, pattern2, show_verbose);
801  break;
802  case 'p':
803  success = listOpFamilyFunctions(pattern, pattern2, show_verbose);
804  break;
805  default:
806  status = PSQL_CMD_UNKNOWN;
807  break;
808  }
809 
810  free(pattern2);
811  }
812  break;
813  case 'a':
814  success = describeAggregates(pattern, show_verbose, show_system);
815  break;
816  case 'b':
817  success = describeTablespaces(pattern, show_verbose);
818  break;
819  case 'c':
820  if (strncmp(cmd, "dconfig", 7) == 0)
822  show_verbose,
823  show_system);
824  else
825  success = listConversions(pattern,
826  show_verbose,
827  show_system);
828  break;
829  case 'C':
830  success = listCasts(pattern, show_verbose);
831  break;
832  case 'd':
833  if (strncmp(cmd, "ddp", 3) == 0)
834  success = listDefaultACLs(pattern);
835  else
836  success = objectDescription(pattern, show_system);
837  break;
838  case 'D':
839  success = listDomains(pattern, show_verbose, show_system);
840  break;
841  case 'f': /* function subsystem */
842  switch (cmd[2])
843  {
844  case '\0':
845  case '+':
846  case 'S':
847  case 'a':
848  case 'n':
849  case 'p':
850  case 't':
851  case 'w':
852  success = exec_command_dfo(scan_state, cmd, pattern,
853  show_verbose, show_system);
854  break;
855  default:
856  status = PSQL_CMD_UNKNOWN;
857  break;
858  }
859  break;
860  case 'g':
861  /* no longer distinct from \du */
862  success = describeRoles(pattern, show_verbose, show_system);
863  break;
864  case 'l':
865  success = listLargeObjects(show_verbose);
866  break;
867  case 'L':
868  success = listLanguages(pattern, show_verbose, show_system);
869  break;
870  case 'n':
871  success = listSchemas(pattern, show_verbose, show_system);
872  break;
873  case 'o':
874  success = exec_command_dfo(scan_state, cmd, pattern,
875  show_verbose, show_system);
876  break;
877  case 'O':
878  success = listCollations(pattern, show_verbose, show_system);
879  break;
880  case 'p':
881  success = permissionsList(pattern, show_system);
882  break;
883  case 'P':
884  {
885  switch (cmd[2])
886  {
887  case '\0':
888  case '+':
889  case 't':
890  case 'i':
891  case 'n':
892  success = listPartitionedTables(&cmd[2], pattern, show_verbose);
893  break;
894  default:
895  status = PSQL_CMD_UNKNOWN;
896  break;
897  }
898  }
899  break;
900  case 'T':
901  success = describeTypes(pattern, show_verbose, show_system);
902  break;
903  case 't':
904  case 'v':
905  case 'm':
906  case 'i':
907  case 's':
908  case 'E':
909  success = listTables(&cmd[1], pattern, show_verbose, show_system);
910  break;
911  case 'r':
912  if (cmd[2] == 'd' && cmd[3] == 's')
913  {
914  char *pattern2 = NULL;
915 
916  if (pattern)
917  pattern2 = psql_scan_slash_option(scan_state,
918  OT_NORMAL, NULL, true);
919  success = listDbRoleSettings(pattern, pattern2);
920 
921  free(pattern2);
922  }
923  else if (cmd[2] == 'g')
924  success = describeRoleGrants(pattern, show_system);
925  else
926  status = PSQL_CMD_UNKNOWN;
927  break;
928  case 'R':
929  switch (cmd[2])
930  {
931  case 'p':
932  if (show_verbose)
933  success = describePublications(pattern);
934  else
935  success = listPublications(pattern);
936  break;
937  case 's':
938  success = describeSubscriptions(pattern, show_verbose);
939  break;
940  default:
941  status = PSQL_CMD_UNKNOWN;
942  }
943  break;
944  case 'u':
945  success = describeRoles(pattern, show_verbose, show_system);
946  break;
947  case 'F': /* text search subsystem */
948  switch (cmd[2])
949  {
950  case '\0':
951  case '+':
952  success = listTSConfigs(pattern, show_verbose);
953  break;
954  case 'p':
955  success = listTSParsers(pattern, show_verbose);
956  break;
957  case 'd':
958  success = listTSDictionaries(pattern, show_verbose);
959  break;
960  case 't':
961  success = listTSTemplates(pattern, show_verbose);
962  break;
963  default:
964  status = PSQL_CMD_UNKNOWN;
965  break;
966  }
967  break;
968  case 'e': /* SQL/MED subsystem */
969  switch (cmd[2])
970  {
971  case 's':
972  success = listForeignServers(pattern, show_verbose);
973  break;
974  case 'u':
975  success = listUserMappings(pattern, show_verbose);
976  break;
977  case 'w':
978  success = listForeignDataWrappers(pattern, show_verbose);
979  break;
980  case 't':
981  success = listForeignTables(pattern, show_verbose);
982  break;
983  default:
984  status = PSQL_CMD_UNKNOWN;
985  break;
986  }
987  break;
988  case 'x': /* Extensions */
989  if (show_verbose)
990  success = listExtensionContents(pattern);
991  else
992  success = listExtensions(pattern);
993  break;
994  case 'X': /* Extended Statistics */
995  success = listExtendedStats(pattern);
996  break;
997  case 'y': /* Event Triggers */
998  success = listEventTriggers(pattern, show_verbose);
999  break;
1000  default:
1001  status = PSQL_CMD_UNKNOWN;
1002  }
1003 
1004  free(pattern);
1005  }
1006  else
1007  ignore_slash_options(scan_state);
1008 
1009  if (!success)
1010  status = PSQL_CMD_ERROR;
1011 
1012  return status;
1013 }
static bool exec_command_dfo(PsqlScanState scan_state, const char *cmd, const char *pattern, bool show_verbose, bool show_system)
Definition: command.c:1017
bool listUserMappings(const char *pattern, bool verbose)
Definition: describe.c:5927
bool listTSConfigs(const char *pattern, bool verbose)
Definition: describe.c:5576
bool describeRoles(const char *pattern, bool verbose, bool showSystem)
Definition: describe.c:3666
bool listOpFamilyFunctions(const char *access_method_pattern, const char *family_pattern, bool verbose)
Definition: describe.c:7017
bool listPublications(const char *pattern)
Definition: describe.c:6269
bool listTSParsers(const char *pattern, bool verbose)
Definition: describe.c:5199
bool listExtensionContents(const char *pattern)
Definition: describe.c:6105
bool describeAggregates(const char *pattern, bool verbose, bool showSystem)
Definition: describe.c:71
bool listForeignDataWrappers(const char *pattern, bool verbose)
Definition: describe.c:5780
bool listPartitionedTables(const char *reltypes, const char *pattern, bool verbose)
Definition: describe.c:4159
bool describeSubscriptions(const char *pattern, bool verbose)
Definition: describe.c:6577
bool describeRoleGrants(const char *pattern, bool showSystem)
Definition: describe.c:3882
bool listExtendedStats(const char *pattern)
Definition: describe.c:4746
bool describeTypes(const char *pattern, bool verbose, bool showSystem)
Definition: describe.c:615
bool listOperatorFamilies(const char *access_method_pattern, const char *type_pattern, bool verbose)
Definition: describe.c:6830
bool listForeignServers(const char *pattern, bool verbose)
Definition: describe.c:5851
bool describeTableDetails(const char *pattern, bool verbose, bool showSystem)
Definition: describe.c:1445
bool listDomains(const char *pattern, bool verbose, bool showSystem)
Definition: describe.c:4435
bool listTSDictionaries(const char *pattern, bool verbose)
Definition: describe.c:5446
bool listDbRoleSettings(const char *pattern, const char *pattern2)
Definition: describe.c:3813
bool listCollations(const char *pattern, bool verbose, bool showSystem)
Definition: describe.c:4960
bool listSchemas(const char *pattern, bool verbose, bool showSystem)
Definition: describe.c:5078
bool listExtensions(const char *pattern)
Definition: describe.c:6054
bool listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSystem)
Definition: describe.c:3961
bool listTSTemplates(const char *pattern, bool verbose)
Definition: describe.c:5511
bool describeTablespaces(const char *pattern, bool verbose)
Definition: describe.c:215
bool listCasts(const char *pattern, bool verbose)
Definition: describe.c:4842
bool listOpFamilyOperators(const char *access_method_pattern, const char *family_pattern, bool verbose)
Definition: describe.c:6919
bool listOperatorClasses(const char *access_method_pattern, const char *type_pattern, bool verbose)
Definition: describe.c:6729
bool listForeignTables(const char *pattern, bool verbose)
Definition: describe.c:5982
bool describeConfigurationParameters(const char *pattern, bool verbose, bool showSystem)
Definition: describe.c:4598
bool listEventTriggers(const char *pattern, bool verbose)
Definition: describe.c:4666
bool listDefaultACLs(const char *pattern)
Definition: describe.c:1175
bool listConversions(const char *pattern, bool verbose, bool showSystem)
Definition: describe.c:4518
bool permissionsList(const char *pattern, bool showSystem)
Definition: describe.c:1011
bool describeAccessMethods(const char *pattern, bool verbose)
Definition: describe.c:141
bool listLargeObjects(bool verbose)
Definition: describe.c:7106
bool listLanguages(const char *pattern, bool verbose, bool showSystem)
Definition: describe.c:4359
bool describePublications(const char *pattern)
Definition: describe.c:6391
bool objectDescription(const char *pattern, bool showSystem)
Definition: describe.c:1252
return true
Definition: isn.c:126

References describeAccessMethods(), describeAggregates(), describeConfigurationParameters(), describePublications(), describeRoleGrants(), describeRoles(), describeSubscriptions(), describeTableDetails(), describeTablespaces(), describeTypes(), exec_command_dfo(), free, ignore_slash_options(), listCasts(), listCollations(), listConversions(), listDbRoleSettings(), listDefaultACLs(), listDomains(), listEventTriggers(), listExtendedStats(), listExtensionContents(), listExtensions(), listForeignDataWrappers(), listForeignServers(), listForeignTables(), listLanguages(), listLargeObjects(), listOperatorClasses(), listOperatorFamilies(), listOpFamilyFunctions(), listOpFamilyOperators(), listPartitionedTables(), listPublications(), listSchemas(), listTables(), listTSConfigs(), listTSDictionaries(), listTSParsers(), listTSTemplates(), listUserMappings(), objectDescription(), OT_NORMAL, permissionsList(), PSQL_CMD_ERROR, PSQL_CMD_SKIP_LINE, PSQL_CMD_UNKNOWN, psql_scan_slash_option(), success, and true.

Referenced by exec_command().

◆ exec_command_dfo()

static bool exec_command_dfo ( PsqlScanState  scan_state,
const char *  cmd,
const char *  pattern,
bool  show_verbose,
bool  show_system 
)
static

Definition at line 1017 of file command.c.

1020 {
1021  bool success;
1022  char *arg_patterns[FUNC_MAX_ARGS];
1023  int num_arg_patterns = 0;
1024 
1025  /* Collect argument-type patterns too */
1026  if (pattern) /* otherwise it was just \df or \do */
1027  {
1028  char *ap;
1029 
1030  while ((ap = psql_scan_slash_option(scan_state,
1031  OT_NORMAL, NULL, true)) != NULL)
1032  {
1033  arg_patterns[num_arg_patterns++] = ap;
1034  if (num_arg_patterns >= FUNC_MAX_ARGS)
1035  break; /* protect limited-size array */
1036  }
1037  }
1038 
1039  if (cmd[1] == 'f')
1040  success = describeFunctions(&cmd[2], pattern,
1041  arg_patterns, num_arg_patterns,
1042  show_verbose, show_system);
1043  else
1044  success = describeOperators(pattern,
1045  arg_patterns, num_arg_patterns,
1046  show_verbose, show_system);
1047 
1048  while (--num_arg_patterns >= 0)
1049  free(arg_patterns[num_arg_patterns]);
1050 
1051  return success;
1052 }
bool describeFunctions(const char *functypes, const char *func_pattern, char **arg_patterns, int num_arg_patterns, bool verbose, bool showSystem)
Definition: describe.c:288
bool describeOperators(const char *oper_pattern, char **arg_patterns, int num_arg_patterns, bool verbose, bool showSystem)
Definition: describe.c:770
#define FUNC_MAX_ARGS

References describeFunctions(), describeOperators(), free, FUNC_MAX_ARGS, OT_NORMAL, psql_scan_slash_option(), and success.

Referenced by exec_command_d().

◆ exec_command_echo()

static backslashResult exec_command_echo ( PsqlScanState  scan_state,
bool  active_branch,
const char *  cmd 
)
static

Definition at line 1271 of file command.c.

1272 {
1273  if (active_branch)
1274  {
1275  char *value;
1276  char quoted;
1277  bool no_newline = false;
1278  bool first = true;
1279  FILE *fout;
1280 
1281  if (strcmp(cmd, "qecho") == 0)
1282  fout = pset.queryFout;
1283  else if (strcmp(cmd, "warn") == 0)
1284  fout = stderr;
1285  else
1286  fout = stdout;
1287 
1288  while ((value = psql_scan_slash_option(scan_state,
1289  OT_NORMAL, &quoted, false)))
1290  {
1291  if (first && !no_newline && !quoted && strcmp(value, "-n") == 0)
1292  no_newline = true;
1293  else
1294  {
1295  if (first)
1296  first = false;
1297  else
1298  fputc(' ', fout);
1299  fputs(value, fout);
1300  }
1301  free(value);
1302  }
1303  if (!no_newline)
1304  fputs("\n", fout);
1305  }
1306  else
1307  ignore_slash_options(scan_state);
1308 
1309  return PSQL_CMD_SKIP_LINE;
1310 }
FILE * queryFout
Definition: settings.h:84

References free, ignore_slash_options(), OT_NORMAL, pset, PSQL_CMD_SKIP_LINE, psql_scan_slash_option(), _psqlSettings::queryFout, generate_unaccent_rules::stdout, and value.

Referenced by exec_command().

◆ exec_command_edit()

static backslashResult exec_command_edit ( PsqlScanState  scan_state,
bool  active_branch,
PQExpBuffer  query_buf,
PQExpBuffer  previous_buf 
)
static

Definition at line 1059 of file command.c.

1061 {
1063 
1064  if (active_branch)
1065  {
1066  if (!query_buf)
1067  {
1068  pg_log_error("no query buffer");
1069  status = PSQL_CMD_ERROR;
1070  }
1071  else
1072  {
1073  char *fname;
1074  char *ln = NULL;
1075  int lineno = -1;
1076 
1077  fname = psql_scan_slash_option(scan_state,
1078  OT_NORMAL, NULL, true);
1079  if (fname)
1080  {
1081  /* try to get separate lineno arg */
1082  ln = psql_scan_slash_option(scan_state,
1083  OT_NORMAL, NULL, true);
1084  if (ln == NULL)
1085  {
1086  /* only one arg; maybe it is lineno not fname */
1087  if (fname[0] &&
1088  strspn(fname, "0123456789") == strlen(fname))
1089  {
1090  /* all digits, so assume it is lineno */
1091  ln = fname;
1092  fname = NULL;
1093  }
1094  }
1095  }
1096  if (ln)
1097  {
1098  lineno = atoi(ln);
1099  if (lineno < 1)
1100  {
1101  pg_log_error("invalid line number: %s", ln);
1102  status = PSQL_CMD_ERROR;
1103  }
1104  }
1105  if (status != PSQL_CMD_ERROR)
1106  {
1107  bool discard_on_quit;
1108 
1109  expand_tilde(&fname);
1110  if (fname)
1111  {
1112  canonicalize_path(fname);
1113  /* Always clear buffer if the file isn't modified */
1114  discard_on_quit = true;
1115  }
1116  else
1117  {
1118  /*
1119  * If query_buf is empty, recall previous query for
1120  * editing. But in that case, the query buffer should be
1121  * emptied if editing doesn't modify the file.
1122  */
1123  discard_on_quit = copy_previous_query(query_buf,
1124  previous_buf);
1125  }
1126 
1127  if (do_edit(fname, query_buf, lineno, discard_on_quit, NULL))
1128  status = PSQL_CMD_NEWEDIT;
1129  else
1130  status = PSQL_CMD_ERROR;
1131  }
1132 
1133  /*
1134  * On error while editing or if specifying an incorrect line
1135  * number, reset the query buffer.
1136  */
1137  if (status == PSQL_CMD_ERROR)
1138  resetPQExpBuffer(query_buf);
1139 
1140  free(fname);
1141  free(ln);
1142  }
1143  }
1144  else
1145  ignore_slash_options(scan_state);
1146 
1147  return status;
1148 }
void expand_tilde(char **filename)
Definition: common.c:2352
static bool do_edit(const char *filename_arg, PQExpBuffer query_buf, int lineno, bool discard_on_quit, bool *edited)
Definition: command.c:4021
@ PSQL_CMD_NEWEDIT
Definition: command.h:21
void canonicalize_path(char *path)
Definition: path.c:264

References canonicalize_path(), copy_previous_query(), do_edit(), expand_tilde(), free, ignore_slash_options(), OT_NORMAL, pg_log_error, PSQL_CMD_ERROR, PSQL_CMD_NEWEDIT, PSQL_CMD_SKIP_LINE, psql_scan_slash_option(), and resetPQExpBuffer().

Referenced by exec_command().

◆ exec_command_ef_ev()

static backslashResult exec_command_ef_ev ( PsqlScanState  scan_state,
bool  active_branch,
PQExpBuffer  query_buf,
bool  is_func 
)
static

Definition at line 1155 of file command.c.

1157 {
1159 
1160  if (active_branch)
1161  {
1162  char *obj_desc = psql_scan_slash_option(scan_state,
1163  OT_WHOLE_LINE,
1164  NULL, true);
1165  int lineno = -1;
1166 
1167  if (!query_buf)
1168  {
1169  pg_log_error("no query buffer");
1170  status = PSQL_CMD_ERROR;
1171  }
1172  else
1173  {
1174  Oid obj_oid = InvalidOid;
1176 
1177  lineno = strip_lineno_from_objdesc(obj_desc);
1178  if (lineno == 0)
1179  {
1180  /* error already reported */
1181  status = PSQL_CMD_ERROR;
1182  }
1183  else if (!obj_desc)
1184  {
1185  /* set up an empty command to fill in */
1186  resetPQExpBuffer(query_buf);
1187  if (is_func)
1188  appendPQExpBufferStr(query_buf,
1189  "CREATE FUNCTION ( )\n"
1190  " RETURNS \n"
1191  " LANGUAGE \n"
1192  " -- common options: IMMUTABLE STABLE STRICT SECURITY DEFINER\n"
1193  "AS $function$\n"
1194  "\n$function$\n");
1195  else
1196  appendPQExpBufferStr(query_buf,
1197  "CREATE VIEW AS\n"
1198  " SELECT \n"
1199  " -- something...\n");
1200  }
1201  else if (!lookup_object_oid(eot, obj_desc, &obj_oid))
1202  {
1203  /* error already reported */
1204  status = PSQL_CMD_ERROR;
1205  }
1206  else if (!get_create_object_cmd(eot, obj_oid, query_buf))
1207  {
1208  /* error already reported */
1209  status = PSQL_CMD_ERROR;
1210  }
1211  else if (is_func && lineno > 0)
1212  {
1213  /*
1214  * lineno "1" should correspond to the first line of the
1215  * function body. We expect that pg_get_functiondef() will
1216  * emit that on a line beginning with "AS ", "BEGIN ", or
1217  * "RETURN ", and that there can be no such line before the
1218  * real start of the function body. Increment lineno by the
1219  * number of lines before that line, so that it becomes
1220  * relative to the first line of the function definition.
1221  */
1222  const char *lines = query_buf->data;
1223 
1224  while (*lines != '\0')
1225  {
1226  if (strncmp(lines, "AS ", 3) == 0 ||
1227  strncmp(lines, "BEGIN ", 6) == 0 ||
1228  strncmp(lines, "RETURN ", 7) == 0)
1229  break;
1230  lineno++;
1231  /* find start of next line */
1232  lines = strchr(lines, '\n');
1233  if (!lines)
1234  break;
1235  lines++;
1236  }
1237  }
1238  }
1239 
1240  if (status != PSQL_CMD_ERROR)
1241  {
1242  bool edited = false;
1243 
1244  if (!do_edit(NULL, query_buf, lineno, true, &edited))
1245  status = PSQL_CMD_ERROR;
1246  else if (!edited)
1247  puts(_("No changes"));
1248  else
1249  status = PSQL_CMD_NEWEDIT;
1250  }
1251 
1252  /*
1253  * On error while doing object lookup or while editing, or if
1254  * specifying an incorrect line number, reset the query buffer.
1255  */
1256  if (status == PSQL_CMD_ERROR)
1257  resetPQExpBuffer(query_buf);
1258 
1259  free(obj_desc);
1260  }
1261  else
1262  ignore_slash_whole_line(scan_state);
1263 
1264  return status;
1265 }
static bool get_create_object_cmd(EditableObjectType obj_type, Oid oid, PQExpBuffer buf)
Definition: command.c:5497
static bool lookup_object_oid(EditableObjectType obj_type, const char *desc, Oid *obj_oid)
Definition: command.c:5437
static int strip_lineno_from_objdesc(char *obj)
Definition: command.c:5657
#define InvalidOid
Definition: postgres_ext.h:36
unsigned int Oid
Definition: postgres_ext.h:31

References _, appendPQExpBufferStr(), PQExpBufferData::data, do_edit(), EditableFunction, EditableView, free, get_create_object_cmd(), ignore_slash_whole_line(), InvalidOid, lookup_object_oid(), OT_WHOLE_LINE, pg_log_error, PSQL_CMD_ERROR, PSQL_CMD_NEWEDIT, PSQL_CMD_SKIP_LINE, psql_scan_slash_option(), resetPQExpBuffer(), and strip_lineno_from_objdesc().

Referenced by exec_command().

◆ exec_command_elif()

static backslashResult exec_command_elif ( PsqlScanState  scan_state,
ConditionalStack  cstack,
PQExpBuffer  query_buf 
)
static

Definition at line 1766 of file command.c.

1768 {
1769  bool success = true;
1770 
1771  switch (conditional_stack_peek(cstack))
1772  {
1773  case IFSTATE_TRUE:
1774 
1775  /*
1776  * Just finished active branch of this \if block. Update saved
1777  * state so we will keep whatever data was put in query_buf by the
1778  * active branch.
1779  */
1780  save_query_text_state(scan_state, cstack, query_buf);
1781 
1782  /*
1783  * Discard \elif expression and ignore the rest until \endif.
1784  * Switch state before reading expression to ensure proper lexer
1785  * behavior.
1786  */
1788  ignore_boolean_expression(scan_state);
1789  break;
1790  case IFSTATE_FALSE:
1791 
1792  /*
1793  * Discard any query text added by the just-skipped branch.
1794  */
1795  discard_query_text(scan_state, cstack, query_buf);
1796 
1797  /*
1798  * Have not yet found a true expression in this \if block, so this
1799  * might be the first. We have to change state before examining
1800  * the expression, or the lexer won't do the right thing.
1801  */
1803  if (!is_true_boolean_expression(scan_state, "\\elif expression"))
1805  break;
1806  case IFSTATE_IGNORED:
1807 
1808  /*
1809  * Discard any query text added by the just-skipped branch.
1810  */
1811  discard_query_text(scan_state, cstack, query_buf);
1812 
1813  /*
1814  * Skip expression and move on. Either the \if block already had
1815  * an active section, or whole block is being skipped.
1816  */
1817  ignore_boolean_expression(scan_state);
1818  break;
1819  case IFSTATE_ELSE_TRUE:
1820  case IFSTATE_ELSE_FALSE:
1821  pg_log_error("\\elif: cannot occur after \\else");
1822  success = false;
1823  break;
1824  case IFSTATE_NONE:
1825  /* no \if to elif from */
1826  pg_log_error("\\elif: no matching \\if");
1827  success = false;
1828  break;
1829  }
1830 
1832 }
static void discard_query_text(PsqlScanState scan_state, ConditionalStack cstack, PQExpBuffer query_buf)
Definition: command.c:3199
static void ignore_boolean_expression(PsqlScanState scan_state)
Definition: command.c:3098
static bool is_true_boolean_expression(PsqlScanState scan_state, const char *name)
Definition: command.c:3081
static void save_query_text_state(PsqlScanState scan_state, ConditionalStack cstack, PQExpBuffer query_buf)
Definition: command.c:3179
ifState conditional_stack_peek(ConditionalStack cstack)
Definition: conditional.c:106
bool conditional_stack_poke(ConditionalStack cstack, ifState new_state)
Definition: conditional.c:118
@ IFSTATE_FALSE
Definition: conditional.h:34
@ IFSTATE_ELSE_TRUE
Definition: conditional.h:40
@ IFSTATE_IGNORED
Definition: conditional.h:37
@ IFSTATE_TRUE
Definition: conditional.h:32
@ IFSTATE_NONE
Definition: conditional.h:31
@ IFSTATE_ELSE_FALSE
Definition: conditional.h:42

References conditional_stack_peek(), conditional_stack_poke(), discard_query_text(), IFSTATE_ELSE_FALSE, IFSTATE_ELSE_TRUE, IFSTATE_FALSE, IFSTATE_IGNORED, IFSTATE_NONE, IFSTATE_TRUE, ignore_boolean_expression(), is_true_boolean_expression(), pg_log_error, PSQL_CMD_ERROR, PSQL_CMD_SKIP_LINE, save_query_text_state(), and success.

Referenced by exec_command().

◆ exec_command_else()

static backslashResult exec_command_else ( PsqlScanState  scan_state,
ConditionalStack  cstack,
PQExpBuffer  query_buf 
)
static

Definition at line 1842 of file command.c.

1844 {
1845  bool success = true;
1846 
1847  switch (conditional_stack_peek(cstack))
1848  {
1849  case IFSTATE_TRUE:
1850 
1851  /*
1852  * Just finished active branch of this \if block. Update saved
1853  * state so we will keep whatever data was put in query_buf by the
1854  * active branch.
1855  */
1856  save_query_text_state(scan_state, cstack, query_buf);
1857 
1858  /* Now skip the \else branch */
1860  break;
1861  case IFSTATE_FALSE:
1862 
1863  /*
1864  * Discard any query text added by the just-skipped branch.
1865  */
1866  discard_query_text(scan_state, cstack, query_buf);
1867 
1868  /*
1869  * We've not found any true \if or \elif expression, so execute
1870  * the \else branch.
1871  */
1873  break;
1874  case IFSTATE_IGNORED:
1875 
1876  /*
1877  * Discard any query text added by the just-skipped branch.
1878  */
1879  discard_query_text(scan_state, cstack, query_buf);
1880 
1881  /*
1882  * Either we previously processed the active branch of this \if,
1883  * or the whole \if block is being skipped. Either way, skip the
1884  * \else branch.
1885  */
1887  break;
1888  case IFSTATE_ELSE_TRUE:
1889  case IFSTATE_ELSE_FALSE:
1890  pg_log_error("\\else: cannot occur after \\else");
1891  success = false;
1892  break;
1893  case IFSTATE_NONE:
1894  /* no \if to else from */
1895  pg_log_error("\\else: no matching \\if");
1896  success = false;
1897  break;
1898  }
1899 
1901 }

References conditional_stack_peek(), conditional_stack_poke(), discard_query_text(), IFSTATE_ELSE_FALSE, IFSTATE_ELSE_TRUE, IFSTATE_FALSE, IFSTATE_IGNORED, IFSTATE_NONE, IFSTATE_TRUE, pg_log_error, PSQL_CMD_ERROR, PSQL_CMD_SKIP_LINE, save_query_text_state(), and success.

Referenced by exec_command().

◆ exec_command_encoding()

static backslashResult exec_command_encoding ( PsqlScanState  scan_state,
bool  active_branch 
)
static

Definition at line 1316 of file command.c.

1317 {
1318  if (active_branch)
1319  {
1320  char *encoding = psql_scan_slash_option(scan_state,
1321  OT_NORMAL, NULL, false);
1322 
1323  if (!encoding)
1324  {
1325  /* show encoding */
1327  }
1328  else
1329  {
1330  /* set encoding */
1331  if (PQsetClientEncoding(pset.db, encoding) == -1)
1332  pg_log_error("%s: invalid encoding name or conversion procedure not found", encoding);
1333  else
1334  {
1335  /* save encoding info into psql internal data */
1338  SetVariable(pset.vars, "ENCODING",
1340  }
1341  free(encoding);
1342  }
1343  }
1344  else
1345  ignore_slash_options(scan_state);
1346 
1347  return PSQL_CMD_SKIP_LINE;
1348 }
int PQclientEncoding(const PGconn *conn)
Definition: fe-connect.c:7036
int PQsetClientEncoding(PGconn *conn, const char *encoding)
Definition: fe-connect.c:7044
int32 encoding
Definition: pg_database.h:41
#define pg_encoding_to_char
Definition: pg_wchar.h:630
VariableSpace vars
Definition: settings.h:122
int encoding
Definition: settings.h:83
int encoding
Definition: print.h:138
bool SetVariable(VariableSpace space, const char *name, const char *value)
Definition: variables.c:211

References _psqlSettings::db, _psqlSettings::encoding, encoding, printTableOpt::encoding, free, ignore_slash_options(), OT_NORMAL, pg_encoding_to_char, pg_log_error, _psqlSettings::popt, PQclientEncoding(), PQsetClientEncoding(), pset, PSQL_CMD_SKIP_LINE, psql_scan_slash_option(), SetVariable(), printQueryOpt::topt, and _psqlSettings::vars.

Referenced by exec_command().

◆ exec_command_endif()

static backslashResult exec_command_endif ( PsqlScanState  scan_state,
ConditionalStack  cstack,
PQExpBuffer  query_buf 
)
static

Definition at line 1907 of file command.c.

1909 {
1910  bool success = true;
1911 
1912  switch (conditional_stack_peek(cstack))
1913  {
1914  case IFSTATE_TRUE:
1915  case IFSTATE_ELSE_TRUE:
1916  /* Close the \if block, keeping the query text */
1917  success = conditional_stack_pop(cstack);
1918  Assert(success);
1919  break;
1920  case IFSTATE_FALSE:
1921  case IFSTATE_IGNORED:
1922  case IFSTATE_ELSE_FALSE:
1923 
1924  /*
1925  * Discard any query text added by the just-skipped branch.
1926  */
1927  discard_query_text(scan_state, cstack, query_buf);
1928 
1929  /* Close the \if block */
1930  success = conditional_stack_pop(cstack);
1931  Assert(success);
1932  break;
1933  case IFSTATE_NONE:
1934  /* no \if to end */
1935  pg_log_error("\\endif: no matching \\if");
1936  success = false;
1937  break;
1938  }
1939 
1941 }
bool conditional_stack_pop(ConditionalStack cstack)
Definition: conditional.c:69

References Assert(), conditional_stack_peek(), conditional_stack_pop(), discard_query_text(), IFSTATE_ELSE_FALSE, IFSTATE_ELSE_TRUE, IFSTATE_FALSE, IFSTATE_IGNORED, IFSTATE_NONE, IFSTATE_TRUE, pg_log_error, PSQL_CMD_ERROR, PSQL_CMD_SKIP_LINE, and success.

Referenced by exec_command().

◆ exec_command_errverbose()

static backslashResult exec_command_errverbose ( PsqlScanState  scan_state,
bool  active_branch 
)
static

Definition at line 1354 of file command.c.

1355 {
1356  if (active_branch)
1357  {
1358  if (pset.last_error_result)
1359  {
1360  char *msg;
1361 
1365  if (msg)
1366  {
1367  pg_log_error("%s", msg);
1368  PQfreemem(msg);
1369  }
1370  else
1371  puts(_("out of memory"));
1372  }
1373  else
1374  puts(_("There is no previous error."));
1375  }
1376 
1377  return PSQL_CMD_SKIP_LINE;
1378 }
char * PQresultVerboseErrorMessage(const PGresult *res, PGVerbosity verbosity, PGContextVisibility show_context)
Definition: fe-exec.c:3395
@ PQSHOW_CONTEXT_ALWAYS
Definition: libpq-fe.h:140
@ PQERRORS_VERBOSE
Definition: libpq-fe.h:132
PGresult * last_error_result
Definition: settings.h:89

References _, _psqlSettings::last_error_result, pg_log_error, PQERRORS_VERBOSE, PQfreemem(), PQresultVerboseErrorMessage(), PQSHOW_CONTEXT_ALWAYS, pset, and PSQL_CMD_SKIP_LINE.

Referenced by exec_command().

◆ exec_command_f()

static backslashResult exec_command_f ( PsqlScanState  scan_state,
bool  active_branch 
)
static

Definition at line 1384 of file command.c.

1385 {
1386  bool success = true;
1387 
1388  if (active_branch)
1389  {
1390  char *fname = psql_scan_slash_option(scan_state,
1391  OT_NORMAL, NULL, false);
1392 
1393  success = do_pset("fieldsep", fname, &pset.popt, pset.quiet);
1394  free(fname);
1395  }
1396  else
1397  ignore_slash_options(scan_state);
1398 
1400 }

References do_pset(), free, ignore_slash_options(), OT_NORMAL, _psqlSettings::popt, pset, PSQL_CMD_ERROR, PSQL_CMD_SKIP_LINE, psql_scan_slash_option(), _psqlSettings::quiet, and success.

Referenced by exec_command().

◆ exec_command_g()

static backslashResult exec_command_g ( PsqlScanState  scan_state,
bool  active_branch,
const char *  cmd 
)
static

Definition at line 1412 of file command.c.

1413 {
1415  char *fname;
1416 
1417  /*
1418  * Because the option processing for this is fairly complicated, we do it
1419  * and then decide whether the branch is active.
1420  */
1421  fname = psql_scan_slash_option(scan_state,
1422  OT_FILEPIPE, NULL, false);
1423 
1424  if (fname && fname[0] == '(')
1425  {
1426  /* Consume pset options through trailing ')' ... */
1427  status = process_command_g_options(fname + 1, scan_state,
1428  active_branch, cmd);
1429  free(fname);
1430  /* ... and again attempt to scan the filename. */
1431  fname = psql_scan_slash_option(scan_state,
1432  OT_FILEPIPE, NULL, false);
1433  }
1434 
1435  if (status == PSQL_CMD_SKIP_LINE && active_branch)
1436  {
1437  if (!fname)
1438  pset.gfname = NULL;
1439  else
1440  {
1441  expand_tilde(&fname);
1442  pset.gfname = pg_strdup(fname);
1443  }
1444  if (strcmp(cmd, "gx") == 0)
1445  {
1446  /* save settings if not done already, then force expanded=on */
1447  if (pset.gsavepopt == NULL)
1449  pset.popt.topt.expanded = 1;
1450  }
1451  status = PSQL_CMD_SEND;
1452  }
1453 
1454  free(fname);
1455 
1456  return status;
1457 }
printQueryOpt * savePsetInfo(const printQueryOpt *popt)
Definition: command.c:4922
static backslashResult process_command_g_options(char *first_option, PsqlScanState scan_state, bool active_branch, const char *cmd)
Definition: command.c:1465
@ OT_FILEPIPE
Definition: psqlscanslash.h:20
printQueryOpt * gsavepopt
Definition: settings.h:94
char * gfname
Definition: settings.h:93

References expand_tilde(), printTableOpt::expanded, free, _psqlSettings::gfname, _psqlSettings::gsavepopt, OT_FILEPIPE, pg_strdup(), _psqlSettings::popt, process_command_g_options(), pset, PSQL_CMD_SEND, PSQL_CMD_SKIP_LINE, psql_scan_slash_option(), savePsetInfo(), and printQueryOpt::topt.

Referenced by exec_command().

◆ exec_command_gdesc()

static backslashResult exec_command_gdesc ( PsqlScanState  scan_state,
bool  active_branch 
)
static

Definition at line 1540 of file command.c.

1541 {
1543 
1544  if (active_branch)
1545  {
1546  pset.gdesc_flag = true;
1547  status = PSQL_CMD_SEND;
1548  }
1549 
1550  return status;
1551 }
bool gdesc_flag
Definition: settings.h:97

References _psqlSettings::gdesc_flag, pset, PSQL_CMD_SEND, and PSQL_CMD_SKIP_LINE.

Referenced by exec_command().

◆ exec_command_getenv()

static backslashResult exec_command_getenv ( PsqlScanState  scan_state,
bool  active_branch,
const char *  cmd 
)
static

Definition at line 1557 of file command.c.

1559 {
1560  bool success = true;
1561 
1562  if (active_branch)
1563  {
1564  char *myvar = psql_scan_slash_option(scan_state,
1565  OT_NORMAL, NULL, false);
1566  char *envvar = psql_scan_slash_option(scan_state,
1567  OT_NORMAL, NULL, false);
1568 
1569  if (!myvar || !envvar)
1570  {
1571  pg_log_error("\\%s: missing required argument", cmd);
1572  success = false;
1573  }
1574  else
1575  {
1576  char *envval = getenv(envvar);
1577 
1578  if (envval && !SetVariable(pset.vars, myvar, envval))
1579  success = false;
1580  }
1581  free(myvar);
1582  free(envvar);
1583  }
1584  else
1585  ignore_slash_options(scan_state);
1586 
1588 }

References free, ignore_slash_options(), OT_NORMAL, pg_log_error, pset, PSQL_CMD_ERROR, PSQL_CMD_SKIP_LINE, psql_scan_slash_option(), SetVariable(), success, and _psqlSettings::vars.

Referenced by exec_command().

◆ exec_command_gexec()

static backslashResult exec_command_gexec ( PsqlScanState  scan_state,
bool  active_branch 
)
static

Definition at line 1594 of file command.c.

1595 {
1597 
1598  if (active_branch)
1599  {
1600  pset.gexec_flag = true;
1601  status = PSQL_CMD_SEND;
1602  }
1603 
1604  return status;
1605 }
bool gexec_flag
Definition: settings.h:98

References _psqlSettings::gexec_flag, pset, PSQL_CMD_SEND, and PSQL_CMD_SKIP_LINE.

Referenced by exec_command().

◆ exec_command_gset()

static backslashResult exec_command_gset ( PsqlScanState  scan_state,
bool  active_branch 
)
static

Definition at line 1611 of file command.c.

1612 {
1614 
1615  if (active_branch)
1616  {
1617  char *prefix = psql_scan_slash_option(scan_state,
1618  OT_NORMAL, NULL, false);
1619 
1620  if (prefix)
1621  pset.gset_prefix = prefix;
1622  else
1623  {
1624  /* we must set a non-NULL prefix to trigger storing */
1625  pset.gset_prefix = pg_strdup("");
1626  }
1627  /* gset_prefix is freed later */
1628  status = PSQL_CMD_SEND;
1629  }
1630  else
1631  ignore_slash_options(scan_state);
1632 
1633  return status;
1634 }
char * gset_prefix
Definition: settings.h:96

References _psqlSettings::gset_prefix, ignore_slash_options(), OT_NORMAL, pg_strdup(), pset, PSQL_CMD_SEND, PSQL_CMD_SKIP_LINE, and psql_scan_slash_option().

Referenced by exec_command().

◆ exec_command_help()

static backslashResult exec_command_help ( PsqlScanState  scan_state,
bool  active_branch 
)
static

Definition at line 1640 of file command.c.

1641 {
1642  if (active_branch)
1643  {
1644  char *opt = psql_scan_slash_option(scan_state,
1645  OT_WHOLE_LINE, NULL, true);
1646 
1647  helpSQL(opt, pset.popt.topt.pager);
1648  free(opt);
1649  }
1650  else
1651  ignore_slash_whole_line(scan_state);
1652 
1653  return PSQL_CMD_SKIP_LINE;
1654 }
void helpSQL(const char *topic, unsigned short int pager)

References free, helpSQL(), ignore_slash_whole_line(), OT_WHOLE_LINE, printTableOpt::pager, _psqlSettings::popt, pset, PSQL_CMD_SKIP_LINE, psql_scan_slash_option(), and printQueryOpt::topt.

Referenced by exec_command().

◆ exec_command_html()

static backslashResult exec_command_html ( PsqlScanState  scan_state,
bool  active_branch 
)
static

Definition at line 1660 of file command.c.

1661 {
1662  bool success = true;
1663 
1664  if (active_branch)
1665  {
1666  if (pset.popt.topt.format != PRINT_HTML)
1667  success = do_pset("format", "html", &pset.popt, pset.quiet);
1668  else
1669  success = do_pset("format", "aligned", &pset.popt, pset.quiet);
1670  }
1671 
1673 }

References do_pset(), printTableOpt::format, _psqlSettings::popt, PRINT_HTML, pset, PSQL_CMD_ERROR, PSQL_CMD_SKIP_LINE, _psqlSettings::quiet, success, and printQueryOpt::topt.

Referenced by exec_command().

◆ exec_command_if()

static backslashResult exec_command_if ( PsqlScanState  scan_state,
ConditionalStack  cstack,
PQExpBuffer  query_buf 
)
static

Definition at line 1720 of file command.c.

1722 {
1723  if (conditional_active(cstack))
1724  {
1725  /*
1726  * First, push a new active stack entry; this ensures that the lexer
1727  * will perform variable substitution and backtick evaluation while
1728  * scanning the expression. (That should happen anyway, since we know
1729  * we're in an active outer branch, but let's be sure.)
1730  */
1732 
1733  /* Remember current query state in case we need to restore later */
1734  save_query_text_state(scan_state, cstack, query_buf);
1735 
1736  /*
1737  * Evaluate the expression; if it's false, change to inactive state.
1738  */
1739  if (!is_true_boolean_expression(scan_state, "\\if expression"))
1741  }
1742  else
1743  {
1744  /*
1745  * We're within an inactive outer branch, so this entire \if block
1746  * will be ignored. We don't want to evaluate the expression, so push
1747  * the "ignored" stack state before scanning it.
1748  */
1750 
1751  /* Remember current query state in case we need to restore later */
1752  save_query_text_state(scan_state, cstack, query_buf);
1753 
1754  ignore_boolean_expression(scan_state);
1755  }
1756 
1757  return PSQL_CMD_SKIP_LINE;
1758 }
void conditional_stack_push(ConditionalStack cstack, ifState new_state)
Definition: conditional.c:53

References conditional_active(), conditional_stack_poke(), conditional_stack_push(), IFSTATE_FALSE, IFSTATE_IGNORED, IFSTATE_TRUE, ignore_boolean_expression(), is_true_boolean_expression(), PSQL_CMD_SKIP_LINE, and save_query_text_state().

Referenced by exec_command().

◆ exec_command_include()

static backslashResult exec_command_include ( PsqlScanState  scan_state,
bool  active_branch,
const char *  cmd 
)
static

Definition at line 1679 of file command.c.

1680 {
1681  bool success = true;
1682 
1683  if (active_branch)
1684  {
1685  char *fname = psql_scan_slash_option(scan_state,
1686  OT_NORMAL, NULL, true);
1687 
1688  if (!fname)
1689  {
1690  pg_log_error("\\%s: missing required argument", cmd);
1691  success = false;
1692  }
1693  else
1694  {
1695  bool include_relative;
1696 
1697  include_relative = (strcmp(cmd, "ir") == 0
1698  || strcmp(cmd, "include_relative") == 0);
1699  expand_tilde(&fname);
1700  success = (process_file(fname, include_relative) == EXIT_SUCCESS);
1701  free(fname);
1702  }
1703  }
1704  else
1705  ignore_slash_options(scan_state);
1706 
1708 }
int process_file(char *filename, bool use_relative_path)
Definition: command.c:4216
#define EXIT_SUCCESS
Definition: settings.h:163

References EXIT_SUCCESS, expand_tilde(), free, ignore_slash_options(), OT_NORMAL, pg_log_error, process_file(), PSQL_CMD_ERROR, PSQL_CMD_SKIP_LINE, psql_scan_slash_option(), and success.

Referenced by exec_command().

◆ exec_command_list()

static backslashResult exec_command_list ( PsqlScanState  scan_state,
bool  active_branch,
const char *  cmd 
)
static

Definition at line 1947 of file command.c.

1948 {
1949  bool success = true;
1950 
1951  if (active_branch)
1952  {
1953  char *pattern;
1954  bool show_verbose;
1955 
1956  pattern = psql_scan_slash_option(scan_state,
1957  OT_NORMAL, NULL, true);
1958 
1959  show_verbose = strchr(cmd, '+') ? true : false;
1960 
1961  success = listAllDbs(pattern, show_verbose);
1962 
1963  free(pattern);
1964  }
1965  else
1966  ignore_slash_options(scan_state);
1967 
1969 }
bool listAllDbs(const char *pattern, bool verbose)
Definition: describe.c:911

References free, ignore_slash_options(), listAllDbs(), OT_NORMAL, PSQL_CMD_ERROR, PSQL_CMD_SKIP_LINE, psql_scan_slash_option(), success, and true.

Referenced by exec_command().

◆ exec_command_lo()

static backslashResult exec_command_lo ( PsqlScanState  scan_state,
bool  active_branch,
const char *  cmd 
)
static

Definition at line 1975 of file command.c.

1976 {
1978  bool success = true;
1979 
1980  if (active_branch)
1981  {
1982  char *opt1,
1983  *opt2;
1984 
1985  opt1 = psql_scan_slash_option(scan_state,
1986  OT_NORMAL, NULL, true);
1987  opt2 = psql_scan_slash_option(scan_state,
1988  OT_NORMAL, NULL, true);
1989 
1990  if (strcmp(cmd + 3, "export") == 0)
1991  {
1992  if (!opt2)
1993  {
1994  pg_log_error("\\%s: missing required argument", cmd);
1995  success = false;
1996  }
1997  else
1998  {
1999  expand_tilde(&opt2);
2000  success = do_lo_export(opt1, opt2);
2001  }
2002  }
2003 
2004  else if (strcmp(cmd + 3, "import") == 0)
2005  {
2006  if (!opt1)
2007  {
2008  pg_log_error("\\%s: missing required argument", cmd);
2009  success = false;
2010  }
2011  else
2012  {
2013  expand_tilde(&opt1);
2014  success = do_lo_import(opt1, opt2);
2015  }
2016  }
2017 
2018  else if (strcmp(cmd + 3, "list") == 0)
2019  success = listLargeObjects(false);
2020  else if (strcmp(cmd + 3, "list+") == 0)
2021  success = listLargeObjects(true);
2022 
2023  else if (strcmp(cmd + 3, "unlink") == 0)
2024  {
2025  if (!opt1)
2026  {
2027  pg_log_error("\\%s: missing required argument", cmd);
2028  success = false;
2029  }
2030  else
2031  success = do_lo_unlink(opt1);
2032  }
2033 
2034  else
2035  status = PSQL_CMD_UNKNOWN;
2036 
2037  free(opt1);
2038  free(opt2);
2039  }
2040  else
2041  ignore_slash_options(scan_state);
2042 
2043  if (!success)
2044  status = PSQL_CMD_ERROR;
2045 
2046  return status;
2047 }
bool do_lo_export(const char *loid_arg, const char *filename_arg)
Definition: large_obj.c:142
bool do_lo_import(const char *filename_arg, const char *comment_arg)
Definition: large_obj.c:176
bool do_lo_unlink(const char *loid_arg)
Definition: large_obj.c:239

References do_lo_export(), do_lo_import(), do_lo_unlink(), expand_tilde(), free, ignore_slash_options(), listLargeObjects(), OT_NORMAL, pg_log_error, PSQL_CMD_ERROR, PSQL_CMD_SKIP_LINE, PSQL_CMD_UNKNOWN, psql_scan_slash_option(), and success.

Referenced by exec_command().

◆ exec_command_out()

static backslashResult exec_command_out ( PsqlScanState  scan_state,
bool  active_branch 
)
static

Definition at line 2053 of file command.c.

2054 {
2055  bool success = true;
2056 
2057  if (active_branch)
2058  {
2059  char *fname = psql_scan_slash_option(scan_state,
2060  OT_FILEPIPE, NULL, true);
2061 
2062  expand_tilde(&fname);
2063  success = setQFout(fname);
2064  free(fname);
2065  }
2066  else
2067  ignore_slash_filepipe(scan_state);
2068 
2070 }
bool setQFout(const char *fname)
Definition: common.c:94
static void ignore_slash_filepipe(PsqlScanState scan_state)
Definition: command.c:3131

References expand_tilde(), free, ignore_slash_filepipe(), OT_FILEPIPE, PSQL_CMD_ERROR, PSQL_CMD_SKIP_LINE, psql_scan_slash_option(), setQFout(), and success.

Referenced by exec_command().

◆ exec_command_password()

static backslashResult exec_command_password ( PsqlScanState  scan_state,
bool  active_branch 
)
static

Definition at line 2102 of file command.c.

2103 {
2104  bool success = true;
2105 
2106  if (active_branch)
2107  {
2108  char *user = psql_scan_slash_option(scan_state,
2109  OT_SQLID, NULL, true);
2110  char *pw1 = NULL;
2111  char *pw2 = NULL;
2113  PromptInterruptContext prompt_ctx;
2114 
2115  if (user == NULL)
2116  {
2117  /* By default, the command applies to CURRENT_USER */
2118  PGresult *res;
2119 
2120  res = PSQLexec("SELECT CURRENT_USER");
2121  if (!res)
2122  return PSQL_CMD_ERROR;
2123 
2124  user = pg_strdup(PQgetvalue(res, 0, 0));
2125  PQclear(res);
2126  }
2127 
2128  /* Set up to let SIGINT cancel simple_prompt_extended() */
2129  prompt_ctx.jmpbuf = sigint_interrupt_jmp;
2130  prompt_ctx.enabled = &sigint_interrupt_enabled;
2131  prompt_ctx.canceled = false;
2132 
2133  initPQExpBuffer(&buf);
2134  printfPQExpBuffer(&buf, _("Enter new password for user \"%s\": "), user);
2135 
2136  pw1 = simple_prompt_extended(buf.data, false, &prompt_ctx);
2137  if (!prompt_ctx.canceled)
2138  pw2 = simple_prompt_extended("Enter it again: ", false, &prompt_ctx);
2139 
2140  if (prompt_ctx.canceled)
2141  {
2142  /* fail silently */
2143  success = false;
2144  }
2145  else if (strcmp(pw1, pw2) != 0)
2146  {
2147  pg_log_error("Passwords didn't match.");
2148  success = false;
2149  }
2150  else
2151  {
2153 
2155  {
2157  success = false;
2158  }
2159 
2160  PQclear(res);
2161  }
2162 
2163  free(user);
2164  free(pw1);
2165  free(pw2);
2166  termPQExpBuffer(&buf);
2167  }
2168  else
2169  ignore_slash_options(scan_state);
2170 
2172 }
volatile sig_atomic_t sigint_interrupt_enabled
Definition: common.c:254
PGresult * PSQLexec(const char *query)
Definition: common.c:581
sigjmp_buf sigint_interrupt_jmp
Definition: common.c:256
PGresult * PQchangePassword(PGconn *conn, const char *user, const char *passwd)
Definition: fe-auth.c:1400
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:3371
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3836
@ PGRES_COMMAND_OK
Definition: libpq-fe.h:100
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:235
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:90
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:129
@ OT_SQLID
Definition: psqlscanslash.h:18
char * simple_prompt_extended(const char *prompt, bool echo, PromptInterruptContext *prompt_ctx)
Definition: sprompt.c:53
volatile sig_atomic_t * enabled
Definition: string.h:21

References _, buf, PromptInterruptContext::canceled, _psqlSettings::db, PromptInterruptContext::enabled, free, ignore_slash_options(), initPQExpBuffer(), PromptInterruptContext::jmpbuf, OT_SQLID, pg_log_error, pg_log_info, pg_strdup(), PGRES_COMMAND_OK, PQchangePassword(), PQclear(), PQerrorMessage(), PQgetvalue(), PQresultStatus(), printfPQExpBuffer(), pset, PSQL_CMD_ERROR, PSQL_CMD_SKIP_LINE, psql_scan_slash_option(), PSQLexec(), res, sigint_interrupt_enabled, sigint_interrupt_jmp, simple_prompt_extended(), success, termPQExpBuffer(), and user.

Referenced by exec_command().

◆ exec_command_print()

static backslashResult exec_command_print ( PsqlScanState  scan_state,
bool  active_branch,
PQExpBuffer  query_buf,
PQExpBuffer  previous_buf 
)
static

Definition at line 2076 of file command.c.

2078 {
2079  if (active_branch)
2080  {
2081  /*
2082  * We want to print the same thing \g would execute, but not to change
2083  * the query buffer state; so we can't use copy_previous_query().
2084  * Also, beware of possibility that buffer pointers are NULL.
2085  */
2086  if (query_buf && query_buf->len > 0)
2087  puts(query_buf->data);
2088  else if (previous_buf && previous_buf->len > 0)
2089  puts(previous_buf->data);
2090  else if (!pset.quiet)
2091  puts(_("Query buffer is empty."));
2092  fflush(stdout);
2093  }
2094 
2095  return PSQL_CMD_SKIP_LINE;
2096 }

References _, PQExpBufferData::data, fflush(), PQExpBufferData::len, pset, PSQL_CMD_SKIP_LINE, _psqlSettings::quiet, and generate_unaccent_rules::stdout.

Referenced by exec_command().

◆ exec_command_prompt()

static backslashResult exec_command_prompt ( PsqlScanState  scan_state,
bool  active_branch,
const char *  cmd 
)
static

Definition at line 2178 of file command.c.

2180 {
2181  bool success = true;
2182 
2183  if (active_branch)
2184  {
2185  char *opt,
2186  *prompt_text = NULL;
2187  char *arg1,
2188  *arg2;
2189 
2190  arg1 = psql_scan_slash_option(scan_state, OT_NORMAL, NULL, false);
2191  arg2 = psql_scan_slash_option(scan_state, OT_NORMAL, NULL, false);
2192 
2193  if (!arg1)
2194  {
2195  pg_log_error("\\%s: missing required argument", cmd);
2196  success = false;
2197  }
2198  else
2199  {
2200  char *result;
2201  PromptInterruptContext prompt_ctx;
2202 
2203  /* Set up to let SIGINT cancel simple_prompt_extended() */
2204  prompt_ctx.jmpbuf = sigint_interrupt_jmp;
2205  prompt_ctx.enabled = &sigint_interrupt_enabled;
2206  prompt_ctx.canceled = false;
2207 
2208  if (arg2)
2209  {
2210  prompt_text = arg1;
2211  opt = arg2;
2212  }
2213  else
2214  opt = arg1;
2215 
2216  if (!pset.inputfile)
2217  {
2218  result = simple_prompt_extended(prompt_text, true, &prompt_ctx);
2219  }
2220  else
2221  {
2222  if (prompt_text)
2223  {
2224  fputs(prompt_text, stdout);
2225  fflush(stdout);
2226  }
2227  result = gets_fromFile(stdin);
2228  if (!result)
2229  {
2230  pg_log_error("\\%s: could not read value for variable",
2231  cmd);
2232  success = false;
2233  }
2234  }
2235 
2236  if (prompt_ctx.canceled ||
2237  (result && !SetVariable(pset.vars, opt, result)))
2238  success = false;
2239 
2240  free(result);
2241  free(prompt_text);
2242  free(opt);
2243  }
2244  }
2245  else
2246  ignore_slash_options(scan_state);
2247 
2249 }
char * gets_fromFile(FILE *source)
Definition: input.c:186
char * inputfile
Definition: settings.h:114

References PromptInterruptContext::canceled, PromptInterruptContext::enabled, fflush(), free, gets_fromFile(), ignore_slash_options(), _psqlSettings::inputfile, PromptInterruptContext::jmpbuf, OT_NORMAL, pg_log_error, pset, PSQL_CMD_ERROR, PSQL_CMD_SKIP_LINE, psql_scan_slash_option(), SetVariable(), sigint_interrupt_enabled, sigint_interrupt_jmp, simple_prompt_extended(), generate_unaccent_rules::stdout, success, and _psqlSettings::vars.

Referenced by exec_command().

◆ exec_command_pset()

static backslashResult exec_command_pset ( PsqlScanState  scan_state,
bool  active_branch 
)
static

Definition at line 2255 of file command.c.

2256 {
2257  bool success = true;
2258 
2259  if (active_branch)
2260  {
2261  char *opt0 = psql_scan_slash_option(scan_state,
2262  OT_NORMAL, NULL, false);
2263  char *opt1 = psql_scan_slash_option(scan_state,
2264  OT_NORMAL, NULL, false);
2265 
2266  if (!opt0)
2267  {
2268  /* list all variables */
2269 
2270  int i;
2271  static const char *const my_list[] = {
2272  "border", "columns", "csv_fieldsep", "expanded", "fieldsep",
2273  "fieldsep_zero", "footer", "format", "linestyle", "null",
2274  "numericlocale", "pager", "pager_min_lines",
2275  "recordsep", "recordsep_zero",
2276  "tableattr", "title", "tuples_only",
2277  "unicode_border_linestyle",
2278  "unicode_column_linestyle",
2279  "unicode_header_linestyle",
2280  "xheader_width",
2281  NULL
2282  };
2283 
2284  for (i = 0; my_list[i] != NULL; i++)
2285  {
2286  char *val = pset_value_string(my_list[i], &pset.popt);
2287 
2288  printf("%-24s %s\n", my_list[i], val);
2289  free(val);
2290  }
2291 
2292  success = true;
2293  }
2294  else
2295  success = do_pset(opt0, opt1, &pset.popt, pset.quiet);
2296 
2297  free(opt0);
2298  free(opt1);
2299  }
2300  else
2301  ignore_slash_options(scan_state);
2302 
2304 }
static char * pset_value_string(const char *param, printQueryOpt *popt)
Definition: command.c:5029
long val
Definition: informix.c:670

References do_pset(), free, i, ignore_slash_options(), OT_NORMAL, _psqlSettings::popt, printf, pset, pset_value_string(), PSQL_CMD_ERROR, PSQL_CMD_SKIP_LINE, psql_scan_slash_option(), _psqlSettings::quiet, success, and val.

Referenced by exec_command().

◆ exec_command_quit()

static backslashResult exec_command_quit ( PsqlScanState  scan_state,
bool  active_branch 
)
static

Definition at line 2310 of file command.c.

2311 {
2313 
2314  if (active_branch)
2315  status = PSQL_CMD_TERMINATE;
2316 
2317  return status;
2318 }
@ PSQL_CMD_TERMINATE
Definition: command.h:20

References PSQL_CMD_SKIP_LINE, and PSQL_CMD_TERMINATE.

Referenced by exec_command().

◆ exec_command_reset()

static backslashResult exec_command_reset ( PsqlScanState  scan_state,
bool  active_branch,
PQExpBuffer  query_buf 
)
static

Definition at line 2324 of file command.c.

2326 {
2327  if (active_branch)
2328  {
2329  resetPQExpBuffer(query_buf);
2330  psql_scan_reset(scan_state);
2331  if (!pset.quiet)
2332  puts(_("Query buffer reset (cleared)."));
2333  }
2334 
2335  return PSQL_CMD_SKIP_LINE;
2336 }
void psql_scan_reset(PsqlScanState state)

References _, pset, PSQL_CMD_SKIP_LINE, psql_scan_reset(), _psqlSettings::quiet, and resetPQExpBuffer().

Referenced by exec_command().

◆ exec_command_s()

static backslashResult exec_command_s ( PsqlScanState  scan_state,
bool  active_branch 
)
static

Definition at line 2342 of file command.c.

2343 {
2344  bool success = true;
2345 
2346  if (active_branch)
2347  {
2348  char *fname = psql_scan_slash_option(scan_state,
2349  OT_NORMAL, NULL, true);
2350 
2351  expand_tilde(&fname);
2352  success = printHistory(fname, pset.popt.topt.pager);
2353  if (success && !pset.quiet && fname)
2354  printf(_("Wrote history to file \"%s\".\n"), fname);
2355  if (!fname)
2356  putchar('\n');
2357  free(fname);
2358  }
2359  else
2360  ignore_slash_options(scan_state);
2361 
2363 }
bool printHistory(const char *fname, unsigned short int pager)
Definition: input.c:494

References _, expand_tilde(), free, ignore_slash_options(), OT_NORMAL, printTableOpt::pager, _psqlSettings::popt, printf, printHistory(), pset, PSQL_CMD_ERROR, PSQL_CMD_SKIP_LINE, psql_scan_slash_option(), _psqlSettings::quiet, success, and printQueryOpt::topt.

Referenced by exec_command().

◆ exec_command_set()

static backslashResult exec_command_set ( PsqlScanState  scan_state,
bool  active_branch 
)
static

Definition at line 2369 of file command.c.

2370 {
2371  bool success = true;
2372 
2373  if (active_branch)
2374  {
2375  char *opt0 = psql_scan_slash_option(scan_state,
2376  OT_NORMAL, NULL, false);
2377 
2378  if (!opt0)
2379  {
2380  /* list all variables */
2382  success = true;
2383  }
2384  else
2385  {
2386  /*
2387  * Set variable to the concatenation of the arguments.
2388  */
2389  char *newval;
2390  char *opt;
2391 
2392  opt = psql_scan_slash_option(scan_state,
2393  OT_NORMAL, NULL, false);
2394  newval = pg_strdup(opt ? opt : "");
2395  free(opt);
2396 
2397  while ((opt = psql_scan_slash_option(scan_state,
2398  OT_NORMAL, NULL, false)))
2399  {
2400  newval = pg_realloc(newval, strlen(newval) + strlen(opt) + 1);
2401  strcat(newval, opt);
2402  free(opt);
2403  }
2404 
2405  if (!SetVariable(pset.vars, opt0, newval))
2406  success = false;
2407 
2408  free(newval);
2409  }
2410  free(opt0);
2411  }
2412  else
2413  ignore_slash_options(scan_state);
2414 
2416 }
void * pg_realloc(void *ptr, size_t size)
Definition: fe_memutils.c:65
#define newval
void PrintVariables(VariableSpace space)
Definition: variables.c:186

References free, ignore_slash_options(), newval, OT_NORMAL, pg_realloc(), pg_strdup(), PrintVariables(), pset, PSQL_CMD_ERROR, PSQL_CMD_SKIP_LINE, psql_scan_slash_option(), SetVariable(), success, and _psqlSettings::vars.

Referenced by exec_command().

◆ exec_command_setenv()

static backslashResult exec_command_setenv ( PsqlScanState  scan_state,
bool  active_branch,
const char *  cmd 
)
static

Definition at line 2422 of file command.c.

2424 {
2425  bool success = true;
2426 
2427  if (active_branch)
2428  {
2429  char *envvar = psql_scan_slash_option(scan_state,
2430  OT_NORMAL, NULL, false);
2431  char *envval = psql_scan_slash_option(scan_state,
2432  OT_NORMAL, NULL, false);
2433 
2434  if (!envvar)
2435  {
2436  pg_log_error("\\%s: missing required argument", cmd);
2437  success = false;
2438  }
2439  else if (strchr(envvar, '=') != NULL)
2440  {
2441  pg_log_error("\\%s: environment variable name must not contain \"=\"",
2442  cmd);
2443  success = false;
2444  }
2445  else if (!envval)
2446  {
2447  /* No argument - unset the environment variable */
2448  unsetenv(envvar);
2449  success = true;
2450  }
2451  else
2452  {
2453  /* Set variable to the value of the next argument */
2454  setenv(envvar, envval, 1);
2455  success = true;
2456  }
2457  free(envvar);
2458  free(envval);
2459  }
2460  else
2461  ignore_slash_options(scan_state);
2462 
2464 }
#define unsetenv(x)
Definition: win32_port.h:538
#define setenv(x, y, z)
Definition: win32_port.h:537

References free, ignore_slash_options(), OT_NORMAL, pg_log_error, PSQL_CMD_ERROR, PSQL_CMD_SKIP_LINE, psql_scan_slash_option(), setenv, success, and unsetenv.

Referenced by exec_command().

◆ exec_command_sf_sv()

static backslashResult exec_command_sf_sv ( PsqlScanState  scan_state,
bool  active_branch,
const char *  cmd,
bool  is_func 
)
static

Definition at line 2470 of file command.c.

2472 {
2474 
2475  if (active_branch)
2476  {
2477  bool show_linenumbers = (strchr(cmd, '+') != NULL);
2478  PQExpBuffer buf;
2479  char *obj_desc;
2480  Oid obj_oid = InvalidOid;
2482 
2483  buf = createPQExpBuffer();
2484  obj_desc = psql_scan_slash_option(scan_state,
2485  OT_WHOLE_LINE, NULL, true);
2486  if (!obj_desc)
2487  {
2488  if (is_func)
2489  pg_log_error("function name is required");
2490  else
2491  pg_log_error("view name is required");
2492  status = PSQL_CMD_ERROR;
2493  }
2494  else if (!lookup_object_oid(eot, obj_desc, &obj_oid))
2495  {
2496  /* error already reported */
2497  status = PSQL_CMD_ERROR;
2498  }
2499  else if (!get_create_object_cmd(eot, obj_oid, buf))
2500  {
2501  /* error already reported */
2502  status = PSQL_CMD_ERROR;
2503  }
2504  else
2505  {
2506  FILE *output;
2507  bool is_pager;
2508 
2509  /* Select output stream: stdout, pager, or file */
2510  if (pset.queryFout == stdout)
2511  {
2512  /* count lines in function to see if pager is needed */
2513  int lineno = count_lines_in_buf(buf);
2514 
2515  output = PageOutput(lineno, &(pset.popt.topt));
2516  is_pager = true;
2517  }
2518  else
2519  {
2520  /* use previously set output file, without pager */
2521  output = pset.queryFout;
2522  is_pager = false;
2523  }
2524 
2525  if (show_linenumbers)
2526  {
2527  /* add line numbers */
2528  print_with_linenumbers(output, buf->data, is_func);
2529  }
2530  else
2531  {
2532  /* just send the definition to output */
2533  fputs(buf->data, output);
2534  }
2535 
2536  if (is_pager)
2537  ClosePager(output);
2538  }
2539 
2540  free(obj_desc);
2542  }
2543  else
2544  ignore_slash_whole_line(scan_state);
2545 
2546  return status;
2547 }
static int count_lines_in_buf(PQExpBuffer buf)
Definition: command.c:5715
static void print_with_linenumbers(FILE *output, char *lines, bool is_func)
Definition: command.c:5745
void ClosePager(FILE *pagerpipe)
Definition: print.c:3141
FILE * PageOutput(int lines, const printTableOpt *topt)
Definition: print.c:3089
FILE * output
PQExpBuffer createPQExpBuffer(void)
Definition: pqexpbuffer.c:72
void destroyPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:114

References buf, ClosePager(), count_lines_in_buf(), createPQExpBuffer(), destroyPQExpBuffer(), EditableFunction, EditableView, free, get_create_object_cmd(), ignore_slash_whole_line(), InvalidOid, lookup_object_oid(), OT_WHOLE_LINE, output, PageOutput(), pg_log_error, _psqlSettings::popt, print_with_linenumbers(), pset, PSQL_CMD_ERROR, PSQL_CMD_SKIP_LINE, psql_scan_slash_option(), _psqlSettings::queryFout, generate_unaccent_rules::stdout, and printQueryOpt::topt.

Referenced by exec_command().

◆ exec_command_shell_escape()

static backslashResult exec_command_shell_escape ( PsqlScanState  scan_state,
bool  active_branch 
)
static

Definition at line 2958 of file command.c.

2959 {
2960  bool success = true;
2961 
2962  if (active_branch)
2963  {
2964  char *opt = psql_scan_slash_option(scan_state,
2965  OT_WHOLE_LINE, NULL, false);
2966 
2967  success = do_shell(opt);
2968  free(opt);
2969  }
2970  else
2971  ignore_slash_whole_line(scan_state);
2972 
2974 }
static bool do_shell(const char *command)
Definition: command.c:5118

References do_shell(), free, ignore_slash_whole_line(), OT_WHOLE_LINE, PSQL_CMD_ERROR, PSQL_CMD_SKIP_LINE, psql_scan_slash_option(), and success.

Referenced by exec_command().

◆ exec_command_slash_command_help()

static backslashResult exec_command_slash_command_help ( PsqlScanState  scan_state,
bool  active_branch 
)
static

Definition at line 2980 of file command.c.

2981 {
2982  if (active_branch)
2983  {
2984  char *opt0 = psql_scan_slash_option(scan_state,
2985  OT_NORMAL, NULL, false);
2986 
2987  if (!opt0 || strcmp(opt0, "commands") == 0)
2989  else if (strcmp(opt0, "options") == 0)
2991  else if (strcmp(opt0, "variables") == 0)
2993  else
2995 
2996  free(opt0);
2997  }
2998  else
2999  ignore_slash_options(scan_state);
3000 
3001  return PSQL_CMD_SKIP_LINE;
3002 }
void slashUsage(unsigned short int pager)
Definition: help.c:151
void helpVariables(unsigned short int pager)
static void usage(const char *progname)
Definition: vacuumlo.c:414

References free, helpVariables(), ignore_slash_options(), OT_NORMAL, printTableOpt::pager, _psqlSettings::popt, pset, PSQL_CMD_SKIP_LINE, psql_scan_slash_option(), slashUsage(), printQueryOpt::topt, and usage().

Referenced by exec_command().

◆ exec_command_t()

static backslashResult exec_command_t ( PsqlScanState  scan_state,
bool  active_branch 
)
static

Definition at line 2553 of file command.c.

2554 {
2555  bool success = true;
2556 
2557  if (active_branch)
2558  {
2559  char *opt = psql_scan_slash_option(scan_state,
2560  OT_NORMAL, NULL, true);
2561 
2562  success = do_pset("tuples_only", opt, &pset.popt, pset.quiet);
2563  free(opt);
2564  }
2565  else
2566  ignore_slash_options(scan_state);
2567 
2569 }

References do_pset(), free, ignore_slash_options(), OT_NORMAL, _psqlSettings::popt, pset, PSQL_CMD_ERROR, PSQL_CMD_SKIP_LINE, psql_scan_slash_option(), _psqlSettings::quiet, and success.

Referenced by exec_command().

◆ exec_command_T()

static backslashResult exec_command_T ( PsqlScanState  scan_state,
bool  active_branch 
)
static

Definition at line 2575 of file command.c.

2576 {
2577  bool success = true;
2578 
2579  if (active_branch)
2580  {
2581  char *value = psql_scan_slash_option(scan_state,
2582  OT_NORMAL, NULL, false);
2583 
2584  success = do_pset("tableattr", value, &pset.popt, pset.quiet);
2585  free(value);
2586  }
2587  else
2588  ignore_slash_options(scan_state);
2589 
2591 }

References do_pset(), free, ignore_slash_options(), OT_NORMAL, _psqlSettings::popt, pset, PSQL_CMD_ERROR, PSQL_CMD_SKIP_LINE, psql_scan_slash_option(), _psqlSettings::quiet, success, and value.

Referenced by exec_command().

◆ exec_command_timing()

static backslashResult exec_command_timing ( PsqlScanState  scan_state,
bool  active_branch 
)
static

Definition at line 2597 of file command.c.

2598 {
2599  bool success = true;
2600 
2601  if (active_branch)
2602  {
2603  char *opt = psql_scan_slash_option(scan_state,
2604  OT_NORMAL, NULL, false);
2605 
2606  if (opt)
2607  success = ParseVariableBool(opt, "\\timing", &pset.timing);
2608  else
2609  pset.timing = !pset.timing;
2610  if (!pset.quiet)
2611  {
2612  if (pset.timing)
2613  puts(_("Timing is on."));
2614  else
2615  puts(_("Timing is off."));
2616  }
2617  free(opt);
2618  }
2619  else
2620  ignore_slash_options(scan_state);
2621 
2623 }

References _, free, ignore_slash_options(), OT_NORMAL, ParseVariableBool(), pset, PSQL_CMD_ERROR, PSQL_CMD_SKIP_LINE, psql_scan_slash_option(), _psqlSettings::quiet, success, and _psqlSettings::timing.

Referenced by exec_command().

◆ exec_command_unset()

static backslashResult exec_command_unset ( PsqlScanState  scan_state,
bool  active_branch,
const char *  cmd 
)
static

Definition at line 2629 of file command.c.

2631 {
2632  bool success = true;
2633 
2634  if (active_branch)
2635  {
2636  char *opt = psql_scan_slash_option(scan_state,
2637  OT_NORMAL, NULL, false);
2638 
2639  if (!opt)
2640  {
2641  pg_log_error("\\%s: missing required argument", cmd);
2642  success = false;
2643  }
2644  else if (!SetVariable(pset.vars, opt, NULL))
2645  success = false;
2646 
2647  free(opt);
2648  }
2649  else
2650  ignore_slash_options(scan_state);
2651 
2653 }

References free, ignore_slash_options(), OT_NORMAL, pg_log_error, pset, PSQL_CMD_ERROR, PSQL_CMD_SKIP_LINE, psql_scan_slash_option(), SetVariable(), success, and _psqlSettings::vars.

Referenced by exec_command().

◆ exec_command_watch()

static backslashResult exec_command_watch ( PsqlScanState  scan_state,
bool  active_branch,
PQExpBuffer  query_buf,
PQExpBuffer  previous_buf 
)
static

Definition at line 2761 of file command.c.

2763 {
2764  bool success = true;
2765 
2766  if (active_branch)
2767  {
2768  bool have_sleep = false;
2769  bool have_iter = false;
2770  bool have_min_rows = false;
2771  double sleep = 2;
2772  int iter = 0;
2773  int min_rows = 0;
2774 
2775  /*
2776  * Parse arguments. We allow either an unlabeled interval or
2777  * "name=value", where name is from the set ('i', 'interval', 'c',
2778  * 'count', 'm', 'min_rows').
2779  */
2780  while (success)
2781  {
2782  char *opt = psql_scan_slash_option(scan_state,
2783  OT_NORMAL, NULL, true);
2784  char *valptr;
2785  char *opt_end;
2786 
2787  if (!opt)
2788  break; /* no more arguments */
2789 
2790  valptr = strchr(opt, '=');
2791  if (valptr)
2792  {
2793  /* Labeled argument */
2794  valptr++;
2795  if (strncmp("i=", opt, strlen("i=")) == 0 ||
2796  strncmp("interval=", opt, strlen("interval=")) == 0)
2797  {
2798  if (have_sleep)
2799  {
2800  pg_log_error("\\watch: interval value is specified more than once");
2801  success = false;
2802  }
2803  else
2804  {
2805  have_sleep = true;
2806  errno = 0;
2807  sleep = strtod(valptr, &opt_end);
2808  if (sleep < 0 || *opt_end || errno == ERANGE)
2809  {
2810  pg_log_error("\\watch: incorrect interval value \"%s\"", valptr);
2811  success = false;
2812  }
2813  }
2814  }
2815  else if (strncmp("c=", opt, strlen("c=")) == 0 ||
2816  strncmp("count=", opt, strlen("count=")) == 0)
2817  {
2818  if (have_iter)
2819  {
2820  pg_log_error("\\watch: iteration count is specified more than once");
2821  success = false;
2822  }
2823  else
2824  {
2825  have_iter = true;
2826  errno = 0;
2827  iter = strtoint(valptr, &opt_end, 10);
2828  if (iter <= 0 || *opt_end || errno == ERANGE)
2829  {
2830  pg_log_error("\\watch: incorrect iteration count \"%s\"", valptr);
2831  success = false;
2832  }
2833  }
2834  }
2835  else if (strncmp("m=", opt, strlen("m=")) == 0 ||
2836  strncmp("min_rows=", opt, strlen("min_rows=")) == 0)
2837  {
2838  if (have_min_rows)
2839  {
2840  pg_log_error("\\watch: minimum row count specified more than once");
2841  success = false;
2842  }
2843  else
2844  {
2845  have_min_rows = true;
2846  errno = 0;
2847  min_rows = strtoint(valptr, &opt_end, 10);
2848  if (min_rows <= 0 || *opt_end || errno == ERANGE)
2849  {
2850  pg_log_error("\\watch: incorrect minimum row count \"%s\"", valptr);
2851  success = false;
2852  }
2853  }
2854  }
2855  else
2856  {
2857  pg_log_error("\\watch: unrecognized parameter \"%s\"", opt);
2858  success = false;
2859  }
2860  }
2861  else
2862  {
2863  /* Unlabeled argument: take it as interval */
2864  if (have_sleep)
2865  {
2866  pg_log_error("\\watch: interval value is specified more than once");
2867  success = false;
2868  }
2869  else
2870  {
2871  have_sleep = true;
2872  errno = 0;
2873  sleep = strtod(opt, &opt_end);
2874  if (sleep < 0 || *opt_end || errno == ERANGE)
2875  {
2876  pg_log_error("\\watch: incorrect interval value \"%s\"", opt);
2877  success = false;
2878  }
2879  }
2880  }
2881 
2882  free(opt);
2883  }
2884 
2885  /* If we parsed arguments successfully, do the command */
2886  if (success)
2887  {
2888  /* If query_buf is empty, recall and execute previous query */
2889  (void) copy_previous_query(query_buf, previous_buf);
2890 
2891  success = do_watch(query_buf, sleep, iter, min_rows);
2892  }
2893 
2894  /* Reset the query buffer as though for \r */
2895  resetPQExpBuffer(query_buf);
2896  psql_scan_reset(scan_state);
2897  }
2898  else
2899  ignore_slash_options(scan_state);
2900 
2902 }
static bool do_watch(PQExpBuffer query_buf, double sleep, int iter, int min_rows)
Definition: command.c:5165
int strtoint(const char *pg_restrict str, char **pg_restrict endptr, int base)
Definition: string.c:51

References copy_previous_query(), do_watch(), free, ignore_slash_options(), OT_NORMAL, pg_log_error, PSQL_CMD_ERROR, PSQL_CMD_SKIP_LINE, psql_scan_reset(), psql_scan_slash_option(), resetPQExpBuffer(), strtoint(), and success.

Referenced by exec_command().

◆ exec_command_write()

static backslashResult exec_command_write ( PsqlScanState  scan_state,
bool  active_branch,
const char *  cmd,
PQExpBuffer  query_buf,
PQExpBuffer  previous_buf 
)
static

Definition at line 2659 of file command.c.

2662 {
2664 
2665  if (active_branch)
2666  {
2667  char *fname = psql_scan_slash_option(scan_state,
2668  OT_FILEPIPE, NULL, true);
2669  FILE *fd = NULL;
2670  bool is_pipe = false;
2671 
2672  if (!query_buf)
2673  {
2674  pg_log_error("no query buffer");
2675  status = PSQL_CMD_ERROR;
2676  }
2677  else
2678  {
2679  if (!fname)
2680  {
2681  pg_log_error("\\%s: missing required argument", cmd);
2682  status = PSQL_CMD_ERROR;
2683  }
2684  else
2685  {
2686  expand_tilde(&fname);
2687  if (fname[0] == '|')
2688  {
2689  is_pipe = true;
2690  fflush(NULL);
2692  fd = popen(&fname[1], "w");
2693  }
2694  else
2695  {
2696  canonicalize_path(fname);
2697  fd = fopen(fname, "w");
2698  }
2699  if (!fd)
2700  {
2701  pg_log_error("%s: %m", fname);
2702  status = PSQL_CMD_ERROR;
2703  }
2704  }
2705  }
2706 
2707  if (fd)
2708  {
2709  int result;
2710 
2711  /*
2712  * We want to print the same thing \g would execute, but not to
2713  * change the query buffer state; so we can't use
2714  * copy_previous_query(). Also, beware of possibility that buffer
2715  * pointers are NULL.
2716  */
2717  if (query_buf && query_buf->len > 0)
2718  fprintf(fd, "%s\n", query_buf->data);
2719  else if (previous_buf && previous_buf->len > 0)
2720  fprintf(fd, "%s\n", previous_buf->data);
2721 
2722  if (is_pipe)
2723  {
2724  result = pclose(fd);
2725 
2726  if (result != 0)
2727  {
2728  pg_log_error("%s: %s", fname, wait_result_to_str(result));
2729  status = PSQL_CMD_ERROR;
2730  }
2731  SetShellResultVariables(result);
2732  }
2733  else
2734  {
2735  result = fclose(fd);
2736 
2737  if (result == EOF)
2738  {
2739  pg_log_error("%s: %m", fname);
2740  status = PSQL_CMD_ERROR;
2741  }
2742  }
2743  }
2744 
2745  if (is_pipe)
2747 
2748  free(fname);
2749  }
2750  else
2751  ignore_slash_filepipe(scan_state);
2752 
2753  return status;
2754 }
char * wait_result_to_str(int exitstatus)
Definition: wait_error.c:33

References canonicalize_path(), PQExpBufferData::data, disable_sigpipe_trap(), expand_tilde(), fd(), fflush(), fprintf, free, ignore_slash_filepipe(), PQExpBufferData::len, OT_FILEPIPE, pg_log_error, PSQL_CMD_ERROR, PSQL_CMD_SKIP_LINE, psql_scan_slash_option(), restore_sigpipe_trap(), SetShellResultVariables(), and wait_result_to_str().

Referenced by exec_command().

◆ exec_command_x()

static backslashResult exec_command_x ( PsqlScanState  scan_state,
bool  active_branch 
)
static

Definition at line 2908 of file command.c.

2909 {
2910  bool success = true;
2911 
2912  if (active_branch)
2913  {
2914  char *opt = psql_scan_slash_option(scan_state,
2915  OT_NORMAL, NULL, true);
2916 
2917  success = do_pset("expanded", opt, &pset.popt, pset.quiet);
2918  free(opt);
2919  }
2920  else
2921  ignore_slash_options(scan_state);
2922 
2924 }

References do_pset(), free, ignore_slash_options(), OT_NORMAL, _psqlSettings::popt, pset, PSQL_CMD_ERROR, PSQL_CMD_SKIP_LINE, psql_scan_slash_option(), _psqlSettings::quiet, and success.

Referenced by exec_command().

◆ exec_command_z()

static backslashResult exec_command_z ( PsqlScanState  scan_state,
bool  active_branch,
const char *  cmd 
)
static

Definition at line 2930 of file command.c.

2931 {
2932  bool success = true;
2933 
2934  if (active_branch)
2935  {
2936  char *pattern;
2937  bool show_system;
2938 
2939  pattern = psql_scan_slash_option(scan_state,
2940  OT_NORMAL, NULL, true);
2941 
2942  show_system = strchr(cmd, 'S') ? true : false;
2943 
2944  success = permissionsList(pattern, show_system);
2945 
2946  free(pattern);
2947  }
2948  else
2949  ignore_slash_options(scan_state);
2950 
2952 }

References free, ignore_slash_options(), OT_NORMAL, permissionsList(), PSQL_CMD_ERROR, PSQL_CMD_SKIP_LINE, psql_scan_slash_option(), success, and true.

Referenced by exec_command().

◆ gather_boolean_expression()

static PQExpBuffer gather_boolean_expression ( PsqlScanState  scan_state)
static

Definition at line 3051 of file command.c.

3052 {
3053  PQExpBuffer exp_buf = createPQExpBuffer();
3054  int num_options = 0;
3055  char *value;
3056 
3057  /* collect all arguments for the conditional command into exp_buf */
3058  while ((value = psql_scan_slash_option(scan_state,
3059  OT_NORMAL, NULL, false)) != NULL)
3060  {
3061  /* add spaces between tokens */
3062  if (num_options > 0)
3063  appendPQExpBufferChar(exp_buf, ' ');
3064  appendPQExpBufferStr(exp_buf, value);
3065  num_options++;
3066  free(value);
3067  }
3068 
3069  return exp_buf;
3070 }

References appendPQExpBufferChar(), appendPQExpBufferStr(), createPQExpBuffer(), free, OT_NORMAL, psql_scan_slash_option(), and value.

Referenced by ignore_boolean_expression(), and is_true_boolean_expression().

◆ get_create_object_cmd()

static bool get_create_object_cmd ( EditableObjectType  obj_type,
Oid  oid,
PQExpBuffer  buf 
)
static

Definition at line 5497 of file command.c.

5499 {
5500  bool result = true;
5501  PQExpBuffer query = createPQExpBuffer();
5502  PGresult *res;
5503 
5504  switch (obj_type)
5505  {
5506  case EditableFunction:
5507  printfPQExpBuffer(query,
5508  "SELECT pg_catalog.pg_get_functiondef(%u)",
5509  oid);
5510  break;
5511 
5512  case EditableView:
5513 
5514  /*
5515  * pg_get_viewdef() just prints the query, so we must prepend
5516  * CREATE for ourselves. We must fully qualify the view name to
5517  * ensure the right view gets replaced. Also, check relation kind
5518  * to be sure it's a view.
5519  *
5520  * Starting with PG 9.4, views may have WITH [LOCAL|CASCADED]
5521  * CHECK OPTION. These are not part of the view definition
5522  * returned by pg_get_viewdef() and so need to be retrieved
5523  * separately. Materialized views (introduced in 9.3) may have
5524  * arbitrary storage parameter reloptions.
5525  */
5526  if (pset.sversion >= 90400)
5527  {
5528  printfPQExpBuffer(query,
5529  "SELECT nspname, relname, relkind, "
5530  "pg_catalog.pg_get_viewdef(c.oid, true), "
5531  "pg_catalog.array_remove(pg_catalog.array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, "
5532  "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text "
5533  "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption "
5534  "FROM pg_catalog.pg_class c "
5535  "LEFT JOIN pg_catalog.pg_namespace n "
5536  "ON c.relnamespace = n.oid WHERE c.oid = %u",
5537  oid);
5538  }
5539  else
5540  {
5541  printfPQExpBuffer(query,
5542  "SELECT nspname, relname, relkind, "
5543  "pg_catalog.pg_get_viewdef(c.oid, true), "
5544  "c.reloptions AS reloptions, "
5545  "NULL AS checkoption "
5546  "FROM pg_catalog.pg_class c "
5547  "LEFT JOIN pg_catalog.pg_namespace n "
5548  "ON c.relnamespace = n.oid WHERE c.oid = %u",
5549  oid);
5550  }
5551  break;
5552  }
5553 
5554  if (!echo_hidden_command(query->data))
5555  {
5556  destroyPQExpBuffer(query);
5557  return false;
5558  }
5559  res = PQexec(pset.db, query->data);
5560  if (PQresultStatus(res) == PGRES_TUPLES_OK && PQntuples(res) == 1)
5561  {
5563  switch (obj_type)
5564  {
5565  case EditableFunction:
5567  break;
5568 
5569  case EditableView:
5570  {
5571  char *nspname = PQgetvalue(res, 0, 0);
5572  char *relname = PQgetvalue(res, 0, 1);
5573  char *relkind = PQgetvalue(res, 0, 2);
5574  char *viewdef = PQgetvalue(res, 0, 3);
5575  char *reloptions = PQgetvalue(res, 0, 4);
5576  char *checkoption = PQgetvalue(res, 0, 5);
5577 
5578  /*
5579  * If the backend ever supports CREATE OR REPLACE
5580  * MATERIALIZED VIEW, allow that here; but as of today it
5581  * does not, so editing a matview definition in this way
5582  * is impossible.
5583  */
5584  switch (relkind[0])
5585  {
5586 #ifdef NOT_USED
5587  case RELKIND_MATVIEW:
5588  appendPQExpBufferStr(buf, "CREATE OR REPLACE MATERIALIZED VIEW ");
5589  break;
5590 #endif
5591  case RELKIND_VIEW:
5592  appendPQExpBufferStr(buf, "CREATE OR REPLACE VIEW ");
5593  break;
5594  default:
5595  pg_log_error("\"%s.%s\" is not a view",
5596  nspname, relname);
5597  result = false;
5598  break;
5599  }
5600  appendPQExpBuffer(buf, "%s.", fmtId(nspname));
5602 
5603  /* reloptions, if not an empty array "{}" */
5604  if (reloptions != NULL && strlen(reloptions) > 2)
5605  {
5606  appendPQExpBufferStr(buf, "\n WITH (");
5607  if (!appendReloptionsArray(buf, reloptions, "",
5608  pset.encoding,
5609  standard_strings()))
5610  {
5611  pg_log_error("could not parse reloptions array");
5612  result = false;
5613  }
5614  appendPQExpBufferChar(buf, ')');
5615  }
5616 
5617  /* View definition from pg_get_viewdef (a SELECT query) */
5618  appendPQExpBuffer(buf, " AS\n%s", viewdef);
5619 
5620  /* Get rid of the semicolon that pg_get_viewdef appends */
5621  if (buf->len > 0 && buf->data[buf->len - 1] == ';')
5622  buf->data[--(buf->len)] = '\0';
5623 
5624  /* WITH [LOCAL|CASCADED] CHECK OPTION */
5625  if (checkoption && checkoption[0] != '\0')
5626  appendPQExpBuffer(buf, "\n WITH %s CHECK OPTION",
5627  checkoption);
5628  }
5629  break;
5630  }
5631  /* Make sure result ends with a newline */
5632  if (buf->len > 0 && buf->data[buf->len - 1] != '\n')
5633  appendPQExpBufferChar(buf, '\n');
5634  }
5635  else
5636  {
5638  result = false;
5639  }
5640 
5641  PQclear(res);
5642  destroyPQExpBuffer(query);
5643 
5644  return result;
5645 }
bool standard_strings(void)
Definition: common.c:2311
static bool echo_hidden_command(const char *query)
Definition: command.c:5405
static void minimal_error_message(PGresult *res)
Definition: command.c:5787
int PQntuples(const PGresult *res)
Definition: fe-exec.c:3441
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:2224
@ PGRES_TUPLES_OK
Definition: libpq-fe.h:103
NameData relname
Definition: pg_class.h:38
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:265
const char * fmtId(const char *rawid)
Definition: string_utils.c:64
bool appendReloptionsArray(PQExpBuffer buffer, const char *reloptions, const char *prefix, int encoding, bool std_strings)
Definition: string_utils.c:804

References appendPQExpBuffer(), appendPQExpBufferChar(), appendPQExpBufferStr(), appendReloptionsArray(), buf, createPQExpBuffer(), PQExpBufferData::data, _psqlSettings::db, destroyPQExpBuffer(), echo_hidden_command(), EditableFunction, EditableView, _psqlSettings::encoding, fmtId(), minimal_error_message(), pg_log_error, PGRES_TUPLES_OK, PQclear(), PQexec(), PQgetvalue(), PQntuples(), PQresultStatus(), printfPQExpBuffer(), pset, relname, res, resetPQExpBuffer(), standard_strings(), and _psqlSettings::sversion.

Referenced by exec_command_ef_ev(), and exec_command_sf_sv().

◆ HandleSlashCmds()

backslashResult HandleSlashCmds ( PsqlScanState  scan_state,
ConditionalStack  cstack,
PQExpBuffer  query_buf,
PQExpBuffer  previous_buf 
)

Definition at line 214 of file command.c.

218 {
219  backslashResult status;
220  char *cmd;
221  char *arg;
222 
223  Assert(scan_state != NULL);
224  Assert(cstack != NULL);
225 
226  /* Parse off the command name */
227  cmd = psql_scan_slash_command(scan_state);
228 
229  /* And try to execute it */
230  status = exec_command(cmd, scan_state, cstack, query_buf, previous_buf);
231 
232  if (status == PSQL_CMD_UNKNOWN)
233  {
234  pg_log_error("invalid command \\%s", cmd);
236  pg_log_error_hint("Try \\? for help.");
237  status = PSQL_CMD_ERROR;
238  }
239 
240  if (status != PSQL_CMD_ERROR)
241  {
242  /*
243  * Eat any remaining arguments after a valid command. We want to
244  * suppress evaluation of backticks in this situation, so transiently
245  * push an inactive conditional-stack entry.
246  */
247  bool active_branch = conditional_active(cstack);
248 
250  while ((arg = psql_scan_slash_option(scan_state,
251  OT_NORMAL, NULL, false)))
252  {
253  if (active_branch)
254  pg_log_warning("\\%s: extra argument \"%s\" ignored", cmd, arg);
255  free(arg);
256  }
257  conditional_stack_pop(cstack);
258  }
259  else
260  {
261  /* silently throw away rest of line after an erroneous command */
262  while ((arg = psql_scan_slash_option(scan_state,
263  OT_WHOLE_LINE, NULL, false)))
264  free(arg);
265  }
266 
267  /* if there is a trailing \\, swallow it */
268  psql_scan_slash_command_end(scan_state);
269 
270  free(cmd);
271 
272  /* some commands write to queryFout, so make sure output is sent */
274 
275  return status;
276 }
static backslashResult exec_command(const char *cmd, PsqlScanState scan_state, ConditionalStack cstack, PQExpBuffer query_buf, PQExpBuffer previous_buf)
Definition: command.c:287
#define pg_log_error_hint(...)
Definition: logging.h:112
void * arg
char * psql_scan_slash_command(PsqlScanState state)
void psql_scan_slash_command_end(PsqlScanState state)

References arg, Assert(), conditional_active(), conditional_stack_pop(), conditional_stack_push(), _psqlSettings::cur_cmd_interactive, exec_command(), fflush(), free, IFSTATE_IGNORED, OT_NORMAL, OT_WHOLE_LINE, pg_log_error, pg_log_error_hint, pg_log_warning, pset, PSQL_CMD_ERROR, PSQL_CMD_UNKNOWN, psql_scan_slash_command(), psql_scan_slash_command_end(), psql_scan_slash_option(), and _psqlSettings::queryFout.

Referenced by main(), and MainLoop().

◆ ignore_boolean_expression()

static void ignore_boolean_expression ( PsqlScanState  scan_state)
static

Definition at line 3098 of file command.c.

3099 {
3101 
3103 }
static PQExpBuffer gather_boolean_expression(PsqlScanState scan_state)
Definition: command.c:3051

References buf, destroyPQExpBuffer(), and gather_boolean_expression().

Referenced by exec_command_elif(), and exec_command_if().

◆ ignore_slash_filepipe()

static void ignore_slash_filepipe ( PsqlScanState  scan_state)
static

Definition at line 3131 of file command.c.

3132 {
3133  char *arg = psql_scan_slash_option(scan_state,
3134  OT_FILEPIPE, NULL, false);
3135 
3136  free(arg);
3137 }

References arg, free, OT_FILEPIPE, and psql_scan_slash_option().

Referenced by exec_command_out(), and exec_command_write().

◆ ignore_slash_options()

◆ ignore_slash_whole_line()

static void ignore_slash_whole_line ( PsqlScanState  scan_state)
static

Definition at line 3151 of file command.c.

3152 {
3153  char *arg = psql_scan_slash_option(scan_state,
3154  OT_WHOLE_LINE, NULL, false);
3155 
3156  free(arg);
3157 }

References arg, free, OT_WHOLE_LINE, and psql_scan_slash_option().

Referenced by exec_command_copy(), exec_command_ef_ev(), exec_command_help(), exec_command_sf_sv(), and exec_command_shell_escape().

◆ is_branching_command()

static bool is_branching_command ( const char *  cmd)
static

Definition at line 3163 of file command.c.

3164 {
3165  return (strcmp(cmd, "if") == 0 ||
3166  strcmp(cmd, "elif") == 0 ||
3167  strcmp(cmd, "else") == 0 ||
3168  strcmp(cmd, "endif") == 0);
3169 }

Referenced by exec_command().

◆ is_true_boolean_expression()

static bool is_true_boolean_expression ( PsqlScanState  scan_state,
const char *  name 
)
static

Definition at line 3081 of file command.c.

3082 {
3084  bool value = false;
3085  bool success = ParseVariableBool(buf->data, name, &value);
3086 
3088  return success && value;
3089 }

References buf, destroyPQExpBuffer(), gather_boolean_expression(), name, ParseVariableBool(), success, and value.

Referenced by exec_command_elif(), and exec_command_if().

◆ lookup_object_oid()

static bool lookup_object_oid ( EditableObjectType  obj_type,
const char *  desc,
Oid obj_oid 
)
static

Definition at line 5437 of file command.c.

5439 {
5440  bool result = true;
5441  PQExpBuffer query = createPQExpBuffer();
5442  PGresult *res;
5443 
5444  switch (obj_type)
5445  {
5446  case EditableFunction:
5447 
5448  /*
5449  * We have a function description, e.g. "x" or "x(int)". Issue a
5450  * query to retrieve the function's OID using a cast to regproc or
5451  * regprocedure (as appropriate).
5452  */
5453  appendPQExpBufferStr(query, "SELECT ");
5454  appendStringLiteralConn(query, desc, pset.db);
5455  appendPQExpBuffer(query, "::pg_catalog.%s::pg_catalog.oid",
5456  strchr(desc, '(') ? "regprocedure" : "regproc");
5457  break;
5458 
5459  case EditableView:
5460 
5461  /*
5462  * Convert view name (possibly schema-qualified) to OID. Note:
5463  * this code doesn't check if the relation is actually a view.
5464  * We'll detect that in get_create_object_cmd().
5465  */
5466  appendPQExpBufferStr(query, "SELECT ");
5467  appendStringLiteralConn(query, desc, pset.db);
5468  appendPQExpBufferStr(query, "::pg_catalog.regclass::pg_catalog.oid");
5469  break;
5470  }
5471 
5472  if (!echo_hidden_command(query->data))
5473  {
5474  destroyPQExpBuffer(query);
5475  return false;
5476  }
5477  res = PQexec(pset.db, query->data);
5478  if (PQresultStatus(res) == PGRES_TUPLES_OK && PQntuples(res) == 1)
5479  *obj_oid = atooid(PQgetvalue(res, 0, 0));
5480  else
5481  {
5483  result = false;
5484  }
5485 
5486  PQclear(res);
5487  destroyPQExpBuffer(query);
5488 
5489  return result;
5490 }
#define atooid(x)
Definition: postgres_ext.h:42
void appendStringLiteralConn(PQExpBuffer buf, const char *str, PGconn *conn)
Definition: string_utils.c:293

References appendPQExpBuffer(), appendPQExpBufferStr(), appendStringLiteralConn(), atooid, createPQExpBuffer(), PQExpBufferData::data, _psqlSettings::db, destroyPQExpBuffer(), echo_hidden_command(), EditableFunction, EditableView, minimal_error_message(), PGRES_TUPLES_OK, PQclear(), PQexec(), PQgetvalue(), PQntuples(), PQresultStatus(), pset, and res.

Referenced by exec_command_ef_ev(), and exec_command_sf_sv().

◆ minimal_error_message()

static void minimal_error_message ( PGresult res)
static

Definition at line 5787 of file command.c.

5788 {
5789  PQExpBuffer msg;
5790  const char *fld;
5791 
5792  msg = createPQExpBuffer();
5793 
5795  if (fld)
5796  printfPQExpBuffer(msg, "%s: ", fld);
5797  else
5798  printfPQExpBuffer(msg, "ERROR: ");
5800  if (fld)
5801  appendPQExpBufferStr(msg, fld);
5802  else
5803  appendPQExpBufferStr(msg, "(not available)");
5804  appendPQExpBufferChar(msg, '\n');
5805 
5806  pg_log_error("%s", msg->data);
5807 
5808  destroyPQExpBuffer(msg);
5809 }
char * PQresultErrorField(const PGresult *res, int fieldcode)
Definition: fe-exec.c:3426
#define PG_DIAG_MESSAGE_PRIMARY
Definition: postgres_ext.h:57
#define PG_DIAG_SEVERITY
Definition: postgres_ext.h:54

References appendPQExpBufferChar(), appendPQExpBufferStr(), createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), PG_DIAG_MESSAGE_PRIMARY, PG_DIAG_SEVERITY, pg_log_error, PQresultErrorField(), printfPQExpBuffer(), and res.

Referenced by get_create_object_cmd(), and lookup_object_oid().

◆ param_is_newly_set()

static bool param_is_newly_set ( const char *  old_val,
const char *  new_val 
)
static

Definition at line 3271 of file command.c.

3272 {
3273  if (new_val == NULL)
3274  return false;
3275 
3276  if (old_val == NULL || strcmp(old_val, new_val) != 0)
3277  return true;
3278 
3279  return false;
3280 }

Referenced by do_connect().

◆ print_with_linenumbers()

static void print_with_linenumbers ( FILE *  output,
char *  lines,
bool  is_func 
)
static

Definition at line 5745 of file command.c.

5746 {
5747  bool in_header = is_func;
5748  int lineno = 0;
5749 
5750  while (*lines != '\0')
5751  {
5752  char *eol;
5753 
5754  if (in_header &&
5755  (strncmp(lines, "AS ", 3) == 0 ||
5756  strncmp(lines, "BEGIN ", 6) == 0 ||
5757  strncmp(lines, "RETURN ", 7) == 0))
5758  in_header = false;
5759 
5760  /* increment lineno only for body's lines */
5761  if (!in_header)
5762  lineno++;
5763 
5764  /* find and mark end of current line */
5765  eol = strchr(lines, '\n');
5766  if (eol != NULL)
5767  *eol = '\0';
5768 
5769  /* show current line as appropriate */
5770  if (in_header)
5771  fprintf(output, " %s\n", lines);
5772  else
5773  fprintf(output, "%-7d %s\n", lineno, lines);
5774 
5775  /* advance to next line, if any */
5776  if (eol == NULL)
5777  break;
5778  lines = ++eol;
5779  }
5780 }

References fprintf, and output.

Referenced by exec_command_sf_sv().

◆ printGSSInfo()

static void printGSSInfo ( void  )
static

Definition at line 3837 of file command.c.

3838 {
3839  if (!PQgssEncInUse(pset.db))
3840  return; /* no GSSAPI encryption in use */
3841 
3842  printf(_("GSSAPI-encrypted connection\n"));
3843 }
int PQgssEncInUse(PGconn *conn)

References _, _psqlSettings::db, PQgssEncInUse(), printf, and pset.

Referenced by connection_warnings(), and exec_command_conninfo().

◆ printPsetInfo()

static bool printPsetInfo ( const char *  param,
printQueryOpt popt 
)
static

Definition at line 4722 of file command.c.

4723 {
4724  Assert(param != NULL);
4725 
4726  /* show border style/width */
4727  if (strcmp(param, "border") == 0)
4728  printf(_("Border style is %d.\n"), popt->topt.border);
4729 
4730  /* show the target width for the wrapped format */
4731  else if (strcmp(param, "columns") == 0)
4732  {
4733  if (!popt->topt.columns)
4734  printf(_("Target width is unset.\n"));
4735  else
4736  printf(_("Target width is %d.\n"), popt->topt.columns);
4737  }
4738 
4739  /* show expanded/vertical mode */
4740  else if (strcmp(param, "x") == 0 || strcmp(param, "expanded") == 0 || strcmp(param, "vertical") == 0)
4741  {
4742  if (popt->topt.expanded == 1)
4743  printf(_("Expanded display is on.\n"));
4744  else if (popt->topt.expanded == 2)
4745  printf(_("Expanded display is used automatically.\n"));
4746  else
4747  printf(_("Expanded display is off.\n"));
4748  }
4749 
4750  /* show xheader width value */
4751  else if (strcmp(param, "xheader_width") == 0)
4752  {
4754  printf(_("Expanded header width is \"%s\".\n"), "full");
4756  printf(_("Expanded header width is \"%s\".\n"), "column");
4758  printf(_("Expanded header width is \"%s\".\n"), "page");
4760  printf(_("Expanded header width is %d.\n"), popt->topt.expanded_header_exact_width);
4761  }
4762 
4763  /* show field separator for CSV format */
4764  else if (strcmp(param, "csv_fieldsep") == 0)
4765  {
4766  printf(_("Field separator for CSV is \"%s\".\n"),
4767  popt->topt.csvFieldSep);
4768  }
4769 
4770  /* show field separator for unaligned text */
4771  else if (strcmp(param, "fieldsep") == 0)
4772  {
4773  if (popt->topt.fieldSep.separator_zero)
4774  printf(_("Field separator is zero byte.\n"));
4775  else
4776  printf(_("Field separator is \"%s\".\n"),
4777  popt->topt.fieldSep.separator);
4778  }
4779 
4780  else if (strcmp(param, "fieldsep_zero") == 0)
4781  {
4782  printf(_("Field separator is zero byte.\n"));
4783  }
4784 
4785  /* show disable "(x rows)" footer */
4786  else if (strcmp(param, "footer") == 0)
4787  {
4788  if (popt->topt.default_footer)
4789  printf(_("Default footer is on.\n"));
4790  else
4791  printf(_("Default footer is off.\n"));
4792  }
4793 
4794  /* show format */
4795  else if (strcmp(param, "format") == 0)
4796  {
4797  printf(_("Output format is %s.\n"), _align2string(popt->topt.format));
4798  }
4799 
4800  /* show table line style */
4801  else if (strcmp(param, "linestyle") == 0)
4802  {
4803  printf(_("Line style is %s.\n"),
4804  get_line_style(&popt->topt)->name);
4805  }
4806 
4807  /* show null display */
4808  else if (strcmp(param, "null") == 0)
4809  {
4810  printf(_("Null display is \"%s\".\n"),
4811  popt->nullPrint ? popt->nullPrint : "");
4812  }
4813 
4814  /* show locale-aware numeric output */
4815  else if (strcmp(param, "numericlocale") == 0)
4816  {
4817  if (popt->topt.numericLocale)
4818  printf(_("Locale-adjusted numeric output is on.\n"));
4819  else
4820  printf(_("Locale-adjusted numeric output is off.\n"));
4821  }
4822 
4823  /* show toggle use of pager */
4824  else if (strcmp(param, "pager") == 0)
4825  {
4826  if (popt->topt.pager == 1)
4827  printf(_("Pager is used for long output.\n"));
4828  else if (popt->topt.pager == 2)
4829  printf(_("Pager is always used.\n"));
4830  else
4831  printf(_("Pager usage is off.\n"));
4832  }
4833 
4834  /* show minimum lines for pager use */
4835  else if (strcmp(param, "pager_min_lines") == 0)
4836  {
4837  printf(ngettext("Pager won't be used for less than %d line.\n",
4838  "Pager won't be used for less than %d lines.\n",
4839  popt->topt.pager_min_lines),
4840  popt->topt.pager_min_lines);
4841  }
4842 
4843  /* show record separator for unaligned text */
4844  else if (strcmp(param, "recordsep") == 0)
4845  {
4846  if (popt->topt.recordSep.separator_zero)
4847  printf(_("Record separator is zero byte.\n"));
4848  else if (strcmp(popt->topt.recordSep.separator, "\n") == 0)
4849  printf(_("Record separator is <newline>.\n"));
4850  else
4851  printf(_("Record separator is \"%s\".\n"),
4852  popt->topt.recordSep.separator);
4853  }
4854 
4855  else if (strcmp(param, "recordsep_zero") == 0)
4856  {
4857  printf(_("Record separator is zero byte.\n"));
4858  }
4859 
4860  /* show HTML table tag options */
4861  else if (strcmp(param, "T") == 0 || strcmp(param, "tableattr") == 0)
4862  {
4863  if (popt->topt.tableAttr)
4864  printf(_("Table attributes are \"%s\".\n"),
4865  popt->topt.tableAttr);
4866  else
4867  printf(_("Table attributes unset.\n"));
4868  }
4869 
4870  /* show title override */
4871  else if (strcmp(param, "C") == 0 || strcmp(param, "title") == 0)
4872  {
4873  if (popt->title)
4874  printf(_("Title is \"%s\".\n"), popt->title);
4875  else
4876  printf(_("Title is unset.\n"));
4877  }
4878 
4879  /* show toggle between full and tuples-only format */
4880  else if (strcmp(param, "t") == 0 || strcmp(param, "tuples_only") == 0)
4881  {
4882  if (popt->topt.tuples_only)
4883  printf(_("Tuples only is on.\n"));
4884  else
4885  printf(_("Tuples only is off.\n"));
4886  }
4887 
4888  /* Unicode style formatting */
4889  else if (strcmp(param, "unicode_border_linestyle") == 0)
4890  {
4891  printf(_("Unicode border line style is \"%s\".\n"),
4893  }
4894 
4895  else if (strcmp(param, "unicode_column_linestyle") == 0)
4896  {
4897  printf(_("Unicode column line style is \"%s\".\n"),
4899  }
4900 
4901  else if (strcmp(param, "unicode_header_linestyle") == 0)
4902  {
4903  printf(_("Unicode header line style is \"%s\".\n"),
4905  }
4906 
4907  else
4908  {
4909  pg_log_error("\\pset: unknown option: %s", param);
4910  return false;
4911  }
4912 
4913  return true;
4914 }
#define ngettext(s, p, n)
Definition: c.h:1168
static const char * _align2string(enum printFormat in)
Definition: command.c:4283
static const char * _unicode_linestyle2string(int linestyle)
Definition: command.c:4339
const printTextFormat * get_line_style(const printTableOpt *opt)
Definition: print.c:3677
const char * name
Definition: print.h:84

References _, _align2string(), _unicode_linestyle2string(), Assert(), printTableOpt::border, printTableOpt::columns, printTableOpt::csvFieldSep, printTableOpt::default_footer, printTableOpt::expanded, printTableOpt::expanded_header_exact_width, printTableOpt::expanded_header_width_type, printTableOpt::fieldSep, printTableOpt::format, get_line_style(), printTextFormat::name, ngettext, printQueryOpt::nullPrint, printTableOpt::numericLocale, printTableOpt::pager, printTableOpt::pager_min_lines, pg_log_error, PRINT_XHEADER_COLUMN, PRINT_XHEADER_EXACT_WIDTH, PRINT_XHEADER_FULL, PRINT_XHEADER_PAGE, printf, printTableOpt::recordSep, separator::separator, separator::separator_zero, printTableOpt::tableAttr, printQueryOpt::title, printQueryOpt::topt, printTableOpt::tuples_only, printTableOpt::unicode_border_linestyle, printTableOpt::unicode_column_linestyle, and printTableOpt::unicode_header_linestyle.

Referenced by do_pset().

◆ printSSLInfo()

static void printSSLInfo ( void  )
static

Definition at line 3812 of file command.c.

3813 {
3814  const char *protocol;
3815  const char *cipher;
3816  const char *compression;
3817 
3818  if (!PQsslInUse(pset.db))
3819  return; /* no SSL */
3820 
3821  protocol = PQsslAttribute(pset.db, "protocol");
3822  cipher = PQsslAttribute(pset.db, "cipher");
3823  compression = PQsslAttribute(pset.db, "compression");
3824 
3825  printf(_("SSL connection (protocol: %s, cipher: %s, compression: %s)\n"),
3826  protocol ? protocol : _("unknown"),
3827  cipher ? cipher : _("unknown"),
3828  (compression && strcmp(compression, "off") != 0) ? _("on") : _("off"));
3829 }
const char * PQsslAttribute(PGconn *conn, const char *attribute_name)
int PQsslInUse(PGconn *conn)
Definition: fe-secure.c:103

References _, _psqlSettings::db, PQsslAttribute(), PQsslInUse(), printf, and pset.

Referenced by connection_warnings(), and exec_command_conninfo().

◆ process_command_g_options()

static backslashResult process_command_g_options ( char *  first_option,
PsqlScanState  scan_state,
bool  active_branch,
const char *  cmd 
)
static

Definition at line 1465 of file command.c.

1467 {
1468  bool success = true;
1469  bool found_r_paren = false;
1470 
1471  do
1472  {
1473  char *option;
1474  size_t optlen;
1475 
1476  /* If not first time through, collect a new option */
1477  if (first_option)
1478  option = first_option;
1479  else
1480  {
1481  option = psql_scan_slash_option(scan_state,
1482  OT_NORMAL, NULL, false);
1483  if (!option)
1484  {
1485  if (active_branch)
1486  {
1487  pg_log_error("\\%s: missing right parenthesis", cmd);
1488  success = false;
1489  }
1490  break;
1491  }
1492  }
1493 
1494  /* Check for terminating right paren, and remove it from string */
1495  optlen = strlen(option);
1496  if (optlen > 0 && option[optlen - 1] == ')')
1497  {
1498  option[--optlen] = '\0';
1499  found_r_paren = true;
1500  }
1501 
1502  /* If there was anything besides parentheses, parse/execute it */
1503  if (optlen > 0)
1504  {
1505  /* We can have either "name" or "name=value" */
1506  char *valptr = strchr(option, '=');
1507 
1508  if (valptr)
1509  *valptr++ = '\0';
1510  if (active_branch)
1511  {
1512  /* save settings if not done already, then apply option */
1513  if (pset.gsavepopt == NULL)
1515  success &= do_pset(option, valptr, &pset.popt, true);
1516  }
1517  }
1518 
1519  /* Clean up after this option. We should not free first_option. */
1520  if (first_option)
1521  first_option = NULL;
1522  else
1523  free(option);
1524  } while (!found_r_paren);
1525 
1526  /* If we failed after already changing some options, undo side-effects */
1527  if (!success && active_branch && pset.gsavepopt)
1528  {
1530  pset.gsavepopt = NULL;
1531  }
1532 
1534 }
void restorePsetInfo(printQueryOpt *popt, printQueryOpt *save)
Definition: command.c:4958

References do_pset(), free, _psqlSettings::gsavepopt, OT_NORMAL, pg_log_error, _psqlSettings::popt, pset, PSQL_CMD_ERROR, PSQL_CMD_SKIP_LINE, psql_scan_slash_option(), restorePsetInfo(), savePsetInfo(), and success.

Referenced by exec_command_g().

◆ process_file()

int process_file ( char *  filename,
bool  use_relative_path 
)

Definition at line 4216 of file command.c.

4217 {
4218  FILE *fd;
4219  int result;
4220  char *oldfilename;
4221  char relpath[MAXPGPATH];
4222 
4223  if (!filename)
4224  {
4225  fd = stdin;
4226  filename = NULL;
4227  }
4228  else if (strcmp(filename, "-") != 0)
4229  {
4231 
4232  /*
4233  * If we were asked to resolve the pathname relative to the location
4234  * of the currently executing script, and there is one, and this is a
4235  * relative pathname, then prepend all but the last pathname component
4236  * of the current script to this pathname.
4237  */
4238  if (use_relative_path && pset.inputfile &&
4240  {
4241  strlcpy(relpath, pset.inputfile, sizeof(relpath));
4245 
4246  filename = relpath;
4247  }
4248 
4249  fd = fopen(filename, PG_BINARY_R);
4250 
4251  if (!fd)
4252  {
4253  pg_log_error("%s: %m", filename);
4254  return EXIT_FAILURE;
4255  }
4256  }
4257  else
4258  {
4259  fd = stdin;
4260  filename = "<stdin>"; /* for future error messages */
4261  }
4262 
4263  oldfilename = pset.inputfile;
4265 
4267 
4268  result = MainLoop(fd);
4269 
4270  if (fd != stdin)
4271  fclose(fd);
4272 
4273  pset.inputfile = oldfilename;
4274 
4276 
4277  return result;
4278 }
void pg_logging_config(int new_flags)
Definition: logging.c:163
#define PG_LOG_FLAG_TERSE
Definition: logging.h:86
int MainLoop(FILE *source)
Definition: mainloop.c:33
static char * filename
Definition: pg_dumpall.c:121
void join_path_components(char *ret_path, const char *head, const char *tail)
Definition: path.c:219
#define is_absolute_path(filename)
Definition: port.h:103
void get_parent_directory(char *path)
Definition: path.c:976
bool has_drive_prefix(const char *path)
Definition: path.c:88
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
#define relpath(rlocator, forknum)
Definition: relpath.h:94
#define EXIT_FAILURE
Definition: settings.h:167

References canonicalize_path(), EXIT_FAILURE, fd(), filename, get_parent_directory(), has_drive_prefix(), _psqlSettings::inputfile, is_absolute_path, join_path_components(), MainLoop(), MAXPGPATH, PG_BINARY_R, pg_log_error, PG_LOG_FLAG_TERSE, pg_logging_config(), pset, relpath, and strlcpy().

Referenced by exec_command_include().

◆ prompt_for_password()

static char* prompt_for_password ( const char *  username,
bool canceled 
)
static

Definition at line 3243 of file command.c.

3244 {
3245  char *result;
3246  PromptInterruptContext prompt_ctx;
3247 
3248  /* Set up to let SIGINT cancel simple_prompt_extended() */
3249  prompt_ctx.jmpbuf = sigint_interrupt_jmp;
3250  prompt_ctx.enabled = &sigint_interrupt_enabled;
3251  prompt_ctx.canceled = false;
3252 
3253  if (username == NULL || username[0] == '\0')
3254  result = simple_prompt_extended("Password: ", false, &prompt_ctx);
3255  else
3256  {
3257  char *prompt_text;
3258 
3259  prompt_text = psprintf(_("Password for user %s: "), username);
3260  result = simple_prompt_extended(prompt_text, false, &prompt_ctx);
3261  free(prompt_text);
3262  }
3263 
3264  if (canceled)
3265  *canceled = prompt_ctx.canceled;
3266 
3267  return result;
3268 }
const char * username
Definition: pgbench.c:296

References _, PromptInterruptContext::canceled, PromptInterruptContext::enabled, free, PromptInterruptContext::jmpbuf, psprintf(), sigint_interrupt_enabled, sigint_interrupt_jmp, simple_prompt_extended(), and username.

Referenced by do_connect().

◆ pset_bool_string()

static const char* pset_bool_string ( bool  val)
static

Definition at line 4984 of file command.c.

4985 {
4986  return val ? "on" : "off";
4987 }

References val.

Referenced by pset_value_string().

◆ pset_quoted_string()

static char* pset_quoted_string ( const char *  str)
static

Definition at line 4991 of file command.c.

4992 {
4993  char *ret = pg_malloc(strlen(str) * 2 + 3);
4994  char *r = ret;
4995 
4996  *r++ = '\'';
4997 
4998  for (; *str; str++)
4999  {
5000  if (*str == '\n')
5001  {
5002  *r++ = '\\';
5003  *r++ = 'n';
5004  }
5005  else if (*str == '\'')
5006  {
5007  *r++ = '\\';
5008  *r++ = '\'';
5009  }
5010  else
5011  *r++ = *str;
5012  }
5013 
5014  *r++ = '\'';
5015  *r = '\0';
5016 
5017  return ret;
5018 }

References pg_malloc(), and generate_unaccent_rules::str.

Referenced by pset_value_string().

◆ pset_value_string()

static char * pset_value_string ( const char *  param,
printQueryOpt popt 
)
static

Definition at line 5029 of file command.c.

5030 {
5031  Assert(param != NULL);
5032 
5033  if (strcmp(param, "border") == 0)
5034  return psprintf("%d", popt->topt.border);
5035  else if (strcmp(param, "columns") == 0)
5036  return psprintf("%d", popt->topt.columns);
5037  else if (strcmp(param, "csv_fieldsep") == 0)
5038  return pset_quoted_string(popt->topt.csvFieldSep);
5039  else if (strcmp(param, "expanded") == 0)
5040  return pstrdup(popt->topt.expanded == 2
5041  ? "auto"
5042  : pset_bool_string(popt->topt.expanded));
5043  else if (strcmp(param, "fieldsep") == 0)
5045  ? popt->topt.fieldSep.separator
5046  : "");
5047  else if (strcmp(param, "fieldsep_zero") == 0)
5049  else if (strcmp(param, "footer") == 0)
5051  else if (strcmp(param, "format") == 0)
5052  return pstrdup(_align2string(popt->topt.format));
5053  else if (strcmp(param, "linestyle") == 0)
5054  return pstrdup(get_line_style(&popt->topt)->name);
5055  else if (strcmp(param, "null") == 0)
5056  return pset_quoted_string(popt->nullPrint
5057  ? popt->nullPrint
5058  : "");
5059  else if (strcmp(param, "numericlocale") == 0)
5060  return pstrdup(pset_bool_string(popt->topt.numericLocale));
5061  else if (strcmp(param, "pager") == 0)
5062  return psprintf("%d", popt->topt.pager);
5063  else if (strcmp(param, "pager_min_lines") == 0)
5064  return psprintf("%d", popt->topt.pager_min_lines);
5065  else if (strcmp(param, "recordsep") == 0)
5067  ? popt->topt.recordSep.separator
5068  : "");
5069  else if (strcmp(param, "recordsep_zero") == 0)
5071  else if (strcmp(param, "tableattr") == 0)
5072  return popt->topt.tableAttr ? pset_quoted_string(popt->topt.tableAttr) : pstrdup("");
5073  else if (strcmp(param, "title") == 0)
5074  return popt->title ? pset_quoted_string(popt->title) : pstrdup("");
5075  else if (strcmp(param, "tuples_only") == 0)
5076  return pstrdup(pset_bool_string(popt->topt.tuples_only));
5077  else if (strcmp(param, "unicode_border_linestyle") == 0)
5079  else if (strcmp(param, "unicode_column_linestyle") == 0)
5081  else if (strcmp(param, "unicode_header_linestyle") == 0)
5083  else if (strcmp(param, "xheader_width") == 0)
5084  {
5086  return pstrdup("full");
5088  return pstrdup("column");
5090  return pstrdup("page");
5091  else
5092  {
5093  /* must be PRINT_XHEADER_EXACT_WIDTH */
5094  char wbuff[32];
5095 
5096  snprintf(wbuff, sizeof(wbuff), "%d",
5098  return pstrdup(wbuff);
5099  }
5100  }
5101  else
5102  return pstrdup("ERROR");
5103 }
static char * pset_quoted_string(const char *str)
Definition: command.c:4991
static const char * pset_bool_string(bool val)
Definition: command.c:4984
char * pstrdup(const char *in)
Definition: mcxt.c:1683

References _align2string(), _unicode_linestyle2string(), Assert(), printTableOpt::border, printTableOpt::columns, printTableOpt::csvFieldSep, printTableOpt::default_footer, printTableOpt::expanded, printTableOpt::expanded_header_exact_width, printTableOpt::expanded_header_width_type, printTableOpt::fieldSep, printTableOpt::format, get_line_style(), printTextFormat::name, printQueryOpt::nullPrint, printTableOpt::numericLocale, printTableOpt::pager, printTableOpt::pager_min_lines, PRINT_XHEADER_COLUMN, PRINT_XHEADER_FULL, PRINT_XHEADER_PAGE, pset_bool_string(), pset_quoted_string(), psprintf(), pstrdup(), printTableOpt::recordSep, separator::separator, separator::separator_zero, snprintf, printTableOpt::tableAttr, printQueryOpt::title, printQueryOpt::topt, printTableOpt::tuples_only, printTableOpt::unicode_border_linestyle, printTableOpt::unicode_column_linestyle, and printTableOpt::unicode_header_linestyle.

Referenced by exec_command_pset().

◆ read_connect_arg()

static char * read_connect_arg ( PsqlScanState  scan_state)
static

Definition at line 3011 of file command.c.

3012 {
3013  char *result;
3014  char quote;
3015 
3016  /*
3017  * Ideally we should treat the arguments as SQL identifiers. But for
3018  * backwards compatibility with 7.2 and older pg_dump files, we have to
3019  * take unquoted arguments verbatim (don't downcase them). For now,
3020  * double-quoted arguments may be stripped of double quotes (as if SQL
3021  * identifiers). By 7.4 or so, pg_dump files can be expected to
3022  * double-quote all mixed-case \connect arguments, and then we can get rid
3023  * of OT_SQLIDHACK.
3024  */
3025  result = psql_scan_slash_option(scan_state, OT_SQLIDHACK, &quote, true);
3026 
3027  if (!result)
3028  return NULL;
3029 
3030  if (quote)
3031  return result;
3032 
3033  if (*result == '\0' || strcmp(result, "-") == 0)
3034  {
3035  free(result);
3036  return NULL;
3037  }
3038 
3039  return result;
3040 }
@ OT_SQLIDHACK
Definition: psqlscanslash.h:19

References free, OT_SQLIDHACK, and psql_scan_slash_option().

Referenced by exec_command_connect().

◆ restorePsetInfo()

void restorePsetInfo ( printQueryOpt popt,
printQueryOpt save 
)

Definition at line 4958 of file command.c.

4959 {
4960  /* Free all the old data we're about to overwrite the pointers to. */
4961 
4962  /* topt.line_style points to const data that need not be duplicated */
4963  free(popt->topt.fieldSep.separator);
4964  free(popt->topt.recordSep.separator);
4965  free(popt->topt.tableAttr);
4966  free(popt->nullPrint);
4967  free(popt->title);
4968 
4969  /*
4970  * footers and translate_columns are never set in psql's print settings,
4971  * so we needn't write code to duplicate them.
4972  */
4973  Assert(popt->footers == NULL);
4974  Assert(popt->translate_columns == NULL);
4975 
4976  /* Now we may flat-copy all the fields, including pointers. */
4977  memcpy(popt, save, sizeof(printQueryOpt));
4978 
4979  /* Lastly, free "save" ... but its sub-structures now belong to popt. */
4980  free(save);
4981 }
const bool * translate_columns
Definition: print.h:190
char ** footers
Definition: print.h:188

References Assert(), printTableOpt::fieldSep, printQueryOpt::footers, free, printQueryOpt::nullPrint, printTableOpt::recordSep, separator::separator, printTableOpt::tableAttr, printQueryOpt::title, printQueryOpt::topt, and printQueryOpt::translate_columns.

Referenced by process_command_g_options(), and SendQuery().

◆ save_query_text_state()

static void save_query_text_state ( PsqlScanState  scan_state,
ConditionalStack  cstack,
PQExpBuffer  query_buf 
)
static

Definition at line 3179 of file command.c.

3181 {
3182  if (query_buf)
3183  conditional_stack_set_query_len(cstack, query_buf->len);
3185  psql_scan_get_paren_depth(scan_state));
3186 }
void conditional_stack_set_paren_depth(ConditionalStack cstack, int depth)
Definition: conditional.c:173
void conditional_stack_set_query_len(ConditionalStack cstack, int len)
Definition: conditional.c:151
int psql_scan_get_paren_depth(PsqlScanState state)

References conditional_stack_set_paren_depth(), conditional_stack_set_query_len(), PQExpBufferData::len, and psql_scan_get_paren_depth().

Referenced by exec_command_elif(), exec_command_else(), and exec_command_if().

◆ savePsetInfo()

printQueryOpt* savePsetInfo ( const printQueryOpt popt)

Definition at line 4922 of file command.c.

4923 {
4924  printQueryOpt *save;
4925 
4926  save = (printQueryOpt *) pg_malloc(sizeof(printQueryOpt));
4927 
4928  /* Flat-copy all the scalar fields, then duplicate sub-structures. */
4929  memcpy(save, popt, sizeof(printQueryOpt));
4930 
4931  /* topt.line_style points to const data that need not be duplicated */
4932  if (popt->topt.fieldSep.separator)
4934  if (popt->topt.recordSep.separator)
4936  if (popt->topt.tableAttr)
4937  save->topt.tableAttr = pg_strdup(popt->topt.tableAttr);
4938  if (popt->nullPrint)
4939  save->nullPrint = pg_strdup(popt->nullPrint);
4940  if (popt->title)
4941  save->title = pg_strdup(popt->title);
4942 
4943  /*
4944  * footers and translate_columns are never set in psql's print settings,
4945  * so we needn't write code to duplicate them.
4946  */
4947  Assert(popt->footers == NULL);
4948  Assert(popt->translate_columns == NULL);
4949 
4950  return save;
4951 }

References Assert(), printTableOpt::fieldSep, printQueryOpt::footers, printQueryOpt::nullPrint, pg_malloc(), pg_strdup(), printTableOpt::recordSep, separator::separator, printTableOpt::tableAttr, printQueryOpt::title, printQueryOpt::topt, and printQueryOpt::translate_columns.

Referenced by exec_command_g(), and process_command_g_options().

◆ set_unicode_line_style()

static bool set_unicode_line_style ( const char *  value,
size_t  vallen,
unicode_linestyle linestyle 
)
static

Definition at line 4326 of file command.c.

4328 {
4329  if (pg_strncasecmp("single", value, vallen) == 0)
4330  *linestyle = UNICODE_LINESTYLE_SINGLE;
4331  else if (pg_strncasecmp("double", value, vallen) == 0)
4332  *linestyle = UNICODE_LINESTYLE_DOUBLE;
4333  else
4334  return false;
4335  return true;
4336 }

References pg_strncasecmp(), UNICODE_LINESTYLE_DOUBLE, UNICODE_LINESTYLE_SINGLE, and value.

Referenced by do_pset().

◆ strip_lineno_from_objdesc()

static int strip_lineno_from_objdesc ( char *  obj)
static

Definition at line 5657 of file command.c.

5658 {
5659  char *c;
5660  int lineno;
5661 
5662  if (!obj || obj[0] == '\0')
5663  return -1;
5664 
5665  c = obj + strlen(obj) - 1;
5666 
5667  /*
5668  * This business of parsing backwards is dangerous as can be in a
5669  * multibyte environment: there is no reason to believe that we are
5670  * looking at the first byte of a character, nor are we necessarily
5671  * working in a "safe" encoding. Fortunately the bitpatterns we are
5672  * looking for are unlikely to occur as non-first bytes, but beware of
5673  * trying to expand the set of cases that can be recognized. We must
5674  * guard the <ctype.h> macros by using isascii() first, too.
5675  */
5676 
5677  /* skip trailing whitespace */
5678  while (c > obj && isascii((unsigned char) *c) && isspace((unsigned char) *c))
5679  c--;
5680 
5681  /* must have a digit as last non-space char */
5682  if (c == obj || !isascii((unsigned char) *c) || !isdigit((unsigned char) *c))
5683  return -1;
5684 
5685  /* find start of digit string */
5686  while (c > obj && isascii((unsigned char) *c) && isdigit((unsigned char) *c))
5687  c--;
5688 
5689  /* digits must be separated from object name by space or closing paren */
5690  /* notice also that we are not allowing an empty object name ... */
5691  if (c == obj || !isascii((unsigned char) *c) ||
5692  !(isspace((unsigned char) *c) || *c == ')'))
5693  return -1;
5694 
5695  /* parse digit string */
5696  c++;
5697  lineno = atoi(c);
5698  if (lineno < 1)
5699  {
5700  pg_log_error("invalid line number: %s", c);
5701  return 0;
5702  }
5703 
5704  /* strip digit string from object name */
5705  *c = '\0';
5706 
5707  return lineno;
5708 }
char * c

References pg_log_error.

Referenced by exec_command_ef_ev().

◆ SyncVariables()

void SyncVariables ( void  )

Definition at line 3878 of file command.c.

3879 {
3880  char vbuf[32];
3881  const char *server_version;
3882 
3883  /* get stuff from connection */
3887 
3888  SetVariable(pset.vars, "DBNAME", PQdb(pset.db));
3889  SetVariable(pset.vars, "USER", PQuser(pset.db));
3890  SetVariable(pset.vars, "HOST", PQhost(pset.db));
3891  SetVariable(pset.vars, "PORT", PQport(pset.db));
3893 
3894  /* this bit should match connection_warnings(): */
3895  /* Try to get full text form of version, might include "devel" etc */
3896  server_version = PQparameterStatus(pset.db, "server_version");
3897  /* Otherwise fall back on pset.sversion */
3898  if (!server_version)
3899  {
3900  formatPGVersionNumber(pset.sversion, true, vbuf, sizeof(vbuf));
3901  server_version = vbuf;
3902  }
3903  SetVariable(pset.vars, "SERVER_VERSION_NAME", server_version);
3904 
3905  snprintf(vbuf, sizeof(vbuf), "%d", pset.sversion);
3906  SetVariable(pset.vars, "SERVER_VERSION_NUM", vbuf);
3907 
3908  /* send stuff to it, too */
3911 }
int PQserverVersion(const PGconn *conn)
Definition: fe-connect.c:6938
PGContextVisibility PQsetErrorContextVisibility(PGconn *conn, PGContextVisibility show_context)
Definition: fe-connect.c:7098
PGVerbosity PQsetErrorVerbosity(PGconn *conn, PGVerbosity verbosity)
Definition: fe-connect.c:7086
PGVerbosity verbosity
Definition: settings.h:154
PGContextVisibility show_context
Definition: settings.h:156

References _psqlSettings::db, _psqlSettings::encoding, printTableOpt::encoding, formatPGVersionNumber(), pg_encoding_to_char, _psqlSettings::popt, PQclientEncoding(), PQdb(), PQhost(), PQparameterStatus(), PQport(), PQserverVersion(), PQsetErrorContextVisibility(), PQsetErrorVerbosity(), PQuser(), pset, server_version, SetVariable(), _psqlSettings::show_context, snprintf, _psqlSettings::sversion, printQueryOpt::topt, _psqlSettings::vars, and _psqlSettings::verbosity.

Referenced by CheckConnection(), do_connect(), and main().

◆ UnsyncVariables()

void UnsyncVariables ( void  )

Definition at line 3919 of file command.c.

3920 {
3921  SetVariable(pset.vars, "DBNAME", NULL);
3922  SetVariable(pset.vars, "USER", NULL);
3923  SetVariable(pset.vars, "HOST", NULL);
3924  SetVariable(pset.vars, "PORT", NULL);
3925  SetVariable(pset.vars, "ENCODING", NULL);
3926  SetVariable(pset.vars, "SERVER_VERSION_NAME", NULL);
3927  SetVariable(pset.vars, "SERVER_VERSION_NUM", NULL);
3928 }

References pset, SetVariable(), and _psqlSettings::vars.

Referenced by CheckConnection(), and do_connect().