(
context: &mut ParserContext,
env: &mut Environment,
tokens: &[Token],
position: &mut usize,
)
| 3351 | } |
| 3352 | |
| 3353 | fn parse_symbol_expression( |
| 3354 | context: &mut ParserContext, |
| 3355 | env: &mut Environment, |
| 3356 | tokens: &[Token], |
| 3357 | position: &mut usize, |
| 3358 | ) -> Result<Box<dyn Expr>, Box<Diagnostic>> { |
| 3359 | let mut value = tokens[*position].to_string(); |
| 3360 | let location = tokens[*position].location; |
| 3361 | |
| 3362 | // Collect projections only inside select statement |
| 3363 | if !context.has_select_statement { |
| 3364 | context.projection_names.push(value.to_string()); |
| 3365 | context.projection_locations.push(location); |
| 3366 | |
| 3367 | // If user perform member access with Composite type, composite type name should be in hidden selection |
| 3368 | // For example `SELECT (commit).author_name`, commit should be in hidden selection |
| 3369 | if let Some(symbol_type) = env.schema.tables_fields_types.get(&value.as_str()) { |
| 3370 | if symbol_type.is_composite() && !context.hidden_selections.contains(&value) { |
| 3371 | context.hidden_selections.push(value.to_string()); |
| 3372 | } |
| 3373 | } |
| 3374 | } |
| 3375 | |
| 3376 | // In case of using un selected column name inside OVER(....) clauses, mark it as hidden selection for now |
| 3377 | if context.inside_over_clauses |
| 3378 | && env.schema.tables_fields_types.contains_key(&value.as_str()) |
| 3379 | && !context.hidden_selections.contains(&value) |
| 3380 | { |
| 3381 | context.hidden_selections.push(value.to_string()); |
| 3382 | } |
| 3383 | |
| 3384 | if context.has_select_statement { |
| 3385 | // Replace name by alias if it used after select statement |
| 3386 | // This workaround will help to execute query like |
| 3387 | // SELECT commit_count as cc from branches where commit_count > 1 |
| 3388 | if context.name_alias_table.contains_key(&value) { |
| 3389 | value = context.name_alias_table[&value].to_string(); |
| 3390 | } |
| 3391 | |
| 3392 | if !env.scopes.contains_key(&value) { |
| 3393 | return Err(Diagnostic::error("Unresolved column or variable name") |
| 3394 | .add_help("Please check schema from docs website or SHOW query") |
| 3395 | .with_location(tokens[*position].location) |
| 3396 | .as_boxed()); |
| 3397 | } |
| 3398 | |
| 3399 | if !context.selected_fields.contains(&value) { |
| 3400 | context.hidden_selections.push(value.to_string()); |
| 3401 | } |
| 3402 | } |
| 3403 | |
| 3404 | let mut symbol_name = &value; |
| 3405 | |
| 3406 | // If this symbol is alias, resolve it back to the original name and perform the checks |
| 3407 | let has_alias = context.name_alias_table.values().any(|v| v.eq(symbol_name)); |
| 3408 | if has_alias { |
| 3409 | for (key, value) in context.name_alias_table.iter() { |
| 3410 | if value.eq(symbol_name) { |
no test coverage detected
searching dependent graphs…