]> granicus.if.org Git - postgresql/commitdiff
Showing index details with \d on psql.
authorBruce Momjian <bruce@momjian.us>
Tue, 5 Mar 2002 02:42:56 +0000 (02:42 +0000)
committerBruce Momjian <bruce@momjian.us>
Tue, 5 Mar 2002 02:42:56 +0000 (02:42 +0000)
Greg Sabino Mullane

src/bin/psql/describe.c

index e285535c817e5d9117312ea424daa9736a03b717..ef31c5ee906b5489fa2a5bedaa92712b10afd16c 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright 2000 by PostgreSQL Global Development Group
  *
- * $Header: /cvsroot/pgsql/src/bin/psql/describe.c,v 1.42 2001/11/12 15:57:08 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/bin/psql/describe.c,v 1.43 2002/03/05 02:42:56 momjian Exp $
  */
 #include "postgres_fe.h"
 #include "describe.h"
@@ -532,15 +532,23 @@ describeTableDetails(const char *name, bool desc)
        headers[cols] = NULL;
 
 
-       /* Get column info */
-       strcpy(buf, "SELECT a.attname, format_type(a.atttypid, a.atttypmod), a.attnotnull, a.atthasdef, a.attnum");
+       /* Get column info (index requires additional checks) */
+       if (tableinfo.relkind == 'i')
+               strcpy(buf, "SELECT\n  CASE i.indproc WHEN ('-'::regproc) THEN a.attname\n  ELSE SUBSTR(pg_get_indexdef(attrelid),\n  POSITION('(' in pg_get_indexdef(attrelid)))\n  END, ");
+       else
+               strcpy(buf, "SELECT a.attname, ");
+       strcat(buf, "format_type(a.atttypid, a.atttypmod), a.attnotnull, a.atthasdef, a.attnum");
        if (desc)
                strcat(buf, ", col_description(a.attrelid, a.attnum)");
-       strcat(buf, "\nFROM pg_class c, pg_attribute a\n"
-                  "WHERE c.relname = '");
+       strcat(buf, "\nFROM pg_class c, pg_attribute a");
+       if (tableinfo.relkind == 'i')
+               strcat(buf, ", pg_index i");
+       strcat(buf, "\nWHERE c.relname = '");
        strncat(buf, name, NAMEDATALEN);
-       strcat(buf, "'\n  AND a.attnum > 0 AND a.attrelid = c.oid\n"
-                  "ORDER BY a.attnum");
+       strcat(buf, "'\n  AND a.attnum > 0 AND a.attrelid = c.oid");
+       if (tableinfo.relkind == 'i')
+               strcat(buf, " AND a.attrelid = i.indexrelid");
+       strcat(buf, "\nORDER BY a.attnum");
 
        res = PSQLexec(buf);
        if (!res)
@@ -651,11 +659,11 @@ describeTableDetails(const char *name, bool desc)
        {
                /* Footer information about an index */
                PGresult   *result;
-
-               sprintf(buf, "SELECT i.indisunique, i.indisprimary, a.amname,\n"
-                               "       pg_get_expr(i.indpred, i.indrelid) as indpred\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",
+               sprintf(buf, "SELECT i.indisunique, i.indisprimary, a.amname, c2.relname,\n"
+                               "pg_get_expr(i.indpred,i.indrelid)\n"
+                               "FROM pg_index i, pg_class c, pg_class c2, pg_am a\n"
+                               "WHERE i.indexrelid = c.oid AND c.relname = '%s' AND c.relam = a.oid\n"
+                               "AND i.indrelid = c2.oid",
                                name);
 
                result = PSQLexec(buf);
@@ -666,27 +674,18 @@ describeTableDetails(const char *name, bool desc)
                        char       *indisunique = PQgetvalue(result, 0, 0);
                        char       *indisprimary = PQgetvalue(result, 0, 1);
                        char       *indamname = PQgetvalue(result, 0, 2);
-                       char       *indpred = PQgetvalue(result, 0, 3);
+                       char       *indtable = PQgetvalue(result, 0, 3);
+                       char       *indpred = PQgetvalue(result, 0, 4);
 
-                       footers = xmalloc(3 * sizeof(*footers));
+                       footers = xmalloc(2 * sizeof(*footers));
                        /* XXX This construction is poorly internationalized. */
-                       footers[0] = xmalloc(NAMEDATALEN + 128);
-                       snprintf(footers[0], NAMEDATALEN + 128, "%s%s",
+                       footers[0] = xmalloc(NAMEDATALEN*4 + 128);
+                       snprintf(footers[0], NAMEDATALEN*4 + 128, "%s%s for %s \"%s\"%s%s",
+                                        strcmp(indisprimary, "t") == 0 ? _("primary key ") : 
                                         strcmp(indisunique, "t") == 0 ? _("unique ") : "",
-                                        indamname);
-                       if (strcmp(indisprimary, "t") == 0)
-                               snprintf(footers[0] + strlen(footers[0]),
-                                                NAMEDATALEN + 128 - strlen(footers[0]),
-                                                _(" (primary key)"));
-                       if (strlen(indpred) > 0)
-                       {
-                               footers[1] = xmalloc(64 + strlen(indpred));
-                               snprintf(footers[1], 64 + strlen(indpred),
-                                                _("Index predicate: %s"), indpred);
-                               footers[2] = NULL;
-                       }
-                       else
-                               footers[1] = NULL;
+                                        indamname, _("table"), indtable, 
+                                        strlen(indpred) ? " WHERE " : "",indpred);
+                       footers[1] = NULL;
                }
 
                PQclear(result);
@@ -706,12 +705,8 @@ describeTableDetails(const char *name, bool desc)
                PGresult   *result1 = NULL,
                                   *result2 = NULL,
                                   *result3 = NULL,
-                                  *result4 = NULL,
-                                  *result5 = NULL,
-                                  *result6 = NULL;
+                                  *result4 = NULL;
                int                     index_count = 0,
-                                       primary_count = 0,
-                                       unique_count = 0,
                                        constr_count = 0,
                                        rule_count = 0,
                                        trigger_count = 0;
@@ -720,10 +715,12 @@ describeTableDetails(const char *name, bool desc)
                /* count indexes */
                if (!error && tableinfo.hasindex)
                {
-                       sprintf(buf, "SELECT c2.relname\n"
+                       sprintf(buf, "SELECT c2.relname, i.indisprimary, i.indisunique,\n"
+                                       "SUBSTR(pg_get_indexdef(i.indexrelid),\n"
+                                       "POSITION('USING ' IN pg_get_indexdef(i.indexrelid))+5)\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"
-                                       "AND NOT i.indisunique ORDER BY c2.relname",
+                                       "ORDER BY i.indisprimary DESC, i.indisunique DESC, c2.relname",
                                        name);
                        result1 = PSQLexec(buf);
                        if (!result1)
@@ -732,36 +729,6 @@ describeTableDetails(const char *name, bool desc)
                                index_count = PQntuples(result1);
                }
 
-               /* count primary keys */
-               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"
-                         "AND i.indisprimary AND i.indisunique ORDER BY c2.relname",
-                                       name);
-                       result5 = PSQLexec(buf);
-                       if (!result5)
-                               error = true;
-                       else
-                               primary_count = PQntuples(result5);
-               }
-
-               /* count unique constraints */
-               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"
-                                       "AND NOT i.indisprimary AND i.indisunique ORDER BY c2.relname",
-                                       name);
-                       result6 = PSQLexec(buf);
-                       if (!result6)
-                               error = true;
-                       else
-                               unique_count = PQntuples(result6);
-               }
-
                /* count table (and column) constraints */
                if (!error && tableinfo.checks)
                {
@@ -806,54 +773,32 @@ describeTableDetails(const char *name, bool desc)
                                trigger_count = PQntuples(result4);
                }
 
