Use COALESCE instead of NVL for nested ??
See original GitHub issueThis is not a bug, everything works fine. It’s a small SQL codegen improvement.
linq2db uses nvl
to translate ??
, which is nice because it’s shorter than SQL standard coalesce
.
The trick with nvl
is that it only accepts 2 parameters, whereas coalesce
accepts many.
In our codebase, we have a query that computes an error message based on a list of checks, it looks like this:
That’s 7 ??
chained.
The resulting SQL is of course 7 nested nvls: nvl(.., nvl(.., nvl(.., /*4 more*/)))))))
.
It works well enough, I just think it’d be easier to read if it was a single coalesce(.., .., .., .., .., .., ..)
.
So my suggestion is to convert nested ??
expressions into a single coalesce
instead of nested nvl
.
This expression tree:
Could be converted into
coalesce(A, B, C, D, E)
(i.e. a depth-first traversal).
A related Oracle SQL codegen you could have is convert patterns a == null ? c : d
(and a != null
) into nvl2(a, d, c)
(resp. a, c, d).
nvl2 is another Oracle proprietary function that returns the 2nd arg if the first is not null, and the 2rd arg is the first is null.
Issue Analytics
- State:
- Created 2 years ago
- Comments:21 (21 by maintainers)
Seems like I need to dig up the codebase a little bit for this one. Let me raise a PR for the first part. Would take care this one in a separate PR.
Yes,
COALESCE
is the SQL standard function for that purpose.NVL
is an Oracle proprietary function that performs the same, but only for 2 parameters.So you’re right, this conversion is unnecessary. As it is in place and generates shorter SQL I’d say it’s nice to keep it in? I don’t know who wrote this piece of code but it was the intention to generate “optimized” code per provider. Plus having only 2 parameters is quite a common case.