Plans a `VALUES` clause that appears in a `SELECT` statement.
(
qcx: &QueryContext,
values: &[Vec<Expr<Aug>>],
)
| 2074 | |
| 2075 | /// Plans a `VALUES` clause that appears in a `SELECT` statement. |
| 2076 | fn plan_values( |
| 2077 | qcx: &QueryContext, |
| 2078 | values: &[Vec<Expr<Aug>>], |
| 2079 | ) -> Result<(HirRelationExpr, Scope), PlanError> { |
| 2080 | assert!(!values.is_empty()); |
| 2081 | |
| 2082 | let ecx = &ExprContext { |
| 2083 | qcx, |
| 2084 | name: "VALUES", |
| 2085 | scope: &Scope::empty(), |
| 2086 | relation_type: &SqlRelationType::empty(), |
| 2087 | allow_aggregates: false, |
| 2088 | allow_subqueries: true, |
| 2089 | allow_parameters: true, |
| 2090 | allow_windows: false, |
| 2091 | }; |
| 2092 | |
| 2093 | let ncols = values[0].len(); |
| 2094 | let nrows = values.len(); |
| 2095 | |
| 2096 | // Arrange input expressions by columns, not rows, so that we can |
| 2097 | // call `coerce_homogeneous_exprs` on each column. |
| 2098 | let mut cols = vec![vec![]; ncols]; |
| 2099 | for row in values { |
| 2100 | if row.len() != ncols { |
| 2101 | sql_bail!( |
| 2102 | "VALUES expression has varying number of columns: {} vs {}", |
| 2103 | row.len(), |
| 2104 | ncols |
| 2105 | ); |
| 2106 | } |
| 2107 | for (i, v) in row.iter().enumerate() { |
| 2108 | cols[i].push(v); |
| 2109 | } |
| 2110 | } |
| 2111 | |
| 2112 | // Plan each column. |
| 2113 | let mut col_iters = Vec::with_capacity(ncols); |
| 2114 | let mut col_types = Vec::with_capacity(ncols); |
| 2115 | for col in &cols { |
| 2116 | let col = coerce_homogeneous_exprs(ecx, plan_exprs(ecx, col)?, None)?; |
| 2117 | let mut col_type = ecx.column_type(&col[0]); |
| 2118 | for val in &col[1..] { |
| 2119 | col_type = col_type.sql_union(&ecx.column_type(val))?; // HIR deliberately not using `union` |
| 2120 | } |
| 2121 | col_types.push(col_type); |
| 2122 | col_iters.push(col.into_iter()); |
| 2123 | } |
| 2124 | |
| 2125 | // Build constant relation. |
| 2126 | let mut exprs = vec![]; |
| 2127 | for _ in 0..nrows { |
| 2128 | for i in 0..ncols { |
| 2129 | exprs.push(col_iters[i].next().unwrap()); |
| 2130 | } |
| 2131 | } |
| 2132 | let out = HirRelationExpr::CallTable { |
| 2133 | func: TableFunc::Wrap { |
no test coverage detected