Email list hosting service & mailing list manager

Named vs numbered SQL parameters Lassi Kortela (18 Sep 2019 08:48 UTC)
Re: Named vs numbered SQL parameters Peter Bex (18 Sep 2019 09:13 UTC)
Re: Named vs numbered SQL parameters Lassi Kortela (18 Sep 2019 09:35 UTC)
Re: Named vs numbered SQL parameters Peter Bex (18 Sep 2019 09:49 UTC)
Re: Named vs numbered SQL parameters Lassi Kortela (18 Sep 2019 10:10 UTC)
Re: Named vs numbered SQL parameters Peter Bex (18 Sep 2019 10:16 UTC)
Re: Named vs numbered SQL parameters Lassi Kortela (18 Sep 2019 10:30 UTC)
Re: Named vs numbered SQL parameters Peter Bex (18 Sep 2019 10:38 UTC)
Re: Named vs numbered SQL parameters Lassi Kortela (18 Sep 2019 10:50 UTC)
Re: Named vs numbered SQL parameters Alaric Snell-Pym (18 Sep 2019 10:39 UTC)
Re: Named vs numbered SQL parameters Lassi Kortela (19 Sep 2019 14:20 UTC)
Re: Named vs numbered SQL parameters Peter Bex (19 Sep 2019 14:53 UTC)
Re: Named vs numbered SQL parameters Alaric Snell-Pym (19 Sep 2019 16:05 UTC)
Re: Named vs numbered SQL parameters John Cowan (18 Sep 2019 22:36 UTC)
Re: Named vs numbered SQL parameters Peter Bex (19 Sep 2019 07:20 UTC)
Re: Named vs numbered SQL parameters John Cowan (19 Sep 2019 13:54 UTC)
Re: Named vs numbered SQL parameters Peter Bex (19 Sep 2019 14:04 UTC)
Re: Named vs numbered SQL parameters Lassi Kortela (19 Sep 2019 14:07 UTC)
Re: Named vs numbered SQL parameters Peter Bex (19 Sep 2019 14:19 UTC)
Re: Named vs numbered SQL parameters Lassi Kortela (19 Sep 2019 14:28 UTC)
Re: Named vs numbered SQL parameters Alaric Snell-Pym (19 Sep 2019 16:00 UTC)

Re: Named vs numbered SQL parameters Lassi Kortela 18 Sep 2019 10:10 UTC

> [braces] balance nicely and allows you to
> more easily navigate over them using something like "next expression" in
> a proper editor.

True as well!

Also, it's easier to figure out how to replace "{cad}" in
"abra{cad}abra" than how to replace "$cad" in "abra$cadabra". No
ambiguity about what to do when the placeholder is in the middle of a
bigger word. We just have to ban braces in the placeholder name itself,
so '|{foo}| and '|{foo| and '|foo}| are not valid placeholder symbols.

> Yeah, I would go for the single braces, there's a lot of duplicate things
> in this query already.

Fine :)

> So if we had
>
>       (sql-execute
>        "INSERT INTO foo VALUES ({myval1}, '{myval2}'::text[])"
>        '((myval1 . 1)))
>
> this would simply insert a tuple of 1 and the array with the single
> string value 'myval2' into the table, right?  Because myval2 is not
> supplied, it gets converted to
>
>     "INSERT INTO foo VALUES ($1, '{myval2}'::text[])".
>
> or in MySQL:
>
>     "INSERT INTO foo VALUES (?, '{myval2}'::text[])".

Yeah. (Added the missing closing ' quotes that you probably intended.)

It does look counterintuitive that {myval2} is not expanded, but I don't
see a way to avoid situations like this without a baroque SQL parser.

> I could see some problems with this if the user would incorrectly quote
> their expressions.  In the case of
>
>       (sql-execute
>        "INSERT INTO foo VALUES ('{myval1}', '{myval2}'::text[])"
>        '((myval1 . "hi there")))
>
> it would get translated into the following, because we're doing "dumb"
> replacement:
>
>     "INSERT INTO foo VALUES ('$1', '{myval2}'::text[])"
>
> or in MySQL:
>
>     "INSERT INTO foo VALUES ('?', '{myval2}'::text[])"
>
> With a positional parameter of 'hi there', which will hopefully give
> an error message.

Good point. So in this case, the DB engine would not parse any parameter
names from the SQL query, but we would send it one parameter anyway.
I.e. the same thing as calling a procedure with too many arguments in a
programming language.

Again, how to avoid this without a baroque parser? There is probably no way.

One more thing that bothers me is that in (sql-execute sql params), the
sql string and params list can come from anywhere. This is similar to
the classic problems with printf() in C, and there evolved a convention
of always using a constant string for the formatting template.

In Scheme, this might be a good place for a macro so we can guarantee
that the query is a literal string, we can parse the placeholders from
the string template at macroexpansion time, can parse the parameter
names (which must be symbols known at macroexpansion time), and can
check that the set of placeholders exactly matches the set of symbols.

There could be a low-level (sql-execute-raw ...) that is a procedure
instead of a macro.