Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitff783fb

Browse files
committed
here is a patch fixing today's bug report:
> Date: Thu, 14 Dec 2000 12:44:47 +0100 (CET)> From: Kovacs Zoltan Sandor <tip@pc10.radnoti-szeged.sulinet.hu>> To: pgsql-bugs@postgresql.org> Subject: [BUGS] to_char() causes backend to close connection>> Hi, this query gives different strange results:>> select to_char(now()::abstime,'YYMMDDHH24MI');>> I get e.g. a "backend closed the channel unexpectedly..." error with> successful or failed resetting attempt (indeterministic) Again thanks Kovacs, you found really designing bug, that appearif anyone write bad format template to "number" version of to_char()(as you with 'DD'). Karel
1 parent0cf3765 commitff783fb

File tree

1 file changed

+71
-10
lines changed

1 file changed

+71
-10
lines changed

‎src/backend/utils/adt/formatting.c

Lines changed: 71 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/* -----------------------------------------------------------------------
22
* formatting.c
33
*
4-
* $Header: /cvsroot/pgsql/src/backend/utils/adt/formatting.c,v 1.26 2000/12/03 20:45:35 tgl Exp $
4+
* $Header: /cvsroot/pgsql/src/backend/utils/adt/formatting.c,v 1.27 2000/12/15 19:15:09 momjian Exp $
55
*
66
*
77
* Portions Copyright (c) 1999-2000, PostgreSQL, Inc
@@ -44,6 +44,17 @@
4444
*
4545
*Karel Zak
4646
*
47+
* TODO (7.2):
48+
*- replace some global values by struct that handle it
49+
*- check last used entry in the cache_search
50+
*- better number building (formatting)
51+
*- add support for abstime
52+
*- add support for roman number to standard number conversion
53+
*- add support for number spelling
54+
*- add support for string to string formatting (we must be better
55+
* than Oracle :-),
56+
*to_char('Hello', 'X X X X X') -> 'H e l l o'
57+
*
4758
* -----------------------------------------------------------------------
4859
*/
4960

@@ -334,11 +345,12 @@ static intDCHCounter = 0;
334345

335346
/* global cache for --- number part */
336347
staticNUMCacheEntryNUMCache[NUM_CACHE_FIELDS+1];
348+
staticNUMCacheEntry*last_NUMCacheEntry;
337349

338350
staticintn_NUMCache=0;/* number of entries */
339351
staticintNUMCounter=0;
340352

341-
#defineMAX_INT32(2147483640)
353+
#defineMAX_INT32(2147483600)
342354

