Skip to main content

nodedb_sql/placeholder_types/
mod.rs

1// SPDX-License-Identifier: Apache-2.0
2
3//! Best-effort type inference for `$N` prepared-statement placeholders.
4//!
5//! The pgwire extended-query protocol lets a client send `Parse` without
6//! declaring any parameter OIDs. The server then has to answer `Describe`
7//! with a `ParameterDescription`, and answering "unknown" (OID 0) for every
8//! position forces well-behaved clients into a failure: `tokio-postgres`
9//! refuses to serialize an `i64` against an unknown OID. This module walks
10//! the *unsubstituted* statement and reports the positions whose type the
11//! SQL — plus the catalog the SQL names — pins down.
12//!
13//! # Why a separate walk rather than planner output
14//!
15//! The planner cannot plan an AST that still contains placeholders — the
16//! resolver has no `Value::Placeholder` arm — and the Control Plane's
17//! schema-inference pass therefore rewrites `$N` to `NULL` in the SQL text
18//! before planning. That rewrite destroys the position → type link, so
19//! inference has to happen here, on the parsed-but-unbound AST.
20//!
21//! # Directionality: under-infer, never over-infer
22//!
23//! A PostgreSQL client that receives an unknown parameter type sends the
24//! value in text format, which the bind layer already handles — so leaving
25//! a position unresolved only costs a text round-trip. Reporting a concrete
26//! OID, by contrast, makes the client commit to that type's *binary*
27//! encoding. Any position whose type is not pinned down unambiguously stays
28//! `None`.
29
30mod catalog_free;
31mod column_backed;
32mod infer;
33mod scope;
34mod slots;
35
36pub use infer::infer_placeholder_types;
37pub use slots::InferredParamType;