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

Commit5bf948d

Browse files
committed
Replace static bufs with a StringInfo in cash_words()
For clarity. The code was correct, and the buffer was large enough,but string manipulation with no bounds checking is scary.This incurs an extra palloc+pfree to every call, but in quickperformance testing, it doesn't seem to be significant.Reviewed-by: Robert HaasDiscussion:https://www.postgresql.org/message-id/7f86e06a-98c5-4ce3-8ec9-3885c8de0358@iki.fi
1 parent47c9803 commit5bf948d

File tree

1 file changed

+44
-41
lines changed

1 file changed

+44
-41
lines changed

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

Lines changed: 44 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,9 @@
3535
* Private routines
3636
************************************************************************/
3737

38-
staticconstchar*
39-
num_word(Cashvalue)
38+
staticvoid
39+
append_num_word(StringInfobuf,Cashvalue)
4040
{
41-
staticcharbuf[128];
4241
staticconstchar*constsmall[]= {
4342
"zero","one","two","three","four","five","six","seven",
4443
"eight","nine","ten","eleven","twelve","thirteen","fourteen",
@@ -50,41 +49,42 @@ num_word(Cash value)
5049

5150
/* deal with the simple cases first */
5251
if (value <=20)
53-
returnsmall[value];
52+
{
53+
appendStringInfoString(buf,small[value]);
54+
return;
55+
}
5456

5557
/* is it an even multiple of 100? */
5658
if (!tu)
5759
{
58-
sprintf(buf,"%s hundred",small[value /100]);
59-
returnbuf;
60+
appendStringInfo(buf,"%s hundred",small[value /100]);
61+
return;
6062
}
6163

6264
/* more than 99? */
6365
if (value>99)
6466
{
6567
/* is it an even multiple of 10 other than 10? */
6668
if (value %10==0&&tu>10)
67-
sprintf(buf,"%s hundred %s",
68-
small[value /100],big[tu /10]);
69+
appendStringInfo(buf,"%s hundred %s",
70+
small[value /100],big[tu /10]);
6971
elseif (tu<20)
70-
sprintf(buf,"%s hundred and %s",
71-
small[value /100],small[tu]);
72+
appendStringInfo(buf,"%s hundred and %s",
73+
small[value /100],small[tu]);
7274
else
73-
sprintf(buf,"%s hundred %s %s",
74-
small[value /100],big[tu /10],small[tu %10]);
75+
appendStringInfo(buf,"%s hundred %s %s",
76+
small[value /100],big[tu /10],small[tu %10]);
7577
}
7678
else
7779
{
7880
/* is it an even multiple of 10 other than 10? */
7981
if (value %10==0&&tu>10)
80-
sprintf(buf,"%s",big[tu /10]);
82+
appendStringInfoString(buf,big[tu /10]);
8183
elseif (tu<20)
82-
sprintf(buf,"%s",small[tu]);
84+
appendStringInfoString(buf,small[tu]);
8385
else
84-
sprintf(buf,"%s %s",big[tu /10],small[tu %10]);
86+
appendStringInfo(buf,"%s %s",big[tu /10],small[tu %10]);
8587
}
86-
87-
returnbuf;
8888
}/* num_word() */
8989

9090
staticinlineCash
@@ -960,8 +960,9 @@ cash_words(PG_FUNCTION_ARGS)
960960
{
961961
Cashvalue=PG_GETARG_CASH(0);
962962
uint64val;
963-
charbuf[256];
964-
char*p=buf;
963+
StringInfoDatabuf;
964+
text*res;
965+
Cashdollars;
965966
Cashm0;
966967
Cashm1;
967968
Cashm2;
@@ -970,19 +971,19 @@ cash_words(PG_FUNCTION_ARGS)
970971
Cashm5;
971972
Cashm6;
972973

974+
initStringInfo(&buf);
975+
973976
/* work with positive numbers */
974977
if (value<0)
975978
{
976979
value=-value;
977-
strcpy(buf,"minus ");
978-
p+=6;
980+
appendStringInfoString(&buf,"minus ");
979981
}
980-
else
981-
buf[0]='\0';
982982

983983
/* Now treat as unsigned, to avoid trouble at INT_MIN */
984984
val= (uint64)value;
985985

986+
dollars=val /INT64CONST(100);
986987
m0=val %INT64CONST(100);/* cents */
987988
m1= (val /INT64CONST(100)) %1000;/* hundreds */
988989
m2= (val /INT64CONST(100000)) %1000;/* thousands */
@@ -993,49 +994,51 @@ cash_words(PG_FUNCTION_ARGS)
993994

994995
if (m6)
995996
{
996-
strcat(buf,num_word(m6));
997-
strcat(buf," quadrillion ");
997+
append_num_word(&buf,m6);
998+
appendStringInfoString(&buf," quadrillion ");
998999
}
9991000

10001001
if (m5)
10011002
{
1002-
strcat(buf,num_word(m5));
1003-
strcat(buf," trillion ");
1003+
append_num_word(&buf,m5);
1004+
appendStringInfoString(&buf," trillion ");
10041005
}
10051006

10061007
if (m4)
10071008
{
1008-
strcat(buf,num_word(m4));
1009-
strcat(buf," billion ");
1009+
append_num_word(&buf,m4);
1010+
appendStringInfoString(&buf," billion ");
10101011
}
10111012

10121013
if (m3)
10131014
{
1014-
strcat(buf,num_word(m3));
1015-
strcat(buf," million ");
1015+
append_num_word(&buf,m3);
1016+
appendStringInfoString(&buf," million ");
10161017
}
10171018

10181019
if (m2)
10191020
{
1020-
strcat(buf,num_word(m2));
1021-
strcat(buf," thousand ");
1021+
append_num_word(&buf,m2);
1022+
appendStringInfoString(&buf," thousand ");
10221023
}
10231024

10241025
if (m1)
1025-
strcat(buf,num_word(m1));
1026+
append_num_word(&buf,m1);
10261027

1027-
if (!*p)
1028-
strcat(buf,"zero");
1028+
if (dollars==0)
1029+
appendStringInfoString(&buf,"zero");
10291030

1030-
strcat(buf,(val /100)==1 ?" dollar and " :" dollars and ");
1031-
strcat(buf,num_word(m0));
1032-
strcat(buf,m0==1 ?" cent" :" cents");
1031+
appendStringInfoString(&buf,dollars==1 ?" dollar and " :" dollars and ");
1032+
append_num_word(&buf,m0);
1033+
appendStringInfoString(&buf,m0==1 ?" cent" :" cents");
10331034

10341035
/* capitalize output */
1035-
buf[0]=pg_toupper((unsignedchar)buf[0]);
1036+
buf.data[0]=pg_toupper((unsignedchar)buf.data[0]);
10361037

10371038
/* return as text datum */
1038-
PG_RETURN_TEXT_P(cstring_to_text(buf));
1039+
res=cstring_to_text_with_len(buf.data,buf.len);
1040+
pfree(buf.data);
1041+
PG_RETURN_TEXT_P(res);
10391042
}
10401043

10411044

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp