(args: &[ast::Expr], catalog: &dyn SqlCatalog)
| 148 | } |
| 149 | |
| 150 | fn plan_project(args: &[ast::Expr], catalog: &dyn SqlCatalog) -> Result<SqlPlan> { |
| 151 | if args.len() != 2 { |
| 152 | return Err(SqlError::Unsupported { |
| 153 | detail: format!( |
| 154 | "ARRAY_PROJECT expects 2 args (name, [attrs]); got {}", |
| 155 | args.len() |
| 156 | ), |
| 157 | }); |
| 158 | } |
| 159 | let name = require_array_name(args, 0, "ARRAY_PROJECT", catalog)?; |
| 160 | let view = catalog |
| 161 | .lookup_array(&name) |
| 162 | .ok_or_else(|| SqlError::Unsupported { |
| 163 | detail: format!("ARRAY_PROJECT: array '{name}' not found"), |
| 164 | })?; |
| 165 | let attr_projection = expect_string_array(&args[1], "ARRAY_PROJECT attrs")?; |
| 166 | if attr_projection.is_empty() { |
| 167 | return Err(SqlError::Unsupported { |
| 168 | detail: "ARRAY_PROJECT: attr list must not be empty".into(), |
| 169 | }); |
| 170 | } |
| 171 | for attr in &attr_projection { |
| 172 | if !view.attrs.iter().any(|a| &a.name == attr) { |
| 173 | return Err(SqlError::Unsupported { |
| 174 | detail: format!("ARRAY_PROJECT: array '{name}' has no attr '{attr}'"), |
| 175 | }); |
| 176 | } |
| 177 | } |
| 178 | Ok(SqlPlan::ArrayProject { |
| 179 | name, |
| 180 | attr_projection, |
| 181 | }) |
| 182 | } |
| 183 | |
| 184 | fn plan_agg( |
| 185 | args: &[ast::Expr], |
no test coverage detected