Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 7564654

Browse files
committed
Revert addition of third argument to format_type().
Including collation in the behavior of that function promotes a world view we do not want. Moreover, it was producing the wrong behavior for pg_dump anyway: what we want is to dump a COLLATE clause on attributes whose attcollation is different from the underlying type, and likewise for domains, and the function cannot do that for us. Doing it the hard way in pg_dump is a bit more tedious but produces more correct output. In passing, fix initdb so that the initial entry in pg_collation is properly pinned. It was droppable before :-(
1 parent 551c07d commit 7564654

File tree

9 files changed

+92
-43
lines changed

9 files changed

+92
-43
lines changed

doc/src/sgml/func.sgml

+2-4
Original file line numberDiff line numberDiff line change
@@ -13269,7 +13269,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype);
1326913269

1327013270
<tbody>
1327113271
<row>
13272-
<entry><literal><function>format_type(<parameter>type_oid</parameter> [, <parameter>typemod</> [, <parameter>collation_oid</> ]])</function></literal></entry>
13272+
<entry><literal><function>format_type(<parameter>type_oid</parameter>, <parameter>typemod</>)</function></literal></entry>
1327313273
<entry><type>text</type></entry>
1327413274
<entry>get SQL name of a data type</entry>
1327513275
</row>
@@ -13410,9 +13410,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype);
1341013410
<para>
1341113411
<function>format_type</function> returns the SQL name of a data type that
1341213412
is identified by its type OID and possibly a type modifier. Pass NULL
13413-
for the type modifier or omit the argument if no specific modifier is known.
13414-
If a collation is given as third argument, a <literal>COLLATE</> clause
13415-
followed by a formatted collation name is appended.
13413+
for the type modifier if no specific modifier is known.
1341613414
</para>
1341713415

1341813416
<para>

src/backend/catalog/system_views.sql

-4
Original file line numberDiff line numberDiff line change
@@ -693,10 +693,6 @@ COMMENT ON FUNCTION ts_debug(text) IS
693693
-- to get filled in.)
694694
--
695695

696-
CREATE OR REPLACE FUNCTION
697-
format_type(oid, int DEFAULT NULL, oid DEFAULT NULL)
698-
RETURNS text STABLE LANGUAGE internal AS 'format_type';
699-
700696
CREATE OR REPLACE FUNCTION
701697
pg_start_backup(label text, fast boolean DEFAULT false)
702698
RETURNS text STRICT VOLATILE LANGUAGE internal AS 'pg_start_backup';

src/backend/utils/adt/format_type.c

+7-18
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
#include <ctype.h>
1919

2020
#include "catalog/namespace.h"
21-
#include "catalog/pg_collation.h"
2221
#include "catalog/pg_type.h"
2322
#include "utils/builtins.h"
2423
#include "utils/lsyscache.h"
@@ -29,8 +28,7 @@
2928
#define MAX_INT32_LEN 11
3029

