PostgreSQL Source Code git master
Loading...
Searching...
No Matches
float.c
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 *
3 * float.c
4 * Functions for the built-in floating-point types.
5 *
6 * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
8 *
9 *
10 * IDENTIFICATION
11 * src/backend/utils/adt/float.c
12 *
13 *-------------------------------------------------------------------------
14 */
15#include "postgres.h"
16
17#include <ctype.h>
18#include <float.h>
19#include <math.h>
20#include <limits.h>
21
22#include "catalog/pg_type.h"
23#include "common/int.h"
24#include "common/shortest_dec.h"
25#include "libpq/pqformat.h"
26#include "utils/array.h"
27#include "utils/float.h"
28#include "utils/fmgrprotos.h"
29#include "utils/sortsupport.h"
30
31
32/*
33 * Reject building with gcc's -ffast-math switch. It breaks our handling of
34 * float Infinity and NaN values (via -ffinite-math-only), causes results to
35 * be less accurate than expected (via -funsafe-math-optimizations and
36 * -fexcess-precision=fast), and causes some math error reports to be missed
37 * (via -fno-math-errno). Unfortunately we can't easily detect cases where
38 * those options were given individually, but this at least catches the most
39 * obvious case.
40 *
41 * We test this only here, not in any header file, to allow extensions to use
42 * -ffast-math if they need to. But the inline functions in float.h will
43 * misbehave in such an extension, so its authors had better be careful.
44 */
45#ifdef __FAST_MATH__
46#error -ffast-math is known to break this code
47#endif
48
49/*
50 * Configurable GUC parameter
51 *
52 * If >0, use shortest-decimal format for output; this is both the default and
53 * allows for compatibility with clients that explicitly set a value here to
54 * get round-trip-accurate results. If 0 or less, then use the old, slow,
55 * decimal rounding method.
56 */
58
59/* Cached constants for degree-based trig functions */
60static bool degree_consts_set = false;
61static float8 sin_30 = 0;
63static float8 asin_0_5 = 0;
64static float8 acos_0_5 = 0;
65static float8 atan_1_0 = 0;
66static float8 tan_45 = 0;
67static float8 cot_45 = 0;
68
69/*
70 * These are intentionally not static; don't "fix" them. They will never
71 * be referenced by other files, much less changed; but we don't want the
72 * compiler to know that, else it might try to precompute expressions
73 * involving them. See comments for init_degree_constants().
74 *
75 * The additional extern declarations are to silence
76 * -Wmissing-variable-declarations.
77 */
82extern float8 degree_c_one;
88
89/* Local function prototypes */
90static double sind_q1(double x);
91static double cosd_q1(double x);
92static void init_degree_constants(void);
93
94
95/*
96 * We use these out-of-line ereport() calls to report float overflow,
97 * underflow, and zero-divide, because following our usual practice of
98 * repeating them at each call site would lead to a lot of code bloat.
99 *
100 * This does mean that you don't get a useful error location indicator.
101 */
102pg_noinline void
104{
107 errmsg("value out of range: overflow")));
108}
109
110pg_noinline void
112{
115 errmsg("value out of range: underflow")));
116}
117
118pg_noinline void
120{
123 errmsg("division by zero")));
124}
125
126float8
128{
129 ereturn(escontext, 0.0,
131 errmsg("value out of range: overflow"));
132}
133
134float8
136{
137 ereturn(escontext, 0.0,
139 errmsg("value out of range: underflow"));
140}
141
142float8
144{
145 ereturn(escontext, 0.0,
147 errmsg("division by zero")));
148}
149
150
151/*
152 * Returns -1 if 'val' represents negative infinity, 1 if 'val'
153 * represents (positive) infinity, and 0 otherwise. On some platforms,
154 * this is equivalent to the isinf() macro, but not everywhere: C99
155 * does not specify that isinf() needs to distinguish between positive
156 * and negative infinity.
157 */
158int
160{
161 int inf = isinf(val);
162
163 if (inf == 0)
164 return 0;
165 else if (val > 0)
166 return 1;
167 else
168 return -1;
169}
170
171
172/* ========== USER I/O ROUTINES ========== */
173
174
175/*
176 * float4in - converts "num" to float4
177 *
178 * Note that this code now uses strtof(), where it used to use strtod().
179 *
180 * The motivation for using strtof() is to avoid a double-rounding problem:
181 * for certain decimal inputs, if you round the input correctly to a double,
182 * and then round the double to a float, the result is incorrect in that it
183 * does not match the result of rounding the decimal value to float directly.
184 *
185 * One of the best examples is 7.038531e-26:
186 *
187 * 0xAE43FDp-107 = 7.03853069185120912085...e-26
188 * midpoint 7.03853100000000022281...e-26
189 * 0xAE43FEp-107 = 7.03853130814879132477...e-26
190 *
191 * making 0xAE43FDp-107 the correct float result, but if you do the conversion
192 * via a double, you get
193 *
194 * 0xAE43FD.7FFFFFF8p-107 = 7.03853099999999907487...e-26
195 * midpoint 7.03853099999999964884...e-26
196 * 0xAE43FD.80000000p-107 = 7.03853100000000022281...e-26
197 * 0xAE43FD.80000008p-107 = 7.03853100000000137076...e-26
198 *
199 * so the value rounds to the double exactly on the midpoint between the two
200 * nearest floats, and then rounding again to a float gives the incorrect
201 * result of 0xAE43FEp-107.
202 *
203 */
204Datum
206{
207 char *num = PG_GETARG_CSTRING(0);
208
209 PG_RETURN_FLOAT4(float4in_internal(num, NULL, "real", num,
210 fcinfo->context));
211}
212
213/*
214 * float4in_internal - guts of float4in()
215 *
216 * This is exposed for use by functions that want a reasonably
217 * platform-independent way of inputting floats. The behavior is
218 * essentially like strtof + ereturn on error.
219 *
220 * Uses the same API as float8in_internal below, so most of its
221 * comments also apply here, except regarding use in geometric types.
222 */
223float4
224float4in_internal(char *num, char **endptr_p,
225 const char *type_name, const char *orig_string,
226 struct Node *escontext)
227{
228 float val;
229 char *endptr;
230
231 /*
232 * endptr points to the first character _after_ the sequence we recognized
233 * as a valid floating point number. orig_string points to the original
234 * input string.
235 */
236
237 /* skip leading whitespace */
238 while (*num != '\0' && isspace((unsigned char) *num))
239 num++;
240
241 /*
242 * Check for an empty-string input to begin with, to avoid the vagaries of
243 * strtod() on different platforms.
244 */
245 if (*num == '\0')
246 ereturn(escontext, 0,
248 errmsg("invalid input syntax for type %s: \"%s\"",
249 type_name, orig_string)));
250
251 errno = 0;
252 val = strtof(num, &endptr);
253
254 /* did we not see anything that looks like a double? */
255 if (endptr == num || errno != 0)
256 {
257 int save_errno = errno;
258
259 /*
260 * C99 requires that strtof() accept NaN, [+-]Infinity, and [+-]Inf,
261 * but not all platforms support all of these (and some accept them
262 * but set ERANGE anyway...) Therefore, we check for these inputs
263 * ourselves if strtof() fails.
264 *
265 * Note: C99 also requires hexadecimal input as well as some extended
266 * forms of NaN, but we consider these forms unportable and don't try
267 * to support them. You can use 'em if your strtof() takes 'em.
268 */
269 if (pg_strncasecmp(num, "NaN", 3) == 0)
270 {
272 endptr = num + 3;
273 }
274 else if (pg_strncasecmp(num, "Infinity", 8) == 0)
275 {
277 endptr = num + 8;
278 }
279 else if (pg_strncasecmp(num, "+Infinity", 9) == 0)
280 {
282 endptr = num + 9;
283 }
284 else if (pg_strncasecmp(num, "-Infinity", 9) == 0)
285 {
287 endptr = num + 9;
288 }
289 else if (pg_strncasecmp(num, "inf", 3) == 0)
290 {
292 endptr = num + 3;
293 }
294 else if (pg_strncasecmp(num, "+inf", 4) == 0)
295 {
297 endptr = num + 4;
298 }
299 else if (pg_strncasecmp(num, "-inf", 4) == 0)
300 {
302 endptr = num + 4;
303 }
304 else if (save_errno == ERANGE)
305 {
306 /*
307 * Some platforms return ERANGE for denormalized numbers (those
308 * that are not zero, but are too close to zero to have full
309 * precision). We'd prefer not to throw error for that, so try to
310 * detect whether it's a "real" out-of-range condition by checking
311 * to see if the result is zero or huge.
312 */
313 if (val == 0.0 ||
314#if !defined(HUGE_VALF)
315 isinf(val)
316#else
317 (val >= HUGE_VALF || val <= -HUGE_VALF)
318#endif
319 )
320 {
321 /* see comments in float8in_internal for rationale */
322 char *errnumber = pstrdup(num);
323
324 errnumber[endptr - num] = '\0';
325
326 ereturn(escontext, 0,
328 errmsg("\"%s\" is out of range for type real",
329 errnumber)));
330 }
331 }
332 else
333 ereturn(escontext, 0,
335 errmsg("invalid input syntax for type %s: \"%s\"",
336 type_name, orig_string)));
337 }
338
339 /* skip trailing whitespace */
340 while (*endptr != '\0' && isspace((unsigned char) *endptr))
341 endptr++;
342
343 /* report stopping point if wanted, else complain if not end of string */
344 if (endptr_p)
345 *endptr_p = endptr;
346 else if (*endptr != '\0')
347 ereturn(escontext, 0,
349 errmsg("invalid input syntax for type %s: \"%s\"",
350 type_name, orig_string)));
351
352 return val;
353}
354
355/*
356 * float4out - converts a float4 number to a string
357 * using a standard output format
358 */
359Datum
361{
362 float4 num = PG_GETARG_FLOAT4(0);
363 char *ascii = (char *) palloc(32);
365
366 if (extra_float_digits > 0)
367 {
370 }
371
372 (void) pg_strfromd(ascii, 32, ndig, num);
374}
375
376/*
377 * float4recv - converts external binary format to float4
378 */
379Datum
386
387/*
388 * float4send - converts float4 to binary format
389 */
390Datum
400
401/*
402 * float8in - converts "num" to float8
403 */
404Datum
406{
407 char *num = PG_GETARG_CSTRING(0);
408
409 PG_RETURN_FLOAT8(float8in_internal(num, NULL, "double precision", num,
410 fcinfo->context));
411}
412
413/*
414 * float8in_internal - guts of float8in()
415 *
416 * This is exposed for use by functions that want a reasonably
417 * platform-independent way of inputting doubles. The behavior is
418 * essentially like strtod + ereturn on error, but note the following
419 * differences:
420 * 1. Both leading and trailing whitespace are skipped.
421 * 2. If endptr_p is NULL, we report error if there's trailing junk.
422 * Otherwise, it's up to the caller to complain about trailing junk.
423 * 3. In event of a syntax error, the report mentions the given type_name
424 * and prints orig_string as the input; this is meant to support use of
425 * this function with types such as "box" and "point", where what we are
426 * parsing here is just a substring of orig_string.
427 *
428 * If escontext points to an ErrorSaveContext node, that is filled instead
429 * of throwing an error; the caller must check SOFT_ERROR_OCCURRED()
430 * to detect errors.
431 *
432 * "num" could validly be declared "const char *", but that results in an
433 * unreasonable amount of extra casting both here and in callers, so we don't.
434 */
435float8
436float8in_internal(char *num, char **endptr_p,
437 const char *type_name, const char *orig_string,
438 struct Node *escontext)
439{
440 double val;
441 char *endptr;
442
443 /* skip leading whitespace */
444 while (*num != '\0' && isspace((unsigned char) *num))
445 num++;
446
447 /*
448 * Check for an empty-string input to begin with, to avoid the vagaries of
449 * strtod() on different platforms.
450 */
451 if (*num == '\0')
452 ereturn(escontext, 0,
454 errmsg("invalid input syntax for type %s: \"%s\"",
455 type_name, orig_string)));
456
457 errno = 0;
458 val = strtod(num, &endptr);
459
460 /* did we not see anything that looks like a double? */
461 if (endptr == num || errno != 0)
462 {
463 int save_errno = errno;
464
465 /*
466 * C99 requires that strtod() accept NaN, [+-]Infinity, and [+-]Inf,
467 * but not all platforms support all of these (and some accept them
468 * but set ERANGE anyway...) Therefore, we check for these inputs
469 * ourselves if strtod() fails.
470 *
471 * Note: C99 also requires hexadecimal input as well as some extended
472 * forms of NaN, but we consider these forms unportable and don't try
473 * to support them. You can use 'em if your strtod() takes 'em.
474 */
475 if (pg_strncasecmp(num, "NaN", 3) == 0)
476 {
478 endptr = num + 3;
479 }
480 else if (pg_strncasecmp(num, "Infinity", 8) == 0)
481 {
483 endptr = num + 8;
484 }
485 else if (pg_strncasecmp(num, "+Infinity", 9) == 0)
486 {
488 endptr = num + 9;
489 }
490 else if (pg_strncasecmp(num, "-Infinity", 9) == 0)
491 {
493 endptr = num + 9;
494 }
495 else if (pg_strncasecmp(num, "inf", 3) == 0)
496 {
498 endptr = num + 3;
499 }
500 else if (pg_strncasecmp(num, "+inf", 4) == 0)
501 {
503 endptr = num + 4;
504 }
505 else if (pg_strncasecmp(num, "-inf", 4) == 0)
506 {
508 endptr = num + 4;
509 }
510 else if (save_errno == ERANGE)
511 {
512 /*
513 * Some platforms return ERANGE for denormalized numbers (those
514 * that are not zero, but are too close to zero to have full
515 * precision). We'd prefer not to throw error for that, so try to
516 * detect whether it's a "real" out-of-range condition by checking
517 * to see if the result is zero or huge.
518 *
519 * On error, we intentionally complain about double precision not
520 * the given type name, and we print only the part of the string
521 * that is the current number.
522 */
523 if (val == 0.0 || val >= HUGE_VAL || val <= -HUGE_VAL)
524 {
525 char *errnumber = pstrdup(num);
526
527 errnumber[endptr - num] = '\0';
528 ereturn(escontext, 0,
530 errmsg("\"%s\" is out of range for type double precision",
531 errnumber)));
532 }
533 }
534 else
535 ereturn(escontext, 0,
537 errmsg("invalid input syntax for type %s: \"%s\"",
538 type_name, orig_string)));
539 }
540
541 /* skip trailing whitespace */
542 while (*endptr != '\0' && isspace((unsigned char) *endptr))
543 endptr++;
544
545 /* report stopping point if wanted, else complain if not end of string */
546 if (endptr_p)
547 *endptr_p = endptr;
548 else if (*endptr != '\0')
549 ereturn(escontext, 0,
551 errmsg("invalid input syntax for type %s: \"%s\"",
552 type_name, orig_string)));
553
554 return val;
555}
556
557
558/*
559 * float8out - converts float8 number to a string
560 * using a standard output format
561 */
562Datum
569
570/*
571 * float8out_internal - guts of float8out()
572 *
573 * This is exposed for use by functions that want a reasonably
574 * platform-independent way of outputting doubles.
575 * The result is always palloc'd.
576 */
577char *
579{
580 char *ascii = (char *) palloc(32);
582
583 if (extra_float_digits > 0)
584 {
586 return ascii;
587 }
588
589 (void) pg_strfromd(ascii, 32, ndig, num);
590 return ascii;
591}
592
593/*
594 * float8recv - converts external binary format to float8
595 */
596Datum
603
604/*
605 * float8send - converts float8 to binary format
606 */
607Datum
617
618
619/* ========== PUBLIC ROUTINES ========== */
620
621
622/*
623 * ======================
624 * FLOAT4 BASE OPERATIONS
625 * ======================
626 */
627
628/*
629 * float4abs - returns |arg1| (absolute value)
630 */
631Datum
638
639/*
640 * float4um - returns -arg1 (unary minus)
641 */
642Datum
651
652Datum
659
660Datum
673
674Datum
687
688/*
689 * ======================
690 * FLOAT8 BASE OPERATIONS
691 * ======================
692 */
693
694/*
695 * float8abs - returns |arg1| (absolute value)
696 */
697Datum
704
705
706/*
707 * float8um - returns -arg1 (unary minus)
708 */
709Datum
718
719Datum
726
727Datum
740
741Datum
754
755
756/*
757 * ====================
758 * ARITHMETIC OPERATORS
759 * ====================
760 */
761
762/*
763 * float4pl - returns arg1 + arg2
764 * float4mi - returns arg1 - arg2
765 * float4mul - returns arg1 * arg2
766 * float4div - returns arg1 / arg2
767 */
768Datum
776
777Datum
785
786Datum
794
795Datum
803
804/*
805 * float8pl - returns arg1 + arg2
806 * float8mi - returns arg1 - arg2
807 * float8mul - returns arg1 * arg2
808 * float8div - returns arg1 / arg2
809 */
810Datum
818
819Datum
827
828Datum
836
837Datum
845
846
847/*
848 * ====================
849 * COMPARISON OPERATORS
850 * ====================
851 */
852
853/*
854 * float4{eq,ne,lt,le,gt,ge} - float4/float4 comparison operations
855 */
856int
858{
859 if (float4_gt(a, b))
860 return 1;
861 if (float4_lt(a, b))
862 return -1;
863 return 0;
864}
865
866Datum
874
875Datum
883
884Datum
892
893Datum
901
902Datum
910
911Datum
919
920Datum
928
929static int
937
938Datum
946
947/*
948 * float8{eq,ne,lt,le,gt,ge} - float8/float8 comparison operations
949 */
950int
952{
953 if (float8_gt(a, b))
954 return 1;
955 if (float8_lt(a, b))
956 return -1;
957 return 0;
958}
959
960Datum
968
969Datum
977
978Datum
986
987Datum
995
996Datum
1004
1005Datum
1013
1014Datum
1022
1023static int
1031
1032Datum
1040
1041Datum
1043{
1046
1047 /* widen float4 to float8 and then compare */
1049}
1050
1051Datum
1053{
1056
1057 /* widen float4 to float8 and then compare */
1059}
1060
1061/*
1062 * in_range support function for float8.
1063 *
1064 * Note: we needn't supply a float8_float4 variant, as implicit coercion
1065 * of the offset value takes care of that scenario just as well.
1066 */
1067Datum
1069{
1071 float8 base = PG_GETARG_FLOAT8(1);
1072 float8 offset = PG_GETARG_FLOAT8(2);
1073 bool sub = PG_GETARG_BOOL(3);
1074 bool less = PG_GETARG_BOOL(4);
1075 float8 sum;
1076
1077 /*
1078 * Reject negative or NaN offset. Negative is per spec, and NaN is
1079 * because appropriate semantics for that seem non-obvious.
1080 */
1081 if (isnan(offset) || offset < 0)
1082 ereport(ERROR,
1084 errmsg("invalid preceding or following size in window function")));
1085
1086 /*
1087 * Deal with cases where val and/or base is NaN, following the rule that
1088 * NaN sorts after non-NaN (cf float8_cmp_internal). The offset cannot
1089 * affect the conclusion.
1090 */
1091 if (isnan(val))
1092 {
1093 if (isnan(base))
1094 PG_RETURN_BOOL(true); /* NAN = NAN */
1095 else
1096 PG_RETURN_BOOL(!less); /* NAN > non-NAN */
1097 }
1098 else if (isnan(base))
1099 {
1100 PG_RETURN_BOOL(less); /* non-NAN < NAN */
1101 }
1102
1103 /*
1104 * Deal with cases where both base and offset are infinite, and computing
1105 * base +/- offset would produce NaN. This corresponds to a window frame
1106 * whose boundary infinitely precedes +inf or infinitely follows -inf,
1107 * which is not well-defined. For consistency with other cases involving
1108 * infinities, such as the fact that +inf infinitely follows +inf, we
1109 * choose to assume that +inf infinitely precedes +inf and -inf infinitely
1110 * follows -inf, and therefore that all finite and infinite values are in
1111 * such a window frame.
1112 *
1113 * offset is known positive, so we need only check the sign of base in
1114 * this test.
1115 */
1116 if (isinf(offset) && isinf(base) &&
1117 (sub ? base > 0 : base < 0))
1118 PG_RETURN_BOOL(true);
1119
1120 /*
1121 * Otherwise it should be safe to compute base +/- offset. We trust the
1122 * FPU to cope if an input is +/-inf or the true sum would overflow, and
1123 * produce a suitably signed infinity, which will compare properly against
1124 * val whether or not that's infinity.
1125 */
1126 if (sub)
1127 sum = base - offset;
1128 else
1129 sum = base + offset;
1130
1131 if (less)
1132 PG_RETURN_BOOL(val <= sum);
1133 else
1134 PG_RETURN_BOOL(val >= sum);
1135}
1136
1137/*
1138 * in_range support function for float4.
1139 *
1140 * We would need a float4_float8 variant in any case, so we supply that and
1141 * let implicit coercion take care of the float4_float4 case.
1142 */
1143Datum
1145{
1147 float4 base = PG_GETARG_FLOAT4(1);
1148 float8 offset = PG_GETARG_FLOAT8(2);
1149 bool sub = PG_GETARG_BOOL(3);
1150 bool less = PG_GETARG_BOOL(4);
1151 float8 sum;
1152
1153 /*
1154 * Reject negative or NaN offset. Negative is per spec, and NaN is
1155 * because appropriate semantics for that seem non-obvious.
1156 */
1157 if (isnan(offset) || offset < 0)
1158 ereport(ERROR,
1160 errmsg("invalid preceding or following size in window function")));
1161
1162 /*
1163 * Deal with cases where val and/or base is NaN, following the rule that
1164 * NaN sorts after non-NaN (cf float8_cmp_internal). The offset cannot
1165 * affect the conclusion.
1166 */
1167 if (isnan(val))
1168 {
1169 if (isnan(base))
1170 PG_RETURN_BOOL(true); /* NAN = NAN */
1171 else
1172 PG_RETURN_BOOL(!less); /* NAN > non-NAN */
1173 }
1174 else if (isnan(base))
1175 {
1176 PG_RETURN_BOOL(less); /* non-NAN < NAN */
1177 }
1178
1179 /*
1180 * Deal with cases where both base and offset are infinite, and computing
1181 * base +/- offset would produce NaN. This corresponds to a window frame
1182 * whose boundary infinitely precedes +inf or infinitely follows -inf,
1183 * which is not well-defined. For consistency with other cases involving
1184 * infinities, such as the fact that +inf infinitely follows +inf, we
1185 * choose to assume that +inf infinitely precedes +inf and -inf infinitely
1186 * follows -inf, and therefore that all finite and infinite values are in
1187 * such a window frame.
1188 *
1189 * offset is known positive, so we need only check the sign of base in
1190 * this test.
1191 */
1192 if (isinf(offset) && isinf(base) &&
1193 (sub ? base > 0 : base < 0))
1194 PG_RETURN_BOOL(true);
1195
1196 /*
1197 * Otherwise it should be safe to compute base +/- offset. We trust the
1198 * FPU to cope if an input is +/-inf or the true sum would overflow, and
1199 * produce a suitably signed infinity, which will compare properly against
1200 * val whether or not that's infinity.
1201 */
1202 if (sub)
1203 sum = base - offset;
1204 else
1205 sum = base + offset;
1206
1207 if (less)
1208 PG_RETURN_BOOL(val <= sum);
1209 else
1210 PG_RETURN_BOOL(val >= sum);
1211}
1212
1213
1214/*
1215 * ===================
1216 * CONVERSION ROUTINES
1217 * ===================
1218 */
1219
1220/*
1221 * ftod - converts a float4 number to a float8 number
1222 */
1223Datum
1225{
1226 float4 num = PG_GETARG_FLOAT4(0);
1227
1228 PG_RETURN_FLOAT8((float8) num);
1229}
1230
1231
1232/*
1233 * dtof - converts a float8 number to a float4 number
1234 */
1235Datum
1237{
1238 float8 num = PG_GETARG_FLOAT8(0);
1239 float4 result;
1240
1241 result = (float4) num;
1242 if (unlikely(isinf(result)) && !isinf(num))
1243 float_overflow_error_ext(fcinfo->context);
1244 if (unlikely(result == 0.0f) && num != 0.0)
1245 float_underflow_error_ext(fcinfo->context);
1246
1248}
1249
1250
1251/*
1252 * dtoi4 - converts a float8 number to an int4 number
1253 */
1254Datum
1256{
1257 float8 num = PG_GETARG_FLOAT8(0);
1258
1259 /*
1260 * Get rid of any fractional part in the input. This is so we don't fail
1261 * on just-out-of-range values that would round into range. Note
1262 * assumption that rint() will pass through a NaN or Inf unchanged.
1263 */
1264 num = rint(num);
1265
1266 /* Range check */
1267 if (unlikely(isnan(num) || !FLOAT8_FITS_IN_INT32(num)))
1268 ereturn(fcinfo->context, (Datum) 0,
1270 errmsg("integer out of range")));
1271
1272 PG_RETURN_INT32((int32) num);
1273}
1274
1275
1276/*
1277 * dtoi2 - converts a float8 number to an int2 number
1278 */
1279Datum
1281{
1282 float8 num = PG_GETARG_FLOAT8(0);
1283
1284 /*
1285 * Get rid of any fractional part in the input. This is so we don't fail
1286 * on just-out-of-range values that would round into range. Note
1287 * assumption that rint() will pass through a NaN or Inf unchanged.
1288 */
1289 num = rint(num);
1290
1291 /* Range check */
1292 if (unlikely(isnan(num) || !FLOAT8_FITS_IN_INT16(num)))
1293 ereturn(fcinfo->context, (Datum) 0,
1295 errmsg("smallint out of range")));
1296
1297 PG_RETURN_INT16((int16) num);
1298}
1299
1300
1301/*
1302 * i4tod - converts an int4 number to a float8 number
1303 */
1304Datum
1306{
1307 int32 num = PG_GETARG_INT32(0);
1308
1309 PG_RETURN_FLOAT8((float8) num);
1310}
1311
1312
1313/*
1314 * i2tod - converts an int2 number to a float8 number
1315 */
1316Datum
1318{
1319 int16 num = PG_GETARG_INT16(0);
1320
1321 PG_RETURN_FLOAT8((float8) num);
1322}
1323
1324
1325/*
1326 * ftoi4 - converts a float4 number to an int4 number
1327 */
1328Datum
1330{
1331 float4 num = PG_GETARG_FLOAT4(0);
1332
1333 /*
1334 * Get rid of any fractional part in the input. This is so we don't fail
1335 * on just-out-of-range values that would round into range. Note
1336 * assumption that rint() will pass through a NaN or Inf unchanged.
1337 */
1338 num = rint(num);
1339
1340 /* Range check */
1341 if (unlikely(isnan(num) || !FLOAT4_FITS_IN_INT32(num)))
1342 ereturn(fcinfo->context, (Datum) 0,
1344 errmsg("integer out of range")));
1345
1346 PG_RETURN_INT32((int32) num);
1347}
1348
1349
1350/*
1351 * ftoi2 - converts a float4 number to an int2 number
1352 */
1353Datum
1355{
1356 float4 num = PG_GETARG_FLOAT4(0);
1357
1358 /*
1359 * Get rid of any fractional part in the input. This is so we don't fail
1360 * on just-out-of-range values that would round into range. Note
1361 * assumption that rint() will pass through a NaN or Inf unchanged.
1362 */
1363 num = rint(num);
1364
1365 /* Range check */
1366 if (unlikely(isnan(num) || !FLOAT4_FITS_IN_INT16(num)))
1367 ereturn(fcinfo->context, (Datum) 0,
1369 errmsg("smallint out of range")));
1370
1371 PG_RETURN_INT16((int16) num);
1372}
1373
1374
1375/*
1376 * i4tof - converts an int4 number to a float4 number
1377 */
1378Datum
1380{
1381 int32 num = PG_GETARG_INT32(0);
1382
1383 PG_RETURN_FLOAT4((float4) num);
1384}
1385
1386
1387/*
1388 * i2tof - converts an int2 number to a float4 number
1389 */
1390Datum
1392{
1393 int16 num = PG_GETARG_INT16(0);
1394
1395 PG_RETURN_FLOAT4((float4) num);
1396}
1397
1398
1399/*
1400 * =======================
1401 * RANDOM FLOAT8 OPERATORS
1402 * =======================
1403 */
1404
1405/*
1406 * dround - returns ROUND(arg1)
1407 */
1408Datum
1415
1416/*
1417 * dceil - returns the smallest integer greater than or
1418 * equal to the specified float
1419 */
1420Datum
1427
1428/*
1429 * dfloor - returns the largest integer lesser than or
1430 * equal to the specified float
1431 */
1432Datum
1439
1440/*
1441 * dsign - returns -1 if the argument is less than 0, 0
1442 * if the argument is equal to 0, and 1 if the
1443 * argument is greater than zero.
1444 */
1445Datum
1447{
1449 float8 result;
1450
1451 if (arg1 > 0)
1452 result = 1.0;
1453 else if (arg1 < 0)
1454 result = -1.0;
1455 else
1456 result = 0.0;
1457
1459}
1460
1461/*
1462 * dtrunc - returns truncation-towards-zero of arg1,
1463 * arg1 >= 0 ... the greatest integer less
1464 * than or equal to arg1
1465 * arg1 < 0 ... the least integer greater
1466 * than or equal to arg1
1467 */
1468Datum
1470{
1472 float8 result;
1473
1474 if (arg1 >= 0)
1475 result = floor(arg1);
1476 else
1477 result = -floor(-arg1);
1478
1480}
1481
1482
1483/*
1484 * dsqrt - returns square root of arg1
1485 */
1486Datum
1488{
1490 float8 result;
1491
1492 if (arg1 < 0)
1493 ereport(ERROR,
1495 errmsg("cannot take square root of a negative number")));
1496
1497 result = sqrt(arg1);
1498 if (unlikely(isinf(result)) && !isinf(arg1))
1500 if (unlikely(result == 0.0) && arg1 != 0.0)
1502
1504}
1505
1506
1507/*
1508 * dcbrt - returns cube root of arg1
1509 */
1510Datum
1512{
1514 float8 result;
1515
1516 result = cbrt(arg1);
1517 if (unlikely(isinf(result)) && !isinf(arg1))
1519 if (unlikely(result == 0.0) && arg1 != 0.0)
1521
1523}
1524
1525
1526/*
1527 * dpow - returns pow(arg1,arg2)
1528 */
1529Datum
1531{
1534 float8 result;
1535
1536 /*
1537 * The POSIX spec says that NaN ^ 0 = 1, and 1 ^ NaN = 1, while all other
1538 * cases with NaN inputs yield NaN (with no error). Many older platforms
1539 * get one or more of these cases wrong, so deal with them via explicit
1540 * logic rather than trusting pow(3).
1541 */
1542 if (isnan(arg1))
1543 {
1544 if (isnan(arg2) || arg2 != 0.0)
1546 PG_RETURN_FLOAT8(1.0);
1547 }
1548 if (isnan(arg2))
1549 {
1550 if (arg1 != 1.0)
1552 PG_RETURN_FLOAT8(1.0);
1553 }
1554
1555 /*
1556 * The SQL spec requires that we emit a particular SQLSTATE error code for
1557 * certain error conditions. Specifically, we don't return a
1558 * divide-by-zero error code for 0 ^ -1.
1559 */
1560 if (arg1 == 0 && arg2 < 0)
1561 ereport(ERROR,
1563 errmsg("zero raised to a negative power is undefined")));
1564 if (arg1 < 0 && floor(arg2) != arg2)
1565 ereport(ERROR,
1567 errmsg("a negative number raised to a non-integer power yields a complex result")));
1568
1569 /*
1570 * We don't trust the platform's pow() to handle infinity cases per POSIX
1571 * spec either, so deal with those explicitly too. It's easier to handle
1572 * infinite y first, so that it doesn't matter if x is also infinite.
1573 */
1574 if (isinf(arg2))
1575 {
1576 float8 absx = fabs(arg1);
1577
1578 if (absx == 1.0)
1579 result = 1.0;
1580 else if (arg2 > 0.0) /* y = +Inf */
1581 {
1582 if (absx > 1.0)
1583 result = arg2;
1584 else
1585 result = 0.0;
1586 }
1587 else /* y = -Inf */
1588 {
1589 if (absx > 1.0)
1590 result = 0.0;
1591 else
1592 result = -arg2;
1593 }
1594 }
1595 else if (isinf(arg1))
1596 {
1597 if (arg2 == 0.0)
1598 result = 1.0;
1599 else if (arg1 > 0.0) /* x = +Inf */
1600 {
1601 if (arg2 > 0.0)
1602 result = arg1;
1603 else
1604 result = 0.0;
1605 }
1606 else /* x = -Inf */
1607 {
1608 /*
1609 * Per POSIX, the sign of the result depends on whether y is an
1610 * odd integer. Since x < 0, we already know from the previous
1611 * domain check that y is an integer. It is odd if y/2 is not
1612 * also an integer.
1613 */
1614 float8 halfy = arg2 / 2; /* should be computed exactly */
1615 bool yisoddinteger = (floor(halfy) != halfy);
1616
1617 if (arg2 > 0.0)
1619 else
1620 result = yisoddinteger ? -0.0 : 0.0;
1621 }
1622 }
1623 else
1624 {
1625 /*
1626 * pow() sets errno on only some platforms, depending on whether it
1627 * follows _IEEE_, _POSIX_, _XOPEN_, or _SVID_, so we must check both
1628 * errno and invalid output values. (We can't rely on just the
1629 * latter, either; some old platforms return a large-but-finite
1630 * HUGE_VAL when reporting overflow.)
1631 */
1632 errno = 0;
1633 result = pow(arg1, arg2);
1634 if (errno == EDOM || isnan(result))
1635 {
1636 /*
1637 * We handled all possible domain errors above, so this should be
1638 * impossible. However, old glibc versions on x86 have a bug that
1639 * causes them to fail this way for abs(y) greater than 2^63:
1640 *
1641 * https://sourceware.org/bugzilla/show_bug.cgi?id=3866
1642 *
1643 * Hence, if we get here, assume y is finite but large (large
1644 * enough to be certainly even). The result should be 0 if x == 0,
1645 * 1.0 if abs(x) == 1.0, otherwise an overflow or underflow error.
1646 */
1647 if (arg1 == 0.0)
1648 result = 0.0; /* we already verified y is positive */
1649 else
1650 {
1651 float8 absx = fabs(arg1);
1652
1653 if (absx == 1.0)
1654 result = 1.0;
1655 else if (arg2 >= 0.0 ? (absx > 1.0) : (absx < 1.0))
1657 else
1659 }
1660 }
1661 else if (errno == ERANGE)
1662 {
1663 if (result != 0.0)
1665 else
1667 }
1668 else
1669 {
1670 if (unlikely(isinf(result)))
1672 if (unlikely(result == 0.0) && arg1 != 0.0)
1674 }
1675 }
1676
1678}
1679
1680
1681/*
1682 * dexp - returns the exponential function of arg1
1683 */
1684Datum
1686{
1688 float8 result;
1689
1690 /*
1691 * Handle NaN and Inf cases explicitly. This avoids needing to assume
1692 * that the platform's exp() conforms to POSIX for these cases, and it
1693 * removes some edge cases for the overflow checks below.
1694 */
1695 if (isnan(arg1))
1696 result = arg1;
1697 else if (isinf(arg1))
1698 {
1699 /* Per POSIX, exp(-Inf) is 0 */
1700 result = (arg1 > 0.0) ? arg1 : 0;
1701 }
1702 else
1703 {
1704 /*
1705 * On some platforms, exp() will not set errno but just return Inf or
1706 * zero to report overflow/underflow; therefore, test both cases.
1707 */
1708 errno = 0;
1709 result = exp(arg1);
1710 if (unlikely(errno == ERANGE))
1711 {
1712 if (result != 0.0)
1714 else
1716 }
1717 else if (unlikely(isinf(result)))
1719 else if (unlikely(result == 0.0))
1721 }
1722
1724}
1725
1726
1727/*
1728 * dlog1 - returns the natural logarithm of arg1
1729 */
1730Datum
1732{
1734 float8 result;
1735
1736 /*
1737 * Emit particular SQLSTATE error codes for ln(). This is required by the
1738 * SQL standard.
1739 */
1740 if (arg1 == 0.0)
1741 ereport(ERROR,
1743 errmsg("cannot take logarithm of zero")));
1744 if (arg1 < 0)
1745 ereport(ERROR,
1747 errmsg("cannot take logarithm of a negative number")));
1748
1749 result = log(arg1);
1750 if (unlikely(isinf(result)) && !isinf(arg1))
1752 if (unlikely(result == 0.0) && arg1 != 1.0)
1754
1756}
1757
1758
1759/*
1760 * dlog10 - returns the base 10 logarithm of arg1
1761 */
1762Datum
1764{
1766 float8 result;
1767
1768 /*
1769 * Emit particular SQLSTATE error codes for log(). The SQL spec doesn't
1770 * define log(), but it does define ln(), so it makes sense to emit the
1771 * same error code for an analogous error condition.
1772 */
1773 if (arg1 == 0.0)
1774 ereport(ERROR,
1776 errmsg("cannot take logarithm of zero")));
1777 if (arg1 < 0)
1778 ereport(ERROR,
1780 errmsg("cannot take logarithm of a negative number")));
1781
1782 result = log10(arg1);
1783 if (unlikely(isinf(result)) && !isinf(arg1))
1785 if (unlikely(result == 0.0) && arg1 != 1.0)
1787
1789}
1790
1791
1792/*
1793 * dacos - returns the arccos of arg1 (radians)
1794 */
1795Datum
1797{
1799 float8 result;
1800
1801 /* Per the POSIX spec, return NaN if the input is NaN */
1802 if (isnan(arg1))
1804
1805 /*
1806 * The principal branch of the inverse cosine function maps values in the
1807 * range [-1, 1] to values in the range [0, Pi], so we should reject any
1808 * inputs outside that range and the result will always be finite.
1809 */
1810 if (arg1 < -1.0 || arg1 > 1.0)
1811 ereport(ERROR,
1813 errmsg("input is out of range")));
1814
1815 result = acos(arg1);
1816 if (unlikely(isinf(result)))
1818
1820}
1821
1822
1823/*
1824 * dasin - returns the arcsin of arg1 (radians)
1825 */
1826Datum
1828{
1830 float8 result;
1831
1832 /* Per the POSIX spec, return NaN if the input is NaN */
1833 if (isnan(arg1))
1835
1836 /*
1837 * The principal branch of the inverse sine function maps values in the
1838 * range [-1, 1] to values in the range [-Pi/2, Pi/2], so we should reject
1839 * any inputs outside that range and the result will always be finite.
1840 */
1841 if (arg1 < -1.0 || arg1 > 1.0)
1842 ereport(ERROR,
1844 errmsg("input is out of range")));
1845
1846 result = asin(arg1);
1847 if (unlikely(isinf(result)))
1849
1851}
1852
1853
1854/*
1855 * datan - returns the arctan of arg1 (radians)
1856 */
1857Datum
1859{
1861 float8 result;
1862
1863 /* Per the POSIX spec, return NaN if the input is NaN */
1864 if (isnan(arg1))
1866
1867 /*
1868 * The principal branch of the inverse tangent function maps all inputs to
1869 * values in the range [-Pi/2, Pi/2], so the result should always be
1870 * finite, even if the input is infinite.
1871 */
1872 result = atan(arg1);
1873 if (unlikely(isinf(result)))
1875
1877}
1878
1879
1880/*
1881 * atan2 - returns the arctan of arg1/arg2 (radians)
1882 */
1883Datum
1885{
1888 float8 result;
1889
1890 /* Per the POSIX spec, return NaN if either input is NaN */
1891 if (isnan(arg1) || isnan(arg2))
1893
1894 /*
1895 * atan2 maps all inputs to values in the range [-Pi, Pi], so the result
1896 * should always be finite, even if the inputs are infinite.
1897 */
1898 result = atan2(arg1, arg2);
1899 if (unlikely(isinf(result)))
1901
1903}
1904
1905
1906/*
1907 * dcos - returns the cosine of arg1 (radians)
1908 */
1909Datum
1911{
1913 float8 result;
1914
1915 /* Per the POSIX spec, return NaN if the input is NaN */
1916 if (isnan(arg1))
1918
1919 /*
1920 * cos() is periodic and so theoretically can work for all finite inputs,
1921 * but some implementations may choose to throw error if the input is so
1922 * large that there are no significant digits in the result. So we should
1923 * check for errors. POSIX allows an error to be reported either via
1924 * errno or via fetestexcept(), but currently we only support checking
1925 * errno. (fetestexcept() is rumored to report underflow unreasonably
1926 * early on some platforms, so it's not clear that believing it would be a
1927 * net improvement anyway.)
1928 *
1929 * For infinite inputs, POSIX specifies that the trigonometric functions
1930 * should return a domain error; but we won't notice that unless the
1931 * platform reports via errno, so also explicitly test for infinite
1932 * inputs.
1933 */
1934 errno = 0;
1935 result = cos(arg1);
1936 if (errno != 0 || isinf(arg1))
1937 ereport(ERROR,
1939 errmsg("input is out of range")));
1940 if (unlikely(isinf(result)))
1942
1944}
1945
1946
1947/*
1948 * dcot - returns the cotangent of arg1 (radians)
1949 */
1950Datum
1952{
1954 float8 result;
1955
1956 /* Per the POSIX spec, return NaN if the input is NaN */
1957 if (isnan(arg1))
1959
1960 /* Be sure to throw an error if the input is infinite --- see dcos() */
1961 errno = 0;
1962 result = tan(arg1);
1963 if (errno != 0 || isinf(arg1))
1964 ereport(ERROR,
1966 errmsg("input is out of range")));
1967
1968 result = 1.0 / result;
1969 /* Not checking for overflow because cot(0) == Inf */
1970
1972}
1973
1974
1975/*
1976 * dsin - returns the sine of arg1 (radians)
1977 */
1978Datum
1980{
1982 float8 result;
1983
1984 /* Per the POSIX spec, return NaN if the input is NaN */
1985 if (isnan(arg1))
1987
1988 /* Be sure to throw an error if the input is infinite --- see dcos() */
1989 errno = 0;
1990 result = sin(arg1);
1991 if (errno != 0 || isinf(arg1))
1992 ereport(ERROR,
1994 errmsg("input is out of range")));
1995 if (unlikely(isinf(result)))
1997
1999}
2000
2001
2002/*
2003 * dtan - returns the tangent of arg1 (radians)
2004 */
2005Datum
2007{
2009 float8 result;
2010
2011 /* Per the POSIX spec, return NaN if the input is NaN */
2012 if (isnan(arg1))
2014
2015 /* Be sure to throw an error if the input is infinite --- see dcos() */
2016 errno = 0;
2017 result = tan(arg1);
2018 if (errno != 0 || isinf(arg1))
2019 ereport(ERROR,
2021 errmsg("input is out of range")));
2022 /* Not checking for overflow because tan(pi/2) == Inf */
2023
2025}
2026
2027
2028/* ========== DEGREE-BASED TRIGONOMETRIC FUNCTIONS ========== */
2029
2030
2031/*
2032 * Initialize the cached constants declared at the head of this file
2033 * (sin_30 etc). The fact that we need those at all, let alone need this
2034 * Rube-Goldberg-worthy method of initializing them, is because there are
2035 * compilers out there that will precompute expressions such as sin(constant)
2036 * using a sin() function different from what will be used at runtime. If we
2037 * want exact results, we must ensure that none of the scaling constants used
2038 * in the degree-based trig functions are computed that way. To do so, we
2039 * compute them from the variables degree_c_thirty etc, which are also really
2040 * constants, but the compiler cannot assume that.
2041 *
2042 * Other hazards we are trying to forestall with this kluge include the
2043 * possibility that compilers will rearrange the expressions, or compute
2044 * some intermediate results in registers wider than a standard double.
2045 *
2046 * In the places where we use these constants, the typical pattern is like
2047 * volatile float8 sin_x = sin(x * RADIANS_PER_DEGREE);
2048 * return (sin_x / sin_30);
2049 * where we hope to get a value of exactly 1.0 from the division when x = 30.
2050 * The volatile temporary variable is needed on machines with wide float
2051 * registers, to ensure that the result of sin(x) is rounded to double width
2052 * the same as the value of sin_30 has been. Experimentation with gcc shows
2053 * that marking the temp variable volatile is necessary to make the store and
2054 * reload actually happen; hopefully the same trick works for other compilers.
2055 * (gcc's documentation suggests using the -ffloat-store compiler switch to
2056 * ensure this, but that is compiler-specific and it also pessimizes code in
2057 * many places where we don't care about this.)
2058 */
2059static void
2071
2072#define INIT_DEGREE_CONSTANTS() \
2073do { \
2074 if (!degree_consts_set) \
2075 init_degree_constants(); \
2076} while(0)
2077
2078
2079/*
2080 * asind_q1 - returns the inverse sine of x in degrees, for x in
2081 * the range [0, 1]. The result is an angle in the
2082 * first quadrant --- [0, 90] degrees.
2083 *
2084 * For the 3 special case inputs (0, 0.5 and 1), this
2085 * function will return exact values (0, 30 and 90
2086 * degrees respectively).
2087 */
2088static double
2090{
2091 /*
2092 * Stitch together inverse sine and cosine functions for the ranges [0,
2093 * 0.5] and (0.5, 1]. Each expression below is guaranteed to return
2094 * exactly 30 for x=0.5, so the result is a continuous monotonic function
2095 * over the full range.
2096 */
2097 if (x <= 0.5)
2098 {
2099 volatile float8 asin_x = asin(x);
2100
2101 return (asin_x / asin_0_5) * 30.0;
2102 }
2103 else
2104 {
2105 volatile float8 acos_x = acos(x);
2106
2107 return 90.0 - (acos_x / acos_0_5) * 60.0;
2108 }
2109}
2110
2111
2112/*
2113 * acosd_q1 - returns the inverse cosine of x in degrees, for x in
2114 * the range [0, 1]. The result is an angle in the
2115 * first quadrant --- [0, 90] degrees.
2116 *
2117 * For the 3 special case inputs (0, 0.5 and 1), this
2118 * function will return exact values (0, 60 and 90
2119 * degrees respectively).
2120 */
2121static double
2123{
2124 /*
2125 * Stitch together inverse sine and cosine functions for the ranges [0,
2126 * 0.5] and (0.5, 1]. Each expression below is guaranteed to return
2127 * exactly 60 for x=0.5, so the result is a continuous monotonic function
2128 * over the full range.
2129 */
2130 if (x <= 0.5)
2131 {
2132 volatile float8 asin_x = asin(x);
2133
2134 return 90.0 - (asin_x / asin_0_5) * 30.0;
2135 }
2136 else
2137 {
2138 volatile float8 acos_x = acos(x);
2139
2140 return (acos_x / acos_0_5) * 60.0;
2141 }
2142}
2143
2144
2145/*
2146 * dacosd - returns the arccos of arg1 (degrees)
2147 */
2148Datum
2150{
2152 float8 result;
2153
2154 /* Per the POSIX spec, return NaN if the input is NaN */
2155 if (isnan(arg1))
2157
2159
2160 /*
2161 * The principal branch of the inverse cosine function maps values in the
2162 * range [-1, 1] to values in the range [0, 180], so we should reject any
2163 * inputs outside that range and the result will always be finite.
2164 */
2165 if (arg1 < -1.0 || arg1 > 1.0)
2166 ereport(ERROR,
2168 errmsg("input is out of range")));
2169
2170 if (arg1 >= 0.0)
2171 result = acosd_q1(arg1);
2172 else
2173 result = 90.0 + asind_q1(-arg1);
2174
2175 if (unlikely(isinf(result)))
2177
2179}
2180
2181
2182/*
2183 * dasind - returns the arcsin of arg1 (degrees)
2184 */
2185Datum
2187{
2189 float8 result;
2190
2191 /* Per the POSIX spec, return NaN if the input is NaN */
2192 if (isnan(arg1))
2194
2196
2197 /*
2198 * The principal branch of the inverse sine function maps values in the
2199 * range [-1, 1] to values in the range [-90, 90], so we should reject any
2200 * inputs outside that range and the result will always be finite.
2201 */
2202 if (arg1 < -1.0 || arg1 > 1.0)
2203 ereport(ERROR,
2205 errmsg("input is out of range")));
2206
2207 if (arg1 >= 0.0)
2208 result = asind_q1(arg1);
2209 else
2210 result = -asind_q1(-arg1);
2211
2212 if (unlikely(isinf(result)))
2214
2216}
2217
2218
2219/*
2220 * datand - returns the arctan of arg1 (degrees)
2221 */
2222Datum
2224{
2226 float8 result;
2227 volatile float8 atan_arg1;
2228
2229 /* Per the POSIX spec, return NaN if the input is NaN */
2230 if (isnan(arg1))
2232
2234
2235 /*
2236 * The principal branch of the inverse tangent function maps all inputs to
2237 * values in the range [-90, 90], so the result should always be finite,
2238 * even if the input is infinite. Additionally, we take care to ensure
2239 * than when arg1 is 1, the result is exactly 45.
2240 */
2241 atan_arg1 = atan(arg1);
2242 result = (atan_arg1 / atan_1_0) * 45.0;
2243
2244 if (unlikely(isinf(result)))
2246
2248}
2249
2250
2251/*
2252 * atan2d - returns the arctan of arg1/arg2 (degrees)
2253 */
2254Datum
2256{
2259 float8 result;
2260 volatile float8 atan2_arg1_arg2;
2261
2262 /* Per the POSIX spec, return NaN if either input is NaN */
2263 if (isnan(arg1) || isnan(arg2))
2265
2267
2268 /*
2269 * atan2d maps all inputs to values in the range [-180, 180], so the
2270 * result should always be finite, even if the inputs are infinite.
2271 *
2272 * Note: this coding assumes that atan(1.0) is a suitable scaling constant
2273 * to get an exact result from atan2(). This might well fail on us at
2274 * some point, requiring us to decide exactly what inputs we think we're
2275 * going to guarantee an exact result for.
2276 */
2278 result = (atan2_arg1_arg2 / atan_1_0) * 45.0;
2279
2280 if (unlikely(isinf(result)))
2282
2284}
2285
2286
2287/*
2288 * sind_0_to_30 - returns the sine of an angle that lies between 0 and
2289 * 30 degrees. This will return exactly 0 when x is 0,
2290 * and exactly 0.5 when x is 30 degrees.
2291 */
2292static double
2294{
2295 volatile float8 sin_x = sin(x * RADIANS_PER_DEGREE);
2296
2297 return (sin_x / sin_30) / 2.0;
2298}
2299
2300
2301/*
2302 * cosd_0_to_60 - returns the cosine of an angle that lies between 0
2303 * and 60 degrees. This will return exactly 1 when x
2304 * is 0, and exactly 0.5 when x is 60 degrees.
2305 */
2306static double
2308{
2309 volatile float8 one_minus_cos_x = 1.0 - cos(x * RADIANS_PER_DEGREE);
2310
2311 return 1.0 - (one_minus_cos_x / one_minus_cos_60) / 2.0;
2312}
2313
2314
2315/*
2316 * sind_q1 - returns the sine of an angle in the first quadrant
2317 * (0 to 90 degrees).
2318 */
2319static double
2320sind_q1(double x)
2321{
2322 /*
2323 * Stitch together the sine and cosine functions for the ranges [0, 30]
2324 * and (30, 90]. These guarantee to return exact answers at their
2325 * endpoints, so the overall result is a continuous monotonic function
2326 * that gives exact results when x = 0, 30 and 90 degrees.
2327 */
2328 if (x <= 30.0)
2329 return sind_0_to_30(x);
2330 else
2331 return cosd_0_to_60(90.0 - x);
2332}
2333
2334
2335/*
2336 * cosd_q1 - returns the cosine of an angle in the first quadrant
2337 * (0 to 90 degrees).
2338 */
2339static double
2340cosd_q1(double x)
2341{
2342 /*
2343 * Stitch together the sine and cosine functions for the ranges [0, 60]
2344 * and (60, 90]. These guarantee to return exact answers at their
2345 * endpoints, so the overall result is a continuous monotonic function
2346 * that gives exact results when x = 0, 60 and 90 degrees.
2347 */
2348 if (x <= 60.0)
2349 return cosd_0_to_60(x);
2350 else
2351 return sind_0_to_30(90.0 - x);
2352}
2353
2354
2355/*
2356 * dcosd - returns the cosine of arg1 (degrees)
2357 */
2358Datum
2360{
2362 float8 result;
2363 int sign = 1;
2364
2365 /*
2366 * Per the POSIX spec, return NaN if the input is NaN and throw an error
2367 * if the input is infinite.
2368 */
2369 if (isnan(arg1))
2371
2372 if (isinf(arg1))
2373 ereport(ERROR,
2375 errmsg("input is out of range")));
2376
2378
2379 /* Reduce the range of the input to [0,90] degrees */
2380 arg1 = fmod(arg1, 360.0);
2381
2382 if (arg1 < 0.0)
2383 {
2384 /* cosd(-x) = cosd(x) */
2385 arg1 = -arg1;
2386 }
2387
2388 if (arg1 > 180.0)
2389 {
2390 /* cosd(360-x) = cosd(x) */
2391 arg1 = 360.0 - arg1;
2392 }
2393
2394 if (arg1 > 90.0)
2395 {
2396 /* cosd(180-x) = -cosd(x) */
2397 arg1 = 180.0 - arg1;
2398 sign = -sign;
2399 }
2400
2401 result = sign * cosd_q1(arg1);
2402
2403 if (unlikely(isinf(result)))
2405
2407}
2408
2409
2410/*
2411 * dcotd - returns the cotangent of arg1 (degrees)
2412 */
2413Datum
2415{
2417 float8 result;
2418 volatile float8 cot_arg1;
2419 int sign = 1;
2420
2421 /*
2422 * Per the POSIX spec, return NaN if the input is NaN and throw an error
2423 * if the input is infinite.
2424 */
2425 if (isnan(arg1))
2427
2428 if (isinf(arg1))
2429 ereport(ERROR,
2431 errmsg("input is out of range")));
2432
2434
2435 /* Reduce the range of the input to [0,90] degrees */
2436 arg1 = fmod(arg1, 360.0);
2437
2438 if (arg1 < 0.0)
2439 {
2440 /* cotd(-x) = -cotd(x) */
2441 arg1 = -arg1;
2442 sign = -sign;
2443 }
2444
2445 if (arg1 > 180.0)
2446 {
2447 /* cotd(360-x) = -cotd(x) */
2448 arg1 = 360.0 - arg1;
2449 sign = -sign;
2450 }
2451
2452 if (arg1 > 90.0)
2453 {
2454 /* cotd(180-x) = -cotd(x) */
2455 arg1 = 180.0 - arg1;
2456 sign = -sign;
2457 }
2458
2460 result = sign * (cot_arg1 / cot_45);
2461
2462 /*
2463 * On some machines we get cotd(270) = minus zero, but this isn't always
2464 * true. For portability, and because the user constituency for this
2465 * function probably doesn't want minus zero, force it to plain zero.
2466 */
2467 if (result == 0.0)
2468 result = 0.0;
2469
2470 /* Not checking for overflow because cotd(0) == Inf */
2471
2473}
2474
2475
2476/*
2477 * dsind - returns the sine of arg1 (degrees)
2478 */
2479Datum
2481{
2483 float8 result;
2484 int sign = 1;
2485
2486 /*
2487 * Per the POSIX spec, return NaN if the input is NaN and throw an error
2488 * if the input is infinite.
2489 */
2490 if (isnan(arg1))
2492
2493 if (isinf(arg1))
2494 ereport(ERROR,
2496 errmsg("input is out of range")));
2497
2499
2500 /* Reduce the range of the input to [0,90] degrees */
2501 arg1 = fmod(arg1, 360.0);
2502
2503 if (arg1 < 0.0)
2504 {
2505 /* sind(-x) = -sind(x) */
2506 arg1 = -arg1;
2507 sign = -sign;
2508 }
2509
2510 if (arg1 > 180.0)
2511 {
2512 /* sind(360-x) = -sind(x) */
2513 arg1 = 360.0 - arg1;
2514 sign = -sign;
2515 }
2516
2517 if (arg1 > 90.0)
2518 {
2519 /* sind(180-x) = sind(x) */
2520 arg1 = 180.0 - arg1;
2521 }
2522
2523 result = sign * sind_q1(arg1);
2524
2525 if (unlikely(isinf(result)))
2527
2529}
2530
2531
2532/*
2533 * dtand - returns the tangent of arg1 (degrees)
2534 */
2535Datum
2537{
2539 float8 result;
2540 volatile float8 tan_arg1;
2541 int sign = 1;
2542
2543 /*
2544 * Per the POSIX spec, return NaN if the input is NaN and throw an error
2545 * if the input is infinite.
2546 */
2547 if (isnan(arg1))
2549
2550 if (isinf(arg1))
2551 ereport(ERROR,
2553 errmsg("input is out of range")));
2554
2556
2557 /* Reduce the range of the input to [0,90] degrees */
2558 arg1 = fmod(arg1, 360.0);
2559
2560 if (arg1 < 0.0)
2561 {
2562 /* tand(-x) = -tand(x) */
2563 arg1 = -arg1;
2564 sign = -sign;
2565 }
2566
2567 if (arg1 > 180.0)
2568 {
2569 /* tand(360-x) = -tand(x) */
2570 arg1 = 360.0 - arg1;
2571 sign = -sign;
2572 }
2573
2574 if (arg1 > 90.0)
2575 {
2576 /* tand(180-x) = -tand(x) */
2577 arg1 = 180.0 - arg1;
2578 sign = -sign;
2579 }
2580
2582 result = sign * (tan_arg1 / tan_45);
2583
2584 /*
2585 * On some machines we get tand(180) = minus zero, but this isn't always
2586 * true. For portability, and because the user constituency for this
2587 * function probably doesn't want minus zero, force it to plain zero.
2588 */
2589 if (result == 0.0)
2590 result = 0.0;
2591
2592 /* Not checking for overflow because tand(90) == Inf */
2593
2595}
2596
2597
2598/*
2599 * degrees - returns degrees converted from radians
2600 */
2601Datum
2608
2609
2610/*
2611 * dpi - returns the constant PI
2612 */
2613Datum
2618
2619
2620/*
2621 * radians - returns radians converted from degrees
2622 */
2623Datum
2630
2631
2632/* ========== HYPERBOLIC FUNCTIONS ========== */
2633
2634
2635/*
2636 * dsinh - returns the hyperbolic sine of arg1
2637 */
2638Datum
2640{
2642 float8 result;
2643
2644 errno = 0;
2645 result = sinh(arg1);
2646
2647 /*
2648 * if an ERANGE error occurs, it means there is an overflow. For sinh,
2649 * the result should be either -infinity or infinity, depending on the
2650 * sign of arg1.
2651 */
2652 if (errno == ERANGE)
2653 {
2654 if (arg1 < 0)
2656 else
2658 }
2659
2661}
2662
2663
2664/*
2665 * dcosh - returns the hyperbolic cosine of arg1
2666 */
2667Datum
2669{
2671 float8 result;
2672
2673 errno = 0;
2674 result = cosh(arg1);
2675
2676 /*
2677 * if an ERANGE error occurs, it means there is an overflow. As cosh is
2678 * always positive, it always means the result is positive infinity.
2679 */
2680 if (errno == ERANGE)
2682
2683 if (unlikely(result == 0.0))
2685
2687}
2688
2689/*
2690 * dtanh - returns the hyperbolic tangent of arg1
2691 */
2692Datum
2694{
2696 float8 result;
2697
2698 /*
2699 * For tanh, we don't need an errno check because it never overflows.
2700 */
2701 result = tanh(arg1);
2702
2703 if (unlikely(isinf(result)))
2705
2707}
2708
2709/*
2710 * dasinh - returns the inverse hyperbolic sine of arg1
2711 */
2712Datum
2714{
2716 float8 result;
2717
2718 /*
2719 * For asinh, we don't need an errno check because it never overflows.
2720 */
2721 result = asinh(arg1);
2722
2724}
2725
2726/*
2727 * dacosh - returns the inverse hyperbolic cosine of arg1
2728 */
2729Datum
2731{
2733 float8 result;
2734
2735 /*
2736 * acosh is only defined for inputs >= 1.0. By checking this ourselves,
2737 * we need not worry about checking for an EDOM error, which is a good
2738 * thing because some implementations will report that for NaN. Otherwise,
2739 * no error is possible.
2740 */
2741 if (arg1 < 1.0)
2742 ereport(ERROR,
2744 errmsg("input is out of range")));
2745
2746 result = acosh(arg1);
2747
2749}
2750
2751/*
2752 * datanh - returns the inverse hyperbolic tangent of arg1
2753 */
2754Datum
2756{
2758 float8 result;
2759
2760 /*
2761 * atanh is only defined for inputs between -1 and 1. By checking this
2762 * ourselves, we need not worry about checking for an EDOM error, which is
2763 * a good thing because some implementations will report that for NaN.
2764 */
2765 if (arg1 < -1.0 || arg1 > 1.0)
2766 ereport(ERROR,
2768 errmsg("input is out of range")));
2769
2770 /*
2771 * Also handle the infinity cases ourselves; this is helpful because old
2772 * glibc versions may produce the wrong errno for this. All other inputs
2773 * cannot produce an error.
2774 */
2775 if (arg1 == -1.0)
2777 else if (arg1 == 1.0)
2779 else
2780 result = atanh(arg1);
2781
2783}
2784
2785
2786/* ========== ERROR FUNCTIONS ========== */
2787
2788
2789/*
2790 * derf - returns the error function: erf(arg1)
2791 */
2792Datum
2794{
2796 float8 result;
2797
2798 /*
2799 * For erf, we don't need an errno check because it never overflows.
2800 */
2801 result = erf(arg1);
2802
2803 if (unlikely(isinf(result)))
2805
2807}
2808
2809/*
2810 * derfc - returns the complementary error function: 1 - erf(arg1)
2811 */
2812Datum
2814{
2816 float8 result;
2817
2818 /*
2819 * For erfc, we don't need an errno check because it never overflows.
2820 */
2821 result = erfc(arg1);
2822
2823 if (unlikely(isinf(result)))
2825
2827}
2828
2829
2830/* ========== GAMMA FUNCTIONS ========== */
2831
2832
2833/*
2834 * dgamma - returns the gamma function of arg1
2835 */
2836Datum
2838{
2840 float8 result;
2841
2842 /*
2843 * Handle NaN and Inf cases explicitly. This simplifies the overflow
2844 * checks on platforms that do not set errno.
2845 */
2846 if (isnan(arg1))
2847 result = arg1;
2848 else if (isinf(arg1))
2849 {
2850 /* Per POSIX, an input of -Inf causes a domain error */
2851 if (arg1 < 0)
2852 {
2854 result = get_float8_nan(); /* keep compiler quiet */
2855 }
2856 else
2857 result = arg1;
2858 }
2859 else
2860 {
2861 /*
2862 * Note: the POSIX/C99 gamma function is called "tgamma", not "gamma".
2863 *
2864 * On some platforms, tgamma() will not set errno but just return Inf,
2865 * NaN, or zero to report overflow/underflow; therefore, test those
2866 * cases explicitly (note that, like the exponential function, the
2867 * gamma function has no zeros).
2868 */
2869 errno = 0;
2870 result = tgamma(arg1);
2871
2872 if (errno != 0 || isinf(result) || isnan(result))
2873 {
2874 if (result != 0.0)
2876 else
2878 }
2879 else if (result == 0.0)
2881 }
2882
2884}
2885
2886
2887/*
2888 * dlgamma - natural logarithm of absolute value of gamma of arg1
2889 */
2890Datum
2892{
2894 float8 result;
2895
2896 /* On some versions of AIX, lgamma(NaN) fails with ERANGE */
2897#if defined(_AIX)
2898 if (isnan(arg1))
2900#endif
2901
2902 /*
2903 * Note: lgamma may not be thread-safe because it may write to a global
2904 * variable signgam, which may not be thread-local. However, this doesn't
2905 * matter to us, since we don't use signgam.
2906 */
2907 errno = 0;
2908 result = lgamma(arg1);
2909
2910 /*
2911 * If an ERANGE error occurs, it means there was an overflow or a pole
2912 * error (which happens for zero and negative integer inputs).
2913 *
2914 * On some platforms, lgamma() will not set errno but just return infinity
2915 * to report overflow, but it should never underflow.
2916 */
2917 if (errno == ERANGE || (isinf(result) && !isinf(arg1)))
2919
2921}
2922
2923
2924
2925/*
2926 * =========================
2927 * FLOAT AGGREGATE OPERATORS
2928 * =========================
2929 *
2930 * float8_accum - accumulate for AVG(), variance aggregates, etc.
2931 * float4_accum - same, but input data is float4
2932 * float8_avg - produce final result for float AVG()
2933 * float8_var_samp - produce final result for float VAR_SAMP()
2934 * float8_var_pop - produce final result for float VAR_POP()
2935 * float8_stddev_samp - produce final result for float STDDEV_SAMP()
2936 * float8_stddev_pop - produce final result for float STDDEV_POP()
2937 *
2938 * The naive schoolbook implementation of these aggregates works by
2939 * accumulating sum(X) and sum(X^2). However, this approach suffers from
2940 * large rounding errors in the final computation of quantities like the
2941 * population variance (N*sum(X^2) - sum(X)^2) / N^2, since each of the
2942 * intermediate terms is potentially very large, while the difference is often
2943 * quite small.
2944 *
2945 * Instead we use the Youngs-Cramer algorithm [1] which works by accumulating
2946 * Sx=sum(X) and Sxx=sum((X-Sx/N)^2), using a numerically stable algorithm to
2947 * incrementally update those quantities. The final computations of each of
2948 * the aggregate values is then trivial and gives more accurate results (for
2949 * example, the population variance is just Sxx/N). This algorithm is also
2950 * fairly easy to generalize to allow parallel execution without loss of
2951 * precision (see, for example, [2]). For more details, and a comparison of
2952 * this with other algorithms, see [3].
2953 *
2954 * The transition datatype for all these aggregates is a 3-element array
2955 * of float8, holding the values N, Sx, Sxx in that order.
2956 *
2957 * Note that we represent N as a float to avoid having to build a special
2958 * datatype. Given a reasonable floating-point implementation, there should
2959 * be no accuracy loss unless N exceeds 2 ^ 52 or so (by which time the
2960 * user will have doubtless lost interest anyway...)
2961 *
2962 * [1] Some Results Relevant to Choice of Sum and Sum-of-Product Algorithms,
2963 * E. A. Youngs and E. M. Cramer, Technometrics Vol 13, No 3, August 1971.
2964 *
2965 * [2] Updating Formulae and a Pairwise Algorithm for Computing Sample
2966 * Variances, T. F. Chan, G. H. Golub & R. J. LeVeque, COMPSTAT 1982.
2967 *
2968 * [3] Numerically Stable Parallel Computation of (Co-)Variance, Erich
2969 * Schubert and Michael Gertz, Proceedings of the 30th International
2970 * Conference on Scientific and Statistical Database Management, 2018.
2971 */
2972
2973static float8 *
2975{
2976 /*
2977 * We expect the input to be an N-element float array; verify that. We
2978 * don't need to use deconstruct_array() since the array data is just
2979 * going to look like a C array of N float8 values.
2980 */
2981 if (ARR_NDIM(transarray) != 1 ||
2982 ARR_DIMS(transarray)[0] != n ||
2985 elog(ERROR, "%s: expected %d-element float8 array", caller, n);
2986 return (float8 *) ARR_DATA_PTR(transarray);
2987}
2988
2989/*
2990 * float8_combine
2991 *
2992 * An aggregate combine function used to combine two 3 fields
2993 * aggregate transition data into a single transition data.
2994 * This function is used only in two stage aggregation and
2995 * shouldn't be called outside aggregate context.
2996 */
2997Datum
2999{
3004 float8 N1,
3005 Sx1,
3006 Sxx1,
3007 N2,
3008 Sx2,
3009 Sxx2,
3010 tmp,
3011 N,
3012 Sx,
3013 Sxx;
3014
3015 transvalues1 = check_float8_array(transarray1, "float8_combine", 3);
3016 transvalues2 = check_float8_array(transarray2, "float8_combine", 3);
3017
3018 N1 = transvalues1[0];
3019 Sx1 = transvalues1[1];
3020 Sxx1 = transvalues1[2];
3021
3022 N2 = transvalues2[0];
3023 Sx2 = transvalues2[1];
3024 Sxx2 = transvalues2[2];
3025
3026 /*--------------------
3027 * The transition values combine using a generalization of the
3028 * Youngs-Cramer algorithm as follows:
3029 *
3030 * N = N1 + N2
3031 * Sx = Sx1 + Sx2
3032 * Sxx = Sxx1 + Sxx2 + N1 * N2 * (Sx1/N1 - Sx2/N2)^2 / N;
3033 *
3034 * It's worth handling the special cases N1 = 0 and N2 = 0 separately
3035 * since those cases are trivial, and we then don't need to worry about
3036 * division-by-zero errors in the general case.
3037 *--------------------
3038 */
3039 if (N1 == 0.0)
3040 {
3041 N = N2;
3042 Sx = Sx2;
3043 Sxx = Sxx2;
3044 }
3045 else if (N2 == 0.0)
3046 {
3047 N = N1;
3048 Sx = Sx1;
3049 Sxx = Sxx1;
3050 }
3051 else
3052 {
3053 N = N1 + N2;
3054 Sx = float8_pl(Sx1, Sx2);
3055 tmp = Sx1 / N1 - Sx2 / N2;
3056 Sxx = Sxx1 + Sxx2 + N1 * N2 * tmp * tmp / N;
3057 if (unlikely(isinf(Sxx)) && !isinf(Sxx1) && !isinf(Sxx2))
3059 }
3060
3061 /*
3062 * If we're invoked as an aggregate, we can cheat and modify our first
3063 * parameter in-place to reduce palloc overhead. Otherwise we construct a
3064 * new array with the updated transition data and return it.
3065 */
3066 if (AggCheckCallContext(fcinfo, NULL))
3067 {
3068 transvalues1[0] = N;
3069 transvalues1[1] = Sx;
3070 transvalues1[2] = Sxx;
3071
3073 }
3074 else
3075 {
3076 Datum transdatums[3];
3078
3082
3084
3086 }
3087}
3088
3089Datum
3091{
3095 float8 N,
3096 Sx,
3097 Sxx,
3098 tmp;
3099
3100 transvalues = check_float8_array(transarray, "float8_accum", 3);
3101 N = transvalues[0];
3102 Sx = transvalues[1];
3103 Sxx = transvalues[2];
3104
3105 /*
3106 * Use the Youngs-Cramer algorithm to incorporate the new value into the
3107 * transition values.
3108 */
3109 N += 1.0;
3110 Sx += newval;
3111 if (transvalues[0] > 0.0)
3112 {
3113 tmp = newval * N - Sx;
3114 Sxx += tmp * tmp / (N * transvalues[0]);
3115
3116 /*
3117 * Overflow check. We only report an overflow error when finite
3118 * inputs lead to infinite results. Note also that Sxx should be NaN
3119 * if any of the inputs are infinite, so we intentionally prevent Sxx
3120 * from becoming infinite.
3121 */
3122 if (isinf(Sx) || isinf(Sxx))
3123 {
3124 if (!isinf(transvalues[1]) && !isinf(newval))
3126
3127 Sxx = get_float8_nan();
3128 }
3129 }
3130 else
3131 {
3132 /*
3133 * At the first input, we normally can leave Sxx as 0. However, if
3134 * the first input is Inf or NaN, we'd better force Sxx to NaN;
3135 * otherwise we will falsely report variance zero when there are no
3136 * more inputs.
3137 */
3138 if (isnan(newval) || isinf(newval))
3139 Sxx = get_float8_nan();
3140 }
3141
3142 /*
3143 * If we're invoked as an aggregate, we can cheat and modify our first
3144 * parameter in-place to reduce palloc overhead. Otherwise we construct a
3145 * new array with the updated transition data and return it.
3146 */
3147 if (AggCheckCallContext(fcinfo, NULL))
3148 {
3149 transvalues[0] = N;
3150 transvalues[1] = Sx;
3151 transvalues[2] = Sxx;
3152
3154 }
3155 else
3156 {
3157 Datum transdatums[3];
3159
3163
3165
3167 }
3168}
3169
3170Datum
3172{
3174
3175 /* do computations as float8 */
3178 float8 N,
3179 Sx,
3180 Sxx,
3181 tmp;
3182
3183 transvalues = check_float8_array(transarray, "float4_accum", 3);
3184 N = transvalues[0];
3185 Sx = transvalues[1];
3186 Sxx = transvalues[2];
3187
3188 /*
3189 * Use the Youngs-Cramer algorithm to incorporate the new value into the
3190 * transition values.
3191 */
3192 N += 1.0;
3193 Sx += newval;
3194 if (transvalues[0] > 0.0)
3195 {
3196 tmp = newval * N - Sx;
3197 Sxx += tmp * tmp / (N * transvalues[0]);
3198
3199 /*
3200 * Overflow check. We only report an overflow error when finite
3201 * inputs lead to infinite results. Note also that Sxx should be NaN
3202 * if any of the inputs are infinite, so we intentionally prevent Sxx
3203 * from becoming infinite.
3204 */
3205 if (isinf(Sx) || isinf(Sxx))
3206 {
3207 if (!isinf(transvalues[1]) && !isinf(newval))
3209
3210 Sxx = get_float8_nan();
3211 }
3212 }
3213 else
3214 {
3215 /*
3216 * At the first input, we normally can leave Sxx as 0. However, if
3217 * the first input is Inf or NaN, we'd better force Sxx to NaN;
3218 * otherwise we will falsely report variance zero when there are no
3219 * more inputs.
3220 */
3221 if (isnan(newval) || isinf(newval))
3222 Sxx = get_float8_nan();
3223 }
3224
3225 /*
3226 * If we're invoked as an aggregate, we can cheat and modify our first
3227 * parameter in-place to reduce palloc overhead. Otherwise we construct a
3228 * new array with the updated transition data and return it.
3229 */
3230 if (AggCheckCallContext(fcinfo, NULL))
3231 {
3232 transvalues[0] = N;
3233 transvalues[1] = Sx;
3234 transvalues[2] = Sxx;
3235
3237 }
3238 else
3239 {
3240 Datum transdatums[3];
3242
3246
3248
3250 }
3251}
3252
3253Datum
3255{
3258 float8 N,
3259 Sx;
3260
3261 transvalues = check_float8_array(transarray, "float8_avg", 3);
3262 N = transvalues[0];
3263 Sx = transvalues[1];
3264 /* ignore Sxx */
3265
3266 /* SQL defines AVG of no values to be NULL */
3267 if (N == 0.0)
3269
3270 PG_RETURN_FLOAT8(Sx / N);
3271}
3272
3273Datum
3275{
3278 float8 N,
3279 Sxx;
3280
3281 transvalues = check_float8_array(transarray, "float8_var_pop", 3);
3282 N = transvalues[0];
3283 /* ignore Sx */
3284 Sxx = transvalues[2];
3285
3286 /* Population variance is undefined when N is 0, so return NULL */
3287 if (N == 0.0)
3289
3290 /* Note that Sxx is guaranteed to be non-negative */
3291
3292 PG_RETURN_FLOAT8(Sxx / N);
3293}
3294
3295Datum
3297{
3300 float8 N,
3301 Sxx;
3302
3303 transvalues = check_float8_array(transarray, "float8_var_samp", 3);
3304 N = transvalues[0];
3305 /* ignore Sx */
3306 Sxx = transvalues[2];
3307
3308 /* Sample variance is undefined when N is 0 or 1, so return NULL */
3309 if (N <= 1.0)
3311
3312 /* Note that Sxx is guaranteed to be non-negative */
3313
3314 PG_RETURN_FLOAT8(Sxx / (N - 1.0));
3315}
3316
3317Datum
3319{
3322 float8 N,
3323 Sxx;
3324
3325 transvalues = check_float8_array(transarray, "float8_stddev_pop", 3);
3326 N = transvalues[0];
3327 /* ignore Sx */
3328 Sxx = transvalues[2];
3329
3330 /* Population stddev is undefined when N is 0, so return NULL */
3331 if (N == 0.0)
3333
3334 /* Note that Sxx is guaranteed to be non-negative */
3335
3337}
3338
3339Datum
3341{
3344 float8 N,
3345 Sxx;
3346
3347 transvalues = check_float8_array(transarray, "float8_stddev_samp", 3);
3348 N = transvalues[0];
3349 /* ignore Sx */
3350 Sxx = transvalues[2];
3351
3352 /* Sample stddev is undefined when N is 0 or 1, so return NULL */
3353 if (N <= 1.0)
3355
3356 /* Note that Sxx is guaranteed to be non-negative */
3357
3358 PG_RETURN_FLOAT8(sqrt(Sxx / (N - 1.0)));
3359}
3360
3361/*
3362 * =========================
3363 * SQL2003 BINARY AGGREGATES
3364 * =========================
3365 *
3366 * As with the preceding aggregates, we use the Youngs-Cramer algorithm to
3367 * reduce rounding errors in the aggregate final functions.
3368 *
3369 * The transition datatype for all these aggregates is an 8-element array of
3370 * float8, holding the values N, Sx=sum(X), Sxx=sum((X-Sx/N)^2), Sy=sum(Y),
3371 * Syy=sum((Y-Sy/N)^2), Sxy=sum((X-Sx/N)*(Y-Sy/N)), commonX, and commonY
3372 * in that order.
3373 *
3374 * commonX is defined as the common X value if all the X values were the same,
3375 * else NaN; likewise for commonY. This is useful for deciding whether corr()
3376 * and related functions should return NULL. This representation cannot
3377 * distinguish the-values-were-all-NaN from the-values-were-not-all-the-same,
3378 * but that's okay because for this purpose we use the IEEE float arithmetic
3379 * principle that two NaNs are never equal. The SQL standard doesn't mention
3380 * NaNs, but it says that NULL is to be returned when N*sum(X*X) equals
3381 * sum(X)*sum(X) (etc), and that shouldn't be considered true for NaNs.
3382 * Testing this as written in the spec would be highly subject to roundoff
3383 * error, so instead we directly track whether all the inputs are equal.
3384 *
3385 * Note that Y is the first argument to all these aggregates!
3386 *
3387 * It might seem attractive to optimize this by having multiple accumulator
3388 * functions that only calculate the sums actually needed. But on most
3389 * modern machines, a couple of extra floating-point multiplies will be
3390 * insignificant compared to the other per-tuple overhead, so I've chosen
3391 * to minimize code space instead.
3392 */
3393
3394Datum
3396{
3401 float8 N,
3402 Sx,
3403 Sxx,
3404 Sy,
3405 Syy,
3406 Sxy,
3407 commonX,
3408 commonY,
3409 tmpX,
3410 tmpY,
3411 scale;
3412
3413 transvalues = check_float8_array(transarray, "float8_regr_accum", 8);
3414 N = transvalues[0];
3415 Sx = transvalues[1];
3416 Sxx = transvalues[2];
3417 Sy = transvalues[3];
3418 Syy = transvalues[4];
3419 Sxy = transvalues[5];
3420 commonX = transvalues[6];
3421 commonY = transvalues[7];
3422
3423 /*
3424 * Use the Youngs-Cramer algorithm to incorporate the new values into the
3425 * transition values.
3426 */
3427 N += 1.0;
3428 Sx += newvalX;
3429 Sy += newvalY;
3430 if (transvalues[0] > 0.0)
3431 {
3432 /*
3433 * Check to see if we have seen distinct inputs. We can use a test
3434 * that's a bit cheaper than float8_ne() because if commonX is already
3435 * NaN, it does not matter whether the != test returns true or not.
3436 */
3437 if (newvalX != commonX || isnan(newvalX))
3439 if (newvalY != commonY || isnan(newvalY))
3441
3442 tmpX = newvalX * N - Sx;
3443 tmpY = newvalY * N - Sy;
3444 scale = 1.0 / (N * transvalues[0]);
3445
3446 /*
3447 * If we have not seen distinct inputs, then Sxx, Syy, and/or Sxy
3448 * should remain zero (since Sx's exact value would be N * commonX,
3449 * etc). Updating them would just create the possibility of injecting
3450 * roundoff error, and we need exact zero results so that the final
3451 * functions will return NULL in the right cases.
3452 */
3453 if (isnan(commonX))
3454 Sxx += tmpX * tmpX * scale;
3455 if (isnan(commonY))
3456 Syy += tmpY * tmpY * scale;
3457 if (isnan(commonX) && isnan(commonY))
3458 Sxy += tmpX * tmpY * scale;
3459
3460 /*
3461 * Overflow check. We only report an overflow error when finite
3462 * inputs lead to infinite results. Note also that Sxx, Syy and Sxy
3463 * should be NaN if any of the relevant inputs are infinite, so we
3464 * intentionally prevent them from becoming infinite.
3465 */
3466 if (isinf(Sx) || isinf(Sxx) || isinf(Sy) || isinf(Syy) || isinf(Sxy))
3467 {
3468 if (((isinf(Sx) || isinf(Sxx)) &&
3469 !isinf(transvalues[1]) && !isinf(newvalX)) ||
3470 ((isinf(Sy) || isinf(Syy)) &&
3471 !isinf(transvalues[3]) && !isinf(newvalY)) ||
3472 (isinf(Sxy) &&
3473 !isinf(transvalues[1]) && !isinf(newvalX) &&
3474 !isinf(transvalues[3]) && !isinf(newvalY)))
3476
3477 if (isinf(Sxx))
3478 Sxx = get_float8_nan();
3479 if (isinf(Syy))
3480 Syy = get_float8_nan();
3481 if (isinf(Sxy))
3482 Sxy = get_float8_nan();
3483 }
3484 }
3485 else
3486 {
3487 /*
3488 * At the first input, we normally can leave Sxx et al as 0. However,
3489 * if the first input is Inf or NaN, we'd better force the dependent
3490 * sums to NaN; otherwise we will falsely report variance zero when
3491 * there are no more inputs.
3492 */
3493 if (isnan(newvalX) || isinf(newvalX))
3494 Sxx = Sxy = get_float8_nan();
3495 if (isnan(newvalY) || isinf(newvalY))
3496 Syy = Sxy = get_float8_nan();
3497
3498 commonX = newvalX;
3499 commonY = newvalY;
3500 }
3501
3502 /*
3503 * If we're invoked as an aggregate, we can cheat and modify our first
3504 * parameter in-place to reduce palloc overhead. Otherwise we construct a
3505 * new array with the updated transition data and return it.
3506 */
3507 if (AggCheckCallContext(fcinfo, NULL))
3508 {
3509 transvalues[0] = N;
3510 transvalues[1] = Sx;
3511 transvalues[2] = Sxx;
3512 transvalues[3] = Sy;
3513 transvalues[4] = Syy;
3514 transvalues[5] = Sxy;
3515 transvalues[6] = commonX;
3516 transvalues[7] = commonY;
3517
3519 }
3520 else
3521 {
3522 Datum transdatums[8];
3524
3533
3535
3537 }
3538}
3539
3540/*
3541 * float8_regr_combine
3542 *
3543 * An aggregate combine function used to combine two 8-fields
3544 * aggregate transition data into a single transition data.
3545 * This function is used only in two stage aggregation and
3546 * shouldn't be called outside aggregate context.
3547 */
3548Datum
3550{
3555 float8 N1,
3556 Sx1,
3557 Sxx1,
3558 Sy1,
3559 Syy1,
3560 Sxy1,
3561 Cx1,
3562 Cy1,
3563 N2,
3564 Sx2,
3565 Sxx2,
3566 Sy2,
3567 Syy2,
3568 Sxy2,
3569 Cx2,
3570 Cy2,
3571 tmp1,
3572 tmp2,
3573 N,
3574 Sx,
3575 Sxx,
3576 Sy,
3577 Syy,
3578 Sxy,
3579 Cx,
3580 Cy;
3581
3582 transvalues1 = check_float8_array(transarray1, "float8_regr_combine", 8);
3583 transvalues2 = check_float8_array(transarray2, "float8_regr_combine", 8);
3584
3585 N1 = transvalues1[0];
3586 Sx1 = transvalues1[1];
3587 Sxx1 = transvalues1[2];
3588 Sy1 = transvalues1[3];
3589 Syy1 = transvalues1[4];
3590 Sxy1 = transvalues1[5];
3591 Cx1 = transvalues1[6];
3592 Cy1 = transvalues1[7];
3593
3594 N2 = transvalues2[0];
3595 Sx2 = transvalues2[1];
3596 Sxx2 = transvalues2[2];
3597 Sy2 = transvalues2[3];
3598 Syy2 = transvalues2[4];
3599 Sxy2 = transvalues2[5];
3600 Cx2 = transvalues2[6];
3601 Cy2 = transvalues2[7];
3602
3603 /*--------------------
3604 * The transition values combine using a generalization of the
3605 * Youngs-Cramer algorithm as follows:
3606 *
3607 * N = N1 + N2
3608 * Sx = Sx1 + Sx2
3609 * Sxx = Sxx1 + Sxx2 + N1 * N2 * (Sx1/N1 - Sx2/N2)^2 / N
3610 * Sy = Sy1 + Sy2
3611 * Syy = Syy1 + Syy2 + N1 * N2 * (Sy1/N1 - Sy2/N2)^2 / N
3612 * Sxy = Sxy1 + Sxy2 + N1 * N2 * (Sx1/N1 - Sx2/N2) * (Sy1/N1 - Sy2/N2) / N
3613 *
3614 * It's worth handling the special cases N1 = 0 and N2 = 0 separately
3615 * since those cases are trivial, and we then don't need to worry about
3616 * division-by-zero errors in the general case.
3617 *--------------------
3618 */
3619 if (N1 == 0.0)
3620 {
3621 N = N2;
3622 Sx = Sx2;
3623 Sxx = Sxx2;
3624 Sy = Sy2;
3625 Syy = Syy2;
3626 Sxy = Sxy2;
3627 Cx = Cx2;
3628 Cy = Cy2;
3629 }
3630 else if (N2 == 0.0)
3631 {
3632 N = N1;
3633 Sx = Sx1;
3634 Sxx = Sxx1;
3635 Sy = Sy1;
3636 Syy = Syy1;
3637 Sxy = Sxy1;
3638 Cx = Cx1;
3639 Cy = Cy1;
3640 }
3641 else
3642 {
3643 N = N1 + N2;
3644 Sx = float8_pl(Sx1, Sx2);
3645 tmp1 = Sx1 / N1 - Sx2 / N2;
3646 Sxx = Sxx1 + Sxx2 + N1 * N2 * tmp1 * tmp1 / N;
3647 if (unlikely(isinf(Sxx)) && !isinf(Sxx1) && !isinf(Sxx2))
3649 Sy = float8_pl(Sy1, Sy2);
3650 tmp2 = Sy1 / N1 - Sy2 / N2;
3651 Syy = Syy1 + Syy2 + N1 * N2 * tmp2 * tmp2 / N;
3652 if (unlikely(isinf(Syy)) && !isinf(Syy1) && !isinf(Syy2))
3654 Sxy = Sxy1 + Sxy2 + N1 * N2 * tmp1 * tmp2 / N;
3655 if (unlikely(isinf(Sxy)) && !isinf(Sxy1) && !isinf(Sxy2))
3657 if (float8_eq(Cx1, Cx2))
3658 Cx = Cx1;
3659 else
3660 Cx = get_float8_nan();
3661 if (float8_eq(Cy1, Cy2))
3662 Cy = Cy1;
3663 else
3664 Cy = get_float8_nan();
3665 }
3666
3667 /*
3668 * If we're invoked as an aggregate, we can cheat and modify our first
3669 * parameter in-place to reduce palloc overhead. Otherwise we construct a
3670 * new array with the updated transition data and return it.
3671 */
3672 if (AggCheckCallContext(fcinfo, NULL))
3673 {
3674 transvalues1[0] = N;
3675 transvalues1[1] = Sx;
3676 transvalues1[2] = Sxx;
3677 transvalues1[3] = Sy;
3678 transvalues1[4] = Syy;
3679 transvalues1[5] = Sxy;
3680 transvalues1[6] = Cx;
3681 transvalues1[7] = Cy;
3682
3684 }
3685 else
3686 {
3687 Datum transdatums[8];
3689
3698
3700
3702 }
3703}
3704
3705
3706Datum
3708{
3711 float8 N,
3712 Sxx;
3713
3714 transvalues = check_float8_array(transarray, "float8_regr_sxx", 8);
3715 N = transvalues[0];
3716 Sxx = transvalues[2];
3717
3718 /* if N is 0 we should return NULL */
3719 if (N < 1.0)
3721
3722 /* Note that Sxx is guaranteed to be non-negative */
3723
3725}
3726
3727Datum
3729{
3732 float8 N,
3733 Syy;
3734
3735 transvalues = check_float8_array(transarray, "float8_regr_syy", 8);
3736 N = transvalues[0];
3737 Syy = transvalues[4];
3738
3739 /* if N is 0 we should return NULL */
3740 if (N < 1.0)
3742
3743 /* Note that Syy is guaranteed to be non-negative */
3744
3746}
3747
3748Datum
3750{
3753 float8 N,
3754 Sxy;
3755
3756 transvalues = check_float8_array(transarray, "float8_regr_sxy", 8);
3757 N = transvalues[0];
3758 Sxy = transvalues[5];
3759
3760 /* if N is 0 we should return NULL */
3761 if (N < 1.0)
3763
3764 /* A negative result is valid here */
3765
3767}
3768
3769Datum
3771{
3774 float8 N,
3775 Sx,
3776 commonX;
3777
3778 transvalues = check_float8_array(transarray, "float8_regr_avgx", 8);
3779 N = transvalues[0];
3780 Sx = transvalues[1];
3781 commonX = transvalues[6];
3782
3783 /* if N is 0 we should return NULL */
3784 if (N < 1.0)
3786
3787 /* if all inputs were the same just return that, avoiding roundoff error */
3788 if (!isnan(commonX))
3790
3791 PG_RETURN_FLOAT8(Sx / N);
3792}
3793
3794Datum
3796{
3799 float8 N,
3800 Sy,
3801 commonY;
3802
3803 transvalues = check_float8_array(transarray, "float8_regr_avgy", 8);
3804 N = transvalues[0];
3805 Sy = transvalues[3];
3806 commonY = transvalues[7];
3807
3808 /* if N is 0 we should return NULL */
3809 if (N < 1.0)
3811
3812 /* if all inputs were the same just return that, avoiding roundoff error */
3813 if (!isnan(commonY))
3815
3816 PG_RETURN_FLOAT8(Sy / N);
3817}
3818
3819Datum
3821{
3824 float8 N,
3825 Sxy;
3826
3827 transvalues = check_float8_array(transarray, "float8_covar_pop", 8);
3828 N = transvalues[0];
3829 Sxy = transvalues[5];
3830
3831 /* if N is 0 we should return NULL */
3832 if (N < 1.0)
3834
3835 PG_RETURN_FLOAT8(Sxy / N);
3836}
3837
3838Datum
3840{
3843 float8 N,
3844 Sxy;
3845
3846 transvalues = check_float8_array(transarray, "float8_covar_samp", 8);
3847 N = transvalues[0];
3848 Sxy = transvalues[5];
3849
3850 /* if N is <= 1 we should return NULL */
3851 if (N < 2.0)
3853
3854 PG_RETURN_FLOAT8(Sxy / (N - 1.0));
3855}
3856
3857Datum
3859{
3862 float8 N,
3863 Sxx,
3864 Syy,
3865 Sxy,
3866 product,
3868 result;
3869
3870 transvalues = check_float8_array(transarray, "float8_corr", 8);
3871 N = transvalues[0];
3872 Sxx = transvalues[2];
3873 Syy = transvalues[4];
3874 Sxy = transvalues[5];
3875
3876 /* if N is 0 we should return NULL */
3877 if (N < 1.0)
3879
3880 /* Note that Sxx and Syy are guaranteed to be non-negative */
3881
3882 /* per spec, return NULL for horizontal and vertical lines */
3883 if (Sxx == 0 || Syy == 0)
3885
3886 /*
3887 * The product Sxx * Syy might underflow or overflow. If so, we can
3888 * recover by computing sqrt(Sxx) * sqrt(Syy) instead of sqrt(Sxx * Syy).
3889 * However, the double sqrt() calculation is a bit slower and less
3890 * accurate, so don't do it if we don't have to.
3891 */
3892 product = Sxx * Syy;
3893 if (product == 0 || isinf(product))
3894 sqrtproduct = sqrt(Sxx) * sqrt(Syy);
3895 else
3898
3899 /*
3900 * Despite all these precautions, this formula can yield results outside
3901 * [-1, 1] due to roundoff error. Clamp it to the expected range.
3902 */
3903 if (result < -1)
3904 result = -1;
3905 else if (result > 1)
3906 result = 1;
3907
3909}
3910
3911Datum
3913{
3916 float8 N,
3917 Sxx,
3918 Syy,
3919 Sxy;
3920
3921 transvalues = check_float8_array(transarray, "float8_regr_r2", 8);
3922 N = transvalues[0];
3923 Sxx = transvalues[2];
3924 Syy = transvalues[4];
3925 Sxy = transvalues[5];
3926
3927 /* if N is 0 we should return NULL */
3928 if (N < 1.0)
3930
3931 /* Note that Sxx and Syy are guaranteed to be non-negative */
3932
3933 /* per spec, return NULL for a vertical line */
3934 if (Sxx == 0)
3936
3937 /* per spec, return 1.0 for a horizontal line */
3938 if (Syy == 0)
3939 PG_RETURN_FLOAT8(1.0);
3940
3941 PG_RETURN_FLOAT8((Sxy * Sxy) / (Sxx * Syy));
3942}
3943
3944Datum
3946{
3949 float8 N,
3950 Sxx,
3951 Sxy;
3952
3953 transvalues = check_float8_array(transarray, "float8_regr_slope", 8);
3954 N = transvalues[0];
3955 Sxx = transvalues[2];
3956 Sxy = transvalues[5];
3957
3958 /* if N is 0 we should return NULL */
3959 if (N < 1.0)
3961
3962 /* Note that Sxx is guaranteed to be non-negative */
3963
3964 /* per spec, return NULL for a vertical line */
3965 if (Sxx == 0)
3967
3969}
3970
3971Datum
3973{
3976 float8 N,
3977 Sx,
3978 Sxx,
3979 Sy,
3980 Sxy;
3981
3982 transvalues = check_float8_array(transarray, "float8_regr_intercept", 8);
3983 N = transvalues[0];
3984 Sx = transvalues[1];
3985 Sxx = transvalues[2];
3986 Sy = transvalues[3];
3987 Sxy = transvalues[5];
3988
3989 /* if N is 0 we should return NULL */
3990 if (N < 1.0)
3992
3993 /* Note that Sxx is guaranteed to be non-negative */
3994
3995 /* per spec, return NULL for a vertical line */
3996 if (Sxx == 0)
3998
3999 PG_RETURN_FLOAT8((Sy - Sx * Sxy / Sxx) / N);
4000}
4001
4002
4003/*
4004 * ====================================
4005 * MIXED-PRECISION ARITHMETIC OPERATORS
4006 * ====================================
4007 */
4008
4009/*
4010 * float48pl - returns arg1 + arg2
4011 * float48mi - returns arg1 - arg2
4012 * float48mul - returns arg1 * arg2
4013 * float48div - returns arg1 / arg2
4014 */
4015Datum
4023
4024Datum
4032
4033Datum
4041
4042Datum
4050
4051/*
4052 * float84pl - returns arg1 + arg2
4053 * float84mi - returns arg1 - arg2
4054 * float84mul - returns arg1 * arg2
4055 * float84div - returns arg1 / arg2
4056 */
4057Datum
4065
4066Datum
4074
4075Datum
4083
4084Datum
4092
4093/*
4094 * ====================
4095 * COMPARISON OPERATORS
4096 * ====================
4097 */
4098
4099/*
4100 * float48{eq,ne,lt,le,gt,ge} - float4/float8 comparison operations
4101 */
4102Datum
4110
4111Datum
4119
4120Datum
4128
4129Datum
4137
4138Datum
4146
4147Datum
4155
4156/*
4157 * float84{eq,ne,lt,le,gt,ge} - float8/float4 comparison operations
4158 */
4159Datum
4167
4168Datum
4176
4177Datum
4185
4186Datum
4194
4195Datum
4203
4204Datum
4212
4213/*
4214 * Implements the float8 version of the width_bucket() function
4215 * defined by SQL2003. See also width_bucket_numeric().
4216 *
4217 * 'bound1' and 'bound2' are the lower and upper bounds of the
4218 * histogram's range, respectively. 'count' is the number of buckets
4219 * in the histogram. width_bucket() returns an integer indicating the
4220 * bucket number that 'operand' belongs to in an equiwidth histogram
4221 * with the specified characteristics. An operand smaller than the
4222 * lower bound is assigned to bucket 0. An operand greater than or equal
4223 * to the upper bound is assigned to an additional bucket (with number
4224 * count+1). We don't allow the histogram bounds to be NaN or +/- infinity,
4225 * but we do allow those values for the operand (taking NaN to be larger
4226 * than any other value, as we do in comparisons).
4227 */
4228Datum
4230{
4231 float8 operand = PG_GETARG_FLOAT8(0);
4234 int32 count = PG_GETARG_INT32(3);
4235 int32 result;
4236
4237 if (count <= 0)
4238 ereport(ERROR,
4240 errmsg("count must be greater than zero")));
4241
4242 if (isnan(bound1) || isnan(bound2))
4243 ereport(ERROR,
4245 errmsg("lower and upper bounds cannot be NaN")));
4246
4247 if (isinf(bound1) || isinf(bound2))
4248 ereport(ERROR,
4250 errmsg("lower and upper bounds must be finite")));
4251
4252 if (bound1 < bound2)
4253 {
4254 if (isnan(operand) || operand >= bound2)
4255 {
4256 if (pg_add_s32_overflow(count, 1, &result))
4257 ereport(ERROR,
4259 errmsg("integer out of range")));
4260 }
4261 else if (operand < bound1)
4262 result = 0;
4263 else
4264 {
4265 if (!isinf(bound2 - bound1))
4266 {
4267 /* The quotient is surely in [0,1], so this can't overflow */
4268 result = count * ((operand - bound1) / (bound2 - bound1));
4269 }
4270 else
4271 {
4272 /*
4273 * We get here if bound2 - bound1 overflows DBL_MAX. Since
4274 * both bounds are finite, their difference can't exceed twice
4275 * DBL_MAX; so we can perform the computation without overflow
4276 * by dividing all the inputs by 2. That should be exact too,
4277 * except in the case where a very small operand underflows to
4278 * zero, which would have negligible impact on the result
4279 * given such large bounds.
4280 */
4281 result = count * ((operand / 2 - bound1 / 2) / (bound2 / 2 - bound1 / 2));
4282 }
4283 /* The quotient could round to 1.0, which would be a lie */
4284 if (result >= count)
4285 result = count - 1;
4286 /* Having done that, we can add 1 without fear of overflow */
4287 result++;
4288 }
4289 }
4290 else if (bound1 > bound2)
4291 {
4292 if (isnan(operand) || operand > bound1)
4293 result = 0;
4294 else if (operand <= bound2)
4295 {
4296 if (pg_add_s32_overflow(count, 1, &result))
4297 ereport(ERROR,
4299 errmsg("integer out of range")));
4300 }
4301 else
4302 {
4303 if (!isinf(bound1 - bound2))
4304 result = count * ((bound1 - operand) / (bound1 - bound2));
4305 else
4306 result = count * ((bound1 / 2 - operand / 2) / (bound1 / 2 - bound2 / 2));
4307 if (result >= count)
4308 result = count - 1;
4309 result++;
4310 }
4311 }
4312 else
4313 {
4314 ereport(ERROR,
4316 errmsg("lower bound cannot equal upper bound")));
4317 result = 0; /* keep the compiler quiet */
4318 }
4319
4321}
#define ARR_NDIM(a)
Definition array.h:290
#define PG_GETARG_ARRAYTYPE_P(n)
Definition array.h:263
#define ARR_DATA_PTR(a)
Definition array.h:322
#define ARR_ELEMTYPE(a)
Definition array.h:292
#define PG_RETURN_ARRAYTYPE_P(x)
Definition array.h:265
#define ARR_DIMS(a)
Definition array.h:294
#define ARR_HASNULL(a)
Definition array.h:291
ArrayType * construct_array_builtin(Datum *elems, int nelems, Oid elmtype)
#define FLOAT4_FITS_IN_INT32(num)
Definition c.h:1171
#define FLOAT8_FITS_IN_INT32(num)
Definition c.h:1177
#define pg_noinline
Definition c.h:321
#define FLOAT4_FITS_IN_INT16(num)
Definition c.h:1169
double float8
Definition c.h:714
int16_t int16
Definition c.h:619
int32_t int32
Definition c.h:620
#define FLOAT8_FITS_IN_INT16(num)
Definition c.h:1175
#define unlikely(x)
Definition c.h:438
float float4
Definition c.h:713
uint32 result
int double_to_shortest_decimal_buf(double f, char *result)
Definition d2s.c:1053
#define M_PI
Datum arg
Definition elog.c:1322
int errcode(int sqlerrcode)
Definition elog.c:874
#define ereturn(context, dummy_value,...)
Definition elog.h:280
#define ERROR
Definition elog.h:40
#define elog(elevel,...)
Definition elog.h:228
#define ereport(elevel,...)
Definition elog.h:152
struct SortSupportData * SortSupport
Definition execnodes.h:61
int float_to_shortest_decimal_buf(float f, char *result)
Definition f2s.c:780
float8 float8in_internal(char *num, char **endptr_p, const char *type_name, const char *orig_string, struct Node *escontext)
Definition float.c:436
Datum float4lt(PG_FUNCTION_ARGS)
Definition float.c:885
Datum dceil(PG_FUNCTION_ARGS)
Definition float.c:1421
float8 float_underflow_error_ext(struct Node *escontext)
Definition float.c:135
Datum btfloat4cmp(PG_FUNCTION_ARGS)
Definition float.c:921
float8 degree_c_sixty
Definition float.c:85
static float8 acos_0_5
Definition float.c:64
Datum float84gt(PG_FUNCTION_ARGS)
Definition float.c:4196
Datum dasinh(PG_FUNCTION_ARGS)
Definition float.c:2713
Datum float84mi(PG_FUNCTION_ARGS)
Definition float.c:4067
static double sind_0_to_30(double x)
Definition float.c:2293
Datum dtof(PG_FUNCTION_ARGS)
Definition float.c:1236
Datum radians(PG_FUNCTION_ARGS)
Definition float.c:2624
pg_noinline void float_zero_divide_error(void)
Definition float.c:119
pg_noinline void float_overflow_error(void)
Definition float.c:103
Datum width_bucket_float8(PG_FUNCTION_ARGS)
Definition float.c:4229
Datum dasind(PG_FUNCTION_ARGS)
Definition float.c:2186
Datum float8_var_samp(PG_FUNCTION_ARGS)
Definition float.c:3296
Datum btfloat84cmp(PG_FUNCTION_ARGS)
Definition float.c:1052
Datum ftoi4(PG_FUNCTION_ARGS)
Definition float.c:1329
Datum dsind(PG_FUNCTION_ARGS)
Definition float.c:2480
Datum datan2(PG_FUNCTION_ARGS)
Definition float.c:1884
Datum derfc(PG_FUNCTION_ARGS)
Definition float.c:2813
Datum float8div(PG_FUNCTION_ARGS)
Definition float.c:838
Datum float8_regr_syy(PG_FUNCTION_ARGS)
Definition float.c:3728
Datum float48gt(PG_FUNCTION_ARGS)
Definition float.c:4139
Datum degrees(PG_FUNCTION_ARGS)
Definition float.c:2602
Datum btfloat4sortsupport(PG_FUNCTION_ARGS)
Definition float.c:939
Datum dlgamma(PG_FUNCTION_ARGS)
Definition float.c:2891
Datum dacosd(PG_FUNCTION_ARGS)
Definition float.c:2149
float8 degree_c_thirty
Definition float.c:83
int extra_float_digits
Definition float.c:57
static double acosd_q1(double x)
Definition float.c:2122
Datum float8_regr_r2(PG_FUNCTION_ARGS)
Definition float.c:3912
Datum float8_regr_combine(PG_FUNCTION_ARGS)
Definition float.c:3549
Datum float8_regr_slope(PG_FUNCTION_ARGS)
Definition float.c:3945
Datum float8eq(PG_FUNCTION_ARGS)
Definition float.c:961
Datum dtanh(PG_FUNCTION_ARGS)
Definition float.c:2693
static double cosd_q1(double x)
Definition float.c:2340
Datum dlog10(PG_FUNCTION_ARGS)
Definition float.c:1763
Datum float84mul(PG_FUNCTION_ARGS)
Definition float.c:4076
static bool degree_consts_set
Definition float.c:60
Datum datanh(PG_FUNCTION_ARGS)
Definition float.c:2755
Datum dcosd(PG_FUNCTION_ARGS)
Definition float.c:2359
static int btfloat8fastcmp(Datum x, Datum y, SortSupport ssup)
Definition float.c:1024
Datum derf(PG_FUNCTION_ARGS)
Definition float.c:2793
Datum float4up(PG_FUNCTION_ARGS)
Definition float.c:653
static float8 atan_1_0
Definition float.c:65
Datum float48pl(PG_FUNCTION_ARGS)
Definition float.c:4016
Datum dsinh(PG_FUNCTION_ARGS)
Definition float.c:2639
Datum float8_combine(PG_FUNCTION_ARGS)
Definition float.c:2998
Datum float8_avg(PG_FUNCTION_ARGS)
Definition float.c:3254
Datum float8_covar_pop(PG_FUNCTION_ARGS)
Definition float.c:3820
Datum dtan(PG_FUNCTION_ARGS)
Definition float.c:2006
Datum float8ge(PG_FUNCTION_ARGS)
Definition float.c:1006
Datum float8_stddev_pop(PG_FUNCTION_ARGS)
Definition float.c:3318
static double asind_q1(double x)
Definition float.c:2089
Datum dround(PG_FUNCTION_ARGS)
Definition float.c:1409
Datum float4um(PG_FUNCTION_ARGS)
Definition float.c:643
Datum dlog1(PG_FUNCTION_ARGS)
Definition float.c:1731
Datum datan2d(PG_FUNCTION_ARGS)
Definition float.c:2255
Datum float4abs(PG_FUNCTION_ARGS)
Definition float.c:632
Datum ftod(PG_FUNCTION_ARGS)
Definition float.c:1224
Datum float4mul(PG_FUNCTION_ARGS)
Definition float.c:787
Datum float4le(PG_FUNCTION_ARGS)
Definition float.c:894
Datum dcos(PG_FUNCTION_ARGS)
Definition float.c:1910
Datum float8_regr_intercept(PG_FUNCTION_ARGS)
Definition float.c:3972
Datum float8out(PG_FUNCTION_ARGS)
Definition float.c:563
Datum float84le(PG_FUNCTION_ARGS)
Definition float.c:4187
Datum dexp(PG_FUNCTION_ARGS)
Definition float.c:1685
Datum float8pl(PG_FUNCTION_ARGS)
Definition float.c:811
Datum float8lt(PG_FUNCTION_ARGS)
Definition float.c:979
Datum float4gt(PG_FUNCTION_ARGS)
Definition float.c:903
Datum float4out(PG_FUNCTION_ARGS)
Definition float.c:360
#define INIT_DEGREE_CONSTANTS()
Definition float.c:2072
Datum dsign(PG_FUNCTION_ARGS)
Definition float.c:1446
Datum float8recv(PG_FUNCTION_ARGS)
Definition float.c:597
Datum float4send(PG_FUNCTION_ARGS)
Definition float.c:391
static float8 cot_45
Definition float.c:67
Datum float4ne(PG_FUNCTION_ARGS)
Definition float.c:876
Datum float84eq(PG_FUNCTION_ARGS)
Definition float.c:4160
Datum float84lt(PG_FUNCTION_ARGS)
Definition float.c:4178
Datum float48mi(PG_FUNCTION_ARGS)
Definition float.c:4025
Datum float8le(PG_FUNCTION_ARGS)
Definition float.c:988
Datum dtrunc(PG_FUNCTION_ARGS)
Definition float.c:1469
Datum btfloat8cmp(PG_FUNCTION_ARGS)
Definition float.c:1015
Datum float8in(PG_FUNCTION_ARGS)
Definition float.c:405
Datum float8ne(PG_FUNCTION_ARGS)
Definition float.c:970
Datum dpow(PG_FUNCTION_ARGS)
Definition float.c:1530
Datum float8mi(PG_FUNCTION_ARGS)
Definition float.c:820
static double sind_q1(double x)
Definition float.c:2320
Datum ftoi2(PG_FUNCTION_ARGS)
Definition float.c:1354
Datum float4mi(PG_FUNCTION_ARGS)
Definition float.c:778
Datum float8_accum(PG_FUNCTION_ARGS)
Definition float.c:3090
Datum float48eq(PG_FUNCTION_ARGS)
Definition float.c:4103
Datum i2tof(PG_FUNCTION_ARGS)
Definition float.c:1391
static float8 one_minus_cos_60
Definition float.c:62
Datum float84pl(PG_FUNCTION_ARGS)
Definition float.c:4058
Datum btfloat48cmp(PG_FUNCTION_ARGS)
Definition float.c:1042
Datum float48ge(PG_FUNCTION_ARGS)
Definition float.c:4148
Datum float84div(PG_FUNCTION_ARGS)
Definition float.c:4085
Datum dcotd(PG_FUNCTION_ARGS)
Definition float.c:2414
pg_noinline void float_underflow_error(void)
Definition float.c:111
Datum float8smaller(PG_FUNCTION_ARGS)
Definition float.c:742
float8 degree_c_forty_five
Definition float.c:84
Datum dsqrt(PG_FUNCTION_ARGS)
Definition float.c:1487
Datum float84ge(PG_FUNCTION_ARGS)
Definition float.c:4205
Datum float8_stddev_samp(PG_FUNCTION_ARGS)
Definition float.c:3340
Datum datand(PG_FUNCTION_ARGS)
Definition float.c:2223
Datum float8larger(PG_FUNCTION_ARGS)
Definition float.c:728
Datum dcbrt(PG_FUNCTION_ARGS)
Definition float.c:1511
Datum float4in(PG_FUNCTION_ARGS)
Definition float.c:205
static int btfloat4fastcmp(Datum x, Datum y, SortSupport ssup)
Definition float.c:930
Datum float8_regr_sxy(PG_FUNCTION_ARGS)
Definition float.c:3749
Datum float8_var_pop(PG_FUNCTION_ARGS)
Definition float.c:3274
Datum float48div(PG_FUNCTION_ARGS)
Definition float.c:4043
Datum float84ne(PG_FUNCTION_ARGS)
Definition float.c:4169
Datum float4_accum(PG_FUNCTION_ARGS)
Definition float.c:3171
Datum float8up(PG_FUNCTION_ARGS)
Definition float.c:720
int float4_cmp_internal(float4 a, float4 b)
Definition float.c:857
static float8 tan_45
Definition float.c:66
Datum float48le(PG_FUNCTION_ARGS)
Definition float.c:4130
Datum float8_regr_sxx(PG_FUNCTION_ARGS)
Definition float.c:3707
Datum float8_corr(PG_FUNCTION_ARGS)
Definition float.c:3858
static float8 sin_30
Definition float.c:61
float8 degree_c_one
Definition float.c:87
Datum float4recv(PG_FUNCTION_ARGS)
Definition float.c:380
float8 degree_c_one_half
Definition float.c:86
Datum in_range_float8_float8(PG_FUNCTION_ARGS)
Definition float.c:1068
float8 float_overflow_error_ext(struct Node *escontext)
Definition float.c:127
Datum float48ne(PG_FUNCTION_ARGS)
Definition float.c:4112
Datum dpi(PG_FUNCTION_ARGS)
Definition float.c:2614
float4 float4in_internal(char *num, char **endptr_p, const char *type_name, const char *orig_string, struct Node *escontext)
Definition float.c:224
Datum dacos(PG_FUNCTION_ARGS)
Definition float.c:1796
Datum float48lt(PG_FUNCTION_ARGS)
Definition float.c:4121
static void init_degree_constants(void)
Definition float.c:2060
Datum dgamma(PG_FUNCTION_ARGS)
Definition float.c:2837
Datum float8mul(PG_FUNCTION_ARGS)
Definition float.c:829
Datum float4div(PG_FUNCTION_ARGS)
Definition float.c:796
Datum in_range_float4_float8(PG_FUNCTION_ARGS)
Definition float.c:1144
Datum dtand(PG_FUNCTION_ARGS)
Definition float.c:2536
Datum float8abs(PG_FUNCTION_ARGS)
Definition float.c:698
Datum i4tod(PG_FUNCTION_ARGS)
Definition float.c:1305
int is_infinite(double val)
Definition float.c:159
Datum i2tod(PG_FUNCTION_ARGS)
Definition float.c:1317
Datum dfloor(PG_FUNCTION_ARGS)
Definition float.c:1433
Datum btfloat8sortsupport(PG_FUNCTION_ARGS)
Definition float.c:1033
Datum dcosh(PG_FUNCTION_ARGS)
Definition float.c:2668
Datum dacosh(PG_FUNCTION_ARGS)
Definition float.c:2730
Datum float4ge(PG_FUNCTION_ARGS)
Definition float.c:912
Datum dasin(PG_FUNCTION_ARGS)
Definition float.c:1827
Datum i4tof(PG_FUNCTION_ARGS)
Definition float.c:1379
Datum datan(PG_FUNCTION_ARGS)
Definition float.c:1858
Datum float8gt(PG_FUNCTION_ARGS)
Definition float.c:997
Datum float8_regr_avgx(PG_FUNCTION_ARGS)
Definition float.c:3770
Datum float8um(PG_FUNCTION_ARGS)
Definition float.c:710
Datum float8_regr_avgy(PG_FUNCTION_ARGS)
Definition float.c:3795
Datum dcot(PG_FUNCTION_ARGS)
Definition float.c:1951
Datum dsin(PG_FUNCTION_ARGS)
Definition float.c:1979
Datum dtoi4(PG_FUNCTION_ARGS)
Definition float.c:1255
Datum float4pl(PG_FUNCTION_ARGS)
Definition float.c:769
static float8 asin_0_5
Definition float.c:63
Datum float8_covar_samp(PG_FUNCTION_ARGS)
Definition float.c:3839
Datum float8send(PG_FUNCTION_ARGS)
Definition float.c:608
Datum float4larger(PG_FUNCTION_ARGS)
Definition float.c:661
Datum dtoi2(PG_FUNCTION_ARGS)
Definition float.c:1280
static float8 * check_float8_array(ArrayType *transarray, const char *caller, int n)
Definition float.c:2974
static double cosd_0_to_60(double x)
Definition float.c:2307
Datum float48mul(PG_FUNCTION_ARGS)
Definition float.c:4034
float8 float_zero_divide_error_ext(struct Node *escontext)
Definition float.c:143
Datum float4smaller(PG_FUNCTION_ARGS)
Definition float.c:675
Datum float8_regr_accum(PG_FUNCTION_ARGS)
Definition float.c:3395
char * float8out_internal(double num)
Definition float.c:578
int float8_cmp_internal(float8 a, float8 b)
Definition float.c:951
Datum float4eq(PG_FUNCTION_ARGS)
Definition float.c:867
static float8 float8_mul(const float8 val1, const float8 val2)
Definition float.h:192
static float4 float4_div(const float4 val1, const float4 val2)
Definition float.h:198
#define RADIANS_PER_DEGREE
Definition float.h:26
static float4 get_float4_infinity(void)
Definition float.h:61
static bool float4_lt(const float4 val1, const float4 val2)
Definition float.h:268
static float8 float8_pl(const float8 val1, const float8 val2)
Definition float.h:128
static float8 float8_mi(const float8 val1, const float8 val2)
Definition float.h:158
static bool float4_ge(const float4 val1, const float4 val2)
Definition float.h:304
static float4 get_float4_nan(void)
Definition float.h:80
static bool float8_ne(const float8 val1, const float8 val2)
Definition float.h:262
static bool float4_ne(const float4 val1, const float4 val2)
Definition float.h:256
static float4 float4_pl(const float4 val1, const float4 val2)
Definition float.h:104
static bool float4_eq(const float4 val1, const float4 val2)
Definition float.h:244
static float4 float4_mul(const float4 val1, const float4 val2)
Definition float.h:164
static float8 get_float8_infinity(void)
Definition float.h:68
static bool float8_ge(const float8 val1, const float8 val2)
Definition float.h:310
static float4 float4_mi(const float4 val1, const float4 val2)
Definition float.h:134
static bool float8_le(const float8 val1, const float8 val2)
Definition float.h:286
static bool float4_gt(const float4 val1, const float4 val2)
Definition float.h:292
static bool float8_eq(const float8 val1, const float8 val2)
Definition float.h:250
static bool float4_le(const float4 val1, const float4 val2)
Definition float.h:280
static float8 get_float8_nan(void)
Definition float.h:87
static float8 float8_div(const float8 val1, const float8 val2)
Definition float.h:230
static bool float8_lt(const float8 val1, const float8 val2)
Definition float.h:274
static bool float8_gt(const float8 val1, const float8 val2)
Definition float.h:298
#define PG_RETURN_VOID()
Definition fmgr.h:350
#define PG_RETURN_BYTEA_P(x)
Definition fmgr.h:373
#define PG_GETARG_FLOAT8(n)
Definition fmgr.h:283
#define PG_RETURN_FLOAT8(x)
Definition fmgr.h:369
#define PG_GETARG_POINTER(n)
Definition fmgr.h:277
#define PG_RETURN_CSTRING(x)
Definition fmgr.h:364
#define PG_GETARG_CSTRING(n)
Definition fmgr.h:278
#define PG_RETURN_NULL()
Definition fmgr.h:346
#define PG_RETURN_INT16(x)
Definition fmgr.h:357
#define PG_RETURN_INT32(x)
Definition fmgr.h:355
#define PG_GETARG_INT32(n)
Definition fmgr.h:269
#define PG_GETARG_BOOL(n)
Definition fmgr.h:274
#define PG_GETARG_FLOAT4(n)
Definition fmgr.h:282
#define PG_RETURN_FLOAT4(x)
Definition fmgr.h:368
#define PG_FUNCTION_ARGS
Definition fmgr.h:193
#define PG_RETURN_BOOL(x)
Definition fmgr.h:360
#define PG_GETARG_INT16(n)
Definition fmgr.h:271
#define newval
long val
Definition informix.c:689
char sign
Definition informix.c:693
static bool pg_add_s32_overflow(int32 a, int32 b, int32 *result)
Definition int.h:151
int y
Definition isn.c:76
int b
Definition isn.c:74
int x
Definition isn.c:75
int a
Definition isn.c:73
char * pstrdup(const char *in)
Definition mcxt.c:1781
void * palloc(Size size)
Definition mcxt.c:1387
int AggCheckCallContext(FunctionCallInfo fcinfo, MemoryContext *aggcontext)
Definition nodeAgg.c:4609
static char * errmsg
Datum ascii(PG_FUNCTION_ARGS)
static char buf[DEFAULT_XLOG_SEG_SIZE]
static int scale
Definition pgbench.c:182
int pg_strfromd(char *str, size_t count, int precision, double value)
Definition snprintf.c:1276
int pg_strncasecmp(const char *s1, const char *s2, size_t n)
static float4 DatumGetFloat4(Datum X)
Definition postgres.h:451
#define Float8GetDatumFast(X)
Definition postgres.h:527
static float8 DatumGetFloat8(Datum X)
Definition postgres.h:485
uint64_t Datum
Definition postgres.h:70
float4 pq_getmsgfloat4(StringInfo msg)
Definition pqformat.c:468
float8 pq_getmsgfloat8(StringInfo msg)
Definition pqformat.c:487
void pq_begintypsend(StringInfo buf)
Definition pqformat.c:325
void pq_sendfloat4(StringInfo buf, float4 f)
Definition pqformat.c:252
bytea * pq_endtypsend(StringInfo buf)
Definition pqformat.c:345
void pq_sendfloat8(StringInfo buf, float8 f)
Definition pqformat.c:276
static int fb(int x)
struct StringInfoData * StringInfo
Definition string.h:15
Definition nodes.h:135
int(* comparator)(Datum x, Datum y, SortSupport ssup)