3
3
*
4
4
* Copyright 2000 by PostgreSQL Global Development Group
5
5
*
6
- * $Header: /cvsroot/pgsql/src/bin/psql/describe.c,v 1.42 2001/11/12 15:57:08 tgl Exp $
6
+ * $Header: /cvsroot/pgsql/src/bin/psql/describe.c,v 1.43 2002/03/05 02:42:56 momjian Exp $
7
7
*/
8
8
#include "postgres_fe.h"
9
9
#include "describe.h"
@@ -532,15 +532,23 @@ describeTableDetails(const char *name, bool desc)
532
532
headers [cols ] = NULL ;
533
533
534
534
535
- /* Get column info */
536
- strcpy (buf , "SELECT a.attname, format_type(a.atttypid, a.atttypmod), a.attnotnull, a.atthasdef, a.attnum" );
535
+ /* Get column info (index requires additional checks) */
536
+ if (tableinfo .relkind == 'i' )
537
+ 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, " );
538
+ else
539
+ strcpy (buf , "SELECT a.attname, " );
540
+ strcat (buf , "format_type(a.atttypid, a.atttypmod), a.attnotnull, a.atthasdef, a.attnum" );
537
541
if (desc )
538
542
strcat (buf , ", col_description(a.attrelid, a.attnum)" );
539
- strcat (buf , "\nFROM pg_class c, pg_attribute a\n"
540
- "WHERE c.relname = '" );
543
+ strcat (buf , "\nFROM pg_class c, pg_attribute a" );
544
+ if (tableinfo .relkind == 'i' )
545
+ strcat (buf , ", pg_index i" );
546
+ strcat (buf , "\nWHERE c.relname = '" );
541
547
strncat (buf , name , NAMEDATALEN );
542
- strcat (buf , "'\n AND a.attnum > 0 AND a.attrelid = c.oid\n"
543
- "ORDER BY a.attnum" );
548
+ strcat (buf , "'\n AND a.attnum > 0 AND a.attrelid = c.oid" );
549
+ if (tableinfo .relkind == 'i' )
550
+ strcat (buf , " AND a.attrelid = i.indexrelid" );
551
+ strcat (buf , "\nORDER BY a.attnum" );
544
552
545
553
res = PSQLexec (buf );
546
554
if (!res )
@@ -651,11 +659,11 @@ describeTableDetails(const char *name, bool desc)
651
659
{
652
660
/* Footer information about an index */
653
661
PGresult * result ;
654
-
655
- sprintf ( buf , "SELECT i.indisunique, i.indisprimary, a.amname, \n"
656
- " pg_get_expr(i.indpred, i.indrelid) as indpred \n"
657
- "FROM pg_index i, pg_class c, pg_am a \n"
658
- "WHERE i.indexrelid = c.oid AND c.relname = '%s' AND c.relam = a .oid" ,
662
+ sprintf ( buf , "SELECT i.indisunique, i.indisprimary, a.amname, c2.relname,\n"
663
+ "pg_get_expr(i.indpred,i.indrelid) \n"
664
+ "FROM pg_index i, pg_class c, pg_class c2, pg_am a \n"
665
+ "WHERE i.indexrelid = c.oid AND c.relname = '%s' AND c.relam = a.oid \n"
666
+ "AND i.indrelid = c2 .oid" ,
659
667
name );
660
668
661
669
result = PSQLexec (buf );
@@ -666,27 +674,18 @@ describeTableDetails(const char *name, bool desc)
666
674
char * indisunique = PQgetvalue (result , 0 , 0 );
667
675
char * indisprimary = PQgetvalue (result , 0 , 1 );
668
676
char * indamname = PQgetvalue (result , 0 , 2 );
669
- char * indpred = PQgetvalue (result , 0 , 3 );
677
+ char * indtable = PQgetvalue (result , 0 , 3 );
678
+ char * indpred = PQgetvalue (result , 0 , 4 );
670
679
671
- footers = xmalloc (3 * sizeof (* footers ));
680
+ footers = xmalloc (2 * sizeof (* footers ));
672
681
/* XXX This construction is poorly internationalized. */
673
- footers [0 ] = xmalloc (NAMEDATALEN + 128 );
674
- snprintf (footers [0 ], NAMEDATALEN + 128 , "%s%s" ,
682
+ footers [0 ] = xmalloc (NAMEDATALEN * 4 + 128 );
683
+ snprintf (footers [0 ], NAMEDATALEN * 4 + 128 , "%s%s for %s \"%s\"%s%s" ,
684
+ strcmp (indisprimary , "t" ) == 0 ? _ ("primary key " ) :
675
685
strcmp (indisunique , "t" ) == 0 ? _ ("unique " ) : "" ,
676
- indamname );
677
- if (strcmp (indisprimary , "t" ) == 0 )
678
- snprintf (footers [0 ] + strlen (footers [0 ]),
679
- NAMEDATALEN + 128 - strlen (footers [0 ]),
680
- _ (" (primary key)" ));
681
- if (strlen (indpred ) > 0 )
682
- {
683
- footers [1 ] = xmalloc (64 + strlen (indpred ));
684
- snprintf (footers [1 ], 64 + strlen (indpred ),
685
- _ ("Index predicate: %s" ), indpred );
686
- footers [2 ] = NULL ;
687
- }
688
- else
689
- footers [1 ] = NULL ;
686
+ indamname , _ ("table" ), indtable ,
687
+ strlen (indpred ) ? " WHERE " : "" ,indpred );
688
+ footers [1 ] = NULL ;
690
689
}
691
690
692
691
PQclear (result );
@@ -706,12 +705,8 @@ describeTableDetails(const char *name, bool desc)
706
705
PGresult * result1 = NULL ,
707
706
* result2 = NULL ,
708
707
* result3 = NULL ,
709
- * result4 = NULL ,
710
- * result5 = NULL ,
711
- * result6 = NULL ;
708
+ * result4 = NULL ;
712
709
int index_count = 0 ,
713
- primary_count = 0 ,
714
- unique_count = 0 ,
715
710
constr_count = 0 ,
716
711
rule_count = 0 ,
717
712
trigger_count = 0 ;
@@ -720,10 +715,12 @@ describeTableDetails(const char *name, bool desc)
720
715
/* count indexes */
721
716
if (!error && tableinfo .hasindex )
722
717
{
723
- sprintf (buf , "SELECT c2.relname\n"
718
+ sprintf (buf , "SELECT c2.relname, i.indisprimary, i.indisunique,\n"
719
+ "SUBSTR(pg_get_indexdef(i.indexrelid),\n"
720
+ "POSITION('USING ' IN pg_get_indexdef(i.indexrelid))+5)\n"
724
721
"FROM pg_class c, pg_class c2, pg_index i\n"
725
722
"WHERE c.relname = '%s' AND c.oid = i.indrelid AND i.indexrelid = c2.oid\n"
726
- "AND NOT i.indisunique ORDER BY c2.relname" ,
723
+ "ORDER BY i.indisprimary DESC, i.indisunique DESC, c2.relname" ,
727
724
name );
728
725
result1 = PSQLexec (buf );
729
726
if (!result1 )
@@ -732,36 +729,6 @@ describeTableDetails(const char *name, bool desc)
732
729
index_count = PQntuples (result1 );
733
730
}
734
731
735
- /* count primary keys */
736
- if (!error && tableinfo .hasindex )
737
- {
738
- sprintf (buf , "SELECT c2.relname\n"
739
- "FROM pg_class c, pg_class c2, pg_index i\n"
740
- "WHERE c.relname = '%s' AND c.oid = i.indrelid AND i.indexrelid = c2.oid\n"
741
- "AND i.indisprimary AND i.indisunique ORDER BY c2.relname" ,
742
- name );
743
- result5 = PSQLexec (buf );
744
- if (!result5 )
745
- error = true;
746
- else
747
- primary_count = PQntuples (result5 );
748
- }
749
-
750
- /* count unique constraints */
751
- if (!error && tableinfo .hasindex )
752
- {
753
- sprintf (buf , "SELECT c2.relname\n"
754
- "FROM pg_class c, pg_class c2, pg_index i\n"
755
- "WHERE c.relname = '%s' AND c.oid = i.indrelid AND i.indexrelid = c2.oid\n"
756
- "AND NOT i.indisprimary AND i.indisunique ORDER BY c2.relname" ,
757
- name );
758
- result6 = PSQLexec (buf );
759
- if (!result6 )
760
- error = true;
761
- else
762
- unique_count = PQntuples (result6 );
763
- }
764
-
765
732
/* count table (and column) constraints */
766
733
if (!error && tableinfo .checks )
767
734
{
@@ -806,54 +773,32 @@ describeTableDetails(const char *name, bool desc)
806
773
trigger_count = PQntuples (result4 );
807
774
}
808
775
809
- footers = xmalloc ((index_count + primary_count + unique_count +
810
- constr_count + rule_count + trigger_count + 1 )
776
+ footers = xmalloc ((index_count + constr_count + rule_count + trigger_count + 1 )
811
777
* sizeof (* footers ));
812
778
813
779
/* print indexes */
814
780
for (i = 0 ; i < index_count ; i ++ )
815
781
{
816
782
char * s = _ ("Indexes" );
817
-
783
+
818
784
if (i == 0 )
819
785
snprintf (buf , sizeof (buf ), "%s: %s" , s , PQgetvalue (result1 , i , 0 ));
820
786
else
821
787
snprintf (buf , sizeof (buf ), "%*s %s" , (int ) strlen (s ), "" , PQgetvalue (result1 , i , 0 ));
822
- if (i < index_count - 1 )
823
- strcat (buf , "," );
824
788
825
- footers [count_footers ++ ] = xstrdup (buf );
826
- }
789
+ /* Label as primary key or unique (but not both) */
790
+ strcat (buf , strcmp (PQgetvalue (result1 ,i ,1 ),"t" ) == 0 ?
791
+ _ (" primary key" ) : strcmp (PQgetvalue (result1 ,i ,2 ),"t" ) == 0 ? _ (" unique" ) : "" );
827
792
828
- /* print primary keys */
829
- for (i = 0 ; i < primary_count ; i ++ )
830
- {
831
- char * s = _ ("Primary key" );
793
+ /* Everything after "USING" is echoed verbatim */
794
+ strcat (buf , PQgetvalue (result1 ,i ,3 ));
832
795
833
- if (i == 0 )
834
- snprintf (buf , sizeof (buf ), "%s: %s" , s , PQgetvalue (result5 , i , 0 ));
835
- else
836
- snprintf (buf , sizeof (buf ), "%*s %s" , (int ) strlen (s ), "" , PQgetvalue (result5 , i , 0 ));
837
- if (i < primary_count - 1 )
796
+ if (i < index_count - 1 )
838
797
strcat (buf , "," );
839
798
840
799
footers [count_footers ++ ] = xstrdup (buf );
841
800
}
842
801
843
- /* print unique constraints */
844
- for (i = 0 ; i < unique_count ; i ++ )
845
- {
846
- char * s = _ ("Unique keys" );
847
-
848
- if (i == 0 )
849
- snprintf (buf , sizeof (buf ), "%s: %s" , s , PQgetvalue (result6 , i , 0 ));
850
- else
851
- snprintf (buf , sizeof (buf ), "%*s %s" , (int ) strlen (s ), "" , PQgetvalue (result6 , i , 0 ));
852
- if (i < unique_count - 1 )
853
- strcat (buf , "," );
854
-
855
- footers [count_footers ++ ] = xstrdup (buf );
856
- }
857
802
858
803
/* print constraints */
859
804
for (i = 0 ; i < constr_count ; i ++ )
@@ -906,8 +851,6 @@ describeTableDetails(const char *name, bool desc)
906
851
PQclear (result2 );
907
852
PQclear (result3 );
908
853
PQclear (result4 );
909
- PQclear (result5 );
910
- PQclear (result6 );
911
854
}
912
855
913
856
if (!error )
@@ -1031,9 +974,19 @@ listTables(const char *infotype, const char *name, bool desc)
1031
974
snprintf (buf + strlen (buf ), sizeof (buf ) - strlen (buf ),
1032
975
",\n obj_description(c.oid, 'pg_class') as \"%s\"" ,
1033
976
_ ("Description" ));
1034
- strcat (buf ,
1035
- "\nFROM pg_class c LEFT JOIN pg_user u ON c.relowner = u.usesysid\n"
1036
- "WHERE c.relkind IN (" );
977
+ if (showIndexes ) {
978
+ snprintf (buf + strlen (buf ), sizeof (buf ) - strlen (buf ),
979
+ ",\n c2.relname as \"%s\"" ,
980
+ _ ("Table" ));
981
+ strcat (buf , "\nFROM pg_class c, pg_class c2, pg_index i, pg_user u\n"
982
+ "WHERE c.relowner = u.usesysid\n"
983
+ "AND i.indrelid = c2.oid AND i.indexrelid = c.oid\n" );
984
+ }
985
+ else {
986
+ strcat (buf , "\nFROM pg_class c, pg_user u\n"
987
+ "WHERE c.relowner = u.usesysid\n" );
988
+ }
989
+ strcat (buf , "AND c.relkind IN (" );
1037
990
if (showTables )
1038
991
strcat (buf , "'r'," );
1039
992
if (showViews )
0 commit comments