Fix a few errors in comments. Patch by Fujii Masao, plus the one in
[PostgreSQL.git] / src / bin / scripts / droplang.c
blobfcd47fc90363e8ec2ea5b81de841a4c73ab613fd
1 /*-------------------------------------------------------------------------
3 * droplang
5 * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
6 * Portions Copyright (c) 1994, Regents of the University of California
8 * $PostgreSQL$
10 *-------------------------------------------------------------------------
13 #include "postgres_fe.h"
14 #include "common.h"
15 #include "print.h"
17 #define atooid(x) ((Oid) strtoul((x), NULL, 10))
20 static void help(const char *progname);
23 int
24 main(int argc, char *argv[])
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}
38 const char *progname;
39 int optindex;
40 int c;
42 bool listlangs = false;
43 const char *dbname = NULL;
44 char *host = NULL;
45 char *port = NULL;
46 char *username = NULL;
47 enum trivalue prompt_password = TRI_DEFAULT;
48 bool echo = false;
49 char *langname = NULL;
51 char *p;
52 Oid lanplcallfoid;
53 Oid lanvalidator;
54 char *handler;
55 char *validator;
56 char *handler_ns;
57 char *validator_ns;
58 bool keephandler;
59 bool keepvalidator;
61 PQExpBufferData sql;
63 PGconn *conn;
64 PGresult *result;
66 progname = get_progname(argv[0]);
67 set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pgscripts"));
69 handle_help_version_opts(argc, argv, "droplang", help);
71 while ((c = getopt_long(argc, argv, "lh:p:U:wWd:e", long_options, &optindex)) != -1)
73 switch (c)
75 case 'l':
76 listlangs = true;
77 break;
78 case 'h':
79 host = optarg;
80 break;
81 case 'p':
82 port = optarg;
83 break;
84 case 'U':
85 username = optarg;
86 break;
87 case 'w':
88 prompt_password = TRI_NO;
89 break;
90 case 'W':
91 prompt_password = TRI_YES;
92 break;
93 case 'd':
94 dbname = optarg;
95 break;
96 case 'e':
97 echo = true;
98 break;
99 default:
100 fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
101 exit(1);
105 if (argc - optind > 0)
107 if (listlangs)
108 dbname = argv[optind++];
109 else
111 langname = argv[optind++];
112 if (argc - optind > 0)
113 dbname = argv[optind++];
117 if (argc - optind > 0)
119 fprintf(stderr, _("%s: too many command-line arguments (first is \"%s\")\n"),
120 progname, argv[optind]);
121 fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
122 exit(1);
125 if (dbname == NULL)
127 if (getenv("PGDATABASE"))
128 dbname = getenv("PGDATABASE");
129 else if (getenv("PGUSER"))
130 dbname = getenv("PGUSER");
131 else
132 dbname = get_user_name(progname);
135 initPQExpBuffer(&sql);
138 * List option
140 if (listlangs)
142 printQueryOpt popt;
143 static const bool translate_columns[] = {false, true};
145 conn = connectDatabase(dbname, host, port, username, prompt_password,
146 progname);
148 printfPQExpBuffer(&sql, "SELECT lanname as \"%s\", "
149 "(CASE WHEN lanpltrusted THEN '%s' ELSE '%s' END) as \"%s\" "
150 "FROM pg_catalog.pg_language WHERE lanispl;",
151 gettext_noop("Name"),
152 gettext_noop("yes"), gettext_noop("no"),
153 gettext_noop("Trusted?"));
154 result = executeQuery(conn, sql.data, progname, echo);
156 memset(&popt, 0, sizeof(popt));
157 popt.topt.format = PRINT_ALIGNED;
158 popt.topt.border = 1;
159 popt.topt.start_table = true;
160 popt.topt.stop_table = true;
161 popt.topt.encoding = PQclientEncoding(conn);
162 popt.title = _("Procedural Languages");
163 popt.translate_header = true;
164 popt.translate_columns = translate_columns;
165 printQuery(result, &popt, stdout, NULL);
167 PQfinish(conn);
168 exit(0);
171 if (langname == NULL)
173 fprintf(stderr, _("%s: missing required argument language name\n"),
174 progname);
175 fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
176 progname);
177 exit(1);
180 for (p = langname; *p; p++)
181 if (*p >= 'A' && *p <= 'Z')
182 *p += ('a' - 'A');
184 conn = connectDatabase(dbname, host, port, username, prompt_password, progname);
187 * Force schema search path to be just pg_catalog, so that we don't have
188 * to be paranoid about search paths below.
190 executeCommand(conn, "SET search_path = pg_catalog;", progname, echo);
193 * Make sure the language is installed and find the OIDs of the handler
194 * and validator functions
196 printfPQExpBuffer(&sql, "SELECT lanplcallfoid, lanvalidator "
197 "FROM pg_language WHERE lanname = '%s' AND lanispl;",
198 langname);
199 result = executeQuery(conn, sql.data, progname, echo);
200 if (PQntuples(result) == 0)
202 PQfinish(conn);
203 fprintf(stderr, _("%s: language \"%s\" is not installed in "
204 "database \"%s\"\n"),
205 progname, langname, dbname);
206 exit(1);
208 lanplcallfoid = atooid(PQgetvalue(result, 0, 0));
209 lanvalidator = atooid(PQgetvalue(result, 0, 1));
210 PQclear(result);
213 * Check that there are no functions left defined in that language
215 printfPQExpBuffer(&sql, "SELECT count(proname) FROM pg_proc P, "
216 "pg_language L WHERE P.prolang = L.oid "
217 "AND L.lanname = '%s';", langname);
218 result = executeQuery(conn, sql.data, progname, echo);
219 if (strcmp(PQgetvalue(result, 0, 0), "0") != 0)
221 PQfinish(conn);
222 fprintf(stderr,
223 _("%s: still %s functions declared in language \"%s\"; "
224 "language not removed\n"),
225 progname, PQgetvalue(result, 0, 0), langname);
226 exit(1);
228 PQclear(result);
231 * Check that the handler function isn't used by some other language
233 printfPQExpBuffer(&sql, "SELECT count(*) FROM pg_language "
234 "WHERE lanplcallfoid = %u AND lanname <> '%s';",
235 lanplcallfoid, langname);
236 result = executeQuery(conn, sql.data, progname, echo);
237 if (strcmp(PQgetvalue(result, 0, 0), "0") == 0)
238 keephandler = false;
239 else
240 keephandler = true;
241 PQclear(result);
244 * Find the handler name
246 if (!keephandler)
248 printfPQExpBuffer(&sql, "SELECT proname, (SELECT nspname "
249 "FROM pg_namespace ns WHERE ns.oid = pronamespace) "
250 "AS prons FROM pg_proc WHERE oid = %u;",
251 lanplcallfoid);
252 result = executeQuery(conn, sql.data, progname, echo);
253 handler = strdup(PQgetvalue(result, 0, 0));
254 handler_ns = strdup(PQgetvalue(result, 0, 1));
255 PQclear(result);
257 else
259 handler = NULL;
260 handler_ns = NULL;
264 * Check that the validator function isn't used by some other language
266 if (OidIsValid(lanvalidator))
268 printfPQExpBuffer(&sql, "SELECT count(*) FROM pg_language "
269 "WHERE lanvalidator = %u AND lanname <> '%s';",
270 lanvalidator, langname);
271 result = executeQuery(conn, sql.data, progname, echo);
272 if (strcmp(PQgetvalue(result, 0, 0), "0") == 0)
273 keepvalidator = false;
274 else
275 keepvalidator = true;
276 PQclear(result);
278 else
279 keepvalidator = true; /* don't try to delete it */
282 * Find the validator name
284 if (!keepvalidator)
286 printfPQExpBuffer(&sql, "SELECT proname, (SELECT nspname "
287 "FROM pg_namespace ns WHERE ns.oid = pronamespace) "
288 "AS prons FROM pg_proc WHERE oid = %u;",
289 lanvalidator);
290 result = executeQuery(conn, sql.data, progname, echo);
291 validator = strdup(PQgetvalue(result, 0, 0));
292 validator_ns = strdup(PQgetvalue(result, 0, 1));
293 PQclear(result);
295 else
297 validator = NULL;
298 validator_ns = NULL;
302 * Drop the language and the functions
304 printfPQExpBuffer(&sql, "DROP LANGUAGE \"%s\";\n", langname);
305 if (!keephandler)
306 appendPQExpBuffer(&sql, "DROP FUNCTION \"%s\".\"%s\" ();\n",
307 handler_ns, handler);
308 if (!keepvalidator)
309 appendPQExpBuffer(&sql, "DROP FUNCTION \"%s\".\"%s\" (oid);\n",
310 validator_ns, validator);
311 if (echo)
312 printf("%s", sql.data);
313 result = PQexec(conn, sql.data);
314 if (PQresultStatus(result) != PGRES_COMMAND_OK)
316 fprintf(stderr, _("%s: language removal failed: %s"),
317 progname, PQerrorMessage(conn));
318 PQfinish(conn);
319 exit(1);
322 PQclear(result);
323 PQfinish(conn);
324 exit(0);
328 static void
329 help(const char *progname)
331 printf(_("%s removes a procedural language from a database.\n\n"), progname);
332 printf(_("Usage:\n"));
333 printf(_(" %s [OPTION]... LANGNAME [DBNAME]\n"), progname);
334 printf(_("\nOptions:\n"));
335 printf(_(" -d, --dbname=DBNAME database from which to remove the language\n"));
336 printf(_(" -e, --echo show the commands being sent to the server\n"));
337 printf(_(" -l, --list show a list of currently installed languages\n"));
338 printf(_(" --help show this help, then exit\n"));
339 printf(_(" --version output version information, then exit\n"));
340 printf(_("\nConnection options:\n"));
341 printf(_(" -h, --host=HOSTNAME database server host or socket directory\n"));
342 printf(_(" -p, --port=PORT database server port\n"));
343 printf(_(" -U, --username=USERNAME user name to connect as\n"));
344 printf(_(" -w, --no-password never prompt for password\n"));
345 printf(_(" -W, --password force password prompt\n"));
346 printf(_("\nReport bugs to <pgsql-bugs@postgresql.org>.\n"));