Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit586b98f

Browse files
committed
Make type "name" collation-aware.
The "name" comparison operators now all support collations, making themfunctionally equivalent to "text" comparisons, except for the differentphysical representation of the datatype. They do, in fact, mostly sharethe varstr_cmp and varstr_sortsupport infrastructure, which has beenslightly enlarged to handle the case.To avoid changes in the default behavior of the datatype, set name'stypcollation to C_COLLATION_OID not DEFAULT_COLLATION_OID, so thatby default comparisons to a name value will continue to use strcmpsemantics. (This would have been the case for system catalog columnsanyway, because of commit6b0faf7, but doing this makes it true foruser-created name columns as well. In particular, this avoidslocale-dependent changes in our regression test results.)In consequence, tweak a couple of places that made assumptions aboutcollatable base types always having typcollation DEFAULT_COLLATION_OID.I have not, however, attempted to relax the restriction that user-defined collatable types must have that. Hence, "name" doesn'tbehave quite like a user-defined type; it acts more like a domainwith COLLATE "C". (Conceivably, if we ever get rid of the need forcatalog name columns to be fixed-length, "name" could actually becomesuch a domain over text. But that'd be a pretty massive undertaking,and I'm not volunteering.)Discussion:https://postgr.es/m/15938.1544377821@sss.pgh.pa.us
1 parent68f6f2b commit586b98f

File tree

16 files changed

+211
-125
lines changed

16 files changed

+211
-125
lines changed

‎doc/src/sgml/catalogs.sgml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7866,10 +7866,10 @@ SCRAM-SHA-256$<replaceable>&lt;iteration count&gt;</replaceable>:<replaceable>&l
78667866
<entry><para>
78677867
<structfield>typcollation</structfield> specifies the collation
78687868
of the type. If the type does not support collations, this will
7869-
be zero. A base type that supports collations will have
7870-
<symbol>DEFAULT_COLLATION_OID</symbol> here. A domain over a
7871-
collatable type can havesome othercollation OID, if one was
7872-
specified for the domain.
7869+
be zero. A base type that supports collations will have a nonzero
7870+
value here, typically<symbol>DEFAULT_COLLATION_OID</symbol>.
7871+
A domain over acollatable type can haveacollation OID different
7872+
from its base type's, if one wasspecified for the domain.
78737873
</para></entry>
78747874
</row>
78757875

‎src/backend/access/nbtree/nbtcompare.c

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -333,30 +333,3 @@ btcharcmp(PG_FUNCTION_ARGS)
333333
/* Be careful to compare chars as unsigned */
334334
PG_RETURN_INT32((int32) ((uint8)a)- (int32) ((uint8)b));
335335
}
336-
337-
Datum
338-
btnamecmp(PG_FUNCTION_ARGS)
339-
{
340-
Namea=PG_GETARG_NAME(0);
341-
Nameb=PG_GETARG_NAME(1);
342-
343-
PG_RETURN_INT32(strncmp(NameStr(*a),NameStr(*b),NAMEDATALEN));
344-
}
345-
346-
staticint
347-
btnamefastcmp(Datumx,Datumy,SortSupportssup)
348-
{
349-
Namea=DatumGetName(x);
350-
Nameb=DatumGetName(y);
351-
352-
returnstrncmp(NameStr(*a),NameStr(*b),NAMEDATALEN);
353-
}
354-
355-
Datum
356-
btnamesortsupport(PG_FUNCTION_ARGS)
357-
{
358-
SortSupportssup= (SortSupport)PG_GETARG_POINTER(0);
359-
360-
ssup->comparator=btnamefastcmp;
361-
PG_RETURN_VOID();
362-
}

