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

Commit77585bc

Browse files
committed
Do ScalarArrayOp estimation correctly when array is a stable expression.
Most estimation functions apply estimate_expression_value to see if theycan reduce an expression to a constant; the key difference is that itallows evaluation of stable as well as immutable functions in hopes ofending up with a simple Const node. scalararraysel didn't get the memothough, and neither did gincost_opexpr/gincost_scalararrayopexpr. Fixthat, and remove a now-unnecessary estimate_expression_value step in thesubsidiary function scalararraysel_containment.Per complaint from Alexey Klyukin. Back-patch to 9.3. The problemgoes back further, but I'm hesitant to change estimation behavior inlong-stable release branches.
1 parent0c5783f commit77585bc

File tree

2 files changed

+26
-11
lines changed

2 files changed

+26
-11
lines changed

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

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -68,11 +68,13 @@ static intfloat_compare_desc(const void *key1, const void *key2);
6868
* scalararraysel_containment
6969
*Estimate selectivity of ScalarArrayOpExpr via array containment.
7070
*
71-
* scalararraysel() has already verified that the operator of a
72-
* ScalarArrayOpExpr is the array element type's default equality or
73-
* inequality operator. If we have const =/<> ANY/ALL (array_var)
74-
* then we can estimate the selectivity as though this were an array
75-
* containment operator, array_var op ARRAY[const].
71+
* If we have const =/<> ANY/ALL (array_var) then we can estimate the
72+
* selectivity as though this were an array containment operator,
73+
* array_var op ARRAY[const].
74+
*
75+
* scalararraysel() has already verified that the ScalarArrayOpExpr's operator
76+
* is the array element type's default equality or inequality operator, and
77+
* has aggressively simplified both inputs to constants.
7678
*
7779
* Returns selectivity (0..1), or -1 if we fail to estimate selectivity.
7880
*/
@@ -99,9 +101,8 @@ scalararraysel_containment(PlannerInfo *root,
99101
}
100102

101103
/*
102-
*Aggressively reduceleftoptoa constant,if possible.
104+
* leftopmust bea constant,else punt.
103105
*/
104-
leftop=estimate_expression_value(root,leftop);
105106
if (!IsA(leftop,Const))
106107
{
107108
ReleaseVariableStats(vardata);

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

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1735,6 +1735,10 @@ scalararraysel(PlannerInfo *root,
17351735
leftop= (Node*)linitial(clause->args);
17361736
rightop= (Node*)lsecond(clause->args);
17371737

1738+
/* aggressively reduce both sides to constants */
1739+
leftop=estimate_expression_value(root,leftop);
1740+
rightop=estimate_expression_value(root,rightop);
1741+
17381742
/* get nominal (after relabeling) element type of rightop */
17391743
nominal_element_type=get_base_element_type(exprType(rightop));
17401744
if (!OidIsValid(nominal_element_type))
@@ -6856,7 +6860,8 @@ gincost_pattern(IndexOptInfo *index, int indexcol,
68566860
* appropriately. If the query is unsatisfiable, return false.
68576861
*/
68586862
staticbool
6859-
gincost_opexpr(IndexOptInfo*index,OpExpr*clause,GinQualCounts*counts)
6863+
gincost_opexpr(PlannerInfo*root,IndexOptInfo*index,OpExpr*clause,
6864+
GinQualCounts*counts)
68606865
{
68616866
Node*leftop=get_leftop((Expr*)clause);
68626867
Node*rightop=get_rightop((Expr*)clause);
@@ -6880,6 +6885,9 @@ gincost_opexpr(IndexOptInfo *index, OpExpr *clause, GinQualCounts *counts)
68806885
operand=NULL;/* keep compiler quiet */
68816886
}
68826887

6888+
/* aggressively reduce to a constant, and look through relabeling */
6889+
operand=estimate_expression_value(root,operand);
6890+
68836891
if (IsA(operand,RelabelType))
68846892
operand= (Node*) ((RelabelType*)operand)->arg;
68856893

@@ -6918,7 +6926,8 @@ gincost_opexpr(IndexOptInfo *index, OpExpr *clause, GinQualCounts *counts)
69186926
* by N, causing gincostestimate to scale up its estimates accordingly.
69196927
*/
69206928
staticbool
6921-
gincost_scalararrayopexpr(IndexOptInfo*index,ScalarArrayOpExpr*clause,
6929+
gincost_scalararrayopexpr(PlannerInfo*root,
6930+
IndexOptInfo*index,ScalarArrayOpExpr*clause,
69226931
doublenumIndexEntries,
69236932
GinQualCounts*counts)
69246933
{
@@ -6943,6 +6952,9 @@ gincost_scalararrayopexpr(IndexOptInfo *index, ScalarArrayOpExpr *clause,
69436952
if ((indexcol=find_index_column(leftop,index))<0)
69446953
elog(ERROR,"could not match index to operand");
69456954

6955+
/* aggressively reduce to a constant, and look through relabeling */
6956+
rightop=estimate_expression_value(root,rightop);
6957+
69466958
if (IsA(rightop,RelabelType))
69476959
rightop= (Node*) ((RelabelType*)rightop)->arg;
69486960

@@ -7160,15 +7172,17 @@ gincostestimate(PG_FUNCTION_ARGS)
71607172
clause=rinfo->clause;
71617173
if (IsA(clause,OpExpr))
71627174
{
7163-
matchPossible=gincost_opexpr(index,
7175+
matchPossible=gincost_opexpr(root,
7176+
index,
71647177
(OpExpr*)clause,
71657178
&counts);
71667179
if (!matchPossible)
71677180
break;
71687181
}
71697182
elseif (IsA(clause,ScalarArrayOpExpr))
71707183
{
7171-
matchPossible=gincost_scalararrayopexpr(index,
7184+
matchPossible=gincost_scalararrayopexpr(root,
7185+
index,
71727186
(ScalarArrayOpExpr*)clause,
71737187
numEntries,
71747188
&counts);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp