186
* Takes an optional regexp to select particular functions
186
* Takes an optional regexp to select particular functions.
188
* As with \d, you can specify the kinds of functions you want:
195
* and you can mix and match these in any order.
189
describeFunctions(const char *pattern, bool verbose, bool showSystem)
198
describeFunctions(const char *functypes, const char *pattern, bool verbose, bool showSystem)
200
bool showAggregate = strchr(functypes, 'a') != NULL;
201
bool showNormal = strchr(functypes, 'n') != NULL;
202
bool showTrigger = strchr(functypes, 't') != NULL;
203
bool showWindow = strchr(functypes, 'w') != NULL;
191
205
PQExpBufferData buf;
193
207
printQueryOpt myopt = pset.popt;
209
if (strlen(functypes) != strspn(functypes, "antwS+"))
211
fprintf(stderr, _("\\df only takes [antwS+] as options\n"));
215
if (showWindow && pset.sversion < 80400)
217
fprintf(stderr, _("\\df does not take a \"w\" option in %d.%d.\n"),
218
pset.sversion / 10000, (pset.sversion / 100) % 100);
222
if (!showAggregate && !showNormal && !showTrigger && !showWindow)
224
showAggregate = showNormal = showTrigger = true;
225
if (pset.sversion >= 80400)
195
229
initPQExpBuffer(&buf);
197
231
printfPQExpBuffer(&buf,
203
237
if (pset.sversion >= 80400)
204
238
appendPQExpBuffer(&buf,
205
239
" pg_catalog.pg_get_function_result(p.oid) as \"%s\",\n"
206
" pg_catalog.pg_get_function_arguments(p.oid) as \"%s\"",
240
" pg_catalog.pg_get_function_arguments(p.oid) as \"%s\",\n"
242
" WHEN p.proisagg THEN '%s'\n"
243
" WHEN p.proiswindow THEN '%s'\n"
244
" WHEN pg_catalog.pg_get_function_result(p.oid) = 'trigger' THEN '%s'\n"
207
247
gettext_noop("Result data type"),
208
gettext_noop("Argument data types"));
248
gettext_noop("Argument data types"),
249
/* translator: "agg" is short for "aggregate" */
251
gettext_noop("window"),
252
gettext_noop("trigger"),
253
gettext_noop("normal"),
254
gettext_noop("Type"));
209
255
else if (pset.sversion >= 80100)
210
256
appendPQExpBuffer(&buf,
211
257
" CASE WHEN p.proretset THEN 'SETOF ' ELSE '' END ||\n"
239
285
" pg_catalog.generate_series(0, pg_catalog.array_upper(p.proargtypes, 1)) AS s(i)\n"
289
" WHEN p.proisagg THEN '%s'\n"
290
" WHEN 'trigger' = pg_catalog.format_type(p.prorettype, NULL) THEN '%s'\n"
241
292
" END AS \"%s\"",
242
293
gettext_noop("Result data type"),
243
gettext_noop("Argument data types"));
294
gettext_noop("Argument data types"),
295
/* translator: "agg" is short for "aggregate" */
297
gettext_noop("trigger"),
298
gettext_noop("normal"),
299
gettext_noop("Type"));
245
301
appendPQExpBuffer(&buf,
246
302
" CASE WHEN p.proretset THEN 'SETOF ' ELSE '' END ||\n"
247
303
" pg_catalog.format_type(p.prorettype, NULL) as \"%s\",\n"
248
" pg_catalog.oidvectortypes(p.proargtypes) as \"%s\"",
304
" pg_catalog.oidvectortypes(p.proargtypes) as \"%s\",\n"
306
" WHEN p.proisagg THEN '%s'\n"
307
" WHEN 'trigger' = pg_catalog.format_type(p.prorettype, NULL) THEN '%s'\n"
249
310
gettext_noop("Result data type"),
250
gettext_noop("Argument data types"));
311
gettext_noop("Argument data types"),
312
/* translator: "agg" is short for "aggregate" */
314
gettext_noop("trigger"),
315
gettext_noop("normal"),
316
gettext_noop("Type"));
253
319
appendPQExpBuffer(&buf,
274
340
appendPQExpBuffer(&buf,
275
341
" LEFT JOIN pg_catalog.pg_language l ON l.oid = p.prolang\n");
277
appendPQExpBuffer(&buf, "WHERE NOT p.proisagg\n");
343
processSQLNamePattern(pset.db, &buf, pattern, false, true,
344
"n.nspname", "p.proname", NULL,
345
"pg_catalog.pg_function_is_visible(p.oid)");
347
if (showNormal && showAggregate && showTrigger && showWindow)
351
if (!showWindow && pset.sversion >= 80400)
352
appendPQExpBuffer(&buf, " AND NOT p.proiswindow\n");
354
appendPQExpBuffer(&buf, " AND NOT p.proisagg\n");
357
if (pset.sversion >= 80400)
358
appendPQExpBuffer(&buf,
359
" AND pg_catalog.pg_get_function_result(p.oid) <> 'trigger'\n");
361
appendPQExpBuffer(&buf,
362
" AND pg_catalog.format_type(p.prorettype, NULL) <> 'trigger'\n");
367
bool needs_or = false;
369
appendPQExpBuffer(&buf, " AND (\n ");
372
appendPQExpBuffer(&buf,"p.proisagg\n");
378
appendPQExpBuffer(&buf, " OR ");
379
if (pset.sversion >= 80400)
380
appendPQExpBuffer(&buf,
381
"pg_catalog.pg_get_function_result(p.oid) = 'trigger'\n");
383
appendPQExpBuffer(&buf,
384
"'trigger' <> pg_catalog.format_type(p.prorettype, NULL)\n");
390
appendPQExpBuffer(&buf, " OR ");
391
appendPQExpBuffer(&buf, "p.proiswindow\n");
393
appendPQExpBuffer(&buf, " )\n");
279
396
if (!showSystem && !pattern)
280
397
appendPQExpBuffer(&buf, " AND n.nspname <> 'pg_catalog'\n"
281
398
" AND n.nspname <> 'information_schema'\n");
283
processSQLNamePattern(pset.db, &buf, pattern, true, false,
284
"n.nspname", "p.proname", NULL,
285
"pg_catalog.pg_function_is_visible(p.oid)");
287
400
appendPQExpBuffer(&buf, "ORDER BY 1, 2, 4;");
289
402
res = PSQLexec(buf.data, false);