When I did this in DB2, I didn't use the parser - it was too expensive. I just tokenized the statement and used some simple rules to bypass the invalid cases. For example, if I saw the tokens "ORDER" and "BY" then I'd disallow replacement replacement until I hit the end of the current subquery or statement.
There are a few limitations to this approach. For example, DB2 allowed you to cast using function notation like VARCHAR(foo, 10). This meant I would never replace the second parameter of any VARCHAR function. Now it's possible that when the statement was fully compiled we'd find that VARCHAR(foo,10) actually resolved to BOB.VARCHAR() instead of the built-in cast function. Our thinking that these cases were rare enough that we wouldn't worry about them. (Of course, PostgreSQL's ::VARCHAR(10) syntax avoids this problem completely.) Because SQL is so structured, the implementation ended up being quite simple (a few hundred line of code) with no significant maintenance issues. (Other developers had no problem adding in new cases where constants had to be preserved.) The simple tokenizer was also fairly extensible. I'd prototyped using the same code to also normalize statements (uppercase all keywords, collapse whitespace to a single blank, etc.) but that feature was never added to the product. - Doug On Tue, Apr 25, 2017 at 1:47 PM Konstantin Knizhnik < k.knizh...@postgrespro.ru> wrote: > On 04/25/2017 11:40 PM, Serge Rielau wrote: > > > On Apr 25, 2017, at 1:37 PM, Konstantin Knizhnik < > k.knizh...@postgrespro.ru> wrote: > > > SELECT ‘hello’::CHAR(10) || ‘World’, 5 + 6; > > You can substitute ‘hello’, ‘World’, 5, and 6. But not 10. > > > I am substituting only string literals. So the query above will be > transformed to > > SELECT $1::CHAR(10) || $2, 5 + 6; > > What's wrong with it? > > > Oh, well that leaves a lot of opportunities on the table, doesn’t it? > > > Well, actually my primary intention was not to make badly designed > programs (not using prepared statements) work faster. > I wanted to address cases when it is not possible to use prepared > statements. > If we want to substitute with parameters as much literals as possible, > then parse+deparse tree seems to be the only reasonable approach. > I will try to implement it also, just to estimate parsing overhead. > > > > > Cheers > Serge > > > > -- > Konstantin Knizhnik > Postgres Professional: http://www.postgrespro.com > The Russian Postgres Company > >