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_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)
 
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)
 
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, const char *header_keyword)
 
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 4915 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 4143 of file command.c.

4144 {
4145  switch (in)
4146  {
4147  case PRINT_NOTHING:
4148  return "nothing";
4149  break;
4150  case PRINT_ALIGNED:
4151  return "aligned";
4152  break;
4153  case PRINT_ASCIIDOC:
4154  return "asciidoc";
4155  break;
4156  case PRINT_CSV:
4157  return "csv";
4158  break;
4159  case PRINT_HTML:
4160  return "html";
4161  break;
4162  case PRINT_LATEX:
4163  return "latex";
4164  break;
4165  case PRINT_LATEX_LONGTABLE:
4166  return "latex-longtable";
4167  break;
4168  case PRINT_TROFF_MS:
4169  return "troff-ms";
4170  break;
4171  case PRINT_UNALIGNED:
4172  return "unaligned";
4173  break;
4174  case PRINT_WRAPPED:
4175  return "wrapped";
4176  break;
4177  }
4178  return "unknown";
4179 }
@ 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 4199 of file command.c.

4200 {
4201  switch (linestyle)
4202  {
4204  return "single";
4205  break;
4207  return "double";
4208  break;
4209  }
4210  return "unknown";
4211 }
@ UNICODE_LINESTYLE_SINGLE
Definition: print.h:89
@ UNICODE_LINESTYLE_DOUBLE
Definition: print.h:90

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 3614 of file command.c.

3615 {
3616  if (!pset.quiet && !pset.notty)
3617  {
3618  int client_ver = PG_VERSION_NUM;
3619  char cverbuf[32];
3620  char sverbuf[32];
3621 
3622  if (pset.sversion != client_ver)
3623  {
3624  const char *server_version;
3625 
3626  /* Try to get full text form, might include "devel" etc */
3627  server_version = PQparameterStatus(pset.db, "server_version");
3628  /* Otherwise fall back on pset.sversion */
3629  if (!server_version)
3630  {
3632  sverbuf, sizeof(sverbuf));
3633  server_version = sverbuf;
3634  }
3635 
3636  printf(_("%s (%s, server %s)\n"),
3637  pset.progname, PG_VERSION, server_version);
3638  }
3639  /* For version match, only print psql banner on startup. */
3640  else if (in_startup)
3641  printf("%s (%s)\n", pset.progname, PG_VERSION);
3642 
3643  /*
3644  * Warn if server's major version is newer than ours, or if server
3645  * predates our support cutoff (currently 9.2).
3646  */
3647  if (pset.sversion / 100 > client_ver / 100 ||
3648  pset.sversion < 90200)
3649  printf(_("WARNING: %s major version %s, server major version %s.\n"
3650  " Some psql features might not work.\n"),
3651  pset.progname,
3652  formatPGVersionNumber(client_ver, false,
3653  cverbuf, sizeof(cverbuf)),
3655  sverbuf, sizeof(sverbuf)));
3656 
3657 #ifdef WIN32
3658  if (in_startup)
3659  checkWin32Codepage();
3660 #endif
3661  printSSLInfo();
3662  printGSSInfo();
3663  }
3664 }
static void printSSLInfo(void)
Definition: command.c:3673
static void printGSSInfo(void)
Definition: command.c:3698
#define _(x)
Definition: elog.c:89
const char * PQparameterStatus(const PGconn *conn, const char *paramName)
Definition: fe-connect.c:6873
static int server_version
Definition: pg_dumpall.c:85
#define printf(...)
Definition: port.h:231
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:109

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 3084 of file command.c.

3085 {
3086  if (query_buf && query_buf->len == 0)
3087  {
3088  appendPQExpBufferStr(query_buf, previous_buf->data);
3089  return true;
3090  }
3091  return false;
3092 }
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:369

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 5500 of file command.c.

5501 {
5502  int lineno = 0;
5503  const char *lines = buf->data;
5504 
5505  while (*lines != '\0')
5506  {
5507  lineno++;
5508  /* find start of next line */
5509  lines = strchr(lines, '\n');
5510  if (!lines)
5511  break;
5512  lines++;
5513  }
5514 
5515  return lineno;
5516 }
static char * buf
Definition: pg_test_fsync.c:67

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 3058 of file command.c.

