@@ -5502,6 +5502,7 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
5502
5502
int i_attalign ;
5503
5503
int i_attislocal ;
5504
5504
int i_attoptions ;
5505
+ int i_attcollation ;
5505
5506
PGresult * res ;
5506
5507
int ntups ;
5507
5508
bool hasdefaults ;
@@ -5541,13 +5542,20 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
5541
5542
5542
5543
if (g_fout -> remoteVersion >= 90100 )
5543
5544
{
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
+ */
5545
5551
appendPQExpBuffer (q , "SELECT a.attnum, a.attname, a.atttypmod, "
5546
5552
"a.attstattarget, a.attstorage, t.typstorage, "
5547
5553
"a.attnotnull, a.atthasdef, a.attisdropped, "
5548
5554
"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 "
5551
5559
"FROM pg_catalog.pg_attribute a LEFT JOIN pg_catalog.pg_type t "
5552
5560
"ON a.atttypid = t.oid "
5553
5561
"WHERE a.attrelid = '%u'::pg_catalog.oid "
@@ -5563,7 +5571,8 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
5563
5571
"a.attnotnull, a.atthasdef, a.attisdropped, "
5564
5572
"a.attlen, a.attalign, a.attislocal, "
5565
5573
"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 "
5567
5576
"FROM pg_catalog.pg_attribute a LEFT JOIN pg_catalog.pg_type t "
5568
5577
"ON a.atttypid = t.oid "
5569
5578
"WHERE a.attrelid = '%u'::pg_catalog.oid "
@@ -5579,7 +5588,7 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
5579
5588
"a.attnotnull, a.atthasdef, a.attisdropped, "
5580
5589
"a.attlen, a.attalign, a.attislocal, "
5581
5590
"pg_catalog.format_type(t.oid,a.atttypmod) AS atttypname, "
5582
- "'' AS attoptions "
5591
+ "'' AS attoptions, 0 AS attcollation "
5583
5592
"FROM pg_catalog.pg_attribute a LEFT JOIN pg_catalog.pg_type t "
5584
5593
"ON a.atttypid = t.oid "
5585
5594
"WHERE a.attrelid = '%u'::pg_catalog.oid "
@@ -5600,7 +5609,7 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
5600
5609
"false AS attisdropped, a.attlen, "
5601
5610
"a.attalign, false AS attislocal, "
5602
5611
"format_type(t.oid,a.atttypmod) AS atttypname, "
5603
- "'' AS attoptions "
5612
+ "'' AS attoptions, 0 AS attcollation "
5604
5613
"FROM pg_attribute a LEFT JOIN pg_type t "
5605
5614
"ON a.atttypid = t.oid "
5606
5615
"WHERE a.attrelid = '%u'::oid "
@@ -5618,7 +5627,7 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
5618
5627
"attlen, attalign, "
5619
5628
"false AS attislocal, "
5620
5629
"(SELECT typname FROM pg_type WHERE oid = atttypid) AS atttypname, "
5621
- "'' AS attoptions "
5630
+ "'' AS attoptions, 0 AS attcollation "
5622
5631
"FROM pg_attribute a "
5623
5632
"WHERE attrelid = '%u'::oid "
5624
5633
"AND attnum > 0::int2 "
@@ -5645,6 +5654,7 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
5645
5654
i_attalign = PQfnumber (res , "attalign" );
5646
5655
i_attislocal = PQfnumber (res , "attislocal" );
5647
5656
i_attoptions = PQfnumber (res , "attoptions" );
5657
+ i_attcollation = PQfnumber (res , "attcollation" );
5648
5658
5649
5659
tbinfo -> numatts = ntups ;
5650
5660
tbinfo -> attnames = (char * * ) malloc (ntups * sizeof (char * ));
@@ -5660,6 +5670,7 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
5660
5670
tbinfo -> notnull = (bool * ) malloc (ntups * sizeof (bool ));
5661
5671
tbinfo -> attrdefs = (AttrDefInfo * * ) malloc (ntups * sizeof (AttrDefInfo * ));
5662
5672
tbinfo -> attoptions = (char * * ) malloc (ntups * sizeof (char * ));
5673
+ tbinfo -> attcollation = (Oid * ) malloc (ntups * sizeof (Oid ));
5663
5674
tbinfo -> inhAttrs = (bool * ) malloc (ntups * sizeof (bool ));
5664
5675
tbinfo -> inhAttrDef = (bool * ) malloc (ntups * sizeof (bool ));
5665
5676
tbinfo -> inhNotNull = (bool * ) malloc (ntups * sizeof (bool ));
@@ -5685,6 +5696,7 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
5685
5696
tbinfo -> attislocal [j ] = (PQgetvalue (res , j , i_attislocal )[0 ] == 't' );
5686
5697
tbinfo -> notnull [j ] = (PQgetvalue (res , j , i_attnotnull )[0 ] == 't' );
5687
5698
tbinfo -> attoptions [j ] = strdup (PQgetvalue (res , j , i_attoptions ));
5699
+ tbinfo -> attcollation [j ] = atooid (PQgetvalue (res , j , i_attcollation ));
5688
5700
tbinfo -> attrdefs [j ] = NULL ; /* fix below */
5689
5701
if (PQgetvalue (res , j , i_atthasdef )[0 ] == 't' )
5690
5702
hasdefaults = true;
@@ -7359,7 +7371,7 @@ dumpBaseType(Archive *fout, TypeInfo *tyinfo)
7359
7371
"typanalyze::pg_catalog.oid AS typanalyzeoid, "
7360
7372
"typcategory, typispreferred, "
7361
7373
"typdelim, typbyval, typalign, typstorage, "
7362
- "(typcollation = (SELECT oid FROM pg_catalog.pg_collation WHERE collname = 'default') ) AS typcollatable, "
7374
+ "(typcollation <> 0 ) AS typcollatable, "
7363
7375
"pg_catalog.pg_get_expr(typdefaultbin, 0) AS typdefaultbin, typdefault "
7364
7376
"FROM pg_catalog.pg_type "
7365
7377
"WHERE oid = '%u'::pg_catalog.oid" ,
@@ -7736,6 +7748,7 @@ dumpDomain(Archive *fout, TypeInfo *tyinfo)
7736
7748
char * typnotnull ;
7737
7749
char * typdefn ;
7738
7750
char * typdefault ;
7751
+ Oid typcollation ;
7739
7752
bool typdefault_is_literal = false;
7740
7753
7741
7754
/* Set proper schema search path so type references list correctly */
@@ -7745,11 +7758,14 @@ dumpDomain(Archive *fout, TypeInfo *tyinfo)
7745
7758
if (g_fout -> remoteVersion >= 90100 )
7746
7759
{
7747
7760
/* 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 "
7752
7767
"FROM pg_catalog.pg_type t "
7768
+ "LEFT JOIN pg_catalog.pg_type u ON (t.typbasetype = u.oid) "
7753
7769
"WHERE t.oid = '%u'::pg_catalog.oid" ,
7754
7770
tyinfo -> dobj .catId .oid );
7755
7771
}
@@ -7759,7 +7775,7 @@ dumpDomain(Archive *fout, TypeInfo *tyinfo)
7759
7775
appendPQExpBuffer (query , "SELECT typnotnull, "
7760
7776
"pg_catalog.format_type(typbasetype, typtypmod) AS typdefn, "
7761
7777
"pg_catalog.pg_get_expr(typdefaultbin, 'pg_catalog.pg_type'::pg_catalog.regclass) AS typdefaultbin, "
7762
- "typdefault "
7778
+ "typdefault, 0 AS typcollation "
7763
7779
"FROM pg_catalog.pg_type "
7764
7780
"WHERE oid = '%u'::pg_catalog.oid" ,
7765
7781
tyinfo -> dobj .catId .oid );
@@ -7790,6 +7806,7 @@ dumpDomain(Archive *fout, TypeInfo *tyinfo)
7790
7806
}
7791
7807
else
7792
7808
typdefault = NULL ;
7809
+ typcollation = atooid (PQgetvalue (res , 0 , PQfnumber (res , "typcollation" )));
7793
7810
7794
7811
if (binary_upgrade )
7795
7812
binary_upgrade_set_type_oids_by_type_oid (q , tyinfo -> dobj .catId .oid );
@@ -7799,6 +7816,22 @@ dumpDomain(Archive *fout, TypeInfo *tyinfo)
7799
7816
fmtId (tyinfo -> dobj .name ),
7800
7817
typdefn );
7801
7818
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
+
7802
7835
if (typnotnull [0 ] == 't' )
7803
7836
appendPQExpBuffer (q , " NOT NULL" );
7804
7837
@@ -11966,6 +11999,22 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
11966
11999
tbinfo -> atttypmod [j ]));
11967
12000
}
11968
12001
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
+
11969
12018
if (has_default )
11970
12019
appendPQExpBuffer (q , " DEFAULT %s" ,
11971
12020
tbinfo -> attrdefs [j ]-> adef_expr );
0 commit comments