@@ -5502,6 +5502,7 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
55025502 int i_attalign ;
55035503 int i_attislocal ;
55045504 int i_attoptions ;
5505+ int i_attcollation ;
55055506 PGresult * res ;
55065507 int ntups ;
55075508 bool hasdefaults ;
@@ -5541,13 +5542,20 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
55415542
55425543 if (g_fout -> remoteVersion >= 90100 )
55435544 {
5544- /* attcollation is new in 9.1 */
5545+ /*
5546+ * attcollation is new in 9.1. Since we only want to dump
5547+ * COLLATE clauses for attributes whose collation is different
5548+ * from their type's default, we use a CASE here to suppress
5549+ * uninteresting attcollations cheaply.
5550+ */
55455551 appendPQExpBuffer (q , "SELECT a.attnum, a.attname, a.atttypmod, "
55465552 "a.attstattarget, a.attstorage, t.typstorage, "
55475553 "a.attnotnull, a.atthasdef, a.attisdropped, "
55485554 "a.attlen, a.attalign, a.attislocal, "
5549- "pg_catalog.format_type(t.oid,a.atttypmod,a.attcollation) AS atttypname, "
5550- "array_to_string(attoptions, ', ') AS attoptions "
5555+ "pg_catalog.format_type(t.oid,a.atttypmod) AS atttypname, "
5556+ "array_to_string(a.attoptions, ', ') AS attoptions, "
5557+ "CASE WHEN a.attcollation <> t.typcollation "
5558+ "THEN a.attcollation ELSE 0 END AS attcollation "
55515559 "FROM pg_catalog.pg_attribute a LEFT JOIN pg_catalog.pg_type t "
55525560 "ON a.atttypid = t.oid "
55535561 "WHERE a.attrelid = '%u'::pg_catalog.oid "
@@ -5563,7 +5571,8 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
55635571 "a.attnotnull, a.atthasdef, a.attisdropped, "
55645572 "a.attlen, a.attalign, a.attislocal, "
55655573 "pg_catalog.format_type(t.oid,a.atttypmod) AS atttypname, "
5566- "array_to_string(attoptions, ', ') AS attoptions "
5574+ "array_to_string(a.attoptions, ', ') AS attoptions, "
5575+ "0 AS attcollation "
55675576 "FROM pg_catalog.pg_attribute a LEFT JOIN pg_catalog.pg_type t "
55685577 "ON a.atttypid = t.oid "
55695578 "WHERE a.attrelid = '%u'::pg_catalog.oid "
@@ -5579,7 +5588,7 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
55795588 "a.attnotnull, a.atthasdef, a.attisdropped, "
55805589 "a.attlen, a.attalign, a.attislocal, "
55815590 "pg_catalog.format_type(t.oid,a.atttypmod) AS atttypname, "
5582- "'' AS attoptions "
5591+ "'' AS attoptions, 0 AS attcollation "
55835592 "FROM pg_catalog.pg_attribute a LEFT JOIN pg_catalog.pg_type t "
55845593 "ON a.atttypid = t.oid "
55855594 "WHERE a.attrelid = '%u'::pg_catalog.oid "
@@ -5600,7 +5609,7 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
56005609 "false AS attisdropped, a.attlen, "
56015610 "a.attalign, false AS attislocal, "
56025611 "format_type(t.oid,a.atttypmod) AS atttypname, "
5603- "'' AS attoptions "
5612+ "'' AS attoptions, 0 AS attcollation "
56045613 "FROM pg_attribute a LEFT JOIN pg_type t "
56055614 "ON a.atttypid = t.oid "
56065615 "WHERE a.attrelid = '%u'::oid "
@@ -5618,7 +5627,7 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
56185627 "attlen, attalign, "
56195628 "false AS attislocal, "
56205629 "(SELECT typname FROM pg_type WHERE oid = atttypid) AS atttypname, "
5621- "'' AS attoptions "
5630+ "'' AS attoptions, 0 AS attcollation "
56225631 "FROM pg_attribute a "
56235632 "WHERE attrelid = '%u'::oid "
56245633 "AND attnum > 0::int2 "
@@ -5645,6 +5654,7 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
56455654 i_attalign = PQfnumber (res , "attalign" );
56465655 i_attislocal = PQfnumber (res , "attislocal" );
56475656 i_attoptions = PQfnumber (res , "attoptions" );
5657+ i_attcollation = PQfnumber (res , "attcollation" );
56485658
56495659 tbinfo -> numatts = ntups ;
56505660 tbinfo -> attnames = (char * * ) malloc (ntups * sizeof (char * ));
@@ -5660,6 +5670,7 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
56605670 tbinfo -> notnull = (bool * ) malloc (ntups * sizeof (bool ));
56615671 tbinfo -> attrdefs = (AttrDefInfo * * ) malloc (ntups * sizeof (AttrDefInfo * ));
56625672 tbinfo -> attoptions = (char * * ) malloc (ntups * sizeof (char * ));
5673+ tbinfo -> attcollation = (Oid * ) malloc (ntups * sizeof (Oid ));
56635674 tbinfo -> inhAttrs = (bool * ) malloc (ntups * sizeof (bool ));
56645675 tbinfo -> inhAttrDef = (bool * ) malloc (ntups * sizeof (bool ));
56655676 tbinfo -> inhNotNull = (bool * ) malloc (ntups * sizeof (bool ));
@@ -5685,6 +5696,7 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
56855696 tbinfo -> attislocal [j ] = (PQgetvalue (res , j , i_attislocal )[0 ] == 't' );
56865697 tbinfo -> notnull [j ] = (PQgetvalue (res , j , i_attnotnull )[0 ] == 't' );
56875698 tbinfo -> attoptions [j ] = strdup (PQgetvalue (res , j , i_attoptions ));
5699+ tbinfo -> attcollation [j ] = atooid (PQgetvalue (res , j , i_attcollation ));
56885700 tbinfo -> attrdefs [j ] = NULL ; /* fix below */
56895701 if (PQgetvalue (res , j , i_atthasdef )[0 ] == 't' )
56905702 hasdefaults = true;
@@ -7359,7 +7371,7 @@ dumpBaseType(Archive *fout, TypeInfo *tyinfo)
73597371 "typanalyze::pg_catalog.oid AS typanalyzeoid, "
73607372 "typcategory, typispreferred, "
73617373 "typdelim, typbyval, typalign, typstorage, "
7362- "(typcollation = (SELECT oid FROM pg_catalog.pg_collation WHERE collname = 'default') ) AS typcollatable, "
7374+ "(typcollation <> 0 ) AS typcollatable, "
73637375 "pg_catalog.pg_get_expr(typdefaultbin, 0) AS typdefaultbin, typdefault "
73647376 "FROM pg_catalog.pg_type "
73657377 "WHERE oid = '%u'::pg_catalog.oid" ,
@@ -7736,6 +7748,7 @@ dumpDomain(Archive *fout, TypeInfo *tyinfo)
77367748 char * typnotnull ;
77377749 char * typdefn ;
77387750 char * typdefault ;
7751+ Oid typcollation ;
77397752 bool typdefault_is_literal = false;
77407753
77417754 /* Set proper schema search path so type references list correctly */
@@ -7745,11 +7758,14 @@ dumpDomain(Archive *fout, TypeInfo *tyinfo)
77457758 if (g_fout -> remoteVersion >= 90100 )
77467759 {
77477760 /* typcollation is new in 9.1 */
7748- appendPQExpBuffer (query , "SELECT typnotnull, "
7749- "pg_catalog.format_type(typbasetype, typtypmod, typcollation) AS typdefn, "
7750- "pg_catalog.pg_get_expr(typdefaultbin, 'pg_catalog.pg_type'::pg_catalog.regclass) AS typdefaultbin, "
7751- "typdefault "
7761+ appendPQExpBuffer (query , "SELECT t.typnotnull, "
7762+ "pg_catalog.format_type(t.typbasetype, t.typtypmod) AS typdefn, "
7763+ "pg_catalog.pg_get_expr(t.typdefaultbin, 'pg_catalog.pg_type'::pg_catalog.regclass) AS typdefaultbin, "
7764+ "t.typdefault, "
7765+ "CASE WHEN t.typcollation <> u.typcollation "
7766+ "THEN t.typcollation ELSE 0 END AS typcollation "
77527767 "FROM pg_catalog.pg_type t "
7768+ "LEFT JOIN pg_catalog.pg_type u ON (t.typbasetype = u.oid) "
77537769 "WHERE t.oid = '%u'::pg_catalog.oid" ,
77547770 tyinfo -> dobj .catId .oid );
77557771 }
@@ -7759,7 +7775,7 @@ dumpDomain(Archive *fout, TypeInfo *tyinfo)
77597775 appendPQExpBuffer (query , "SELECT typnotnull, "
77607776 "pg_catalog.format_type(typbasetype, typtypmod) AS typdefn, "
77617777 "pg_catalog.pg_get_expr(typdefaultbin, 'pg_catalog.pg_type'::pg_catalog.regclass) AS typdefaultbin, "
7762- "typdefault "
7778+ "typdefault, 0 AS typcollation "
77637779 "FROM pg_catalog.pg_type "
77647780 "WHERE oid = '%u'::pg_catalog.oid" ,
77657781 tyinfo -> dobj .catId .oid );
@@ -7790,6 +7806,7 @@ dumpDomain(Archive *fout, TypeInfo *tyinfo)
77907806 }
77917807 else
77927808 typdefault = NULL ;
7809+ typcollation = atooid (PQgetvalue (res , 0 , PQfnumber (res , "typcollation" )));
77937810
77947811 if (binary_upgrade )
77957812 binary_upgrade_set_type_oids_by_type_oid (q , tyinfo -> dobj .catId .oid );
@@ -7799,6 +7816,22 @@ dumpDomain(Archive *fout, TypeInfo *tyinfo)
77997816 fmtId (tyinfo -> dobj .name ),
78007817 typdefn );
78017818
7819+ /* Print collation only if different from base type's collation */
7820+ if (OidIsValid (typcollation ))
7821+ {
7822+ CollInfo * coll ;
7823+
7824+ coll = findCollationByOid (typcollation );
7825+ if (coll )
7826+ {
7827+ /* always schema-qualify, don't try to be smart */
7828+ appendPQExpBuffer (q , " COLLATE %s." ,
7829+ fmtId (coll -> dobj .namespace -> dobj .name ));
7830+ appendPQExpBuffer (q , "%s" ,
7831+ fmtId (coll -> dobj .name ));
7832+ }
7833+ }
7834+
78027835 if (typnotnull [0 ] == 't' )
78037836 appendPQExpBuffer (q , " NOT NULL" );
78047837
@@ -11966,6 +11999,22 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
1196611999 tbinfo -> atttypmod [j ]));
1196712000 }
1196812001
12002+ /* Add collation if not default for the type */
12003+ if (OidIsValid (tbinfo -> attcollation [j ]))
12004+ {
12005+ CollInfo * coll ;
12006+
12007+ coll = findCollationByOid (tbinfo -> attcollation [j ]);
12008+ if (coll )
12009+ {
12010+ /* always schema-qualify, don't try to be smart */
12011+ appendPQExpBuffer (q , " COLLATE %s." ,
12012+ fmtId (coll -> dobj .namespace -> dobj .name ));
12013+ appendPQExpBuffer (q , "%s" ,
12014+ fmtId (coll -> dobj .name ));
12015+ }
12016+ }
12017+
1196912018 if (has_default )
1197012019 appendPQExpBuffer (q , " DEFAULT %s" ,
1197112020 tbinfo -> attrdefs [j ]-> adef_expr );
0 commit comments