PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
createlang.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * createlang
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/createlang.c
9  *
10  *-------------------------------------------------------------------------
11  */
12 #include "postgres_fe.h"
13 
14 #include "common.h"
15 #include "fe_utils/print.h"
16 
17 static void help(const char *progname);
18 
19 
20 int
21 main(int argc, char *argv[])
22 {
23  static struct option long_options[] = {
24  {"list", no_argument, NULL, 'l'},
25  {"host", required_argument, NULL, 'h'},
26  {"port", required_argument, NULL, 'p'},
27  {"username", required_argument, NULL, 'U'},
28  {"no-password", no_argument, NULL, 'w'},
29  {"password", no_argument, NULL, 'W'},
30  {"dbname", required_argument, NULL, 'd'},
31  {"echo", no_argument, NULL, 'e'},
32  {NULL, 0, NULL, 0}
33  };
34 
35  const char *progname;
36  int optindex;
37  int c;
38 
39  bool listlangs = false;
40  const char *dbname = NULL;
41  char *host = NULL;
42  char *port = NULL;
43  char *username = NULL;
44  enum trivalue prompt_password = TRI_DEFAULT;
45  bool echo = false;
46  char *langname = NULL;
47 
48  char *p;
49 
50  PQExpBufferData sql;
51 
52  PGconn *conn;
53  PGresult *result;
54 
55  progname = get_progname(argv[0]);
56  set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pgscripts"));
57 
58  handle_help_version_opts(argc, argv, "createlang", help);
59 
60  while ((c = getopt_long(argc, argv, "lh:p:U:wWd:e", long_options, &optindex)) != -1)
61  {
62  switch (c)
63  {
64  case 'l':
65  listlangs = true;
66  break;
67  case 'h':
68  host = pg_strdup(optarg);
69  break;
70  case 'p':
71  port = pg_strdup(optarg);
72  break;
73  case 'U':
74  username = pg_strdup(optarg);
75  break;
76  case 'w':
77  prompt_password = TRI_NO;
78  break;
79  case 'W':
80  prompt_password = TRI_YES;
81  break;
82  case 'd':
83  dbname = pg_strdup(optarg);
84  break;
85  case 'e':
86  echo = true;
87  break;
88  default:
89  fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
90  exit(1);
91  }
92  }
93 
94  /*
95  * We set dbname from positional arguments if it is not already set by
96  * option arguments -d. If not doing listlangs, positional dbname must
97  * follow positional langname.
98  */
99 
100  if (argc - optind > 0)
101  {
102  if (listlangs)
103  {
104  if (dbname == NULL)
105  dbname = argv[optind++];
106  }
107  else
108  {
109  langname = argv[optind++];
110  if (argc - optind > 0 && dbname == NULL)
111  dbname = argv[optind++];
112  }
113  }
114 
115  if (argc - optind > 0)
116  {
117  fprintf(stderr, _("%s: too many command-line arguments (first is \"%s\")\n"),
118  progname, argv[optind]);
119  fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
120  exit(1);
121  }
122 
123  if (dbname == NULL)
124  {
125  if (getenv("PGDATABASE"))
126  dbname = getenv("PGDATABASE");
127  else if (getenv("PGUSER"))
128  dbname = getenv("PGUSER");
129  else
130  dbname = get_user_name_or_exit(progname);
131  }
132 
133  initPQExpBuffer(&sql);
134 
135  /*
136  * List option
137  */
138  if (listlangs)
139  {
140  printQueryOpt popt;
141  static const bool translate_columns[] = {false, true};
142 
143  conn = connectDatabase(dbname, host, port, username, prompt_password,
144  progname, false, false);
145 
146  printfPQExpBuffer(&sql, "SELECT lanname as \"%s\", "
147  "(CASE WHEN lanpltrusted THEN '%s' ELSE '%s' END) as \"%s\" "
148  "FROM pg_catalog.pg_language WHERE lanispl;",
149  gettext_noop("Name"),
150  gettext_noop("yes"), gettext_noop("no"),
151  gettext_noop("Trusted?"));
152  result = executeQuery(conn, sql.data, progname, echo);
153 
154  memset(&popt, 0, sizeof(popt));
155  popt.topt.format = PRINT_ALIGNED;
156  popt.topt.border = 1;
157  popt.topt.start_table = true;
158  popt.topt.stop_table = true;
159  popt.topt.encoding = PQclientEncoding(conn);
160  popt.title = _("Procedural Languages");
161  popt.translate_header = true;
162  popt.translate_columns = translate_columns;
163  popt.n_translate_columns = lengthof(translate_columns);
164 
165  printQuery(result, &popt, stdout, false, NULL);
166 
167  PQfinish(conn);
168  exit(0);
169  }
170 
171  if (langname == NULL)
172  {
173  fprintf(stderr, _("%s: missing required argument language name\n"), progname);
174  fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
175  exit(1);
176  }
177 
178  /* lower case language name */
179  for (p = langname; *p; p++)
180  if (*p >= 'A' && *p <= 'Z')
181  *p += ('a' - 'A');
182 
183  conn = connectDatabase(dbname, host, port, username, prompt_password,
184  progname, false, false);
185 
186  /*
187  * Make sure the language isn't already installed
188  */
189  printfPQExpBuffer(&sql,
190  "SELECT oid FROM pg_catalog.pg_language WHERE lanname = '%s';",
191  langname);
192  result = executeQuery(conn, sql.data, progname, echo);
193  if (PQntuples(result) > 0)
194  {
195  fprintf(stderr,
196  _("%s: language \"%s\" is already installed in database \"%s\"\n"),
197  progname, langname, PQdb(conn));
198  PQfinish(conn);
199  /* separate exit status for "already installed" */
200  exit(2);
201  }
202  PQclear(result);
203 
204  /*
205  * In 9.1 and up, assume that languages should be installed using CREATE
206  * EXTENSION. However, it's possible this tool could be used against an
207  * older server, and it's easy enough to continue supporting the old way.
208  */
209  if (PQserverVersion(conn) >= 90100)
210  printfPQExpBuffer(&sql, "CREATE EXTENSION \"%s\";", langname);
211  else
212  printfPQExpBuffer(&sql, "CREATE LANGUAGE \"%s\";", langname);
213 
214  if (echo)
215  printf("%s\n", sql.data);
216  result = PQexec(conn, sql.data);
217  if (PQresultStatus(result) != PGRES_COMMAND_OK)
218  {
219  fprintf(stderr, _("%s: language installation failed: %s"),
220  progname, PQerrorMessage(conn));
221  PQfinish(conn);
222  exit(1);
223  }
224 
225  PQclear(result);
226  PQfinish(conn);
227  exit(0);
228 }
229 
230 
231 
232 static void
233 help(const char *progname)
234 {
235  printf(_("%s installs a procedural language into a PostgreSQL database.\n\n"), progname);
236  printf(_("Usage:\n"));
237  printf(_(" %s [OPTION]... LANGNAME [DBNAME]\n"), progname);
238  printf(_("\nOptions:\n"));
239  printf(_(" -d, --dbname=DBNAME database to install language in\n"));
240  printf(_(" -e, --echo show the commands being sent to the server\n"));
241  printf(_(" -l, --list show a list of currently installed languages\n"));
242  printf(_(" -V, --version output version information, then exit\n"));
243  printf(_(" -?, --help show this help, then exit\n"));
244  printf(_("\nConnection options:\n"));
245  printf(_(" -h, --host=HOSTNAME database server host or socket directory\n"));
246  printf(_(" -p, --port=PORT database server port\n"));
247  printf(_(" -U, --username=USERNAME user name to connect as\n"));
248  printf(_(" -w, --no-password never prompt for password\n"));
249  printf(_(" -W, --password force password prompt\n"));
250  printf(_("\nReport bugs to <pgsql-bugs@postgresql.org>.\n"));
251 }
static PGresult * executeQuery(PGconn *conn, const char *query)
Definition: pg_dumpall.c:2061
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:5959
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:3516
int main(int argc, char *argv[])
Definition: createlang.c:21
#define lengthof(array)
Definition: c.h:558
int PQserverVersion(const PGconn *conn)
Definition: fe-connect.c:5949
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:6019
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:42
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:1012
static void help(const char *progname)
Definition: createlang.c:233
static char * username
Definition: initdb.c:129
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:5827
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:1812
int n_translate_columns
Definition: print.h:172
char * dbname
Definition: streamutil.c:38
void printQuery(const PGresult *result, const printQueryOpt *opt, FILE *fout, bool is_pager, FILE *flog)
Definition: print.c:3285
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
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:74