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

Commitefeffae

Browse files
committed
Tweak selectivity and related routines to cope with domains. Per report
from Andreas Pflug.
1 parent8f5fb5f commitefeffae

File tree

2 files changed

+83
-24
lines changed

2 files changed

+83
-24
lines changed

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

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*
1010
*
1111
* IDENTIFICATION
12-
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/indxpath.c,v 1.135 2003/02/08 20:20:54 tgl Exp $
12+
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/indxpath.c,v 1.136 2003/03/23 01:49:02 tgl Exp $
1313
*
1414
*-------------------------------------------------------------------------
1515
*/
@@ -2039,7 +2039,7 @@ expand_indexqual_conditions(List *indexquals)
20392039
* Given a fixed prefix that all the "leftop" values must have,
20402040
* generate suitable indexqual condition(s). expr_op is the original
20412041
* LIKE or regex operator; we use it to deduce the appropriate comparison
2042-
* operators.
2042+
* operators and operand datatypes.
20432043
*/
20442044
staticList*
20452045
prefix_quals(Node*leftop,Oidexpr_op,
@@ -2094,10 +2094,13 @@ prefix_quals(Node *leftop, Oid expr_op,
20942094
returnNIL;
20952095
}
20962096

2097-
if (prefix_const->consttype!=BYTEAOID)
2098-
prefix=DatumGetCString(DirectFunctionCall1(textout,prefix_const->constvalue));
2097+
/* Prefix constant is text for all except BYTEA_LIKE */
2098+
if (datatype!=BYTEAOID)
2099+
prefix=DatumGetCString(DirectFunctionCall1(textout,
2100+
prefix_const->constvalue));
20992101
else
2100-
prefix=DatumGetCString(DirectFunctionCall1(byteaout,prefix_const->constvalue));
2102+
prefix=DatumGetCString(DirectFunctionCall1(byteaout,
2103+
prefix_const->constvalue));
21012104

21022105
/*
21032106
* If we found an exact-match pattern, generate an "=" indexqual.

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

Lines changed: 75 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
*
1616
*
1717
* IDENTIFICATION
18-
* $Header: /cvsroot/pgsql/src/backend/utils/adt/selfuncs.c,v 1.132 2003/02/08 20:20:55 tgl Exp $
18+
* $Header: /cvsroot/pgsql/src/backend/utils/adt/selfuncs.c,v 1.133 2003/03/23 01:49:02 tgl Exp $
1919
*
2020
*-------------------------------------------------------------------------
2121
*/
@@ -94,6 +94,7 @@
9494
#include"optimizer/prep.h"
9595
#include"optimizer/tlist.h"
9696
#include"optimizer/var.h"
97+
#include"parser/parse_expr.h"
9798
#include"parser/parse_func.h"
9899
#include"parser/parse_oper.h"
99100
#include"parser/parsetree.h"
@@ -176,7 +177,8 @@ static bool get_restriction_var(List *args, int varRelid,
176177
Var**var,Node**other,
177178
bool*varonleft);
178179
staticvoidget_join_vars(List*args,Var**var1,Var**var2);
179-
staticSelectivityprefix_selectivity(Query*root,Var*var,Const*prefix);
180+
staticSelectivityprefix_selectivity(Query*root,Var*var,Oidvartype,
181+
Const*prefix);
180182
staticSelectivitypattern_selectivity(Const*patt,Pattern_Typeptype);
181183
staticboolstring_lessthan(constchar*str1,constchar*str2,
182184
Oiddatatype);
@@ -227,7 +229,8 @@ eqsel(PG_FUNCTION_ARGS)
227229
* If the something is a NULL constant, assume operator is strict and
228230
* return zero, ie, operator will never return TRUE.
229231
*/
230-
if (IsA(other,Const)&&((Const*)other)->constisnull)
232+
if (IsA(other,Const)&&
233+
((Const*)other)->constisnull)
231234
PG_RETURN_FLOAT8(0.0);
232235

233236
/* get stats for the attribute, if available */
@@ -834,6 +837,8 @@ patternsel(PG_FUNCTION_ARGS, Pattern_Type ptype)
834837
boolvaronleft;
835838
Oidrelid;
836839
Datumconstval;
840+
Oidconsttype;
841+
Oidvartype;
837842
Pattern_Prefix_Statuspstatus;
838843
Const*patt=NULL;
839844
Const*prefix=NULL;
@@ -861,13 +866,25 @@ patternsel(PG_FUNCTION_ARGS, Pattern_Type ptype)
861866
if (((Const*)other)->constisnull)
862867
return0.0;
863868
constval= ((Const*)other)->constvalue;
869+
consttype= ((Const*)other)->consttype;
870+
871+
/*
872+
* The right-hand const is type text or bytea for all supported
873+
* operators. We do not expect to see binary-compatible types here,
874+
* since const-folding should have relabeled the const to exactly match
875+
* the operator's declared type.
876+
*/
877+
if (consttype!=TEXTOID&&consttype!=BYTEAOID)
878+
returnDEFAULT_MATCH_SEL;
864879

865880
/*
866-
* the right-hand const is type text or bytea for all supported
867-
* operators
881+
* The var, on the other hand, might be a binary-compatible type;
882+
* particularly a domain. Try to fold it if it's not recognized
883+
* immediately.
868884
*/
869-
Assert(((Const*)other)->consttype==TEXTOID||
870-
((Const*)other)->consttype==BYTEAOID);
885+
vartype=var->vartype;
886+
if (vartype!=consttype)
887+
vartype=getBaseType(vartype);
871888

872889
/* divide pattern into fixed prefix and remainder */
873890
patt= (Const*)other;
@@ -878,12 +895,12 @@ patternsel(PG_FUNCTION_ARGS, Pattern_Type ptype)
878895
/*
879896
* Pattern specifies an exact match, so pretend operator is '='
880897
*/
881-
Oideqopr=find_operator("=",var->vartype);
898+
Oideqopr=find_operator("=",vartype);
882899
List*eqargs;
883900

884901
if (eqopr==InvalidOid)
885902
elog(ERROR,"patternsel: no = operator for type %u",
886-
var->vartype);
903+
vartype);
887904
eqargs=makeList2(var,prefix);
888905
result=DatumGetFloat8(DirectFunctionCall4(eqsel,
889906
PointerGetDatum(root),
@@ -903,7 +920,7 @@ patternsel(PG_FUNCTION_ARGS, Pattern_Type ptype)
903920
Selectivityselec;
904921

905922
if (pstatus==Pattern_Prefix_Partial)
906-
prefixsel=prefix_selectivity(root,var,prefix);
923+
prefixsel=prefix_selectivity(root,var,vartype,prefix);
907924
else
908925
prefixsel=1.0;
909926
restsel=pattern_selectivity(rest,ptype);
@@ -1033,7 +1050,8 @@ booltestsel(Query *root, BoolTestType booltesttype, Node *arg,
10331050
if (IsA(arg,RelabelType))
10341051
arg= (Node*) ((RelabelType*)arg)->arg;
10351052

1036-
if (IsA(arg,Var)&&(varRelid==0||varRelid== ((Var*)arg)->varno))
1053+
if (IsA(arg,Var)&&
1054+
(varRelid==0||varRelid== ((Var*)arg)->varno))
10371055
var= (Var*)arg;
10381056
else
10391057
{
@@ -1775,6 +1793,8 @@ mergejoinscansel(Query *root, Node *clause,
17751793
{
17761794
Var*left,
17771795
*right;
1796+
Oidlefttype,
1797+
righttype;
17781798
Oidopno,
17791799
lsortop,
17801800
rsortop,
@@ -1799,6 +1819,24 @@ mergejoinscansel(Query *root, Node *clause,
17991819
if (!right)
18001820
return;/* shouldn't happen */
18011821

1822+
/* Save the direct input types of the operator */
1823+
lefttype=exprType((Node*)left);
1824+
righttype=exprType((Node*)right);
1825+
1826+
/*
1827+
* Now skip any binary-compatible relabeling; there can only be one level
1828+
* since constant-expression folder eliminates adjacent RelabelTypes.
1829+
*
1830+
* XXX can't enable this quite yet, it exposes regproc uncertainty problems
1831+
* in regression tests. FIXME soon.
1832+
*/
1833+
#if0
1834+
if (IsA(left,RelabelType))
1835+
left= (Var*) ((RelabelType*)left)->arg;
1836+
if (IsA(right,RelabelType))
1837+
right= (Var*) ((RelabelType*)right)->arg;
1838+
#endif
1839+
18021840
/* Can't do anything if inputs are not Vars */
18031841
if (!IsA(left,Var)||
18041842
!IsA(right,Var))
@@ -1841,13 +1879,13 @@ mergejoinscansel(Query *root, Node *clause,
18411879
* non-default estimates, else stick with our 1.0.
18421880
*/
18431881
selec=scalarineqsel(root,leop, false,left,
1844-
rightmax,right->vartype);
1882+
rightmax,righttype);
18451883
if (selec!=DEFAULT_INEQ_SEL)
18461884
*leftscan=selec;
18471885

18481886
/* And similarly for the right variable. */
18491887
selec=scalarineqsel(root,revleop, false,right,
1850-
leftmax,left->vartype);
1888+
leftmax,lefttype);
18511889
if (selec!=DEFAULT_INEQ_SEL)
18521890
*rightscan=selec;
18531891

@@ -2263,6 +2301,19 @@ convert_to_scalar(Datum value, Oid valuetypid, double *scaledvalue,
22632301
Datumlobound,Datumhibound,Oidboundstypid,
22642302
double*scaledlobound,double*scaledhibound)
22652303
{
2304+
/*
2305+
* In present usage, we can assume that the valuetypid exactly matches
2306+
* the declared input type of the operator we are invoked for (because
2307+
* constant-folding will ensure that any Const passed to the operator
2308+
* has been reduced to the correct type). However, the boundstypid is
2309+
* the type of some variable that might be only binary-compatible with
2310+
* the declared type; in particular it might be a domain type. Must
2311+
* fold the variable type down to base type so we can recognize it.
2312+
* (But we can skip that lookup if the variable type matches the const.)
2313+
*/
2314+
if (boundstypid!=valuetypid)
2315+
boundstypid=getBaseType(boundstypid);
2316+
22662317
switch (valuetypid)
22672318
{
22682319
/*
@@ -3234,31 +3285,36 @@ pattern_fixed_prefix(Const *patt, Pattern_Type ptype,
32343285
* A fixed prefix "foo" is estimated as the selectivity of the expression
32353286
* "var >= 'foo' AND var < 'fop'" (see also indxqual.c).
32363287
*
3288+
* Because of constant-folding, we can assume that the prefixcon constant's
3289+
* type exactly matches the operator's declared input type; but it's not
3290+
* safe to make the same assumption for the Var, so the type to use for the
3291+
* Var must be passed in separately.
3292+
*
32373293
* XXX Note: we make use of the upper bound to estimate operator selectivity
32383294
* even if the locale is such that we cannot rely on the upper-bound string.
32393295
* The selectivity only needs to be approximately right anyway, so it seems
32403296
* more useful to use the upper-bound code than not.
32413297
*/
32423298
staticSelectivity
3243-
prefix_selectivity(Query*root,Var*var,Const*prefixcon)
3299+
prefix_selectivity(Query*root,Var*var,Oidvartype,Const*prefixcon)
32443300
{
32453301
Selectivityprefixsel;
32463302
Oidcmpopr;
32473303
char*prefix;
32483304
List*cmpargs;
32493305
Const*greaterstrcon;
32503306

3251-
cmpopr=find_operator(">=",var->vartype);
3307+
cmpopr=find_operator(">=",vartype);
32523308
if (cmpopr==InvalidOid)
32533309
elog(ERROR,"prefix_selectivity: no >= operator for type %u",
3254-
var->vartype);
3310+
vartype);
32553311
if (prefixcon->consttype!=BYTEAOID)
32563312
prefix=DatumGetCString(DirectFunctionCall1(textout,prefixcon->constvalue));
32573313
else
32583314
prefix=DatumGetCString(DirectFunctionCall1(byteaout,prefixcon->constvalue));
32593315

32603316
/* If var is type NAME, must adjust type of comparison constant */
3261-
if (var->vartype==NAMEOID)
3317+
if (vartype==NAMEOID)
32623318
prefixcon=string_to_const(prefix,NAMEOID);
32633319

32643320
cmpargs=makeList2(var,prefixcon);
@@ -3279,10 +3335,10 @@ prefix_selectivity(Query *root, Var *var, Const *prefixcon)
32793335
{
32803336
Selectivitytopsel;
32813337

3282-
cmpopr=find_operator("<",var->vartype);
3338+
cmpopr=find_operator("<",vartype);
32833339
if (cmpopr==InvalidOid)
32843340
elog(ERROR,"prefix_selectivity: no < operator for type %u",
3285-
var->vartype);
3341+
vartype);
32863342
cmpargs=makeList2(var,greaterstrcon);
32873343
/* Assume scalarltsel is appropriate for all supported types */
32883344
topsel=DatumGetFloat8(DirectFunctionCall4(scalarltsel,

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp