88 *
99 * Copyright (c) 2000-2010, PostgreSQL Global Development Group
1010 *
11- * $PostgreSQL: pgsql/src/bin/psql/describe.c,v 1.240 2010/03/1104:36:43 tgl Exp $
11+ * $PostgreSQL: pgsql/src/bin/psql/describe.c,v 1.241 2010/03/1121:29:32 tgl Exp $
1212 */
1313#include "postgres_fe.h"
1414
@@ -1105,7 +1105,6 @@ describeOneTableDetails(const char *schemaname,
11051105bool hasrules ;
11061106bool hastriggers ;
11071107bool hasoids ;
1108- bool hasexclusion ;
11091108Oid tablespace ;
11101109char * reloptions ;
11111110char * reloftype ;
@@ -1128,8 +1127,8 @@ describeOneTableDetails(const char *schemaname,
11281127printfPQExpBuffer (& buf ,
11291128"SELECT c.relchecks, c.relkind, c.relhasindex, c.relhasrules, "
11301129"c.relhastriggers, c.relhasoids, "
1131- "%s, c.reltablespace,c.relhasexclusion, "
1132- "CASE WHEN c.reloftype = 0 THEN '' ELSE c.reloftype::pg_catalog.regtype::text END\n"
1130+ "%s, c.reltablespace, "
1131+ "CASE WHEN c.reloftype = 0 THEN '' ELSE c.reloftype::pg_catalog.regtype::pg_catalog. text END\n"
11331132"FROM pg_catalog.pg_class c\n "
11341133"LEFT JOIN pg_catalog.pg_class tc ON (c.reltoastrelid = tc.oid)\n"
11351134"WHERE c.oid = '%s'\n" ,
@@ -1207,10 +1206,8 @@ describeOneTableDetails(const char *schemaname,
12071206strdup (PQgetvalue (res ,0 ,6 )) :0 ;
12081207tableinfo .tablespace = (pset .sversion >=80000 ) ?
12091208atooid (PQgetvalue (res ,0 ,7 )) :0 ;
1210- tableinfo .hasexclusion = (pset .sversion >=90000 ) ?
1211- strcmp (PQgetvalue (res ,0 ,8 ),"t" )== 0 : false;
1212- tableinfo .reloftype = (pset .sversion >=90000 && strcmp (PQgetvalue (res ,0 ,9 ),"" )!= 0 ) ?
1213- strdup (PQgetvalue (res ,0 ,9 )) :0 ;
1209+ tableinfo .reloftype = (pset .sversion >=90000 && strcmp (PQgetvalue (res ,0 ,8 ),"" )!= 0 ) ?
1210+ strdup (PQgetvalue (res ,0 ,8 )) :0 ;
12141211PQclear (res );
12151212res = NULL ;
12161213
@@ -1545,27 +1542,23 @@ describeOneTableDetails(const char *schemaname,
15451542appendPQExpBuffer (& buf ,"i.indisvalid, " );
15461543else
15471544appendPQExpBuffer (& buf ,"true as indisvalid, " );
1548- appendPQExpBuffer (& buf ,"pg_catalog.pg_get_indexdef(i.indexrelid, 0, true)" );
1545+ appendPQExpBuffer (& buf ,"pg_catalog.pg_get_indexdef(i.indexrelid, 0, true),\n " );
15491546if (pset .sversion >=90000 )
15501547appendPQExpBuffer (& buf ,
1551- ",\n (NOT i.indimmediate) AND "
1552- "EXISTS (SELECT 1 FROM pg_catalog.pg_constraint "
1553- "WHERE conrelid = i.indrelid AND "
1554- "conindid = i.indexrelid AND "
1555- "contype IN ('p','u','x') AND "
1556- "condeferrable) AS condeferrable"
1557- ",\n (NOT i.indimmediate) AND "
1558- "EXISTS (SELECT 1 FROM pg_catalog.pg_constraint "
1559- "WHERE conrelid = i.indrelid AND "
1560- "conindid = i.indexrelid AND "
1561- "contype IN ('p','u','x') AND "
1562- "condeferred) AS condeferred" );
1548+ "pg_catalog.pg_get_constraintdef(con.oid, true), "
1549+ "contype, condeferrable, condeferred" );
15631550else
1564- appendPQExpBuffer (& buf ,", false AS condeferrable, false AS condeferred" );
1551+ appendPQExpBuffer (& buf ,
1552+ "null AS constraintdef, null AS contype, "
1553+ "false AS condeferrable, false AS condeferred" );
15651554if (pset .sversion >=80000 )
15661555appendPQExpBuffer (& buf ,", c2.reltablespace" );
15671556appendPQExpBuffer (& buf ,
1568- "\nFROM pg_catalog.pg_class c, pg_catalog.pg_class c2, pg_catalog.pg_index i\n"
1557+ "\nFROM pg_catalog.pg_class c, pg_catalog.pg_class c2, pg_catalog.pg_index i\n" );
1558+ if (pset .sversion >=90000 )
1559+ appendPQExpBuffer (& buf ,
1560+ " LEFT JOIN pg_catalog.pg_constraint con ON (conrelid = i.indrelid AND conindid = i.indexrelid AND contype IN ('p','u','x'))\n" );
1561+ appendPQExpBuffer (& buf ,
15691562"WHERE c.oid = '%s' AND c.oid = i.indrelid AND i.indexrelid = c2.oid\n"
15701563"ORDER BY i.indisprimary DESC, i.indisunique DESC, c2.relname" ,
15711564oid );
@@ -1580,46 +1573,55 @@ describeOneTableDetails(const char *schemaname,
15801573printTableAddFooter (& cont ,_ ("Indexes:" ));
15811574for (i = 0 ;i < tuples ;i ++ )
15821575{
1583- const char * indexdef ;
1584- const char * usingpos ;
1585-
15861576/* untranslated index name */
15871577printfPQExpBuffer (& buf ," \"%s\"" ,
15881578PQgetvalue (result ,i ,0 ));
15891579
1590- /* Label as primary key or unique (but not both) */
1591- appendPQExpBuffer (& buf ,
1592- strcmp (PQgetvalue (result ,i ,1 ),"t" )== 0
1593- ?" PRIMARY KEY," :
1594- (strcmp (PQgetvalue (result ,i ,2 ),"t" )== 0
1595- ?" UNIQUE,"
1596- :"" ));
1597- /* Everything after "USING" is echoed verbatim */
1598- indexdef = PQgetvalue (result ,i ,5 );
1599- usingpos = strstr (indexdef ," USING " );
1600- if (usingpos )
1601- indexdef = usingpos + 7 ;
1602-
1603- appendPQExpBuffer (& buf ," %s" ,indexdef );
1580+ /* If exclusion constraint, print the constraintdef */
1581+ if (strcmp (PQgetvalue (result ,i ,7 ),"x" )== 0 )
1582+ {
1583+ appendPQExpBuffer (& buf ," %s" ,
1584+ PQgetvalue (result ,i ,6 ));
1585+ }
1586+ else
1587+ {
1588+ const char * indexdef ;
1589+ const char * usingpos ;
1590+
1591+ /* Label as primary key or unique (but not both) */
1592+ if (strcmp (PQgetvalue (result ,i ,1 ),"t" )== 0 )
1593+ appendPQExpBuffer (& buf ," PRIMARY KEY," );
1594+ else if (strcmp (PQgetvalue (result ,i ,2 ),"t" )== 0 )
1595+ appendPQExpBuffer (& buf ," UNIQUE," );
1596+
1597+ /* Everything after "USING" is echoed verbatim */
1598+ indexdef = PQgetvalue (result ,i ,5 );
1599+ usingpos = strstr (indexdef ," USING " );
1600+ if (usingpos )
1601+ indexdef = usingpos + 7 ;
1602+ appendPQExpBuffer (& buf ," %s" ,indexdef );
1603+
1604+ /* Need these for deferrable PK/UNIQUE indexes */
1605+ if (strcmp (PQgetvalue (result ,i ,8 ),"t" )== 0 )
1606+ appendPQExpBuffer (& buf ," DEFERRABLE" );
1607+
1608+ if (strcmp (PQgetvalue (result ,i ,9 ),"t" )== 0 )
1609+ appendPQExpBuffer (& buf ," INITIALLY DEFERRED" );
1610+ }
16041611
1612+ /* Add these for all cases */
16051613if (strcmp (PQgetvalue (result ,i ,3 ),"t" )== 0 )
16061614appendPQExpBuffer (& buf ," CLUSTER" );
16071615
16081616if (strcmp (PQgetvalue (result ,i ,4 ),"t" )!= 0 )
16091617appendPQExpBuffer (& buf ," INVALID" );
16101618
1611- if (strcmp (PQgetvalue (result ,i ,6 ),"t" )== 0 )
1612- appendPQExpBuffer (& buf ," DEFERRABLE" );
1613-
1614- if (strcmp (PQgetvalue (result ,i ,7 ),"t" )== 0 )
1615- appendPQExpBuffer (& buf ," INITIALLY DEFERRED" );
1616-
16171619printTableAddFooter (& cont ,buf .data );
16181620
16191621/* Print tablespace of the index on the same line */
16201622if (pset .sversion >=80000 )
16211623add_tablespace_footer (& cont ,'i' ,
1622- atooid (PQgetvalue (result ,i ,8 )),
1624+ atooid (PQgetvalue (result ,i ,10 )),
16231625 false);
16241626}
16251627}
@@ -1657,38 +1659,6 @@ describeOneTableDetails(const char *schemaname,
16571659PQclear (result );
16581660}
16591661
1660- /* print exclusion constraints */
1661- if (tableinfo .hasexclusion )
1662- {
1663- printfPQExpBuffer (& buf ,
1664- "SELECT r.conname, "
1665- "pg_catalog.pg_get_constraintdef(r.oid, true)\n"
1666- "FROM pg_catalog.pg_constraint r\n"
1667- "WHERE r.conrelid = '%s' AND r.contype = 'x'\n"
1668- "ORDER BY 1" ,
1669- oid );
1670- result = PSQLexec (buf .data , false);
1671- if (!result )
1672- gotoerror_return ;
1673- else
1674- tuples = PQntuples (result );
1675-
1676- if (tuples > 0 )
1677- {
1678- printTableAddFooter (& cont ,_ ("Exclusion constraints:" ));
1679- for (i = 0 ;i < tuples ;i ++ )
1680- {
1681- /* untranslated contraint name and def */
1682- printfPQExpBuffer (& buf ," \"%s\" %s" ,
1683- PQgetvalue (result ,i ,0 ),
1684- PQgetvalue (result ,i ,1 ));
1685-
1686- printTableAddFooter (& cont ,buf .data );
1687- }
1688- }
1689- PQclear (result );
1690- }
1691-
16921662/* print foreign-key constraints (there are none if no triggers) */
16931663if (tableinfo .hastriggers )
16941664{