Signed-off-by: Jeremy Kerr <j...@ozlabs.org> --- src/backend/utils/adt/varchar.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-)
diff --git a/src/backend/utils/adt/varchar.c b/src/backend/utils/adt/varchar.c index 5f3c658..6889dff 100644 --- a/src/backend/utils/adt/varchar.c +++ b/src/backend/utils/adt/varchar.c @@ -624,16 +624,34 @@ varchartypmodout(PG_FUNCTION_ARGS) static int bcTruelen(BpChar *arg) { + const unsigned int spaces = 0x20202020; + const int wordsize = sizeof(spaces); char *s = VARDATA_ANY(arg); int i; - int len; - len = VARSIZE_ANY_EXHDR(arg); - for (i = len - 1; i >= 0; i--) + i = VARSIZE_ANY_EXHDR(arg) - 1; + + /* compare down to an aligned boundary */ + for (; i >= 0 && i % wordsize != wordsize - 1; i--) { if (s[i] != ' ') + return i + 1; + } + + /* now that we're aligned, compare word at a time */ + for (; i >= wordsize - 1; i -= wordsize) + { + if (*(unsigned int *)(s + i - (wordsize - 1)) != spaces) break; } + + /* check within the last non-matching word */ + for (; i >= 0; i--) + { + if (s[i] != ' ') + break; + } + return i + 1; } -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers