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

Commit9542287

Browse files
committed
Fix patternsel() and callers to do the right thing for NOT LIKE and the other
negated-match operators. patternsel had been using the supplied operator asthough it were a positive-match operator, and thus obtaining a wrong result,which was even more wrong after the caller subtracted it from 1. Seemscleanest to give patternsel an explicit "negate" argument so that it knowswhat's going on. Also install the same factorization scheme for patternjoin selectivity estimators; even though they are just stubs at themoment, this may keep someone from making the same type of mistake whenthey get filled out. Per report from Greg Mullane.Backpatch to 8.2 --- previous releases do not show the problem becausepatternsel() doesn't actually use the operator directly.
1 parent371d7bc commit9542287

File tree

1 file changed

+52
-57
lines changed

1 file changed

+52
-57
lines changed

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

Lines changed: 52 additions & 57 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.236 2007/08/31 23:35:22 tgl Exp $
18+
* $PostgreSQL: pgsql/src/backend/utils/adt/selfuncs.c,v 1.237 2007/11/07 21:00:37 tgl Exp $
1919
*
2020
*-------------------------------------------------------------------------
2121
*/
@@ -901,7 +901,7 @@ scalargtsel(PG_FUNCTION_ARGS)
901901
* patternsel- Generic code for pattern-match selectivity.
902902
*/
903903
staticdouble
904-
patternsel(PG_FUNCTION_ARGS,Pattern_Typeptype)
904+
patternsel(PG_FUNCTION_ARGS,Pattern_Typeptype,boolnegate)
905905
{
906906
PlannerInfo*root= (PlannerInfo*)PG_GETARG_POINTER(0);
907907
Oidoperator=PG_GETARG_OID(1);
@@ -921,23 +921,40 @@ patternsel(PG_FUNCTION_ARGS, Pattern_Type ptype)
921921
Const*rest=NULL;
922922
doubleresult;
923923

924+
/*
925+
* If this is for a NOT LIKE or similar operator, get the corresponding
926+
* positive-match operator and work with that. Set result to the
927+
* correct default estimate, too.
928+
*/
929+
if (negate)
930+
{
931+
operator=get_negator(operator);
932+
if (!OidIsValid(operator))
933+
elog(ERROR,"patternsel called for operator without a negator");
934+
result=1.0-DEFAULT_MATCH_SEL;
935+
}
936+
else
937+
{
938+
result=DEFAULT_MATCH_SEL;
939+
}
940+
924941
/*
925942
* If expression is not variable op constant, then punt and return a
926943
* default estimate.
927944
*/
928945
if (!get_restriction_variable(root,args,varRelid,
929946
&vardata,&other,&varonleft))
930-
returnDEFAULT_MATCH_SEL;
947+
returnresult;
931948
if (!varonleft|| !IsA(other,Const))
932949
{
933950
ReleaseVariableStats(vardata);
934-
returnDEFAULT_MATCH_SEL;
951+
returnresult;
935952
}
936953
variable= (Node*)linitial(args);
937954

938955
/*
939956
* If the constant is NULL, assume operator is strict and return zero, ie,
940-
* operator will never return TRUE.
957+
* operator will never return TRUE. (It's zero even for a negator op.)
941958
*/
942959
if (((Const*)other)->constisnull)
943960
{
@@ -956,7 +973,7 @@ patternsel(PG_FUNCTION_ARGS, Pattern_Type ptype)
956973
if (consttype!=TEXTOID&&consttype!=BYTEAOID)
957974
{
958975
ReleaseVariableStats(vardata);
959-
returnDEFAULT_MATCH_SEL;
976+
returnresult;
960977
}
961978

962979
/*
@@ -988,7 +1005,7 @@ patternsel(PG_FUNCTION_ARGS, Pattern_Type ptype)
9881005
break;
9891006
default:
9901007
ReleaseVariableStats(vardata);
991-
returnDEFAULT_MATCH_SEL;
1008+
returnresult;
9921009
}
9931010

9941011
/* divide pattern into fixed prefix and remainder */
@@ -1017,7 +1034,7 @@ patternsel(PG_FUNCTION_ARGS, Pattern_Type ptype)
10171034
elog(ERROR,"unrecognized consttype: %u",
10181035
prefix->consttype);
10191036
ReleaseVariableStats(vardata);
1020-
returnDEFAULT_MATCH_SEL;
1037+
returnresult;
10211038
}
10221039
prefix=string_to_const(prefixstr,vartype);
10231040
pfree(prefixstr);
@@ -1125,7 +1142,7 @@ patternsel(PG_FUNCTION_ARGS, Pattern_Type ptype)
11251142

11261143
ReleaseVariableStats(vardata);
11271144

1128-
returnresult;
1145+
returnnegate ? (1.0-result) :result;
11291146
}
11301147

