3
3
*
4
4
* Copyright 2000-2002 by PostgreSQL Global Development Group
5
5
*
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 $
7
7
*/
8
8
#include "postgres_fe.h"
9
9
#include "describe.h"
@@ -44,6 +44,16 @@ xmalloc(size_t size)
44
44
return tmp ;
45
45
}
46
46
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
+
47
57
48
58
/*----------------
49
59
* Handlers for various slash commands displaying some sort of list
@@ -635,7 +645,9 @@ describeOneTableDetails(const char *schemaname,
635
645
char * * footers = NULL ;
636
646
char * * ptr ;
637
647
PQExpBufferData title ;
638
- unsigned int cols = 0 ;
648
+ PQExpBufferData tmpbuf ;
649
+ int cols = 0 ;
650
+ int numrows = 0 ;
639
651
struct
640
652
{
641
653
bool hasindex ;
@@ -644,12 +656,14 @@ describeOneTableDetails(const char *schemaname,
644
656
int16 triggers ;
645
657
bool hasrules ;
646
658
} tableinfo ;
659
+ bool show_modifiers = false;
647
660
bool retval ;
648
661
649
662
retval = false;
650
663
651
664
initPQExpBuffer (& buf );
652
665
initPQExpBuffer (& title );
666
+ initPQExpBuffer (& tmpbuf );
653
667
654
668
/* Get general table info */
655
669
printfPQExpBuffer (& buf ,
@@ -683,6 +697,7 @@ describeOneTableDetails(const char *schemaname,
683
697
684
698
if (tableinfo .relkind == 'r' || tableinfo .relkind == 'v' )
685
699
{
700
+ show_modifiers = true;
686
701
cols ++ ;
687
702
headers [cols - 1 ] = _ ("Modifiers" );
688
703
}
@@ -715,6 +730,7 @@ describeOneTableDetails(const char *schemaname,
715
730
res = PSQLexec (buf .data , false);
716
731
if (!res )
717
732
goto error_return ;
733
+ numrows = PQntuples (res );
718
734
719
735
/* Check if table is a view */
720
736
if (tableinfo .relkind == 'v' )
@@ -733,10 +749,10 @@ describeOneTableDetails(const char *schemaname,
733
749
}
734
750
735
751
/* 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 ));
738
754
739
- for (i = 0 ; i < PQntuples ( res ) ; i ++ )
755
+ for (i = 0 ; i < numrows ; i ++ )
740
756
{
741
757
/* Name */
742
758
cells [i * cols + 0 ] = PQgetvalue (res , i , 0 ); /* don't free this
@@ -747,12 +763,11 @@ describeOneTableDetails(const char *schemaname,
747
763
748
764
/* Extra: not null and default */
749
765
/* (I'm cutting off the 'default' string at 128) */
750
- if (tableinfo . relkind == 'r' || tableinfo . relkind == 'v' )
766
+ if (show_modifiers )
751
767
{
752
- cells [i * cols + 2 ] = xmalloc (128 + 128 );
753
- cells [i * cols + 2 ][0 ] = '\0' ;
768
+ resetPQExpBuffer (& tmpbuf );
754
769
if (strcmp (PQgetvalue (res , i , 2 ), "t" ) == 0 )
755
- strcat ( cells [ i * cols + 2 ] , "not null" );
770
+ appendPQExpBufferStr ( & tmpbuf , "not null" );
756
771
757
772
/* handle "default" here */
758
773
if (strcmp (PQgetvalue (res , i , 3 ), "t" ) == 0 )
@@ -761,18 +776,21 @@ describeOneTableDetails(const char *schemaname,
761
776
762
777
printfPQExpBuffer (& buf ,
763
778
"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" ,
765
780
oid , PQgetvalue (res , i , 4 ));
766
781
767
782
result = PSQLexec (buf .data , false);
768
783
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 ) : "?" );
773
789
774
790
PQclear (result );
775
791
}
792
+
793
+ cells [i * cols + 2 ] = xstrdup (tmpbuf .data );
776
794
}
777
795
778
796
/* Description */
@@ -841,15 +859,12 @@ describeOneTableDetails(const char *schemaname,
841
859
}
842
860
else
843
861
{
844
- PQExpBufferData tmpbuf ;
845
862
char * indisunique = PQgetvalue (result , 0 , 0 );
846
863
char * indisprimary = PQgetvalue (result , 0 , 1 );
847
864
char * indamname = PQgetvalue (result , 0 , 2 );
848
865
char * indtable = PQgetvalue (result , 0 , 3 );
849
866
char * indpred = PQgetvalue (result , 0 , 4 );
850
867
851
- initPQExpBuffer (& tmpbuf );
852
-
853
868
if (strcmp (indisprimary , "t" ) == 0 )
854
869
printfPQExpBuffer (& tmpbuf , _ ("primary key, " ));
855
870
else if (strcmp (indisunique , "t" ) == 0 )
@@ -865,10 +880,9 @@ describeOneTableDetails(const char *schemaname,
865
880
if (strlen (indpred ))
866
881
appendPQExpBuffer (& tmpbuf , ", predicate %s" , indpred );
867
882
868
- footers = xmalloc (2 * sizeof (* footers ));
883
+ footers = xmalloczero (2 * sizeof (* footers ));
869
884
footers [0 ] = xstrdup (tmpbuf .data );
870
885
footers [1 ] = NULL ;
871
- termPQExpBuffer (& tmpbuf );
872
886
}
873
887
874
888
PQclear (result );
@@ -895,7 +909,7 @@ describeOneTableDetails(const char *schemaname,
895
909
}
896
910
897
911
/* Footer information about a view */
898
- footers = xmalloc ((rule_count + 2 ) * sizeof (* footers ));
912
+ footers = xmalloczero ((rule_count + 2 ) * sizeof (* footers ));
899
913
footers [count_footers ] = xmalloc (64 + strlen (view_def ));
900
914
snprintf (footers [count_footers ], 64 + strlen (view_def ),
901
915
_ ("View definition: %s" ), view_def );
@@ -1018,8 +1032,8 @@ describeOneTableDetails(const char *schemaname,
1018
1032
foreignkey_count = PQntuples (result5 );
1019
1033
}
1020
1034
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 ));
1023
1037
1024
1038
/* print indexes */
1025
1039
for (i = 0 ; i < index_count ; i ++ )
@@ -1148,12 +1162,15 @@ describeOneTableDetails(const char *schemaname,
1148
1162
/* clean up */
1149
1163
termPQExpBuffer (& buf );
1150
1164
termPQExpBuffer (& title );
1165
+ termPQExpBuffer (& tmpbuf );
1151
1166
1152
1167
if (cells )
1153
1168
{
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 )
1156
1172
free (cells [i * cols + 2 ]);
1173
+ }
1157
1174
free (cells );
1158
1175
}
1159
1176
0 commit comments