‎src/backend/bootstrap/bootstrap.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ static const struct typinfo TypInfo[] = {
111111
F_INT4IN,F_INT4OUT},
112112
{"float4",FLOAT4OID,0,4,FLOAT4PASSBYVAL,'i','p',InvalidOid,
113113
F_FLOAT4IN,F_FLOAT4OUT},
114-
{"name",NAMEOID,CHAROID,NAMEDATALEN, false,'c','p',InvalidOid,
114+
{"name",NAMEOID,CHAROID,NAMEDATALEN, false,'c','p',C_COLLATION_OID,
115115
F_NAMEIN,F_NAMEOUT},
116116
{"regclass",REGCLASSOID,0,4, true,'i','p',InvalidOid,
117117
F_REGCLASSIN,F_REGCLASSOUT},

‎src/backend/commands/explain.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
#include"postgres.h"
1515

1616
#include"access/xact.h"
17-
#include"catalog/pg_collation.h"
1817
#include"catalog/pg_type.h"
1918
#include"commands/createas.h"
2019
#include"commands/defrem.h"
@@ -2347,11 +2346,13 @@ show_sortorder_options(StringInfo buf, Node *sortexpr,
23472346
TYPECACHE_LT_OPR |TYPECACHE_GT_OPR);
23482347

23492348
/*
2350-
* Print COLLATE if it's not default. There are some cases where this is
2351-
* redundant, eg if expression is a column whose declared collation is
2352-
* that collation, but it's hard to distinguish that here.
2349+
* Print COLLATE if it's not default for the column's type. There are
2350+
* some cases where this is redundant, eg if expression is a column whose
2351+
* declared collation is that collation, but it's hard to distinguish that
2352+
* here (and arguably, printing COLLATE explicitly is a good idea anyway
2353+
* in such cases).
23532354
*/
2354-
if (OidIsValid(collation)&&collation!=DEFAULT_COLLATION_OID)
2355+
if (OidIsValid(collation)&&collation!=get_typcollation(sortcoltype))
23552356
{
23562357
char*collname=get_collation_name(collation);
23572358

‎src/backend/nodes/nodeFuncs.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -862,7 +862,11 @@ exprCollation(const Node *expr)
862862
coll= ((constMinMaxExpr*)expr)->minmaxcollid;
863863
break;
864864
caseT_SQLValueFunction:
865-
coll=InvalidOid;/* all cases return non-collatable types */
865+
/* Returns either NAME or a non-collatable type */
866+
if (((constSQLValueFunction*)expr)->type==NAMEOID)
867+
coll=C_COLLATION_OID;
868+
else
869+
coll=InvalidOid;
866870
break;
867871
caseT_XmlExpr:
868872

@@ -1075,7 +1079,9 @@ exprSetCollation(Node *expr, Oid collation)
10751079
((MinMaxExpr*)expr)->minmaxcollid=collation;
10761080
break;
10771081
caseT_SQLValueFunction:
1078-
Assert(!OidIsValid(collation));/* no collatable results */
1082+
Assert((((SQLValueFunction*)expr)->type==NAMEOID) ?
1083+
(collation==C_COLLATION_OID) :
1084+
(collation==InvalidOid));
10791085
break;
10801086
caseT_XmlExpr:
10811087
Assert((((XmlExpr*)expr)->op==IS_XMLSERIALIZE) ?

‎src/backend/optimizer/path/indxpath.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4344,7 +4344,7 @@ string_to_const(const char *str, Oid datatype)
43444344
break;
43454345

43464346
caseNAMEOID:
4347-
collation=InvalidOid;
4347+
collation=C_COLLATION_OID;
43484348
constlen=NAMEDATALEN;
43494349
break;
43504350

‎src/backend/parser/parse_clause.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -788,7 +788,7 @@ transformRangeTableFunc(ParseState *pstate, RangeTableFunc *rtf)
788788
tf->coltypes=lappend_oid(tf->coltypes,typid);
789789
tf->coltypmods=lappend_int(tf->coltypmods,typmod);
790790
tf->colcollations=lappend_oid(tf->colcollations,
791-
type_is_collatable(typid) ?DEFAULT_COLLATION_OID :InvalidOid);
791+
get_typcollation(typid));
792792

793793
/* Transform the PATH and DEFAULT expressions */
794794
if (rawc->colexpr)

‎src/backend/utils/adt/name.c

Lines changed: 61 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,15 @@
2121
#include"postgres.h"
2222

2323
#include"catalog/namespace.h"
24+
#include"catalog/pg_collation.h"
2425
#include"catalog/pg_type.h"
2526
#include"libpq/pqformat.h"
2627
#include"mb/pg_wchar.h"
2728
#include"miscadmin.h"
2829
#include"utils/array.h"
2930
#include"utils/builtins.h"
3031
#include"utils/lsyscache.h"
32+
#include"utils/varlena.h"
3133

3234

3335
/*****************************************************************************
@@ -113,29 +115,29 @@ namesend(PG_FUNCTION_ARGS)
113115

114116

115117
/*****************************************************************************
116-
*PUBLIC ROUTINES *
118+
*COMPARISON/SORTING ROUTINES *
117119
*****************************************************************************/
118120

119121
/*
120122
*nameeq- returns 1 iff arguments are equal
121123
*namene- returns 1 iff arguments are not equal
122-
*
123-
*BUGS:
124-
*Assumes that "xy\0\0a" should be equal to "xy\0b".
125-
*If not, can do the comparison backwards for efficiency.
126-
*
127124
*namelt- returns 1 iff a < b
128125
*namele- returns 1 iff a <= b
129126
*namegt- returns 1 iff a > b
130127
*namege- returns 1 iff a >= b
131128
*
129+
* Note that the use of strncmp with NAMEDATALEN limit is mostly historical;
130+
* strcmp would do as well, because we do not allow NAME values that don't
131+
* have a '\0' terminator. Whatever might be past the terminator is not
132+
* considered relevant to comparisons.
132133
*/
133134
Datum
134135
nameeq(PG_FUNCTION_ARGS)
135136
{
136137
Namearg1=PG_GETARG_NAME(0);
137138
Namearg2=PG_GETARG_NAME(1);
138139

140+
/* Collation doesn't matter: equal only if bitwise-equal */
139141
PG_RETURN_BOOL(strncmp(NameStr(*arg1),NameStr(*arg2),NAMEDATALEN)==0);
140142
}
141143

@@ -145,16 +147,30 @@ namene(PG_FUNCTION_ARGS)
145147
Namearg1=PG_GETARG_NAME(0);
146148
Namearg2=PG_GETARG_NAME(1);
147149

150+
/* Collation doesn't matter: equal only if bitwise-equal */
148151
PG_RETURN_BOOL(strncmp(NameStr(*arg1),NameStr(*arg2),NAMEDATALEN)!=0);
149152
}
150153

154+
staticint
155+
namecmp(Namearg1,Namearg2,Oidcollid)
156+
{
157+
/* Fast path for common case used in system catalogs */
158+
if (collid==C_COLLATION_OID)
159+
returnstrncmp(NameStr(*arg1),NameStr(*arg2),NAMEDATALEN);
160+
161+
/* Else rely on the varstr infrastructure */
162+
returnvarstr_cmp(NameStr(*arg1),strlen(NameStr(*arg1)),
163+
NameStr(*arg2),strlen(NameStr(*arg2)),
164+
collid);
165+
}
166+
151167
Datum
152168
namelt(PG_FUNCTION_ARGS)
153169
{
154170
Namearg1=PG_GETARG_NAME(0);
155171
Namearg2=PG_GETARG_NAME(1);
156172

157-
PG_RETURN_BOOL(strncmp(NameStr(*arg1),NameStr(*arg2),NAMEDATALEN)<0);
173+
PG_RETURN_BOOL(namecmp(arg1,arg2,PG_GET_COLLATION())<0);
158174
}
159175

160176
Datum
@@ -163,7 +179,7 @@ namele(PG_FUNCTION_ARGS)
163179
Namearg1=PG_GETARG_NAME(0);
164180
Namearg2=PG_GETARG_NAME(1);
165181

166-
PG_RETURN_BOOL(strncmp(NameStr(*arg1),NameStr(*arg2),NAMEDATALEN) <=0);
182+
PG_RETURN_BOOL(namecmp(arg1,arg2,PG_GET_COLLATION()) <=0);
167183
}
168184

169185
Datum
@@ -172,7 +188,7 @@ namegt(PG_FUNCTION_ARGS)
172188
Namearg1=PG_GETARG_NAME(0);
173189
Namearg2=PG_GETARG_NAME(1);
174190

175-
PG_RETURN_BOOL(strncmp(NameStr(*arg1),NameStr(*arg2),NAMEDATALEN)>0);
191+
PG_RETURN_BOOL(namecmp(arg1,arg2,PG_GET_COLLATION())>0);
176192
}
177193

178194
Datum
@@ -181,11 +197,39 @@ namege(PG_FUNCTION_ARGS)
181197
Namearg1=PG_GETARG_NAME(0);
182198
Namearg2=PG_GETARG_NAME(1);
183199

184-
PG_RETURN_BOOL(strncmp(NameStr(*arg1),NameStr(*arg2),NAMEDATALEN) >=0);
200+
PG_RETURN_BOOL(namecmp(arg1,arg2,PG_GET_COLLATION()) >=0);
201+
}
202+
203+
Datum
204+
btnamecmp(PG_FUNCTION_ARGS)
205+
{
206+
Namearg1=PG_GETARG_NAME(0);
207+
Namearg2=PG_GETARG_NAME(1);
208+
209+
PG_RETURN_INT32(namecmp(arg1,arg2,PG_GET_COLLATION()));
185210
}
186211

