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

Commitcb1cc30

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 parentf8bd267 commitcb1cc30

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
@@ -1249,6 +1249,7 @@ list_member_strip(List *list, Expr *datum)
12491249
* and in addition we use (6) to represent <>.<> is not a btree-indexable
12501250
* operator, but we assume here that if an equality operator of a btree
12511251
* opfamily has a negator operator, the negator behaves as <> for the opfamily.
1252+
* (This convention is also known to get_op_btree_interpretation().)
12521253
*
12531254
* The interpretation of:
12541255
*
@@ -1285,7 +1286,7 @@ list_member_strip(List *list, Expr *datum)
12851286
#defineBTEQ BTEqualStrategyNumber
12861287
#defineBTGE BTGreaterEqualStrategyNumber
12871288
#defineBTGT BTGreaterStrategyNumber
1288-
#defineBTNE6
1289+
#defineBTNEROWCOMPARE_NE
12891290

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

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

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

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

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

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

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

1669-
if (pred_op_negated)
1670-
{
1671-
/* Only consider negators that are = */
1672-
if (pred_strategy!=BTEqualStrategyNumber)
1661+
if (test_strategy==0)
1662+
{
1663+
/* Can't determine implication using this interpretation */
16731664
continue;
1674-
pred_strategy=BTNE;
1675-
}
1665+
}
16761666

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

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

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

1777-
ReleaseSysCacheList(catlist);
1711+
list_free_deep(pred_op_infos);
1712+
list_free_deep(clause_op_infos);
17781713

17791714
if (!found)
17801715
{

‎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