Hi Matthew,
the option you chosed to implement string index (in substrings, for example) causes two problems:
1. it can not be optimized, since it comes at SQL generation level, thus we'll get some "-1" (and I don't understand why it is not a "+1", but that is not the point)
2. it works only for Oracle, and that's too selfish :) Some SQL providers may have the same problem too.
So here's my suggestion:
1. ISqlProvider gets a StringIndexStartsAtOne property
2. If the above value it true, then we set the involved argument Expression.Add(originalExpression,Expression.Constant(1)) when creating the SpecialExpression.
3. When the special expression is translated again in CLR, the involved argument coming for SpecialExpression is reverted.
Don't mind if it seems heavy, place such manipulations in a single method.
Such expressions will be optimized when possible (when a constant is used), so we're all good.