(
ecx: &ExprContext,
expr: &Expr<Aug>,
table_func_names: &BTreeMap<String, Ident>,
)
| 3527 | } |
| 3528 | |
| 3529 | fn invent( |
| 3530 | ecx: &ExprContext, |
| 3531 | expr: &Expr<Aug>, |
| 3532 | table_func_names: &BTreeMap<String, Ident>, |
| 3533 | ) -> Result<Option<(ColumnName, NameQuality)>, PlanError> { |
| 3534 | Ok(match expr { |
| 3535 | Expr::Identifier(names) => { |
| 3536 | if let [name] = names.as_slice() { |
| 3537 | if let Some(table_func_name) = table_func_names.get(name.as_str()) { |
| 3538 | return Ok(Some(( |
| 3539 | normalize::column_name(table_func_name.clone()), |
| 3540 | NameQuality::High, |
| 3541 | ))); |
| 3542 | } |
| 3543 | } |
| 3544 | names |
| 3545 | .last() |
| 3546 | .map(|n| (normalize::column_name(n.clone()), NameQuality::High)) |
| 3547 | } |
| 3548 | Expr::Value(v) => match v { |
| 3549 | // Per PostgreSQL, `bool` and `interval` literals take on the name |
| 3550 | // of their type, but not other literal types. |
| 3551 | Value::Boolean(_) => Some(("bool".into(), NameQuality::High)), |
| 3552 | Value::Interval(_) => Some(("interval".into(), NameQuality::High)), |
| 3553 | _ => None, |
| 3554 | }, |
| 3555 | Expr::Function(func) => { |
| 3556 | let (schema, item) = match &func.name { |
| 3557 | ResolvedItemName::Item { |
| 3558 | qualifiers, |
| 3559 | full_name, |
| 3560 | .. |
| 3561 | } => (&qualifiers.schema_spec, full_name.item.clone()), |
| 3562 | // Name resolution should have rejected anything other than |
| 3563 | // `Item` for a function call. |
| 3564 | _ => { |
| 3565 | bail_internal!("function name did not resolve to an item: {:?}", func.name) |
| 3566 | } |
| 3567 | }; |
| 3568 | |
| 3569 | if schema == &SchemaSpecifier::from(ecx.qcx.scx.catalog.get_mz_internal_schema_id()) |
| 3570 | || schema |
| 3571 | == &SchemaSpecifier::from(ecx.qcx.scx.catalog.get_mz_unsafe_schema_id()) |
| 3572 | { |
| 3573 | None |
| 3574 | } else { |
| 3575 | Some((item.into(), NameQuality::High)) |
| 3576 | } |
| 3577 | } |
| 3578 | Expr::HomogenizingFunction { function, .. } => Some(( |
| 3579 | function.to_string().to_lowercase().into(), |
| 3580 | NameQuality::High, |
| 3581 | )), |
| 3582 | Expr::NullIf { .. } => Some(("nullif".into(), NameQuality::High)), |
| 3583 | Expr::Array { .. } => Some(("array".into(), NameQuality::High)), |
| 3584 | Expr::List { .. } => Some(("list".into(), NameQuality::High)), |
| 3585 | Expr::Map { .. } | Expr::MapSubquery(_) => Some(("map".into(), NameQuality::High)), |
| 3586 | Expr::Cast { expr, data_type } => match invent(ecx, expr, table_func_names)? { |
no test coverage detected