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

Commita96fa85

Browse files
committed
Second pass at improving LIKE/regex estimation in non-C locales. It turns
out that it's actually quite likely that a string that is an extension ofthe given prefix will sort as larger than the "greater" string our previouscode created. To provide some defense against that, do the comparisonsagainst a modified string instead of just the bare prefix. We tack on"Z", "z", "y", or "9", whichever is seen as largest in the current locale.Testing suggests that this is sufficient at least for cases involvingASCII data.
1 parent4b606ee commita96fa85

File tree

1 file changed

+55
-8
lines changed

1 file changed

+55
-8
lines changed

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

Lines changed: 55 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
*
1616
*
1717
* IDENTIFICATION
18-
* $PostgreSQL: pgsql/src/backend/utils/adt/selfuncs.c,v 1.238 2007/11/07 22:37:24 tgl Exp $
18+
* $PostgreSQL: pgsql/src/backend/utils/adt/selfuncs.c,v 1.239 2007/11/09 20:10:02 tgl Exp $
1919
*
2020
*-------------------------------------------------------------------------
2121
*/
@@ -4586,7 +4586,10 @@ pattern_selectivity(Const *patt, Pattern_Type ptype)
45864586
/*
45874587
* Try to generate a string greater than the given string or any
45884588
* string it is a prefix of. If successful, return a palloc'd string
4589-
* in the form of a Const pointer; else return NULL.
4589+
* in the form of a Const node; else return NULL.
4590+
*
4591+
* The caller must provide the appropriate "less than" comparison function
4592+
* for testing the strings.
45904593
*
45914594
* The key requirement here is that given a prefix string, say "foo",
45924595
* we must be able to generate another string "fop" that is greater than
@@ -4595,11 +4598,13 @@ pattern_selectivity(Const *patt, Pattern_Type ptype)
45954598
* that is not a bulletproof guarantee that an extension of the string might
45964599
* not sort after it; an example is that "foo " is less than "foo!", but it
45974600
* is not clear that a "dictionary" sort ordering will consider "foo!" less
4598-
* than "foo bar". Therefore, this function should be used only for
4601+
* than "foo bar".CAUTION:Therefore, this function should be used only for
45994602
* estimation purposes when working in a non-C locale.
46004603
*
4601-
* The caller must provide the appropriate "less than" comparison function
4602-
* for testing the strings.
4604+
* To try to catch most cases where an extended string might otherwise sort
4605+
* before the result value, we determine which of the strings "Z", "z", "y",
4606+
* and "9" is seen as largest by the locale, and append that to the given
4607+
* prefix before trying to find a string that compares as larger.
46034608
*
46044609
* If we max out the righthand byte, truncate off the last character
46054610
* and start incrementing the next. For example, if "z" were the last
@@ -4615,13 +4620,22 @@ make_greater_string(const Const *str_const, FmgrInfo *ltproc)
46154620
Oiddatatype=str_const->consttype;
46164621
char*workstr;
46174622
intlen;
4623+
Datumcmpstr;
4624+
text*cmptxt=NULL;
46184625

4619-
/* Get a modifiable copy of the string in C-string format */
4626+
/*
4627+
* Get a modifiable copy of the prefix string in C-string format,
4628+
* and set up the string we will compare to as a Datum. In C locale
4629+
* this can just be the given prefix string, otherwise we need to add
4630+
* a suffix. Types NAME and BYTEA sort bytewise so they don't need
4631+
* a suffix either.
4632+
*/
46204633
if (datatype==NAMEOID)
46214634
{
46224635
workstr=DatumGetCString(DirectFunctionCall1(nameout,
46234636
str_const->constvalue));
46244637
len=strlen(workstr);
4638+
cmpstr=str_const->constvalue;
46254639
}
46264640
elseif (datatype==BYTEAOID)
46274641
{
@@ -4632,12 +4646,41 @@ make_greater_string(const Const *str_const, FmgrInfo *ltproc)
46324646
memcpy(workstr,VARDATA(bstr),len);
46334647
if ((Pointer)bstr!=DatumGetPointer(str_const->constvalue))
46344648
pfree(bstr);
4649+
cmpstr=str_const->constvalue;
46354650
}
46364651
else
46374652
{
46384653
workstr=DatumGetCString(DirectFunctionCall1(textout,
46394654
str_const->constvalue));
46404655
len=strlen(workstr);
4656+
if (lc_collate_is_c()||len==0)
4657+
cmpstr=str_const->constvalue;
4658+
else
4659+
{
4660+
/* If first time through, determine the suffix to use */
4661+
staticcharsuffixchar=0;
4662+
4663+
if (!suffixchar)
4664+
{
4665+
char*best;
4666+
4667+
best="Z";
4668+
if (varstr_cmp(best,1,"z",1)<0)
4669+
best="z";
4670+
if (varstr_cmp(best,1,"y",1)<0)
4671+
best="y";
4672+
if (varstr_cmp(best,1,"9",1)<0)
4673+
best="9";
4674+
suffixchar=*best;
4675+
}
4676+
4677+
/* And build the string to compare to */
4678+
cmptxt= (text*)palloc(VARHDRSZ+len+1);
4679+
SET_VARSIZE(cmptxt,VARHDRSZ+len+1);
4680+
memcpy(VARDATA(cmptxt),workstr,len);
4681+
*(VARDATA(cmptxt)+len)=suffixchar;
4682+
cmpstr=PointerGetDatum(cmptxt);
4683+
}
46414684
}
46424685

46434686
while (len>0)
@@ -4665,10 +4708,12 @@ make_greater_string(const Const *str_const, FmgrInfo *ltproc)
46654708
workstr_const=string_to_bytea_const(workstr,len);
46664709

46674710
if (DatumGetBool(FunctionCall2(ltproc,
4668-
str_const->constvalue,
4711+
cmpstr,
46694712
workstr_const->constvalue)))
46704713
{
4671-
/* Successfully made a string larger than the input */
4714+
/* Successfully made a string larger than cmpstr */
4715+
if (cmptxt)
4716+
pfree(cmptxt);
46724717
pfree(workstr);
46734718
returnworkstr_const;
46744719
}
@@ -4695,6 +4740,8 @@ make_greater_string(const Const *str_const, FmgrInfo *ltproc)
46954740
}
46964741

46974742
/* Failed... */
4743+
if (cmptxt)
4744+
pfree(cmptxt);
46984745
pfree(workstr);
46994746

47004747
returnNULL;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp