I believe that the reason for the local buffer is to hold a downcased version of the input, which we can compare to the all-lower-case tables of relevant keywords.
Well, that's one of the reasons, but not the only one. For example, how do you parse '17 minutes31 seconds'::interval without either a working buffer or the ability to resize the input buffer? (We need to split the input into two fields, each of which must be a NUL-terminated string. These fields are currently implemented as into the working buffer. If we changed that to be pointers into the input string, we have no where to put the NUL terminator. So you either need a separate buffer, repalloc() plus shuffling everything down, or palloc'd allocation for the fields themselves.) So I don't see that fixing the casing issue is sufficient.
On closer inspection, the current code seems to get this wrong as well :-( For example, given the query:
select '4millenniums5centuries4decades1year4months4days17minutes31 seconds'::interval;
attaching via gdb, with a breakpoint at datetime.c:890 --
(gdb) p lp $1 = 0xbfffdde1 "ÿÞ@" (gdb) p lowstr + 25 + 51 $4 = 0xbfffdddc "onds"
(i.e. lp points past the end of lowstr)
-Neil
---------------------------(end of broadcast)--------------------------- TIP 8: explain analyze is your friend