343355
/* ----------
344356
* For char->date/time conversion
@@ -850,8 +862,10 @@ static char *NUM_processor(FormatNode *node, NUMDesc *Num, char *inout, char *nu
850862
intplen,intsign,inttype);
851863
staticDCHCacheEntry*DCH_cache_search(char*str);
852864
staticDCHCacheEntry*DCH_cache_getnew(char*str);
865+
853866
staticNUMCacheEntry*NUM_cache_search(char*str);
854867
staticNUMCacheEntry*NUM_cache_getnew(char*str);
868+
staticvoidNUM_cache_remove(NUMCacheEntry*ent);
855869

856870

857871
/* ----------
@@ -917,8 +931,10 @@ NUMDesc_prepare(NUMDesc *num, FormatNode *n)
917931

918932
caseNUM_9:
919933
if (IS_BRACKET(num))
934+
{
935+
NUM_cache_remove(last_NUMCacheEntry);
920936
elog(ERROR,"to_char/to_number(): '9' must be ahead of 'PR'.");
921-
937+
}
922938
if (IS_MULTI(num))
923939
{
924940
++num->multi;
@@ -932,8 +948,10 @@ NUMDesc_prepare(NUMDesc *num, FormatNode *n)
932948

933949
caseNUM_0:
934950
if (IS_BRACKET(num))
951+
{
952+
NUM_cache_remove(last_NUMCacheEntry);
935953
elog(ERROR,"to_char/to_number(): '0' must be ahead of 'PR'.");
936-
954+
}
937955
if (!IS_ZERO(num)&& !IS_DECIMAL(num))
938956
{
939957
num->flag |=NUM_F_ZERO;
@@ -957,9 +975,15 @@ NUMDesc_prepare(NUMDesc *num, FormatNode *n)
957975
num->need_locale= TRUE;
958976
caseNUM_DEC:
959977
if (IS_DECIMAL(num))
978+
{
979+
NUM_cache_remove(last_NUMCacheEntry);
960980
elog(ERROR,"to_char/to_number(): not unique decimal poit.");
981+
}
961982
if (IS_MULTI(num))
983+
{
984+
NUM_cache_remove(last_NUMCacheEntry);
962985
elog(ERROR,"to_char/to_number(): can't use 'V' and decimal poin together.");
986+
}
963987
num->flag |=NUM_F_DECIMAL;
964988
break;
965989

@@ -969,11 +993,15 @@ NUMDesc_prepare(NUMDesc *num, FormatNode *n)
969993

970994
caseNUM_S:
971995
if (IS_LSIGN(num))
996+
{
997+
NUM_cache_remove(last_NUMCacheEntry);
972998
elog(ERROR,"to_char/to_number(): not unique 'S'.");
973-
999+
}
9741000
if (IS_PLUS(num)||IS_MINUS(num)||IS_BRACKET(num))
1001+
{
1002+
NUM_cache_remove(last_NUMCacheEntry);
9751003
elog(ERROR,"to_char/to_number(): can't use 'S' and 'PL'/'MI'/'SG'/'PR' together.");
976-
1004+
}
9771005
if (!IS_DECIMAL(num))
9781006
{
9791007
num->lsign=NUM_LSIGN_PRE;
@@ -992,29 +1020,38 @@ NUMDesc_prepare(NUMDesc *num, FormatNode *n)
9921020

9931021
caseNUM_MI:
9941022
if (IS_LSIGN(num))
1023+
{
1024+
NUM_cache_remove(last_NUMCacheEntry);
9951025
elog(ERROR,"to_char/to_number(): can't use 'S' and 'MI' together.");
996-
1026+
}
9971027
num->flag |=NUM_F_MINUS;
9981028
break;
9991029

10001030
caseNUM_PL:
10011031
if (IS_LSIGN(num))
1032+
{
1033+
NUM_cache_remove(last_NUMCacheEntry);
10021034
elog(ERROR,"to_char/to_number(): can't use 'S' and 'PL' together.");
1003-
1035+
}
10041036
num->flag |=NUM_F_PLUS;
10051037
break;
10061038

10071039
caseNUM_SG:
10081040
if (IS_LSIGN(num))
1041+
{
1042+
NUM_cache_remove(last_NUMCacheEntry);
10091043
elog(ERROR,"to_char/to_number(): can't use 'S' and 'SG' together.");
1010-
1044+
}
10111045
num->flag |=NUM_F_MINUS;
10121046
num->flag |=NUM_F_PLUS;
10131047
break;
10141048

10151049
caseNUM_PR:
10161050
if (IS_LSIGN(num)||IS_PLUS(num)||IS_MINUS(num))
1051+
{
1052+
NUM_cache_remove(last_NUMCacheEntry);
10171053
elog(ERROR,"to_char/to_number(): can't use 'PR' and 'S'/'PL'/'MI'/'SG' together.");
1054+
}
10181055
num->flag |=NUM_F_BRACKET;
10191056
break;
10201057

@@ -1030,11 +1067,15 @@ NUMDesc_prepare(NUMDesc *num, FormatNode *n)
10301067

10311068
caseNUM_V:
10321069
if (IS_DECIMAL(num))
1070+
{
1071+
NUM_cache_remove(last_NUMCacheEntry);
10331072
elog(ERROR,"to_char/to_number(): can't use 'V' and decimal poin together.");
1073+
}
10341074
num->flag |=NUM_F_MULTI;
10351075
break;
10361076

10371077
caseNUM_E:
1078+
NUM_cache_remove(last_NUMCacheEntry);
10381079
elog(ERROR,"to_char/to_number(): 'E' is not supported.");
10391080
}
10401081

@@ -2988,6 +3029,14 @@ NUM_cache_getnew(char *str)
29883029

29893030
for (ent=NUMCache;ent <= (NUMCache+NUM_CACHE_FIELDS);ent++)
29903031
{
3032+
/* entry removed via NUM_cache_remove()
3033+
* can be used here
3034+
*/
3035+
if (*ent->str=='\0')
3036+
{
3037+
old=ent;
3038+
break;
3039+
}
29913040
if (ent->age<old->age)
29923041
old=ent;
29933042
}
@@ -3015,6 +3064,7 @@ NUM_cache_getnew(char *str)
30153064

30163065
zeroize_NUM(&ent->Num);
30173066

3067+
last_NUMCacheEntry=ent;
30183068
returnent;/* never */
30193069
}
30203070

@@ -3040,6 +3090,7 @@ NUM_cache_search(char *str)
30403090
if (strcmp(ent->str,str)==0)
30413091
{
30423092
ent->age= (++NUMCounter);
3093+
last_NUMCacheEntry=ent;
30433094
returnent;
30443095
}
30453096
i++;
@@ -3048,6 +3099,16 @@ NUM_cache_search(char *str)
30483099
return (NUMCacheEntry*)NULL;
30493100
}
30503101

3102+
staticvoid
3103+
NUM_cache_remove(NUMCacheEntry*ent)
3104+
{
3105+
#ifdefDEBUG_TO_FROM_CHAR
3106+
elog(DEBUG_elog_output,"REMOVING ENTRY (%s)",ent->str);
3107+
#endif
3108+
*ent->str='\0';
3109+
ent->age=0;
3110+
}
3111+
30513112
/* ----------
30523113
* Cache routine for NUM to_char version
30533114
* ----------
@@ -3070,7 +3131,7 @@ NUM_cache(int len, NUMDesc *Num, char *pars_str, int *flag)
30703131
* Allocate new memory if format picture is bigger than static cache
30713132
* and not use cache (call parser always) - flag=1 show this variant
30723133
* ----------
3073-
*/
3134+
*/
30743135
if (len>NUM_CACHE_SIZE)
30753136
{
30763137

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp