Re: adding an immutable variant of to_date

From: "Sven R(dot) Kunze" <srkunze(at)mail(dot)de>
To: Andreas Karlsson <andreas(at)proxel(dot)se>, pgsql-hackers(at)postgresql(dot)org
Subject: Re: adding an immutable variant of to_date
Date: 2017-03-09 20:09:20
Message-ID: 3fd60f88-5532-22f3-432b-3d1c91a50450@mail.de
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Thanks!

On 08.03.2017 17:37, Andreas Karlsson wrote:
> The current code for to_char will on the first call to to_char build
> arrays with the localized names of the week days and the months. I
> suspect that you may need to build something similar but a set of
> arrays per locale.

Not sure what the most C-like way of solving this is. Coming from a
Python background, I would tend to use a dict. The keys are the locales,
the values are the arrays.

I would use something which is described here:
http://stackoverflow.com/questions/3269881/how-to-represent-a-python-like-dictionary-in-c
. Preferred libc-related, like hcreate and hsearch.

> See the DCH_to_char function and its call to cache_locale_time.

Alright. Found the cache here:

**** src/backend/utils/adt/pg_locale.c
/* lc_time localization cache */
char *localized_abbrev_days[7];
char *localized_full_days[7];
char *localized_abbrev_months[12];
char *localized_full_months[12];

/* .... */

void
cache_locale_time(void)
{
char *save_lc_time;
time_t timenow;
struct tm *timeinfo;
int i;

#ifdef WIN32
char *save_lc_ctype;
#endif

/* did we do this already? */
if (CurrentLCTimeValid)
return;

I would replace the invalidation check with a hsearch lookup.

Grepping for the cache variables, I found:

~/src/postgres$ grep -r localized_abbrev_days *
src/backend/utils/adt/pg_locale.c:char *localized_abbrev_days[7];
src/backend/utils/adt/pg_locale.c:
cache_single_time(&localized_abbrev_days[i], "%a", timeinfo);
src/backend/utils/adt/formatting.c: char *str =
str_toupper_z(localized_abbrev_days[tm->tm_wday], collid);
src/backend/utils/adt/formatting.c: char *str =
str_initcap_z(localized_abbrev_days[tm->tm_wday], collid);
src/backend/utils/adt/formatting.c: char *str =
str_tolower_z(localized_abbrev_days[tm->tm_wday], collid);
src/include/utils/pg_locale.h:extern char *localized_abbrev_days[];

~/src/postgres$ grep -r localized_full_days *
src/backend/utils/adt/pg_locale.c:char *localized_full_days[7];
src/backend/utils/adt/pg_locale.c:
cache_single_time(&localized_full_days[i], "%A", timeinfo);
src/backend/utils/adt/formatting.c: char *str =
str_toupper_z(localized_full_days[tm->tm_wday], collid);
src/backend/utils/adt/formatting.c: char *str =
str_initcap_z(localized_full_days[tm->tm_wday], collid);
src/backend/utils/adt/formatting.c: char *str =
str_tolower_z(localized_full_days[tm->tm_wday], collid);
src/include/utils/pg_locale.h:extern char *localized_full_days[];

~/src/postgres$ grep -r localized_abbrev_months *
src/backend/utils/adt/pg_locale.c:char *localized_abbrev_months[12];
src/backend/utils/adt/pg_locale.c:
cache_single_time(&localized_abbrev_months[i], "%b", timeinfo);
src/backend/utils/adt/formatting.c: char *str =
str_toupper_z(localized_abbrev_months[tm->tm_mon - 1], collid);
src/backend/utils/adt/formatting.c: char *str =
str_initcap_z(localized_abbrev_months[tm->tm_mon - 1], collid);
src/backend/utils/adt/formatting.c: char *str =
str_tolower_z(localized_abbrev_months[tm->tm_mon - 1], collid);
src/include/utils/pg_locale.h:extern char *localized_abbrev_months[];

srkunze(at)mexico:~/src/postgres$ grep -r localized_full_months *
src/backend/utils/adt/pg_locale.c:char *localized_full_months[12];
src/backend/utils/adt/pg_locale.c:
cache_single_time(&localized_full_months[i], "%B", timeinfo);
src/backend/utils/adt/formatting.c: char *str =
str_toupper_z(localized_full_months[tm->tm_mon - 1], collid);
src/backend/utils/adt/formatting.c: char *str =
str_initcap_z(localized_full_months[tm->tm_mon - 1], collid);
src/backend/utils/adt/formatting.c: char *str =
str_tolower_z(localized_full_months[tm->tm_mon - 1], collid);
src/include/utils/pg_locale.h:extern char *localized_full_months[];

It seems to me, that I would need to make them point to the correct
array address at the beginning of those functions by doing an hsearch.

That step is basically independent of the actual immutable to_date idea.

What do you think?

Best,
Sven

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Sven R. Kunze 2017-03-09 20:20:35 Re: adding an immutable variant of to_date
Previous Message Stephen Frost 2017-03-09 19:46:05 Re: Query fails when SRFs are part of FROM clause (Commit id: 69f4b9c85f)