11311148
/*
@@ -1134,7 +1151,7 @@ patternsel(PG_FUNCTION_ARGS, Pattern_Type ptype)
11341151
Datum
11351152
regexeqsel(PG_FUNCTION_ARGS)
11361153
{
1137-
PG_RETURN_FLOAT8(patternsel(fcinfo,Pattern_Type_Regex));
1154+
PG_RETURN_FLOAT8(patternsel(fcinfo,Pattern_Type_Regex, false));
11381155
}
11391156

11401157
/*
@@ -1143,7 +1160,7 @@ regexeqsel(PG_FUNCTION_ARGS)
11431160
Datum
11441161
icregexeqsel(PG_FUNCTION_ARGS)
11451162
{
1146-
PG_RETURN_FLOAT8(patternsel(fcinfo,Pattern_Type_Regex_IC));
1163+
PG_RETURN_FLOAT8(patternsel(fcinfo,Pattern_Type_Regex_IC, false));
11471164
}
11481165

11491166
/*
@@ -1152,7 +1169,7 @@ icregexeqsel(PG_FUNCTION_ARGS)
11521169
Datum
11531170
likesel(PG_FUNCTION_ARGS)
11541171
{
1155-
PG_RETURN_FLOAT8(patternsel(fcinfo,Pattern_Type_Like));
1172+
PG_RETURN_FLOAT8(patternsel(fcinfo,Pattern_Type_Like, false));
11561173
}
11571174

11581175
/*
@@ -1161,7 +1178,7 @@ likesel(PG_FUNCTION_ARGS)
11611178
Datum
11621179
iclikesel(PG_FUNCTION_ARGS)
11631180
{
1164-
PG_RETURN_FLOAT8(patternsel(fcinfo,Pattern_Type_Like_IC));
1181+
PG_RETURN_FLOAT8(patternsel(fcinfo,Pattern_Type_Like_IC, false));
11651182
}
11661183

11671184
/*
@@ -1170,11 +1187,7 @@ iclikesel(PG_FUNCTION_ARGS)
11701187
Datum
11711188
regexnesel(PG_FUNCTION_ARGS)
11721189
{
1173-
doubleresult;
1174-
1175-
result=patternsel(fcinfo,Pattern_Type_Regex);
1176-
result=1.0-result;
1177-
PG_RETURN_FLOAT8(result);
1190+
PG_RETURN_FLOAT8(patternsel(fcinfo,Pattern_Type_Regex, true));
11781191
}
11791192

11801193
/*
@@ -1183,11 +1196,7 @@ regexnesel(PG_FUNCTION_ARGS)
11831196
Datum
11841197
icregexnesel(PG_FUNCTION_ARGS)
11851198
{
1186-
doubleresult;
1187-
1188-
result=patternsel(fcinfo,Pattern_Type_Regex_IC);
1189-
result=1.0-result;
1190-
PG_RETURN_FLOAT8(result);
1199+
PG_RETURN_FLOAT8(patternsel(fcinfo,Pattern_Type_Regex_IC, true));
11911200
}
11921201

11931202
/*
@@ -1196,11 +1205,7 @@ icregexnesel(PG_FUNCTION_ARGS)
11961205
Datum
11971206
nlikesel(PG_FUNCTION_ARGS)
11981207
{
1199-
doubleresult;
1200-
1201-
result=patternsel(fcinfo,Pattern_Type_Like);
1202-
result=1.0-result;
1203-
PG_RETURN_FLOAT8(result);
1208+
PG_RETURN_FLOAT8(patternsel(fcinfo,Pattern_Type_Like, true));
12041209
}
12051210

12061211
/*
@@ -1209,11 +1214,7 @@ nlikesel(PG_FUNCTION_ARGS)
12091214
Datum
12101215
icnlikesel(PG_FUNCTION_ARGS)
12111216
{
1212-
doubleresult;
1213-
1214-
result=patternsel(fcinfo,Pattern_Type_Like_IC);
1215-
result=1.0-result;
1216-
PG_RETURN_FLOAT8(result);
1217+
PG_RETURN_FLOAT8(patternsel(fcinfo,Pattern_Type_Like_IC, true));
12171218
}
12181219

12191220
/*
@@ -2081,13 +2082,23 @@ scalargtjoinsel(PG_FUNCTION_ARGS)
20812082
PG_RETURN_FLOAT8(DEFAULT_INEQ_SEL);
20822083
}
20832084

2085+
/*
2086+
* patternjoinsel- Generic code for pattern-match join selectivity.
2087+
*/
2088+
staticdouble
2089+
patternjoinsel(PG_FUNCTION_ARGS,Pattern_Typeptype,boolnegate)
2090+
{
2091+
/* For the moment we just punt. */
2092+
returnnegate ? (1.0-DEFAULT_MATCH_SEL) :DEFAULT_MATCH_SEL;
2093+
}
2094+
20842095
/*
20852096
*regexeqjoinsel- Join selectivity of regular-expression pattern match.
20862097
*/
20872098
Datum
20882099
regexeqjoinsel(PG_FUNCTION_ARGS)
20892100
{
2090-
PG_RETURN_FLOAT8(DEFAULT_MATCH_SEL);
2101+
PG_RETURN_FLOAT8(patternjoinsel(fcinfo,Pattern_Type_Regex, false));
20912102
}
20922103

