Skip to main content

helios_sof/sqlquery/
mod.rs

1//! SQL-on-FHIR v2 `$sqlquery-run` engine.
2//!
3//! Pure execution logic: parse a SQLQuery Library, materialize its `depends-on`
4//! ViewDefinitions into an in-memory SQLite database, bind `Library.parameter`
5//! values to the SQL, run the user query, and format the rows.
6//!
7//! The REST handler in `helios-rest` wires this to storage (resolving Library
8//! / ViewDefinition resources and supplying `RowStream`s from the wired
9//! `SofRunner`); this module contains no storage or HTTP concerns.
10
11pub mod bind;
12pub mod engine;
13pub mod library;
14pub mod output;
15pub mod params;
16
17pub use bind::{BoundParam, bind_supplied_params};
18pub use engine::{ColumnFhirType, InMemorySqlEngine, QueryResult, TableSchema};
19pub use library::{DependsOnView, LibraryParameter, SqlQueryLibrary, parse_sqlquery_library};
20pub use output::format_fhir_parameters;
21pub use params::{SqlQueryRunParams, extract_sqlquery_params_from_json};
22
23use thiserror::Error;
24
25/// Errors produced by the `$sqlquery-run` pipeline.
26#[derive(Debug, Error)]
27pub enum SqlQueryError {
28    #[error("malformed Library: {0}")]
29    MalformedLibrary(String),
30
31    #[error("SQLQuery Library has no SQL content")]
32    MissingSql,
33
34    #[error("depends-on entry missing label")]
35    MissingDependsOnLabel,
36
37    #[error("could not resolve canonical URL: {0}")]
38    UnknownCanonical(String),
39
40    #[error("too many depends-on ViewDefinitions: {count} (max {max})")]
41    TooManyDependsOn { count: usize, max: usize },
42
43    #[error("row limit exceeded ({max} rows)")]
44    RowCapExceeded { max: usize },
45
46    #[error("query exceeded {secs}s timeout")]
47    Timeout { secs: u64 },
48
49    #[error("SQL parse error: {0}")]
50    NotSelect(String),
51
52    #[error("invalid parameter binding: {0}")]
53    BindParameter(String),
54
55    #[error("invalid identifier '{0}': must not contain a double-quote")]
56    InvalidIdentifier(String),
57
58    #[error("SQLite error: {0}")]
59    Sqlite(#[from] rusqlite::Error),
60
61    #[error("composite SQL value for column '{0}' cannot be represented as a FHIR scalar")]
62    UnsupportedFhirValue(String),
63}