1 /*-------------------------------------------------------------------------
5 * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
6 * Portions Copyright (c) 1994, Regents of the University of California
8 * $PostgreSQL: pgsql/src/bin/scripts/createlang.c,v 1.12 2004/06/03 00:07:38 momjian Exp $
10 *-------------------------------------------------------------------------
13 #include "postgres_fe.h"
18 static void help(const char *progname);
22 main(int argc, char *argv[])
24 static struct option long_options[] = {
25 {"list", no_argument, NULL, 'l'},
26 {"host", required_argument, NULL, 'h'},
27 {"port", required_argument, NULL, 'p'},
28 {"username", required_argument, NULL, 'U'},
29 {"password", no_argument, NULL, 'W'},
30 {"dbname", required_argument, NULL, 'd'},
31 {"pglib", required_argument, NULL, 'L'},
32 {"echo", no_argument, NULL, 'e'},
40 bool listlangs = false;
41 const char *dbname = NULL;
44 char *username = NULL;
45 bool password = false;
48 char *langname = NULL;
55 char *validator = NULL;
63 progname = get_progname(argv[0]);
64 set_pglocale_pgservice(argv[0], "pgscripts");
66 handle_help_version_opts(argc, argv, "createlang", help);
68 while ((c = getopt_long(argc, argv, "lh:p:U:Wd:L:e", long_options, &optindex)) != -1)
97 fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
102 if (argc - optind > 0)
105 dbname = argv[optind++];
108 langname = argv[optind++];
109 if (argc - optind > 0)
110 dbname = argv[optind++];
114 if (argc - optind > 0)
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);
124 if (getenv("PGDATABASE"))
125 dbname = getenv("PGDATABASE");
126 else if (getenv("PGUSER"))
127 dbname = getenv("PGUSER");
129 dbname = get_user_name(progname);
132 initPQExpBuffer(&sql);
141 conn = connectDatabase(dbname, host, port, username, password, progname);
143 printfPQExpBuffer(&sql, "SELECT lanname as \"%s\", (CASE WHEN lanpltrusted THEN '%s' ELSE '%s' END) as \"%s\" FROM pg_language WHERE lanispl IS TRUE;", _("Name"), _("yes"), _("no"), _("Trusted?"));
144 result = executeQuery(conn, sql.data, progname, echo);
146 memset(&popt, 0, sizeof(popt));
147 popt.topt.format = PRINT_ALIGNED;
148 popt.topt.border = 1;
149 popt.topt.encoding = PQclientEncoding(conn);
150 popt.title = _("Procedural Languages");
151 printQuery(result, &popt, stdout);
157 if (langname == NULL)
159 fprintf(stderr, _("%s: missing required argument language name\n"), progname);
160 fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
167 for (p = langname; *p; p++)
168 if (*p >= 'A' && *p <= 'Z')
171 if (strcmp(langname, "plpgsql") == 0)
174 handler = "plpgsql_call_handler";
175 validator = "plpgsql_validator";
178 else if (strcmp(langname, "pltcl") == 0)
181 handler = "pltcl_call_handler";
184 else if (strcmp(langname, "pltclu") == 0)
187 handler = "pltclu_call_handler";
190 else if (strcmp(langname, "plperl") == 0)
193 handler = "plperl_call_handler";
196 else if (strcmp(langname, "plperlu") == 0)
199 handler = "plperl_call_handler";
202 else if (strcmp(langname, "plpythonu") == 0)
205 handler = "plpython_call_handler";
210 fprintf(stderr, _("%s: unsupported language \"%s\"\n"), progname, langname);
211 fprintf(stderr, _("Supported languages are plpgsql, pltcl, pltclu, plperl, plperlu, and plpythonu.\n"));
215 conn = connectDatabase(dbname, host, port, username, password, progname);
218 * Make sure the language isn't already installed
220 printfPQExpBuffer(&sql, "SELECT oid FROM pg_language WHERE lanname = '%s';", langname);
221 result = executeQuery(conn, sql.data, progname, echo);
222 if (PQntuples(result) > 0)
226 _("%s: language \"%s\" is already installed in database \"%s\"\n"),
227 progname, langname, dbname);
228 /* separate exit status for "already installed" */
234 * Check whether the call handler exists
236 printfPQExpBuffer(&sql, "SELECT oid FROM pg_proc WHERE proname = '%s' AND prorettype = 'pg_catalog.language_handler'::regtype AND pronargs = 0;", handler);
237 result = executeQuery(conn, sql.data, progname, echo);
238 handlerexists = (PQntuples(result) > 0);
242 * Check whether the validator exists
246 printfPQExpBuffer(&sql, "SELECT oid FROM pg_proc WHERE proname = '%s' AND proargtypes[0] = 'pg_catalog.oid'::regtype AND pronargs = 1;", validator);
247 result = executeQuery(conn, sql.data, progname, echo);
248 validatorexists = (PQntuples(result) > 0);
252 validatorexists = true; /* don't try to create it */
255 * Create the function(s) and the language
257 resetPQExpBuffer(&sql);
260 appendPQExpBuffer(&sql,
261 "CREATE FUNCTION \"%s\" () RETURNS language_handler AS '%s/%s' LANGUAGE C;\n",
262 handler, pglib, object);
264 if (!validatorexists)
265 appendPQExpBuffer(&sql,
266 "CREATE FUNCTION \"%s\" (oid) RETURNS void AS '%s/%s' LANGUAGE C;\n",
267 validator, pglib, object);
269 appendPQExpBuffer(&sql,
270 "CREATE %sLANGUAGE \"%s\" HANDLER \"%s\"",
271 (trusted ? "TRUSTED " : ""), langname, handler);
274 appendPQExpBuffer(&sql, " VALIDATOR \"%s\"", validator);
276 appendPQExpBuffer(&sql, ";\n");
279 printf("%s", sql.data);
280 result = PQexec(conn, sql.data);
281 if (PQresultStatus(result) != PGRES_COMMAND_OK)
283 fprintf(stderr, _("%s: language installation failed: %s"),
284 progname, PQerrorMessage(conn));
296 help(const char *progname)
298 printf(_("%s installs a procedural language into a PostgreSQL database.\n\n"), progname);
299 printf(_("Usage:\n"));
300 printf(_(" %s [OPTION]... LANGNAME [DBNAME]\n"), progname);
301 printf(_("\nOptions:\n"));
302 printf(_(" -d, --dbname=DBNAME database to install language in\n"));
303 printf(_(" -e, --echo show the commands being sent to the server\n"));
304 printf(_(" -l, --list show a list of currently installed languages\n"));
305 printf(_(" -L, --pglib=DIRECTORY find language interpreter file in DIRECTORY\n"));
306 printf(_(" -h, --host=HOSTNAME database server host or socket directory\n"));
307 printf(_(" -p, --port=PORT database server port\n"));
308 printf(_(" -U, --username=USERNAME user name to connect as\n"));
309 printf(_(" -W, --password prompt for password\n"));
310 printf(_(" --help show this help, then exit\n"));
311 printf(_(" --version output version information, then exit\n"));
312 printf(_("\nReport bugs to <pgsql-bugs@postgresql.org>.\n"));