I agree that the SQL shouldn't contain errors, however the developer as well should take responsibility of what's passed to the API: if the API decides to throw an exception, the developer as well has to anticipate on that, so has to make sure the right values are passed to the API.
The main problem here is: what to do if the list is empty. The predicate is expected to produce some SQL snippet, so if the list is empty, it has to produce something, but it can't, as the list is empty, so it can't produce a proper range compare.
Though, a runtime exception won't help much as the exception is likely to pop up in production at 3 AM on a sunday morning.
I indeed think '1=0' is a more useful snippet (and if negate is true: '1=1'), as that mimics semantically what's going on.
However, yowl, you've to understand that it's your code calling our code. We can't anticipate on what's 'correct' in the semantical context of your application, you have to check for that. This means that if we decide to throw an exception, you too have to take care of that exception, if you pass null for some parameter to a method and it causes problems, you have to take action, because apparently 'null' doesn't make sense for example. Sure we can throw exceptions all over the place, but that's not going to help you: they pop up at runtime, you have to write your code in such a way that it makes sense what you pass to the methods and ctors you call. Only then you can be sure your software is reliable and has a smaller chance of running into exceptions at runtime. Because the downside of exceptions is that if you don't have a testcase which triggers them, you won't know when or if they pop up.
I'll add behavior for empty lists in fieldcomparerange predicate for v2.6
And to make Simon happy:
http://www.llblgen.com/tinyforum/GotoMessage.aspx?MessageID=77340&ThreadID=13726