PRQL/prql · error
prql_to_sql! proc macro expected a string
Error message
prql_to_sql! proc macro expected a string
What it means
prql_to_sql! is a proc macro that compiles a PRQL string literal to SQL at compile time. It only accepts a single string literal argument; any other token (identifiers, non-string literals, expressions, concatenation) panics with this message. Because it is a proc macro, the panic surfaces as a compile-time error in the calling crate.
Solutions
- Pass a plain string literal directly inside prql_to_sql!("...")
- If the query must be dynamic, call prqlc::compile at runtime instead of the macro
- Use include_str! to load a .prql file as the literal argument, which is accepted since it expands to a string literal
- Check that you are not wrapping the argument in extra macros like concat! or format!
Example fix
// before
let q = "from employees | filter age > 21";
let sql = prql_to_sql!(q);
// after
let sql = prql_to_sql!("from employees | filter age > 21"); Defensive patterns
Strategy: validation
Validate before calling
// Only string literals are accepted
const QUERY: &str = "from employees | take 5"; // literal itself, not a variable
let sql = prql_to_sql!(QUERY); // WRONG
let sql = prql_to_sql!("from employees | take 5"); // correct Type guard
macro_rules! ensure_str { ($l:literal) => {}; ($e:expr) => { compile_error!("prql_to_sql! requires a string literal") }; } Prevention
- Always inline the PRQL as a string literal directly in the macro
- Use include_str!("query.prql") for large queries instead of variables
- Reserve prqlc::compile (runtime) for dynamic queries
When it happens
Trigger: Invoking prql_to_sql! with a non-string-literal argument: a variable (prql_to_sql!(my_query)), a numeric/bool literal, concat!(...), format!(...), or an empty/no argument at all.
Common situations: Developers trying to reuse the PRQL query stored in a const/variable, building the query dynamically, or passing include_str! output concatenated with other strings; also typos like double-nesting prql_to_sql!(prql_to_sql!(...)).
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- {}
- Could not parse PRQL version
- Could not parse prqlc version number
- Crate is not built with the `cli` feature enabled, or was…
- tuple: expected to have at least one entry when initial…
AI-assisted analysis of PRQL/prql@e164e249b9 (2026-09-09).
Data as JSON: /api/errors/ff5a5c9aab4337f8.
Report an issue: GitHub.
Appendix: source
Thrown at prqlc/prqlc-macros/src/lib.rs:24
//! let sql: &str = prql_to_sql!("from albums | select {title, artist_id}");
//! assert_eq!(sql, "SELECT title, artist_id FROM albums");
//! ```
//!
//! "at build time" means that PRQL will be compiled during Rust compilation,
//! producing errors alongside Rust errors. Limited to string literals.
use proc_macro::{Literal, TokenStream, TokenTree};
use syn::{Expr, ExprLit, Lit};
#[proc_macro]
pub fn prql_to_sql(input: TokenStream) -> TokenStream {
let input: Expr = syn::parse(input).unwrap();
let prql_string = match input {
Expr::Lit(ExprLit {
lit: Lit::Str(lit_str),
..
}) => lit_str.value(),
_ => panic!("prql_to_sql! proc macro expected a string"),
};
let opts = prqlc::Options::default().no_format().no_signature();
let sql_string = match prqlc::compile(&prql_string, &opts) {
Ok(r) => r,
Err(err) => {
panic!("{}", err);
}
};
TokenStream::from_iter(vec![TokenTree::Literal(Literal::string(&sql_string))])
}
View on GitHub (pinned to e164e249b9)