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

Commit9ff5b69

Browse files
committed
Sync patternsel_common's operator selection logic with pattern_prefix's.
Make patternsel_common() select the comparison operators to use withhardwired logic that matches pattern_prefix()'s new logic, eliminatingits dependencies on particular index opfamilies.This shouldn't change any behavior, as it's just replacing runtimeoperator lookups with the same values hard-wired. But it makes theseclosely-related functions look more alike, and saving some runtimesyscache lookups is worth something.Actually, it's not quite true that this is zero behavioral change:when estimating for a column of type "name", the comparison constantwill be kept as "text" not coerced to "name". But that's more correctanyway, and it allows additional simplification of the coercion logic,again syncing this more closely with pattern_prefix().Per consideration of a report from Manuel Rigger.Discussion:https://postgr.es/m/CA+u7OA7nnGYy8rY0vdTe811NuA+Frr9nbcBO9u2Z+JxqNaud+g@mail.gmail.com
1 parent9f0f12a commit9ff5b69

File tree

1 file changed

+58
-61
lines changed

1 file changed

+58
-61
lines changed

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

Lines changed: 58 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,8 @@ static Pattern_Prefix_Status pattern_fixed_prefix(Const *patt,
9191
Selectivity*rest_selec);
9292
staticSelectivityprefix_selectivity(PlannerInfo*root,
9393
VariableStatData*vardata,
94-
Oidvartype,Oidopfamily,Const*prefixcon);
94+
Oideqopr,Oidltopr,Oidgeopr,
95+
Const*prefixcon);
9596
staticSelectivitylike_selectivity(constchar*patt,intpattlen,
9697
boolcase_insensitive);
9798
staticSelectivityregex_selectivity(constchar*patt,intpattlen,
@@ -470,7 +471,10 @@ patternsel_common(PlannerInfo *root,
470471
Datumconstval;
471472
Oidconsttype;
472473
Oidvartype;
473-
Oidopfamily;
474+
Oidrdatatype;
475+
Oideqopr;
476+
Oidltopr;
477+
Oidgeopr;
474478
Pattern_Prefix_Statuspstatus;
475479
Const*patt;
476480
Const*prefix=NULL;
@@ -527,29 +531,51 @@ patternsel_common(PlannerInfo *root,
527531
/*
528532
* Similarly, the exposed type of the left-hand side should be one of
529533
* those we know. (Do not look at vardata.atttype, which might be
530-
* something binary-compatible but different.)We can use it to choose
531-
* the index opfamily from which we must draw the comparison operators.
534+
* something binary-compatible but different.)We can use it to identify
535+
* the comparison operators and the required type of the comparison
536+
* constant, much as in match_pattern_prefix().
532537
*
533-
* NOTE: It would be more correct to use the PATTERN opfamilies than the
534-
* simple ones, but at the moment ANALYZE will not generate statistics for
535-
* the PATTERN operators. But our results are so approximate anyway that
536-
* it probably hardly matters.
538+
* NOTE: this logic does not consider collations. Ideally we'd force use
539+
* of "C" collation, but since ANALYZE only generates statistics for the
540+
* column's specified collation, we have little choice but to use those.
541+
* But our results are so approximate anyway that it probably hardly
542+
* matters.
537543
*/
538544
vartype=vardata.vartype;
539545

540546
switch (vartype)
541547
{
542548
caseTEXTOID:
549+
eqopr=TextEqualOperator;
550+
ltopr=TextLessOperator;
551+
geopr=TextGreaterEqualOperator;
552+
rdatatype=TEXTOID;
553+
break;
543554
caseNAMEOID:
544-
opfamily=TEXT_BTREE_FAM_OID;
555+
556+
/*
557+
* Note that here, we need the RHS type to be text, so that the
558+
* comparison value isn't improperly truncated to NAMEDATALEN.
559+
*/
560+
eqopr=NameEqualTextOperator;
561+
ltopr=NameLessTextOperator;
562+
geopr=NameGreaterEqualTextOperator;
563+
rdatatype=TEXTOID;
545564
break;
546565
caseBPCHAROID:
547-
opfamily=BPCHAR_BTREE_FAM_OID;
566+
eqopr=BpcharEqualOperator;
567+
ltopr=BpcharLessOperator;
568+
geopr=BpcharGreaterEqualOperator;
569+
rdatatype=BPCHAROID;
548570
break;
549571
caseBYTEAOID:
550-
opfamily=BYTEA_BTREE_FAM_OID;
572+
eqopr=ByteaEqualOperator;
573+
ltopr=ByteaLessOperator;
574+
geopr=ByteaGreaterEqualOperator;
575+
rdatatype=BYTEAOID;
551576
break;
552577
default:
578+
/* Can't get here unless we're attached to the wrong operator */
553579
ReleaseVariableStats(vardata);
554580
returnresult;
555581
}
@@ -579,41 +605,23 @@ patternsel_common(PlannerInfo *root,
579605
&prefix,&rest_selec);
580606

581607
/*
582-
* If necessary, coerce the prefix constant to the right type.
608+
* If necessary, coerce the prefix constant to the right type. The only
609+
* case where we need to do anything is when converting text to bpchar.
610+
* Those two types are binary-compatible, so relabeling the Const node is
611+
* sufficient.
583612
*/
584-
if (prefix&&prefix->consttype!=vartype)
613+
if (prefix&&prefix->consttype!=rdatatype)
585614
{
586-
char*prefixstr;
587-
588-
switch (prefix->consttype)
589-
{
590-
caseTEXTOID:
591-
prefixstr=TextDatumGetCString(prefix->constvalue);
592-
break;
593-
caseBYTEAOID:
594-
prefixstr=DatumGetCString(DirectFunctionCall1(byteaout,
595-
prefix->constvalue));
596-
break;
597-
default:
598-
elog(ERROR,"unrecognized consttype: %u",
599-
prefix->consttype);
600-
ReleaseVariableStats(vardata);
601-
returnresult;
602-
}
603-
prefix=string_to_const(prefixstr,vartype);
604-
pfree(prefixstr);
615+
Assert(prefix->consttype==TEXTOID&&
616+
rdatatype==BPCHAROID);
617+
prefix->consttype=rdatatype;
605618
}
606619

607620
if (pstatus==Pattern_Prefix_Exact)
608621
{
609622
/*
610-
* Pattern specifies an exact match, sopretend operator is '='
623+
* Pattern specifies an exact match, soestimate as for '='
611624
*/
612-
Oideqopr=get_opfamily_member(opfamily,vartype,vartype,
613-
BTEqualStrategyNumber);
614-
615-
if (eqopr==InvalidOid)
616-
elog(ERROR,"no = operator for opfamily %u",opfamily);
617625
result=var_eq_const(&vardata,eqopr,prefix->constvalue,
618626
false, true, false);
619627
}
@@ -656,8 +664,9 @@ patternsel_common(PlannerInfo *root,
656664
Selectivityprefixsel;
657665

658666
if (pstatus==Pattern_Prefix_Partial)
659-
prefixsel=prefix_selectivity(root,&vardata,vartype,
660-
opfamily,prefix);
667+
prefixsel=prefix_selectivity(root,&vardata,
668+
eqopr,ltopr,geopr,
669+
prefix);
661670
else
662671
prefixsel=1.0;
663672
heursel=prefixsel*rest_selec;
@@ -1181,15 +1190,14 @@ pattern_fixed_prefix(Const *patt, Pattern_Type ptype, Oid collation,
11811190
* Estimate the selectivity of a fixed prefix for a pattern match.
11821191
*
11831192
* A fixed prefix "foo" is estimated as the selectivity of the expression
1184-
* "variable >= 'foo' AND variable < 'fop'" (see also indxpath.c).
1193+
* "variable >= 'foo' AND variable < 'fop'".
11851194
*
11861195
* The selectivity estimate is with respect to the portion of the column
11871196
* population represented by the histogram --- the caller must fold this
11881197
* together with info about MCVs and NULLs.
11891198
*
1190-
* We use the >= and < operators from the specified btree opfamily to do the
1191-
* estimation. The given variable and Const must be of the associated
1192-
* datatype.
1199+
* We use the specified btree comparison operators to do the estimation.
1200+
* The given variable and Const must be of the associated datatype(s).
11931201
*
11941202
* XXX Note: we make use of the upper bound to estimate operator selectivity
11951203
* even if the locale is such that we cannot rely on the upper-bound string.
@@ -1198,20 +1206,17 @@ pattern_fixed_prefix(Const *patt, Pattern_Type ptype, Oid collation,
11981206
*/
11991207
staticSelectivity
12001208
prefix_selectivity(PlannerInfo*root,VariableStatData*vardata,
1201-
Oidvartype,Oidopfamily,Const*prefixcon)
1209+
Oideqopr,Oidltopr,Oidgeopr,
1210+
Const*prefixcon)
12021211
{
12031212
Selectivityprefixsel;
1204-
Oidcmpopr;
12051213
FmgrInfoopproc;
12061214
AttStatsSlotsslot;
12071215
Const*greaterstrcon;
12081216
Selectivityeq_sel;
12091217

1210-
cmpopr=get_opfamily_member(opfamily,vartype,vartype,
1211-
BTGreaterEqualStrategyNumber);
1212-
if (cmpopr==InvalidOid)
1213-
elog(ERROR,"no >= operator for opfamily %u",opfamily);
1214-
fmgr_info(get_opcode(cmpopr),&opproc);
1218+
/* Estimate the selectivity of "x >= prefix" */
1219+
fmgr_info(get_opcode(geopr),&opproc);
12151220

12161221
prefixsel=ineq_histogram_selectivity(root,vardata,
12171222
&opproc, true, true,
@@ -1237,11 +1242,7 @@ prefix_selectivity(PlannerInfo *root, VariableStatData *vardata,
12371242
/* sslot.stacoll is set up */ ;
12381243
else
12391244
sslot.stacoll=DEFAULT_COLLATION_OID;
1240-
cmpopr=get_opfamily_member(opfamily,vartype,vartype,
1241-
BTLessStrategyNumber);
1242-
if (cmpopr==InvalidOid)
1243-
elog(ERROR,"no < operator for opfamily %u",opfamily);
1244-
fmgr_info(get_opcode(cmpopr),&opproc);
1245+
fmgr_info(get_opcode(ltopr),&opproc);
12451246
greaterstrcon=make_greater_string(prefixcon,&opproc,sslot.stacoll);
12461247
if (greaterstrcon)
12471248
{
@@ -1277,11 +1278,7 @@ prefix_selectivity(PlannerInfo *root, VariableStatData *vardata,
12771278
* probably off the end of the histogram, and thus we probably got a very
12781279
* small estimate from the >= condition; so we still need to clamp.
12791280
*/
1280-
cmpopr=get_opfamily_member(opfamily,vartype,vartype,
1281-
BTEqualStrategyNumber);
1282-
if (cmpopr==InvalidOid)
1283-
elog(ERROR,"no = operator for opfamily %u",opfamily);
1284-
eq_sel=var_eq_const(vardata,cmpopr,prefixcon->constvalue,
1281+
eq_sel=var_eq_const(vardata,eqopr,prefixcon->constvalue,
12851282
false, true, false);
12861283

12871284
prefixsel=Max(prefixsel,eq_sel);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp