mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-12-27 08:39:28 +08:00
Modify psql's \d printout to fold exclusion constraints in with regular
indexes, rather than printing them twice. Per my gripe when the exclusion constraint feature was committed.
This commit is contained in:
parent
f4898c945f
commit
924d6ed437
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright (c) 2000-2010, PostgreSQL Global Development Group
|
* Copyright (c) 2000-2010, PostgreSQL Global Development Group
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/bin/psql/describe.c,v 1.240 2010/03/11 04:36:43 tgl Exp $
|
* $PostgreSQL: pgsql/src/bin/psql/describe.c,v 1.241 2010/03/11 21:29:32 tgl Exp $
|
||||||
*/
|
*/
|
||||||
#include "postgres_fe.h"
|
#include "postgres_fe.h"
|
||||||
|
|
||||||
@ -1105,7 +1105,6 @@ describeOneTableDetails(const char *schemaname,
|
|||||||
bool hasrules;
|
bool hasrules;
|
||||||
bool hastriggers;
|
bool hastriggers;
|
||||||
bool hasoids;
|
bool hasoids;
|
||||||
bool hasexclusion;
|
|
||||||
Oid tablespace;
|
Oid tablespace;
|
||||||
char *reloptions;
|
char *reloptions;
|
||||||
char *reloftype;
|
char *reloftype;
|
||||||
@ -1128,8 +1127,8 @@ describeOneTableDetails(const char *schemaname,
|
|||||||
printfPQExpBuffer(&buf,
|
printfPQExpBuffer(&buf,
|
||||||
"SELECT c.relchecks, c.relkind, c.relhasindex, c.relhasrules, "
|
"SELECT c.relchecks, c.relkind, c.relhasindex, c.relhasrules, "
|
||||||
"c.relhastriggers, c.relhasoids, "
|
"c.relhastriggers, c.relhasoids, "
|
||||||
"%s, c.reltablespace, c.relhasexclusion, "
|
"%s, c.reltablespace, "
|
||||||
"CASE WHEN c.reloftype = 0 THEN '' ELSE c.reloftype::pg_catalog.regtype::text END\n"
|
"CASE WHEN c.reloftype = 0 THEN '' ELSE c.reloftype::pg_catalog.regtype::pg_catalog.text END\n"
|
||||||
"FROM pg_catalog.pg_class c\n "
|
"FROM pg_catalog.pg_class c\n "
|
||||||
"LEFT JOIN pg_catalog.pg_class tc ON (c.reltoastrelid = tc.oid)\n"
|
"LEFT JOIN pg_catalog.pg_class tc ON (c.reltoastrelid = tc.oid)\n"
|
||||||
"WHERE c.oid = '%s'\n",
|
"WHERE c.oid = '%s'\n",
|
||||||
@ -1207,10 +1206,8 @@ describeOneTableDetails(const char *schemaname,
|
|||||||
strdup(PQgetvalue(res, 0, 6)) : 0;
|
strdup(PQgetvalue(res, 0, 6)) : 0;
|
||||||
tableinfo.tablespace = (pset.sversion >= 80000) ?
|
tableinfo.tablespace = (pset.sversion >= 80000) ?
|
||||||
atooid(PQgetvalue(res, 0, 7)) : 0;
|
atooid(PQgetvalue(res, 0, 7)) : 0;
|
||||||
tableinfo.hasexclusion = (pset.sversion >= 90000) ?
|
tableinfo.reloftype = (pset.sversion >= 90000 && strcmp(PQgetvalue(res, 0, 8), "") != 0) ?
|
||||||
strcmp(PQgetvalue(res, 0, 8), "t") == 0 : false;
|
strdup(PQgetvalue(res, 0, 8)) : 0;
|
||||||
tableinfo.reloftype = (pset.sversion >= 90000 && strcmp(PQgetvalue(res, 0, 9), "") != 0) ?
|
|
||||||
strdup(PQgetvalue(res, 0, 9)) : 0;
|
|
||||||
PQclear(res);
|
PQclear(res);
|
||||||
res = NULL;
|
res = NULL;
|
||||||
|
|
||||||
@ -1545,27 +1542,23 @@ describeOneTableDetails(const char *schemaname,
|
|||||||
appendPQExpBuffer(&buf, "i.indisvalid, ");
|
appendPQExpBuffer(&buf, "i.indisvalid, ");
|
||||||
else
|
else
|
||||||
appendPQExpBuffer(&buf, "true as indisvalid, ");
|
appendPQExpBuffer(&buf, "true as indisvalid, ");
|
||||||
appendPQExpBuffer(&buf, "pg_catalog.pg_get_indexdef(i.indexrelid, 0, true)");
|
appendPQExpBuffer(&buf, "pg_catalog.pg_get_indexdef(i.indexrelid, 0, true),\n ");
|
||||||
if (pset.sversion >= 90000)
|
if (pset.sversion >= 90000)
|
||||||
appendPQExpBuffer(&buf,
|
appendPQExpBuffer(&buf,
|
||||||
",\n (NOT i.indimmediate) AND "
|
"pg_catalog.pg_get_constraintdef(con.oid, true), "
|
||||||
"EXISTS (SELECT 1 FROM pg_catalog.pg_constraint "
|
"contype, condeferrable, condeferred");
|
||||||
"WHERE conrelid = i.indrelid AND "
|
|
||||||
"conindid = i.indexrelid AND "
|
|
||||||
"contype IN ('p','u','x') AND "
|
|
||||||
"condeferrable) AS condeferrable"
|
|
||||||
",\n (NOT i.indimmediate) AND "
|
|
||||||
"EXISTS (SELECT 1 FROM pg_catalog.pg_constraint "
|
|
||||||
"WHERE conrelid = i.indrelid AND "
|
|
||||||
"conindid = i.indexrelid AND "
|
|
||||||
"contype IN ('p','u','x') AND "
|
|
||||||
"condeferred) AS condeferred");
|
|
||||||
else
|
else
|
||||||
appendPQExpBuffer(&buf, ", false AS condeferrable, false AS condeferred");
|
appendPQExpBuffer(&buf,
|
||||||
|
"null AS constraintdef, null AS contype, "
|
||||||
|
"false AS condeferrable, false AS condeferred");
|
||||||
if (pset.sversion >= 80000)
|
if (pset.sversion >= 80000)
|
||||||
appendPQExpBuffer(&buf, ", c2.reltablespace");
|
appendPQExpBuffer(&buf, ", c2.reltablespace");
|
||||||
appendPQExpBuffer(&buf,
|
appendPQExpBuffer(&buf,
|
||||||
"\nFROM pg_catalog.pg_class c, pg_catalog.pg_class c2, pg_catalog.pg_index i\n"
|
"\nFROM pg_catalog.pg_class c, pg_catalog.pg_class c2, pg_catalog.pg_index i\n");
|
||||||
|
if (pset.sversion >= 90000)
|
||||||
|
appendPQExpBuffer(&buf,
|
||||||
|
" LEFT JOIN pg_catalog.pg_constraint con ON (conrelid = i.indrelid AND conindid = i.indexrelid AND contype IN ('p','u','x'))\n");
|
||||||
|
appendPQExpBuffer(&buf,
|
||||||
"WHERE c.oid = '%s' AND c.oid = i.indrelid AND i.indexrelid = c2.oid\n"
|
"WHERE c.oid = '%s' AND c.oid = i.indrelid AND i.indexrelid = c2.oid\n"
|
||||||
"ORDER BY i.indisprimary DESC, i.indisunique DESC, c2.relname",
|
"ORDER BY i.indisprimary DESC, i.indisunique DESC, c2.relname",
|
||||||
oid);
|
oid);
|
||||||
@ -1580,46 +1573,55 @@ describeOneTableDetails(const char *schemaname,
|
|||||||
printTableAddFooter(&cont, _("Indexes:"));
|
printTableAddFooter(&cont, _("Indexes:"));
|
||||||
for (i = 0; i < tuples; i++)
|
for (i = 0; i < tuples; i++)
|
||||||
{
|
{
|
||||||
const char *indexdef;
|
|
||||||
const char *usingpos;
|
|
||||||
|
|
||||||
/* untranslated index name */
|
/* untranslated index name */
|
||||||
printfPQExpBuffer(&buf, " \"%s\"",
|
printfPQExpBuffer(&buf, " \"%s\"",
|
||||||
PQgetvalue(result, i, 0));
|
PQgetvalue(result, i, 0));
|
||||||
|
|
||||||
/* Label as primary key or unique (but not both) */
|
/* If exclusion constraint, print the constraintdef */
|
||||||
appendPQExpBuffer(&buf,
|
if (strcmp(PQgetvalue(result, i, 7), "x") == 0)
|
||||||
strcmp(PQgetvalue(result, i, 1), "t") == 0
|
{
|
||||||
? " PRIMARY KEY," :
|
appendPQExpBuffer(&buf, " %s",
|
||||||
(strcmp(PQgetvalue(result, i, 2), "t") == 0
|
PQgetvalue(result, i, 6));
|
||||||
? " UNIQUE,"
|
}
|
||||||
: ""));
|
else
|
||||||
/* Everything after "USING" is echoed verbatim */
|
{
|
||||||
indexdef = PQgetvalue(result, i, 5);
|
const char *indexdef;
|
||||||
usingpos = strstr(indexdef, " USING ");
|
const char *usingpos;
|
||||||
if (usingpos)
|
|
||||||
indexdef = usingpos + 7;
|
|
||||||
|
|
||||||
appendPQExpBuffer(&buf, " %s", indexdef);
|
/* Label as primary key or unique (but not both) */
|
||||||
|
if (strcmp(PQgetvalue(result, i, 1), "t") == 0)
|
||||||
|
appendPQExpBuffer(&buf, " PRIMARY KEY,");
|
||||||
|
else if (strcmp(PQgetvalue(result, i, 2), "t") == 0)
|
||||||
|
appendPQExpBuffer(&buf, " UNIQUE,");
|
||||||
|
|
||||||
|
/* Everything after "USING" is echoed verbatim */
|
||||||
|
indexdef = PQgetvalue(result, i, 5);
|
||||||
|
usingpos = strstr(indexdef, " USING ");
|
||||||
|
if (usingpos)
|
||||||
|
indexdef = usingpos + 7;
|
||||||
|
appendPQExpBuffer(&buf, " %s", indexdef);
|
||||||
|
|
||||||
|
/* Need these for deferrable PK/UNIQUE indexes */
|
||||||
|
if (strcmp(PQgetvalue(result, i, 8), "t") == 0)
|
||||||
|
appendPQExpBuffer(&buf, " DEFERRABLE");
|
||||||
|
|
||||||
|
if (strcmp(PQgetvalue(result, i, 9), "t") == 0)
|
||||||
|
appendPQExpBuffer(&buf, " INITIALLY DEFERRED");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add these for all cases */
|
||||||
if (strcmp(PQgetvalue(result, i, 3), "t") == 0)
|
if (strcmp(PQgetvalue(result, i, 3), "t") == 0)
|
||||||
appendPQExpBuffer(&buf, " CLUSTER");
|
appendPQExpBuffer(&buf, " CLUSTER");
|
||||||
|
|
||||||
if (strcmp(PQgetvalue(result, i, 4), "t") != 0)
|
if (strcmp(PQgetvalue(result, i, 4), "t") != 0)
|
||||||
appendPQExpBuffer(&buf, " INVALID");
|
appendPQExpBuffer(&buf, " INVALID");
|
||||||
|
|
||||||
if (strcmp(PQgetvalue(result, i, 6), "t") == 0)
|
|
||||||
appendPQExpBuffer(&buf, " DEFERRABLE");
|
|
||||||
|
|
||||||
if (strcmp(PQgetvalue(result, i, 7), "t") == 0)
|
|
||||||
appendPQExpBuffer(&buf, " INITIALLY DEFERRED");
|
|
||||||
|
|
||||||
printTableAddFooter(&cont, buf.data);
|
printTableAddFooter(&cont, buf.data);
|
||||||
|
|
||||||
/* Print tablespace of the index on the same line */
|
/* Print tablespace of the index on the same line */
|
||||||
if (pset.sversion >= 80000)
|
if (pset.sversion >= 80000)
|
||||||
add_tablespace_footer(&cont, 'i',
|
add_tablespace_footer(&cont, 'i',
|
||||||
atooid(PQgetvalue(result, i, 8)),
|
atooid(PQgetvalue(result, i, 10)),
|
||||||
false);
|
false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1657,38 +1659,6 @@ describeOneTableDetails(const char *schemaname,
|
|||||||
PQclear(result);
|
PQclear(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* print exclusion constraints */
|
|
||||||
if (tableinfo.hasexclusion)
|
|
||||||
{
|
|
||||||
printfPQExpBuffer(&buf,
|
|
||||||
"SELECT r.conname, "
|
|
||||||
"pg_catalog.pg_get_constraintdef(r.oid, true)\n"
|
|
||||||
"FROM pg_catalog.pg_constraint r\n"
|
|
||||||
"WHERE r.conrelid = '%s' AND r.contype = 'x'\n"
|
|
||||||
"ORDER BY 1",
|
|
||||||
oid);
|
|
||||||
result = PSQLexec(buf.data, false);
|
|
||||||
if (!result)
|
|
||||||
goto error_return;
|
|
||||||
else
|
|
||||||
tuples = PQntuples(result);
|
|
||||||
|
|
||||||
if (tuples > 0)
|
|
||||||
{
|
|
||||||
printTableAddFooter(&cont, _("Exclusion constraints:"));
|
|
||||||
for (i = 0; i < tuples; i++)
|
|
||||||
{
|
|
||||||
/* untranslated contraint name and def */
|
|
||||||
printfPQExpBuffer(&buf, " \"%s\" %s",
|
|
||||||
PQgetvalue(result, i, 0),
|
|
||||||
PQgetvalue(result, i, 1));
|
|
||||||
|
|
||||||
printTableAddFooter(&cont, buf.data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
PQclear(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* print foreign-key constraints (there are none if no triggers) */
|
/* print foreign-key constraints (there are none if no triggers) */
|
||||||
if (tableinfo.hastriggers)
|
if (tableinfo.hastriggers)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user