| From: | Tatsuo Ishii <ishii(at)postgresql(dot)org> |
|---|---|
| To: | li(dot)evan(dot)chao(at)gmail(dot)com |
| Cc: | vik(at)postgresfriends(dot)org, david(dot)g(dot)johnston(at)gmail(dot)com, jacob(dot)champion(at)enterprisedb(dot)com, er(at)xs4all(dot)nl, peter(at)eisentraut(dot)org, pgsql-hackers(at)postgresql(dot)org |
| Subject: | Re: Row pattern recognition |
| Date: | 2025-11-27 03:10:08 |
| Message-ID: | 20251127.121008.1999156897377972745.ishii@postgresql.org |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-hackers |
Hi Chao,
Any comment on this?
>> 13 - 0005 - nodeWindowAgg.c
>> ```
>> static
>> int
>> do_pattern_match(char *pattern, char *encoded_str, int len)
>> {
>> static regex_t *regcache = NULL;
>> static regex_t preg;
>> static char patbuf[1024]; /* most recent 'pattern' is cached here */
>> ```
>>
>> Using static variable in executor seems something I have never seen, which may persistent data across queries. I think usually per query data are stored in state structures.
>
>Yeah, such a usage maybe rare. But I hesitate to store the data
>(regex_t) in WindowAggState because:
>
>(1) it bloats WindowAggState which we want to avoid if possible
>(2) it requires execnodes.h to include regex.h. (maybe this itself is harmless, I am not sure)
>
>> 14 - 0005 - nodeWindowAgg.c
>> ```
>> + MemoryContext oldContext = MemoryContextSwitchTo(TopMemoryContext);
>> +
>> + if (regcache != NULL)
>> + pg_regfree(regcache); /* free previous re */
>> +
>> + /* we need to convert to char to pg_wchar */
>> + plen = strlen(pattern);
>> + data = (pg_wchar *) palloc((plen + 1) * sizeof(pg_wchar));
>> + data_len = pg_mb2wchar_with_len(pattern, data, plen);
>> + /* compile re */
>> + sts = pg_regcomp(&preg, /* compiled re */
>> + data, /* target pattern */
>> + data_len, /* length of pattern */
>> + cflags, /* compile option */
>> + C_COLLATION_OID /* collation */
>> + );
>> + pfree(data);
>> +
>> + MemoryContextSwitchTo(oldContext);
>> ```
>>
>> Here in do_pattern_match, it switches to top memory context and compiles the re and stores to “preg". Based on the comment of pg_regcomp:
>> ```
>> /*
>> * pg_regcomp - compile regular expression
>> *
>> * Note: on failure, no resources remain allocated, so pg_regfree()
>> * need not be applied to re.
>> */
>> int
>> pg_regcomp(regex_t *re,
>> const chr *string,
>> size_t len,
>> int flags,
>> Oid collation)
>> ```
>>
>> “preg” should be freed by pg_regfree(), given the memory is allocated in TopMemoryContext, this looks like a memory leak.
>
>I admit current patch leaves the memory unfreed even after a query
>finishes. What about adding something like:
>
>static void do_pattern_match_end(void)
>{
> if (regcache != NULL)
> pg_regfree(regcache);
>}
>
>and let ExecEndWindowAgg() call it?
Best regards,
--
Tatsuo Ishii
SRA OSS K.K.
English: http://www.sraoss.co.jp/index_en/
Japanese:http://www.sraoss.co.jp
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Amit Langote | 2025-11-27 03:10:54 | Re: Refactoring: Use soft error reporting for *_opt_overflow functions of date/timestamp |
| Previous Message | 邱宇航 | 2025-11-27 03:07:43 | Re: Add pg_buffercache_mark_dirty[_all] functions to the pg_buffercache |