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

  1. Pass a plain string literal directly inside prql_to_sql!("...")
  2. If the query must be dynamic, call prqlc::compile at runtime instead of the macro
  3. Use include_str! to load a .prql file as the literal argument, which is accepted since it expands to a string literal
  4. 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

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


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)