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

Commite8655a7

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 parent5a7e758 commite8655a7

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
@@ -1734,6 +1734,10 @@ scalararraysel(PlannerInfo *root,
17341734
leftop= (Node*)linitial(clause->args);
17351735
rightop= (Node*)lsecond(clause->args);
17361736

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

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

@@ -6917,7 +6925,8 @@ gincost_opexpr(IndexOptInfo *index, OpExpr *clause, GinQualCounts *counts)
69176925
* by N, causing gincostestimate to scale up its estimates accordingly.
69186926
*/
69196927
staticbool
6920-
gincost_scalararrayopexpr(IndexOptInfo*index,ScalarArrayOpExpr*clause,
6928+
gincost_scalararrayopexpr(PlannerInfo*root,
6929+
IndexOptInfo*index,ScalarArrayOpExpr*clause,
69216930
doublenumIndexEntries,
69226931
GinQualCounts*counts)
69236932
{
@@ -6942,6 +6951,9 @@ gincost_scalararrayopexpr(IndexOptInfo *index, ScalarArrayOpExpr *clause,
69426951
if ((indexcol=find_index_column(leftop,index))<0)
69436952
elog(ERROR,"could not match index to operand");
69446953

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

@@ -7159,15 +7171,17 @@ gincostestimate(PG_FUNCTION_ARGS)
71597171
clause=rinfo->clause;
71607172
if (IsA(clause,OpExpr))
71617173
{
7162-
matchPossible=gincost_opexpr(index,
7174+
matchPossible=gincost_opexpr(root,
7175+
index,
71637176
(OpExpr*)clause,
71647177
&counts);
71657178
if (!matchPossible)
71667179
break;
71677180
}
71687181
elseif (IsA(clause,ScalarArrayOpExpr))
71697182
{
7170-
matchPossible=gincost_scalararrayopexpr(index,
7183+
matchPossible=gincost_scalararrayopexpr(root,
7184+
index,
71717185
(ScalarArrayOpExpr*)clause,
71727186
numEntries,
71737187
&counts);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp