~ubuntu-branches/ubuntu/precise/postgresql-9.1/precise-security

« back to all changes in this revision

Viewing changes to src/backend/optimizer/util/predtest.c

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2011-07-14 18:39:43 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20110714183943-eqlbsrurk6kh6lou
Tags: 9.1~beta3-1
* New upstream beta release.
  - Works around gcc 4.6.0 bug. (Closes: #633086)

  Note that this does not change the data format since Beta 2, so no need
  to dump/reload clusters.

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
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
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
1623
         * corresponding test operator.  This should work for any logically
1629
1624
         * consistent opfamilies.
1630
1625
         */
1631
 
        catlist = SearchSysCacheList1(AMOPOPID, ObjectIdGetDatum(pred_op));
1632
 
 
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)
1639
 
        {
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
 
        }
1649
 
 
1650
 
        /* Also may need the clause_op's negator */
1651
 
        clause_op_negator = get_negator(clause_op);
1652
 
 
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;
1659
 
 
1660
 
                /* Must be btree */
1661
 
                if (pred_form->amopmethod != BTREE_AM_OID)
1662
 
                        continue;
1663
 
 
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);
1668
 
 
1669
 
                if (pred_op_negated)
1670
 
                {
1671
 
                        /* Only consider negators that are = */
1672
 
                        if (pred_strategy != BTEqualStrategyNumber)
1673
 
                                continue;
1674
 
                        pred_strategy = BTNE;
1675
 
                }
1676
 
 
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))
1703
 
                        {
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;
1717
 
                        }
1718
 
                        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];
1731
 
 
1732
 
                if (test_strategy == 0)
1733
 
                {
1734
 
                        /* Can't determine implication using this interpretation */
1735
 
                        continue;
1736
 
                }
1737
 
 
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
 
                {
 
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;
 
1631
 
 
1632
        foreach(lcp, pred_op_infos)
 
1633
        {
 
1634
                OpBtreeInterpretation *pred_op_info = lfirst(lcp);
 
1635
                Oid                     opfamily_id = pred_op_info->opfamily_id;
 
1636
 
 
1637
                foreach(lcc, clause_op_infos)
 
1638
                {
 
1639
                        OpBtreeInterpretation *clause_op_info = lfirst(lcc);
 
1640
                        StrategyNumber pred_strategy,
 
1641
                                                clause_strategy,
 
1642
                                                test_strategy;
 
1643
 
 
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);
 
1649
 
 
1650
                        pred_strategy = pred_op_info->strategy;
 
1651
                        clause_strategy = clause_op_info->strategy;
 
1652
 
 
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];
 
1660
 
 
1661
                        if (test_strategy == 0)
 
1662
                        {
 
1663
                                /* Can't determine implication using this interpretation */
 
1664
                                continue;
 
1665
                        }
 
1666
 
 
1667
                        /*
 
1668
                         * See if opfamily has an operator for the test strategy and the
 
1669
                         * datatypes.
 
1670
                         */
 
1671
                        if (test_strategy == BTNE)
 
1672
                        {
 
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);
 
1679
                        }
 
1680
                        else
 
1681
                        {
 
1682
                                test_op = get_opfamily_member(opfamily_id,
 
1683
                                                                                          pred_op_info->oprighttype,
 
1684
                                                                                          clause_op_info->oprighttype,
 
1685
                                                                                          test_strategy);
 
1686
                        }
 
1687
 
 
1688
                        if (!OidIsValid(test_op))
 
1689
                                continue;
 
1690
 
1760
1691
                        /*
1761
1692
                         * Last check: test_op must be immutable.
1762
1693
                         *
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
        {