|
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