sqlfmt icon indicating copy to clipboard operation
sqlfmt copied to clipboard

Statement Parameters are not handled correctly

Open BramGruneir opened this issue 6 years ago • 9 comments

The common ones that I can think of are:

  • ?
  • $0, $1 ...
  • %0, %1 ...

I guess, it's probably best to handle ?, $, % with and without numbers.

e.g.

SELECT * FROM pg_catalog.pg_foreign_table WHERE ftrelid = ?;

BramGruneir avatar Aug 06 '18 18:08 BramGruneir

What's the motivation for this? Pg/CRDB don't support ? afaik. sqlfmt has a limited goal of parsing PG SQL.

maddyblue avatar Aug 06 '18 18:08 maddyblue

Query rewriting when coding and eventually integration within an editor. I get a ton of queries that are destined not to be ingested directly, but instead used in coding. I always want those formatted correctly.

Golang's db package uses ? for example:

updateMoney, err := db.Prepare("UPDATE balance SET money=money+? WHERE id=?")
...
tx, err := db.Begin()
...
res, err := tx.Stmt(updateMoney).Exec(123.45, 98293203)

This is from here: https://golang.org/pkg/database/sql/#Tx.Stmt

BramGruneir avatar Aug 06 '18 19:08 BramGruneir

I guess my point is that currently, sqlfmt's goal is to format PG SQL. ? is not valid in postgres, so sqlfmt also doesn't think it's valid. Supporting all or more forms of SQL changes the goal of sqlfmt. Maybe that's ok but it would bump the complexity up at least a little.

maddyblue avatar Aug 06 '18 19:08 maddyblue

If I have some spare cycles, I might hack away and send you a PR. This hurts the usefulness of the website when coding.

BramGruneir avatar Aug 06 '18 20:08 BramGruneir

Ok. Out of curiosity, how do you expect this to work? We'd have to teach the cockroach parser about ?. Maybe we could change the placeholder datum type to also take a placeholder character so it can parse and print them correctly? @knz thoughts?

maddyblue avatar Aug 06 '18 20:08 maddyblue

I honestly haven't looked at it all, but yes, that was the idea.

BramGruneir avatar Aug 06 '18 21:08 BramGruneir

This is going to break horribly. What you really need to do is to filter the query through the Go text subtitution for question marks (which may live in lib/pq?) and the get the placeholders out of that, then parse that with sqlfmt.

knz avatar Aug 06 '18 21:08 knz

So the detail of why it will break:

  • the usage of a ? for placeholders is not part of the pgwire protocol / pg SQL syntax. It is the responsibility of the client driver/framework to perform this substitution.
  • when the developer of a client driver/framework makes a mistake and does not perform this substitution correctly, it is the responsibility of the pg/crdb server to report an error ("syntax '?' not recognized" or similar) to explain to the client programmer that they made a mistake
  • if we were to change crdb to silently accept this syntax for whatever reason, we'd start silently accepting bogus requests by erroneous client drivers. Who knows what hell would ensue (including potentially insecure data being processed by our engine...)

knz avatar Aug 07 '18 05:08 knz

I also forgot to mention that a standalone ? is a valid SQL operator now (it's a JSON operator).

knz avatar Aug 07 '18 08:08 knz