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