Function validateWhereExpression

  • Experimental

    Contain a caller-authored Query.where expression before it is embedded in generated DuckDB SQL, returning the trimmed text on success.

    where is raw filter SQL — the GeoParquet/DuckDB lane has no value-escaping equivalent for it, and the semantic (typed, parameterized) compiler in query-planner/duckdb.ts is the path that removes the raw text entirely. Until a caller migrates to that path, this validator draws the boundary:

    Guaranteed by this function. The accepted text is a single expression that cannot leave the WHERE ( … ) slot it is spliced into. It rejects, with a typed GeoParquetWhereClauseError:

    • statement separators (;) and therefore chained/multi-statement input;
    • SQL comments — both line (--) and block comment markers — including the trailing-comment trick that would otherwise swallow the compiler's own AND (<spatial predicate>);
    • unterminated string / quoted-identifier literals, which is how x' OR 1=1 style probes escape a literal;
    • E'…' escape strings, where a backslash escapes a quote: that second escaping grammar would let a literal end for this scanner but not for DuckDB, so every boundary after it is mis-parsed. Plain literals with doubled quotes carry the same data;
    • unbalanced parentheses, so the wrapping ( … ) cannot be closed early to re-associate or append clauses;
    • SELECT / UNION and other statement or set-operation keywords, plus a table-context FROM, so a filter cannot become a subquery or UNION probe that reads other tables or files registered in the same DuckDB session. FROM stays available in its expression forms — EXTRACT(YEAR FROM ts), TRIM(BOTH ' ' FROM name), SUBSTRING(name FROM 2 FOR 3), OVERLAY(…);
    • parameter markers (?, $1, $name) — this lane binds no values;
    • control characters other than tab / newline / carriage return.

    Still the caller's responsibility. This is containment, not a semantic parser: accepted text is still executed by DuckDB. It can reference any column in the scanned files, call any scalar function the session exposes, and cost arbitrary CPU. Fabricating a syntactically invalid expression still fails at DuckDB, not here. Applications that forward end-user input (a filter box, a URL parameter) should build the expression from typed inputs rather than concatenating strings, and treat this validator as a backstop.

    The Source.protocol("geoparquet").sql(...) handle remains an explicit, opt-in raw-SQL escape hatch and is deliberately not covered here.

    Parameters

    • where: string

    Returns string