I found a fix but I am not qualified to determine if it should go in as a patch.
I basically added a % on each side. I think %% distills down to % without triggering a substitution. http://code.google.com/p/web2py/source/browse/gluon/dal.py#1924 From: key = '%|'+str(second).replace('|','||').replace('%','%%')+'|%' To: key = '%%|'+str(second).replace('|','||').replace('%','%%')+'|%%'