33 *
44 * Copyright 2000-2002 by PostgreSQL Global Development Group
55 *
6- * $Header: /cvsroot/pgsql/src/bin/psql/describe.c,v 1.72 2002/12/12 21:02:24 momjian Exp $
6+ * $Header: /cvsroot/pgsql/src/bin/psql/describe.c,v 1.73 2002/12/21 01:07:07 tgl Exp $
77 */
88#include "postgres_fe.h"
99#include "describe.h"
@@ -44,6 +44,16 @@ xmalloc(size_t size)
4444return tmp ;
4545}
4646
47+ static void *
48+ xmalloczero (size_t size )
49+ {
50+ void * tmp ;
51+
52+ tmp = xmalloc (size );
53+ memset (tmp ,0 ,size );
54+ return tmp ;
55+ }
56+
4757
4858/*----------------
4959 * Handlers for various slash commands displaying some sort of list
@@ -635,7 +645,9 @@ describeOneTableDetails(const char *schemaname,
635645char * * footers = NULL ;
636646char * * ptr ;
637647PQExpBufferData title ;
638- unsignedint cols = 0 ;
648+ PQExpBufferData tmpbuf ;
649+ int cols = 0 ;
650+ int numrows = 0 ;
639651struct
640652{
641653bool hasindex ;
@@ -644,12 +656,14 @@ describeOneTableDetails(const char *schemaname,
644656int16 triggers ;
645657bool hasrules ;
646658}tableinfo ;
659+ bool show_modifiers = false;
647660bool retval ;
648661
649662retval = false;
650663
651664initPQExpBuffer (& buf );
652665initPQExpBuffer (& title );
666+ initPQExpBuffer (& tmpbuf );
653667
654668/* Get general table info */
655669printfPQExpBuffer (& buf ,
@@ -683,6 +697,7 @@ describeOneTableDetails(const char *schemaname,
683697
684698if (tableinfo .relkind == 'r' || tableinfo .relkind == 'v' )
685699{
700+ show_modifiers = true;
686701cols ++ ;
687702headers [cols - 1 ]= _ ("Modifiers" );
688703}
@@ -715,6 +730,7 @@ describeOneTableDetails(const char *schemaname,
715730res = PSQLexec (buf .data , false);
716731if (!res )
717732gotoerror_return ;
733+ numrows = PQntuples (res );
718734
719735/* Check if table is a view */
720736if (tableinfo .relkind == 'v' )
@@ -733,10 +749,10 @@ describeOneTableDetails(const char *schemaname,
733749}
734750
735751/* Generate table cells to be printed */
736- cells = xmalloc (( PQntuples ( res ) * cols + 1 ) * sizeof ( * cells ));
737- cells [ PQntuples ( res ) * cols ] = NULL ; /* end of list */
752+ /* note: initialize all cells[] to NULL in case of error exit */
753+ cells = xmalloczero (( numrows * cols + 1 ) * sizeof ( * cells ));
738754
739- for (i = 0 ;i < PQntuples ( res ) ;i ++ )
755+ for (i = 0 ;i < numrows ;i ++ )
740756{
741757/* Name */
742758cells [i * cols + 0 ]= PQgetvalue (res ,i ,0 );/* don't free this
@@ -747,12 +763,11 @@ describeOneTableDetails(const char *schemaname,
747763
748764/* Extra: not null and default */
749765/* (I'm cutting off the 'default' string at 128) */
750- if (tableinfo . relkind == 'r' || tableinfo . relkind == 'v' )
766+ if (show_modifiers )
751767{
752- cells [i * cols + 2 ]= xmalloc (128 + 128 );
753- cells [i * cols + 2 ][0 ]= '\0' ;
768+ resetPQExpBuffer (& tmpbuf );
754769if (strcmp (PQgetvalue (res ,i ,2 ),"t" )== 0 )
755- strcat ( cells [ i * cols + 2 ] ,"not null" );
770+ appendPQExpBufferStr ( & tmpbuf ,"not null" );
756771
757772/* handle "default" here */
758773if (strcmp (PQgetvalue (res ,i ,3 ),"t" )== 0 )
@@ -761,18 +776,21 @@ describeOneTableDetails(const char *schemaname,
761776
762777printfPQExpBuffer (& buf ,
763778"SELECT substring(d.adsrc for 128) FROM pg_catalog.pg_attrdef d\n"
764- "WHERE d.adrelid = '%s' AND d.adnum = %s" ,
779+ "WHERE d.adrelid = '%s' AND d.adnum = %s" ,
765780oid ,PQgetvalue (res ,i ,4 ));
766781
767782result = PSQLexec (buf .data , false);
768783
769- if (cells [i * cols + 2 ][0 ])
770- strcat (cells [i * cols + 2 ]," " );
771- strcat (cells [i * cols + 2 ],"default " );
772- strcat (cells [i * cols + 2 ],result ?PQgetvalue (result ,0 ,0 ) :"?" );
784+ if (tmpbuf .len > 0 )
785+ appendPQExpBufferStr (& tmpbuf ," " );
786+
787+ appendPQExpBuffer (& tmpbuf ,"default %s" ,
788+ result ?PQgetvalue (result ,0 ,0 ) :"?" );
773789
774790PQclear (result );
775791}
792+
793+ cells [i * cols + 2 ]= xstrdup (tmpbuf .data );
776794}
777795
778796/* Description */
@@ -841,15 +859,12 @@ describeOneTableDetails(const char *schemaname,
841859}
842860else
843861{
844- PQExpBufferData tmpbuf ;
845862char * indisunique = PQgetvalue (result ,0 ,0 );
846863char * indisprimary = PQgetvalue (result ,0 ,1 );
847864char * indamname = PQgetvalue (result ,0 ,2 );
848865char * indtable = PQgetvalue (result ,0 ,3 );
849866char * indpred = PQgetvalue (result ,0 ,4 );
850867
851- initPQExpBuffer (& tmpbuf );
852-
853868if (strcmp (indisprimary ,"t" )== 0 )
854869printfPQExpBuffer (& tmpbuf ,_ ("primary key, " ));
855870else if (strcmp (indisunique ,"t" )== 0 )
@@ -865,10 +880,9 @@ describeOneTableDetails(const char *schemaname,
865880if (strlen (indpred ))
866881appendPQExpBuffer (& tmpbuf ,", predicate %s" ,indpred );
867882
868- footers = xmalloc (2 * sizeof (* footers ));
883+ footers = xmalloczero (2 * sizeof (* footers ));
869884footers [0 ]= xstrdup (tmpbuf .data );
870885footers [1 ]= NULL ;
871- termPQExpBuffer (& tmpbuf );
872886}
873887
874888PQclear (result );
@@ -895,7 +909,7 @@ describeOneTableDetails(const char *schemaname,
895909}
896910
897911/* Footer information about a view */
898- footers = xmalloc ((rule_count + 2 )* sizeof (* footers ));
912+ footers = xmalloczero ((rule_count + 2 )* sizeof (* footers ));
899913footers [count_footers ]= xmalloc (64 + strlen (view_def ));
900914snprintf (footers [count_footers ],64 + strlen (view_def ),
901915_ ("View definition: %s" ),view_def );
@@ -1018,8 +1032,8 @@ describeOneTableDetails(const char *schemaname,
10181032foreignkey_count = PQntuples (result5 );
10191033}
10201034
1021- footers = xmalloc ((index_count + check_count + rule_count + trigger_count + foreignkey_count + 1 )
1022- * sizeof (* footers ));
1035+ footers = xmalloczero ((index_count + check_count + rule_count + trigger_count + foreignkey_count + 1 )
1036+ * sizeof (* footers ));
10231037
10241038/* print indexes */
10251039for (i = 0 ;i < index_count ;i ++ )
@@ -1148,12 +1162,15 @@ describeOneTableDetails(const char *schemaname,
11481162/* clean up */
11491163termPQExpBuffer (& buf );
11501164termPQExpBuffer (& title );
1165+ termPQExpBuffer (& tmpbuf );
11511166
11521167if (cells )
11531168{
1154- for (i = 0 ;i < PQntuples (res );i ++ )
1155- if (tableinfo .relkind == 'r' || tableinfo .relkind == 'v' )
1169+ for (i = 0 ;i < numrows ;i ++ )
1170+ {
1171+ if (show_modifiers )
11561172free (cells [i * cols + 2 ]);
1173+ }
11571174free (cells );
11581175}
11591176