PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
droplang.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * droplang
4  *
5  * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
6  * Portions Copyright (c) 1994, Regents of the University of California
7  *
8  * src/bin/scripts/droplang.c
9  *
10  *-------------------------------------------------------------------------
11  */
12 #include "postgres_fe.h"
13 
14 #include "common.h"
15 #include "fe_utils/print.h"
16 
17 #define atooid(x) ((Oid) strtoul((x), NULL, 10))
18 
19 
20 static void help(const char *progname);
21 
22 
23 int
24 main(int argc, char *argv[])
25 {
26  static struct option long_options[] = {
27  {"list", no_argument, NULL, 'l'},
28  {"host", required_argument, NULL, 'h'},
29  {"port", required_argument, NULL, 'p'},
30  {"username", required_argument, NULL, 'U'},
31  {"no-password", no_argument, NULL, 'w'},
32  {"password", no_argument, NULL, 'W'},
33  {"dbname", required_argument, NULL, 'd'},
34  {"echo", no_argument, NULL, 'e'},
35  {NULL, 0, NULL, 0}
36  };
37 
38  const char *progname;
39  int optindex;
40  int c;
41  bool listlangs = false;
42  const char *dbname = NULL;
43  char *host = NULL;
44  char *port = NULL;
45  char *username = NULL;
46  enum trivalue prompt_password = TRI_DEFAULT;
47  bool echo = false;
48  char *langname = NULL;
49  char *p;
50  PQExpBufferData sql;
51  PGconn *conn;
52  PGresult *result;
53 
54  progname = get_progname(argv[0]);
55  set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pgscripts"));
56 
57  handle_help_version_opts(argc, argv, "droplang", help);
58 
59  while ((c = getopt_long(argc, argv, "lh:p:U:wWd:e", long_options, &optindex)) != -1)
60  {
61  switch (c)
62  {
63  case 'l':
64  listlangs = true;
65  break;
66  case 'h':
67  host = pg_strdup(optarg);
68  break;
69  case 'p':
70  port = pg_strdup(optarg);
71  break;
72  case 'U':
73  username = pg_strdup(optarg);
74  break;
75  case 'w':
76  prompt_password = TRI_NO;
77  break;
78  case 'W':
79  prompt_password = TRI_YES;
80  break;
81  case 'd':
82  dbname = pg_strdup(optarg);
83  break;
84  case 'e':
85  echo = true;
86  break;
87  default:
88  fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
89  exit(1);
90  }
91  }
92 
93  /*
94  * We set dbname from positional arguments if it is not already set by
95  * option arguments -d. If not doing listlangs, positional dbname must
96  * follow positional langname.
97  */
98 
99  if (argc - optind > 0)
100  {
101  if (listlangs)
102  {
103  if (dbname == NULL)
104  dbname = argv[optind++];
105  }
106  else
107  {
108  langname = argv[optind++];
109  if (argc - optind > 0 && dbname == NULL)
110  dbname = argv[optind++];
111  }
112  }
113 
114  if (argc - optind > 0)
115  {
116  fprintf(stderr, _("%s: too many command-line arguments (first is \"%s\")\n"),
117  progname, argv[optind]);
118  fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
119  exit(1);
120  }
121 
122  if (dbname == NULL)
123  {
124  if (getenv("PGDATABASE"))
125  dbname = getenv("PGDATABASE");
126  else if (getenv("PGUSER"))
127  dbname = getenv("PGUSER");
128  else
129  dbname = get_user_name_or_exit(progname);
130  }
131 
132  initPQExpBuffer(&sql);
133 
134  /*
135  * List option
136  */
137  if (listlangs)
138  {
139  printQueryOpt popt;
140  static const bool translate_columns[] = {false, true};
141 
142  conn = connectDatabase(dbname, host, port, username, prompt_password,
143  progname, false, false);
144 
145  printfPQExpBuffer(&sql, "SELECT lanname as \"%s\", "
146  "(CASE WHEN lanpltrusted THEN '%s' ELSE '%s' END) as \"%s\" "
147  "FROM pg_catalog.pg_language WHERE lanispl;",
148  gettext_noop("Name"),
149  gettext_noop("yes"), gettext_noop("no"),
150  gettext_noop("Trusted?"));
151  result = executeQuery(conn, sql.data, progname, echo);
152 
153  memset(&popt, 0, sizeof(popt));
154  popt.topt.format = PRINT_ALIGNED;
155  popt.topt.border = 1;
156  popt.topt.start_table = true;
157  popt.topt.stop_table = true;
158  popt.topt.encoding = PQclientEncoding(conn);
159  popt.title = _("Procedural Languages");
160  popt.translate_header = true;
161  popt.translate_columns = translate_columns;
162  popt.n_translate_columns = lengthof(translate_columns);
163 
164  printQuery(result, &popt, stdout, false, NULL);
165 
166  PQfinish(conn);
167  exit(0);
168  }
169 
170  if (langname == NULL)
171  {
172  fprintf(stderr, _("%s: missing required argument language name\n"),
173  progname);
174  fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
175  progname);
176  exit(1);
177  }
178 
179  /* lower case language name */
180  for (p = langname; *p; p++)
181  if (*p >= 'A' && *p <= 'Z')
182  *p += ('a' - 'A');
183 
184  conn = connectDatabase(dbname, host, port, username, prompt_password,
185  progname, false, false);
186 
187  /*
188  * Force schema search path to be just pg_catalog, so that we don't have
189  * to be paranoid about search paths below.
190  */
191  executeCommand(conn, "SET search_path = pg_catalog;", progname, echo);
192 
193  /*
194  * Make sure the language is installed
195  */
196  printfPQExpBuffer(&sql, "SELECT oid "
197  "FROM pg_language WHERE lanname = '%s' AND lanispl;",
198  langname);
199  result = executeQuery(conn, sql.data, progname, echo);
200  if (PQntuples(result) == 0)
201  {
202  fprintf(stderr, _("%s: language \"%s\" is not installed in "
203  "database \"%s\"\n"),
204  progname, langname, PQdb(conn));
205  PQfinish(conn);
206  exit(1);
207  }
208  PQclear(result);
209 
210  /*
211  * Attempt to drop the language. We do not use CASCADE, so that the drop
212  * will fail if there are any functions in the language.
213  */
214  printfPQExpBuffer(&sql, "DROP EXTENSION \"%s\";", langname);
215 
216  if (echo)
217  printf("%s\n", sql.data);
218  result = PQexec(conn, sql.data);
219  if (PQresultStatus(result) != PGRES_COMMAND_OK)
220  {
221  fprintf(stderr, _("%s: language removal failed: %s"),
222  progname, PQerrorMessage(conn));
223  PQfinish(conn);
224  exit(1);
225  }
226 
227  PQclear(result);
228  PQfinish(conn);
229  exit(0);
230 }
231 
232 
233 static void
234 help(const char *progname)
235 {
236  printf(_("%s removes a procedural language from a database.\n\n"), progname);
237  printf(_("Usage:\n"));
238  printf(_(" %s [OPTION]... LANGNAME [DBNAME]\n"), progname);
239  printf(_("\nOptions:\n"));
240  printf(_(" -d, --dbname=DBNAME database from which to remove the language\n"));
241  printf(_(" -e, --echo show the commands being sent to the server\n"));
242  printf(_(" -l, --list show a list of currently installed languages\n"));
243  printf(_(" -V, --version output version information, then exit\n"));
244  printf(_(" -?, --help show this help, then exit\n"));
245  printf(_("\nConnection options:\n"));
246  printf(_(" -h, --host=HOSTNAME database server host or socket directory\n"));
247  printf(_(" -p, --port=PORT database server port\n"));
248  printf(_(" -U, --username=USERNAME user name to connect as\n"));
249  printf(_(" -w, --no-password never prompt for password\n"));
250  printf(_(" -W, --password force password prompt\n"));
251  printf(_("\nReport bugs to <pgsql-bugs@postgresql.org>.\n"));
252 }
static PGresult * executeQuery(PGconn *conn, const char *query)
Definition: pg_dumpall.c:2065
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:5960
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
int encoding
Definition: print.h:118
const char * get_progname(const char *argv0)
Definition: path.c:453
int getopt_long(int argc, char *const argv[], const char *optstring, const struct option *longopts, int *longindex)
Definition: getopt_long.c:57
bool start_table
Definition: print.h:108
enum printFormat format
Definition: print.h:98
printTableOpt topt
Definition: print.h:165
#define gettext_noop(x)
Definition: c.h:139
void PQfinish(PGconn *conn)
Definition: fe-connect.c:3517
#define lengthof(array)
Definition: c.h:557
const char * progname
Definition: pg_standby.c:37
int PQntuples(const PGresult *res)
Definition: fe-exec.c:2673
int PQclientEncoding(const PGconn *conn)
Definition: fe-connect.c:6020
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2596
unsigned short int border
Definition: print.h:101
#define required_argument
Definition: getopt_long.h:25
int optind
Definition: getopt.c:51
PGconn * conn
Definition: streamutil.c:45
static void executeCommand(PGconn *conn, const char *query)
Definition: pg_dumpall.c:2091
char * c
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
bool translate_header
Definition: print.h:169
static int port
Definition: pg_regress.c:87
void handle_help_version_opts(int argc, char *argv[], const char *fixed_progname, help_handler hlp)
Definition: common.c:35
trivalue
Definition: vacuumlo.c:31
#define no_argument
Definition: getopt_long.h:24
#define PG_TEXTDOMAIN(domain)
Definition: c.h:1011
static char * username
Definition: initdb.c:130
void PQclear(PGresult *res)
Definition: fe-exec.c:650
bool stop_table
Definition: print.h:109
char * PQdb(const PGconn *conn)
Definition: fe-connect.c:5828
char * title
Definition: print.h:167
#define NULL
Definition: c.h:226
static PGconn * connectDatabase(const char *dbname, const char *connstr, const char *pghost, const char *pgport, const char *pguser, trivalue prompt_password, bool fail_on_error)
Definition: pg_dumpall.c:1816
int n_translate_columns
Definition: print.h:172
char * dbname
Definition: streamutil.c:41
void printQuery(const PGresult *result, const printQueryOpt *opt, FILE *fout, bool is_pager, FILE *flog)
Definition: print.c:3286
static void help(const char *progname)
Definition: droplang.c:234
void set_pglocale_pgservice(const char *argv0, const char *app)
Definition: exec.c:550
char * optarg
Definition: getopt.c:53
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:1846
int main(int argc, char *argv[])
Definition: droplang.c:24
const bool * translate_columns
Definition: print.h:170
#define _(x)
Definition: elog.c:84
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:89
const char * get_user_name_or_exit(const char *progname)
Definition: username.c:76