Skip to main content

uqa_sql/expr/
diagnostics.rs

1//
2// Unified Query Algebra
3//
4// Copyright (c) 2023-2026 Cognica, Inc.
5//
6
7//! `PostgreSQL`-compatible scalar type and routine diagnostics.
8
9use uqa_core::{TemporalValue, Value};
10
11use crate::error::SQLError;
12
13pub fn value_type_name(v: &Value) -> &'static str {
14    match v {
15        Value::Null => "unknown",
16        Value::Void => "void",
17        Value::Bool(_) => "boolean",
18        Value::Int(_) => "integer",
19        Value::Float(_) => "double precision",
20        Value::Str(_) => "text",
21        Value::FixedChar(_) => "character",
22        Value::Bytes(_) => "bytea",
23        Value::Temporal(TemporalValue::Interval { .. }) => "interval",
24        Value::Temporal(_) => "timestamp",
25        Value::Decimal(_) => "numeric",
26        Value::Json(_) => "json",
27        Value::JsonB(_) => "jsonb",
28        Value::Array(_) => "anyarray",
29        Value::LegacyVector(vector) => vector.kind().type_name(),
30        Value::List(_) => "anyarray",
31        Value::Row(_) | Value::Record(_) => "record",
32        Value::Map(_) => "jsonb",
33    }
34}
35
36/// `function name(arg types) does not exist` - the error `PostgreSQL`
37/// raises when call resolution fails (SQLSTATE 42883).
38pub fn unknown_function_error(name: &str, args: &[(Option<String>, Value)]) -> SQLError {
39    let types = args
40        .iter()
41        .map(|(arg_name, value)| match arg_name {
42            Some(arg_name) => format!("{arg_name} => {}", value_type_name(value)),
43            None => value_type_name(value).to_string(),
44        })
45        .collect::<Vec<_>>()
46        .join(", ");
47    SQLError::Routine {
48        sqlstate: "42883".into(),
49        message: format!("function {name}({types}) does not exist"),
50    }
51}