index bounds row types

There's two parts to this:
1. Range endpoints with null values are typed
2. Range bounds have the type of the actual bound, not the index. TypeResolver checks that these two values are comparable, and only cast when appropriate, so it's just a matter of returning the right type here.