20932104
/*
@@ -2096,7 +2107,7 @@ regexeqjoinsel(PG_FUNCTION_ARGS)
20962107
Datum
20972108
icregexeqjoinsel(PG_FUNCTION_ARGS)
20982109
{
2099-
PG_RETURN_FLOAT8(DEFAULT_MATCH_SEL);
2110+
PG_RETURN_FLOAT8(patternjoinsel(fcinfo,Pattern_Type_Regex_IC, false));
21002111
}
21012112

21022113
/*
@@ -2105,7 +2116,7 @@ icregexeqjoinsel(PG_FUNCTION_ARGS)
21052116
Datum
21062117
likejoinsel(PG_FUNCTION_ARGS)
21072118
{
2108-
PG_RETURN_FLOAT8(DEFAULT_MATCH_SEL);
2119+
PG_RETURN_FLOAT8(patternjoinsel(fcinfo,Pattern_Type_Like, false));
21092120
}
21102121

21112122
/*
@@ -2114,7 +2125,7 @@ likejoinsel(PG_FUNCTION_ARGS)
21142125
Datum
21152126
iclikejoinsel(PG_FUNCTION_ARGS)
21162127
{
2117-
PG_RETURN_FLOAT8(DEFAULT_MATCH_SEL);
2128+
PG_RETURN_FLOAT8(patternjoinsel(fcinfo,Pattern_Type_Like_IC, false));
21182129
}
21192130

21202131
/*
@@ -2123,11 +2134,7 @@ iclikejoinsel(PG_FUNCTION_ARGS)
21232134
Datum
21242135
regexnejoinsel(PG_FUNCTION_ARGS)
21252136
{
2126-
float8result;
2127-
2128-
result=DatumGetFloat8(regexeqjoinsel(fcinfo));
2129-
result=1.0-result;
2130-
PG_RETURN_FLOAT8(result);
2137+
PG_RETURN_FLOAT8(patternjoinsel(fcinfo,Pattern_Type_Regex, true));
21312138
}
21322139

21332140
/*
@@ -2136,11 +2143,7 @@ regexnejoinsel(PG_FUNCTION_ARGS)
21362143
Datum
21372144
icregexnejoinsel(PG_FUNCTION_ARGS)
21382145
{
2139-
float8result;
2140-
2141-
result=DatumGetFloat8(icregexeqjoinsel(fcinfo));
2142-
result=1.0-result;
2143-
PG_RETURN_FLOAT8(result);
2146+
PG_RETURN_FLOAT8(patternjoinsel(fcinfo,Pattern_Type_Regex_IC, true));
21442147
}
21452148

21462149
/*
@@ -2149,11 +2152,7 @@ icregexnejoinsel(PG_FUNCTION_ARGS)
21492152
Datum
21502153
nlikejoinsel(PG_FUNCTION_ARGS)
21512154
{
2152-
float8result;
2153-
2154-
result=DatumGetFloat8(likejoinsel(fcinfo));
2155-
result=1.0-result;
2156-
PG_RETURN_FLOAT8(result);
2155+
PG_RETURN_FLOAT8(patternjoinsel(fcinfo,Pattern_Type_Like, true));
21572156
}
21582157

21592158
/*
@@ -2162,11 +2161,7 @@ nlikejoinsel(PG_FUNCTION_ARGS)
21622161
Datum
21632162
icnlikejoinsel(PG_FUNCTION_ARGS)
21642163
{
2165-
float8result;
2166-
2167-
result=DatumGetFloat8(iclikejoinsel(fcinfo));
2168-
result=1.0-result;
2169-
PG_RETURN_FLOAT8(result);
2164+
PG_RETURN_FLOAT8(patternjoinsel(fcinfo,Pattern_Type_Like_IC, true));
21702165
}
21712166

21722167
/*

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp