Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit dad75eb

Browse files
committed
Have pg_itoa, pg_ltoa and pg_lltoa return the length of the string
Core by no means makes excessive use of these functions, but quite a large number of those usages do require the caller to call strlen() on the returned string. This is quite wasteful since these functions do already have a good idea of the length of the string, so we might as well just have them return that. Reviewed-by: Andrew Gierth Discussion: https://postgr.es/m/CAApHDvrm2A5x2uHYxsqriO2cUaGcFvND%2BksC9e7Tjep0t2RK_A%40mail.gmail.com
1 parent 9a7fccd commit dad75eb

File tree

5 files changed

+38
-25
lines changed

5 files changed

+38
-25
lines changed

src/backend/access/common/printsimple.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -103,19 +103,21 @@ printsimple(TupleTableSlot *slot, DestReceiver *self)
103103
{
104104
int32 num = DatumGetInt32(value);
105105
char str[12]; /* sign, 10 digits and '\0' */
106+
int len;
106107

107-
pg_ltoa(num, str);
108-
pq_sendcountedtext(&buf, str, strlen(str), false);
108+
len = pg_ltoa(num, str);
109+
pq_sendcountedtext(&buf, str, len, false);
109110
}
110111
break;
111112

112113
case INT8OID:
113114
{
114115
int64 num = DatumGetInt64(value);
115116
char str[MAXINT8LEN + 1];
117+
int len;
116118

117-
pg_lltoa(num, str);
118-
pq_sendcountedtext(&buf, str, strlen(str), false);
119+
len = pg_lltoa(num, str);
120+
pq_sendcountedtext(&buf, str, len, false);
119121
}
120122
break;
121123

src/backend/utils/adt/int.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -191,9 +191,7 @@ int2vectorout(PG_FUNCTION_ARGS)
191191
{
192192
if (num != 0)
193193
*rp++ = ' ';
194-
pg_itoa(int2Array->values[num], rp);
195-
while (*++rp != '\0')
196-
;
194+
rp += pg_itoa(int2Array->values[num], rp);
197195
}
198196
*rp = '\0';
199197
PG_RETURN_CSTRING(result);

src/backend/utils/adt/int8.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,9 +149,16 @@ int8out(PG_FUNCTION_ARGS)
149149
int64 val = PG_GETARG_INT64(0);
150150
char buf[MAXINT8LEN + 1];
151151
char *result;
152+
int len;
152153

153-
pg_lltoa(val, buf);
154-
result = pstrdup(buf);
154+
len = pg_lltoa(val, buf) + 1;
155+
156+
/*
157+
* Since the length is already known, we do a manual palloc() and memcpy()
158+
* to avoid the strlen() call that would otherwise be done in pstrdup().
159+
*/
160+
result = palloc(len);
161+
memcpy(result, buf, len);
155162
PG_RETURN_CSTRING(result);
156163
}
157164

src/backend/utils/adt/numutils.c

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -327,16 +327,17 @@ pg_strtoint32(const char *s)
327327

328328
/*
329329
* pg_itoa: converts a signed 16-bit integer to its string representation
330+
* and returns strlen(a).
330331
*
331332
* Caller must ensure that 'a' points to enough memory to hold the result
332333
* (at least 7 bytes, counting a leading sign and trailing NUL).
333334
*
334335
* It doesn't seem worth implementing this separately.
335336
*/
336-
void
337+
int
337338
pg_itoa(int16 i, char *a)
338339
{
339-
pg_ltoa((int32) i, a);
340+
return pg_ltoa((int32) i, a);
340341
}
341342

342343
/*
@@ -404,25 +405,27 @@ pg_ultoa_n(uint32 value, char *a)
404405
}
405406

406407
/*
407-
* NUL-terminate the output of pg_ultoa_n.
408+
* pg_ltoa: converts a signed 32-bit integer to its string representation and
409+
* returns strlen(a).
408410
*
409411
* It is the caller's responsibility to ensure that a is at least 12 bytes long,
410412
* which is enough room to hold a minus sign, a maximally long int32, and the
411413
* above terminating NUL.
412414
*/
413-
void
415+
int
414416
pg_ltoa(int32 value, char *a)
415417
{
416418
uint32 uvalue = (uint32) value;
417-
int len;
419+
int len = 0;
418420

419421
if (value < 0)
420422
{
421423
uvalue = (uint32) 0 - uvalue;
422-
*a++ = '-';
424+
a[len++] = '-';
423425
}
424-
len = pg_ultoa_n(uvalue, a);
426+
len += pg_ultoa_n(uvalue, a + len);
425427
a[len] = '\0';
428+
return len;
426429
}
427430

428431
/*
@@ -510,24 +513,27 @@ pg_ulltoa_n(uint64 value, char *a)
510513
}
511514

512515
/*
513-
* pg_lltoa: convert a signed 64-bit integer to its string representation
516+
* pg_lltoa: converts a signed 64-bit integer to its string representation and
517+
* returns strlen(a).
514518
*
515519
* Caller must ensure that 'a' points to enough memory to hold the result
516520
* (at least MAXINT8LEN + 1 bytes, counting a leading sign and trailing NUL).
517521
*/
518-
void
522+
int
519523
pg_lltoa(int64 value, char *a)
520524
{
521-
int len;
522525
uint64 uvalue = value;
526+
int len = 0;
523527

524528
if (value < 0)
525529
{
526-
*a++ = '-';
527530
uvalue = (uint64) 0 - uvalue;
531+
a[len++] = '-';
528532
}
529-
len = pg_ulltoa_n(uvalue, a);
530-
a[len] = 0;
533+
534+
len += pg_ulltoa_n(uvalue, a + len);
535+
a[len] = '\0';
536+
return len;
531537
}
532538

533539

src/include/utils/builtins.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,11 @@ extern int namestrcmp(Name name, const char *str);
4747
extern int32 pg_atoi(const char *s, int size, int c);
4848
extern int16 pg_strtoint16(const char *s);
4949
extern int32 pg_strtoint32(const char *s);
50-
extern void pg_itoa(int16 i, char *a);
50+
extern int pg_itoa(int16 i, char *a);
5151
extern int pg_ultoa_n(uint32 l, char *a);
5252
extern int pg_ulltoa_n(uint64 l, char *a);
53-
extern void pg_ltoa(int32 l, char *a);
54-
extern void pg_lltoa(int64 ll, char *a);
53+
extern int pg_ltoa(int32 l, char *a);
54+
extern int pg_lltoa(int64 ll, char *a);
5555
extern char *pg_ultostr_zeropad(char *str, uint32 value, int32 minwidth);
5656
extern char *pg_ultostr(char *str, uint32 value);
5757
extern uint64 pg_strtouint64(const char *str, char **endptr, int base);

0 commit comments

Comments
 (0)