> On Tue, Feb 11, 2025 at 08:00:27PM GMT, Dmitry Dolgov wrote: > > Hmm, what about doing something much simpler, such as testing whether > > there's just a CoerceViaIO/RelabelType around a Const or a one-parameter > > function call of an immutable boostrap-OID function that has a Const as > > argument, and trivial cases like that? Something very very simple > > that's going to catch the majority of cases without anything as complex > > as a node walker. > > > > Maybe something like statext_is_compatible_clause_internal() can be an > > inspiration (and even that is far more complex than we need here.) > > I'm somewhat hesitant to cover only some cases, but let me try, maybe > it's indeed going to be good enough.
I've been experimenting with this today, and while it's easy to implement, there is one annoying thing for which I don't have a solution yet. When generating a normalized version for such merged queries in pgss we rely on expression location, something like: select i from t where i in (a1, a2, a3, ..., aN); | | expr loc1 expr loc2 We remember loc1 and loc2, then do not copy anything between then into the normalized query. Now, the expression location is only known up to the parsing token, without taking into account e.g. parenthesis in more complex expressions. Which means we don't know exactly where an expression starts or ends, and it's hard to correctly represent queries like: select i from t where i in (((a1)), ((a2)), ((a3)), ..., ((aN))); | | expr loc1 expr loc2 The normalized version looks like this: select i from t where i in (((...))); While it does not affect the actual functionality and is purely cosmetic, it's quite visible and causes questions. In theory this could be addressed by extending fill_in_constant_lengths to chase parenthesis, but it sounds complicated. Another option is to try a different visual representation of merging, something that will keep the first and the last constant intact.