|
15 | 15 | *
|
16 | 16 | *
|
17 | 17 | * IDENTIFICATION
|
18 |
| - * $Header: /cvsroot/pgsql/src/backend/utils/adt/selfuncs.c,v 1.127 2003/01/20 18:54:59 tgl Exp $ |
| 18 | + * $Header: /cvsroot/pgsql/src/backend/utils/adt/selfuncs.c,v 1.128 2003/01/22 20:16:42 tgl Exp $ |
19 | 19 | *
|
20 | 20 | *-------------------------------------------------------------------------
|
21 | 21 | */
|
@@ -1742,7 +1742,9 @@ mergejoinscansel(Query *root, Node *clause,
|
1742 | 1742 | rsortop,
|
1743 | 1743 | ltop,
|
1744 | 1744 | gtop,
|
1745 |
| - revltop; |
| 1745 | + leop, |
| 1746 | + revgtop, |
| 1747 | + revleop; |
1746 | 1748 | Datum leftmax,
|
1747 | 1749 | rightmax;
|
1748 | 1750 | double selec;
|
@@ -1780,35 +1782,49 @@ mergejoinscansel(Query *root, Node *clause,
|
1780 | 1782 | /* Look up the "left < right" and "left > right" operators */
|
1781 | 1783 | op_mergejoin_crossops(opno, <op, >op, NULL, NULL);
|
1782 | 1784 |
|
1783 |
| - /* Look up the "right < left" operator */ |
1784 |
| - revltop = get_commutator(gtop); |
1785 |
| - if (!OidIsValid(revltop)) |
1786 |
| - return; /* shouldn't happen */ |
| 1785 | + /* Look up the "left <= right" operator */ |
| 1786 | + leop = get_negator(gtop); |
| 1787 | + if (!OidIsValid(leop)) |
| 1788 | + return; /* insufficient info in catalogs */ |
| 1789 | + |
| 1790 | + /* Look up the "right > left" operator */ |
| 1791 | + revgtop = get_commutator(ltop); |
| 1792 | + if (!OidIsValid(revgtop)) |
| 1793 | + return; /* insufficient info in catalogs */ |
| 1794 | + |
| 1795 | + /* Look up the "right <= left" operator */ |
| 1796 | + revleop = get_negator(revgtop); |
| 1797 | + if (!OidIsValid(revleop)) |
| 1798 | + return; /* insufficient info in catalogs */ |
1787 | 1799 |
|
1788 | 1800 | /*
|
1789 | 1801 | * Now, the fraction of the left variable that will be scanned is the
|
1790 | 1802 | * fraction that's <= the right-side maximum value. But only believe
|
1791 | 1803 | * non-default estimates, else stick with our 1.0.
|
1792 | 1804 | */
|
1793 |
| - selec = scalarineqsel(root, ltop, false, left, |
| 1805 | + selec = scalarineqsel(root, leop, false, left, |
1794 | 1806 | rightmax, right->vartype);
|
1795 | 1807 | if (selec != DEFAULT_INEQ_SEL)
|
1796 | 1808 | *leftscan = selec;
|
1797 | 1809 |
|
1798 | 1810 | /* And similarly for the right variable. */
|
1799 |
| - selec = scalarineqsel(root, revltop, false, right, |
| 1811 | + selec = scalarineqsel(root, revleop, false, right, |
1800 | 1812 | leftmax, left->vartype);
|
1801 | 1813 | if (selec != DEFAULT_INEQ_SEL)
|
1802 | 1814 | *rightscan = selec;
|
1803 | 1815 |
|
1804 | 1816 | /*
|
1805 | 1817 | * Only one of the two fractions can really be less than 1.0; believe
|
1806 |
| - * the smaller estimate and reset the other one to exactly 1.0. |
| 1818 | + * the smaller estimate and reset the other one to exactly 1.0. If we |
| 1819 | + * get exactly equal estimates (as can easily happen with self-joins), |
| 1820 | + * believe neither. |
1807 | 1821 | */
|
1808 | 1822 | if (*leftscan > *rightscan)
|
1809 | 1823 | *leftscan = 1.0;
|
1810 |
| - else |
| 1824 | + else if (*leftscan < *rightscan) |
1811 | 1825 | *rightscan = 1.0;
|
| 1826 | + else |
| 1827 | + *leftscan = *rightscan = 1.0; |
1812 | 1828 | }
|
1813 | 1829 |
|
1814 | 1830 | /*
|
|
0 commit comments