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