| 1610 | } |
| 1611 | |
| 1612 | fn predicate( |
| 1613 | &self, |
| 1614 | predicate_expr: &MirScalarExpr, |
| 1615 | unique_columns: &BTreeSet<usize>, |
| 1616 | ) -> OrderedFloat<f64> { |
| 1617 | let index_selectivity = |expr: &MirScalarExpr| -> Option<OrderedFloat<f64>> { |
| 1618 | match expr { |
| 1619 | MirScalarExpr::Column(col, _) => { |
| 1620 | if unique_columns.contains(col) { |
| 1621 | // TODO(mgree): when we have index cardinality statistics, they should go here when `expr` is a `MirScalarExpr::Column` that's in `unique_columns` |
| 1622 | None |
| 1623 | } else { |
| 1624 | None |
| 1625 | } |
| 1626 | } |
| 1627 | _ => None, |
| 1628 | } |
| 1629 | }; |
| 1630 | |
| 1631 | match predicate_expr { |
| 1632 | MirScalarExpr::Column(_, _) |
| 1633 | | MirScalarExpr::Literal(_, _) |
| 1634 | | MirScalarExpr::CallUnmaterializable(_) => OrderedFloat(1.0), |
| 1635 | MirScalarExpr::CallUnary { func, expr } => match func { |
| 1636 | UnaryFunc::Not(_) => OrderedFloat(1.0) - self.predicate(expr, unique_columns), |
| 1637 | UnaryFunc::IsTrue(_) | UnaryFunc::IsFalse(_) => OrderedFloat(0.5), |
| 1638 | UnaryFunc::IsNull(_) => { |
| 1639 | if let Some(icard) = index_selectivity(expr) { |
| 1640 | icard |
| 1641 | } else { |
| 1642 | WORST_CASE_SELECTIVITY |
| 1643 | } |
| 1644 | } |
| 1645 | _ => WORST_CASE_SELECTIVITY, |
| 1646 | }, |
| 1647 | MirScalarExpr::CallBinary { func, expr1, expr2 } => { |
| 1648 | match func { |
| 1649 | BinaryFunc::Eq(_) => { |
| 1650 | match (index_selectivity(expr1), index_selectivity(expr2)) { |
| 1651 | (Some(isel1), Some(isel2)) => std::cmp::max(isel1, isel2), |
| 1652 | (Some(isel), None) | (None, Some(isel)) => isel, |
| 1653 | (None, None) => WORST_CASE_SELECTIVITY, |
| 1654 | } |
| 1655 | } |
| 1656 | // 1.0 - the Eq case |
| 1657 | BinaryFunc::NotEq(_) => { |
| 1658 | match (index_selectivity(expr1), index_selectivity(expr2)) { |
| 1659 | (Some(isel1), Some(isel2)) => { |
| 1660 | OrderedFloat(1.0) - std::cmp::max(isel1, isel2) |
| 1661 | } |
| 1662 | (Some(isel), None) | (None, Some(isel)) => OrderedFloat(1.0) - isel, |
| 1663 | (None, None) => OrderedFloat(1.0) - WORST_CASE_SELECTIVITY, |
| 1664 | } |
| 1665 | } |
| 1666 | BinaryFunc::Lt(_) |
| 1667 | | BinaryFunc::Lte(_) |
| 1668 | | BinaryFunc::Gt(_) |
| 1669 | | BinaryFunc::Gte(_) => { |