3130
static char *format_type_internal(Oid type_oid, int32 typemod,
32-
bool typemod_given, bool allow_invalid,
33-
Oid collation_oid);
31+
bool typemod_given, bool allow_invalid);
3432
static char *printTypmod(const char *typname, int32 typmod, Oid typmodout);
3533
static char *
3634
psnprintf(size_t len, const char *fmt,...)
@@ -69,22 +67,20 @@ format_type(PG_FUNCTION_ARGS)
6967
{
7068
Oid type_oid;
7169
int32 typemod;
72-
Oid collation_oid;
7370
char *result;
7471

7572
/* Since this function is not strict, we must test for null args */
7673
if (PG_ARGISNULL(0))
7774
PG_RETURN_NULL();
7875

7976
type_oid = PG_GETARG_OID(0);
80-
collation_oid = PG_ARGISNULL(2) ? InvalidOid : PG_GETARG_OID(2);
8177

8278
if (PG_ARGISNULL(1))
83-
result = format_type_internal(type_oid, -1, false, true, collation_oid);
79+
result = format_type_internal(type_oid, -1, false, true);
8480
else
8581
{
8682
typemod = PG_GETARG_INT32(1);
87-
result = format_type_internal(type_oid, typemod, true, true, collation_oid);
83+
result = format_type_internal(type_oid, typemod, true, true);
8884
}
8985

9086
PG_RETURN_TEXT_P(cstring_to_text(result));
@@ -99,7 +95,7 @@ format_type(PG_FUNCTION_ARGS)
9995
char *
10096
format_type_be(Oid type_oid)
10197
{
102-
return format_type_internal(type_oid, -1, false, false, InvalidOid);
98+
return format_type_internal(type_oid, -1, false, false);
10399
}
104100

105101
/*
@@ -108,15 +104,14 @@ format_type_be(Oid type_oid)
108104
char *
109105
format_type_with_typemod(Oid type_oid, int32 typemod)
110106
{
111-
return format_type_internal(type_oid, typemod, true, false, InvalidOid);
107+
return format_type_internal(type_oid, typemod, true, false);
112108
}
113109

114110

115111

116112
static char *
117113
format_type_internal(Oid type_oid, int32 typemod,
118-
bool typemod_given, bool allow_invalid,
119-
Oid collation_oid)
114+
bool typemod_given, bool allow_invalid)
120115
{
121116
bool with_typemod = typemod_given && (typemod >= 0);
122117
HeapTuple tuple;
@@ -322,12 +317,6 @@ format_type_internal(Oid type_oid, int32 typemod,
322317

323318
ReleaseSysCache(tuple);
324319

325-
if (collation_oid && collation_oid != DEFAULT_COLLATION_OID)
326-
{
327-
char *collstr = generate_collation_name(collation_oid);
328-
buf = psnprintf(strlen(buf) + 10 + strlen(collstr), "%s COLLATE %s", buf, collstr);
329-
}
330-
331320
return buf;
332321
}
333322

@@ -431,7 +420,7 @@ oidvectortypes(PG_FUNCTION_ARGS)
431420
for (num = 0; num < numargs; num++)
432421
{
433422
char *typename = format_type_internal(oidArray->values[num], -1,
434-
false, true, InvalidOid);
423+
false, true);
435424
size_t slen = strlen(typename);
436425

437426
if (left < (slen + 2))

src/bin/initdb/initdb.c

+2
Original file line numberDiff line numberDiff line change
@@ -1388,6 +1388,8 @@ setup_depend(void)
13881388
" FROM pg_ts_template;\n",
13891389
"INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
13901390
" FROM pg_ts_config;\n",
1391+
"INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
1392+
" FROM pg_collation;\n",
13911393
"INSERT INTO pg_shdepend SELECT 0,0,0,0, tableoid,oid, 'p' "
13921394
" FROM pg_authid;\n",
13931395
NULL

src/bin/pg_dump/common.c

+14-1
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,12 @@ static int numTables;
5454
static int numTypes;
5555
static int numFuncs;
5656
static int numOperators;
57+
static int numCollations;
5758
static DumpableObject **tblinfoindex;
5859
static DumpableObject **typinfoindex;
5960
static DumpableObject **funinfoindex;
6061
static DumpableObject **oprinfoindex;
62+
static DumpableObject **collinfoindex;
6163

6264

6365
static void flagInhTables(TableInfo *tbinfo, int numTables,
@@ -105,7 +107,6 @@ getSchemaData(int *numTablesPtr)
105107
int numCasts;
106108
int numOpclasses;
107109
int numOpfamilies;
108-
int numCollations;
109110
int numConversions;
110111
int numTSParsers;
111112
int numTSTemplates;
@@ -187,6 +188,7 @@ getSchemaData(int *numTablesPtr)
187188
if (g_verbose)
188189
write_msg(NULL, "reading user-defined collations\n");
189190
collinfo = getCollations(&numCollations);
191+
collinfoindex = buildIndexArray(collinfo, numCollations, sizeof(CollInfo));
190192

191193
if (g_verbose)
192194
write_msg(NULL, "reading user-defined conversions\n");
@@ -784,6 +786,17 @@ findOprByOid(Oid oid)
784786
return (OprInfo *) findObjectByOid(oid, oprinfoindex, numOperators);
785787
}
786788

789+
/*
790+
* findCollationByOid
791+
* finds the entry (in collinfo) of the collation with the given oid
792+
* returns NULL if not found
793+
*/
794+
CollInfo *
795+
findCollationByOid(Oid oid)
796+
{
797+
return (CollInfo *) findObjectByOid(oid, collinfoindex, numCollations);
798+
}
799+
787800

788801
/*
789802
* findParentsByOid

src/bin/pg_dump/pg_dump.c

+62-13
Original file line numberDiff line numberDiff line change
@@ -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);

src/bin/pg_dump/pg_dump.h

+2
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,7 @@ typedef struct _tableInfo
272272
char *attalign; /* attribute align, used by binary_upgrade */
273273
bool *attislocal; /* true if attr has local definition */
274274
char **attoptions; /* per-attribute options */
275+
Oid *attcollation; /* per-attribute collation selection */
275276

276277
/*
277278
* Note: we need to store per-attribute notnull, default, and constraint
@@ -510,6 +511,7 @@ extern TableInfo *findTableByOid(Oid oid);
510511
extern TypeInfo *findTypeByOid(Oid oid);
511512
extern FuncInfo *findFuncByOid(Oid oid);
512513
extern OprInfo *findOprByOid(Oid oid);
514+
extern CollInfo *findCollationByOid(Oid oid);
513515

514516
extern void simple_oid_list_append(SimpleOidList *list, Oid val);
515517
extern void simple_string_list_append(SimpleStringList *list, const char *val);

src/include/catalog/catversion.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,6 @@
5353
*/
5454

5555
/* yyyymmddN */
56-
#define CATALOG_VERSION_NO 201103061
56+
#define CATALOG_VERSION_NO 201103101
5757

5858
#endif

0 commit comments

Comments
 (0)