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

Commitaf18f6a

Browse files
committed
Fix scalararraysel() to cope with binary-compatible cases, such as text[]
versus varchar[]. This oversight probably explains Ryan Holmes' recentcomplaint --- he was getting a generic selectivity estimate instead ofanything intelligent.
1 parent82480fc commitaf18f6a

File tree

1 file changed

+83
-8
lines changed

1 file changed

+83
-8
lines changed

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

Lines changed: 83 additions & 8 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.221 2007/01/22 20:00:40 tgl Exp $
18+
* $PostgreSQL: pgsql/src/backend/utils/adt/selfuncs.c,v 1.222 2007/01/28 01:37:38 tgl Exp $
1919
*
2020
*-------------------------------------------------------------------------
2121
*/
@@ -88,11 +88,13 @@
8888
#include"optimizer/plancat.h"
8989
#include"optimizer/restrictinfo.h"
9090
#include"optimizer/var.h"
91+
#include"parser/parse_coerce.h"
9192
#include"parser/parse_expr.h"
9293
#include"parser/parsetree.h"
9394
#include"utils/builtins.h"
9495
#include"utils/date.h"
9596
#include"utils/datum.h"
97+
#include"utils/fmgroids.h"
9698
#include"utils/lsyscache.h"
9799
#include"utils/nabstime.h"
98100
#include"utils/pg_locale.h"
@@ -1448,6 +1450,63 @@ nulltestsel(PlannerInfo *root, NullTestType nulltesttype,
14481450
return (Selectivity)selec;
14491451
}
14501452

1453+
/*
1454+
* strip_array_coercion - strip binary-compatible relabeling from an array expr
1455+
*
1456+
* For array values, the parser doesn't generate simple RelabelType nodes,
1457+
* but function calls of array_type_coerce() or array_type_length_coerce().
1458+
* If we want to cope with binary-compatible situations we have to look
1459+
* through these calls whenever the element-type coercion is binary-compatible.
1460+
*/
1461+
staticNode*
1462+
strip_array_coercion(Node*node)
1463+
{
1464+
/* could be more than one level, so loop */
1465+
for (;;)
1466+
{
1467+
if (node&&IsA(node,RelabelType))
1468+
{
1469+
/* We don't really expect this case, but may as well cope */
1470+
node= (Node*) ((RelabelType*)node)->arg;
1471+
}
1472+
elseif (node&&IsA(node,FuncExpr))
1473+
{
1474+
FuncExpr*fexpr= (FuncExpr*)node;
1475+
Node*arg1;
1476+
Oidsrc_elem_type;
1477+
Oidtgt_elem_type;
1478+
OidfuncId;
1479+
1480+
/* must be the right function(s) */
1481+
if (!(fexpr->funcid==F_ARRAY_TYPE_COERCE||
1482+
fexpr->funcid==F_ARRAY_TYPE_LENGTH_COERCE))
1483+
break;
1484+
1485+
/* fetch source and destination array element types */
1486+
arg1= (Node*)linitial(fexpr->args);
1487+
src_elem_type=get_element_type(exprType(arg1));
1488+
if (src_elem_type==InvalidOid)
1489+
break;/* probably shouldn't happen */
1490+
tgt_elem_type=get_element_type(fexpr->funcresulttype);
1491+
if (tgt_elem_type==InvalidOid)
1492+
break;/* probably shouldn't happen */
1493+
1494+
/* find out how to coerce */
1495+
if (!find_coercion_pathway(tgt_elem_type,src_elem_type,
1496+
COERCION_EXPLICIT,&funcId))
1497+
break;/* definitely shouldn't happen */
1498+
1499+
if (OidIsValid(funcId))
1500+
break;/* non-binary-compatible coercion */
1501+
1502+
node=arg1;/* OK to look through the node */
1503+
}
1504+
else
1505+
break;
1506+
}
1507+
returnnode;
1508+
}
1509+
14511510
/*
14521511
*scalararraysel- Selectivity of ScalarArrayOpExpr Node.
14531512
*/
@@ -1461,6 +1520,7 @@ scalararraysel(PlannerInfo *root,
14611520
booluseOr=clause->useOr;
14621521
Node*leftop;
14631522
Node*rightop;
1523+
Oidnominal_element_type;
14641524
RegProcedureoprsel;
14651525
FmgrInfooprselproc;
14661526
Datumselarg4;
@@ -1484,6 +1544,19 @@ scalararraysel(PlannerInfo *root,
14841544
return (Selectivity)0.5;
14851545
fmgr_info(oprsel,&oprselproc);
14861546

1547+
/* deconstruct the expression */
1548+
Assert(list_length(clause->args)==2);
1549+
leftop= (Node*)linitial(clause->args);
1550+
rightop= (Node*)lsecond(clause->args);
1551+
1552+
/* get nominal (after relabeling) element type of rightop */
1553+
nominal_element_type=get_element_type(exprType(rightop));
1554+
if (!OidIsValid(nominal_element_type))
1555+
return (Selectivity)0.5;/* probably shouldn't happen */
1556+
1557+
/* look through any binary-compatible relabeling of rightop */
1558+
rightop=strip_array_coercion(rightop);
1559+
14871560
/*
14881561
* We consider three cases:
14891562
*
@@ -1496,10 +1569,6 @@ scalararraysel(PlannerInfo *root,
14961569
*
14971570
* 3. otherwise, make a guess ...
14981571
*/
1499-
Assert(list_length(clause->args)==2);
1500-
leftop= (Node*)linitial(clause->args);
1501-
rightop= (Node*)lsecond(clause->args);
1502-
15031572
if (rightop&&IsA(rightop,Const))
15041573
{
15051574
Datumarraydatum= ((Const*)rightop)->constvalue;
@@ -1529,7 +1598,7 @@ scalararraysel(PlannerInfo *root,
15291598
Selectivitys2;
15301599

15311600
args=list_make2(leftop,
1532-
makeConst(ARR_ELEMTYPE(arrayval),
1601+
makeConst(nominal_element_type,
15331602
elmlen,
15341603
elem_values[i],
15351604
elem_nulls[i],
@@ -1558,10 +1627,16 @@ scalararraysel(PlannerInfo *root,
15581627
s1=useOr ?0.0 :1.0;
15591628
foreach(l,arrayexpr->elements)
15601629
{
1630+
Node*elem= (Node*)lfirst(l);
15611631
List*args;
15621632
Selectivitys2;
15631633

1564-
args=list_make2(leftop,lfirst(l));
1634+
/*
1635+
* Theoretically, if elem isn't of nominal_element_type we should
1636+
* insert a RelabelType, but it seems unlikely that any operator
1637+
* estimation function would really care ...
1638+
*/
1639+
args=list_make2(leftop,elem);
15651640
s2=DatumGetFloat8(FunctionCall4(&oprselproc,
15661641
PointerGetDatum(root),
15671642
ObjectIdGetDatum(operator),
@@ -1586,7 +1661,7 @@ scalararraysel(PlannerInfo *root,
15861661
* constant; CaseTestExpr is a convenient choice.
15871662
*/
15881663
dummyexpr=makeNode(CaseTestExpr);
1589-
dummyexpr->typeId=get_element_type(exprType(rightop));
1664+
dummyexpr->typeId=nominal_element_type;
15901665
dummyexpr->typeMod=-1;
15911666
args=list_make2(leftop,dummyexpr);
15921667
s2=DatumGetFloat8(FunctionCall4(&oprselproc,

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp