Re: Rethinking parameterized SQL queries
Lassi Kortela 27 Feb 2021 09:13 UTC
Thanks for getting back to the topic with a detailed writeup.
I continue to believe that string handling is an anti-pattern to be
avoided unless absolutely necessary, especially with something like SQL
that can read sensitive data and do destructive writes. I also continue
to believe that prepared statements are mandatory from a security and
performance point of view.
Psycopg, the PostgreSQL interface for Python, is probably one of the
most mature SQL interfaces (it's now going on version 3) and this is the
kind of escaping they did in v2: <https://www.psycopg.org/docs/sql.html.
That page doesn't inspire confidence that they know what they're doing.
The quote_ident() function for escaping identifiers such as table and
column names is a good idea though.
If a complete SQL grammar covering the major DB engines is too hard,
could we at least assume that we can represent a complete tokenization
of the grammar as S-expressions? Something like this:
(let ((foo <...>) (bar <...>))
`(insert into ($table-name ,foo) values (col1 |,| ($column-name ,bar))))
That syntax isn't very good, but the general idea is that the SQL
insert into foo values (bar, baz)
is tokenized as the S-expression
(insert into foo values (bar |,| baz))
which is literal, except that ($type value) escapes that can poke holes
in it and inject variables. You could have many categories:
($view-name "x")
($table-name "x)
($column-name "x")
($parameter 1)
($parameter "foo")
...
as needed.