(
qcx: &mut QueryContext,
q: &SetExpr<Aug>,
)
| 1825 | } |
| 1826 | |
| 1827 | fn plan_set_expr( |
| 1828 | qcx: &mut QueryContext, |
| 1829 | q: &SetExpr<Aug>, |
| 1830 | ) -> Result<(HirRelationExpr, Scope), PlanError> { |
| 1831 | match q { |
| 1832 | SetExpr::Select(select) => { |
| 1833 | let order_by_exprs = Vec::new(); |
| 1834 | let plan = plan_select_from_where(qcx, *select.clone(), order_by_exprs)?; |
| 1835 | // We didn't provide any `order_by_exprs`, so `plan_select_from_where` |
| 1836 | // should not have planned any ordering. |
| 1837 | assert!(plan.order_by.is_empty()); |
| 1838 | Ok((plan.expr.project(plan.project), plan.scope)) |
| 1839 | } |
| 1840 | SetExpr::SetOperation { |
| 1841 | op, |
| 1842 | all, |
| 1843 | left, |
| 1844 | right, |
| 1845 | } => { |
| 1846 | // Plan the LHS and RHS. |
| 1847 | let (left_expr, left_scope) = qcx.checked_recur_mut(|qcx| plan_set_expr(qcx, left))?; |
| 1848 | let (right_expr, right_scope) = |
| 1849 | qcx.checked_recur_mut(|qcx| plan_set_expr(qcx, right))?; |
| 1850 | |
| 1851 | // Validate that the LHS and RHS are the same width. |
| 1852 | let left_type = qcx.relation_type(&left_expr); |
| 1853 | let right_type = qcx.relation_type(&right_expr); |
| 1854 | if left_type.arity() != right_type.arity() { |
| 1855 | sql_bail!( |
| 1856 | "each {} query must have the same number of columns: {} vs {}", |
| 1857 | op, |
| 1858 | left_type.arity(), |
| 1859 | right_type.arity(), |
| 1860 | ); |
| 1861 | } |
| 1862 | |
| 1863 | // Match the types of the corresponding columns on the LHS and RHS |
| 1864 | // using the normal type coercion rules. This is equivalent to |
| 1865 | // `coerce_homogeneous_exprs`, but implemented in terms of |
| 1866 | // `HirRelationExpr` rather than `HirScalarExpr`. |
| 1867 | let left_ecx = &ExprContext { |
| 1868 | qcx, |
| 1869 | name: &op.to_string(), |
| 1870 | scope: &left_scope, |
| 1871 | relation_type: &left_type, |
| 1872 | allow_aggregates: false, |
| 1873 | allow_subqueries: false, |
| 1874 | allow_parameters: false, |
| 1875 | allow_windows: false, |
| 1876 | }; |
| 1877 | let right_ecx = &ExprContext { |
| 1878 | qcx, |
| 1879 | name: &op.to_string(), |
| 1880 | scope: &right_scope, |
| 1881 | relation_type: &right_type, |
| 1882 | allow_aggregates: false, |
| 1883 | allow_subqueries: false, |
| 1884 | allow_parameters: false, |
no test coverage detected