-               footers = xmalloc((index_count + primary_count + unique_count +
-                                                  constr_count + rule_count + trigger_count + 1)
+               footers = xmalloc((index_count + constr_count + rule_count + trigger_count + 1)
                                                  * sizeof(*footers));
 
                /* print indexes */
                for (i = 0; i < index_count; i++)
                {
                        char       *s = _("Indexes");
-
+       
                        if (i == 0)
                                snprintf(buf, sizeof(buf), "%s: %s", s, PQgetvalue(result1, i, 0));
                        else
                                snprintf(buf, sizeof(buf), "%*s  %s", (int) strlen(s), "", PQgetvalue(result1, i, 0));
-                       if (i < index_count - 1)
-                               strcat(buf, ",");
 
-                       footers[count_footers++] = xstrdup(buf);
-               }
+                       /* Label as primary key or unique (but not both) */
+                       strcat(buf, strcmp(PQgetvalue(result1,i,1),"t") == 0 ? 
+                                  _(" primary key") : strcmp(PQgetvalue(result1,i,2),"t") == 0 ? _(" unique") : "");
 
-               /* print primary keys */
-               for (i = 0; i < primary_count; i++)
-               {
-                       char       *s = _("Primary key");
+                       /* Everything after "USING" is echoed verbatim */
+                       strcat(buf, PQgetvalue(result1,i,3));
 
-                       if (i == 0)
-                               snprintf(buf, sizeof(buf), "%s: %s", s, PQgetvalue(result5, i, 0));
-                       else
-                               snprintf(buf, sizeof(buf), "%*s  %s", (int) strlen(s), "", PQgetvalue(result5, i, 0));
-                       if (i < primary_count - 1)
+                       if (i < index_count - 1)
                                strcat(buf, ",");
 
                        footers[count_footers++] = xstrdup(buf);
                }
 
-               /* print unique constraints */
-               for (i = 0; i < unique_count; i++)
-               {
-                       char       *s = _("Unique keys");
-
-                       if (i == 0)
-                               snprintf(buf, sizeof(buf), "%s: %s", s, PQgetvalue(result6, i, 0));
-                       else
-                               snprintf(buf, sizeof(buf), "%*s  %s", (int) strlen(s), "", PQgetvalue(result6, i, 0));
-                       if (i < unique_count - 1)
-                               strcat(buf, ",");
-
-                       footers[count_footers++] = xstrdup(buf);
-               }
 
                /* print constraints */
                for (i = 0; i < constr_count; i++)
@@ -906,8 +851,6 @@ describeTableDetails(const char *name, bool desc)
                PQclear(result2);
                PQclear(result3);
                PQclear(result4);
-               PQclear(result5);
-               PQclear(result6);
        }
 
        if (!error)
@@ -1031,9 +974,19 @@ listTables(const char *infotype, const char *name, bool desc)
                snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
                                 ",\n  obj_description(c.oid, 'pg_class') as \"%s\"",
                                 _("Description"));
-       strcat(buf,
-        "\nFROM pg_class c LEFT JOIN pg_user u ON c.relowner = u.usesysid\n"
-                  "WHERE c.relkind IN (");
+    if (showIndexes) {
+               snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
+                                ",\n c2.relname as \"%s\"",
+                                _("Table"));
+               strcat(buf, "\nFROM pg_class c, pg_class c2, pg_index i, pg_user u\n"
+                          "WHERE c.relowner = u.usesysid\n"
+                          "AND i.indrelid = c2.oid AND i.indexrelid = c.oid\n");
+       }
+       else {
+               strcat(buf, "\nFROM pg_class c, pg_user u\n"
+                          "WHERE c.relowner = u.usesysid\n");
+       }
+       strcat(buf, "AND c.relkind IN (");
        if (showTables)
                strcat(buf, "'r',");
        if (showViews)