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

Commit101c7ee

Browse files
committed
Use new overflow aware integer operations.
A previous commit added inline functions that provide fast(er) andcorrect overflow checks for signed integer math. Use them in asignificant portion of backend code. There's more to touch in bothbackend and frontend code, but these were the easily identifiablecases.The old overflow checks are noticeable in integer heavy workloads.A secondary benefit is that getting rid of overflow checks that relyon signed integer overflow wrapping around, will allow us to get ridof -fwrapv in the future. Which in turn slows down other code.Author: Andres FreundDiscussion:https://postgr.es/m/20171024103954.ztmatprlglz3rwke@alap3.anarazel.de
1 parent4d6ad31 commit101c7ee

File tree

14 files changed

+217
-539
lines changed

14 files changed

+217
-539
lines changed

‎contrib/btree_gist/btree_cash.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
#include"btree_gist.h"
77
#include"btree_utils_num.h"
8+
#include"common/int.h"
89
#include"utils/cash.h"
910

1011
typedefstruct
@@ -99,15 +100,14 @@ cash_dist(PG_FUNCTION_ARGS)
99100
Cashr;
100101
Cashra;
101102

102-
r=a-b;
103-
ra=Abs(r);
104-
105-
/* Overflow check. */
106-
if (ra<0|| (!SAMESIGN(a,b)&& !SAMESIGN(r,a)))
103+
if (pg_sub_s64_overflow(a,b,&r)||
104+
r==INT64_MIN)
107105
ereport(ERROR,
108106
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
109107
errmsg("money out of range")));
110108

109+
ra=Abs(r);
110+
111111
PG_RETURN_CASH(ra);
112112
}
113113

‎contrib/btree_gist/btree_int2.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
#include"btree_gist.h"
77
#include"btree_utils_num.h"
8+
#include"common/int.h"
89

910
typedefstructint16key
1011
{
@@ -98,15 +99,14 @@ int2_dist(PG_FUNCTION_ARGS)
9899
int16r;
99100
int16ra;
100101

101-
r=a-b;
102-
ra=Abs(r);
103-
104-
/* Overflow check. */
105-
if (ra<0|| (!SAMESIGN(a,b)&& !SAMESIGN(r,a)))
102+
if (pg_sub_s16_overflow(a,b,&r)||
103+
r==INT16_MIN)
106104
ereport(ERROR,
107105
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
108106
errmsg("smallint out of range")));
109107

108+
ra=Abs(r);
109+
110110
PG_RETURN_INT16(ra);
111111
}
112112

‎contrib/btree_gist/btree_int4.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
#include"btree_gist.h"
77
#include"btree_utils_num.h"
8+
#include"common/int.h"
89

910
typedefstructint32key
1011
{
@@ -99,15 +100,14 @@ int4_dist(PG_FUNCTION_ARGS)
99100
int32r;
100101
int32ra;
101102

102-
r=a-b;
103-
ra=Abs(r);
104-
105-
/* Overflow check. */
106-
if (ra<0|| (!SAMESIGN(a,b)&& !SAMESIGN(r,a)))
103+
if (pg_sub_s32_overflow(a,b,&r)||
104+
r==INT32_MIN)
107105
ereport(ERROR,
108106
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
109107
errmsg("integer out of range")));
110108

109+
ra=Abs(r);
110+
111111
PG_RETURN_INT32(ra);
112112
}
113113

‎contrib/btree_gist/btree_int8.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
#include"btree_gist.h"
77
#include"btree_utils_num.h"
8+
#include"common/int.h"
89

910
typedefstructint64key
1011
{
@@ -99,15 +100,14 @@ int8_dist(PG_FUNCTION_ARGS)
99100
int64r;
100101
int64ra;
101102

102-
r=a-b;
103-
ra=Abs(r);
104-
105-
/* Overflow check. */
106-
if (ra<0|| (!SAMESIGN(a,b)&& !SAMESIGN(r,a)))
103+
if (pg_sub_s64_overflow(a,b,&r)||
104+
r==INT64_MIN)
107105
ereport(ERROR,
108106
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
109107
errmsg("bigint out of range")));
110108

109+
ra=Abs(r);
110+
111111
PG_RETURN_INT64(ra);
112112
}
113113

‎contrib/btree_gist/btree_utils_num.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,6 @@ typedef struct
8989

9090
#defineGET_FLOAT_DISTANCE(t,arg1,arg2)Abs( ((float8) *((const t *) (arg1))) - ((float8) *((const t *) (arg2))) )
9191

92-
#defineSAMESIGN(a,b)(((a) < 0) == ((b) < 0))
93-
9492
/*
9593
* check to see if a float4/8 val has underflowed or overflowed
9694
* borrowed from src/backend/utils/adt/float.c

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

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include"postgres.h"
1414

1515
#include"catalog/pg_type.h"
16+
#include"common/int.h"
1617
#include"utils/array.h"
1718
#include"utils/builtins.h"
1819
#include"utils/lsyscache.h"
@@ -118,15 +119,11 @@ array_append(PG_FUNCTION_ARGS)
118119
if (eah->ndims==1)
119120
{
120121
/* append newelem */
121-
intub;
122-
123122
lb=eah->lbound;
124123
dimv=eah->dims;
125-
ub=dimv[0]+lb[0]-1;
126-
indx=ub+1;
127124

128-
/*overflow? */
129-
if (indx<ub)
125+
/*index of added elem is at lb[0] + (dimv[0] - 1) + 1 */
126+
if (pg_add_s32_overflow(lb[0],dimv[0],&indx))
130127
ereport(ERROR,
131128
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
132129
errmsg("integer out of range")));
@@ -176,11 +173,9 @@ array_prepend(PG_FUNCTION_ARGS)
176173
{
177174
/* prepend newelem */
178175
lb=eah->lbound;
179-
indx=lb[0]-1;
180176
lb0=lb[0];
181177

182-
/* overflow? */
183-
if (indx>lb[0])
178+
if (pg_sub_s32_overflow(lb0,1,&indx))
184179
ereport(ERROR,
185180
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
186181
errmsg("integer out of range")));

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

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include<ctype.h>
2323
#include<math.h>
2424

25+
#include"common/int.h"
2526
#include"libpq/pqformat.h"
2627
#include"utils/builtins.h"
2728
#include"utils/cash.h"
@@ -199,20 +200,21 @@ cash_in(PG_FUNCTION_ARGS)
199200

200201
for (;*s;s++)
201202
{
202-
/* we look for digits as long as we have found less */
203-
/* than the required number of decimal places */
203+
/*
204+
* We look for digits as long as we have found less than the required
205+
* number of decimal places.
206+
*/
204207
if (isdigit((unsignedchar)*s)&& (!seen_dot||dec<fpoint))
205208
{
206-
Cashnewvalue=(value*10)- (*s-'0');
209+
int8digit=*s-'0';
207210

208-
if (newvalue /10!=value)
211+
if (pg_mul_s64_overflow(value,10,&value)||
212+
pg_sub_s64_overflow(value,digit,&value))
209213
ereport(ERROR,
210214
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
211215
errmsg("value \"%s\" is out of range for type %s",
212216
str,"money")));
213217

214-
value=newvalue;
215-
216218
if (seen_dot)
217219
dec++;
218220
}
@@ -230,26 +232,23 @@ cash_in(PG_FUNCTION_ARGS)
230232

231233
/* round off if there's another digit */
232234
if (isdigit((unsignedchar)*s)&&*s >='5')
233-
value--;/* remember we build the value in the negative */
234-
235-
if (value>0)
236-
ereport(ERROR,
237-
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
238-
errmsg("value \"%s\" is out of range for type %s",
239-
str,"money")));
235+
{
236+
/* remember we build the value in the negative */
237+
if (pg_sub_s64_overflow(value,1,&value))
238+
ereport(ERROR,
239+
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
240+
errmsg("value \"%s\" is out of range for type %s",
241+
str,"money")));
242+
}
240243

241244
/* adjust for less than required decimal places */
242245
for (;dec<fpoint;dec++)
243246
{
244-
Cashnewvalue=value*10;
245-
246-
if (newvalue /10!=value)
247+
if (pg_mul_s64_overflow(value,10,&value))
247248
ereport(ERROR,
248249
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
249250
errmsg("value \"%s\" is out of range for type %s",
250251
str,"money")));
251-
252-
value=newvalue;
253252
}
254253

255254
/*
@@ -285,12 +284,12 @@ cash_in(PG_FUNCTION_ARGS)
285284
*/
286285
if (sgn>0)
287286
{
288-
result=-value;
289-
if (result<0)
287+
if (value==PG_INT64_MIN)
290288
ereport(ERROR,
291289
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
292290
errmsg("value \"%s\" is out of range for type %s",
293291
str,"money")));
292+
result=-value;
294293
}
295294
else
296295
result=value;

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

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include<limits.h>
2121

2222
#include"catalog/pg_type.h"
23+
#include"common/int.h"
2324
#include"libpq/pqformat.h"
2425
#include"utils/array.h"
2526
#include"utils/builtins.h"
@@ -3548,9 +3549,7 @@ width_bucket_float8(PG_FUNCTION_ARGS)
35483549
result=0;
35493550
elseif (operand >=bound2)
35503551
{
3551-
result=count+1;
3552-
/* check for overflow */
3553-
if (result<count)
3552+
if (pg_add_s32_overflow(count,1,&result))
35543553
ereport(ERROR,
35553554
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
35563555
errmsg("integer out of range")));
@@ -3564,9 +3563,7 @@ width_bucket_float8(PG_FUNCTION_ARGS)
35643563
result=0;
35653564
elseif (operand <=bound2)
35663565
{
3567-
result=count+1;
3568-
/* check for overflow */
3569-
if (result<count)
3566+
if (pg_add_s32_overflow(count,1,&result))
35703567
ereport(ERROR,
35713568
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
35723569
errmsg("integer out of range")));

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp