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

Commit14f6719

Browse files
committed
Remove assumptions that not-equals operators cannot be in any opclass.
get_op_btree_interpretation assumed this in order to save some duplicationof code, but it's not true in general anymore because we added <> supportto btree_gist. (We still assume it for btree opclasses, though.)Also, essentially the same logic was baked into predtest.c. Get rid ofthat duplication by generalizing get_op_btree_interpretation so that itcan be used by predtest.c.Per bug report from Denis de Bernardy and investigation by Jeff Davis,though I didn't use Jeff's patch exactly as-is.Back-patch to 9.1; we do not support this usage before that.
1 parentc7f2349 commit14f6719

File tree

4 files changed

+145
-181
lines changed

4 files changed

+145
-181
lines changed

‎src/backend/optimizer/util/predtest.c

Lines changed: 63 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -1250,6 +1250,7 @@ list_member_strip(List *list, Expr *datum)
12501250
* and in addition we use (6) to represent <>.<> is not a btree-indexable
12511251
* operator, but we assume here that if an equality operator of a btree
12521252
* opfamily has a negator operator, the negator behaves as <> for the opfamily.
1253+
* (This convention is also known to get_op_btree_interpretation().)
12531254
*
12541255
* The interpretation of:
12551256
*
@@ -1286,7 +1287,7 @@ list_member_strip(List *list, Expr *datum)
12861287
#defineBTEQ BTEqualStrategyNumber
12871288
#defineBTGE BTGreaterEqualStrategyNumber
12881289
#defineBTGT BTGreaterStrategyNumber
1289-
#defineBTNE6
1290+
#defineBTNEROWCOMPARE_NE
12901291

12911292
staticconstStrategyNumberBT_implic_table[6][6]= {
12921293
/*
@@ -1557,18 +1558,12 @@ get_btree_test_op(Oid pred_op, Oid clause_op, bool refute_it)
15571558
OprProofCacheKeykey;
15581559
OprProofCacheEntry*cache_entry;
15591560
boolcfound;
1560-
boolpred_op_negated;
1561-
Oidpred_op_negator,
1562-
clause_op_negator,
1563-
test_op=InvalidOid;
1564-
Oidopfamily_id;
1561+
Oidtest_op=InvalidOid;
15651562
boolfound= false;
1566-
StrategyNumberpred_strategy,
1567-
clause_strategy,
1568-
test_strategy;
1569-
Oidclause_righttype;
1570-
CatCList*catlist;
1571-
inti;
1563+
List*pred_op_infos,
1564+
*clause_op_infos;
1565+
ListCell*lcp,
1566+
*lcc;
15721567

15731568
/*
15741569
* Find or make a cache entry for this pair of operators.
@@ -1629,135 +1624,71 @@ get_btree_test_op(Oid pred_op, Oid clause_op, bool refute_it)
16291624
* corresponding test operator. This should work for any logically
16301625
* consistent opfamilies.
16311626
*/
1632-
catlist=SearchSysCacheList1(AMOPOPID,ObjectIdGetDatum(pred_op));
1627+
clause_op_infos=get_op_btree_interpretation(clause_op);
1628+
if (clause_op_infos)
1629+
pred_op_infos=get_op_btree_interpretation(pred_op);
1630+
else/* no point in looking */
1631+
pred_op_infos=NIL;
16331632

1634-
/*
1635-
* If we couldn't find any opfamily containing the pred_op, perhaps it is
1636-
* a <> operator. See if it has a negator that is in an opfamily.
1637-
*/
1638-
pred_op_negated= false;
1639-
if (catlist->n_members==0)
1633+
foreach(lcp,pred_op_infos)
16401634
{
1641-
pred_op_negator=get_negator(pred_op);
1642-
if (OidIsValid(pred_op_negator))
1643-
{
1644-
pred_op_negated= true;
1645-
ReleaseSysCacheList(catlist);
1646-
catlist=SearchSysCacheList1(AMOPOPID,
1647-
ObjectIdGetDatum(pred_op_negator));
1648-
}
1649-
}
1635+
OpBtreeInterpretation*pred_op_info=lfirst(lcp);
1636+
Oidopfamily_id=pred_op_info->opfamily_id;
16501637

1651-
/* Also may need the clause_op's negator */
1652-
clause_op_negator=get_negator(clause_op);
1638+
foreach(lcc,clause_op_infos)
1639+
{
1640+
OpBtreeInterpretation*clause_op_info=lfirst(lcc);
1641+
StrategyNumberpred_strategy,
1642+
clause_strategy,
1643+
test_strategy;
16531644

1654-
/* Now search the opfamilies */
1655-
for (i=0;i<catlist->n_members;i++)
1656-
{
1657-
HeapTuplepred_tuple=&catlist->members[i]->tuple;
1658-
Form_pg_amoppred_form= (Form_pg_amop)GETSTRUCT(pred_tuple);
1659-
HeapTupleclause_tuple;
1645+
/* Must find them in same opfamily */
1646+
if (opfamily_id!=clause_op_info->opfamily_id)
1647+
continue;
1648+
/* Lefttypes should match */
1649+
Assert(clause_op_info->oplefttype==pred_op_info->oplefttype);
16601650

1661-
/* Must be btree */
1662-
if (pred_form->amopmethod!=BTREE_AM_OID)
1663-
continue;
1651+
pred_strategy=pred_op_info->strategy;
1652+
clause_strategy=clause_op_info->strategy;
16641653

1665-
/* Get the predicate operator's btree strategy number */
1666-
opfamily_id=pred_form->amopfamily;
1667-
pred_strategy= (StrategyNumber)pred_form->amopstrategy;
1668-
Assert(pred_strategy >=1&&pred_strategy <=5);
1654+
/*
1655+
* Look up the "test" strategy number in the implication table
1656+
*/
1657+
if (refute_it)
1658+
test_strategy=BT_refute_table[clause_strategy-1][pred_strategy-1];
1659+
else
1660+
test_strategy=BT_implic_table[clause_strategy-1][pred_strategy-1];
16691661

1670-
if (pred_op_negated)
1671-
{
1672-
/* Only consider negators that are = */
1673-
if (pred_strategy!=BTEqualStrategyNumber)
1662+
if (test_strategy==0)
1663+
{
1664+
/* Can't determine implication using this interpretation */
16741665
continue;
1675-
pred_strategy=BTNE;
1676-
}
1666+
}
16771667

1678-
/*
1679-
* From the same opfamily, find a strategy number for the clause_op,
1680-
* if possible
1681-
*/
1682-
clause_tuple=SearchSysCache3(AMOPOPID,
1683-
ObjectIdGetDatum(clause_op),
1684-
CharGetDatum(AMOP_SEARCH),
1685-
ObjectIdGetDatum(opfamily_id));
1686-
if (HeapTupleIsValid(clause_tuple))
1687-
{
1688-
Form_pg_amopclause_form= (Form_pg_amop)GETSTRUCT(clause_tuple);
1689-
1690-
/* Get the restriction clause operator's strategy/datatype */
1691-
clause_strategy= (StrategyNumber)clause_form->amopstrategy;
1692-
Assert(clause_strategy >=1&&clause_strategy <=5);
1693-
Assert(clause_form->amoplefttype==pred_form->amoplefttype);
1694-
clause_righttype=clause_form->amoprighttype;
1695-
ReleaseSysCache(clause_tuple);
1696-
}
1697-
elseif (OidIsValid(clause_op_negator))
1698-
{
1699-
clause_tuple=SearchSysCache3(AMOPOPID,
1700-
ObjectIdGetDatum(clause_op_negator),
1701-
CharGetDatum(AMOP_SEARCH),
1702-
ObjectIdGetDatum(opfamily_id));
1703-
if (HeapTupleIsValid(clause_tuple))
1668+
/*
1669+
* See if opfamily has an operator for the test strategy and the
1670+
* datatypes.
1671+
*/
1672+
if (test_strategy==BTNE)
17041673
{
1705-
Form_pg_amopclause_form= (Form_pg_amop)GETSTRUCT(clause_tuple);
1706-
1707-
/* Get the restriction clause operator's strategy/datatype */
1708-
clause_strategy= (StrategyNumber)clause_form->amopstrategy;
1709-
Assert(clause_strategy >=1&&clause_strategy <=5);
1710-
Assert(clause_form->amoplefttype==pred_form->amoplefttype);
1711-
clause_righttype=clause_form->amoprighttype;
1712-
ReleaseSysCache(clause_tuple);
1713-
1714-
/* Only consider negators that are = */
1715-
if (clause_strategy!=BTEqualStrategyNumber)
1716-
continue;
1717-
clause_strategy=BTNE;
1674+
test_op=get_opfamily_member(opfamily_id,
1675+
pred_op_info->oprighttype,
1676+
clause_op_info->oprighttype,
1677+
BTEqualStrategyNumber);
1678+
if (OidIsValid(test_op))
1679+
test_op=get_negator(test_op);
17181680
}
17191681
else
1720-
continue;
1721-
}
1722-
else
1723-
continue;
1724-
1725-
/*
1726-
* Look up the "test" strategy number in the implication table
1727-
*/
1728-
if (refute_it)
1729-
test_strategy=BT_refute_table[clause_strategy-1][pred_strategy-1];
1730-
else
1731-
test_strategy=BT_implic_table[clause_strategy-1][pred_strategy-1];
1682+
{
1683+
test_op=get_opfamily_member(opfamily_id,
1684+
pred_op_info->oprighttype,
1685+
clause_op_info->oprighttype,
1686+
test_strategy);
1687+
}
17321688

1733-
if (test_strategy==0)
1734-
{
1735-
/* Can't determine implication using this interpretation */
1736-
continue;
1737-
}
1689+
if (!OidIsValid(test_op))
1690+
continue;
17381691

1739-
/*
1740-
* See if opfamily has an operator for the test strategy and the
1741-
* datatypes.
1742-
*/
1743-
if (test_strategy==BTNE)
1744-
{
1745-
test_op=get_opfamily_member(opfamily_id,
1746-
pred_form->amoprighttype,
1747-
clause_righttype,
1748-
BTEqualStrategyNumber);
1749-
if (OidIsValid(test_op))
1750-
test_op=get_negator(test_op);
1751-
}
1752-
else
1753-
{
1754-
test_op=get_opfamily_member(opfamily_id,
1755-
pred_form->amoprighttype,
1756-
clause_righttype,
1757-
test_strategy);
1758-
}
1759-
if (OidIsValid(test_op))
1760-
{
17611692
/*
17621693
* Last check: test_op must be immutable.
17631694
*
@@ -1773,9 +1704,13 @@ get_btree_test_op(Oid pred_op, Oid clause_op, bool refute_it)
17731704
break;
17741705
}
17751706
}
1707+
1708+
if (found)
1709+
break;
17761710
}
17771711

1778-
ReleaseSysCacheList(catlist);
1712+
list_free_deep(pred_op_infos);
1713+
list_free_deep(clause_op_infos);
17791714

17801715
if (!found)
17811716
{

‎src/backend/parser/parse_expr.c

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2170,8 +2170,7 @@ make_row_comparison_op(ParseState *pstate, List *opname,
21702170
List*opfamilies;
21712171
ListCell*l,
21722172
*r;
2173-
List**opfamily_lists;
2174-
List**opstrat_lists;
2173+
List**opinfo_lists;
21752174
Bitmapset*strats;
21762175
intnopers;
21772176
inti;
@@ -2241,8 +2240,7 @@ make_row_comparison_op(ParseState *pstate, List *opname,
22412240
* containing the operators, and see which interpretations (strategy
22422241
* numbers) exist for each operator.
22432242
*/
2244-
opfamily_lists= (List**)palloc(nopers*sizeof(List*));
2245-
opstrat_lists= (List**)palloc(nopers*sizeof(List*));
2243+
opinfo_lists= (List**)palloc(nopers*sizeof(List*));
22462244
strats=NULL;
22472245
i=0;
22482246
foreach(l,opexprs)
@@ -2251,17 +2249,18 @@ make_row_comparison_op(ParseState *pstate, List *opname,
22512249
Bitmapset*this_strats;
22522250
ListCell*j;
22532251

2254-
get_op_btree_interpretation(opno,
2255-
&opfamily_lists[i],&opstrat_lists[i]);
2252+
opinfo_lists[i]=get_op_btree_interpretation(opno);
22562253

22572254
/*
2258-
* convert strategynumber list to a Bitmapset to make the
2255+
* convert strategynumbers into a Bitmapset to make the
22592256
* intersection calculation easy.
22602257
*/
22612258
this_strats=NULL;
2262-
foreach(j,opstrat_lists[i])
2259+
foreach(j,opinfo_lists[i])
22632260
{
2264-
this_strats=bms_add_member(this_strats,lfirst_int(j));
2261+
OpBtreeInterpretation*opinfo=lfirst(j);
2262+
2263+
this_strats=bms_add_member(this_strats,opinfo->strategy);
22652264
}
22662265
if (i==0)
22672266
strats=this_strats;
@@ -2309,14 +2308,15 @@ make_row_comparison_op(ParseState *pstate, List *opname,
23092308
for (i=0;i<nopers;i++)
23102309
{
23112310
Oidopfamily=InvalidOid;
2311+
ListCell*j;
23122312

2313-
forboth(l,opfamily_lists[i],r,opstrat_lists[i])
2313+
foreach(j,opinfo_lists[i])
23142314
{
2315-
intopstrat=lfirst_int(r);
2315+
OpBtreeInterpretation*opinfo=lfirst(j);
23162316

2317-
if (opstrat==rctype)
2317+
if (opinfo->strategy==rctype)
23182318
{
2319-
opfamily=lfirst_oid(l);
2319+
opfamily=opinfo->opfamily_id;
23202320
break;
23212321
}
23222322
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp