@@ -1249,6 +1249,7 @@ list_member_strip(List *list, Expr *datum)
1249
1249
* and in addition we use (6) to represent <>. <> is not a btree-indexable
1250
1250
* operator, but we assume here that if an equality operator of a btree
1251
1251
* opfamily has a negator operator, the negator behaves as <> for the opfamily.
1252
+ * (This convention is also known to get_op_btree_interpretation().)
1252
1253
*
1253
1254
* The interpretation of:
1254
1255
*
@@ -1285,7 +1286,7 @@ list_member_strip(List *list, Expr *datum)
1285
1286
#define BTEQ BTEqualStrategyNumber
1286
1287
#define BTGE BTGreaterEqualStrategyNumber
1287
1288
#define BTGT BTGreaterStrategyNumber
1288
- #define BTNE 6
1289
+ #define BTNE ROWCOMPARE_NE
1289
1290
1290
1291
static const StrategyNumber BT_implic_table [6 ][6 ] = {
1291
1292
/*
@@ -1556,18 +1557,12 @@ get_btree_test_op(Oid pred_op, Oid clause_op, bool refute_it)
1556
1557
OprProofCacheKey key ;
1557
1558
OprProofCacheEntry * cache_entry ;
1558
1559
bool cfound ;
1559
- bool pred_op_negated ;
1560
- Oid pred_op_negator ,
1561
- clause_op_negator ,
1562
- test_op = InvalidOid ;
1563
- Oid opfamily_id ;
1560
+ Oid test_op = InvalidOid ;
1564
1561
bool found = false;
1565
- StrategyNumber pred_strategy ,
1566
- clause_strategy ,
1567
- test_strategy ;
1568
- Oid clause_righttype ;
1569
- CatCList * catlist ;
1570
- int i ;
1562
+ List * pred_op_infos ,
1563
+ * clause_op_infos ;
1564
+ ListCell * lcp ,
1565
+ * lcc ;
1571
1566
1572
1567
/*
1573
1568
* 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)
1628
1623
* corresponding test operator. This should work for any logically
1629
1624
* consistent opfamilies.
1630
1625
*/
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 ;
1632
1631
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 )
1639
1633
{
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
+ Oid opfamily_id = pred_op_info -> opfamily_id ;
1649
1636
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
+ StrategyNumber pred_strategy ,
1641
+ clause_strategy ,
1642
+ test_strategy ;
1652
1643
1653
- /* Now search the opfamilies */
1654
- for (i = 0 ; i < catlist -> n_members ; i ++ )
1655
- {
1656
- HeapTuple pred_tuple = & catlist -> members [i ]-> tuple ;
1657
- Form_pg_amop pred_form = (Form_pg_amop ) GETSTRUCT (pred_tuple );
1658
- HeapTuple clause_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 );
1659
1649
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 ;
1663
1652
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 ];
1668
1660
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 */
1673
1664
continue ;
1674
- pred_strategy = BTNE ;
1675
- }
1665
+ }
1676
1666
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_amop clause_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
- else if (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 )
1703
1672
{
1704
- Form_pg_amop clause_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 );
1717
1679
}
1718
1680
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
+ }
1731
1687
1732
- if (test_strategy == 0 )
1733
- {
1734
- /* Can't determine implication using this interpretation */
1735
- continue ;
1736
- }
1688
+ if (!OidIsValid (test_op ))
1689
+ continue ;
1737
1690
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
- {
1760
1691
/*
1761
1692
* Last check: test_op must be immutable.
1762
1693
*
@@ -1772,9 +1703,13 @@ get_btree_test_op(Oid pred_op, Oid clause_op, bool refute_it)
1772
1703
break ;
1773
1704
}
1774
1705
}
1706
+
1707
+ if (found )
1708
+ break ;
1775
1709
}
1776
1710
1777
- ReleaseSysCacheList (catlist );
1711
+ list_free_deep (pred_op_infos );
1712
+ list_free_deep (clause_op_infos );
1778
1713
1779
1714
if (!found )
1780
1715
{
0 commit comments