1212 *by PostgreSQL
1313 *
1414 * IDENTIFICATION
15- * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.521 2009/02/16 23:06:55 momjian Exp $
15+ * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.522 2009/02/17 15:41:50 momjian Exp $
1616 *
1717 *-------------------------------------------------------------------------
1818 */
@@ -99,6 +99,8 @@ static SimpleOidList table_exclude_oids = {NULL, NULL};
9999/* default, if no "inclusion" switches appear, is to dump everything */
100100static bool include_everything = true;
101101
102+ static int binary_upgrade = 0 ;
103+
102104char g_opaque_type [10 ];/* name for the opaque type */
103105
104106/* placeholders for the delimiters for comments */
@@ -236,7 +238,8 @@ main(int argc, char **argv)
236238static int outputNoTablespaces = 0 ;
237239static int use_setsessauth = 0 ;
238240
239- static struct option long_options []= {
241+ struct option long_options []= {
242+ {"binary-upgrade" ,no_argument ,& binary_upgrade ,1 },/* not documented */
240243{"data-only" ,no_argument ,NULL ,'a' },
241244{"blobs" ,no_argument ,NULL ,'b' },
242245{"clean" ,no_argument ,NULL ,'c' },
@@ -4611,6 +4614,8 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
46114614int i_attnotnull ;
46124615int i_atthasdef ;
46134616int i_attisdropped ;
4617+ int i_attlen ;
4618+ int i_attalign ;
46144619int i_attislocal ;
46154620PGresult * res ;
46164621int ntups ;
@@ -4655,7 +4660,7 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
46554660appendPQExpBuffer (q ,"SELECT a.attnum, a.attname, a.atttypmod, "
46564661"a.attstattarget, a.attstorage, t.typstorage, "
46574662"a.attnotnull, a.atthasdef, a.attisdropped, "
4658- "a.attislocal, "
4663+ "a.attlen, a.attalign, a.attislocal, "
46594664"pg_catalog.format_type(t.oid,a.atttypmod) AS atttypname "
46604665"FROM pg_catalog.pg_attribute a LEFT JOIN pg_catalog.pg_type t "
46614666"ON a.atttypid = t.oid "
@@ -4674,7 +4679,8 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
46744679appendPQExpBuffer (q ,"SELECT a.attnum, a.attname, "
46754680"a.atttypmod, -1 AS attstattarget, a.attstorage, "
46764681"t.typstorage, a.attnotnull, a.atthasdef, "
4677- "false AS attisdropped, false AS attislocal, "
4682+ "false AS attisdropped, 0 AS attlen, "
4683+ "' ' AS attalign, false AS attislocal, "
46784684"format_type(t.oid,a.atttypmod) AS atttypname "
46794685"FROM pg_attribute a LEFT JOIN pg_type t "
46804686"ON a.atttypid = t.oid "
@@ -4690,7 +4696,8 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
46904696"-1 AS attstattarget, attstorage, "
46914697"attstorage AS typstorage, "
46924698"attnotnull, atthasdef, false AS attisdropped, "
4693- "false AS attislocal, "
4699+ "0 AS attlen, ' ' AS attalign, "
4700+ "false AS attislocal, "
46944701"(SELECT typname FROM pg_type WHERE oid = atttypid) AS atttypname "
46954702"FROM pg_attribute a "
46964703"WHERE attrelid = '%u'::oid "
@@ -4714,6 +4721,8 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
47144721i_attnotnull = PQfnumber (res ,"attnotnull" );
47154722i_atthasdef = PQfnumber (res ,"atthasdef" );
47164723i_attisdropped = PQfnumber (res ,"attisdropped" );
4724+ i_attlen = PQfnumber (res ,"attlen" );
4725+ i_attalign = PQfnumber (res ,"attalign" );
47174726i_attislocal = PQfnumber (res ,"attislocal" );
47184727
47194728tbinfo -> numatts = ntups ;
@@ -4724,6 +4733,8 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
47244733tbinfo -> attstorage = (char * )malloc (ntups * sizeof (char ));
47254734tbinfo -> typstorage = (char * )malloc (ntups * sizeof (char ));
47264735tbinfo -> attisdropped = (bool * )malloc (ntups * sizeof (bool ));
4736+ tbinfo -> attlen = (int * )malloc (ntups * sizeof (int ));
4737+ tbinfo -> attalign = (char * )malloc (ntups * sizeof (char ));
47274738tbinfo -> attislocal = (bool * )malloc (ntups * sizeof (bool ));
47284739tbinfo -> notnull = (bool * )malloc (ntups * sizeof (bool ));
47294740tbinfo -> attrdefs = (AttrDefInfo * * )malloc (ntups * sizeof (AttrDefInfo * ));
@@ -4747,6 +4758,8 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
47474758tbinfo -> attstorage [j ]= * (PQgetvalue (res ,j ,i_attstorage ));
47484759tbinfo -> typstorage [j ]= * (PQgetvalue (res ,j ,i_typstorage ));
47494760tbinfo -> attisdropped [j ]= (PQgetvalue (res ,j ,i_attisdropped )[0 ]== 't' );
4761+ tbinfo -> attlen [j ]= atoi (PQgetvalue (res ,j ,i_attlen ));
4762+ tbinfo -> attalign [j ]= * (PQgetvalue (res ,j ,i_attalign ));
47504763tbinfo -> attislocal [j ]= (PQgetvalue (res ,j ,i_attislocal )[0 ]== 't' );
47514764tbinfo -> notnull [j ]= (PQgetvalue (res ,j ,i_attnotnull )[0 ]== 't' );
47524765tbinfo -> attrdefs [j ]= NULL ;/* fix below */
@@ -4760,6 +4773,21 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
47604773
47614774PQclear (res );
47624775
4776+
4777+ /*
4778+ *ALTER TABLE DROP COLUMN clears pg_attribute.atttypid, so we
4779+ *set the column data type to 'TEXT; we will later drop the
4780+ *column.
4781+ */
4782+ if (binary_upgrade )
4783+ {
4784+ for (j = 0 ;j < ntups ;j ++ )
4785+ {
4786+ if (tbinfo -> attisdropped [j ])
4787+ tbinfo -> atttypnames [j ]= strdup ("TEXT" );
4788+ }
4789+ }
4790+
47634791/*
47644792 * Get info about column defaults
47654793 */
@@ -9680,7 +9708,8 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
96809708for (j = 0 ;j < tbinfo -> numatts ;j ++ )
96819709{
96829710/* Is this one of the table's own attrs, and not dropped ? */
9683- if (!tbinfo -> inhAttrs [j ]&& !tbinfo -> attisdropped [j ])
9711+ if (!tbinfo -> inhAttrs [j ]&&
9712+ (!tbinfo -> attisdropped [j ]|| binary_upgrade ))
96849713{
96859714/* Format properly if not first attr */
96869715if (actual_atts > 0 )
@@ -9786,6 +9815,53 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
97869815
97879816appendPQExpBuffer (q ,";\n" );
97889817
9818+ /*
9819+ * For binary-compatible heap files, we create dropped columns
9820+ * above and drop them here.
9821+ */
9822+ if (binary_upgrade )
9823+ {
9824+ for (j = 0 ;j < tbinfo -> numatts ;j ++ )
9825+ {
9826+ if (tbinfo -> attisdropped [j ])
9827+ {
9828+ appendPQExpBuffer (q ,"ALTER TABLE ONLY %s " ,
9829+ fmtId (tbinfo -> dobj .name ));
9830+ appendPQExpBuffer (q ,"DROP COLUMN %s;\n" ,
9831+ fmtId (tbinfo -> attnames [j ]));
9832+
9833+ /*
9834+ *ALTER TABLE DROP COLUMN clears pg_attribute.atttypid,
9835+ *so we have to set pg_attribute.attlen and
9836+ *pg_attribute.attalign values because that is what
9837+ *is used to skip over dropped columns in the heap tuples.
9838+ *We have atttypmod, but it seems impossible to know the
9839+ *correct data type that will yield pg_attribute values
9840+ *that match the old installation.
9841+ *See comment in backend/catalog/heap.c::RemoveAttributeById()
9842+ */
9843+ appendPQExpBuffer (q ,"\n-- For binary upgrade, recreate dropped column's length and alignment.\n" );
9844+ appendPQExpBuffer (q ,"UPDATE pg_attribute\n"
9845+ "SET attlen = %d, "
9846+ "attalign = '%c'\n"
9847+ "WHEREattname = '%s'\n"
9848+ "AND attrelid = \n"
9849+ "(\n"
9850+ "SELECT oid\n"
9851+ "FROM pg_class\n"
9852+ "WHERErelnamespace = "
9853+ "(SELECT oid FROM pg_namespace "
9854+ "WHERE nspname = CURRENT_SCHEMA)\n"
9855+ "AND relname = '%s'\n"
9856+ ");" ,
9857+ tbinfo -> attlen [j ],
9858+ tbinfo -> attalign [j ],
9859+ tbinfo -> attnames [j ],
9860+ tbinfo -> dobj .name );
9861+ }
9862+ }
9863+ }
9864+
97899865/* Loop dumping statistics and storage statements */
97909866for (j = 0 ;j < tbinfo -> numatts ;j ++ )
97919867{