212+
Datum
213+
btnamesortsupport(PG_FUNCTION_ARGS)
214+
{
215+
SortSupportssup= (SortSupport)PG_GETARG_POINTER(0);
216+
Oidcollid=ssup->ssup_collation;
217+
MemoryContextoldcontext;
218+
219+
oldcontext=MemoryContextSwitchTo(ssup->ssup_cxt);
220+
221+
/* Use generic string SortSupport */
222+
varstr_sortsupport(ssup,NAMEOID,collid);
187223

188-
/* (see char.c for comparison/operation routines) */
224+
MemoryContextSwitchTo(oldcontext);
225+
226+
PG_RETURN_VOID();
227+
}
228+
229+
230+
/*****************************************************************************
231+
* MISCELLANEOUS PUBLIC ROUTINES *
232+
*****************************************************************************/
189233

190234
int
191235
namecpy(Namen1,constNameData*n2)
@@ -204,14 +248,6 @@ namecat(Name n1, Name n2)
204248
}
205249
#endif
206250

207-
#ifdefNOT_USED
208-
int
209-
namecmp(Namen1,Namen2)
210-
{
211-
returnstrncmp(NameStr(*n1),NameStr(*n2),NAMEDATALEN);
212-
}
213-
#endif
214-
215251
int
216252
namestrcpy(Namename,constchar*str)
217253
{
@@ -243,6 +279,12 @@ namestrcat(Name name, const char *str)
243279
}
244280
#endif
245281

