|
15 | 15 |
|
16 | 16 | #include "catalog/namespace.h"
|
17 | 17 | #include "commands/defrem.h"
|
| 18 | +#include "lib/stringinfo.h" |
18 | 19 | #include "tsearch/ts_cache.h"
|
19 | 20 | #include "tsearch/ts_locale.h"
|
20 | 21 | #include "tsearch/ts_public.h"
|
@@ -263,46 +264,48 @@ unaccent_lexize(PG_FUNCTION_ARGS)
|
263 | 264 | TrieChar *rootTrie = (TrieChar *) PG_GETARG_POINTER(0);
|
264 | 265 | char *srcchar = (char *) PG_GETARG_POINTER(1);
|
265 | 266 | int32 len = PG_GETARG_INT32(2);
|
266 |
| - char *srcstart, |
267 |
| - *trgchar = NULL; |
268 |
| - int charlen; |
269 |
| - TSLexeme *res = NULL; |
270 |
| - TrieChar *node; |
| 267 | + char *srcstart = srcchar; |
| 268 | + TSLexeme *res; |
| 269 | + StringInfoData buf; |
| 270 | + |
| 271 | + /* we allocate storage for the buffer only if needed */ |
| 272 | + buf.data = NULL; |
271 | 273 |
|
272 |
| - srcstart = srcchar; |
273 | 274 | while (srcchar - srcstart < len)
|
274 | 275 | {
|
| 276 | + TrieChar *node; |
| 277 | + int charlen; |
| 278 | + |
275 | 279 | charlen = pg_mblen(srcchar);
|
276 | 280 |
|
277 | 281 | node = findReplaceTo(rootTrie, (unsigned char *) srcchar, charlen);
|
278 | 282 | if (node && node->replaceTo)
|
279 | 283 | {
|
280 |
| - if (!res) |
| 284 | + if (buf.data == NULL) |
281 | 285 | {
|
282 |
| - /* allocate res only if it's needed */ |
283 |
| - res = palloc0(sizeof(TSLexeme) * 2); |
284 |
| - res->lexeme = trgchar = palloc(len * pg_database_encoding_max_length() + 1 /* \0 */ ); |
285 |
| - res->flags = TSL_FILTER; |
| 286 | + /* initialize buffer */ |
| 287 | + initStringInfo(&buf); |
| 288 | + /* insert any data we already skipped over */ |
286 | 289 | if (srcchar != srcstart)
|
287 |
| - { |
288 |
| - memcpy(trgchar, srcstart, srcchar - srcstart); |
289 |
| - trgchar += (srcchar - srcstart); |
290 |
| - } |
| 290 | + appendBinaryStringInfo(&buf, srcstart, srcchar - srcstart); |
291 | 291 | }
|
292 |
| - memcpy(trgchar, node->replaceTo, node->replacelen); |
293 |
| - trgchar += node->replacelen; |
294 |
| - } |
295 |
| - else if (res) |
296 |
| - { |
297 |
| - memcpy(trgchar, srcchar, charlen); |
298 |
| - trgchar += charlen; |
| 292 | + appendBinaryStringInfo(&buf, node->replaceTo, node->replacelen); |
299 | 293 | }
|
| 294 | + else if (buf.data != NULL) |
| 295 | + appendBinaryStringInfo(&buf, srcchar, charlen); |
300 | 296 |
|
301 | 297 | srcchar += charlen;
|
302 | 298 | }
|
303 | 299 |
|
304 |
| - if (res) |
305 |
| - *trgchar = '\0'; |
| 300 | + /* return a result only if we made at least one substitution */ |
| 301 | + if (buf.data != NULL) |
| 302 | + { |
| 303 | + res = (TSLexeme *) palloc0(sizeof(TSLexeme) * 2); |
| 304 | + res->lexeme = buf.data; |
| 305 | + res->flags = TSL_FILTER; |
| 306 | + } |
| 307 | + else |
| 308 | + res = NULL; |
306 | 309 |
|
307 | 310 | PG_RETURN_POINTER(res);
|
308 | 311 | }
|
|
0 commit comments