I have just come across this project (as a long time Snowflake buyer / user) and am super excited by the potential, and started to build out a library for it for my open source BI platform (see https://www.drizby.com/), via https://github.com/cliftonc/drizzle-databend.
However, I immediately ran into what I think is potentially a major issue ...
The /v1/query HTTP endpoint currently accepts only a sql string field. Parameter binding is handled entirely client-side by bendsql: the driver parses the SQL AST to find placeholders (?, $1, :name), calls Param::as_sql_string() on each value, and sends the fully-interpolated SQL string to the server.
This architecture has inherent limitations:
- Security — every client library must independently implement correct escaping. Any new language SDK will face the same problem. Given the prevalence of SQL injection attacks I think this really could be a problem (I think there are also separate issues in your
Param::as_sql_string() functions related to escaping that should be addressed for SQL Injection).
- Performance — the server cannot cache query plans across different parameter values since every execution is a unique SQL string.
- Type fidelity — values are serialized to SQL text and re-parsed by the server.
Proposal
Add a params field to the /v1/query request body:
{
"sql": "SELECT * FROM users WHERE name = $1 AND age > $2",
"params": ["O'Brien", 42]
}
The server would bind parameters directly, eliminating client-side interpolation. This is how PostgreSQL ($1), MySQL (?), and most databases handle HTTP/wire protocol parameters.
Without this, ORM drivers (e.g., drizzle-databend) must pre-escape string values before passing them to bendsql, and convert numeric strings to actual numbers based on column type metadata — effectively reimplementing parts of what server-side binding would provide.
This would be non breaking - as you can just omit it and the sql would still be sql. I'd be happy to look at implementing via a PR, but not sure what your status re. external contributions is?
Related? databendlabs/databend#8802
I have just come across this project (as a long time Snowflake buyer / user) and am super excited by the potential, and started to build out a library for it for my open source BI platform (see https://www.drizby.com/), via https://github.com/cliftonc/drizzle-databend.
However, I immediately ran into what I think is potentially a major issue ...
The
/v1/queryHTTP endpoint currently accepts only a sql string field. Parameter binding is handled entirely client-side by bendsql: the driver parses the SQL AST to find placeholders (?, $1, :name), callsParam::as_sql_string()on each value, and sends the fully-interpolated SQL string to the server.This architecture has inherent limitations:
Param::as_sql_string()functions related to escaping that should be addressed for SQL Injection).Proposal
Add a params field to the /v1/query request body:
{ "sql": "SELECT * FROM users WHERE name = $1 AND age > $2", "params": ["O'Brien", 42] }The server would bind parameters directly, eliminating client-side interpolation. This is how PostgreSQL ($1), MySQL (?), and most databases handle HTTP/wire protocol parameters.
Without this, ORM drivers (e.g., drizzle-databend) must pre-escape string values before passing them to bendsql, and convert numeric strings to actual numbers based on column type metadata — effectively reimplementing parts of what server-side binding would provide.
This would be non breaking - as you can just omit it and the sql would still be sql. I'd be happy to look at implementing via a PR, but not sure what your status re. external contributions is?
Related? databendlabs/databend#8802