282+
/*
283+
* Compare a NAME to a C string
284+
*
285+
* Assumes C collation always; be careful when using this for
286+
* anything but equality checks!
287+
*/
246288
int
247289
namestrcmp(Namename,constchar*str)
248290
{

‎src/backend/utils/adt/selfuncs.c

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6341,23 +6341,16 @@ make_greater_string(const Const *str_const, FmgrInfo *ltproc, Oid collation)
63416341
char*workstr;
63426342
intlen;
63436343
Datumcmpstr;
6344-
text*cmptxt=NULL;
6344+
char*cmptxt=NULL;
63456345
mbcharacter_incrementercharinc;
63466346

63476347
/*
63486348
* Get a modifiable copy of the prefix string in C-string format, and set
63496349
* up the string we will compare to as a Datum. In C locale this can just
6350-
* be the given prefix string, otherwise we need to add a suffix.Types
6351-
*NAME andBYTEAsort bytewise sothey don't need a suffix either.
6350+
* be the given prefix string, otherwise we need to add a suffix.Type
6351+
* BYTEAsorts bytewise soit never needs a suffix either.
63526352
*/
6353-
if (datatype==NAMEOID)
6354-
{
6355-
workstr=DatumGetCString(DirectFunctionCall1(nameout,
6356-
str_const->constvalue));
6357-
len=strlen(workstr);
6358-
cmpstr=str_const->constvalue;
6359-
}
6360-
elseif (datatype==BYTEAOID)
6353+
if (datatype==BYTEAOID)
63616354
{
63626355
bytea*bstr=DatumGetByteaPP(str_const->constvalue);
63636356

@@ -6369,7 +6362,11 @@ make_greater_string(const Const *str_const, FmgrInfo *ltproc, Oid collation)
63696362
}
63706363
else
63716364
{
6372-
workstr=TextDatumGetCString(str_const->constvalue);
6365+
if (datatype==NAMEOID)
6366+
workstr=DatumGetCString(DirectFunctionCall1(nameout,
6367+
str_const->constvalue));
6368+
else
6369+
workstr=TextDatumGetCString(str_const->constvalue);
63736370
len=strlen(workstr);
63746371
if (lc_collate_is_c(collation)||len==0)
63756372
cmpstr=str_const->constvalue;
@@ -6395,11 +6392,22 @@ make_greater_string(const Const *str_const, FmgrInfo *ltproc, Oid collation)
63956392
}
63966393

63976394
/* And build the string to compare to */
6398-
cmptxt= (text*)palloc(VARHDRSZ+len+1);
6399-
SET_VARSIZE(cmptxt,VARHDRSZ+len+1);
6400-
memcpy(VARDATA(cmptxt),workstr,len);
6401-
*(VARDATA(cmptxt)+len)=suffixchar;
6402-
cmpstr=PointerGetDatum(cmptxt);
6395+
if (datatype==NAMEOID)
6396+
{
6397+
cmptxt=palloc(len+2);
6398+
memcpy(cmptxt,workstr,len);
6399+
cmptxt[len]=suffixchar;
6400+
cmptxt[len+1]='\0';
6401+
cmpstr=PointerGetDatum(cmptxt);
6402+
}
6403+
else
6404+
{
6405+
cmptxt=palloc(VARHDRSZ+len+1);
6406+
SET_VARSIZE(cmptxt,VARHDRSZ+len+1);
6407+
memcpy(VARDATA(cmptxt),workstr,len);
6408+
*(VARDATA(cmptxt)+len)=suffixchar;
6409+
cmpstr=PointerGetDatum(cmptxt);
6410+
}
64036411
}
64046412
}
64056413

@@ -6518,7 +6526,7 @@ string_to_const(const char *str, Oid datatype)
65186526
break;
65196527

65206528
caseNAMEOID:
6521-
collation=InvalidOid;
6529+
collation=C_COLLATION_OID;
65226530
constlen=NAMEDATALEN;
65236531
break;
65246532

‎src/backend/utils/adt/varchar.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include"access/hash.h"
1919
#include"access/tuptoaster.h"
2020
#include"catalog/pg_collation.h"
21+
#include"catalog/pg_type.h"
2122
#include"libpq/pqformat.h"
2223
#include"nodes/nodeFuncs.h"
2324
#include"utils/array.h"
@@ -876,7 +877,7 @@ bpchar_sortsupport(PG_FUNCTION_ARGS)
876877
oldcontext=MemoryContextSwitchTo(ssup->ssup_cxt);
877878

878879
/* Use generic string SortSupport */
879-
varstr_sortsupport(ssup,collid, true);
880+
varstr_sortsupport(ssup,BPCHAROID,collid);
880881

881882
MemoryContextSwitchTo(oldcontext);
882883

@@ -1085,7 +1086,7 @@ btbpchar_pattern_sortsupport(PG_FUNCTION_ARGS)
10851086
oldcontext=MemoryContextSwitchTo(ssup->ssup_cxt);
10861087

10871088
/* Use generic string SortSupport, forcing "C" collation */
1088-
varstr_sortsupport(ssup,C_COLLATION_OID, true);
1089+
varstr_sortsupport(ssup,BPCHAROID,C_COLLATION_OID);
10891090

10901091
MemoryContextSwitchTo(oldcontext);
10911092

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp