aboutsummaryrefslogtreecommitdiff
path: root/src/bin/psql/describe.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/bin/psql/describe.c')
-rw-r--r--src/bin/psql/describe.c698
1 files changed, 359 insertions, 339 deletions
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index 631a04b336d..75c9df37143 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -3,7 +3,7 @@
*
* Copyright 2000 by PostgreSQL Global Development Group
*
- * $Header: /cvsroot/pgsql/src/bin/psql/describe.c,v 1.18 2000/02/26 18:31:25 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/bin/psql/describe.c,v 1.19 2000/04/12 17:16:22 momjian Exp $
*/
#include "postgres.h"
#include "describe.h"
@@ -45,10 +45,10 @@ describeAggregates(const char *name)
*/
strcpy(buf,
"SELECT a.aggname AS \"Name\", t.typname AS \"Type\",\n"
- " obj_description(a.oid) as \"Description\"\n"
- "FROM pg_aggregate a, pg_type t\n"
- "WHERE a.aggbasetype = t.oid\n"
- );
+ " obj_description(a.oid) as \"Description\"\n"
+ "FROM pg_aggregate a, pg_type t\n"
+ "WHERE a.aggbasetype = t.oid\n"
+ );
if (name)
{
@@ -60,10 +60,10 @@ describeAggregates(const char *name)
strcat(buf,
"UNION\n"
"SELECT a.aggname AS \"Name\", '(all types)' as \"Type\",\n"
- " obj_description(a.oid) as \"Description\"\n"
+ " obj_description(a.oid) as \"Description\"\n"
"FROM pg_aggregate a\n"
- "WHERE a.aggbasetype = 0\n"
- );
+ "WHERE a.aggbasetype = 0\n"
+ );
if (name)
{
@@ -103,21 +103,21 @@ describeFunctions(const char *name, bool verbose)
* arguments, but have no types defined for those arguments
*/
strcpy(buf,
- "SELECT t.typname as \"Result\", p.proname as \"Function\",\n"
+ "SELECT t.typname as \"Result\", p.proname as \"Function\",\n"
" oidvectortypes(p.proargtypes) as \"Arguments\"");
- if (verbose)
- strcat(buf, ",\n u.usename as \"Owner\", l.lanname as \"Language\", p.prosrc as \"Source\",\n"
- " obj_description(p.oid) as \"Description\"");
+ if (verbose)
+ strcat(buf, ",\n u.usename as \"Owner\", l.lanname as \"Language\", p.prosrc as \"Source\",\n"
+ " obj_description(p.oid) as \"Description\"");
- if (!verbose)
- strcat(buf,
- "\nFROM pg_proc p, pg_type t\n"
- "WHERE p.prorettype = t.oid and (pronargs = 0 or oidvectortypes(p.proargtypes) != '')\n");
- else
- strcat(buf,
- "\nFROM pg_proc p, pg_type t, pg_language l, pg_user u\n"
- "WHERE p.prorettype = t.oid AND p.prolang = l.oid AND p.proowner = u.usesysid\n"
- " AND (pronargs = 0 or oidvectortypes(p.proargtypes) != '')\n");
+ if (!verbose)
+ strcat(buf,
+ "\nFROM pg_proc p, pg_type t\n"
+ "WHERE p.prorettype = t.oid and (pronargs = 0 or oidvectortypes(p.proargtypes) != '')\n");
+ else
+ strcat(buf,
+ "\nFROM pg_proc p, pg_type t, pg_language l, pg_user u\n"
+ "WHERE p.prorettype = t.oid AND p.prolang = l.oid AND p.proowner = u.usesysid\n"
+ " AND (pronargs = 0 or oidvectortypes(p.proargtypes) != '')\n");
if (name)
{
@@ -154,13 +154,14 @@ describeTypes(const char *name, bool verbose)
printQueryOpt myopt = pset.popt;
strcpy(buf, "SELECT t.typname AS \"Type\"");
- if (verbose)
- strcat(buf, ",\n (CASE WHEN t.typlen = -1 THEN 'var'::text ELSE t.typlen::text END) as \"Size\"");
+ if (verbose)
+ strcat(buf, ",\n (CASE WHEN t.typlen = -1 THEN 'var'::text ELSE t.typlen::text END) as \"Size\"");
strcat(buf, ",\n obj_description(t.oid) as \"Description\"");
- /*
- * do not include array types (start with underscore),
- * do not include user relations (typrelid!=0)
- */
+
+ /*
+ * do not include array types (start with underscore), do not include
+ * user relations (typrelid!=0)
+ */
strcat(buf, "\nFROM pg_type t\nWHERE t.typrelid = 0 AND t.typname !~ '^_.*'\n");
if (name)
@@ -196,12 +197,12 @@ describeOperators(const char *name)
printQueryOpt myopt = pset.popt;
strcpy(buf,
- "SELECT o.oprname AS \"Op\",\n"
+ "SELECT o.oprname AS \"Op\",\n"
" t1.typname AS \"Left arg\",\n"
" t2.typname AS \"Right arg\",\n"
" t0.typname AS \"Result\",\n"
" obj_description(p.oid) as \"Description\"\n"
- "FROM pg_proc p, pg_type t0,\n"
+ "FROM pg_proc p, pg_type t0,\n"
" pg_type t1, pg_type t2,\n"
" pg_operator o\n"
"WHERE p.prorettype = t0.oid AND\n"
@@ -221,8 +222,8 @@ describeOperators(const char *name)
" ''::name AS \"Left arg\",\n"
" t1.typname AS \"Right arg\",\n"
" t0.typname AS \"Result\",\n"
- " obj_description(p.oid) as \"Description\"\n"
- "FROM pg_operator o, pg_proc p, pg_type t0, pg_type t1\n"
+ " obj_description(p.oid) as \"Description\"\n"
+ "FROM pg_operator o, pg_proc p, pg_type t0, pg_type t1\n"
"WHERE RegprocToOid(o.oprcode) = p.oid AND\n"
" o.oprresult = t0.oid AND\n"
" o.oprkind = 'l' AND\n"
@@ -239,8 +240,8 @@ describeOperators(const char *name)
" t1.typname AS \"Left arg\",\n"
" ''::name AS \"Right arg\",\n"
" t0.typname AS \"Result\",\n"
- " obj_description(p.oid) as \"Description\"\n"
- "FROM pg_operator o, pg_proc p, pg_type t0, pg_type t1\n"
+ " obj_description(p.oid) as \"Description\"\n"
+ "FROM pg_operator o, pg_proc p, pg_type t0, pg_type t1\n"
"WHERE RegprocToOid(o.oprcode) = p.oid AND\n"
" o.oprresult = t0.oid AND\n"
" o.oprkind = 'r' AND\n"
@@ -280,7 +281,7 @@ listAllDbs(bool desc)
printQueryOpt myopt = pset.popt;
strcpy(buf,
- "SELECT pg_database.datname as \"Database\",\n"
+ "SELECT pg_database.datname as \"Database\",\n"
" pg_user.usename as \"Owner\"");
#ifdef MULTIBYTE
strcat(buf,
@@ -291,11 +292,11 @@ listAllDbs(bool desc)
strcat(buf, "FROM pg_database, pg_user\n"
"WHERE pg_database.datdba = pg_user.usesysid\n");
- /* Also include databases that have no valid owner. */
- strcat(buf, "\nUNION\n\n");
+ /* Also include databases that have no valid owner. */
+ strcat(buf, "\nUNION\n\n");
strcat(buf,
- "SELECT pg_database.datname as \"Database\",\n"
+ "SELECT pg_database.datname as \"Database\",\n"
" NULL as \"Owner\"");
#ifdef MULTIBYTE
strcat(buf,
@@ -304,9 +305,9 @@ listAllDbs(bool desc)
if (desc)
strcat(buf, ",\n obj_description(pg_database.oid) as \"Description\"\n");
strcat(buf, "FROM pg_database\n"
- "WHERE pg_database.datdba NOT IN (SELECT usesysid FROM pg_user)\n");
+ "WHERE pg_database.datdba NOT IN (SELECT usesysid FROM pg_user)\n");
- strcat(buf, "ORDER BY \"Database\"");
+ strcat(buf, "ORDER BY \"Database\"");
res = PSQLexec(buf);
if (!res)
@@ -352,11 +353,11 @@ permissionsList(const char *name)
if (!res)
return false;
- myopt.nullPrint = NULL;
- sprintf(descbuf, "Access permissions for database \"%s\"", PQdb(pset.db));
- myopt.title = descbuf;
+ myopt.nullPrint = NULL;
+ sprintf(descbuf, "Access permissions for database \"%s\"", PQdb(pset.db));
+ myopt.title = descbuf;
- printQuery(res, &myopt, pset.queryFout);
+ printQuery(res, &myopt, pset.queryFout);
PQclear(res);
return true;
@@ -408,7 +409,7 @@ objectDescription(const char *object)
strcat(descbuf, "\nUNION ALL\n\n");
strcat(descbuf, "SELECT DISTINCT o.oprname as \"Name\", 'operator'::text as \"Object\", d.description as \"Description\"\n"
"FROM pg_operator o, pg_description d\n"
- /* must get comment via associated function */
+ /* must get comment via associated function */
"WHERE RegprocToOid(o.oprcode) = d.objoid\n");
if (object)
{
@@ -521,25 +522,34 @@ describeTableDetails(const char *name, bool desc)
char **footers = NULL;
char **ptr;
unsigned int cols;
- struct { bool hasindex; char relkind; int16 checks; int16 triggers; bool hasrules; } tableinfo;
- bool error = false;
+ struct
+ {
+ bool hasindex;
+ char relkind;
+ int16 checks;
+ int16 triggers;
+ bool hasrules;
+ } tableinfo;
+ bool error = false;
+
+ /* truncate table name */
+ if (strlen(name) > NAMEDATALEN)
+ {
+ char *my_name = xmalloc(NAMEDATALEN + 1);
- /* truncate table name */
- if (strlen(name) > NAMEDATALEN) {
- char *my_name = xmalloc(NAMEDATALEN+1);
- strncpy(my_name, name, NAMEDATALEN);
- my_name[NAMEDATALEN] = '\0';
- name = my_name;
- }
+ strncpy(my_name, name, NAMEDATALEN);
+ my_name[NAMEDATALEN] = '\0';
+ name = my_name;
+ }
/* Get general table info */
- sprintf(buf,
- "SELECT relhasindex, relkind, relchecks, reltriggers, relhasrules\n"
- "FROM pg_class WHERE relname='%s'",
- name);
- res = PSQLexec(buf);
- if (!res)
- return false;
+ sprintf(buf,
+ "SELECT relhasindex, relkind, relchecks, reltriggers, relhasrules\n"
+ "FROM pg_class WHERE relname='%s'",
+ name);
+ res = PSQLexec(buf);
+ if (!res)
+ return false;
/* Did we get anything? */
if (PQntuples(res) == 0)
@@ -550,35 +560,35 @@ describeTableDetails(const char *name, bool desc)
return false;
}
- /* FIXME: check for null pointers here? */
- tableinfo.hasindex = strcmp(PQgetvalue(res,0,0),"t")==0;
- tableinfo.relkind = *(PQgetvalue(res,0,1));
- tableinfo.checks = atoi(PQgetvalue(res,0,2));
- tableinfo.triggers = atoi(PQgetvalue(res,0,3));
- tableinfo.hasrules = strcmp(PQgetvalue(res,0,4),"t")==0;
- PQclear(res);
+ /* FIXME: check for null pointers here? */
+ tableinfo.hasindex = strcmp(PQgetvalue(res, 0, 0), "t") == 0;
+ tableinfo.relkind = *(PQgetvalue(res, 0, 1));
+ tableinfo.checks = atoi(PQgetvalue(res, 0, 2));
+ tableinfo.triggers = atoi(PQgetvalue(res, 0, 3));
+ tableinfo.hasrules = strcmp(PQgetvalue(res, 0, 4), "t") == 0;
+ PQclear(res);
headers[0] = "Attribute";
headers[1] = "Type";
cols = 2;
- if (tableinfo.relkind == 'r')
- {
- cols++;
- headers[cols-1] = "Modifier";
- }
+ if (tableinfo.relkind == 'r')
+ {
+ cols++;
+ headers[cols - 1] = "Modifier";
+ }
if (desc)
{
- cols++;
- headers[cols-1] = "Description";
+ cols++;
+ headers[cols - 1] = "Description";
}
- headers[cols] = NULL;
+ headers[cols] = NULL;
- /* Get column info */
+ /* Get column info */
strcpy(buf, "SELECT a.attname, t.typname, a.attlen, a.atttypmod, a.attnotnull, a.atthasdef, a.attnum");
if (desc)
strcat(buf, ", obj_description(a.oid)");
@@ -593,55 +603,58 @@ describeTableDetails(const char *name, bool desc)
return false;
/* Check if table is a view */
- if (tableinfo.hasrules) {
- PGresult *result;
- sprintf(buf, "SELECT definition FROM pg_views WHERE viewname = '%s'", name);
- result = PSQLexec(buf);
- if (!result)
- {
- PQclear(res);
- PQclear(result);
- return false;
- }
-
- if (PQntuples(result) > 0)
- view_def = xstrdup(PQgetvalue(result, 0, 0));
- PQclear(result);
- }
+ if (tableinfo.hasrules)
+ {
+ PGresult *result;
+
+ sprintf(buf, "SELECT definition FROM pg_views WHERE viewname = '%s'", name);
+ result = PSQLexec(buf);
+ if (!result)
+ {
+ PQclear(res);
+ PQclear(result);
+ return false;
+ }
+
+ if (PQntuples(result) > 0)
+ view_def = xstrdup(PQgetvalue(result, 0, 0));
+ PQclear(result);
+ }
/* Generate table cells to be printed */
cells = xmalloc((PQntuples(res) * cols + 1) * sizeof(*cells));
- cells[PQntuples(res) * cols] = NULL; /* end of list */
+ cells[PQntuples(res) * cols] = NULL; /* end of list */
for (i = 0; i < PQntuples(res); i++)
{
int4 attypmod = atoi(PQgetvalue(res, i, 3));
const char *attype = PQgetvalue(res, i, 1);
- const char *typename;
- bool isarray = false;
+ const char *typename;
+ bool isarray = false;
/* Name */
- cells[i * cols + 0] = PQgetvalue(res, i, 0); /* don't free this afterwards */
+ cells[i * cols + 0] = PQgetvalue(res, i, 0); /* don't free this
+ * afterwards */
/* Type */
- if (attype[0] == '_')
- {
- isarray = true;
- attype++;
- }
- /* (convert some internal type names to SQL'ish) */
- if (strcmp(attype, "int2")==0)
- typename = "smallint";
- else if (strcmp(attype, "int4")==0)
- typename = "integer";
- else if (strcmp(attype, "int8")==0)
- typename = "bigint";
- else if (strcmp(attype, "bool")==0)
- typename = "boolean";
- else
- typename = attype;
- /* more might need to be added when date/time types are sorted out */
+ if (attype[0] == '_')
+ {
+ isarray = true;
+ attype++;
+ }
+ /* (convert some internal type names to SQL'ish) */
+ if (strcmp(attype, "int2") == 0)
+ typename = "smallint";
+ else if (strcmp(attype, "int4") == 0)
+ typename = "integer";
+ else if (strcmp(attype, "int8") == 0)
+ typename = "bigint";
+ else if (strcmp(attype, "bool") == 0)
+ typename = "boolean";
+ else
+ typename = attype;
+ /* more might need to be added when date/time types are sorted out */
cells[i * cols + 1] = xmalloc(NAMEDATALEN + 16);
if (strcmp(typename, "bpchar") == 0)
@@ -667,100 +680,101 @@ describeTableDetails(const char *name, bool desc)
else
strcpy(cells[i * cols + 1], typename);
- if (isarray)
+ if (isarray)
strcat(cells[i * cols + 1], "[]");
/* Extra: not null and default */
/* (I'm cutting off the 'default' string at 128) */
- if (tableinfo.relkind == 'r')
- {
- cells[i * cols + 2] = xmalloc(128 + 128);
- cells[i * cols + 2][0] = '\0';
- if (strcmp(PQgetvalue(res, i, 4), "t") == 0)
- strcat(cells[i * cols + 2], "not null");
-
- /* handle "default" here */
- if (strcmp(PQgetvalue(res, i, 5), "t") == 0)
- {
- PGresult *result;
-
- sprintf(buf, "SELECT substring(d.adsrc for 128) FROM pg_attrdef d, pg_class c\n"
- "WHERE c.relname = '%s' AND c.oid = d.adrelid AND d.adnum = %s",
- name, PQgetvalue(res, i, 6));
-
- result = PSQLexec(buf);
- if (!result)
- error = true;
- else
- {
- if (cells[i * cols + 2][0])
- strcat(cells[i * cols + 2], " ");
- strcat(cells[i * cols + 2], "default ");
- strcat(cells[i * cols + 2], PQgetvalue(result, 0, 0));
- PQclear(result);
- }
- }
- }
-
- if (error)
- break;
-
+ if (tableinfo.relkind == 'r')
+ {
+ cells[i * cols + 2] = xmalloc(128 + 128);
+ cells[i * cols + 2][0] = '\0';
+ if (strcmp(PQgetvalue(res, i, 4), "t") == 0)
+ strcat(cells[i * cols + 2], "not null");
+
+ /* handle "default" here */
+ if (strcmp(PQgetvalue(res, i, 5), "t") == 0)
+ {
+ PGresult *result;
+
+ sprintf(buf, "SELECT substring(d.adsrc for 128) FROM pg_attrdef d, pg_class c\n"
+ "WHERE c.relname = '%s' AND c.oid = d.adrelid AND d.adnum = %s",
+ name, PQgetvalue(res, i, 6));
+
+ result = PSQLexec(buf);
+ if (!result)
+ error = true;
+ else
+ {
+ if (cells[i * cols + 2][0])
+ strcat(cells[i * cols + 2], " ");
+ strcat(cells[i * cols + 2], "default ");
+ strcat(cells[i * cols + 2], PQgetvalue(result, 0, 0));
+ PQclear(result);
+ }
+ }
+ }
+
+ if (error)
+ break;
+
/* Description */
if (desc)
- cells[i * cols + cols-1] = PQgetvalue(res, i, 7);
+ cells[i * cols + cols - 1] = PQgetvalue(res, i, 7);
}
/* Make title */
title = xmalloc(22 + strlen(name));
- switch (tableinfo.relkind) {
- case 'r':
- if (view_def)
- sprintf(title, "View \"%s\"", name);
- else
- sprintf(title, "Table \"%s\"", name);
- break;
- case 'S':
- sprintf(title, "Sequence \"%s\"", name);
- break;
- case 'i':
- sprintf(title, "Index \"%s\"", name);
- break;
- case 's':
- sprintf(title, "Special relation \"%s\"", name);
- break;
- default:
- sprintf(title, "?%c?", tableinfo.relkind);
- }
+ switch (tableinfo.relkind)
+ {
+ case 'r':
+ if (view_def)
+ sprintf(title, "View \"%s\"", name);
+ else
+ sprintf(title, "Table \"%s\"", name);
+ break;
+ case 'S':
+ sprintf(title, "Sequence \"%s\"", name);
+ break;
+ case 'i':
+ sprintf(title, "Index \"%s\"", name);
+ break;
+ case 's':
+ sprintf(title, "Special relation \"%s\"", name);
+ break;
+ default:
+ sprintf(title, "?%c?", tableinfo.relkind);
+ }
/* Make footers */
- /* Information about the index */
- if (tableinfo.relkind == 'i')
- {
- PGresult * result;
-
- sprintf(buf, "SELECT i.indisunique, i.indisprimary, a.amname\n"
- "FROM pg_index i, pg_class c, pg_am a\n"
- "WHERE i.indexrelid = c.oid AND c.relname = '%s' AND c.relam = a.oid",
- name);
-
- result = PSQLexec(buf);
- if (!result)
- error = true;
- else
- {
- footers = xmalloc(2 * sizeof(*footers));
- footers[0] = xmalloc(NAMEDATALEN + 32);
- sprintf(footers[0], "%s%s",
- strcmp(PQgetvalue(result, 0, 0), "t")==0 ? "unique " : "",
- PQgetvalue(result, 0, 2)
- );
- if (strcmp(PQgetvalue(result, 0, 1), "t")==0)
- strcat(footers[0], " (primary key)");
- footers[1] = NULL;
- }
- }
- /* Information about the view */
+ /* Information about the index */
+ if (tableinfo.relkind == 'i')
+ {
+ PGresult *result;
+
+ sprintf(buf, "SELECT i.indisunique, i.indisprimary, a.amname\n"
+ "FROM pg_index i, pg_class c, pg_am a\n"
+ "WHERE i.indexrelid = c.oid AND c.relname = '%s' AND c.relam = a.oid",
+ name);
+
+ result = PSQLexec(buf);
+ if (!result)
+ error = true;
+ else
+ {
+ footers = xmalloc(2 * sizeof(*footers));
+ footers[0] = xmalloc(NAMEDATALEN + 32);
+ sprintf(footers[0], "%s%s",
+ strcmp(PQgetvalue(result, 0, 0), "t") == 0 ? "unique " : "",
+ PQgetvalue(result, 0, 2)
+ );
+ if (strcmp(PQgetvalue(result, 0, 1), "t") == 0)
+ strcat(footers[0], " (primary key)");
+ footers[1] = NULL;
+ }
+ }
+ /* Information about the view */
else if (tableinfo.relkind == 'r' && view_def)
{
footers = xmalloc(2 * sizeof(*footers));
@@ -769,137 +783,143 @@ describeTableDetails(const char *name, bool desc)
footers[1] = NULL;
}
- /* Information about the table */
+ /* Information about the table */
else if (tableinfo.relkind == 'r')
{
- PGresult *result1=NULL, *result2=NULL, *result3=NULL, *result4=NULL;
- int index_count=0, constr_count=0, rule_count=0, trigger_count=0;
- int count_footers=0;
+ PGresult *result1 = NULL,
+ *result2 = NULL,
+ *result3 = NULL,
+ *result4 = NULL;
+ int index_count = 0,
+ constr_count = 0,
+ rule_count = 0,
+ trigger_count = 0;
+ int count_footers = 0;
/* count indices */
- if (!error && tableinfo.hasindex)
- {
- sprintf(buf, "SELECT c2.relname\n"
- "FROM pg_class c, pg_class c2, pg_index i\n"
- "WHERE c.relname = '%s' AND c.oid = i.indrelid AND i.indexrelid = c2.oid\n"
- "ORDER BY c2.relname",
- name);
- result1 = PSQLexec(buf);
- if (!result1)
- error = true;
- else
- index_count = PQntuples(result1);
- }
-
- /* count table (and column) constraints */
- if (!error && tableinfo.checks)
- {
- sprintf(buf, "SELECT rcsrc\n"
- "FROM pg_relcheck r, pg_class c\n"
- "WHERE c.relname='%s' AND c.oid = r.rcrelid",
- name);
- result2 = PSQLexec(buf);
- if (!result2)
- error = true;
- else
- constr_count = PQntuples(result2);
- }
-
- /* count rules */
- if (!error && tableinfo.hasrules)
- {
- sprintf(buf,
- "SELECT r.rulename\n"
- "FROM pg_rewrite r, pg_class c\n"
- "WHERE c.relname='%s' AND c.oid = r.ev_class",
- name);
- result3 = PSQLexec(buf);
- if (!result3)
- error = true;
- else
- rule_count = PQntuples(result3);
- }
-
- /* count triggers */
- if (!error && tableinfo.hasrules)
- {
- sprintf(buf,
- "SELECT t.tgname\n"
- "FROM pg_trigger t, pg_class c\n"
- "WHERE c.relname='%s' AND c.oid = t.tgrelid",
- name);
- result4 = PSQLexec(buf);
- if (!result4)
- error = true;
- else
- trigger_count = PQntuples(result4);
- }
-
- footers = xmalloc((index_count + constr_count + rule_count + trigger_count + 1)
- * sizeof(*footers));
-
- /* print indices */
- for (i = 0; i < index_count; i++)
- {
- sprintf(buf, "%s %s",
- index_count==1 ? "Index:" : (i==0 ? "Indices:" : " "),
- PQgetvalue(result1, i, 0)
- );
- if (i < index_count-1)
- strcat(buf, ",");
-
- footers[count_footers++] = xstrdup(buf);
- }
-
- /* print contraints */
- for (i = 0; i < constr_count; i++)
- {
- sprintf(buf, "%s %s",
- constr_count==1 ? "Constraint:" : (i==0 ? "Constraints:" : " "),
- PQgetvalue(result2, i, 0)
- );
- footers[count_footers++] = xstrdup(buf);
- }
-
- /* print rules */
- for (i = 0; i < rule_count; i++)
- {
- sprintf(buf, "%s %s",
- rule_count==1 ? "Rule:" : (i==0 ? "Rules:" : " "),
- PQgetvalue(result3, i, 0)
- );
- if (i < rule_count-1)
- strcat(buf, ",");
-
- footers[count_footers++] = xstrdup(buf);
- }
-
- /* print triggers */
- for (i = 0; i < trigger_count; i++)
- {
- sprintf(buf, "%s %s",
- trigger_count==1 ? "Trigger:" : (i==0 ? "Triggers:" : " "),
- PQgetvalue(result4, i, 0)
- );
- if (i < trigger_count-1)
- strcat(buf, ",");
-
- footers[count_footers++] = xstrdup(buf);
- }
-
- /* end of list marker */
- footers[count_footers] = NULL;
-
- PQclear(result1);
- PQclear(result2);
- PQclear(result3);
- PQclear(result4);
+ if (!error && tableinfo.hasindex)
+ {
+ sprintf(buf, "SELECT c2.relname\n"
+ "FROM pg_class c, pg_class c2, pg_index i\n"
+ "WHERE c.relname = '%s' AND c.oid = i.indrelid AND i.indexrelid = c2.oid\n"
+ "ORDER BY c2.relname",
+ name);
+ result1 = PSQLexec(buf);
+ if (!result1)
+ error = true;
+ else
+ index_count = PQntuples(result1);
+ }
+
+ /* count table (and column) constraints */
+ if (!error && tableinfo.checks)
+ {
+ sprintf(buf, "SELECT rcsrc\n"
+ "FROM pg_relcheck r, pg_class c\n"
+ "WHERE c.relname='%s' AND c.oid = r.rcrelid",
+ name);
+ result2 = PSQLexec(buf);
+ if (!result2)
+ error = true;
+ else
+ constr_count = PQntuples(result2);
+ }
+
+ /* count rules */
+ if (!error && tableinfo.hasrules)
+ {
+ sprintf(buf,
+ "SELECT r.rulename\n"
+ "FROM pg_rewrite r, pg_class c\n"
+ "WHERE c.relname='%s' AND c.oid = r.ev_class",
+ name);
+ result3 = PSQLexec(buf);
+ if (!result3)
+ error = true;
+ else
+ rule_count = PQntuples(result3);
+ }
+
+ /* count triggers */
+ if (!error && tableinfo.hasrules)
+ {
+ sprintf(buf,
+ "SELECT t.tgname\n"
+ "FROM pg_trigger t, pg_class c\n"
+ "WHERE c.relname='%s' AND c.oid = t.tgrelid",
+ name);
+ result4 = PSQLexec(buf);
+ if (!result4)
+ error = true;
+ else
+ trigger_count = PQntuples(result4);
+ }
+
+ footers = xmalloc((index_count + constr_count + rule_count + trigger_count + 1)
+ * sizeof(*footers));
+
+ /* print indices */
+ for (i = 0; i < index_count; i++)
+ {
+ sprintf(buf, "%s %s",
+ index_count == 1 ? "Index:" : (i == 0 ? "Indices:" : " "),
+ PQgetvalue(result1, i, 0)
+ );
+ if (i < index_count - 1)
+ strcat(buf, ",");
+
+ footers[count_footers++] = xstrdup(buf);
+ }
+
+ /* print contraints */
+ for (i = 0; i < constr_count; i++)
+ {
+ sprintf(buf, "%s %s",
+ constr_count == 1 ? "Constraint:" : (i == 0 ? "Constraints:" : " "),
+ PQgetvalue(result2, i, 0)
+ );
+ footers[count_footers++] = xstrdup(buf);
+ }
+
+ /* print rules */
+ for (i = 0; i < rule_count; i++)
+ {
+ sprintf(buf, "%s %s",
+ rule_count == 1 ? "Rule:" : (i == 0 ? "Rules:" : " "),
+ PQgetvalue(result3, i, 0)
+ );
+ if (i < rule_count - 1)
+ strcat(buf, ",");
+
+ footers[count_footers++] = xstrdup(buf);
+ }
+
+ /* print triggers */
+ for (i = 0; i < trigger_count; i++)
+ {
+ sprintf(buf, "%s %s",
+ trigger_count == 1 ? "Trigger:" : (i == 0 ? "Triggers:" : " "),
+ PQgetvalue(result4, i, 0)
+ );
+ if (i < trigger_count - 1)
+ strcat(buf, ",");
+
+ footers[count_footers++] = xstrdup(buf);
+ }
+
+ /* end of list marker */
+ footers[count_footers] = NULL;
+
+ PQclear(result1);
+ PQclear(result2);
+ PQclear(result3);
+ PQclear(result4);
}
- if (!error)
- printTable(title, headers,
- (const char**)cells, (const char**)footers,
- "llll", &myopt, pset.queryFout);
+ if (!error)
+ printTable(title, headers,
+ (const char **) cells, (const char **) footers,
+ "llll", &myopt, pset.queryFout);
/* clean up */
free(title);
@@ -907,8 +927,8 @@ describeTableDetails(const char *name, bool desc)
for (i = 0; i < PQntuples(res); i++)
{
free(cells[i * cols + 1]);
- if (tableinfo.relkind == 'r')
- free(cells[i * cols + 2]);
+ if (tableinfo.relkind == 'r')
+ free(cells[i * cols + 2]);
}
free(cells);
@@ -972,14 +992,14 @@ listTables(const char *infotype, const char *name, bool desc)
strcat(buf, "'\n");
}
- strcat(buf, "UNION\n");
+ strcat(buf, "UNION\n");
strcat(buf, "SELECT c.relname as \"Name\", 'table'::text as \"Type\", NULL as \"Owner\"");
if (desc)
strcat(buf, ", obj_description(c.oid) as \"Description\"");
strcat(buf, "\nFROM pg_class c\n"
"WHERE c.relkind = 'r'\n"
" AND not exists (select 1 from pg_views where viewname = c.relname)\n"
- " AND not exists (select 1 from pg_user where usesysid = c.relowner)\n");
+ " AND not exists (select 1 from pg_user where usesysid = c.relowner)\n");
strcat(buf, showSystem ? " AND c.relname ~ '^pg_'\n" : " AND c.relname !~ '^pg_'\n");
if (name)
{
@@ -1009,14 +1029,14 @@ listTables(const char *infotype, const char *name, bool desc)
strcat(buf, "'\n");
}
- strcat(buf, "UNION\n");
+ strcat(buf, "UNION\n");
strcat(buf, "SELECT c.relname as \"Name\", 'view'::text as \"Type\", NULL as \"Owner\"");
if (desc)
strcat(buf, ", obj_description(c.oid) as \"Description\"");
strcat(buf, "\nFROM pg_class c\n"
"WHERE c.relkind = 'r'\n"
" AND exists (select 1 from pg_views where viewname = c.relname)\n"
- " AND not exists (select 1 from pg_user where usesysid = c.relowner)\n");
+ " AND not exists (select 1 from pg_user where usesysid = c.relowner)\n");
strcat(buf, showSystem ? " AND c.relname ~ '^pg_'\n" : " AND c.relname !~ '^pg_'\n");
if (name)
{
@@ -1033,10 +1053,10 @@ listTables(const char *infotype, const char *name, bool desc)
strcat(buf, "\nUNION\n\n");
strcat(buf,
- "SELECT c.relname as \"Name\",\n"
+ "SELECT c.relname as \"Name\",\n"
" (CASE WHEN relkind = 'S' THEN 'sequence'::text ELSE 'index'::text END) as \"Type\",\n"
- " u.usename as \"Owner\""
- );
+ " u.usename as \"Owner\""
+ );
if (desc)
strcat(buf, ", obj_description(c.oid) as \"Description\"");
strcat(buf, "\nFROM pg_class c, pg_user u\n"
@@ -1061,12 +1081,12 @@ listTables(const char *infotype, const char *name, bool desc)
strcat(buf, "'\n");
}
- strcat(buf, "UNION\n");
+ strcat(buf, "UNION\n");
strcat(buf,
- "SELECT c.relname as \"Name\",\n"
+ "SELECT c.relname as \"Name\",\n"
" (CASE WHEN relkind = 'S' THEN 'sequence'::text ELSE 'index'::text END) as \"Type\",\n"
- " NULL as \"Owner\""
- );
+ " NULL as \"Owner\""
+ );
if (desc)
strcat(buf, ", obj_description(c.oid) as \"Description\"");
strcat(buf, "\nFROM pg_class c\n"
@@ -1110,13 +1130,13 @@ listTables(const char *infotype, const char *name, bool desc)
strcat(buf, "'\n");
}
- strcat(buf, "UNION\n");
+ strcat(buf, "UNION\n");
strcat(buf, "SELECT c.relname as \"Name\", 'special'::text as \"Type\", NULL as \"Owner\"");
if (desc)
strcat(buf, ", obj_description(c.oid) as \"Description\"");
strcat(buf, "\nFROM pg_class c\n"
"WHERE c.relkind = 's'\n"
- " AND not exists (select 1 from pg_user where usesysid = c.relowner)");
+ " AND not exists (select 1 from pg_user where usesysid = c.relowner)");
if (name)
{
strcat(buf, " AND c.relname ~ '^");
@@ -1133,12 +1153,12 @@ listTables(const char *infotype, const char *name, bool desc)
return false;
if (PQntuples(res) == 0 && !QUIET())
- {
- if (name)
- fprintf(pset.queryFout, "No matching relations found.\n");
- else
- fprintf(pset.queryFout, "No relations found.\n");
- }
+ {
+ if (name)
+ fprintf(pset.queryFout, "No matching relations found.\n");
+ else
+ fprintf(pset.queryFout, "No relations found.\n");
+ }
else
{
myopt.nullPrint = NULL;