@@ -7937,16 +7937,21 @@ static void
79377937dumpCompositeType (Archive * fout ,TypeInfo * tyinfo )
79387938{
79397939PQExpBuffer q = createPQExpBuffer ();
7940+ PQExpBuffer dropped = createPQExpBuffer ();
79407941PQExpBuffer delq = createPQExpBuffer ();
79417942PQExpBuffer labelq = createPQExpBuffer ();
79427943PQExpBuffer query = createPQExpBuffer ();
79437944PGresult * res ;
79447945int ntups ;
79457946int i_attname ;
79467947int i_atttypdefn ;
7948+ int i_attlen ;
7949+ int i_attalign ;
7950+ int i_attisdropped ;
79477951int i_attcollation ;
79487952int i_typrelid ;
79497953int i ;
7954+ int actual_atts ;
79507955
79517956/* Set proper schema search path so type references list correctly */
79527957selectSourceSchema (tyinfo -> dobj .namespace -> dobj .name );
@@ -7958,33 +7963,37 @@ dumpCompositeType(Archive *fout, TypeInfo *tyinfo)
79587963 * attcollation is new in 9.1.Since we only want to dump COLLATE
79597964 * clauses for attributes whose collation is different from their
79607965 * type's default, we use a CASE here to suppress uninteresting
7961- * attcollations cheaply.
7966+ * attcollations cheaply. atttypid will be 0 for dropped columns;
7967+ * collation does not matter for those.
79627968 */
79637969appendPQExpBuffer (query ,"SELECT a.attname, "
79647970"pg_catalog.format_type(a.atttypid, a.atttypmod) AS atttypdefn, "
7971+ "a.attlen, a.attalign, a.attisdropped, "
79657972"CASE WHEN a.attcollation <> at.typcollation "
79667973"THEN a.attcollation ELSE 0 END AS attcollation, "
79677974"ct.typrelid "
7968- "FROM pg_catalog.pg_type ct, pg_catalog.pg_attribute a, "
7969- "pg_catalog.pg_type at "
7975+ "FROM pg_catalog.pg_type ct "
7976+ "JOIN pg_catalog.pg_attribute a ON a.attrelid = ct.typrelid "
7977+ "LEFT JOIN pg_catalog.pg_type at ON at.oid = a.atttypid "
79707978"WHERE ct.oid = '%u'::pg_catalog.oid "
7971- "AND a.attrelid = ct.typrelid "
7972- "AND a.atttypid = at.oid "
7973- "AND NOT a.attisdropped "
79747979"ORDER BY a.attnum " ,
79757980tyinfo -> dobj .catId .oid );
79767981}
79777982else
79787983{
7979- /* We assume here that remoteVersion must be at least 70300 */
7984+ /*
7985+ * We assume here that remoteVersion must be at least 70300. Since
7986+ * ALTER TYPE could not drop columns until 9.1, attisdropped should
7987+ * always be false.
7988+ */
79807989appendPQExpBuffer (query ,"SELECT a.attname, "
79817990"pg_catalog.format_type(a.atttypid, a.atttypmod) AS atttypdefn, "
7991+ "a.attlen, a.attalign, a.attisdropped, "
79827992"0 AS attcollation, "
79837993"ct.typrelid "
79847994"FROM pg_catalog.pg_type ct, pg_catalog.pg_attribute a "
79857995"WHERE ct.oid = '%u'::pg_catalog.oid "
79867996"AND a.attrelid = ct.typrelid "
7987- "AND NOT a.attisdropped "
79887997"ORDER BY a.attnum " ,
79897998tyinfo -> dobj .catId .oid );
79907999}
@@ -7996,6 +8005,9 @@ dumpCompositeType(Archive *fout, TypeInfo *tyinfo)
79968005
79978006i_attname = PQfnumber (res ,"attname" );
79988007i_atttypdefn = PQfnumber (res ,"atttypdefn" );
8008+ i_attlen = PQfnumber (res ,"attlen" );
8009+ i_attalign = PQfnumber (res ,"attalign" );
8010+ i_attisdropped = PQfnumber (res ,"attisdropped" );
79998011i_attcollation = PQfnumber (res ,"attcollation" );
80008012i_typrelid = PQfnumber (res ,"typrelid" );
80018013
@@ -8010,38 +8022,81 @@ dumpCompositeType(Archive *fout, TypeInfo *tyinfo)
80108022appendPQExpBuffer (q ,"CREATE TYPE %s AS (" ,
80118023fmtId (tyinfo -> dobj .name ));
80128024
8025+ actual_atts = 0 ;
80138026for (i = 0 ;i < ntups ;i ++ )
80148027{
80158028char * attname ;
80168029char * atttypdefn ;
8030+ char * attlen ;
8031+ char * attalign ;
8032+ bool attisdropped ;
80178033Oid attcollation ;
80188034
80198035attname = PQgetvalue (res ,i ,i_attname );
80208036atttypdefn = PQgetvalue (res ,i ,i_atttypdefn );
8037+ attlen = PQgetvalue (res ,i ,i_attlen );
8038+ attalign = PQgetvalue (res ,i ,i_attalign );
8039+ attisdropped = (PQgetvalue (res ,i ,i_attisdropped )[0 ]== 't' );
80218040attcollation = atooid (PQgetvalue (res ,i ,i_attcollation ));
80228041
8023- appendPQExpBuffer (q ,"\n\t%s %s" ,fmtId (attname ),atttypdefn );
8042+ if (attisdropped && !binary_upgrade )
8043+ continue ;
8044+
8045+ /* Format properly if not first attr */
8046+ if (actual_atts ++ > 0 )
8047+ appendPQExpBuffer (q ,"," );
8048+ appendPQExpBuffer (q ,"\n\t" );
80248049
8025- /* Add collation if not default for the column type */
8026- if (OidIsValid (attcollation ))
8050+ if (!attisdropped )
80278051{
8028- CollInfo * coll ;
8052+ appendPQExpBuffer ( q , "%s %s" , fmtId ( attname ), atttypdefn ) ;
80298053
8030- coll = findCollationByOid ( attcollation );
8031- if (coll )
8054+ /* Add collation if not default for the column type */
8055+ if (OidIsValid ( attcollation ) )
80328056{
8033- /* always schema-qualify, don't try to be smart */
8034- appendPQExpBuffer (q ," COLLATE %s." ,
8035- fmtId (coll -> dobj .namespace -> dobj .name ));
8036- appendPQExpBuffer (q ,"%s" ,
8037- fmtId (coll -> dobj .name ));
8057+ CollInfo * coll ;
8058+
8059+ coll = findCollationByOid (attcollation );
8060+ if (coll )
8061+ {
8062+ /* always schema-qualify, don't try to be smart */
8063+ appendPQExpBuffer (q ," COLLATE %s." ,
8064+ fmtId (coll -> dobj .namespace -> dobj .name ));
8065+ appendPQExpBuffer (q ,"%s" ,
8066+ fmtId (coll -> dobj .name ));
8067+ }
80388068}
80398069}
8040-
8041- if (i < ntups - 1 )
8042- appendPQExpBuffer (q ,"," );
8070+ else
8071+ {
8072+ /*
8073+ * This is a dropped attribute and we're in binary_upgrade mode.
8074+ * Insert a placeholder for it in the CREATE TYPE command, and
8075+ * set length and alignment with direct UPDATE to the catalogs
8076+ * afterwards. See similar code in dumpTableSchema().
8077+ */
8078+ appendPQExpBuffer (q ,"%s INTEGER /* dummy */" ,fmtId (attname ));
8079+
8080+ /* stash separately for insertion after the CREATE TYPE */
8081+ appendPQExpBuffer (dropped ,
8082+ "\n-- For binary upgrade, recreate dropped column.\n" );
8083+ appendPQExpBuffer (dropped ,"UPDATE pg_catalog.pg_attribute\n"
8084+ "SET attlen = %s, "
8085+ "attalign = '%s', attbyval = false\n"
8086+ "WHERE attname = " ,attlen ,attalign );
8087+ appendStringLiteralAH (dropped ,attname ,fout );
8088+ appendPQExpBuffer (dropped ,"\n AND attrelid = " );
8089+ appendStringLiteralAH (dropped ,fmtId (tyinfo -> dobj .name ),fout );
8090+ appendPQExpBuffer (dropped ,"::pg_catalog.regclass;\n" );
8091+
8092+ appendPQExpBuffer (dropped ,"ALTER TYPE %s " ,
8093+ fmtId (tyinfo -> dobj .name ));
8094+ appendPQExpBuffer (dropped ,"DROP ATTRIBUTE %s;\n" ,
8095+ fmtId (attname ));
8096+ }
80438097}
80448098appendPQExpBuffer (q ,"\n);\n" );
8099+ appendPQExpBufferStr (q ,dropped -> data );
80458100
80468101/*
80478102 * DROP must be fully qualified in case same name appears in pg_catalog
@@ -8077,6 +8132,7 @@ dumpCompositeType(Archive *fout, TypeInfo *tyinfo)
80778132
80788133PQclear (res );
80798134destroyPQExpBuffer (q );
8135+ destroyPQExpBuffer (dropped );
80808136destroyPQExpBuffer (delq );
80818137destroyPQExpBuffer (labelq );
80828138destroyPQExpBuffer (query );