3060 {
3061  if (query_buf)
3062  {
3063  int new_len = conditional_stack_get_query_len(cstack);
3064 
3065  Assert(new_len >= 0 && new_len <= query_buf->len);
3066  query_buf->len = new_len;
3067  query_buf->data[new_len] = '\0';
3068  }
3069  psql_scan_set_paren_depth(scan_state,
3071 }
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 3153 of file command.c.

3155 {
3156  PGconn *o_conn = pset.db,
3157  *n_conn = NULL;
3158  PQconninfoOption *cinfo;
3159  int nconnopts = 0;
3160  bool same_host = false;
3161  char *password = NULL;
3162  char *client_encoding;
3163  bool success = true;
3164  bool keep_password = true;
3165  bool has_connection_string;
3166  bool reuse_previous;
3167 
3168  has_connection_string = dbname ?
3170 
3171  /* Complain if we have additional arguments after a connection string. */
3172  if (has_connection_string && (user || host || port))
3173  {
3174  pg_log_error("Do not give user, host, or port separately when using a connection string");
3175  return false;
3176  }
3177 
3178  switch (reuse_previous_specification)
3179  {
3180  case TRI_YES:
3181  reuse_previous = true;
3182  break;
3183  case TRI_NO:
3184  reuse_previous = false;
3185  break;
3186  default:
3187  reuse_previous = !has_connection_string;
3188  break;
3189  }
3190 
3191  /*
3192  * If we intend to re-use connection parameters, collect them out of the
3193  * old connection, then replace individual values as necessary. (We may
3194  * need to resort to looking at pset.dead_conn, if the connection died
3195  * previously.) Otherwise, obtain a PQconninfoOption array containing
3196  * libpq's defaults, and modify that. Note this function assumes that
3197  * PQconninfo, PQconndefaults, and PQconninfoParse will all produce arrays
3198  * containing the same options in the same order.
3199  */
3200  if (reuse_previous)
3201  {
3202  if (o_conn)
3203  cinfo = PQconninfo(o_conn);
3204  else if (pset.dead_conn)
3205  cinfo = PQconninfo(pset.dead_conn);
3206  else
3207  {
3208  /* This is reachable after a non-interactive \connect failure */
3209  pg_log_error("No database connection exists to re-use parameters from");
3210  return false;
3211  }
3212  }
3213  else
3214  cinfo = PQconndefaults();
3215 
3216  if (cinfo)
3217  {
3218  if (has_connection_string)
3219  {
3220  /* Parse the connstring and insert values into cinfo */
3221  PQconninfoOption *replcinfo;
3222  char *errmsg;
3223 
3224  replcinfo = PQconninfoParse(dbname, &errmsg);
3225  if (replcinfo)
3226  {
3227  PQconninfoOption *ci;
3228  PQconninfoOption *replci;
3229  bool have_password = false;
3230 
3231  for (ci = cinfo, replci = replcinfo;
3232  ci->keyword && replci->keyword;
3233  ci++, replci++)
3234  {
3235  Assert(strcmp(ci->keyword, replci->keyword) == 0);
3236  /* Insert value from connstring if one was provided */
3237  if (replci->val)
3238  {
3239  /*
3240  * We know that both val strings were allocated by
3241  * libpq, so the least messy way to avoid memory leaks
3242  * is to swap them.
3243  */
3244  char *swap = replci->val;
3245 
3246  replci->val = ci->val;
3247  ci->val = swap;
3248 
3249  /*
3250  * Check whether connstring provides options affecting
3251  * password re-use. While any change in user, host,
3252  * hostaddr, or port causes us to ignore the old
3253  * connection's password, we don't force that for
3254  * dbname, since passwords aren't database-specific.
3255  */
3256  if (replci->val == NULL ||
3257  strcmp(ci->val, replci->val) != 0)
3258  {
3259  if (strcmp(replci->keyword, "user") == 0 ||
3260  strcmp(replci->keyword, "host") == 0 ||
3261  strcmp(replci->keyword, "hostaddr") == 0 ||
3262  strcmp(replci->keyword, "port") == 0)
3263  keep_password = false;
3264  }
3265  /* Also note whether connstring contains a password. */
3266  if (strcmp(replci->keyword, "password") == 0)
3267  have_password = true;
3268  }
3269  else if (!reuse_previous)
3270  {
3271  /*
3272  * When we have a connstring and are not re-using
3273  * parameters, swap *all* entries, even those not set
3274  * by the connstring. This avoids absorbing
3275  * environment-dependent defaults from the result of
3276  * PQconndefaults(). We don't want to do that because
3277  * they'd override service-file entries if the
3278  * connstring specifies a service parameter, whereas
3279  * the priority should be the other way around. libpq
3280  * can certainly recompute any defaults we don't pass
3281  * here. (In this situation, it's a bit wasteful to
3282  * have called PQconndefaults() at all, but not doing
3283  * so would require yet another major code path here.)
3284  */
3285  replci->val = ci->val;
3286  ci->val = NULL;
3287  }
3288  }
3289  Assert(ci->keyword == NULL && replci->keyword == NULL);
3290 
3291  /* While here, determine how many option slots there are */
3292  nconnopts = ci - cinfo;
3293 
3294  PQconninfoFree(replcinfo);
3295 
3296  /*
3297  * If the connstring contains a password, tell the loop below
3298  * that we may use it, regardless of other settings (i.e.,
3299  * cinfo's password is no longer an "old" password).
3300  */
3301  if (have_password)
3302  keep_password = true;
3303 
3304  /* Don't let code below try to inject dbname into params. */
3305  dbname = NULL;
3306  }
3307  else
3308  {
3309  /* PQconninfoParse failed */
3310  if (errmsg)
3311  {
3312  pg_log_error("%s", errmsg);
3313  PQfreemem(errmsg);
3314  }
3315  else
3316  pg_log_error("out of memory");
3317  success = false;
3318  }
3319  }
3320  else
3321  {
3322  /*
3323  * If dbname isn't a connection string, then we'll inject it and
3324  * the other parameters into the keyword array below. (We can't
3325  * easily insert them into the cinfo array because of memory
3326  * management issues: PQconninfoFree would misbehave on Windows.)
3327  * However, to avoid dependencies on the order in which parameters
3328  * appear in the array, make a preliminary scan to set
3329  * keep_password and same_host correctly.
3330  *
3331  * While any change in user, host, or port causes us to ignore the
3332  * old connection's password, we don't force that for dbname,
3333  * since passwords aren't database-specific.
3334  */
3335  PQconninfoOption *ci;
3336 
3337  for (ci = cinfo; ci->keyword; ci++)
3338  {
3339  if (user && strcmp(ci->keyword, "user") == 0)
3340  {
3341  if (!(ci->val && strcmp(user, ci->val) == 0))
3342  keep_password = false;
3343  }
3344  else if (host && strcmp(ci->keyword, "host") == 0)
3345  {
3346  if (ci->val && strcmp(host, ci->val) == 0)
3347  same_host = true;
3348  else
3349  keep_password = false;
3350  }
3351  else if (port && strcmp(ci->keyword, "port") == 0)
3352  {
3353  if (!(ci->val && strcmp(port, ci->val) == 0))
3354  keep_password = false;
3355  }
3356  }
3357 
3358  /* While here, determine how many option slots there are */
3359  nconnopts = ci - cinfo;
3360  }
3361  }
3362  else
3363  {
3364  /* We failed to create the cinfo structure */
3365  pg_log_error("out of memory");
3366  success = false;
3367  }
3368 
3369  /*
3370  * If the user asked to be prompted for a password, ask for one now. If
3371  * not, use the password from the old connection, provided the username
3372  * etc have not changed. Otherwise, try to connect without a password
3373  * first, and then ask for a password if needed.
3374  *
3375  * XXX: this behavior leads to spurious connection attempts recorded in
3376  * the postmaster's log. But libpq offers no API that would let us obtain
3377  * a password and then continue with the first connection attempt.
3378  */
3379  if (pset.getPassword == TRI_YES && success)
3380  {
3381  bool canceled = false;
3382 
3383  /*
3384  * If a connstring or URI is provided, we don't know which username
3385  * will be used, since we haven't dug that out of the connstring.
3386  * Don't risk issuing a misleading prompt. As in startup.c, it does
3387  * not seem worth working harder, since this getPassword setting is
3388  * normally only used in noninteractive cases.
3389  */
3390  password = prompt_for_password(has_connection_string ? NULL : user,
3391  &canceled);
3392  success = !canceled;
3393  }
3394 
3395  /*
3396  * Consider whether to force client_encoding to "auto" (overriding
3397  * anything in the connection string). We do so if we have a terminal
3398  * connection and there is no PGCLIENTENCODING environment setting.
3399  */
3400  if (pset.notty || getenv("PGCLIENTENCODING"))
3401  client_encoding = NULL;
3402  else
3403  client_encoding = "auto";
3404 
3405  /* Loop till we have a connection or fail, which we might've already */
3406  while (success)
3407  {
3408  const char **keywords = pg_malloc((nconnopts + 1) * sizeof(*keywords));
3409  const char **values = pg_malloc((nconnopts + 1) * sizeof(*values));
3410  int paramnum = 0;
3411  PQconninfoOption *ci;
3412 
3413  /*
3414  * Copy non-default settings into the PQconnectdbParams parameter
3415  * arrays; but inject any values specified old-style, as well as any
3416  * interactively-obtained password, and a couple of fields we want to
3417  * set forcibly.
3418  *
3419  * If you change this code, see also the initial-connection code in
3420  * main().
3421  */
3422  for (ci = cinfo; ci->keyword; ci++)
3423  {
3424  keywords[paramnum] = ci->keyword;
3425 
3426  if (dbname && strcmp(ci->keyword, "dbname") == 0)
3427  values[paramnum++] = dbname;
3428  else if (user && strcmp(ci->keyword, "user") == 0)
3429  values[paramnum++] = user;
3430  else if (host && strcmp(ci->keyword, "host") == 0)
3431  values[paramnum++] = host;
3432  else if (host && !same_host && strcmp(ci->keyword, "hostaddr") == 0)
3433  {
3434  /* If we're changing the host value, drop any old hostaddr */
3435  values[paramnum++] = NULL;
3436  }
3437  else if (port && strcmp(ci->keyword, "port") == 0)
3438  values[paramnum++] = port;
3439  /* If !keep_password, we unconditionally drop old password */
3440  else if ((password || !keep_password) &&
3441  strcmp(ci->keyword, "password") == 0)
3442  values[paramnum++] = password;
3443  else if (strcmp(ci->keyword, "fallback_application_name") == 0)
3444  values[paramnum++] = pset.progname;
3445  else if (client_encoding &&
3446  strcmp(ci->keyword, "client_encoding") == 0)
3447  values[paramnum++] = client_encoding;
3448  else if (ci->val)
3449  values[paramnum++] = ci->val;
3450  /* else, don't bother making libpq parse this keyword */
3451  }
3452  /* add array terminator */
3453  keywords[paramnum] = NULL;
3454  values[paramnum] = NULL;
3455 
3456  /* Note we do not want libpq to re-expand the dbname parameter */
3457  n_conn = PQconnectdbParams(keywords, values, false);
3458 
3459  pg_free(keywords);
3460  pg_free(values);
3461 
3462  if (PQstatus(n_conn) == CONNECTION_OK)
3463  break;
3464 
3465  /*
3466  * Connection attempt failed; either retry the connection attempt with
3467  * a new password, or give up.
3468  */
3470  {
3471  bool canceled = false;
3472 
3473  /*
3474  * Prompt for password using the username we actually connected
3475  * with --- it might've come out of "dbname" rather than "user".
3476  */
3477  password = prompt_for_password(PQuser(n_conn), &canceled);
3478  PQfinish(n_conn);
3479  n_conn = NULL;
3480  success = !canceled;
3481  continue;
3482  }
3483 
3484  /*
3485  * We'll report the error below ... unless n_conn is NULL, indicating
3486  * that libpq didn't have enough memory to make a PGconn.
3487  */
3488  if (n_conn == NULL)
3489  pg_log_error("out of memory");
3490 
3491  success = false;
3492  } /* end retry loop */
3493 
3494  /* Release locally allocated data, whether we succeeded or not */
3495  if (password)
3496  pg_free(password);
3497  if (cinfo)
3498  PQconninfoFree(cinfo);
3499 
3500  if (!success)
3501  {
3502  /*
3503  * Failed to connect to the database. In interactive mode, keep the
3504  * previous connection to the DB; in scripting mode, close our
3505  * previous connection as well.
3506  */
3508  {
3509  if (n_conn)
3510  {
3511  pg_log_info("%s", PQerrorMessage(n_conn));
3512  PQfinish(n_conn);
3513  }
3514 
3515  /* pset.db is left unmodified */
3516  if (o_conn)
3517  pg_log_info("Previous connection kept");
3518  }
3519  else
3520  {
3521  if (n_conn)
3522  {
3523  pg_log_error("\\connect: %s", PQerrorMessage(n_conn));
3524  PQfinish(n_conn);
3525  }
3526 
3527  if (o_conn)
3528  {
3529  /*
3530  * Transition to having no connection.
3531  *
3532  * Unlike CheckConnection(), we close the old connection
3533  * immediately to prevent its parameters from being re-used.
3534  * This is so that a script cannot accidentally reuse
3535  * parameters it did not expect to. Otherwise, the state
3536  * cleanup should be the same as in CheckConnection().
3537  */
3538  PQfinish(o_conn);
3539  pset.db = NULL;
3540  ResetCancelConn();
3541  UnsyncVariables();
3542  }
3543 
3544  /* On the same reasoning, release any dead_conn to prevent reuse */
3545  if (pset.dead_conn)
3546  {
3548  pset.dead_conn = NULL;
3549  }
3550  }
3551 
3552  return false;
3553  }
3554 
3555  /*
3556  * Replace the old connection with the new one, and update
3557  * connection-dependent variables. Keep the resynchronization logic in
3558  * sync with CheckConnection().
3559  */
3560  PQsetNoticeProcessor(n_conn, NoticeProcessor, NULL);
3561  pset.db = n_conn;
3562  SyncVariables();
3563  connection_warnings(false); /* Must be after SyncVariables */
3564 
3565  /* Tell the user about the new connection */
3566  if (!pset.quiet)
3567  {
3568  if (!o_conn ||
3569  param_is_newly_set(PQhost(o_conn), PQhost(pset.db)) ||
3570  param_is_newly_set(PQport(o_conn), PQport(pset.db)))
3571  {
3572  char *host = PQhost(pset.db);
3573  char *hostaddr = PQhostaddr(pset.db);
3574 
3575  if (is_unixsock_path(host))
3576  {
3577  /* hostaddr overrides host */
3578  if (hostaddr && *hostaddr)
3579  printf(_("You are now connected to database \"%s\" as user \"%s\" on address \"%s\" at port \"%s\".\n"),
3580  PQdb(pset.db), PQuser(pset.db), hostaddr, PQport(pset.db));
3581  else
3582  printf(_("You are now connected to database \"%s\" as user \"%s\" via socket in \"%s\" at port \"%s\".\n"),
3583  PQdb(pset.db), PQuser(pset.db), host, PQport(pset.db));
3584  }
3585  else
3586  {
3587  if (hostaddr && *hostaddr && strcmp(host, hostaddr) != 0)
3588  printf(_("You are now connected to database \"%s\" as user \"%s\" on host \"%s\" (address \"%s\") at port \"%s\".\n"),
3589  PQdb(pset.db), PQuser(pset.db), host, hostaddr, PQport(pset.db));
3590  else
3591  printf(_("You are now connected to database \"%s\" as user \"%s\" on host \"%s\" at port \"%s\".\n"),
3592  PQdb(pset.db), PQuser(pset.db), host, PQport(pset.db));
3593  }
3594  }
3595  else
3596  printf(_("You are now connected to database \"%s\" as user \"%s\".\n"),
3597  PQdb(pset.db), PQuser(pset.db));
3598  }
3599 
3600  /* Drop no-longer-needed connection(s) */
3601  if (o_conn)
3602  PQfinish(o_conn);
3603  if (pset.dead_conn)
3604  {
3606  pset.dead_conn = NULL;
3607  }
3608 
3609  return true;
3610 }
void NoticeProcessor(void *arg, const char *message)
Definition: common.c:223
bool recognized_connection_string(const char *connstr)
Definition: common.c:2417
static Datum values[MAXATTR]
Definition: bootstrap.c:156
void ResetCancelConn(void)
Definition: cancel.c:107
static char * prompt_for_password(const char *username, bool *canceled)
Definition: command.c:3102
static bool param_is_newly_set(const char *old_val, const char *new_val)
Definition: command.c:3130
void UnsyncVariables(void)
Definition: command.c:3780
void SyncVariables(void)
Definition: command.c:3739
void connection_warnings(bool in_startup)
Definition: command.c:3614
int errmsg(const char *fmt,...)
Definition: elog.c:904
PQconninfoOption * PQconninfoParse(const char *conninfo, char **errmsg)
Definition: fe-connect.c:5501
char * PQhost(const PGconn *conn)
Definition: fe-connect.c:6787
PGconn * PQconnectdbParams(const char *const *keywords, const char *const *values, int expand_dbname)
Definition: fe-connect.c:658
char * PQdb(const PGconn *conn)
Definition: fe-connect.c:6754
PQconninfoOption * PQconndefaults(void)
Definition: fe-connect.c:1477
char * PQhostaddr(const PGconn *conn)
Definition: fe-connect.c:6810
void PQconninfoFree(PQconninfoOption *connOptions)
Definition: fe-connect.c:6736
PQconninfoOption * PQconninfo(PGconn *conn)
Definition: fe-connect.c:6692
int PQconnectionNeedsPassword(const PGconn *conn)
Definition: fe-connect.c:6959
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6908
ConnStatusType PQstatus(const PGconn *conn)
Definition: fe-connect.c:6855
void PQfinish(PGconn *conn)
Definition: fe-connect.c:4261
char * PQuser(const PGconn *conn)
Definition: fe-connect.c:6762
char * PQport(const PGconn *conn)
Definition: fe-connect.c:6823
PQnoticeProcessor PQsetNoticeProcessor(PGconn *conn, PQnoticeProcessor proc, void *arg)
Definition: fe-connect.c:7076
void PQfreemem(void *ptr)
Definition: fe-exec.c:3891
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:169
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:95
static int port
Definition: pg_regress.c:92
static bool is_unixsock_path(const char *path)
Definition: pqcomm.h:93
static char * password
Definition: streamutil.c:53
char * dbname
Definition: streamutil.c:51
PGconn * dead_conn
Definition: settings.h:125
enum trivalue getPassword
Definition: settings.h:104
bool cur_cmd_interactive
Definition: settings.h:107
@ 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 3881 of file command.c.

3883 {
3884  char fnametmp[MAXPGPATH];
3885  FILE *stream = NULL;
3886  const char *fname;
3887  bool error = false;
3888  int fd;
3889  struct stat before,
3890  after;
3891 
3892  if (filename_arg)
3893  fname = filename_arg;
3894  else
3895  {
3896  /* make a temp file to edit */
3897 #ifndef WIN32
3898  const char *tmpdir = getenv("TMPDIR");
3899 
3900  if (!tmpdir)
3901  tmpdir = "/tmp";
3902 #else
3903  char tmpdir[MAXPGPATH];
3904  int ret;
3905 
3906  ret = GetTempPath(MAXPGPATH, tmpdir);
3907  if (ret == 0 || ret > MAXPGPATH)
3908  {
3909  pg_log_error("could not locate temporary directory: %s",
3910  !ret ? strerror(errno) : "");
3911  return false;
3912  }
3913 #endif
3914 
3915  /*
3916  * No canonicalize_path() here. EDIT.EXE run from CMD.EXE prepends the
3917  * current directory to the supplied path unless we use only
3918  * backslashes, so we do that.
3919  */
3920 #ifndef WIN32
3921  snprintf(fnametmp, sizeof(fnametmp), "%s%spsql.edit.%d.sql", tmpdir,
3922  "/", (int) getpid());
3923 #else
3924  snprintf(fnametmp, sizeof(fnametmp), "%s%spsql.edit.%d.sql", tmpdir,
3925  "" /* trailing separator already present */ , (int) getpid());
3926 #endif
3927 
3928  fname = (const char *) fnametmp;
3929 
3930  fd = open(fname, O_WRONLY | O_CREAT | O_EXCL, 0600);
3931  if (fd != -1)
3932  stream = fdopen(fd, "w");
3933 
3934  if (fd == -1 || !stream)
3935  {
3936  pg_log_error("could not open temporary file \"%s\": %m", fname);
3937  error = true;
3938  }
3939  else
3940  {
3941  unsigned int ql = query_buf->len;
3942 
3943  /* force newline-termination of what we send to editor */
3944  if (ql > 0 && query_buf->data[ql - 1] != '\n')
3945  {
3946  appendPQExpBufferChar(query_buf, '\n');
3947  ql++;
3948  }
3949 
3950  if (fwrite(query_buf->data, 1, ql, stream) != ql)
3951  {
3952  pg_log_error("%s: %m", fname);
3953 
3954  if (fclose(stream) != 0)
3955  pg_log_error("%s: %m", fname);
3956 
3957  if (remove(fname) != 0)
3958  pg_log_error("%s: %m", fname);
3959 
3960  error = true;
3961  }
3962  else if (fclose(stream) != 0)
3963  {
3964  pg_log_error("%s: %m", fname);
3965  if (remove(fname) != 0)
3966  pg_log_error("%s: %m", fname);
3967  error = true;
3968  }
3969  else
3970  {
3971  struct utimbuf ut;
3972 
3973  /*
3974  * Try to set the file modification time of the temporary file
3975  * a few seconds in the past. Otherwise, the low granularity
3976  * (one second, or even worse on some filesystems) that we can
3977  * portably measure with stat(2) could lead us to not
3978  * recognize a modification, if the user typed very quickly.
3979  *
3980  * This is a rather unlikely race condition, so don't error
3981  * out if the utime(2) call fails --- that would make the cure
3982  * worse than the disease.
3983  */
3984  ut.modtime = ut.actime = time(NULL) - 2;
3985  (void) utime(fname, &ut);
3986  }
3987  }
3988  }
3989 
3990  if (!error && stat(fname, &before) != 0)
3991  {
3992  pg_log_error("%s: %m", fname);
3993  error = true;
3994  }
3995 
3996  /* call editor */
3997  if (!error)
3998  error = !editFile(fname, lineno);
3999 
4000  if (!error && stat(fname, &after) != 0)
4001  {
4002  pg_log_error("%s: %m", fname);
4003  error = true;
4004  }
4005 
4006  /* file was edited if the size or modification time has changed */
4007  if (!error &&
4008  (before.st_size != after.st_size ||
4009  before.st_mtime != after.st_mtime))
4010  {
4011  stream = fopen(fname, PG_BINARY_R);
4012  if (!stream)
4013  {
4014  pg_log_error("%s: %m", fname);
4015  error = true;
4016  }
4017  else
4018  {
4019  /* read file back into query_buf */
4020  char line[1024];
4021 
4022  resetPQExpBuffer(query_buf);
4023  while (fgets(line, sizeof(line), stream) != NULL)
4024  appendPQExpBufferStr(query_buf, line);
4025 
4026  if (ferror(stream))
4027  {
4028  pg_log_error("%s: %m", fname);
4029  error = true;
4030  resetPQExpBuffer(query_buf);
4031  }
4032  else if (edited)
4033  {
4034  *edited = true;
4035  }
4036 
4037  fclose(stream);
4038  }
4039  }
4040  else
4041  {
4042  /*
4043  * If the file was not modified, and the caller requested it, discard
4044  * the query buffer.
4045  */
4046  if (discard_on_quit)
4047  resetPQExpBuffer(query_buf);
4048  }
4049 
4050  /* remove temp file */
4051  if (!filename_arg)
4052  {
4053  if (remove(fname) == -1)
4054  {
4055  pg_log_error("%s: %m", fname);
4056  error = true;
4057  }
4058  }
4059 
4060  return !error;
4061 }
#define PG_BINARY_R
Definition: c.h:1270
static bool editFile(const char *fname, int lineno)
Definition: command.c:3800
#define MAXPGPATH
#define strerror
Definition: port.h:238
#define snprintf
Definition: port.h:225
void resetPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:148
void appendPQExpBufferChar(PQExpBuffer str, char ch)
Definition: pqexpbuffer.c:380
static int fd(const char *x, int i)
Definition: preproc-init.c:105
static int before(chr x, chr y)
Definition: regc_locale.c:492
static void error(void)
Definition: sql-dyntest.c:147
#define stat
Definition: win32_port.h:283

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 4229 of file command.c.

4230 {
4231  size_t vallen = 0;
4232 
4233  Assert(param != NULL);
4234 
4235  if (value)
4236  vallen = strlen(value);
4237 
4238  /* set format */
4239  if (strcmp(param, "format") == 0)
4240  {
4241  static const struct fmt
4242  {
4243  const char *name;
4244  enum printFormat number;
4245  } formats[] =
4246  {
4247  /* remember to update error message below when adding more */
4248  {"aligned", PRINT_ALIGNED},
4249  {"asciidoc", PRINT_ASCIIDOC},
4250  {"csv", PRINT_CSV},
4251  {"html", PRINT_HTML},
4252  {"latex", PRINT_LATEX},
4253  {"troff-ms", PRINT_TROFF_MS},
4254  {"unaligned", PRINT_UNALIGNED},
4255  {"wrapped", PRINT_WRAPPED}
4256  };
4257 
4258  if (!value)
4259  ;
4260  else
4261  {
4262  int match_pos = -1;
4263 
4264  for (int i = 0; i < lengthof(formats); i++)
4265  {
4266  if (pg_strncasecmp(formats[i].name, value, vallen) == 0)
4267  {
4268  if (match_pos < 0)
4269  match_pos = i;
4270  else
4271  {
4272  pg_log_error("\\pset: ambiguous abbreviation \"%s\" matches both \"%s\" and \"%s\"",
4273  value,
4274  formats[match_pos].name, formats[i].name);
4275  return false;
4276  }
4277  }
4278  }
4279  if (match_pos >= 0)
4280  popt->topt.format = formats[match_pos].number;
4281  else if (pg_strncasecmp("latex-longtable", value, vallen) == 0)
4282  {
4283  /*
4284  * We must treat latex-longtable specially because latex is a
4285  * prefix of it; if both were in the table above, we'd think
4286  * "latex" is ambiguous.
4287  */
4289  }
4290  else
4291  {
4292  pg_log_error("\\pset: allowed formats are aligned, asciidoc, csv, html, latex, latex-longtable, troff-ms, unaligned, wrapped");
4293  return false;
4294  }
4295  }
4296  }
4297 
4298  /* set table line style */
4299  else if (strcmp(param, "linestyle") == 0)
4300  {
4301  if (!value)
4302  ;
4303  else if (pg_strncasecmp("ascii", value, vallen) == 0)
4304  popt->topt.line_style = &pg_asciiformat;
4305  else if (pg_strncasecmp("old-ascii", value, vallen) == 0)
4307  else if (pg_strncasecmp("unicode", value, vallen) == 0)
4308  popt->topt.line_style = &pg_utf8format;
4309  else
4310  {
4311  pg_log_error("\\pset: allowed line styles are ascii, old-ascii, unicode");
4312  return false;
4313  }
4314  }
4315 
4316  /* set unicode border line style */
4317  else if (strcmp(param, "unicode_border_linestyle") == 0)
4318  {
4319  if (!value)
4320  ;
4321  else if (set_unicode_line_style(value, vallen,
4323  refresh_utf8format(&(popt->topt));
4324  else
4325  {
4326  pg_log_error("\\pset: allowed Unicode border line styles are single, double");
4327  return false;
4328  }
4329  }
4330 
4331  /* set unicode column line style */
4332  else if (strcmp(param, "unicode_column_linestyle") == 0)
4333  {
4334  if (!value)
4335  ;
4336  else if (set_unicode_line_style(value, vallen,
4338  refresh_utf8format(&(popt->topt));
4339  else
4340  {
4341  pg_log_error("\\pset: allowed Unicode column line styles are single, double");
4342  return false;
4343  }
4344  }
4345 
4346  /* set unicode header line style */
4347  else if (strcmp(param, "unicode_header_linestyle") == 0)
4348  {
4349  if (!value)
4350  ;
4351  else if (set_unicode_line_style(value, vallen,
4353  refresh_utf8format(&(popt->topt));
4354  else
4355  {
4356  pg_log_error("\\pset: allowed Unicode header line styles are single, double");
4357  return false;
4358  }
4359  }
4360 
4361  /* set border style/width */
4362  else if (strcmp(param, "border") == 0)
4363  {
4364  if (value)
4365  popt->topt.border = atoi(value);
4366  }
4367 
4368  /* set expanded/vertical mode */
4369  else if (strcmp(param, "x") == 0 ||
4370  strcmp(param, "expanded") == 0 ||
4371  strcmp(param, "vertical") == 0)
4372  {
4373  if (value && pg_strcasecmp(value, "auto") == 0)
4374  popt->topt.expanded = 2;
4375  else if (value)
4376  {
4377  bool on_off;
4378 
4379  if (ParseVariableBool(value, NULL, &on_off))
4380  popt->topt.expanded = on_off ? 1 : 0;
4381  else
4382  {
4383  PsqlVarEnumError(param, value, "on, off, auto");
4384  return false;
4385  }
4386  }
4387  else
4388  popt->topt.expanded = !popt->topt.expanded;
4389  }
4390 
4391  /* field separator for CSV format */
4392  else if (strcmp(param, "csv_fieldsep") == 0)
4393  {
4394  if (value)
4395  {
4396  /* CSV separator has to be a one-byte character */
4397  if (strlen(value) != 1)
4398  {
4399  pg_log_error("\\pset: csv_fieldsep must be a single one-byte character");
4400  return false;
4401  }
4402  if (value[0] == '"' || value[0] == '\n' || value[0] == '\r')
4403  {
4404  pg_log_error("\\pset: csv_fieldsep cannot be a double quote, a newline, or a carriage return");
4405  return false;
4406  }
4407  popt->topt.csvFieldSep[0] = value[0];
4408  }
4409  }
4410 
4411  /* locale-aware numeric output */
4412  else if (strcmp(param, "numericlocale") == 0)
4413  {
4414  if (value)
4415  return ParseVariableBool(value, param, &popt->topt.numericLocale);
4416  else
4417  popt->topt.numericLocale = !popt->topt.numericLocale;
4418  }
4419 
4420  /* null display */
4421  else if (strcmp(param, "null") == 0)
4422  {
4423  if (value)
4424  {
4425  free(popt->nullPrint);
4426  popt->nullPrint = pg_strdup(value);
4427  }
4428  }
4429 
4430  /* field separator for unaligned text */
4431  else if (strcmp(param, "fieldsep") == 0)
4432  {
4433  if (value)
4434  {
4435  free(popt->topt.fieldSep.separator);
4437  popt->topt.fieldSep.separator_zero = false;
4438  }
4439  }
4440 
4441  else if (strcmp(param, "fieldsep_zero") == 0)
4442  {
4443  free(popt->topt.fieldSep.separator);
4444  popt->topt.fieldSep.separator = NULL;
4445  popt->topt.fieldSep.separator_zero = true;
4446  }
4447 
4448  /* record separator for unaligned text */
4449  else if (strcmp(param, "recordsep") == 0)
4450  {
4451  if (value)
4452  {
4453  free(popt->topt.recordSep.separator);
4455  popt->topt.recordSep.separator_zero = false;
4456  }
4457  }
4458 
4459  else if (strcmp(param, "recordsep_zero") == 0)
4460  {
4461  free(popt->topt.recordSep.separator);
4462  popt->topt.recordSep.separator = NULL;
4463  popt->topt.recordSep.separator_zero = true;
4464  }
4465 
4466  /* toggle between full and tuples-only format */
4467  else if (strcmp(param, "t") == 0 || strcmp(param, "tuples_only") == 0)
4468  {
4469  if (value)
4470  return ParseVariableBool(value, param, &popt->topt.tuples_only);
4471  else
4472  popt->topt.tuples_only = !popt->topt.tuples_only;
4473  }
4474 
4475  /* set title override */
4476  else if (strcmp(param, "C") == 0 || strcmp(param, "title") == 0)
4477  {
4478  free(popt->title);
4479  if (!value)
4480  popt->title = NULL;
4481  else
4482  popt->title = pg_strdup(value);
4483  }
4484 
4485  /* set HTML table tag options */
4486  else if (strcmp(param, "T") == 0 || strcmp(param, "tableattr") == 0)
4487  {
4488  free(popt->topt.tableAttr);
4489  if (!value)
4490  popt->topt.tableAttr = NULL;
4491  else
4492  popt->topt.tableAttr = pg_strdup(value);
4493  }
4494 
4495  /* toggle use of pager */
4496  else if (strcmp(param, "pager") == 0)
4497  {
4498  if (value && pg_strcasecmp(value, "always") == 0)
4499  popt->topt.pager = 2;
4500  else if (value)
4501  {
4502  bool on_off;
4503 
4504  if (!ParseVariableBool(value, NULL, &on_off))
4505  {
4506  PsqlVarEnumError(param, value, "on, off, always");
4507  return false;
4508  }
4509  popt->topt.pager = on_off ? 1 : 0;
4510  }
4511  else if (popt->topt.pager == 1)
4512  popt->topt.pager = 0;
4513  else
4514  popt->topt.pager = 1;
4515  }
4516 
4517  /* set minimum lines for pager use */
4518  else if (strcmp(param, "pager_min_lines") == 0)
4519  {
4520  if (value)
4521  popt->topt.pager_min_lines = atoi(value);
4522  }
4523 
4524  /* disable "(x rows)" footer */
4525  else if (strcmp(param, "footer") == 0)
4526  {
4527  if (value)
4528  return ParseVariableBool(value, param, &popt->topt.default_footer);
4529  else
4530  popt->topt.default_footer = !popt->topt.default_footer;
4531  }
4532 
4533  /* set border style/width */
4534  else if (strcmp(param, "columns") == 0)
4535  {
4536  if (value)
4537  popt->topt.columns = atoi(value);
4538  }
4539  else
4540  {
4541  pg_log_error("\\pset: unknown option: %s", param);
4542  return false;
4543  }
4544 
4545  if (!quiet)
4546  printPsetInfo(param, &pset.popt);
4547 
4548  return true;
4549 }
#define lengthof(array)
Definition: c.h:734
static bool set_unicode_line_style(const char *value, size_t vallen, unicode_linestyle *linestyle)
Definition: command.c:4186
static bool printPsetInfo(const char *param, printQueryOpt *popt)
Definition: command.c:4555
const char * name
Definition: encode.c:561
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
void refresh_utf8format(const printTableOpt *opt)
Definition: print.c:3632
const printTextFormat pg_asciiformat
Definition: print.c:56
const printTextFormat pg_asciiformat_old
Definition: print.c:77
printTextFormat pg_utf8format
Definition: print.c:99
printFormat
Definition: print.h:29
#define free(a)
Definition: header.h:65
static struct @151 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:169
char * nullPrint
Definition: print.h:170
char * title
Definition: print.h:171
unsigned short int expanded
Definition: print.h:102
unicode_linestyle unicode_border_linestyle
Definition: print.h:125
bool tuples_only
Definition: print.h:110
int columns
Definition: print.h:124
enum printFormat format
Definition: print.h:101
struct separator fieldSep
Definition: print.h:116
struct separator recordSep
Definition: print.h:117
char csvFieldSep[2]
Definition: print.h:118
const printTextFormat * line_style
Definition: print.h:115
bool default_footer
Definition: print.h:113
int pager_min_lines
Definition: print.h:108
unsigned short int pager
Definition: print.h:106
char * tableAttr
Definition: print.h:121
bool numericLocale
Definition: print.h:119
unsigned short int border
Definition: print.h:104
unicode_linestyle unicode_header_linestyle
Definition: print.h:127
unicode_linestyle unicode_column_linestyle
Definition: print.h:126
bool separator_zero
Definition: print.h:96
char * separator
Definition: print.h:95
void PsqlVarEnumError(const char *name, const char *value, const char *suggestions)
Definition: variables.c:417
bool ParseVariableBool(const char *value, const char *name, bool *result)
Definition: variables.c:107

References Assert(), printTableOpt::border, printTableOpt::columns, printTableOpt::csvFieldSep, printTableOpt::default_footer, printTableOpt::expanded, printTableOpt::fieldSep, fmt, printTableOpt::format, free, i, lengthof, printTableOpt::line_style, name, printQueryOpt::nullPrint, printTableOpt::numericLocale, printTableOpt::pager, printTableOpt::pager_min_lines, ParseVariableBool(), 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, 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 4925 of file command.c.

4926 {
4927  int result;
4928 
4929  if (!command)
4930  {
4931  char *sys;
4932  const char *shellName;
4933 
4934  shellName = getenv("SHELL");
4935 #ifdef WIN32
4936  if (shellName == NULL)
4937  shellName = getenv("COMSPEC");
4938 #endif
4939  if (shellName == NULL)
4940  shellName = DEFAULT_SHELL;
4941 
4942  /* See EDITOR handling comment for an explanation */
4943 #ifndef WIN32
4944  sys = psprintf("exec %s", shellName);
4945 #else
4946  sys = psprintf("\"%s\"", shellName);
4947 #endif
4948  result = system(sys);
4949  free(sys);
4950  }
4951  else
4952  result = system(command);
4953 
4954  if (result == 127 || result == -1)
4955  {
4956  pg_log_error("\\!: failed");
4957  return false;
4958  }
4959  return true;
4960 }
#define DEFAULT_SHELL
Definition: command.c:4915
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46

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

Referenced by exec_command_shell_escape().

◆ do_watch()

static bool do_watch ( PQExpBuffer  query_buf,
double  sleep 
)
static

Definition at line 4969 of file command.c.

4970 {
4971  long sleep_ms = (long) (sleep * 1000);
4972  printQueryOpt myopt = pset.popt;
4973  const char *strftime_fmt;
4974  const char *user_title;
4975  char *title;
4976  const char *pagerprog = NULL;
4977  FILE *pagerpipe = NULL;
4978  int title_len;
4979  int res = 0;
4980 #ifdef HAVE_POSIX_DECL_SIGWAIT
4981  sigset_t sigalrm_sigchld_sigint;
4982  sigset_t sigalrm_sigchld;
4983  sigset_t sigint;
4984  struct itimerval interval;
4985  bool done = false;
4986 #endif
4987 
4988  if (!query_buf || query_buf->len <= 0)
4989  {
4990  pg_log_error("\\watch cannot be used with an empty query");
4991  return false;
4992  }
4993 
4994 #ifdef HAVE_POSIX_DECL_SIGWAIT
4995  sigemptyset(&sigalrm_sigchld_sigint);
4996  sigaddset(&sigalrm_sigchld_sigint, SIGCHLD);
4997  sigaddset(&sigalrm_sigchld_sigint, SIGALRM);
4998  sigaddset(&sigalrm_sigchld_sigint, SIGINT);
4999 
5000  sigemptyset(&sigalrm_sigchld);
5001  sigaddset(&sigalrm_sigchld, SIGCHLD);
5002  sigaddset(&sigalrm_sigchld, SIGALRM);
5003 
5004  sigemptyset(&sigint);
5005  sigaddset(&sigint, SIGINT);
5006 
5007  /*
5008  * Block SIGALRM and SIGCHLD before we start the timer and the pager (if
5009  * configured), to avoid races. sigwait() will receive them.
5010  */
5011  sigprocmask(SIG_BLOCK, &sigalrm_sigchld, NULL);
5012 
5013  /*
5014  * Set a timer to interrupt sigwait() so we can run the query at the
5015  * requested intervals.
5016  */
5017  interval.it_value.tv_sec = sleep_ms / 1000;
5018  interval.it_value.tv_usec = (sleep_ms % 1000) * 1000;
5019  interval.it_interval = interval.it_value;
5020  if (setitimer(ITIMER_REAL, &interval, NULL) < 0)
5021  {
5022  pg_log_error("could not set timer: %m");
5023  done = true;
5024  }
5025 #endif
5026 
5027  /*
5028  * For \watch, we ignore the size of the result and always use the pager
5029  * if PSQL_WATCH_PAGER is set. We also ignore the regular PSQL_PAGER or
5030  * PAGER environment variables, because traditional pagers probably won't
5031  * be very useful for showing a stream of results.
5032  */
5033 #ifdef HAVE_POSIX_DECL_SIGWAIT
5034  pagerprog = getenv("PSQL_WATCH_PAGER");
5035 #endif
5036  if (pagerprog && myopt.topt.pager)
5037  {
5039  pagerpipe = popen(pagerprog, "w");
5040 
5041  if (!pagerpipe)
5042  /* silently proceed without pager */
5044  }
5045 
5046  /*
5047  * Choose format for timestamps. We might eventually make this a \pset
5048  * option. In the meantime, using a variable for the format suppresses
5049  * overly-anal-retentive gcc warnings about %c being Y2K sensitive.
5050  */
5051  strftime_fmt = "%c";
5052 
5053  /*
5054  * Set up rendering options, in particular, disable the pager unless
5055  * PSQL_WATCH_PAGER was successfully launched.
5056  */
5057  if (!pagerpipe)
5058  myopt.topt.pager = 0;
5059 
5060 
5061  /*
5062  * If there's a title in the user configuration, make sure we have room
5063  * for it in the title buffer. Allow 128 bytes for the timestamp plus 128
5064  * bytes for the rest.
5065  */
5066  user_title = myopt.title;
5067  title_len = (user_title ? strlen(user_title) : 0) + 256;
5068  title = pg_malloc(title_len);
5069 
5070  for (;;)
5071  {
5072  time_t timer;
5073  char timebuf[128];
5074 
5075  /*
5076  * Prepare title for output. Note that we intentionally include a
5077  * newline at the end of the title; this is somewhat historical but it
5078  * makes for reasonably nicely formatted output in simple cases.
5079  */
5080  timer = time(NULL);
5081  strftime(timebuf, sizeof(timebuf), strftime_fmt, localtime(&timer));
5082 
5083  if (user_title)
5084  snprintf(title, title_len, _("%s\t%s (every %gs)\n"),
5085  user_title, timebuf, sleep);
5086  else
5087  snprintf(title, title_len, _("%s (every %gs)\n"),
5088  timebuf, sleep);
5089  myopt.title = title;
5090 
5091  /* Run the query and print out the result */
5092  res = PSQLexecWatch(query_buf->data, &myopt, pagerpipe);
5093 
5094  /*
5095  * PSQLexecWatch handles the case where we can no longer repeat the
5096  * query, and returns 0 or -1.
5097  */
5098  if (res <= 0)
5099  break;
5100 
5101  if (pagerpipe && ferror(pagerpipe))
5102  break;
5103 
5104 #ifndef HAVE_POSIX_DECL_SIGWAIT
5105 
5106  /*
5107  * Set up cancellation of 'watch' via SIGINT. We redo this each time
5108  * through the loop since it's conceivable something inside
5109  * PSQLexecWatch could change sigint_interrupt_jmp.
5110  */
5111  if (sigsetjmp(sigint_interrupt_jmp, 1) != 0)
5112  break;
5113 
5114  /*
5115  * Enable 'watch' cancellations and wait a while before running the
5116  * query again. Break the sleep into short intervals (at most 1s).
5117  */
5118  sigint_interrupt_enabled = true;
5119  for (long i = sleep_ms; i > 0;)
5120  {
5121  long s = Min(i, 1000L);
5122 
5123  pg_usleep(s * 1000L);
5124  if (cancel_pressed)
5125  break;
5126  i -= s;
5127  }
5128  sigint_interrupt_enabled = false;
5129 #else
5130  /* sigwait() will handle SIGINT. */
5131  sigprocmask(SIG_BLOCK, &sigint, NULL);
5132  if (cancel_pressed)
5133  done = true;
5134 
5135  /* Wait for SIGINT, SIGCHLD or SIGALRM. */
5136  while (!done)
5137  {
5138  int signal_received;
5139 
5140  errno = sigwait(&sigalrm_sigchld_sigint, &signal_received);
5141  if (errno != 0)
5142  {
5143  /* Some other signal arrived? */
5144  if (errno == EINTR)
5145  continue;
5146  else
5147  {
5148  pg_log_error("could not wait for signals: %m");
5149  done = true;
5150  break;
5151  }
5152  }
5153  /* On ^C or pager exit, it's time to stop running the query. */
5154  if (signal_received == SIGINT || signal_received == SIGCHLD)
5155  done = true;
5156  /* Otherwise, we must have SIGALRM. Time to run the query again. */
5157  break;
5158  }
5159 
5160  /* Unblock SIGINT so that slow queries can be interrupted. */
5161  sigprocmask(SIG_UNBLOCK, &sigint, NULL);
5162  if (done)
5163  break;
5164 #endif
5165  }
5166 
5167  if (pagerpipe)
5168  {
5169  pclose(pagerpipe);
5171  }
5172 
5173 #ifdef HAVE_POSIX_DECL_SIGWAIT
5174  /* Disable the interval timer. */
5175  memset(&interval, 0, sizeof(interval));
5176  setitimer(ITIMER_REAL, &interval, NULL);
5177  /* Unblock SIGINT, SIGCHLD and SIGALRM. */
5178  sigprocmask(SIG_UNBLOCK, &sigalrm_sigchld_sigint, NULL);
5179 #endif
5180 
5181  pg_free(title);
5182  return (res >= 0);
5183 }
sigjmp_buf sigint_interrupt_jmp
Definition: common.c:250
volatile bool sigint_interrupt_enabled
Definition: common.c:248
int PSQLexecWatch(const char *query, const printQueryOpt *opt, FILE *printQueryFout)
Definition: common.c:611
#define Min(x, y)
Definition: c.h:986
void restore_sigpipe_trap(void)
Definition: print.c:3018
void disable_sigpipe_trap(void)
Definition: print.c:2995
volatile sig_atomic_t cancel_pressed
Definition: print.c:43
void pg_usleep(long microsec)
Definition: signal.c:53
int setitimer(int which, const struct itimerval *value, struct itimerval *ovalue)
Definition: timer.c:86
#define SIGCHLD
Definition: win32_port.h:177
#define EINTR
Definition: win32_port.h:351
#define SIGALRM
Definition: win32_port.h:173
#define ITIMER_REAL
Definition: win32_port.h:195

References _, cancel_pressed, PQExpBufferData::data, disable_sigpipe_trap(), EINTR, 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, sigint_interrupt_enabled, sigint_interrupt_jmp, snprintf, 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 5190 of file command.c.

5191 {
5193  {
5194  printf(_("********* QUERY **********\n"
5195  "%s\n"
5196  "**************************\n\n"), query);
5197  fflush(stdout);
5198  if (pset.logfile)
5199  {
5201  _("********* QUERY **********\n"
5202  "%s\n"
5203  "**************************\n\n"), query);
5204  fflush(pset.logfile);
5205  }
5206 
5208  return false;
5209  }
5210  return true;
5211 }
static void const char fflush(stdout)
#define fprintf
Definition: port.h:229
@ PSQL_ECHO_HIDDEN_NOEXEC
Definition: settings.h:47
@ PSQL_ECHO_HIDDEN_OFF
Definition: settings.h:45
FILE * logfile
Definition: settings.h:116
PSQL_ECHO_HIDDEN echo_hidden
Definition: settings.h:143

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 3800 of file command.c.

3801 {
3802  const char *editorName;
3803  const char *editor_lineno_arg = NULL;
3804  char *sys;
3805  int result;
3806 
3807  Assert(fname != NULL);
3808 
3809  /* Find an editor to use */
3810  editorName = getenv("PSQL_EDITOR");
3811  if (!editorName)
3812  editorName = getenv("EDITOR");
3813  if (!editorName)
3814  editorName = getenv("VISUAL");
3815  if (!editorName)
3816  editorName = DEFAULT_EDITOR;
3817 
3818  /* Get line number argument, if we need it. */
3819  if (lineno > 0)
3820  {
3821  editor_lineno_arg = getenv("PSQL_EDITOR_LINENUMBER_ARG");
3822 #ifdef DEFAULT_EDITOR_LINENUMBER_ARG
3823  if (!editor_lineno_arg)
3824  editor_lineno_arg = DEFAULT_EDITOR_LINENUMBER_ARG;
3825 #endif
3826  if (!editor_lineno_arg)
3827  {
3828  pg_log_error("environment variable PSQL_EDITOR_LINENUMBER_ARG must be set to specify a line number");
3829  return false;
3830  }
3831  }
3832 
3833  /*
3834  * On Unix the EDITOR value should *not* be quoted, since it might include
3835  * switches, eg, EDITOR="pico -t"; it's up to the user to put quotes in it
3836  * if necessary. But this policy is not very workable on Windows, due to
3837  * severe brain damage in their command shell plus the fact that standard
3838  * program paths include spaces.
3839  */
3840 #ifndef WIN32
3841  if (lineno > 0)
3842  sys = psprintf("exec %s %s%d '%s'",
3843  editorName, editor_lineno_arg, lineno, fname);
3844  else
3845  sys = psprintf("exec %s '%s'",
3846  editorName, fname);
3847 #else
3848  if (lineno > 0)
3849  sys = psprintf("\"%s\" %s%d \"%s\"",
3850  editorName, editor_lineno_arg, lineno, fname);
3851  else
3852  sys = psprintf("\"%s\" \"%s\"",
3853  editorName, fname);
3854 #endif
3855  result = system(sys);
3856  if (result == -1)
3857  pg_log_error("could not start editor \"%s\"", editorName);
3858  else if (result == 127)
3859  pg_log_error("could not start /bin/sh");
3860  free(sys);
3861 
3862  return result == 0;
3863 }
#define DEFAULT_EDITOR_LINENUMBER_ARG
Definition: settings.h:23
#define DEFAULT_EDITOR
Definition: settings.h:22

References Assert(), DEFAULT_EDITOR, DEFAULT_EDITOR_LINENUMBER_ARG, 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 286 of file command.c.

291 {
293  bool active_branch = conditional_active(cstack);
294 
295  /*
296  * In interactive mode, warn when we're ignoring a command within a false
297  * \if-branch. But we continue on, so as to parse and discard the right
298  * amount of parameter text. Each individual backslash command subroutine
299  * is responsible for doing nothing after discarding appropriate
300  * arguments, if !active_branch.
301  */
302  if (pset.cur_cmd_interactive && !active_branch &&
303  !is_branching_command(cmd))
304  {
305  pg_log_warning("\\%s command ignored; use \\endif or Ctrl-C to exit current \\if block",
306  cmd);
307  }
308 
309  if (strcmp(cmd, "a") == 0)
310  status = exec_command_a(scan_state, active_branch);
311  else if (strcmp(cmd, "C") == 0)
312  status = exec_command_C(scan_state, active_branch);
313  else if (strcmp(cmd, "c") == 0 || strcmp(cmd, "connect") == 0)
314  status = exec_command_connect(scan_state, active_branch);
315  else if (strcmp(cmd, "cd") == 0)
316  status = exec_command_cd(scan_state, active_branch, cmd);
317  else if (strcmp(cmd, "conninfo") == 0)
318  status = exec_command_conninfo(scan_state, active_branch);
319  else if (pg_strcasecmp(cmd, "copy") == 0)
320  status = exec_command_copy(scan_state, active_branch);
321  else if (strcmp(cmd, "copyright") == 0)
322  status = exec_command_copyright(scan_state, active_branch);
323  else if (strcmp(cmd, "crosstabview") == 0)
324  status = exec_command_crosstabview(scan_state, active_branch);
325  else if (cmd[0] == 'd')
326  status = exec_command_d(scan_state, active_branch, cmd);
327  else if (strcmp(cmd, "e") == 0 || strcmp(cmd, "edit") == 0)
328  status = exec_command_edit(scan_state, active_branch,
329  query_buf, previous_buf);
330  else if (strcmp(cmd, "ef") == 0)
331  status = exec_command_ef_ev(scan_state, active_branch, query_buf, true);
332  else if (strcmp(cmd, "ev") == 0)
333  status = exec_command_ef_ev(scan_state, active_branch, query_buf, false);
334  else if (strcmp(cmd, "echo") == 0 || strcmp(cmd, "qecho") == 0 ||
335  strcmp(cmd, "warn") == 0)
336  status = exec_command_echo(scan_state, active_branch, cmd);
337  else if (strcmp(cmd, "elif") == 0)
338  status = exec_command_elif(scan_state, cstack, query_buf);
339  else if (strcmp(cmd, "else") == 0)
340  status = exec_command_else(scan_state, cstack, query_buf);
341  else if (strcmp(cmd, "endif") == 0)
342  status = exec_command_endif(scan_state, cstack, query_buf);
343  else if (strcmp(cmd, "encoding") == 0)
344  status = exec_command_encoding(scan_state, active_branch);
345  else if (strcmp(cmd, "errverbose") == 0)
346  status = exec_command_errverbose(scan_state, active_branch);
347  else if (strcmp(cmd, "f") == 0)
348  status = exec_command_f(scan_state, active_branch);
349  else if (strcmp(cmd, "g") == 0 || strcmp(cmd, "gx") == 0)
350  status = exec_command_g(scan_state, active_branch, cmd);
351  else if (strcmp(cmd, "gdesc") == 0)
352  status = exec_command_gdesc(scan_state, active_branch);
353  else if (strcmp(cmd, "getenv") == 0)
354  status = exec_command_getenv(scan_state, active_branch, cmd);
355  else if (strcmp(cmd, "gexec") == 0)
356  status = exec_command_gexec(scan_state, active_branch);
357  else if (strcmp(cmd, "gset") == 0)
358  status = exec_command_gset(scan_state, active_branch);
359  else if (strcmp(cmd, "h") == 0 || strcmp(cmd, "help") == 0)
360  status = exec_command_help(scan_state, active_branch);
361  else if (strcmp(cmd, "H") == 0 || strcmp(cmd, "html") == 0)
362  status = exec_command_html(scan_state, active_branch);
363  else if (strcmp(cmd, "i") == 0 || strcmp(cmd, "include") == 0 ||
364  strcmp(cmd, "ir") == 0 || strcmp(cmd, "include_relative") == 0)
365  status = exec_command_include(scan_state, active_branch, cmd);
366  else if (strcmp(cmd, "if") == 0)
367  status = exec_command_if(scan_state, cstack, query_buf);
368  else if (strcmp(cmd, "l") == 0 || strcmp(cmd, "list") == 0 ||
369  strcmp(cmd, "l+") == 0 || strcmp(cmd, "list+") == 0)
370  status = exec_command_list(scan_state, active_branch, cmd);
371  else if (strncmp(cmd, "lo_", 3) == 0)
372  status = exec_command_lo(scan_state, active_branch, cmd);
373  else if (strcmp(cmd, "o") == 0 || strcmp(cmd, "out") == 0)
374  status = exec_command_out(scan_state, active_branch);
375  else if (strcmp(cmd, "p") == 0 || strcmp(cmd, "print") == 0)
376  status = exec_command_print(scan_state, active_branch,
377  query_buf, previous_buf);
378  else if (strcmp(cmd, "password") == 0)
379  status = exec_command_password(scan_state, active_branch);
380  else if (strcmp(cmd, "prompt") == 0)
381  status = exec_command_prompt(scan_state, active_branch, cmd);
382  else if (strcmp(cmd, "pset") == 0)
383  status = exec_command_pset(scan_state, active_branch);
384  else if (strcmp(cmd, "q") == 0 || strcmp(cmd, "quit") == 0)
385  status = exec_command_quit(scan_state, active_branch);
386  else if (strcmp(cmd, "r") == 0 || strcmp(cmd, "reset") == 0)
387  status = exec_command_reset(scan_state, active_branch, query_buf);
388  else if (strcmp(cmd, "s") == 0)
389  status = exec_command_s(scan_state, active_branch);
390  else if (strcmp(cmd, "set") == 0)
391  status = exec_command_set(scan_state, active_branch);
392  else if (strcmp(cmd, "setenv") == 0)
393  status = exec_command_setenv(scan_state, active_branch, cmd);
394  else if (strcmp(cmd, "sf") == 0 || strcmp(cmd, "sf+") == 0)
395  status = exec_command_sf_sv(scan_state, active_branch, cmd, true);
396  else if (strcmp(cmd, "sv") == 0 || strcmp(cmd, "sv+") == 0)
397  status = exec_command_sf_sv(scan_state, active_branch, cmd, false);
398  else if (strcmp(cmd, "t") == 0)
399  status = exec_command_t(scan_state, active_branch);
400  else if (strcmp(cmd, "T") == 0)
401  status = exec_command_T(scan_state, active_branch);
402  else if (strcmp(cmd, "timing") == 0)
403  status = exec_command_timing(scan_state, active_branch);
404  else if (strcmp(cmd, "unset") == 0)
405  status = exec_command_unset(scan_state, active_branch, cmd);
406  else if (strcmp(cmd, "w") == 0 || strcmp(cmd, "write") == 0)
407  status = exec_command_write(scan_state, active_branch, cmd,
408  query_buf, previous_buf);
409  else if (strcmp(cmd, "watch") == 0)
410  status = exec_command_watch(scan_state, active_branch,
411  query_buf, previous_buf);
412  else if (strcmp(cmd, "x") == 0)
413  status = exec_command_x(scan_state, active_branch);
414  else if (strcmp(cmd, "z") == 0)
415  status = exec_command_z(scan_state, active_branch);
416  else if (strcmp(cmd, "!") == 0)
417  status = exec_command_shell_escape(scan_state, active_branch);
418  else if (strcmp(cmd, "?") == 0)
419  status = exec_command_slash_command_help(scan_state, active_branch);
420  else
422 
423  /*
424  * All the commands that return PSQL_CMD_SEND want to execute previous_buf
425  * if query_buf is empty. For convenience we implement that here, not in
426  * the individual command subroutines.
427  */
428  if (status == PSQL_CMD_SEND)
429  (void) copy_previous_query(query_buf, previous_buf);
430 
431  return status;
432 }
static backslashResult exec_command_endif(PsqlScanState scan_state, ConditionalStack cstack, PQExpBuffer query_buf)
Definition: command.c:1867
static backslashResult exec_command_copyright(PsqlScanState scan_state, bool active_branch)
Definition: command.c:677
static backslashResult exec_command_errverbose(PsqlScanState scan_state, bool active_branch)
Definition: command.c:1303
static backslashResult exec_command_print(PsqlScanState scan_state, bool active_branch, PQExpBuffer query_buf, PQExpBuffer previous_buf)
Definition: command.c:2037
static backslashResult exec_command_html(PsqlScanState scan_state, bool active_branch)
Definition: command.c:1620
static bool copy_previous_query(PQExpBuffer query_buf, PQExpBuffer previous_buf)
Definition: command.c:3084
static backslashResult exec_command_g(PsqlScanState scan_state, bool active_branch, const char *cmd)
Definition: command.c:1361
static backslashResult exec_command_T(PsqlScanState scan_state, bool active_branch)
Definition: command.c:2561
static backslashResult exec_command_gdesc(PsqlScanState scan_state, bool active_branch)
Definition: command.c:1489
static backslashResult exec_command_help(PsqlScanState scan_state, bool active_branch)
Definition: command.c:1589
static backslashResult exec_command_a(PsqlScanState scan_state, bool active_branch)
Definition: command.c:441
static backslashResult exec_command_z(PsqlScanState scan_state, bool active_branch)
Definition: command.c:2795
static backslashResult exec_command_password(PsqlScanState scan_state, bool active_branch)
Definition: command.c:2063
static backslashResult exec_command_x(PsqlScanState scan_state, bool active_branch)
Definition: command.c:2773
static backslashResult exec_command_if(PsqlScanState scan_state, ConditionalStack cstack, PQExpBuffer query_buf)
Definition: command.c:1680
static backslashResult exec_command_elif(PsqlScanState scan_state, ConditionalStack cstack, PQExpBuffer query_buf)
Definition: command.c:1726
static backslashResult exec_command_f(PsqlScanState scan_state, bool active_branch)
Definition: command.c:1333
static backslashResult exec_command_reset(PsqlScanState scan_state, bool active_branch, PQExpBuffer query_buf)
Definition: command.c:2302
static backslashResult exec_command_out(PsqlScanState scan_state, bool active_branch)
Definition: command.c:2014
static backslashResult exec_command_echo(PsqlScanState scan_state, bool active_branch, const char *cmd)
Definition: command.c:1220
static backslashResult exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
Definition: command.c:713
static backslashResult exec_command_shell_escape(PsqlScanState scan_state, bool active_branch)
Definition: command.c:2818
static backslashResult exec_command_cd(PsqlScanState scan_state, bool active_branch, const char *cmd)
Definition: command.c:546
static backslashResult exec_command_gset(PsqlScanState scan_state, bool active_branch)
Definition: command.c:1560
static backslashResult exec_command_ef_ev(PsqlScanState scan_state, bool active_branch, PQExpBuffer query_buf, bool is_func)
Definition: command.c:1112
static backslashResult exec_command_unset(PsqlScanState scan_state, bool active_branch, const char *cmd)
Definition: command.c:2615
static backslashResult exec_command_set(PsqlScanState scan_state, bool active_branch)
Definition: command.c:2347
static backslashResult exec_command_s(PsqlScanState scan_state, bool active_branch)
Definition: command.c:2320
static backslashResult exec_command_prompt(PsqlScanState scan_state, bool active_branch, const char *cmd)
Definition: command.c:2155
static backslashResult exec_command_watch(PsqlScanState scan_state, bool active_branch, PQExpBuffer query_buf, PQExpBuffer previous_buf)
Definition: command.c:2734
static backslashResult exec_command_include(PsqlScanState scan_state, bool active_branch, const char *cmd)
Definition: command.c:1639
static backslashResult exec_command_list(PsqlScanState scan_state, bool active_branch, const char *cmd)
Definition: command.c:1907
static backslashResult exec_command_timing(PsqlScanState scan_state, bool active_branch)
Definition: command.c:2583
static backslashResult exec_command_C(PsqlScanState scan_state, bool active_branch)
Definition: command.c:460
static backslashResult exec_command_encoding(PsqlScanState scan_state, bool active_branch)
Definition: command.c:1265
static backslashResult exec_command_edit(PsqlScanState scan_state, bool active_branch, PQExpBuffer query_buf, PQExpBuffer previous_buf)
Definition: command.c:1022
static backslashResult exec_command_else(PsqlScanState scan_state, ConditionalStack cstack, PQExpBuffer query_buf)
Definition: command.c:1802
static backslashResult exec_command_conninfo(PsqlScanState scan_state, bool active_branch)
Definition: command.c:611
static backslashResult exec_command_copy(PsqlScanState scan_state, bool active_branch)
Definition: command.c:655
static backslashResult exec_command_slash_command_help(PsqlScanState scan_state, bool active_branch)
Definition: command.c:2840
static backslashResult exec_command_crosstabview(PsqlScanState scan_state, bool active_branch)
Definition: command.c:689
static backslashResult exec_command_pset(PsqlScanState scan_state, bool active_branch)
Definition: command.c:2234
static backslashResult exec_command_t(PsqlScanState scan_state, bool active_branch)
Definition: command.c:2539
static backslashResult exec_command_write(PsqlScanState scan_state, bool active_branch, const char *cmd, PQExpBuffer query_buf, PQExpBuffer previous_buf)
Definition: command.c:2645
static backslashResult exec_command_sf_sv(PsqlScanState scan_state, bool active_branch, const char *cmd, bool is_func)
Definition: command.c:2448
static bool is_branching_command(const char *cmd)
Definition: command.c:3022
static backslashResult exec_command_connect(PsqlScanState scan_state, bool active_branch)
Definition: command.c:493
static backslashResult exec_command_gexec(PsqlScanState scan_state, bool active_branch)
Definition: command.c:1543
static backslashResult exec_command_lo(PsqlScanState scan_state, bool active_branch, const char *cmd)
Definition: command.c:1936
static backslashResult exec_command_getenv(PsqlScanState scan_state, bool active_branch, const char *cmd)
Definition: command.c:1506
static backslashResult exec_command_quit(PsqlScanState scan_state, bool active_branch)
Definition: command.c:2288
static backslashResult exec_command_setenv(PsqlScanState scan_state, bool active_branch, const char *cmd)
Definition: command.c:2400
@ 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
static void static void status(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:229
#define pg_log_warning(...)
Definition: pgfnames.c:24

References conditional_active(), copy_previous_query(), _psqlSettings::cur_cmd_interactive, exec_command_a(), 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, PSQL_CMD_UNKNOWN, and status().

Referenced by HandleSlashCmds().

◆ exec_command_a()

static backslashResult exec_command_a ( PsqlScanState  scan_state,
bool  active_branch 
)
static

Definition at line 441 of file command.c.

442 {
443  bool success = true;
444 
445  if (active_branch)
446  {
448  success = do_pset("format", "aligned", &pset.popt, pset.quiet);
449  else
450  success = do_pset("format", "unaligned", &pset.popt, pset.quiet);
451  }
452 
454 }
bool do_pset(const char *param, const char *value, printQueryOpt *popt, bool quiet)
Definition: command.c:4229
@ 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_C()

static backslashResult exec_command_C ( PsqlScanState  scan_state,
bool  active_branch 
)
static

Definition at line 460 of file command.c.

461 {
462  bool success = true;
463 
464  if (active_branch)
465  {
466  char *opt = psql_scan_slash_option(scan_state,
467  OT_NORMAL, NULL, true);
468 
469  success = do_pset("title", opt, &pset.popt, pset.quiet);
470  free(opt);
471  }
472  else
473  ignore_slash_options(scan_state);
474 
476 }
static void ignore_slash_options(PsqlScanState scan_state)
Definition: command.c:2975
@ OT_NORMAL
Definition: psqlscanslash.h:17
char * psql_scan_slash_option(PsqlScanState state, enum slash_option_type type, char *quote, bool semicolon)

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 546 of file command.c.

547 {
548  bool success = true;
549 
550  if (active_branch)
551  {
552  char *opt = psql_scan_slash_option(scan_state,
553  OT_NORMAL, NULL, true);
554  char *dir;
555 
556  if (opt)
557  dir = opt;
558  else
559  {
560 #ifndef WIN32
561  /* This should match get_home_path() */
562  dir = getenv("HOME");
563  if (dir == NULL || dir[0] == '\0')
564  {
565  uid_t user_id = geteuid();
566  struct passwd *pw;
567 
568  errno = 0; /* clear errno before call */
569  pw = getpwuid(user_id);
570  if (pw)
571  dir = pw->pw_dir;
572  else
573  {
574  pg_log_error("could not get home directory for user ID %ld: %s",
575  (long) user_id,
576  errno ? strerror(errno) : _("user does not exist"));
577  success = false;
578  }
579  }
580 #else /* WIN32 */
581 
582  /*
583  * On Windows, 'cd' without arguments prints the current
584  * directory, so if someone wants to code this here instead...
585  */
586  dir = "/";
587 #endif /* WIN32 */
588  }
589 
590  if (success &&
591  chdir(dir) < 0)
592  {
593  pg_log_error("\\%s: could not change directory to \"%s\": %m",
594  cmd, dir);
595  success = false;
596  }
597 
598  if (opt)
599  free(opt);
600  }
601  else
602  ignore_slash_options(scan_state);
603 
605 }
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 493 of file command.c.

494 {
495  bool success = true;
496 
497  if (active_branch)
498  {
499  static const char prefix[] = "-reuse-previous=";
500  char *opt1,
501  *opt2,
502  *opt3,
503  *opt4;
504  enum trivalue reuse_previous = TRI_DEFAULT;
505 
506  opt1 = read_connect_arg(scan_state);
507  if (opt1 != NULL && strncmp(opt1, prefix, sizeof(prefix) - 1) == 0)
508  {
509  bool on_off;
510 
511  success = ParseVariableBool(opt1 + sizeof(prefix) - 1,
512  "-reuse-previous",
513  &on_off);
514  if (success)
515  {
516  reuse_previous = on_off ? TRI_YES : TRI_NO;
517  free(opt1);
518  opt1 = read_connect_arg(scan_state);
519  }
520  }
521 
522  if (success) /* give up if reuse_previous was invalid */
523  {
524  opt2 = read_connect_arg(scan_state);
525  opt3 = read_connect_arg(scan_state);
526  opt4 = read_connect_arg(scan_state);
527 
528  success = do_connect(reuse_previous, opt1, opt2, opt3, opt4);
529 
530  free(opt2);
531  free(opt3);
532  free(opt4);
533  }
534  free(opt1);
535  }
536  else
537  ignore_slash_options(scan_state);
538 
540 }
static bool do_connect(enum trivalue reuse_previous_specification, char *dbname, char *user, char *host, char *port)
Definition: command.c:3153
static char * read_connect_arg(PsqlScanState scan_state)
Definition: command.c:2872
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 611 of file command.c.

612 {
613  if (active_branch)
614  {
615  char *db = PQdb(pset.db);
616 
617  if (db == NULL)
618  printf(_("You are currently not connected to a database.\n"));
619  else
620  {
621  char *host = PQhost(pset.db);
622  char *hostaddr = PQhostaddr(pset.db);
623 
624  if (is_unixsock_path(host))
625  {
626  /* hostaddr overrides host */
627  if (hostaddr && *hostaddr)
628  printf(_("You are connected to database \"%s\" as user \"%s\" on address \"%s\" at port \"%s\".\n"),
629  db, PQuser(pset.db), hostaddr, PQport(pset.db));
630  else
631  printf(_("You are connected to database \"%s\" as user \"%s\" via socket in \"%s\" at port \"%s\".\n"),
632  db, PQuser(pset.db), host, PQport(pset.db));
633  }
634  else
635  {
636  if (hostaddr && *hostaddr && strcmp(host, hostaddr) != 0)
637  printf(_("You are connected to database \"%s\" as user \"%s\" on host \"%s\" (address \"%s\") at port \"%s\".\n"),
638  db, PQuser(pset.db), host, hostaddr, PQport(pset.db));
639  else
640  printf(_("You are connected to database \"%s\" as user \"%s\" on host \"%s\" at port \"%s\".\n"),
641  db, PQuser(pset.db), host, PQport(pset.db));
642  }
643  printSSLInfo();
644  printGSSInfo();
645  }
646  }
647 
648  return PSQL_CMD_SKIP_LINE;
649 }

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 655 of file command.c.

656 {
657  bool success = true;
658 
659  if (active_branch)
660  {
661  char *opt = psql_scan_slash_option(scan_state,
662  OT_WHOLE_LINE, NULL, false);
663 
664  success = do_copy(opt);
665  free(opt);
666  }
667  else
668  ignore_slash_whole_line(scan_state);
669 
671 }
bool do_copy(const char *args)
Definition: copy.c:268
static void ignore_slash_whole_line(PsqlScanState scan_state)
Definition: command.c:3009
@ 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 677 of file command.c.

678 {
679  if (active_branch)
680  print_copyright();
681 
682  return PSQL_CMD_SKIP_LINE;
683 }
void print_copyright(void)
Definition: help.c:692

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 689 of file command.c.

690 {
692 
693  if (active_branch)
694  {
695  int i;
696 
697  for (i = 0; i < lengthof(pset.ctv_args); i++)
698  pset.ctv_args[i] = psql_scan_slash_option(scan_state,
699  OT_NORMAL, NULL, true);
700  pset.crosstab_flag = true;
702  }
703  else
704  ignore_slash_options(scan_state);
705 
706  return status;
707 }
char * ctv_args[4]
Definition: settings.h:100
bool crosstab_flag
Definition: settings.h:99

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

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 713 of file command.c.

714 {
716  bool success = true;
717 
718  if (active_branch)
719  {
720  char *pattern;
721  bool show_verbose,
722  show_system;
723 
724  /* We don't do SQLID reduction on the pattern yet */
725  pattern = psql_scan_slash_option(scan_state,
726  OT_NORMAL, NULL, true);
727 
728  show_verbose = strchr(cmd, '+') ? true : false;
729  show_system = strchr(cmd, 'S') ? true : false;
730 
731  switch (cmd[1])
732  {
733  case '\0':
734  case '+':
735  case 'S':
736  if (pattern)
737  success = describeTableDetails(pattern, show_verbose, show_system);
738  else
739  /* standard listing of interesting things */
740  success = listTables("tvmsE", NULL, show_verbose, show_system);
741  break;
742  case 'A':
743  {
744  char *pattern2 = NULL;
745 
746  if (pattern && cmd[2] != '\0' && cmd[2] != '+')
747  pattern2 = psql_scan_slash_option(scan_state, OT_NORMAL, NULL, true);
748 
749  switch (cmd[2])
750  {
751  case '\0':
752  case '+':
753  success = describeAccessMethods(pattern, show_verbose);
754  break;
755  case 'c':
756  success = listOperatorClasses(pattern, pattern2, show_verbose);
757  break;
758  case 'f':
759  success = listOperatorFamilies(pattern, pattern2, show_verbose);
760  break;
761  case 'o':
762  success = listOpFamilyOperators(pattern, pattern2, show_verbose);
763  break;
764  case 'p':
765  success = listOpFamilyFunctions(pattern, pattern2, show_verbose);
766  break;
767  default:
769  break;
770  }
771 
772  if (pattern2)
773  free(pattern2);
774  }
775  break;
776  case 'a':
777  success = describeAggregates(pattern, show_verbose, show_system);
778  break;
779  case 'b':
780  success = describeTablespaces(pattern, show_verbose);
781  break;
782  case 'c':
783  if (strncmp(cmd, "dconfig", 7) == 0)
785  show_verbose,
786  show_system);
787  else
788  success = listConversions(pattern,
789  show_verbose,
790  show_system);
791  break;
792  case 'C':
793  success = listCasts(pattern, show_verbose);
794  break;
795  case 'd':
796  if (strncmp(cmd, "ddp", 3) == 0)
797  success = listDefaultACLs(pattern);
798  else
799  success = objectDescription(pattern, show_system);
800  break;
801  case 'D':
802  success = listDomains(pattern, show_verbose, show_system);
803  break;
804  case 'f': /* function subsystem */
805  switch (cmd[2])
806  {
807  case '\0':
808  case '+':
809  case 'S':
810  case 'a':
811  case 'n':
812  case 'p':
813  case 't':
814  case 'w':
815  success = exec_command_dfo(scan_state, cmd, pattern,
816  show_verbose, show_system);
817  break;
818  default:
820  break;
821  }
822  break;
823  case 'g':
824  /* no longer distinct from \du */
825  success = describeRoles(pattern, show_verbose, show_system);
826  break;
827  case 'l':
828  success = listLargeObjects(show_verbose);
829  break;
830  case 'L':
831  success = listLanguages(pattern, show_verbose, show_system);
832  break;
833  case 'n':
834  success = listSchemas(pattern, show_verbose, show_system);
835  break;
836  case 'o':
837  success = exec_command_dfo(scan_state, cmd, pattern,
838  show_verbose, show_system);
839  break;
840  case 'O':
841  success = listCollations(pattern, show_verbose, show_system);
842  break;
843  case 'p':
844  success = permissionsList(pattern);
845  break;
846  case 'P':
847  {
848  switch (cmd[2])
849  {
850  case '\0':
851  case '+':
852  case 't':
853  case 'i':
854  case 'n':
855  success = listPartitionedTables(&cmd[2], pattern, show_verbose);
856  break;
857  default:
859  break;
860  }
861  }
862  break;
863  case 'T':
864  success = describeTypes(pattern, show_verbose, show_system);
865  break;
866  case 't':
867  case 'v':
868  case 'm':
869  case 'i':
870  case 's':
871  case 'E':
872  success = listTables(&cmd[1], pattern, show_verbose, show_system);
873  break;
874  case 'r':
875  if (cmd[2] == 'd' && cmd[3] == 's')
876  {
877  char *pattern2 = NULL;
878 
879  if (pattern)
880  pattern2 = psql_scan_slash_option(scan_state,
881  OT_NORMAL, NULL, true);
882  success = listDbRoleSettings(pattern, pattern2);
883 
884  if (pattern2)
885  free(pattern2);
886  }
887  else
889  break;
890  case 'R':
891  switch (cmd[2])
892  {
893  case 'p':
894  if (show_verbose)
895  success = describePublications(pattern);
896  else
897  success = listPublications(pattern);
898  break;
899  case 's':
900  success = describeSubscriptions(pattern, show_verbose);
901  break;
902  default:
904  }
905  break;
906  case 'u':
907  success = describeRoles(pattern, show_verbose, show_system);
908  break;
909  case 'F': /* text search subsystem */
910  switch (cmd[2])
911  {
912  case '\0':
913  case '+':
914  success = listTSConfigs(pattern, show_verbose);
915  break;
916  case 'p':
917  success = listTSParsers(pattern, show_verbose);
918  break;
919  case 'd':
920  success = listTSDictionaries(pattern, show_verbose);
921  break;
922  case 't':
923  success = listTSTemplates(pattern, show_verbose);
924  break;
925  default:
927  break;
928  }
929  break;
930  case 'e': /* SQL/MED subsystem */
931  switch (cmd[2])
932  {
933  case 's':
934  success = listForeignServers(pattern, show_verbose);
935  break;
936  case 'u':
937  success = listUserMappings(pattern, show_verbose);
938  break;
939  case 'w':
940  success = listForeignDataWrappers(pattern, show_verbose);
941  break;
942  case 't':
943  success = listForeignTables(pattern, show_verbose);
944  break;
945  default:
947  break;
948  }
949  break;
950  case 'x': /* Extensions */
951  if (show_verbose)
952  success = listExtensionContents(pattern);
953  else
954  success = listExtensions(pattern);
955  break;
956  case 'X': /* Extended Statistics */
957  success = listExtendedStats(pattern);
958  break;
959  case 'y': /* Event Triggers */
960  success = listEventTriggers(pattern, show_verbose);
961  break;
962  default:
964  }
965 
966  if (pattern)
967  free(pattern);
968  }
969  else
970  ignore_slash_options(scan_state);
971 
972  if (!success)
974 
975  return status;
976 }
static bool exec_command_dfo(PsqlScanState scan_state, const char *cmd, const char *pattern, bool show_verbose, bool show_system)
Definition: command.c:980
bool listUserMappings(const char *pattern, bool verbose)
Definition: describe.c:5718
bool listTSConfigs(const char *pattern, bool verbose)
Definition: describe.c:5375
bool describeRoles(const char *pattern, bool verbose, bool showSystem)
Definition: describe.c:3574
bool listOpFamilyFunctions(const char *access_method_pattern, const char *family_pattern, bool verbose)
Definition: describe.c:6741
bool listPublications(const char *pattern)
Definition: describe.c:6048
bool listTSParsers(const char *pattern, bool verbose)
Definition: describe.c:5008
bool listExtensionContents(const char *pattern)
Definition: describe.c:5890
bool describeAggregates(const char *pattern, bool verbose, bool showSystem)
Definition: describe.c:71
bool listForeignDataWrappers(const char *pattern, bool verbose)
Definition: describe.c:5575
bool listPartitionedTables(const char *reltypes, const char *pattern, bool verbose)
Definition: describe.c:3999
bool describeSubscriptions(const char *pattern, bool verbose)
Definition: describe.c:6351
bool listExtendedStats(const char *pattern)
Definition: describe.c:4575
bool describeTypes(const char *pattern, bool verbose, bool showSystem)
Definition: describe.c:611
bool listOperatorFamilies(const char *access_method_pattern, const char *type_pattern, bool verbose)
Definition: describe.c:6564
bool listForeignServers(const char *pattern, bool verbose)
Definition: describe.c:5644
bool describeTableDetails(const char *pattern, bool verbose, bool showSystem)
Definition: describe.c:1408
bool listDomains(const char *pattern, bool verbose, bool showSystem)
Definition: describe.c:4269
bool listTSDictionaries(const char *pattern, bool verbose)
Definition: describe.c:5249
bool listDbRoleSettings(const char *pattern, const char *pattern2)
Definition: describe.c:3726
bool listCollations(const char *pattern, bool verbose, bool showSystem)
Definition: describe.c:4784
bool listSchemas(const char *pattern, bool verbose, bool showSystem)
Definition: describe.c:4884
bool listExtensions(const char *pattern)
Definition: describe.c:5841
bool listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSystem)
Definition: describe.c:3803
bool listTSTemplates(const char *pattern, bool verbose)
Definition: describe.c:5312
bool describeTablespaces(const char *pattern, bool verbose)
Definition: describe.c:211
bool listCasts(const char *pattern, bool verbose)
Definition: describe.c:4669
bool listOpFamilyOperators(const char *access_method_pattern, const char *family_pattern, bool verbose)
Definition: describe.c:6650
bool permissionsList(const char *pattern)
Definition: describe.c:980
bool listOperatorClasses(const char *access_method_pattern, const char *type_pattern, bool verbose)
Definition: describe.c:6466
bool listForeignTables(const char *pattern, bool verbose)
Definition: describe.c:5771
bool describeConfigurationParameters(const char *pattern, bool verbose, bool showSystem)
Definition: describe.c:4428
bool listEventTriggers(const char *pattern, bool verbose)
Definition: describe.c:4497
bool listDefaultACLs(const char *pattern)
Definition: describe.c:1141
bool listConversions(const char *pattern, bool verbose, bool showSystem)
Definition: describe.c:4350
bool describeAccessMethods(const char *pattern, bool verbose)
Definition: describe.c:139
bool listLargeObjects(bool verbose)
Definition: describe.c:6823
bool listLanguages(const char *pattern, bool verbose, bool showSystem)
Definition: describe.c:4197
bool describePublications(const char *pattern)
Definition: describe.c:6168
bool objectDescription(const char *pattern, bool showSystem)
Definition: describe.c:1218
return true
Definition: isn.c:126

References describeAccessMethods(), describeAggregates(), describeConfigurationParameters(), describePublications(), 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(), status(), 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 980 of file command.c.

983 {
984  bool success;
985  char *arg_patterns[FUNC_MAX_ARGS];
986  int num_arg_patterns = 0;
987 
988  /* Collect argument-type patterns too */
989  if (pattern) /* otherwise it was just \df or \do */
990  {
991  char *ap;
992 
993  while ((ap = psql_scan_slash_option(scan_state,
994  OT_NORMAL, NULL, true)) != NULL)
995  {
996  arg_patterns[num_arg_patterns++] = ap;
997  if (num_arg_patterns >= FUNC_MAX_ARGS)
998  break; /* protect limited-size array */
999  }
1000  }
1001 
1002  if (cmd[1] == 'f')
1003  success = describeFunctions(&cmd[2], pattern,
1004  arg_patterns, num_arg_patterns,
1005  show_verbose, show_system);
1006  else
1007  success = describeOperators(pattern,
1008  arg_patterns, num_arg_patterns,
1009  show_verbose, show_system);
1010 
1011  while (--num_arg_patterns >= 0)
1012  free(arg_patterns[num_arg_patterns]);
1013 
1014  return success;
1015 }
bool describeFunctions(const char *functypes, const char *func_pattern, char **arg_patterns, int num_arg_patterns, bool verbose, bool showSystem)
Definition: describe.c:282
bool describeOperators(const char *oper_pattern, char **arg_patterns, int num_arg_patterns, bool verbose, bool showSystem)
Definition: describe.c:764
#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 1220 of file command.c.

1221 {
1222  if (active_branch)
1223  {
1224  char *value;
1225  char quoted;
1226  bool no_newline = false;
1227  bool first = true;
1228  FILE *fout;
1229 
1230  if (strcmp(cmd, "qecho") == 0)
1231  fout = pset.queryFout;
1232  else if (strcmp(cmd, "warn") == 0)
1233  fout = stderr;
1234  else
1235  fout = stdout;
1236 
1237  while ((value = psql_scan_slash_option(scan_state,
1238  OT_NORMAL, &quoted, false)))
1239  {
1240  if (first && !no_newline && !quoted && strcmp(value, "-n") == 0)
1241  no_newline = true;
1242  else
1243  {
1244  if (first)
1245  first = false;
1246  else
1247  fputc(' ', fout);
1248  fputs(value, fout);
1249  }
1250  free(value);
1251  }
1252  if (!no_newline)
1253  fputs("\n", fout);
1254  }
1255  else
1256  ignore_slash_options(scan_state);
1257 
1258  return PSQL_CMD_SKIP_LINE;
1259 }
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 1022 of file command.c.

1024 {
1026 
1027  if (active_branch)
1028  {
1029  if (!query_buf)
1030  {
1031  pg_log_error("no query buffer");
1033  }
1034  else
1035  {
1036  char *fname;
1037  char *ln = NULL;
1038  int lineno = -1;
1039 
1040  fname = psql_scan_slash_option(scan_state,
1041  OT_NORMAL, NULL, true);
1042  if (fname)
1043  {
1044  /* try to get separate lineno arg */
1045  ln = psql_scan_slash_option(scan_state,
1046  OT_NORMAL, NULL, true);
1047  if (ln == NULL)
1048  {
1049  /* only one arg; maybe it is lineno not fname */
1050  if (fname[0] &&
1051  strspn(fname, "0123456789") == strlen(fname))
1052  {
1053  /* all digits, so assume it is lineno */
1054  ln = fname;
1055  fname = NULL;
1056  }
1057  }
1058  }
1059  if (ln)
1060  {
1061  lineno = atoi(ln);
1062  if (lineno < 1)
1063  {
1064  pg_log_error("invalid line number: %s", ln);
1066  }
1067  }
1068  if (status != PSQL_CMD_ERROR)
1069  {
1070  bool discard_on_quit;
1071 
1072  expand_tilde(&fname);
1073  if (fname)
1074  {
1075  canonicalize_path(fname);
1076  /* Always clear buffer if the file isn't modified */
1077  discard_on_quit = true;
1078  }
1079  else
1080  {
1081  /*
1082  * If query_buf is empty, recall previous query for
1083  * editing. But in that case, the query buffer should be
1084  * emptied if editing doesn't modify the file.
1085  */
1086  discard_on_quit = copy_previous_query(query_buf,
1087  previous_buf);
1088  }
1089 
1090  if (do_edit(fname, query_buf, lineno, discard_on_quit, NULL))
1092  else
1094  }
1095  if (fname)
1096  free(fname);
1097  if (ln)
1098  free(ln);
1099  }
1100  }
1101  else
1102  ignore_slash_options(scan_state);
1103 
1104  return status;
1105 }
void expand_tilde(char **filename)
Definition: common.c:2332
static bool do_edit(const char *filename_arg, PQExpBuffer query_buf, int lineno, bool discard_on_quit, bool *edited)
Definition: command.c:3881
@ 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 status().

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 1112 of file command.c.

1114 {
1116 
1117  if (active_branch)
1118  {
1119  char *obj_desc = psql_scan_slash_option(scan_state,
1120  OT_WHOLE_LINE,
1121  NULL, true);
1122  int lineno = -1;
1123 
1124  if (!query_buf)
1125  {
1126  pg_log_error("no query buffer");
1128  }
1129  else
1130  {
1131  Oid obj_oid = InvalidOid;
1133 
1134  lineno = strip_lineno_from_objdesc(obj_desc);
1135  if (lineno == 0)
1136  {
1137  /* error already reported */
1139  }
1140  else if (!obj_desc)
1141  {
1142  /* set up an empty command to fill in */
1143  resetPQExpBuffer(query_buf);
1144  if (is_func)
1145  appendPQExpBufferStr(query_buf,
1146  "CREATE FUNCTION ( )\n"
1147  " RETURNS \n"
1148  " LANGUAGE \n"
1149  " -- common options: IMMUTABLE STABLE STRICT SECURITY DEFINER\n"
1150  "AS $function$\n"
1151  "\n$function$\n");
1152  else
1153  appendPQExpBufferStr(query_buf,
1154  "CREATE VIEW AS\n"
1155  " SELECT \n"
1156  " -- something...\n");
1157  }
1158  else if (!lookup_object_oid(eot, obj_desc, &obj_oid))
1159  {
1160  /* error already reported */
1162  }
1163  else if (!get_create_object_cmd(eot, obj_oid, query_buf))
1164  {
1165  /* error already reported */
1167  }
1168  else if (is_func && lineno > 0)
1169  {
1170  /*
1171  * lineno "1" should correspond to the first line of the
1172  * function body. We expect that pg_get_functiondef() will
1173  * emit that on a line beginning with "AS ", and that there
1174  * can be no such line before the real start of the function
1175  * body. Increment lineno by the number of lines before that
1176  * line, so that it becomes relative to the first line of the
1177  * function definition.
1178  */
1179  const char *lines = query_buf->data;
1180 
1181  while (*lines != '\0')
1182  {
1183  if (strncmp(lines, "AS ", 3) == 0)
1184  break;
1185  lineno++;
1186  /* find start of next line */
1187  lines = strchr(lines, '\n');
1188  if (!lines)
1189  break;
1190  lines++;
1191  }
1192  }
1193  }
1194 
1195  if (status != PSQL_CMD_ERROR)
1196  {
1197  bool edited = false;
1198 
1199  if (!do_edit(NULL, query_buf, lineno, true, &edited))
1201  else if (!edited)
1202  puts(_("No changes"));
1203  else
1205  }
1206 
1207  if (obj_desc)
1208  free(obj_desc);
1209  }
1210  else
1211  ignore_slash_whole_line(scan_state);
1212 
1213  return status;
1214 }
static bool get_create_object_cmd(EditableObjectType obj_type, Oid oid, PQExpBuffer buf)
Definition: command.c:5282
static bool lookup_object_oid(EditableObjectType obj_type, const char *desc, Oid *obj_oid)
Definition: command.c:5222
static int strip_lineno_from_objdesc(char *obj)
Definition: command.c:5442
#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(), status(), 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 1726 of file command.c.

1728 {
1729  bool success = true;
1730 
1731  switch (conditional_stack_peek(cstack))
1732  {
1733  case IFSTATE_TRUE:
1734 
1735  /*
1736  * Just finished active branch of this \if block. Update saved
1737  * state so we will keep whatever data was put in query_buf by the
1738  * active branch.
1739  */
1740  save_query_text_state(scan_state, cstack, query_buf);
1741 
1742  /*
1743  * Discard \elif expression and ignore the rest until \endif.
1744  * Switch state before reading expression to ensure proper lexer
1745  * behavior.
1746  */
1748  ignore_boolean_expression(scan_state);
1749  break;
1750  case IFSTATE_FALSE:
1751 
1752  /*
1753  * Discard any query text added by the just-skipped branch.
1754  */
1755  discard_query_text(scan_state, cstack, query_buf);
1756 
1757  /*
1758  * Have not yet found a true expression in this \if block, so this
1759  * might be the first. We have to change state before examining
1760  * the expression, or the lexer won't do the right thing.
1761  */
1763  if (!is_true_boolean_expression(scan_state, "\\elif expression"))
1765  break;
1766  case IFSTATE_IGNORED:
1767 
1768  /*
1769  * Discard any query text added by the just-skipped branch.
1770  */
1771  discard_query_text(scan_state, cstack, query_buf);
1772 
1773  /*
1774  * Skip expression and move on. Either the \if block already had
1775  * an active section, or whole block is being skipped.
1776  */
1777  ignore_boolean_expression(scan_state);
1778  break;
1779  case IFSTATE_ELSE_TRUE:
1780  case IFSTATE_ELSE_FALSE:
1781  pg_log_error("\\elif: cannot occur after \\else");
1782  success = false;
1783  break;
1784  case IFSTATE_NONE:
1785  /* no \if to elif from */
1786  pg_log_error("\\elif: no matching \\if");
1787  success = false;
1788  break;
1789  }
1790 
1792 }
static void discard_query_text(PsqlScanState scan_state, ConditionalStack cstack, PQExpBuffer query_buf)
Definition: command.c:3058
static void ignore_boolean_expression(PsqlScanState scan_state)
Definition: command.c:2959
static bool is_true_boolean_expression(PsqlScanState scan_state, const char *name)
Definition: command.c:2942
static void save_query_text_state(PsqlScanState scan_state, ConditionalStack cstack, PQExpBuffer query_buf)
Definition: command.c:3038
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 1802 of file command.c.

1804 {
1805  bool success = true;
1806 
1807  switch (conditional_stack_peek(cstack))
1808  {
1809  case IFSTATE_TRUE:
1810 
1811  /*
1812  * Just finished active branch of this \if block. Update saved
1813  * state so we will keep whatever data was put in query_buf by the
1814  * active branch.
1815  */
1816  save_query_text_state(scan_state, cstack, query_buf);
1817 
1818  /* Now skip the \else branch */
1820  break;
1821  case IFSTATE_FALSE:
1822 
1823  /*
1824  * Discard any query text added by the just-skipped branch.
1825  */
1826  discard_query_text(scan_state, cstack, query_buf);
1827 
1828  /*
1829  * We've not found any true \if or \elif expression, so execute
1830  * the \else branch.
1831  */
1833  break;
1834  case IFSTATE_IGNORED:
1835 
1836  /*
1837  * Discard any query text added by the just-skipped branch.
1838  */
1839  discard_query_text(scan_state, cstack, query_buf);
1840 
1841  /*
1842  * Either we previously processed the active branch of this \if,
1843  * or the whole \if block is being skipped. Either way, skip the
1844  * \else branch.
1845  */
1847  break;
1848  case IFSTATE_ELSE_TRUE:
1849  case IFSTATE_ELSE_FALSE:
1850  pg_log_error("\\else: cannot occur after \\else");
1851  success = false;
1852  break;
1853  case IFSTATE_NONE:
1854  /* no \if to else from */
1855  pg_log_error("\\else: no matching \\if");
1856  success = false;
1857  break;
1858  }
1859 
1861 }

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 1265 of file command.c.

1266 {
1267  if (active_branch)
1268  {
1269  char *encoding = psql_scan_slash_option(scan_state,
1270  OT_NORMAL, NULL, false);
1271 
1272  if (!encoding)
1273  {
1274  /* show encoding */
1276  }
1277  else
1278  {
1279  /* set encoding */
1280  if (PQsetClientEncoding(pset.db, encoding) == -1)
1281  pg_log_error("%s: invalid encoding name or conversion procedure not found", encoding);
1282  else
1283  {
1284  /* save encoding info into psql internal data */
1287  SetVariable(pset.vars, "ENCODING",
1289  }
1290  free(encoding);
1291  }
1292  }
1293  else
1294  ignore_slash_options(scan_state);
1295 
1296  return PSQL_CMD_SKIP_LINE;
1297 }
const char * pg_encoding_to_char(int encoding)
Definition: encnames.c:588
int PQclientEncoding(const PGconn *conn)
Definition: fe-connect.c:6985
int PQsetClientEncoding(PGconn *conn, const char *encoding)
Definition: fe-connect.c:6993
int32 encoding
Definition: pg_database.h:41
VariableSpace vars
Definition: settings.h:118
int encoding
Definition: settings.h:83
int encoding
Definition: print.h:122
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 1867 of file command.c.

1869 {
1870  bool success = true;
1871 
1872  switch (conditional_stack_peek(cstack))
1873  {
1874  case IFSTATE_TRUE:
1875  case IFSTATE_ELSE_TRUE:
1876  /* Close the \if block, keeping the query text */
1877  success = conditional_stack_pop(cstack);
1878  Assert(success);
1879  break;
1880  case IFSTATE_FALSE:
1881  case IFSTATE_IGNORED:
1882  case IFSTATE_ELSE_FALSE:
1883 
1884  /*
1885  * Discard any query text added by the just-skipped branch.
1886  */
1887  discard_query_text(scan_state, cstack, query_buf);
1888 
1889  /* Close the \if block */
1890  success = conditional_stack_pop(cstack);
1891  Assert(success);
1892  break;
1893  case IFSTATE_NONE:
1894  /* no \if to end */
1895  pg_log_error("\\endif: no matching \\if");
1896  success = false;
1897  break;
1898  }
1899 
1901 }
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 1303 of file command.c.

1304 {
1305  if (active_branch)
1306  {
1307  if (pset.last_error_result)
1308  {
1309  char *msg;
1310 
1314  if (msg)
1315  {
1316  pg_log_error("%s", msg);
1317  PQfreemem(msg);
1318  }
1319  else
1320  puts(_("out of memory"));
1321  }
1322  else
1323  puts(_("There is no previous error."));
1324  }
1325 
1326  return PSQL_CMD_SKIP_LINE;
1327 }
char * PQresultVerboseErrorMessage(const PGresult *res, PGVerbosity verbosity, PGContextVisibility show_context)
Definition: fe-exec.c:3294
@ PQSHOW_CONTEXT_ALWAYS
Definition: libpq-fe.h:137
@ PQERRORS_VERBOSE
Definition: libpq-fe.h:129
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 1333 of file command.c.

1334 {
1335  bool success = true;
1336 
1337  if (active_branch)
1338  {
1339  char *fname = psql_scan_slash_option(scan_state,
1340  OT_NORMAL, NULL, false);
1341 
1342  success = do_pset("fieldsep", fname, &pset.popt, pset.quiet);
1343  free(fname);
1344  }
1345  else
1346  ignore_slash_options(scan_state);
1347 
1349 }

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 1361 of file command.c.

1362 {
1364  char *fname;
1365 
1366  /*
1367  * Because the option processing for this is fairly complicated, we do it
1368  * and then decide whether the branch is active.
1369  */
1370  fname = psql_scan_slash_option(scan_state,
1371  OT_FILEPIPE, NULL, false);
1372 
1373  if (fname && fname[0] == '(')
1374  {
1375  /* Consume pset options through trailing ')' ... */
1376  status = process_command_g_options(fname + 1, scan_state,
1377  active_branch, cmd);
1378  free(fname);
1379  /* ... and again attempt to scan the filename. */
1380  fname = psql_scan_slash_option(scan_state,
1381  OT_FILEPIPE, NULL, false);
1382  }
1383 
1384  if (status == PSQL_CMD_SKIP_LINE && active_branch)
1385  {
1386  if (!fname)
1387  pset.gfname = NULL;
1388  else
1389  {
1390  expand_tilde(&fname);
1391  pset.gfname = pg_strdup(fname);
1392  }
1393  if (strcmp(cmd, "gx") == 0)
1394  {
1395  /* save settings if not done already, then force expanded=on */
1396  if (pset.gsavepopt == NULL)
1398  pset.popt.topt.expanded = 1;
1399  }
1401  }
1402 
1403  free(fname);
1404 
1405  return status;
1406 }
printQueryOpt * savePsetInfo(const printQueryOpt *popt)
Definition: command.c:4742
static backslashResult process_command_g_options(char *first_option, PsqlScanState scan_state, bool active_branch, const char *cmd)
Definition: command.c:1414
@ 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(), status(), 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 1489 of file command.c.

1490 {
1492 
1493  if (active_branch)
1494  {
1495  pset.gdesc_flag = true;
1497  }
1498 
1499  return status;
1500 }
bool gdesc_flag
Definition: settings.h:97

References _psqlSettings::gdesc_flag, pset, PSQL_CMD_SEND, PSQL_CMD_SKIP_LINE, and status().

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 1506 of file command.c.

1508 {
1509  bool success = true;
1510 
1511  if (active_branch)
1512  {
1513  char *myvar = psql_scan_slash_option(scan_state,
1514  OT_NORMAL, NULL, false);
1515  char *envvar = psql_scan_slash_option(scan_state,
1516  OT_NORMAL, NULL, false);
1517 
1518  if (!myvar || !envvar)
1519  {
1520  pg_log_error("\\%s: missing required argument", cmd);
1521  success = false;
1522  }
1523  else
1524  {
1525  char *envval = getenv(envvar);
1526 
1527  if (envval && !SetVariable(pset.vars, myvar, envval))
1528  success = false;
1529  }
1530  free(myvar);
1531  free(envvar);
1532  }
1533  else
1534  ignore_slash_options(scan_state);
1535 
1537 }

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 1543 of file command.c.

1544 {
1546 
1547  if (active_branch)
1548  {
1549  pset.gexec_flag = true;
1551  }
1552 
1553  return status;
1554 }
bool gexec_flag
Definition: settings.h:98

References _psqlSettings::gexec_flag, pset, PSQL_CMD_SEND, PSQL_CMD_SKIP_LINE, and status().

Referenced by exec_command().

◆ exec_command_gset()

static backslashResult exec_command_gset ( PsqlScanState  scan_state,
bool  active_branch 
)
static

Definition at line 1560 of file command.c.

1561 {
1563 
1564  if (active_branch)
1565  {
1566  char *prefix = psql_scan_slash_option(scan_state,
1567  OT_NORMAL, NULL, false);
1568 
1569  if (prefix)
1570  pset.gset_prefix = prefix;
1571  else
1572  {
1573  /* we must set a non-NULL prefix to trigger storing */
1574  pset.gset_prefix = pg_strdup("");
1575  }
1576  /* gset_prefix is freed later */
1578  }
1579  else
1580  ignore_slash_options(scan_state);
1581 
1582  return status;
1583 }
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, psql_scan_slash_option(), and status().

Referenced by exec_command().

◆ exec_command_help()

static backslashResult exec_command_help ( PsqlScanState  scan_state,
bool  active_branch 
)
static

Definition at line 1589 of file command.c.

1590 {
1591  if (active_branch)
1592  {
1593  char *opt = psql_scan_slash_option(scan_state,
1594  OT_WHOLE_LINE, NULL, false);
1595  size_t len;
1596 
1597  /* strip any trailing spaces and semicolons */
1598  if (opt)
1599  {
1600  len = strlen(opt);
1601  while (len > 0 &&
1602  (isspace((unsigned char) opt[len - 1])
1603  || opt[len - 1] == ';'))
1604  opt[--len] = '\0';
1605  }
1606 
1607  helpSQL(opt, pset.popt.topt.pager);
1608  free(opt);
1609  }
1610  else
1611  ignore_slash_whole_line(scan_state);
1612 
1613  return PSQL_CMD_SKIP_LINE;
1614 }
void helpSQL(const char *topic, unsigned short int pager)
Definition: help.c:530

References free, helpSQL(), ignore_slash_whole_line(), len, 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 1620 of file command.c.

1621 {
1622  bool success = true;
1623 
1624  if (active_branch)
1625  {
1626  if (pset.popt.topt.format != PRINT_HTML)
1627  success = do_pset("format", "html", &pset.popt, pset.quiet);
1628  else
1629  success = do_pset("format", "aligned", &pset.popt, pset.quiet);
1630  }
1631 
1633 }

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 1680 of file command.c.

1682 {
1683  if (conditional_active(cstack))
1684  {
1685  /*
1686  * First, push a new active stack entry; this ensures that the lexer
1687  * will perform variable substitution and backtick evaluation while
1688  * scanning the expression. (That should happen anyway, since we know
1689  * we're in an active outer branch, but let's be sure.)
1690  */
1692 
1693  /* Remember current query state in case we need to restore later */
1694  save_query_text_state(scan_state, cstack, query_buf);
1695 
1696  /*
1697  * Evaluate the expression; if it's false, change to inactive state.
1698  */
1699  if (!is_true_boolean_expression(scan_state, "\\if expression"))
1701  }
1702  else
1703  {
1704  /*
1705  * We're within an inactive outer branch, so this entire \if block
1706  * will be ignored. We don't want to evaluate the expression, so push
1707  * the "ignored" stack state before scanning it.
1708  */
1710 
1711  /* Remember current query state in case we need to restore later */
1712  save_query_text_state(scan_state, cstack, query_buf);
1713 
1714  ignore_boolean_expression(scan_state);
1715  }
1716 
1717  return PSQL_CMD_SKIP_LINE;
1718 }
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 1639 of file command.c.

1640 {
1641  bool success = true;
1642 
1643  if (active_branch)
1644  {
1645  char *fname = psql_scan_slash_option(scan_state,
1646  OT_NORMAL, NULL, true);
1647 
1648  if (!fname)
1649  {
1650  pg_log_error("\\%s: missing required argument", cmd);
1651  success = false;
1652  }
1653  else
1654  {
1655  bool include_relative;
1656 
1657  include_relative = (strcmp(cmd, "ir") == 0
1658  || strcmp(cmd, "include_relative") == 0);
1659  expand_tilde(&fname);
1660  success = (process_file(fname, include_relative) == EXIT_SUCCESS);
1661  free(fname);
1662  }
1663  }
1664  else
1665  ignore_slash_options(scan_state);
1666 
1668 }
int process_file(char *filename, bool use_relative_path)
Definition: command.c:4076
#define EXIT_SUCCESS
Definition: settings.h:159

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 1907 of file command.c.

1908 {
1909  bool success = true;
1910 
1911  if (active_branch)
1912  {
1913  char *pattern;
1914  bool show_verbose;
1915 
1916  pattern = psql_scan_slash_option(scan_state,
1917  OT_NORMAL, NULL, true);
1918 
1919  show_verbose = strchr(cmd, '+') ? true : false;
1920 
1921  success = listAllDbs(pattern, show_verbose);
1922 
1923  if (pattern)
1924  free(pattern);
1925  }
1926  else
1927  ignore_slash_options(scan_state);
1928 
1930 }
bool listAllDbs(const char *pattern, bool verbose)
Definition: describe.c:902

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 1936 of file command.c.

1937 {
1939  bool success = true;
1940 
1941  if (active_branch)
1942  {
1943  char *opt1,
1944  *opt2;
1945 
1946  opt1 = psql_scan_slash_option(scan_state,
1947  OT_NORMAL, NULL, true);
1948  opt2 = psql_scan_slash_option(scan_state,
1949  OT_NORMAL, NULL, true);
1950 
1951  if (strcmp(cmd + 3, "export") == 0)
1952  {
1953  if (!opt2)
1954  {
1955  pg_log_error("\\%s: missing required argument", cmd);
1956  success = false;
1957  }
1958  else
1959  {
1960  expand_tilde(&opt2);
1961  success = do_lo_export(opt1, opt2);
1962  }
1963  }
1964 
1965  else if (strcmp(cmd + 3, "import") == 0)
1966  {
1967  if (!opt1)
1968  {
1969  pg_log_error("\\%s: missing required argument", cmd);
1970  success = false;
1971  }
1972  else
1973  {
1974  expand_tilde(&opt1);
1975  success = do_lo_import(opt1, opt2);
1976  }
1977  }
1978 
1979  else if (strcmp(cmd + 3, "list") == 0)
1980  success = listLargeObjects(false);
1981  else if (strcmp(cmd + 3, "list+") == 0)
1982  success = listLargeObjects(true);
1983 
1984  else if (strcmp(cmd + 3, "unlink") == 0)
1985  {
1986  if (!opt1)
1987  {
1988  pg_log_error("\\%s: missing required argument", cmd);
1989  success = false;
1990  }
1991  else
1992  success = do_lo_unlink(opt1);
1993  }
1994 
1995  else
1997 
1998  free(opt1);
1999  free(opt2);
2000  }
2001  else
2002  ignore_slash_options(scan_state);
2003 
2004  if (!success)
2006 
2007  return status;
2008 }
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(), status(), and success.

Referenced by exec_command().

◆ exec_command_out()

static backslashResult exec_command_out ( PsqlScanState  scan_state,
bool  active_branch 
)
static

Definition at line 2014 of file command.c.

2015 {
2016  bool success = true;
2017 
2018  if (active_branch)
2019  {
2020  char *fname = psql_scan_slash_option(scan_state,
2021  OT_FILEPIPE, NULL, true);
2022 
2023  expand_tilde(&fname);
2024  success = setQFout(fname);
2025  free(fname);
2026  }
2027  else
2028  ignore_slash_filepipe(scan_state);
2029 
2031 }
bool setQFout(const char *fname)
Definition: common.c:88
static void ignore_slash_filepipe(PsqlScanState scan_state)
Definition: command.c:2992

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 2063 of file command.c.

2064 {
2065  bool success = true;
2066 
2067  if (active_branch)
2068  {
2069  char *user = psql_scan_slash_option(scan_state,
2070  OT_SQLID, NULL, true);
2071  char *pw1 = NULL;
2072  char *pw2 = NULL;
2074  PromptInterruptContext prompt_ctx;
2075 
2076  if (user == NULL)
2077  {
2078  /* By default, the command applies to CURRENT_USER */
2079  PGresult *res;
2080 
2081  res = PSQLexec("SELECT CURRENT_USER");
2082  if (!res)
2083  return PSQL_CMD_ERROR;
2084 
2085  user = pg_strdup(PQgetvalue(res, 0, 0));
2086  PQclear(res);
2087  }
2088 
2089  /* Set up to let SIGINT cancel simple_prompt_extended() */
2090  prompt_ctx.jmpbuf = sigint_interrupt_jmp;
2091  prompt_ctx.enabled = &sigint_interrupt_enabled;
2092  prompt_ctx.canceled = false;
2093 
2094  initPQExpBuffer(&buf);
2095  printfPQExpBuffer(&buf, _("Enter new password for user \"%s\": "), user);
2096 
2097  pw1 = simple_prompt_extended(buf.data, false, &prompt_ctx);
2098  if (!prompt_ctx.canceled)
2099  pw2 = simple_prompt_extended("Enter it again: ", false, &prompt_ctx);
2100 
2101  if (prompt_ctx.canceled)
2102  {
2103  /* fail silently */
2104  success = false;
2105  }
2106  else if (strcmp(pw1, pw2) != 0)
2107  {
2108  pg_log_error("Passwords didn't match.");
2109  success = false;
2110  }
2111  else
2112  {
2113  char *encrypted_password;
2114 
2115  encrypted_password = PQencryptPasswordConn(pset.db, pw1, user, NULL);
2116 
2117  if (!encrypted_password)
2118  {
2120  success = false;
2121  }
2122  else
2123  {
2124  PGresult *res;
2125 
2126  printfPQExpBuffer(&buf, "ALTER USER %s PASSWORD ",
2127  fmtId(user));
2128  appendStringLiteralConn(&buf, encrypted_password, pset.db);
2129  res = PSQLexec(buf.data);
2130  if (!res)
2131  success = false;
2132  else
2133  PQclear(res);
2134  PQfreemem(encrypted_password);
2135  }
2136  }
2137 
2138  free(user);
2139  if (pw1)
2140  free(pw1);
2141  if (pw2)
2142  free(pw2);
2143  termPQExpBuffer(&buf);
2144  }
2145  else
2146  ignore_slash_options(scan_state);
2147 
2149 }
PGresult * PSQLexec(const char *query)
Definition: common.c:556
char * PQencryptPasswordConn(PGconn *conn, const char *passwd, const char *user, const char *algorithm)
Definition: fe-auth.c:1230
void PQclear(PGresult *res)
Definition: fe-exec.c:718
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3735
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:237
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:92
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:131
@ OT_SQLID
Definition: psqlscanslash.h:18
char * simple_prompt_extended(const char *prompt, bool echo, PromptInterruptContext *prompt_ctx)
Definition: sprompt.c:53
void appendStringLiteralConn(PQExpBuffer buf, const char *str, PGconn *conn)
Definition: string_utils.c:293
const char * fmtId(const char *rawid)
Definition: string_utils.c:64
volatile bool * enabled
Definition: string.h:19

References _, appendStringLiteralConn(), buf, PromptInterruptContext::canceled, _psqlSettings::db, PromptInterruptContext::enabled, fmtId(), free, ignore_slash_options(), initPQExpBuffer(), PromptInterruptContext::jmpbuf, OT_SQLID, pg_log_error, pg_log_info, pg_strdup(), PQclear(), PQencryptPasswordConn(), PQerrorMessage(), PQfreemem(), PQgetvalue(), 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 2037 of file command.c.

2039 {
2040  if (active_branch)
2041  {
2042  /*
2043  * We want to print the same thing \g would execute, but not to change
2044  * the query buffer state; so we can't use copy_previous_query().
2045  * Also, beware of possibility that buffer pointers are NULL.
2046  */
2047  if (query_buf && query_buf->len > 0)
2048  puts(query_buf->data);
2049  else if (previous_buf && previous_buf->len > 0)
2050  puts(previous_buf->data);
2051  else if (!pset.quiet)
2052  puts(_("Query buffer is empty."));
2053  fflush(stdout);
2054  }
2055 
2056  return PSQL_CMD_SKIP_LINE;
2057 }

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 2155 of file command.c.

2157 {
2158  bool success = true;
2159 
2160  if (active_branch)
2161  {
2162  char *opt,
2163  *prompt_text = NULL;
2164  char *arg1,
2165  *arg2;
2166 
2167  arg1 = psql_scan_slash_option(scan_state, OT_NORMAL, NULL, false);
2168  arg2 = psql_scan_slash_option(scan_state, OT_NORMAL, NULL, false);
2169 
2170  if (!arg1)
2171  {
2172  pg_log_error("\\%s: missing required argument", cmd);
2173  success = false;
2174  }
2175  else
2176  {
2177  char *result;
2178  PromptInterruptContext prompt_ctx;
2179 
2180  /* Set up to let SIGINT cancel simple_prompt_extended() */
2181  prompt_ctx.jmpbuf = sigint_interrupt_jmp;
2182  prompt_ctx.enabled = &sigint_interrupt_enabled;
2183  prompt_ctx.canceled = false;
2184 
2185  if (arg2)
2186  {
2187  prompt_text = arg1;
2188  opt = arg2;
2189  }
2190  else
2191  opt = arg1;
2192 
2193  if (!pset.inputfile)
2194  {
2195  result = simple_prompt_extended(prompt_text, true, &prompt_ctx);
2196  }
2197  else
2198  {
2199  if (prompt_text)
2200  {
2201  fputs(prompt_text, stdout);
2202  fflush(stdout);
2203  }
2204  result = gets_fromFile(stdin);
2205  if (!result)
2206  {
2207  pg_log_error("\\%s: could not read value for variable",
2208  cmd);
2209  success = false;
2210  }
2211  }
2212 
2213  if (prompt_ctx.canceled ||
2214  (result && !SetVariable(pset.vars, opt, result)))
2215  success = false;
2216 
2217  if (result)
2218  free(result);
2219  if (prompt_text)
2220  free(prompt_text);
2221  free(opt);
2222  }
2223  }
2224  else
2225  ignore_slash_options(scan_state);
2226 
2228 }
char * gets_fromFile(FILE *source)
Definition: input.c:188
char * inputfile
Definition: settings.h:110

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 2234 of file command.c.

2235 {
2236  bool success = true;
2237 
2238  if (active_branch)
2239  {
2240  char *opt0 = psql_scan_slash_option(scan_state,
2241  OT_NORMAL, NULL, false);
2242  char *opt1 = psql_scan_slash_option(scan_state,
2243  OT_NORMAL, NULL, false);
2244 
2245  if (!opt0)
2246  {
2247  /* list all variables */
2248 
2249  int i;
2250  static const char *const my_list[] = {
2251  "border", "columns", "csv_fieldsep", "expanded", "fieldsep",
2252  "fieldsep_zero", "footer", "format", "linestyle", "null",
2253  "numericlocale", "pager", "pager_min_lines",
2254  "recordsep", "recordsep_zero",
2255  "tableattr", "title", "tuples_only",
2256  "unicode_border_linestyle",
2257  "unicode_column_linestyle",
2258  "unicode_header_linestyle",
2259  NULL
2260  };
2261 
2262  for (i = 0; my_list[i] != NULL; i++)
2263  {
2264  char *val = pset_value_string(my_list[i], &pset.popt);
2265 
2266  printf("%-24s %s\n", my_list[i], val);
2267  free(val);
2268  }
2269 
2270  success = true;
2271  }
2272  else
2273  success = do_pset(opt0, opt1, &pset.popt, pset.quiet);
2274 
2275  free(opt0);
2276  free(opt1);
2277  }
2278  else
2279  ignore_slash_options(scan_state);
2280 
2282 }
static char * pset_value_string(const char *param, printQueryOpt *popt)
Definition: command.c:4854
long val
Definition: informix.c:664

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 2288 of file command.c.

2289 {
2291 
2292  if (active_branch)
2294 
2295  return status;
2296 }
@ PSQL_CMD_TERMINATE
Definition: command.h:20

References PSQL_CMD_SKIP_LINE, PSQL_CMD_TERMINATE, and status().

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 2302 of file command.c.

2304 {
2305  if (active_branch)
2306  {
2307  resetPQExpBuffer(query_buf);
2308  psql_scan_reset(scan_state);
2309  if (!pset.quiet)
2310  puts(_("Query buffer reset (cleared)."));
2311  }
2312 
2313  return PSQL_CMD_SKIP_LINE;
2314 }
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 2320 of file command.c.

2321 {
2322  bool success = true;
2323 
2324  if (active_branch)
2325  {
2326  char *fname = psql_scan_slash_option(scan_state,
2327  OT_NORMAL, NULL, true);
2328 
2329  expand_tilde(&fname);
2330  success = printHistory(fname, pset.popt.topt.pager);
2331  if (success && !pset.quiet && fname)
2332  printf(_("Wrote history to file \"%s\".\n"), fname);
2333  if (!fname)
2334  putchar('\n');
2335  free(fname);
2336  }
2337  else
2338  ignore_slash_options(scan_state);
2339 
2341 }
bool printHistory(const char *fname, unsigned short int pager)
Definition: input.c:496

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 2347 of file command.c.

2348 {
2349  bool success = true;
2350 
2351  if (active_branch)
2352  {
2353  char *opt0 = psql_scan_slash_option(scan_state,
2354  OT_NORMAL, NULL, false);
2355 
2356  if (!opt0)
2357  {
2358  /* list all variables */
2360  success = true;
2361  }
2362  else
2363  {
2364  /*
2365  * Set variable to the concatenation of the arguments.
2366  */
2367  char *newval;
2368  char *opt;
2369 
2370  opt = psql_scan_slash_option(scan_state,
2371  OT_NORMAL, NULL, false);
2372  newval = pg_strdup(opt ? opt : "");
2373  free(opt);
2374 
2375  while ((opt = psql_scan_slash_option(scan_state,
2376  OT_NORMAL, NULL, false)))
2377  {
2378  newval = pg_realloc(newval, strlen(newval) + strlen(opt) + 1);
2379  strcat(newval, opt);
2380  free(opt);
2381  }
2382 
2383  if (!SetVariable(pset.vars, opt0, newval))
2384  success = false;
2385 
2386  free(newval);
2387  }
2388  free(opt0);
2389  }
2390  else
2391  ignore_slash_options(scan_state);
2392 
2394 }
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 2400 of file command.c.

2402 {
2403  bool success = true;
2404 
2405  if (active_branch)
2406  {
2407  char *envvar = psql_scan_slash_option(scan_state,
2408  OT_NORMAL, NULL, false);
2409  char *envval = psql_scan_slash_option(scan_state,
2410  OT_NORMAL, NULL, false);
2411 
2412  if (!envvar)
2413  {
2414  pg_log_error("\\%s: missing required argument", cmd);
2415  success = false;
2416  }
2417  else if (strchr(envvar, '=') != NULL)
2418  {
2419  pg_log_error("\\%s: environment variable name must not contain \"=\"",
2420  cmd);
2421  success = false;
2422  }
2423  else if (!envval)
2424  {
2425  /* No argument - unset the environment variable */
2426  unsetenv(envvar);
2427  success = true;
2428  }
2429  else
2430  {
2431  /* Set variable to the value of the next argument */
2432  setenv(envvar, envval, 1);
2433  success = true;
2434  }
2435  free(envvar);
2436  free(envval);
2437  }
2438  else
2439  ignore_slash_options(scan_state);
2440 
2442 }
#define unsetenv(x)
Definition: win32_port.h:508
#define setenv(x, y, z)
Definition: win32_port.h:507

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 2448 of file command.c.

2450 {
2452 
2453  if (active_branch)
2454  {
2455  bool show_linenumbers = (strchr(cmd, '+') != NULL);
2456  PQExpBuffer buf;
2457  char *obj_desc;
2458  Oid obj_oid = InvalidOid;
2460 
2461  buf = createPQExpBuffer();
2462  obj_desc = psql_scan_slash_option(scan_state,
2463  OT_WHOLE_LINE, NULL, true);
2464  if (!obj_desc)
2465  {
2466  if (is_func)
2467  pg_log_error("function name is required");
2468  else
2469  pg_log_error("view name is required");
2471  }
2472  else if (!lookup_object_oid(eot, obj_desc, &obj_oid))
2473  {
2474  /* error already reported */
2476  }
2477  else if (!get_create_object_cmd(eot, obj_oid, buf))
2478  {
2479  /* error already reported */
2481  }
2482  else
2483  {
2484  FILE *output;
2485  bool is_pager;
2486 
2487  /* Select output stream: stdout, pager, or file */
2488  if (pset.queryFout == stdout)
2489  {
2490  /* count lines in function to see if pager is needed */
2491  int lineno = count_lines_in_buf(buf);
2492 
2493  output = PageOutput(lineno, &(pset.popt.topt));
2494  is_pager = true;
2495  }
2496  else
2497  {
2498  /* use previously set output file, without pager */
2499  output = pset.queryFout;
2500  is_pager = false;
2501  }
2502 
2503  if (show_linenumbers)
2504  {
2505  /*
2506  * For functions, lineno "1" should correspond to the first
2507  * line of the function body. We expect that
2508  * pg_get_functiondef() will emit that on a line beginning
2509  * with "AS ", and that there can be no such line before the
2510  * real start of the function body.
2511  */
2513  is_func ? "AS " : NULL);
2514  }
2515  else
2516  {
2517  /* just send the definition to output */
2518  fputs(buf->data, output);
2519  }
2520 
2521  if (is_pager)
2522  ClosePager(output);
2523  }
2524 
2525  if (obj_desc)
2526  free(obj_desc);
2528  }
2529  else
2530  ignore_slash_whole_line(scan_state);
2531 
2532  return status;
2533 }
static int count_lines_in_buf(PQExpBuffer buf)
Definition: command.c:5500
static void print_with_linenumbers(FILE *output, char *lines, const char *header_keyword)
Definition: command.c:5527
void ClosePager(FILE *pagerpipe)
Definition: print.c:3096
FILE * PageOutput(int lines, const printTableOpt *topt)
Definition: print.c:3045
static void output(uint64 loop_count)
PQExpBuffer createPQExpBuffer(void)
Definition: pqexpbuffer.c:74
void destroyPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:116

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, status(), 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 2818 of file command.c.

2819 {
2820  bool success = true;
2821 
2822  if (active_branch)
2823  {
2824  char *opt = psql_scan_slash_option(scan_state,
2825  OT_WHOLE_LINE, NULL, false);
2826 
2827  success = do_shell(opt);
2828  free(opt);
2829  }
2830  else
2831  ignore_slash_whole_line(scan_state);
2832 
2834 }
static bool do_shell(const char *command)
Definition: command.c:4925

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 2840 of file command.c.

2841 {
2842  if (active_branch)
2843  {
2844  char *opt0 = psql_scan_slash_option(scan_state,
2845  OT_NORMAL, NULL, false);
2846 
2847  if (!opt0 || strcmp(opt0, "commands") == 0)
2849  else if (strcmp(opt0, "options") == 0)
2851  else if (strcmp(opt0, "variables") == 0)
2853  else
2855 
2856  if (opt0)
2857  free(opt0);
2858  }
2859  else
2860  ignore_slash_options(scan_state);
2861 
2862  return PSQL_CMD_SKIP_LINE;
2863 }
void helpVariables(unsigned short int pager)
Definition: help.c:339
void slashUsage(unsigned short int pager)
Definition: help.c:154
static void usage(const char *progname)
Definition: vacuumlo.c:417

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 2539 of file command.c.

2540 {
2541  bool success = true;
2542 
2543  if (active_branch)
2544  {
2545  char *opt = psql_scan_slash_option(scan_state,
2546  OT_NORMAL, NULL, true);
2547 
2548  success = do_pset("tuples_only", opt, &pset.popt, pset.quiet);
2549  free(opt);
2550  }
2551  else
2552  ignore_slash_options(scan_state);
2553 
2555 }

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 2561 of file command.c.

2562 {
2563  bool success = true;
2564 
2565  if (active_branch)
2566  {
2567  char *value = psql_scan_slash_option(scan_state,
2568  OT_NORMAL, NULL, false);
2569 
2570  success = do_pset("tableattr", value, &pset.popt, pset.quiet);
2571  free(value);
2572  }
2573  else
2574  ignore_slash_options(scan_state);
2575 
2577 }

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 2583 of file command.c.

2584 {
2585  bool success = true;
2586 
2587  if (active_branch)
2588  {
2589  char *opt = psql_scan_slash_option(scan_state,
2590  OT_NORMAL, NULL, false);
2591 
2592  if (opt)
2593  success = ParseVariableBool(opt, "\\timing", &pset.timing);
2594  else
2595  pset.timing = !pset.timing;
2596  if (!pset.quiet)
2597  {
2598  if (pset.timing)
2599  puts(_("Timing is on."));
2600  else
2601  puts(_("Timing is off."));
2602  }
2603  free(opt);
2604  }
2605  else
2606  ignore_slash_options(scan_state);
2607 
2609 }

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 2615 of file command.c.

2617 {
2618  bool success = true;
2619 
2620  if (active_branch)
2621  {
2622  char *opt = psql_scan_slash_option(scan_state,
2623  OT_NORMAL, NULL, false);
2624 
2625  if (!opt)
2626  {
2627  pg_log_error("\\%s: missing required argument", cmd);
2628  success = false;
2629  }
2630  else if (!SetVariable(pset.vars, opt, NULL))
2631  success = false;
2632 
2633  free(opt);
2634  }
2635  else
2636  ignore_slash_options(scan_state);
2637 
2639 }

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 2734 of file command.c.

2736 {
2737  bool success = true;
2738 
2739  if (active_branch)
2740  {
2741  char *opt = psql_scan_slash_option(scan_state,
2742  OT_NORMAL, NULL, true);
2743  double sleep = 2;
2744 
2745  /* Convert optional sleep-length argument */
2746  if (opt)
2747  {
2748  sleep = strtod(opt, NULL);
2749  if (sleep <= 0)
2750  sleep = 1;
2751  free(opt);
2752  }
2753 
2754  /* If query_buf is empty, recall and execute previous query */
2755  (void) copy_previous_query(query_buf, previous_buf);
2756 
2757  success = do_watch(query_buf, sleep);
2758 
2759  /* Reset the query buffer as though for \r */
2760  resetPQExpBuffer(query_buf);
2761  psql_scan_reset(scan_state);
2762  }
2763  else
2764  ignore_slash_options(scan_state);
2765 
2767 }
static bool do_watch(PQExpBuffer query_buf, double sleep)
Definition: command.c:4969

References copy_previous_query(), do_watch(), free, ignore_slash_options(), OT_NORMAL, PSQL_CMD_ERROR, PSQL_CMD_SKIP_LINE, psql_scan_reset(), psql_scan_slash_option(), resetPQExpBuffer(), 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 2645 of file command.c.

2648 {
2650 
2651  if (active_branch)
2652  {
2653  char *fname = psql_scan_slash_option(scan_state,
2654  OT_FILEPIPE, NULL, true);
2655  FILE *fd = NULL;
2656  bool is_pipe = false;
2657 
2658  if (!query_buf)
2659  {
2660  pg_log_error("no query buffer");
2662  }
2663  else
2664  {
2665  if (!fname)
2666  {
2667  pg_log_error("\\%s: missing required argument", cmd);
2669  }
2670  else
2671  {
2672  expand_tilde(&fname);
2673  if (fname[0] == '|')
2674  {
2675  is_pipe = true;
2677  fd = popen(&fname[1], "w");
2678  }
2679  else
2680  {
2681  canonicalize_path(fname);
2682  fd = fopen(fname, "w");
2683  }
2684  if (!fd)
2685  {
2686  pg_log_error("%s: %m", fname);
2688  }
2689  }
2690  }
2691 
2692  if (fd)
2693  {
2694  int result;
2695 
2696  /*
2697  * We want to print the same thing \g would execute, but not to
2698  * change the query buffer state; so we can't use
2699  * copy_previous_query(). Also, beware of possibility that buffer
2700  * pointers are NULL.
2701  */
2702  if (query_buf && query_buf->len > 0)
2703  fprintf(fd, "%s\n", query_buf->data);
2704  else if (previous_buf && previous_buf->len > 0)
2705  fprintf(fd, "%s\n", previous_buf->data);
2706 
2707  if (is_pipe)
2708  result = pclose(fd);
2709  else
2710  result = fclose(fd);
2711 
2712  if (result == EOF)
2713  {
2714  pg_log_error("%s: %m", fname);
2716  }
2717  }
2718 
2719  if (is_pipe)
2721 
2722  free(fname);
2723  }
2724  else
2725  ignore_slash_filepipe(scan_state);
2726 
2727  return status;
2728 }

References canonicalize_path(), PQExpBufferData::data, disable_sigpipe_trap(), expand_tilde(), fd(), fprintf