summaryrefslogtreecommitdiff
path: root/contrib/unaccent/unaccent.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/unaccent/unaccent.c')
-rw-r--r--contrib/unaccent/unaccent.c45
1 files changed, 24 insertions, 21 deletions
diff --git a/contrib/unaccent/unaccent.c b/contrib/unaccent/unaccent.c
index c7d54b205e..7c4072ed93 100644
--- a/contrib/unaccent/unaccent.c
+++ b/contrib/unaccent/unaccent.c
@@ -15,6 +15,7 @@
#include "catalog/namespace.h"
#include "commands/defrem.h"
+#include "lib/stringinfo.h"
#include "tsearch/ts_cache.h"
#include "tsearch/ts_locale.h"
#include "tsearch/ts_public.h"
@@ -309,9 +310,12 @@ unaccent_lexize(PG_FUNCTION_ARGS)
TrieChar *rootTrie = (TrieChar *) PG_GETARG_POINTER(0);
char *srcchar = (char *) PG_GETARG_POINTER(1);
int32 len = PG_GETARG_INT32(2);
- char *srcstart = srcchar,
- *trgchar = NULL;
- TSLexeme *res = NULL;
+ char *srcstart = srcchar;
+ TSLexeme *res;
+ StringInfoData buf;
+
+ /* we allocate storage for the buffer only if needed */
+ buf.data = NULL;
while (len > 0)
{
@@ -322,37 +326,36 @@ unaccent_lexize(PG_FUNCTION_ARGS)
&matchlen);
if (node && node->replaceTo)
{
- if (!res)
+ if (buf.data == NULL)
{
- /* allocate res only if it's needed */
- res = palloc0(sizeof(TSLexeme) * 2);
- res->lexeme = trgchar = palloc(len * pg_database_encoding_max_length() + 1 /* \0 */ );
- res->flags = TSL_FILTER;
+ /* initialize buffer */
+ initStringInfo(&buf);
+ /* insert any data we already skipped over */
if (srcchar != srcstart)
- {
- memcpy(trgchar, srcstart, srcchar - srcstart);
- trgchar += (srcchar - srcstart);
- }
+ appendBinaryStringInfo(&buf, srcstart, srcchar - srcstart);
}
- memcpy(trgchar, node->replaceTo, node->replacelen);
- trgchar += node->replacelen;
+ appendBinaryStringInfo(&buf, node->replaceTo, node->replacelen);
}
else
{
matchlen = pg_mblen(srcchar);
- if (res)
- {
- memcpy(trgchar, srcchar, matchlen);
- trgchar += matchlen;
- }
+ if (buf.data != NULL)
+ appendBinaryStringInfo(&buf, srcchar, matchlen);
}
srcchar += matchlen;
len -= matchlen;
}
- if (res)
- *trgchar = '\0';
+ /* return a result only if we made at least one substitution */
+ if (buf.data != NULL)
+ {
+ res = (TSLexeme *) palloc0(sizeof(TSLexeme) * 2);
+ res->lexeme = buf.data;
+ res->flags = TSL_FILTER;
+ }
+ else
+ res = NULL;
PG_RETURN_POINTER(res);
}