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 * Configurable GUC parameter
34 *
35 * If >0, use shortest-decimal format for output; this is both the default and
36 * allows for compatibility with clients that explicitly set a value here to
37 * get round-trip-accurate results. If 0 or less, then use the old, slow,
38 * decimal rounding method.
39 */
41
42/* Cached constants for degree-based trig functions */
43static bool degree_consts_set = false;
44static float8 sin_30 = 0;
46static float8 asin_0_5 = 0;
47static float8 acos_0_5 = 0;
48static float8 atan_1_0 = 0;
49static float8 tan_45 = 0;
50static float8 cot_45 = 0;
51
52/*
53 * These are intentionally not static; don't "fix" them. They will never
54 * be referenced by other files, much less changed; but we don't want the
55 * compiler to know that, else it might try to precompute expressions
56 * involving them. See comments for init_degree_constants().
57 *
58 * The additional extern declarations are to silence
59 * -Wmissing-variable-declarations.
60 */
65extern float8 degree_c_one;
71
72/* Local function prototypes */
73static double sind_q1(double x);
74static double cosd_q1(double x);
75static void init_degree_constants(void);
76
77
78/*
79 * We use these out-of-line ereport() calls to report float overflow,
80 * underflow, and zero-divide, because following our usual practice of
81 * repeating them at each call site would lead to a lot of code bloat.
82 *
83 * This does mean that you don't get a useful error location indicator.
84 */
85pg_noinline void
87{
90 errmsg("value out of range: overflow")));
91}
92
93pg_noinline void
95{
98 errmsg("value out of range: underflow")));
99}
100
101pg_noinline void
103{
106 errmsg("division by zero")));
107}
108
109
110/*
111 * Returns -1 if 'val' represents negative infinity, 1 if 'val'
112 * represents (positive) infinity, and 0 otherwise. On some platforms,
113 * this is equivalent to the isinf() macro, but not everywhere: C99
114 * does not specify that isinf() needs to distinguish between positive
115 * and negative infinity.
116 */
117int
119{
120 int inf = isinf(val);
121
122 if (inf == 0)
123 return 0;
124 else if (val > 0)
125 return 1;
126 else
127 return -1;
128}
129
130
131/* ========== USER I/O ROUTINES ========== */
132
133
134/*
135 * float4in - converts "num" to float4
136 *
137 * Note that this code now uses strtof(), where it used to use strtod().
138 *
139 * The motivation for using strtof() is to avoid a double-rounding problem:
140 * for certain decimal inputs, if you round the input correctly to a double,
141 * and then round the double to a float, the result is incorrect in that it
142 * does not match the result of rounding the decimal value to float directly.
143 *
144 * One of the best examples is 7.038531e-26:
145 *
146 * 0xAE43FDp-107 = 7.03853069185120912085...e-26
147 * midpoint 7.03853100000000022281...e-26
148 * 0xAE43FEp-107 = 7.03853130814879132477...e-26
149 *
150 * making 0xAE43FDp-107 the correct float result, but if you do the conversion
151 * via a double, you get
152 *
153 * 0xAE43FD.7FFFFFF8p-107 = 7.03853099999999907487...e-26
154 * midpoint 7.03853099999999964884...e-26
155 * 0xAE43FD.80000000p-107 = 7.03853100000000022281...e-26
156 * 0xAE43FD.80000008p-107 = 7.03853100000000137076...e-26
157 *
158 * so the value rounds to the double exactly on the midpoint between the two
159 * nearest floats, and then rounding again to a float gives the incorrect
160 * result of 0xAE43FEp-107.
161 *
162 */
163Datum
165{
166 char *num = PG_GETARG_CSTRING(0);
167
168 PG_RETURN_FLOAT4(float4in_internal(num, NULL, "real", num,
169 fcinfo->context));
170}
171
172/*
173 * float4in_internal - guts of float4in()
174 *
175 * This is exposed for use by functions that want a reasonably
176 * platform-independent way of inputting floats. The behavior is
177 * essentially like strtof + ereturn on error.
178 *
179 * Uses the same API as float8in_internal below, so most of its
180 * comments also apply here, except regarding use in geometric types.
181 */
182float4
183float4in_internal(char *num, char **endptr_p,
184 const char *type_name, const char *orig_string,
185 struct Node *escontext)
186{
187 float val;
188 char *endptr;
189
190 /*
191 * endptr points to the first character _after_ the sequence we recognized
192 * as a valid floating point number. orig_string points to the original
193 * input string.
194 */
195
196 /* skip leading whitespace */
197 while (*num != '\0' && isspace((unsigned char) *num))
198 num++;
199
200 /*
201 * Check for an empty-string input to begin with, to avoid the vagaries of
202 * strtod() on different platforms.
203 */
204 if (*num == '\0')
205 ereturn(escontext, 0,
207 errmsg("invalid input syntax for type %s: \"%s\"",
208 type_name, orig_string)));
209
210 errno = 0;
211 val = strtof(num, &endptr);
212
213 /* did we not see anything that looks like a double? */
214 if (endptr == num || errno != 0)
215 {
216 int save_errno = errno;
217
218 /*
219 * C99 requires that strtof() accept NaN, [+-]Infinity, and [+-]Inf,
220 * but not all platforms support all of these (and some accept them
221 * but set ERANGE anyway...) Therefore, we check for these inputs
222 * ourselves if strtof() fails.
223 *
224 * Note: C99 also requires hexadecimal input as well as some extended
225 * forms of NaN, but we consider these forms unportable and don't try
226 * to support them. You can use 'em if your strtof() takes 'em.
227 */
228 if (pg_strncasecmp(num, "NaN", 3) == 0)
229 {
231 endptr = num + 3;
232 }
233 else if (pg_strncasecmp(num, "Infinity", 8) == 0)
234 {
236 endptr = num + 8;
237 }
238 else if (pg_strncasecmp(num, "+Infinity", 9) == 0)
239 {
241 endptr = num + 9;
242 }
243 else if (pg_strncasecmp(num, "-Infinity", 9) == 0)
244 {
246 endptr = num + 9;
247 }
248 else if (pg_strncasecmp(num, "inf", 3) == 0)
249 {
251 endptr = num + 3;
252 }
253 else if (pg_strncasecmp(num, "+inf", 4) == 0)
254 {
256 endptr = num + 4;
257 }
258 else if (pg_strncasecmp(num, "-inf", 4) == 0)
259 {
261 endptr = num + 4;
262 }
263 else if (save_errno == ERANGE)
264 {
265 /*
266 * Some platforms return ERANGE for denormalized numbers (those
267 * that are not zero, but are too close to zero to have full
268 * precision). We'd prefer not to throw error for that, so try to
269 * detect whether it's a "real" out-of-range condition by checking
270 * to see if the result is zero or huge.
271 */
272 if (val == 0.0 ||
273#if !defined(HUGE_VALF)
274 isinf(val)
275#else
276 (val >= HUGE_VALF || val <= -HUGE_VALF)
277#endif
278 )
279 {
280 /* see comments in float8in_internal for rationale */
281 char *errnumber = pstrdup(num);
282
283 errnumber[endptr - num] = '\0';
284
285 ereturn(escontext, 0,
287 errmsg("\"%s\" is out of range for type real",
288 errnumber)));
289 }
290 }
291 else
292 ereturn(escontext, 0,
294 errmsg("invalid input syntax for type %s: \"%s\"",
295 type_name, orig_string)));
296 }
297
298 /* skip trailing whitespace */
299 while (*endptr != '\0' && isspace((unsigned char) *endptr))
300 endptr++;
301
302 /* report stopping point if wanted, else complain if not end of string */
303 if (endptr_p)
304 *endptr_p = endptr;
305 else if (*endptr != '\0')
306 ereturn(escontext, 0,
308 errmsg("invalid input syntax for type %s: \"%s\"",
309 type_name, orig_string)));
310
311 return val;
312}
313
314/*
315 * float4out - converts a float4 number to a string
316 * using a standard output format
317 */
318Datum
320{
321 float4 num = PG_GETARG_FLOAT4(0);
322 char *ascii = (char *) palloc(32);
324
325 if (extra_float_digits > 0)
326 {
329 }
330
331 (void) pg_strfromd(ascii, 32, ndig, num);
333}
334
335/*
336 * float4recv - converts external binary format to float4
337 */
338Datum
345
346/*
347 * float4send - converts float4 to binary format
348 */
349Datum
359
360/*
361 * float8in - converts "num" to float8
362 */
363Datum
365{
366 char *num = PG_GETARG_CSTRING(0);
367
368 PG_RETURN_FLOAT8(float8in_internal(num, NULL, "double precision", num,
369 fcinfo->context));
370}
371
372/*
373 * float8in_internal - guts of float8in()
374 *
375 * This is exposed for use by functions that want a reasonably
376 * platform-independent way of inputting doubles. The behavior is
377 * essentially like strtod + ereturn on error, but note the following
378 * differences:
379 * 1. Both leading and trailing whitespace are skipped.
380 * 2. If endptr_p is NULL, we report error if there's trailing junk.
381 * Otherwise, it's up to the caller to complain about trailing junk.
382 * 3. In event of a syntax error, the report mentions the given type_name
383 * and prints orig_string as the input; this is meant to support use of
384 * this function with types such as "box" and "point", where what we are
385 * parsing here is just a substring of orig_string.
386 *
387 * If escontext points to an ErrorSaveContext node, that is filled instead
388 * of throwing an error; the caller must check SOFT_ERROR_OCCURRED()
389 * to detect errors.
390 *
391 * "num" could validly be declared "const char *", but that results in an
392 * unreasonable amount of extra casting both here and in callers, so we don't.
393 */
394float8
395float8in_internal(char *num, char **endptr_p,
396 const char *type_name, const char *orig_string,
397 struct Node *escontext)
398{
399 double val;
400 char *endptr;
401
402 /* skip leading whitespace */
403 while (*num != '\0' && isspace((unsigned char) *num))
404 num++;
405
406 /*
407 * Check for an empty-string input to begin with, to avoid the vagaries of
408 * strtod() on different platforms.
409 */
410 if (*num == '\0')
411 ereturn(escontext, 0,
413 errmsg("invalid input syntax for type %s: \"%s\"",
414 type_name, orig_string)));
415
416 errno = 0;
417 val = strtod(num, &endptr);
418
419 /* did we not see anything that looks like a double? */
420 if (endptr == num || errno != 0)
421 {
422 int save_errno = errno;
423
424 /*
425 * C99 requires that strtod() accept NaN, [+-]Infinity, and [+-]Inf,
426 * but not all platforms support all of these (and some accept them
427 * but set ERANGE anyway...) Therefore, we check for these inputs
428 * ourselves if strtod() fails.
429 *
430 * Note: C99 also requires hexadecimal input as well as some extended
431 * forms of NaN, but we consider these forms unportable and don't try
432 * to support them. You can use 'em if your strtod() takes 'em.
433 */
434 if (pg_strncasecmp(num, "NaN", 3) == 0)
435 {
437 endptr = num + 3;
438 }
439 else if (pg_strncasecmp(num, "Infinity", 8) == 0)
440 {
442 endptr = num + 8;
443 }
444 else if (pg_strncasecmp(num, "+Infinity", 9) == 0)
445 {
447 endptr = num + 9;
448 }
449 else if (pg_strncasecmp(num, "-Infinity", 9) == 0)
450 {
452 endptr = num + 9;
453 }
454 else if (pg_strncasecmp(num, "inf", 3) == 0)
455 {
457 endptr = num + 3;
458 }
459 else if (pg_strncasecmp(num, "+inf", 4) == 0)
460 {
462 endptr = num + 4;
463 }
464 else if (pg_strncasecmp(num, "-inf", 4) == 0)
465 {
467 endptr = num + 4;
468 }
469 else if (save_errno == ERANGE)
470 {
471 /*
472 * Some platforms return ERANGE for denormalized numbers (those
473 * that are not zero, but are too close to zero to have full
474 * precision). We'd prefer not to throw error for that, so try to
475 * detect whether it's a "real" out-of-range condition by checking
476 * to see if the result is zero or huge.
477 *
478 * On error, we intentionally complain about double precision not
479 * the given type name, and we print only the part of the string
480 * that is the current number.
481 */
482 if (val == 0.0 || val >= HUGE_VAL || val <= -HUGE_VAL)
483 {
484 char *errnumber = pstrdup(num);
485
486 errnumber[endptr - num] = '\0';
487 ereturn(escontext, 0,
489 errmsg("\"%s\" is out of range for type double precision",
490 errnumber)));
491 }
492 }
493 else
494 ereturn(escontext, 0,
496 errmsg("invalid input syntax for type %s: \"%s\"",
497 type_name, orig_string)));
498 }
499
500 /* skip trailing whitespace */
501 while (*endptr != '\0' && isspace((unsigned char) *endptr))
502 endptr++;
503
504 /* report stopping point if wanted, else complain if not end of string */
505 if (endptr_p)
506 *endptr_p = endptr;
507 else if (*endptr != '\0')
508 ereturn(escontext, 0,
510 errmsg("invalid input syntax for type %s: \"%s\"",
511 type_name, orig_string)));
512
513 return val;
514}
515
516
517/*
518 * float8out - converts float8 number to a string
519 * using a standard output format
520 */
521Datum
528
529/*
530 * float8out_internal - guts of float8out()
531 *
532 * This is exposed for use by functions that want a reasonably
533 * platform-independent way of outputting doubles.
534 * The result is always palloc'd.
535 */
536char *
538{
539 char *ascii = (char *) palloc(32);
541
542 if (extra_float_digits > 0)
543 {
545 return ascii;
546 }
547
548 (void) pg_strfromd(ascii, 32, ndig, num);
549 return ascii;
550}
551
552/*
553 * float8recv - converts external binary format to float8
554 */
555Datum
562
563/*
564 * float8send - converts float8 to binary format
565 */
566Datum
576
577
578/* ========== PUBLIC ROUTINES ========== */
579
580
581/*
582 * ======================
583 * FLOAT4 BASE OPERATIONS
584 * ======================
585 */
586
587/*
588 * float4abs - returns |arg1| (absolute value)
589 */
590Datum
597
598/*
599 * float4um - returns -arg1 (unary minus)
600 */
601Datum
603{
605 float4 result;
606
607 result = -arg1;
608 PG_RETURN_FLOAT4(result);
609}
610
611Datum
618
619Datum
621{
624 float4 result;
625
626 if (float4_gt(arg1, arg2))
627 result = arg1;
628 else
629 result = arg2;
630 PG_RETURN_FLOAT4(result);
631}
632
633Datum
635{
638 float4 result;
639
640 if (float4_lt(arg1, arg2))
641 result = arg1;
642 else
643 result = arg2;
644 PG_RETURN_FLOAT4(result);
645}
646
647/*
648 * ======================
649 * FLOAT8 BASE OPERATIONS
650 * ======================
651 */
652
653/*
654 * float8abs - returns |arg1| (absolute value)
655 */
656Datum
663
664
665/*
666 * float8um - returns -arg1 (unary minus)
667 */
668Datum
670{
672 float8 result;
673
674 result = -arg1;
675 PG_RETURN_FLOAT8(result);
676}
677
678Datum
685
686Datum
688{
691 float8 result;
692
693 if (float8_gt(arg1, arg2))
694 result = arg1;
695 else
696 result = arg2;
697 PG_RETURN_FLOAT8(result);
698}
699
700Datum
702{
705 float8 result;
706
707 if (float8_lt(arg1, arg2))
708 result = arg1;
709 else
710 result = arg2;
711 PG_RETURN_FLOAT8(result);
712}
713
714
715/*
716 * ====================
717 * ARITHMETIC OPERATORS
718 * ====================
719 */
720
721/*
722 * float4pl - returns arg1 + arg2
723 * float4mi - returns arg1 - arg2
724 * float4mul - returns arg1 * arg2
725 * float4div - returns arg1 / arg2
726 */
727Datum
735
736Datum
744
745Datum
753
754Datum
762
763/*
764 * float8pl - returns arg1 + arg2
765 * float8mi - returns arg1 - arg2
766 * float8mul - returns arg1 * arg2
767 * float8div - returns arg1 / arg2
768 */
769Datum
777
778Datum
786
787Datum
795
796Datum
804
805
806/*
807 * ====================
808 * COMPARISON OPERATORS
809 * ====================
810 */
811
812/*
813 * float4{eq,ne,lt,le,gt,ge} - float4/float4 comparison operations
814 */
815int
817{
818 if (float4_gt(a, b))
819 return 1;
820 if (float4_lt(a, b))
821 return -1;
822 return 0;
823}
824
825Datum
833
834Datum
842
843Datum
851
852Datum
860
861Datum
869
870Datum
878
879Datum
887
888static int
896
897Datum
905
906/*
907 * float8{eq,ne,lt,le,gt,ge} - float8/float8 comparison operations
908 */
909int
911{
912 if (float8_gt(a, b))
913 return 1;
914 if (float8_lt(a, b))
915 return -1;
916 return 0;
917}
918
919Datum
927
928Datum
936
937Datum
945
946Datum
954
955Datum
963
964Datum
972
973Datum
981
982static int
990
991Datum
999
1000Datum
1002{
1005
1006 /* widen float4 to float8 and then compare */
1008}
1009
1010Datum
1012{
1015
1016 /* widen float4 to float8 and then compare */
1018}
1019
1020/*
1021 * in_range support function for float8.
1022 *
1023 * Note: we needn't supply a float8_float4 variant, as implicit coercion
1024 * of the offset value takes care of that scenario just as well.
1025 */
1026Datum
1028{
1030 float8 base = PG_GETARG_FLOAT8(1);
1031 float8 offset = PG_GETARG_FLOAT8(2);
1032 bool sub = PG_GETARG_BOOL(3);
1033 bool less = PG_GETARG_BOOL(4);
1034 float8 sum;
1035
1036 /*
1037 * Reject negative or NaN offset. Negative is per spec, and NaN is
1038 * because appropriate semantics for that seem non-obvious.
1039 */
1040 if (isnan(offset) || offset < 0)
1041 ereport(ERROR,
1043 errmsg("invalid preceding or following size in window function")));
1044
1045 /*
1046 * Deal with cases where val and/or base is NaN, following the rule that
1047 * NaN sorts after non-NaN (cf float8_cmp_internal). The offset cannot
1048 * affect the conclusion.
1049 */
1050 if (isnan(val))
1051 {
1052 if (isnan(base))
1053 PG_RETURN_BOOL(true); /* NAN = NAN */
1054 else
1055 PG_RETURN_BOOL(!less); /* NAN > non-NAN */
1056 }
1057 else if (isnan(base))
1058 {
1059 PG_RETURN_BOOL(less); /* non-NAN < NAN */
1060 }
1061
1062 /*
1063 * Deal with cases where both base and offset are infinite, and computing
1064 * base +/- offset would produce NaN. This corresponds to a window frame
1065 * whose boundary infinitely precedes +inf or infinitely follows -inf,
1066 * which is not well-defined. For consistency with other cases involving
1067 * infinities, such as the fact that +inf infinitely follows +inf, we
1068 * choose to assume that +inf infinitely precedes +inf and -inf infinitely
1069 * follows -inf, and therefore that all finite and infinite values are in
1070 * such a window frame.
1071 *
1072 * offset is known positive, so we need only check the sign of base in
1073 * this test.
1074 */
1075 if (isinf(offset) && isinf(base) &&
1076 (sub ? base > 0 : base < 0))
1077 PG_RETURN_BOOL(true);
1078
1079 /*
1080 * Otherwise it should be safe to compute base +/- offset. We trust the
1081 * FPU to cope if an input is +/-inf or the true sum would overflow, and
1082 * produce a suitably signed infinity, which will compare properly against
1083 * val whether or not that's infinity.
1084 */
1085 if (sub)
1086 sum = base - offset;
1087 else
1088 sum = base + offset;
1089
1090 if (less)
1091 PG_RETURN_BOOL(val <= sum);
1092 else
1093 PG_RETURN_BOOL(val >= sum);
1094}
1095
1096/*
1097 * in_range support function for float4.
1098 *
1099 * We would need a float4_float8 variant in any case, so we supply that and
1100 * let implicit coercion take care of the float4_float4 case.
1101 */
1102Datum
1104{
1106 float4 base = PG_GETARG_FLOAT4(1);
1107 float8 offset = PG_GETARG_FLOAT8(2);
1108 bool sub = PG_GETARG_BOOL(3);
1109 bool less = PG_GETARG_BOOL(4);
1110 float8 sum;
1111
1112 /*
1113 * Reject negative or NaN offset. Negative is per spec, and NaN is
1114 * because appropriate semantics for that seem non-obvious.
1115 */
1116 if (isnan(offset) || offset < 0)
1117 ereport(ERROR,
1119 errmsg("invalid preceding or following size in window function")));
1120
1121 /*
1122 * Deal with cases where val and/or base is NaN, following the rule that
1123 * NaN sorts after non-NaN (cf float8_cmp_internal). The offset cannot
1124 * affect the conclusion.
1125 */
1126 if (isnan(val))
1127 {
1128 if (isnan(base))
1129 PG_RETURN_BOOL(true); /* NAN = NAN */
1130 else
1131 PG_RETURN_BOOL(!less); /* NAN > non-NAN */
1132 }
1133 else if (isnan(base))
1134 {
1135 PG_RETURN_BOOL(less); /* non-NAN < NAN */
1136 }
1137
1138 /*
1139 * Deal with cases where both base and offset are infinite, and computing
1140 * base +/- offset would produce NaN. This corresponds to a window frame
1141 * whose boundary infinitely precedes +inf or infinitely follows -inf,
1142 * which is not well-defined. For consistency with other cases involving
1143 * infinities, such as the fact that +inf infinitely follows +inf, we
1144 * choose to assume that +inf infinitely precedes +inf and -inf infinitely
1145 * follows -inf, and therefore that all finite and infinite values are in
1146 * such a window frame.
1147 *
1148 * offset is known positive, so we need only check the sign of base in
1149 * this test.
1150 */
1151 if (isinf(offset) && isinf(base) &&
1152 (sub ? base > 0 : base < 0))
1153 PG_RETURN_BOOL(true);
1154
1155 /*
1156 * Otherwise it should be safe to compute base +/- offset. We trust the
1157 * FPU to cope if an input is +/-inf or the true sum would overflow, and
1158 * produce a suitably signed infinity, which will compare properly against
1159 * val whether or not that's infinity.
1160 */
1161 if (sub)
1162 sum = base - offset;
1163 else
1164 sum = base + offset;
1165
1166 if (less)
1167 PG_RETURN_BOOL(val <= sum);
1168 else
1169 PG_RETURN_BOOL(val >= sum);
1170}
1171
1172
1173/*
1174 * ===================
1175 * CONVERSION ROUTINES
1176 * ===================
1177 */
1178
1179/*
1180 * ftod - converts a float4 number to a float8 number
1181 */
1182Datum
1184{
1185 float4 num = PG_GETARG_FLOAT4(0);
1186
1187 PG_RETURN_FLOAT8((float8) num);
1188}
1189
1190
1191/*
1192 * dtof - converts a float8 number to a float4 number
1193 */
1194Datum
1196{
1197 float8 num = PG_GETARG_FLOAT8(0);
1198 float4 result;
1199
1200 result = (float4) num;
1201 if (unlikely(isinf(result)) && !isinf(num))
1203 if (unlikely(result == 0.0f) && num != 0.0)
1205
1206 PG_RETURN_FLOAT4(result);
1207}
1208
1209
1210/*
1211 * dtoi4 - converts a float8 number to an int4 number
1212 */
1213Datum
1215{
1216 float8 num = PG_GETARG_FLOAT8(0);
1217
1218 /*
1219 * Get rid of any fractional part in the input. This is so we don't fail
1220 * on just-out-of-range values that would round into range. Note
1221 * assumption that rint() will pass through a NaN or Inf unchanged.
1222 */
1223 num = rint(num);
1224
1225 /* Range check */
1226 if (unlikely(isnan(num) || !FLOAT8_FITS_IN_INT32(num)))
1227 ereport(ERROR,
1229 errmsg("integer out of range")));
1230
1231 PG_RETURN_INT32((int32) num);
1232}
1233
1234
1235/*
1236 * dtoi2 - converts a float8 number to an int2 number
1237 */
1238Datum
1240{
1241 float8 num = PG_GETARG_FLOAT8(0);
1242
1243 /*
1244 * Get rid of any fractional part in the input. This is so we don't fail
1245 * on just-out-of-range values that would round into range. Note
1246 * assumption that rint() will pass through a NaN or Inf unchanged.
1247 */
1248 num = rint(num);
1249
1250 /* Range check */
1251 if (unlikely(isnan(num) || !FLOAT8_FITS_IN_INT16(num)))
1252 ereport(ERROR,
1254 errmsg("smallint out of range")));
1255
1256 PG_RETURN_INT16((int16) num);
1257}
1258
1259
1260/*
1261 * i4tod - converts an int4 number to a float8 number
1262 */
1263Datum
1265{
1266 int32 num = PG_GETARG_INT32(0);
1267
1268 PG_RETURN_FLOAT8((float8) num);
1269}
1270
1271
1272/*
1273 * i2tod - converts an int2 number to a float8 number
1274 */
1275Datum
1277{
1278 int16 num = PG_GETARG_INT16(0);
1279
1280 PG_RETURN_FLOAT8((float8) num);
1281}
1282
1283
1284/*
1285 * ftoi4 - converts a float4 number to an int4 number
1286 */
1287Datum
1289{
1290 float4 num = PG_GETARG_FLOAT4(0);
1291
1292 /*
1293 * Get rid of any fractional part in the input. This is so we don't fail
1294 * on just-out-of-range values that would round into range. Note
1295 * assumption that rint() will pass through a NaN or Inf unchanged.
1296 */
1297 num = rint(num);
1298
1299 /* Range check */
1300 if (unlikely(isnan(num) || !FLOAT4_FITS_IN_INT32(num)))
1301 ereport(ERROR,
1303 errmsg("integer out of range")));
1304
1305 PG_RETURN_INT32((int32) num);
1306}
1307
1308
1309/*
1310 * ftoi2 - converts a float4 number to an int2 number
1311 */
1312Datum
1314{
1315 float4 num = PG_GETARG_FLOAT4(0);
1316
1317 /*
1318 * Get rid of any fractional part in the input. This is so we don't fail
1319 * on just-out-of-range values that would round into range. Note
1320 * assumption that rint() will pass through a NaN or Inf unchanged.
1321 */
1322 num = rint(num);
1323
1324 /* Range check */
1325 if (unlikely(isnan(num) || !FLOAT4_FITS_IN_INT16(num)))
1326 ereport(ERROR,
1328 errmsg("smallint out of range")));
1329
1330 PG_RETURN_INT16((int16) num);
1331}
1332
1333
1334/*
1335 * i4tof - converts an int4 number to a float4 number
1336 */
1337Datum
1339{
1340 int32 num = PG_GETARG_INT32(0);
1341
1342 PG_RETURN_FLOAT4((float4) num);
1343}
1344
1345
1346/*
1347 * i2tof - converts an int2 number to a float4 number
1348 */
1349Datum
1351{
1352 int16 num = PG_GETARG_INT16(0);
1353
1354 PG_RETURN_FLOAT4((float4) num);
1355}
1356
1357
1358/*
1359 * =======================
1360 * RANDOM FLOAT8 OPERATORS
1361 * =======================
1362 */
1363
1364/*
1365 * dround - returns ROUND(arg1)
1366 */
1367Datum
1374
1375/*
1376 * dceil - returns the smallest integer greater than or
1377 * equal to the specified float
1378 */
1379Datum
1386
1387/*
1388 * dfloor - returns the largest integer lesser than or
1389 * equal to the specified float
1390 */
1391Datum
1398
1399/*
1400 * dsign - returns -1 if the argument is less than 0, 0
1401 * if the argument is equal to 0, and 1 if the
1402 * argument is greater than zero.
1403 */
1404Datum
1406{
1408 float8 result;
1409
1410 if (arg1 > 0)
1411 result = 1.0;
1412 else if (arg1 < 0)
1413 result = -1.0;
1414 else
1415 result = 0.0;
1416
1417 PG_RETURN_FLOAT8(result);
1418}
1419
1420/*
1421 * dtrunc - returns truncation-towards-zero of arg1,
1422 * arg1 >= 0 ... the greatest integer less
1423 * than or equal to arg1
1424 * arg1 < 0 ... the least integer greater
1425 * than or equal to arg1
1426 */
1427Datum
1429{
1431 float8 result;
1432
1433 if (arg1 >= 0)
1434 result = floor(arg1);
1435 else
1436 result = -floor(-arg1);
1437
1438 PG_RETURN_FLOAT8(result);
1439}
1440
1441
1442/*
1443 * dsqrt - returns square root of arg1
1444 */
1445Datum
1447{
1449 float8 result;
1450
1451 if (arg1 < 0)
1452 ereport(ERROR,
1454 errmsg("cannot take square root of a negative number")));
1455
1456 result = sqrt(arg1);
1457 if (unlikely(isinf(result)) && !isinf(arg1))
1459 if (unlikely(result == 0.0) && arg1 != 0.0)
1461
1462 PG_RETURN_FLOAT8(result);
1463}
1464
1465
1466/*
1467 * dcbrt - returns cube root of arg1
1468 */
1469Datum
1471{
1473 float8 result;
1474
1475 result = cbrt(arg1);
1476 if (unlikely(isinf(result)) && !isinf(arg1))
1478 if (unlikely(result == 0.0) && arg1 != 0.0)
1480
1481 PG_RETURN_FLOAT8(result);
1482}
1483
1484
1485/*
1486 * dpow - returns pow(arg1,arg2)
1487 */
1488Datum
1490{
1493 float8 result;
1494
1495 /*
1496 * The POSIX spec says that NaN ^ 0 = 1, and 1 ^ NaN = 1, while all other
1497 * cases with NaN inputs yield NaN (with no error). Many older platforms
1498 * get one or more of these cases wrong, so deal with them via explicit
1499 * logic rather than trusting pow(3).
1500 */
1501 if (isnan(arg1))
1502 {
1503 if (isnan(arg2) || arg2 != 0.0)
1505 PG_RETURN_FLOAT8(1.0);
1506 }
1507 if (isnan(arg2))
1508 {
1509 if (arg1 != 1.0)
1511 PG_RETURN_FLOAT8(1.0);
1512 }
1513
1514 /*
1515 * The SQL spec requires that we emit a particular SQLSTATE error code for
1516 * certain error conditions. Specifically, we don't return a
1517 * divide-by-zero error code for 0 ^ -1.
1518 */
1519 if (arg1 == 0 && arg2 < 0)
1520 ereport(ERROR,
1522 errmsg("zero raised to a negative power is undefined")));
1523 if (arg1 < 0 && floor(arg2) != arg2)
1524 ereport(ERROR,
1526 errmsg("a negative number raised to a non-integer power yields a complex result")));
1527
1528 /*
1529 * We don't trust the platform's pow() to handle infinity cases per POSIX
1530 * spec either, so deal with those explicitly too. It's easier to handle
1531 * infinite y first, so that it doesn't matter if x is also infinite.
1532 */
1533 if (isinf(arg2))
1534 {
1535 float8 absx = fabs(arg1);
1536
1537 if (absx == 1.0)
1538 result = 1.0;
1539 else if (arg2 > 0.0) /* y = +Inf */
1540 {
1541 if (absx > 1.0)
1542 result = arg2;
1543 else
1544 result = 0.0;
1545 }
1546 else /* y = -Inf */
1547 {
1548 if (absx > 1.0)
1549 result = 0.0;
1550 else
1551 result = -arg2;
1552 }
1553 }
1554 else if (isinf(arg1))
1555 {
1556 if (arg2 == 0.0)
1557 result = 1.0;
1558 else if (arg1 > 0.0) /* x = +Inf */
1559 {
1560 if (arg2 > 0.0)
1561 result = arg1;
1562 else
1563 result = 0.0;
1564 }
1565 else /* x = -Inf */
1566 {
1567 /*
1568 * Per POSIX, the sign of the result depends on whether y is an
1569 * odd integer. Since x < 0, we already know from the previous
1570 * domain check that y is an integer. It is odd if y/2 is not
1571 * also an integer.
1572 */
1573 float8 halfy = arg2 / 2; /* should be computed exactly */
1574 bool yisoddinteger = (floor(halfy) != halfy);
1575
1576 if (arg2 > 0.0)
1577 result = yisoddinteger ? arg1 : -arg1;
1578 else
1579 result = yisoddinteger ? -0.0 : 0.0;
1580 }
1581 }
1582 else
1583 {
1584 /*
1585 * pow() sets errno on only some platforms, depending on whether it
1586 * follows _IEEE_, _POSIX_, _XOPEN_, or _SVID_, so we must check both
1587 * errno and invalid output values. (We can't rely on just the
1588 * latter, either; some old platforms return a large-but-finite
1589 * HUGE_VAL when reporting overflow.)
1590 */
1591 errno = 0;
1592 result = pow(arg1, arg2);
1593 if (errno == EDOM || isnan(result))
1594 {
1595 /*
1596 * We handled all possible domain errors above, so this should be
1597 * impossible. However, old glibc versions on x86 have a bug that
1598 * causes them to fail this way for abs(y) greater than 2^63:
1599 *
1600 * https://sourceware.org/bugzilla/show_bug.cgi?id=3866
1601 *
1602 * Hence, if we get here, assume y is finite but large (large
1603 * enough to be certainly even). The result should be 0 if x == 0,
1604 * 1.0 if abs(x) == 1.0, otherwise an overflow or underflow error.
1605 */
1606 if (arg1 == 0.0)
1607 result = 0.0; /* we already verified y is positive */
1608 else
1609 {
1610 float8 absx = fabs(arg1);
1611
1612 if (absx == 1.0)
1613 result = 1.0;
1614 else if (arg2 >= 0.0 ? (absx > 1.0) : (absx < 1.0))
1616 else
1618 }
1619 }
1620 else if (errno == ERANGE)
1621 {
1622 if (result != 0.0)
1624 else
1626 }
1627 else
1628 {
1629 if (unlikely(isinf(result)))
1631 if (unlikely(result == 0.0) && arg1 != 0.0)
1633 }
1634 }
1635
1636 PG_RETURN_FLOAT8(result);
1637}
1638
1639
1640/*
1641 * dexp - returns the exponential function of arg1
1642 */
1643Datum
1645{
1647 float8 result;
1648
1649 /*
1650 * Handle NaN and Inf cases explicitly. This avoids needing to assume
1651 * that the platform's exp() conforms to POSIX for these cases, and it
1652 * removes some edge cases for the overflow checks below.
1653 */
1654 if (isnan(arg1))
1655 result = arg1;
1656 else if (isinf(arg1))
1657 {
1658 /* Per POSIX, exp(-Inf) is 0 */
1659 result = (arg1 > 0.0) ? arg1 : 0;
1660 }
1661 else
1662 {
1663 /*
1664 * On some platforms, exp() will not set errno but just return Inf or
1665 * zero to report overflow/underflow; therefore, test both cases.
1666 */
1667 errno = 0;
1668 result = exp(arg1);
1669 if (unlikely(errno == ERANGE))
1670 {
1671 if (result != 0.0)
1673 else
1675 }
1676 else if (unlikely(isinf(result)))
1678 else if (unlikely(result == 0.0))
1680 }
1681
1682 PG_RETURN_FLOAT8(result);
1683}
1684
1685
1686/*
1687 * dlog1 - returns the natural logarithm of arg1
1688 */
1689Datum
1691{
1693 float8 result;
1694
1695 /*
1696 * Emit particular SQLSTATE error codes for ln(). This is required by the
1697 * SQL standard.
1698 */
1699 if (arg1 == 0.0)
1700 ereport(ERROR,
1702 errmsg("cannot take logarithm of zero")));
1703 if (arg1 < 0)
1704 ereport(ERROR,
1706 errmsg("cannot take logarithm of a negative number")));
1707
1708 result = log(arg1);
1709 if (unlikely(isinf(result)) && !isinf(arg1))
1711 if (unlikely(result == 0.0) && arg1 != 1.0)
1713
1714 PG_RETURN_FLOAT8(result);
1715}
1716
1717
1718/*
1719 * dlog10 - returns the base 10 logarithm of arg1
1720 */
1721Datum
1723{
1725 float8 result;
1726
1727 /*
1728 * Emit particular SQLSTATE error codes for log(). The SQL spec doesn't
1729 * define log(), but it does define ln(), so it makes sense to emit the
1730 * same error code for an analogous error condition.
1731 */
1732 if (arg1 == 0.0)
1733 ereport(ERROR,
1735 errmsg("cannot take logarithm of zero")));
1736 if (arg1 < 0)
1737 ereport(ERROR,
1739 errmsg("cannot take logarithm of a negative number")));
1740
1741 result = log10(arg1);
1742 if (unlikely(isinf(result)) && !isinf(arg1))
1744 if (unlikely(result == 0.0) && arg1 != 1.0)
1746
1747 PG_RETURN_FLOAT8(result);
1748}
1749
1750
1751/*
1752 * dacos - returns the arccos of arg1 (radians)
1753 */
1754Datum
1756{
1758 float8 result;
1759
1760 /* Per the POSIX spec, return NaN if the input is NaN */
1761 if (isnan(arg1))
1763
1764 /*
1765 * The principal branch of the inverse cosine function maps values in the
1766 * range [-1, 1] to values in the range [0, Pi], so we should reject any
1767 * inputs outside that range and the result will always be finite.
1768 */
1769 if (arg1 < -1.0 || arg1 > 1.0)
1770 ereport(ERROR,
1772 errmsg("input is out of range")));
1773
1774 result = acos(arg1);
1775 if (unlikely(isinf(result)))
1777
1778 PG_RETURN_FLOAT8(result);
1779}
1780
1781
1782/*
1783 * dasin - returns the arcsin of arg1 (radians)
1784 */
1785Datum
1787{
1789 float8 result;
1790
1791 /* Per the POSIX spec, return NaN if the input is NaN */
1792 if (isnan(arg1))
1794
1795 /*
1796 * The principal branch of the inverse sine function maps values in the
1797 * range [-1, 1] to values in the range [-Pi/2, Pi/2], so we should reject
1798 * any inputs outside that range and the result will always be finite.
1799 */
1800 if (arg1 < -1.0 || arg1 > 1.0)
1801 ereport(ERROR,
1803 errmsg("input is out of range")));
1804
1805 result = asin(arg1);
1806 if (unlikely(isinf(result)))
1808
1809 PG_RETURN_FLOAT8(result);
1810}
1811
1812
1813/*
1814 * datan - returns the arctan of arg1 (radians)
1815 */
1816Datum
1818{
1820 float8 result;
1821
1822 /* Per the POSIX spec, return NaN if the input is NaN */
1823 if (isnan(arg1))
1825
1826 /*
1827 * The principal branch of the inverse tangent function maps all inputs to
1828 * values in the range [-Pi/2, Pi/2], so the result should always be
1829 * finite, even if the input is infinite.
1830 */
1831 result = atan(arg1);
1832 if (unlikely(isinf(result)))
1834
1835 PG_RETURN_FLOAT8(result);
1836}
1837
1838
1839/*
1840 * atan2 - returns the arctan of arg1/arg2 (radians)
1841 */
1842Datum
1844{
1847 float8 result;
1848
1849 /* Per the POSIX spec, return NaN if either input is NaN */
1850 if (isnan(arg1) || isnan(arg2))
1852
1853 /*
1854 * atan2 maps all inputs to values in the range [-Pi, Pi], so the result
1855 * should always be finite, even if the inputs are infinite.
1856 */
1857 result = atan2(arg1, arg2);
1858 if (unlikely(isinf(result)))
1860
1861 PG_RETURN_FLOAT8(result);
1862}
1863
1864
1865/*
1866 * dcos - returns the cosine of arg1 (radians)
1867 */
1868Datum
1870{
1872 float8 result;
1873
1874 /* Per the POSIX spec, return NaN if the input is NaN */
1875 if (isnan(arg1))
1877
1878 /*
1879 * cos() is periodic and so theoretically can work for all finite inputs,
1880 * but some implementations may choose to throw error if the input is so
1881 * large that there are no significant digits in the result. So we should
1882 * check for errors. POSIX allows an error to be reported either via
1883 * errno or via fetestexcept(), but currently we only support checking
1884 * errno. (fetestexcept() is rumored to report underflow unreasonably
1885 * early on some platforms, so it's not clear that believing it would be a
1886 * net improvement anyway.)
1887 *
1888 * For infinite inputs, POSIX specifies that the trigonometric functions
1889 * should return a domain error; but we won't notice that unless the
1890 * platform reports via errno, so also explicitly test for infinite
1891 * inputs.
1892 */
1893 errno = 0;
1894 result = cos(arg1);
1895 if (errno != 0 || isinf(arg1))
1896 ereport(ERROR,
1898 errmsg("input is out of range")));
1899 if (unlikely(isinf(result)))
1901
1902 PG_RETURN_FLOAT8(result);
1903}
1904
1905
1906/*
1907 * dcot - returns the cotangent 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 /* Be sure to throw an error if the input is infinite --- see dcos() */
1920 errno = 0;
1921 result = tan(arg1);
1922 if (errno != 0 || isinf(arg1))
1923 ereport(ERROR,
1925 errmsg("input is out of range")));
1926
1927 result = 1.0 / result;
1928 /* Not checking for overflow because cot(0) == Inf */
1929
1930 PG_RETURN_FLOAT8(result);
1931}
1932
1933
1934/*
1935 * dsin - returns the sine of arg1 (radians)
1936 */
1937Datum
1939{
1941 float8 result;
1942
1943 /* Per the POSIX spec, return NaN if the input is NaN */
1944 if (isnan(arg1))
1946
1947 /* Be sure to throw an error if the input is infinite --- see dcos() */
1948 errno = 0;
1949 result = sin(arg1);
1950 if (errno != 0 || isinf(arg1))
1951 ereport(ERROR,
1953 errmsg("input is out of range")));
1954 if (unlikely(isinf(result)))
1956
1957 PG_RETURN_FLOAT8(result);
1958}
1959
1960
1961/*
1962 * dtan - returns the tangent of arg1 (radians)
1963 */
1964Datum
1966{
1968 float8 result;
1969
1970 /* Per the POSIX spec, return NaN if the input is NaN */
1971 if (isnan(arg1))
1973
1974 /* Be sure to throw an error if the input is infinite --- see dcos() */
1975 errno = 0;
1976 result = tan(arg1);
1977 if (errno != 0 || isinf(arg1))
1978 ereport(ERROR,
1980 errmsg("input is out of range")));
1981 /* Not checking for overflow because tan(pi/2) == Inf */
1982
1983 PG_RETURN_FLOAT8(result);
1984}
1985
1986
1987/* ========== DEGREE-BASED TRIGONOMETRIC FUNCTIONS ========== */
1988
1989
1990/*
1991 * Initialize the cached constants declared at the head of this file
1992 * (sin_30 etc). The fact that we need those at all, let alone need this
1993 * Rube-Goldberg-worthy method of initializing them, is because there are
1994 * compilers out there that will precompute expressions such as sin(constant)
1995 * using a sin() function different from what will be used at runtime. If we
1996 * want exact results, we must ensure that none of the scaling constants used
1997 * in the degree-based trig functions are computed that way. To do so, we
1998 * compute them from the variables degree_c_thirty etc, which are also really
1999 * constants, but the compiler cannot assume that.
2000 *
2001 * Other hazards we are trying to forestall with this kluge include the
2002 * possibility that compilers will rearrange the expressions, or compute
2003 * some intermediate results in registers wider than a standard double.
2004 *
2005 * In the places where we use these constants, the typical pattern is like
2006 * volatile float8 sin_x = sin(x * RADIANS_PER_DEGREE);
2007 * return (sin_x / sin_30);
2008 * where we hope to get a value of exactly 1.0 from the division when x = 30.
2009 * The volatile temporary variable is needed on machines with wide float
2010 * registers, to ensure that the result of sin(x) is rounded to double width
2011 * the same as the value of sin_30 has been. Experimentation with gcc shows
2012 * that marking the temp variable volatile is necessary to make the store and
2013 * reload actually happen; hopefully the same trick works for other compilers.
2014 * (gcc's documentation suggests using the -ffloat-store compiler switch to
2015 * ensure this, but that is compiler-specific and it also pessimizes code in
2016 * many places where we don't care about this.)
2017 */
2018static void
2030
2031#define INIT_DEGREE_CONSTANTS() \
2032do { \
2033 if (!degree_consts_set) \
2034 init_degree_constants(); \
2035} while(0)
2036
2037
2038/*
2039 * asind_q1 - returns the inverse sine of x in degrees, for x in
2040 * the range [0, 1]. The result is an angle in the
2041 * first quadrant --- [0, 90] degrees.
2042 *
2043 * For the 3 special case inputs (0, 0.5 and 1), this
2044 * function will return exact values (0, 30 and 90
2045 * degrees respectively).
2046 */
2047static double
2049{
2050 /*
2051 * Stitch together inverse sine and cosine functions for the ranges [0,
2052 * 0.5] and (0.5, 1]. Each expression below is guaranteed to return
2053 * exactly 30 for x=0.5, so the result is a continuous monotonic function
2054 * over the full range.
2055 */
2056 if (x <= 0.5)
2057 {
2058 volatile float8 asin_x = asin(x);
2059
2060 return (asin_x / asin_0_5) * 30.0;
2061 }
2062 else
2063 {
2064 volatile float8 acos_x = acos(x);
2065
2066 return 90.0 - (acos_x / acos_0_5) * 60.0;
2067 }
2068}
2069
2070
2071/*
2072 * acosd_q1 - returns the inverse cosine of x in degrees, for x in
2073 * the range [0, 1]. The result is an angle in the
2074 * first quadrant --- [0, 90] degrees.
2075 *
2076 * For the 3 special case inputs (0, 0.5 and 1), this
2077 * function will return exact values (0, 60 and 90
2078 * degrees respectively).
2079 */
2080static double
2082{
2083 /*
2084 * Stitch together inverse sine and cosine functions for the ranges [0,
2085 * 0.5] and (0.5, 1]. Each expression below is guaranteed to return
2086 * exactly 60 for x=0.5, so the result is a continuous monotonic function
2087 * over the full range.
2088 */
2089 if (x <= 0.5)
2090 {
2091 volatile float8 asin_x = asin(x);
2092
2093 return 90.0 - (asin_x / asin_0_5) * 30.0;
2094 }
2095 else
2096 {
2097 volatile float8 acos_x = acos(x);
2098
2099 return (acos_x / acos_0_5) * 60.0;
2100 }
2101}
2102
2103
2104/*
2105 * dacosd - returns the arccos of arg1 (degrees)
2106 */
2107Datum
2109{
2111 float8 result;
2112
2113 /* Per the POSIX spec, return NaN if the input is NaN */
2114 if (isnan(arg1))
2116
2118
2119 /*
2120 * The principal branch of the inverse cosine function maps values in the
2121 * range [-1, 1] to values in the range [0, 180], so we should reject any
2122 * inputs outside that range and the result will always be finite.
2123 */
2124 if (arg1 < -1.0 || arg1 > 1.0)
2125 ereport(ERROR,
2127 errmsg("input is out of range")));
2128
2129 if (arg1 >= 0.0)
2130 result = acosd_q1(arg1);
2131 else
2132 result = 90.0 + asind_q1(-arg1);
2133
2134 if (unlikely(isinf(result)))
2136
2137 PG_RETURN_FLOAT8(result);
2138}
2139
2140
2141/*
2142 * dasind - returns the arcsin of arg1 (degrees)
2143 */
2144Datum
2146{
2148 float8 result;
2149
2150 /* Per the POSIX spec, return NaN if the input is NaN */
2151 if (isnan(arg1))
2153
2155
2156 /*
2157 * The principal branch of the inverse sine function maps values in the
2158 * range [-1, 1] to values in the range [-90, 90], so we should reject any
2159 * inputs outside that range and the result will always be finite.
2160 */
2161 if (arg1 < -1.0 || arg1 > 1.0)
2162 ereport(ERROR,
2164 errmsg("input is out of range")));
2165
2166 if (arg1 >= 0.0)
2167 result = asind_q1(arg1);
2168 else
2169 result = -asind_q1(-arg1);
2170
2171 if (unlikely(isinf(result)))
2173
2174 PG_RETURN_FLOAT8(result);
2175}
2176
2177
2178/*
2179 * datand - returns the arctan of arg1 (degrees)
2180 */
2181Datum
2183{
2185 float8 result;
2186 volatile float8 atan_arg1;
2187
2188 /* Per the POSIX spec, return NaN if the input is NaN */
2189 if (isnan(arg1))
2191
2193
2194 /*
2195 * The principal branch of the inverse tangent function maps all inputs to
2196 * values in the range [-90, 90], so the result should always be finite,
2197 * even if the input is infinite. Additionally, we take care to ensure
2198 * than when arg1 is 1, the result is exactly 45.
2199 */
2200 atan_arg1 = atan(arg1);
2201 result = (atan_arg1 / atan_1_0) * 45.0;
2202
2203 if (unlikely(isinf(result)))
2205
2206 PG_RETURN_FLOAT8(result);
2207}
2208
2209
2210/*
2211 * atan2d - returns the arctan of arg1/arg2 (degrees)
2212 */
2213Datum
2215{
2218 float8 result;
2219 volatile float8 atan2_arg1_arg2;
2220
2221 /* Per the POSIX spec, return NaN if either input is NaN */
2222 if (isnan(arg1) || isnan(arg2))
2224
2226
2227 /*
2228 * atan2d maps all inputs to values in the range [-180, 180], so the
2229 * result should always be finite, even if the inputs are infinite.
2230 *
2231 * Note: this coding assumes that atan(1.0) is a suitable scaling constant
2232 * to get an exact result from atan2(). This might well fail on us at
2233 * some point, requiring us to decide exactly what inputs we think we're
2234 * going to guarantee an exact result for.
2235 */
2237 result = (atan2_arg1_arg2 / atan_1_0) * 45.0;
2238
2239 if (unlikely(isinf(result)))
2241
2242 PG_RETURN_FLOAT8(result);
2243}
2244
2245
2246/*
2247 * sind_0_to_30 - returns the sine of an angle that lies between 0 and
2248 * 30 degrees. This will return exactly 0 when x is 0,
2249 * and exactly 0.5 when x is 30 degrees.
2250 */
2251static double
2253{
2254 volatile float8 sin_x = sin(x * RADIANS_PER_DEGREE);
2255
2256 return (sin_x / sin_30) / 2.0;
2257}
2258
2259
2260/*
2261 * cosd_0_to_60 - returns the cosine of an angle that lies between 0
2262 * and 60 degrees. This will return exactly 1 when x
2263 * is 0, and exactly 0.5 when x is 60 degrees.
2264 */
2265static double
2267{
2268 volatile float8 one_minus_cos_x = 1.0 - cos(x * RADIANS_PER_DEGREE);
2269
2270 return 1.0 - (one_minus_cos_x / one_minus_cos_60) / 2.0;
2271}
2272
2273
2274/*
2275 * sind_q1 - returns the sine of an angle in the first quadrant
2276 * (0 to 90 degrees).
2277 */
2278static double
2279sind_q1(double x)
2280{
2281 /*
2282 * Stitch together the sine and cosine functions for the ranges [0, 30]
2283 * and (30, 90]. These guarantee to return exact answers at their
2284 * endpoints, so the overall result is a continuous monotonic function
2285 * that gives exact results when x = 0, 30 and 90 degrees.
2286 */
2287 if (x <= 30.0)
2288 return sind_0_to_30(x);
2289 else
2290 return cosd_0_to_60(90.0 - x);
2291}
2292
2293
2294/*
2295 * cosd_q1 - returns the cosine of an angle in the first quadrant
2296 * (0 to 90 degrees).
2297 */
2298static double
2299cosd_q1(double x)
2300{
2301 /*
2302 * Stitch together the sine and cosine functions for the ranges [0, 60]
2303 * and (60, 90]. These guarantee to return exact answers at their
2304 * endpoints, so the overall result is a continuous monotonic function
2305 * that gives exact results when x = 0, 60 and 90 degrees.
2306 */
2307 if (x <= 60.0)
2308 return cosd_0_to_60(x);
2309 else
2310 return sind_0_to_30(90.0 - x);
2311}
2312
2313
2314/*
2315 * dcosd - returns the cosine of arg1 (degrees)
2316 */
2317Datum
2319{
2321 float8 result;
2322 int sign = 1;
2323
2324 /*
2325 * Per the POSIX spec, return NaN if the input is NaN and throw an error
2326 * if the input is infinite.
2327 */
2328 if (isnan(arg1))
2330
2331 if (isinf(arg1))
2332 ereport(ERROR,
2334 errmsg("input is out of range")));
2335
2337
2338 /* Reduce the range of the input to [0,90] degrees */
2339 arg1 = fmod(arg1, 360.0);
2340
2341 if (arg1 < 0.0)
2342 {
2343 /* cosd(-x) = cosd(x) */
2344 arg1 = -arg1;
2345 }
2346
2347 if (arg1 > 180.0)
2348 {
2349 /* cosd(360-x) = cosd(x) */
2350 arg1 = 360.0 - arg1;
2351 }
2352
2353 if (arg1 > 90.0)
2354 {
2355 /* cosd(180-x) = -cosd(x) */
2356 arg1 = 180.0 - arg1;
2357 sign = -sign;
2358 }
2359
2360 result = sign * cosd_q1(arg1);
2361
2362 if (unlikely(isinf(result)))
2364
2365 PG_RETURN_FLOAT8(result);
2366}
2367
2368
2369/*
2370 * dcotd - returns the cotangent of arg1 (degrees)
2371 */
2372Datum
2374{
2376 float8 result;
2377 volatile float8 cot_arg1;
2378 int sign = 1;
2379
2380 /*
2381 * Per the POSIX spec, return NaN if the input is NaN and throw an error
2382 * if the input is infinite.
2383 */
2384 if (isnan(arg1))
2386
2387 if (isinf(arg1))
2388 ereport(ERROR,
2390 errmsg("input is out of range")));
2391
2393
2394 /* Reduce the range of the input to [0,90] degrees */
2395 arg1 = fmod(arg1, 360.0);
2396
2397 if (arg1 < 0.0)
2398 {
2399 /* cotd(-x) = -cotd(x) */
2400 arg1 = -arg1;
2401 sign = -sign;
2402 }
2403
2404 if (arg1 > 180.0)
2405 {
2406 /* cotd(360-x) = -cotd(x) */
2407 arg1 = 360.0 - arg1;
2408 sign = -sign;
2409 }
2410
2411 if (arg1 > 90.0)
2412 {
2413 /* cotd(180-x) = -cotd(x) */
2414 arg1 = 180.0 - arg1;
2415 sign = -sign;
2416 }
2417
2419 result = sign * (cot_arg1 / cot_45);
2420
2421 /*
2422 * On some machines we get cotd(270) = minus zero, but this isn't always
2423 * true. For portability, and because the user constituency for this
2424 * function probably doesn't want minus zero, force it to plain zero.
2425 */
2426 if (result == 0.0)
2427 result = 0.0;
2428
2429 /* Not checking for overflow because cotd(0) == Inf */
2430
2431 PG_RETURN_FLOAT8(result);
2432}
2433
2434
2435/*
2436 * dsind - returns the sine of arg1 (degrees)
2437 */
2438Datum
2440{
2442 float8 result;
2443 int sign = 1;
2444
2445 /*
2446 * Per the POSIX spec, return NaN if the input is NaN and throw an error
2447 * if the input is infinite.
2448 */
2449 if (isnan(arg1))
2451
2452 if (isinf(arg1))
2453 ereport(ERROR,
2455 errmsg("input is out of range")));
2456
2458
2459 /* Reduce the range of the input to [0,90] degrees */
2460 arg1 = fmod(arg1, 360.0);
2461
2462 if (arg1 < 0.0)
2463 {
2464 /* sind(-x) = -sind(x) */
2465 arg1 = -arg1;
2466 sign = -sign;
2467 }
2468
2469 if (arg1 > 180.0)
2470 {
2471 /* sind(360-x) = -sind(x) */
2472 arg1 = 360.0 - arg1;
2473 sign = -sign;
2474 }
2475
2476 if (arg1 > 90.0)
2477 {
2478 /* sind(180-x) = sind(x) */
2479 arg1 = 180.0 - arg1;
2480 }
2481
2482 result = sign * sind_q1(arg1);
2483
2484 if (unlikely(isinf(result)))
2486
2487 PG_RETURN_FLOAT8(result);
2488}
2489
2490
2491/*
2492 * dtand - returns the tangent of arg1 (degrees)
2493 */
2494Datum
2496{
2498 float8 result;
2499 volatile float8 tan_arg1;
2500 int sign = 1;
2501
2502 /*
2503 * Per the POSIX spec, return NaN if the input is NaN and throw an error
2504 * if the input is infinite.
2505 */
2506 if (isnan(arg1))
2508
2509 if (isinf(arg1))
2510 ereport(ERROR,
2512 errmsg("input is out of range")));
2513
2515
2516 /* Reduce the range of the input to [0,90] degrees */
2517 arg1 = fmod(arg1, 360.0);
2518
2519 if (arg1 < 0.0)
2520 {
2521 /* tand(-x) = -tand(x) */
2522 arg1 = -arg1;
2523 sign = -sign;
2524 }
2525
2526 if (arg1 > 180.0)
2527 {
2528 /* tand(360-x) = -tand(x) */
2529 arg1 = 360.0 - arg1;
2530 sign = -sign;
2531 }
2532
2533 if (arg1 > 90.0)
2534 {
2535 /* tand(180-x) = -tand(x) */
2536 arg1 = 180.0 - arg1;
2537 sign = -sign;
2538 }
2539
2541 result = sign * (tan_arg1 / tan_45);
2542
2543 /*
2544 * On some machines we get tand(180) = minus zero, but this isn't always
2545 * true. For portability, and because the user constituency for this
2546 * function probably doesn't want minus zero, force it to plain zero.
2547 */
2548 if (result == 0.0)
2549 result = 0.0;
2550
2551 /* Not checking for overflow because tand(90) == Inf */
2552
2553 PG_RETURN_FLOAT8(result);
2554}
2555
2556
2557/*
2558 * degrees - returns degrees converted from radians
2559 */
2560Datum
2567
2568
2569/*
2570 * dpi - returns the constant PI
2571 */
2572Datum
2577
2578
2579/*
2580 * radians - returns radians converted from degrees
2581 */
2582Datum
2589
2590
2591/* ========== HYPERBOLIC FUNCTIONS ========== */
2592
2593
2594/*
2595 * dsinh - returns the hyperbolic sine of arg1
2596 */
2597Datum
2599{
2601 float8 result;
2602
2603 errno = 0;
2604 result = sinh(arg1);
2605
2606 /*
2607 * if an ERANGE error occurs, it means there is an overflow. For sinh,
2608 * the result should be either -infinity or infinity, depending on the
2609 * sign of arg1.
2610 */
2611 if (errno == ERANGE)
2612 {
2613 if (arg1 < 0)
2614 result = -get_float8_infinity();
2615 else
2616 result = get_float8_infinity();
2617 }
2618
2619 PG_RETURN_FLOAT8(result);
2620}
2621
2622
2623/*
2624 * dcosh - returns the hyperbolic cosine of arg1
2625 */
2626Datum
2628{
2630 float8 result;
2631
2632 errno = 0;
2633 result = cosh(arg1);
2634
2635 /*
2636 * if an ERANGE error occurs, it means there is an overflow. As cosh is
2637 * always positive, it always means the result is positive infinity.
2638 */
2639 if (errno == ERANGE)
2640 result = get_float8_infinity();
2641
2642 if (unlikely(result == 0.0))
2644
2645 PG_RETURN_FLOAT8(result);
2646}
2647
2648/*
2649 * dtanh - returns the hyperbolic tangent of arg1
2650 */
2651Datum
2653{
2655 float8 result;
2656
2657 /*
2658 * For tanh, we don't need an errno check because it never overflows.
2659 */
2660 result = tanh(arg1);
2661
2662 if (unlikely(isinf(result)))
2664
2665 PG_RETURN_FLOAT8(result);
2666}
2667
2668/*
2669 * dasinh - returns the inverse hyperbolic sine of arg1
2670 */
2671Datum
2673{
2675 float8 result;
2676
2677 /*
2678 * For asinh, we don't need an errno check because it never overflows.
2679 */
2680 result = asinh(arg1);
2681
2682 PG_RETURN_FLOAT8(result);
2683}
2684
2685/*
2686 * dacosh - returns the inverse hyperbolic cosine of arg1
2687 */
2688Datum
2690{
2692 float8 result;
2693
2694 /*
2695 * acosh is only defined for inputs >= 1.0. By checking this ourselves,
2696 * we need not worry about checking for an EDOM error, which is a good
2697 * thing because some implementations will report that for NaN. Otherwise,
2698 * no error is possible.
2699 */
2700 if (arg1 < 1.0)
2701 ereport(ERROR,
2703 errmsg("input is out of range")));
2704
2705 result = acosh(arg1);
2706
2707 PG_RETURN_FLOAT8(result);
2708}
2709
2710/*
2711 * datanh - returns the inverse hyperbolic tangent of arg1
2712 */
2713Datum
2715{
2717 float8 result;
2718
2719 /*
2720 * atanh is only defined for inputs between -1 and 1. By checking this
2721 * ourselves, we need not worry about checking for an EDOM error, which is
2722 * a good thing because some implementations will report that for NaN.
2723 */
2724 if (arg1 < -1.0 || arg1 > 1.0)
2725 ereport(ERROR,
2727 errmsg("input is out of range")));
2728
2729 /*
2730 * Also handle the infinity cases ourselves; this is helpful because old
2731 * glibc versions may produce the wrong errno for this. All other inputs
2732 * cannot produce an error.
2733 */
2734 if (arg1 == -1.0)
2735 result = -get_float8_infinity();
2736 else if (arg1 == 1.0)
2737 result = get_float8_infinity();
2738 else
2739 result = atanh(arg1);
2740
2741 PG_RETURN_FLOAT8(result);
2742}
2743
2744
2745/* ========== ERROR FUNCTIONS ========== */
2746
2747
2748/*
2749 * derf - returns the error function: erf(arg1)
2750 */
2751Datum
2753{
2755 float8 result;
2756
2757 /*
2758 * For erf, we don't need an errno check because it never overflows.
2759 */
2760 result = erf(arg1);
2761
2762 if (unlikely(isinf(result)))
2764
2765 PG_RETURN_FLOAT8(result);
2766}
2767
2768/*
2769 * derfc - returns the complementary error function: 1 - erf(arg1)
2770 */
2771Datum
2773{
2775 float8 result;
2776
2777 /*
2778 * For erfc, we don't need an errno check because it never overflows.
2779 */
2780 result = erfc(arg1);
2781
2782 if (unlikely(isinf(result)))
2784
2785 PG_RETURN_FLOAT8(result);
2786}
2787
2788
2789/* ========== GAMMA FUNCTIONS ========== */
2790
2791
2792/*
2793 * dgamma - returns the gamma function of arg1
2794 */
2795Datum
2797{
2799 float8 result;
2800
2801 /*
2802 * Handle NaN and Inf cases explicitly. This simplifies the overflow
2803 * checks on platforms that do not set errno.
2804 */
2805 if (isnan(arg1))
2806 result = arg1;
2807 else if (isinf(arg1))
2808 {
2809 /* Per POSIX, an input of -Inf causes a domain error */
2810 if (arg1 < 0)
2811 {
2813 result = get_float8_nan(); /* keep compiler quiet */
2814 }
2815 else
2816 result = arg1;
2817 }
2818 else
2819 {
2820 /*
2821 * Note: the POSIX/C99 gamma function is called "tgamma", not "gamma".
2822 *
2823 * On some platforms, tgamma() will not set errno but just return Inf,
2824 * NaN, or zero to report overflow/underflow; therefore, test those
2825 * cases explicitly (note that, like the exponential function, the
2826 * gamma function has no zeros).
2827 */
2828 errno = 0;
2829 result = tgamma(arg1);
2830
2831 if (errno != 0 || isinf(result) || isnan(result))
2832 {
2833 if (result != 0.0)
2835 else
2837 }
2838 else if (result == 0.0)
2840 }
2841
2842 PG_RETURN_FLOAT8(result);
2843}
2844
2845
2846/*
2847 * dlgamma - natural logarithm of absolute value of gamma of arg1
2848 */
2849Datum
2851{
2853 float8 result;
2854
2855 /* On some versions of AIX, lgamma(NaN) fails with ERANGE */
2856#if defined(_AIX)
2857 if (isnan(arg1))
2859#endif
2860
2861 /*
2862 * Note: lgamma may not be thread-safe because it may write to a global
2863 * variable signgam, which may not be thread-local. However, this doesn't
2864 * matter to us, since we don't use signgam.
2865 */
2866 errno = 0;
2867 result = lgamma(arg1);
2868
2869 /*
2870 * If an ERANGE error occurs, it means there was an overflow or a pole
2871 * error (which happens for zero and negative integer inputs).
2872 *
2873 * On some platforms, lgamma() will not set errno but just return infinity
2874 * to report overflow, but it should never underflow.
2875 */
2876 if (errno == ERANGE || (isinf(result) && !isinf(arg1)))
2878
2879 PG_RETURN_FLOAT8(result);
2880}
2881
2882
2883
2884/*
2885 * =========================
2886 * FLOAT AGGREGATE OPERATORS
2887 * =========================
2888 *
2889 * float8_accum - accumulate for AVG(), variance aggregates, etc.
2890 * float4_accum - same, but input data is float4
2891 * float8_avg - produce final result for float AVG()
2892 * float8_var_samp - produce final result for float VAR_SAMP()
2893 * float8_var_pop - produce final result for float VAR_POP()
2894 * float8_stddev_samp - produce final result for float STDDEV_SAMP()
2895 * float8_stddev_pop - produce final result for float STDDEV_POP()
2896 *
2897 * The naive schoolbook implementation of these aggregates works by
2898 * accumulating sum(X) and sum(X^2). However, this approach suffers from
2899 * large rounding errors in the final computation of quantities like the
2900 * population variance (N*sum(X^2) - sum(X)^2) / N^2, since each of the
2901 * intermediate terms is potentially very large, while the difference is often
2902 * quite small.
2903 *
2904 * Instead we use the Youngs-Cramer algorithm [1] which works by accumulating
2905 * Sx=sum(X) and Sxx=sum((X-Sx/N)^2), using a numerically stable algorithm to
2906 * incrementally update those quantities. The final computations of each of
2907 * the aggregate values is then trivial and gives more accurate results (for
2908 * example, the population variance is just Sxx/N). This algorithm is also
2909 * fairly easy to generalize to allow parallel execution without loss of
2910 * precision (see, for example, [2]). For more details, and a comparison of
2911 * this with other algorithms, see [3].
2912 *
2913 * The transition datatype for all these aggregates is a 3-element array
2914 * of float8, holding the values N, Sx, Sxx in that order.
2915 *
2916 * Note that we represent N as a float to avoid having to build a special
2917 * datatype. Given a reasonable floating-point implementation, there should
2918 * be no accuracy loss unless N exceeds 2 ^ 52 or so (by which time the
2919 * user will have doubtless lost interest anyway...)
2920 *
2921 * [1] Some Results Relevant to Choice of Sum and Sum-of-Product Algorithms,
2922 * E. A. Youngs and E. M. Cramer, Technometrics Vol 13, No 3, August 1971.
2923 *
2924 * [2] Updating Formulae and a Pairwise Algorithm for Computing Sample
2925 * Variances, T. F. Chan, G. H. Golub & R. J. LeVeque, COMPSTAT 1982.
2926 *
2927 * [3] Numerically Stable Parallel Computation of (Co-)Variance, Erich
2928 * Schubert and Michael Gertz, Proceedings of the 30th International
2929 * Conference on Scientific and Statistical Database Management, 2018.
2930 */
2931
2932static float8 *
2934{
2935 /*
2936 * We expect the input to be an N-element float array; verify that. We
2937 * don't need to use deconstruct_array() since the array data is just
2938 * going to look like a C array of N float8 values.
2939 */
2940 if (ARR_NDIM(transarray) != 1 ||
2941 ARR_DIMS(transarray)[0] != n ||
2944 elog(ERROR, "%s: expected %d-element float8 array", caller, n);
2945 return (float8 *) ARR_DATA_PTR(transarray);
2946}
2947
2948/*
2949 * float8_combine
2950 *
2951 * An aggregate combine function used to combine two 3 fields
2952 * aggregate transition data into a single transition data.
2953 * This function is used only in two stage aggregation and
2954 * shouldn't be called outside aggregate context.
2955 */
2956Datum
2958{
2963 float8 N1,
2964 Sx1,
2965 Sxx1,
2966 N2,
2967 Sx2,
2968 Sxx2,
2969 tmp,
2970 N,
2971 Sx,
2972 Sxx;
2973
2974 transvalues1 = check_float8_array(transarray1, "float8_combine", 3);
2975 transvalues2 = check_float8_array(transarray2, "float8_combine", 3);
2976
2977 N1 = transvalues1[0];
2978 Sx1 = transvalues1[1];
2979 Sxx1 = transvalues1[2];
2980
2981 N2 = transvalues2[0];
2982 Sx2 = transvalues2[1];
2983 Sxx2 = transvalues2[2];
2984
2985 /*--------------------
2986 * The transition values combine using a generalization of the
2987 * Youngs-Cramer algorithm as follows:
2988 *
2989 * N = N1 + N2
2990 * Sx = Sx1 + Sx2
2991 * Sxx = Sxx1 + Sxx2 + N1 * N2 * (Sx1/N1 - Sx2/N2)^2 / N;
2992 *
2993 * It's worth handling the special cases N1 = 0 and N2 = 0 separately
2994 * since those cases are trivial, and we then don't need to worry about
2995 * division-by-zero errors in the general case.
2996 *--------------------
2997 */
2998 if (N1 == 0.0)
2999 {
3000 N = N2;
3001 Sx = Sx2;
3002 Sxx = Sxx2;
3003 }
3004 else if (N2 == 0.0)
3005 {
3006 N = N1;
3007 Sx = Sx1;
3008 Sxx = Sxx1;
3009 }
3010 else
3011 {
3012 N = N1 + N2;
3013 Sx = float8_pl(Sx1, Sx2);
3014 tmp = Sx1 / N1 - Sx2 / N2;
3015 Sxx = Sxx1 + Sxx2 + N1 * N2 * tmp * tmp / N;
3016 if (unlikely(isinf(Sxx)) && !isinf(Sxx1) && !isinf(Sxx2))
3018 }
3019
3020 /*
3021 * If we're invoked as an aggregate, we can cheat and modify our first
3022 * parameter in-place to reduce palloc overhead. Otherwise we construct a
3023 * new array with the updated transition data and return it.
3024 */
3025 if (AggCheckCallContext(fcinfo, NULL))
3026 {
3027 transvalues1[0] = N;
3028 transvalues1[1] = Sx;
3029 transvalues1[2] = Sxx;
3030
3032 }
3033 else
3034 {
3035 Datum transdatums[3];
3036 ArrayType *result;
3037
3041
3043
3044 PG_RETURN_ARRAYTYPE_P(result);
3045 }
3046}
3047
3048Datum
3050{
3054 float8 N,
3055 Sx,
3056 Sxx,
3057 tmp;
3058
3059 transvalues = check_float8_array(transarray, "float8_accum", 3);
3060 N = transvalues[0];
3061 Sx = transvalues[1];
3062 Sxx = transvalues[2];
3063
3064 /*
3065 * Use the Youngs-Cramer algorithm to incorporate the new value into the
3066 * transition values.
3067 */
3068 N += 1.0;
3069 Sx += newval;
3070 if (transvalues[0] > 0.0)
3071 {
3072 tmp = newval * N - Sx;
3073 Sxx += tmp * tmp / (N * transvalues[0]);
3074
3075 /*
3076 * Overflow check. We only report an overflow error when finite
3077 * inputs lead to infinite results. Note also that Sxx should be NaN
3078 * if any of the inputs are infinite, so we intentionally prevent Sxx
3079 * from becoming infinite.
3080 */
3081 if (isinf(Sx) || isinf(Sxx))
3082 {
3083 if (!isinf(transvalues[1]) && !isinf(newval))
3085
3086 Sxx = get_float8_nan();
3087 }
3088 }
3089 else
3090 {
3091 /*
3092 * At the first input, we normally can leave Sxx as 0. However, if
3093 * the first input is Inf or NaN, we'd better force Sxx to NaN;
3094 * otherwise we will falsely report variance zero when there are no
3095 * more inputs.
3096 */
3097 if (isnan(newval) || isinf(newval))
3098 Sxx = get_float8_nan();
3099 }
3100
3101 /*
3102 * If we're invoked as an aggregate, we can cheat and modify our first
3103 * parameter in-place to reduce palloc overhead. Otherwise we construct a
3104 * new array with the updated transition data and return it.
3105 */
3106 if (AggCheckCallContext(fcinfo, NULL))
3107 {
3108 transvalues[0] = N;
3109 transvalues[1] = Sx;
3110 transvalues[2] = Sxx;
3111
3113 }
3114 else
3115 {
3116 Datum transdatums[3];
3117 ArrayType *result;
3118
3122
3124
3125 PG_RETURN_ARRAYTYPE_P(result);
3126 }
3127}
3128
3129Datum
3131{
3133
3134 /* do computations as float8 */
3137 float8 N,
3138 Sx,
3139 Sxx,
3140 tmp;
3141
3142 transvalues = check_float8_array(transarray, "float4_accum", 3);
3143 N = transvalues[0];
3144 Sx = transvalues[1];
3145 Sxx = transvalues[2];
3146
3147 /*
3148 * Use the Youngs-Cramer algorithm to incorporate the new value into the
3149 * transition values.
3150 */
3151 N += 1.0;
3152 Sx += newval;
3153 if (transvalues[0] > 0.0)
3154 {
3155 tmp = newval * N - Sx;
3156 Sxx += tmp * tmp / (N * transvalues[0]);
3157
3158 /*
3159 * Overflow check. We only report an overflow error when finite
3160 * inputs lead to infinite results. Note also that Sxx should be NaN
3161 * if any of the inputs are infinite, so we intentionally prevent Sxx
3162 * from becoming infinite.
3163 */
3164 if (isinf(Sx) || isinf(Sxx))
3165 {
3166 if (!isinf(transvalues[1]) && !isinf(newval))
3168
3169 Sxx = get_float8_nan();
3170 }
3171 }
3172 else
3173 {
3174 /*
3175 * At the first input, we normally can leave Sxx as 0. However, if
3176 * the first input is Inf or NaN, we'd better force Sxx to NaN;
3177 * otherwise we will falsely report variance zero when there are no
3178 * more inputs.
3179 */
3180 if (isnan(newval) || isinf(newval))
3181 Sxx = get_float8_nan();
3182 }
3183
3184 /*
3185 * If we're invoked as an aggregate, we can cheat and modify our first
3186 * parameter in-place to reduce palloc overhead. Otherwise we construct a
3187 * new array with the updated transition data and return it.
3188 */
3189 if (AggCheckCallContext(fcinfo, NULL))
3190 {
3191 transvalues[0] = N;
3192 transvalues[1] = Sx;
3193 transvalues[2] = Sxx;
3194
3196 }
3197 else
3198 {
3199 Datum transdatums[3];
3200 ArrayType *result;
3201
3205
3207
3208 PG_RETURN_ARRAYTYPE_P(result);
3209 }
3210}
3211
3212Datum
3214{
3217 float8 N,
3218 Sx;
3219
3220 transvalues = check_float8_array(transarray, "float8_avg", 3);
3221 N = transvalues[0];
3222 Sx = transvalues[1];
3223 /* ignore Sxx */
3224
3225 /* SQL defines AVG of no values to be NULL */
3226 if (N == 0.0)
3228
3229 PG_RETURN_FLOAT8(Sx / N);
3230}
3231
3232Datum
3234{
3237 float8 N,
3238 Sxx;
3239
3240 transvalues = check_float8_array(transarray, "float8_var_pop", 3);
3241 N = transvalues[0];
3242 /* ignore Sx */
3243 Sxx = transvalues[2];
3244
3245 /* Population variance is undefined when N is 0, so return NULL */
3246 if (N == 0.0)
3248
3249 /* Note that Sxx is guaranteed to be non-negative */
3250
3251 PG_RETURN_FLOAT8(Sxx / N);
3252}
3253
3254Datum
3256{
3259 float8 N,
3260 Sxx;
3261
3262 transvalues = check_float8_array(transarray, "float8_var_samp", 3);
3263 N = transvalues[0];
3264 /* ignore Sx */
3265 Sxx = transvalues[2];
3266
3267 /* Sample variance is undefined when N is 0 or 1, so return NULL */
3268 if (N <= 1.0)
3270
3271 /* Note that Sxx is guaranteed to be non-negative */
3272
3273 PG_RETURN_FLOAT8(Sxx / (N - 1.0));
3274}
3275
3276Datum
3278{
3281 float8 N,
3282 Sxx;
3283
3284 transvalues = check_float8_array(transarray, "float8_stddev_pop", 3);
3285 N = transvalues[0];
3286 /* ignore Sx */
3287 Sxx = transvalues[2];
3288
3289 /* Population stddev is undefined when N is 0, so return NULL */
3290 if (N == 0.0)
3292
3293 /* Note that Sxx is guaranteed to be non-negative */
3294
3296}
3297
3298Datum
3300{
3303 float8 N,
3304 Sxx;
3305
3306 transvalues = check_float8_array(transarray, "float8_stddev_samp", 3);
3307 N = transvalues[0];
3308 /* ignore Sx */
3309 Sxx = transvalues[2];
3310
3311 /* Sample stddev is undefined when N is 0 or 1, so return NULL */
3312 if (N <= 1.0)
3314
3315 /* Note that Sxx is guaranteed to be non-negative */
3316
3317 PG_RETURN_FLOAT8(sqrt(Sxx / (N - 1.0)));
3318}
3319
3320/*
3321 * =========================
3322 * SQL2003 BINARY AGGREGATES
3323 * =========================
3324 *
3325 * As with the preceding aggregates, we use the Youngs-Cramer algorithm to
3326 * reduce rounding errors in the aggregate final functions.
3327 *
3328 * The transition datatype for all these aggregates is an 8-element array of
3329 * float8, holding the values N, Sx=sum(X), Sxx=sum((X-Sx/N)^2), Sy=sum(Y),
3330 * Syy=sum((Y-Sy/N)^2), Sxy=sum((X-Sx/N)*(Y-Sy/N)), commonX, and commonY
3331 * in that order.
3332 *
3333 * commonX is defined as the common X value if all the X values were the same,
3334 * else NaN; likewise for commonY. This is useful for deciding whether corr()
3335 * and related functions should return NULL. This representation cannot
3336 * distinguish the-values-were-all-NaN from the-values-were-not-all-the-same,
3337 * but that's okay because for this purpose we use the IEEE float arithmetic
3338 * principle that two NaNs are never equal. The SQL standard doesn't mention
3339 * NaNs, but it says that NULL is to be returned when N*sum(X*X) equals
3340 * sum(X)*sum(X) (etc), and that shouldn't be considered true for NaNs.
3341 * Testing this as written in the spec would be highly subject to roundoff
3342 * error, so instead we directly track whether all the inputs are equal.
3343 *
3344 * Note that Y is the first argument to all these aggregates!
3345 *
3346 * It might seem attractive to optimize this by having multiple accumulator
3347 * functions that only calculate the sums actually needed. But on most
3348 * modern machines, a couple of extra floating-point multiplies will be
3349 * insignificant compared to the other per-tuple overhead, so I've chosen
3350 * to minimize code space instead.
3351 */
3352
3353Datum
3355{
3360 float8 N,
3361 Sx,
3362 Sxx,
3363 Sy,
3364 Syy,
3365 Sxy,
3366 commonX,
3367 commonY,
3368 tmpX,
3369 tmpY,
3370 scale;
3371
3372 transvalues = check_float8_array(transarray, "float8_regr_accum", 8);
3373 N = transvalues[0];
3374 Sx = transvalues[1];
3375 Sxx = transvalues[2];
3376 Sy = transvalues[3];
3377 Syy = transvalues[4];
3378 Sxy = transvalues[5];
3379 commonX = transvalues[6];
3380 commonY = transvalues[7];
3381
3382 /*
3383 * Use the Youngs-Cramer algorithm to incorporate the new values into the
3384 * transition values.
3385 */
3386 N += 1.0;
3387 Sx += newvalX;
3388 Sy += newvalY;
3389 if (transvalues[0] > 0.0)
3390 {
3391 /*
3392 * Check to see if we have seen distinct inputs. We can use a test
3393 * that's a bit cheaper than float8_ne() because if commonX is already
3394 * NaN, it does not matter whether the != test returns true or not.
3395 */
3396 if (newvalX != commonX || isnan(newvalX))
3398 if (newvalY != commonY || isnan(newvalY))
3400
3401 tmpX = newvalX * N - Sx;
3402 tmpY = newvalY * N - Sy;
3403 scale = 1.0 / (N * transvalues[0]);
3404
3405 /*
3406 * If we have not seen distinct inputs, then Sxx, Syy, and/or Sxy
3407 * should remain zero (since Sx's exact value would be N * commonX,
3408 * etc). Updating them would just create the possibility of injecting
3409 * roundoff error, and we need exact zero results so that the final
3410 * functions will return NULL in the right cases.
3411 */
3412 if (isnan(commonX))
3413 Sxx += tmpX * tmpX * scale;
3414 if (isnan(commonY))
3415 Syy += tmpY * tmpY * scale;
3416 if (isnan(commonX) && isnan(commonY))
3417 Sxy += tmpX * tmpY * scale;
3418
3419 /*
3420 * Overflow check. We only report an overflow error when finite
3421 * inputs lead to infinite results. Note also that Sxx, Syy and Sxy
3422 * should be NaN if any of the relevant inputs are infinite, so we
3423 * intentionally prevent them from becoming infinite.
3424 */
3425 if (isinf(Sx) || isinf(Sxx) || isinf(Sy) || isinf(Syy) || isinf(Sxy))
3426 {
3427 if (((isinf(Sx) || isinf(Sxx)) &&
3428 !isinf(transvalues[1]) && !isinf(newvalX)) ||
3429 ((isinf(Sy) || isinf(Syy)) &&
3430 !isinf(transvalues[3]) && !isinf(newvalY)) ||
3431 (isinf(Sxy) &&
3432 !isinf(transvalues[1]) && !isinf(newvalX) &&
3433 !isinf(transvalues[3]) && !isinf(newvalY)))
3435
3436 if (isinf(Sxx))
3437 Sxx = get_float8_nan();
3438 if (isinf(Syy))
3439 Syy = get_float8_nan();
3440 if (isinf(Sxy))
3441 Sxy = get_float8_nan();
3442 }
3443 }
3444 else
3445 {
3446 /*
3447 * At the first input, we normally can leave Sxx et al as 0. However,
3448 * if the first input is Inf or NaN, we'd better force the dependent
3449 * sums to NaN; otherwise we will falsely report variance zero when
3450 * there are no more inputs.
3451 */
3452 if (isnan(newvalX) || isinf(newvalX))
3453 Sxx = Sxy = get_float8_nan();
3454 if (isnan(newvalY) || isinf(newvalY))
3455 Syy = Sxy = get_float8_nan();
3456
3457 commonX = newvalX;
3458 commonY = newvalY;
3459 }
3460
3461 /*
3462 * If we're invoked as an aggregate, we can cheat and modify our first
3463 * parameter in-place to reduce palloc overhead. Otherwise we construct a
3464 * new array with the updated transition data and return it.
3465 */
3466 if (AggCheckCallContext(fcinfo, NULL))
3467 {
3468 transvalues[0] = N;
3469 transvalues[1] = Sx;
3470 transvalues[2] = Sxx;
3471 transvalues[3] = Sy;
3472 transvalues[4] = Syy;
3473 transvalues[5] = Sxy;
3474 transvalues[6] = commonX;
3475 transvalues[7] = commonY;
3476
3478 }
3479 else
3480 {
3481 Datum transdatums[8];
3482 ArrayType *result;
3483
3492
3494
3495 PG_RETURN_ARRAYTYPE_P(result);
3496 }
3497}
3498
3499/*
3500 * float8_regr_combine
3501 *
3502 * An aggregate combine function used to combine two 8-fields
3503 * aggregate transition data into a single transition data.
3504 * This function is used only in two stage aggregation and
3505 * shouldn't be called outside aggregate context.
3506 */
3507Datum
3509{
3514 float8 N1,
3515 Sx1,
3516 Sxx1,
3517 Sy1,
3518 Syy1,
3519 Sxy1,
3520 Cx1,
3521 Cy1,
3522 N2,
3523 Sx2,
3524 Sxx2,
3525 Sy2,
3526 Syy2,
3527 Sxy2,
3528 Cx2,
3529 Cy2,
3530 tmp1,
3531 tmp2,
3532 N,
3533 Sx,
3534 Sxx,
3535 Sy,
3536 Syy,
3537 Sxy,
3538 Cx,
3539 Cy;
3540
3541 transvalues1 = check_float8_array(transarray1, "float8_regr_combine", 8);
3542 transvalues2 = check_float8_array(transarray2, "float8_regr_combine", 8);
3543
3544 N1 = transvalues1[0];
3545 Sx1 = transvalues1[1];
3546 Sxx1 = transvalues1[2];
3547 Sy1 = transvalues1[3];
3548 Syy1 = transvalues1[4];
3549 Sxy1 = transvalues1[5];
3550 Cx1 = transvalues1[6];
3551 Cy1 = transvalues1[7];
3552
3553 N2 = transvalues2[0];
3554 Sx2 = transvalues2[1];
3555 Sxx2 = transvalues2[2];
3556 Sy2 = transvalues2[3];
3557 Syy2 = transvalues2[4];
3558 Sxy2 = transvalues2[5];
3559 Cx2 = transvalues2[6];
3560 Cy2 = transvalues2[7];
3561
3562 /*--------------------
3563 * The transition values combine using a generalization of the
3564 * Youngs-Cramer algorithm as follows:
3565 *
3566 * N = N1 + N2
3567 * Sx = Sx1 + Sx2
3568 * Sxx = Sxx1 + Sxx2 + N1 * N2 * (Sx1/N1 - Sx2/N2)^2 / N
3569 * Sy = Sy1 + Sy2
3570 * Syy = Syy1 + Syy2 + N1 * N2 * (Sy1/N1 - Sy2/N2)^2 / N
3571 * Sxy = Sxy1 + Sxy2 + N1 * N2 * (Sx1/N1 - Sx2/N2) * (Sy1/N1 - Sy2/N2) / N
3572 *
3573 * It's worth handling the special cases N1 = 0 and N2 = 0 separately
3574 * since those cases are trivial, and we then don't need to worry about
3575 * division-by-zero errors in the general case.
3576 *--------------------
3577 */
3578 if (N1 == 0.0)
3579 {
3580 N = N2;
3581 Sx = Sx2;
3582 Sxx = Sxx2;
3583 Sy = Sy2;
3584 Syy = Syy2;
3585 Sxy = Sxy2;
3586 Cx = Cx2;
3587 Cy = Cy2;
3588 }
3589 else if (N2 == 0.0)
3590 {
3591 N = N1;
3592 Sx = Sx1;
3593 Sxx = Sxx1;
3594 Sy = Sy1;
3595 Syy = Syy1;
3596 Sxy = Sxy1;
3597 Cx = Cx1;
3598 Cy = Cy1;
3599 }
3600 else
3601 {
3602 N = N1 + N2;
3603 Sx = float8_pl(Sx1, Sx2);
3604 tmp1 = Sx1 / N1 - Sx2 / N2;
3605 Sxx = Sxx1 + Sxx2 + N1 * N2 * tmp1 * tmp1 / N;
3606 if (unlikely(isinf(Sxx)) && !isinf(Sxx1) && !isinf(Sxx2))
3608 Sy = float8_pl(Sy1, Sy2);
3609 tmp2 = Sy1 / N1 - Sy2 / N2;
3610 Syy = Syy1 + Syy2 + N1 * N2 * tmp2 * tmp2 / N;
3611 if (unlikely(isinf(Syy)) && !isinf(Syy1) && !isinf(Syy2))
3613 Sxy = Sxy1 + Sxy2 + N1 * N2 * tmp1 * tmp2 / N;
3614 if (unlikely(isinf(Sxy)) && !isinf(Sxy1) && !isinf(Sxy2))
3616 if (float8_eq(Cx1, Cx2))
3617 Cx = Cx1;
3618 else
3619 Cx = get_float8_nan();
3620 if (float8_eq(Cy1, Cy2))
3621 Cy = Cy1;
3622 else
3623 Cy = get_float8_nan();
3624 }
3625
3626 /*
3627 * If we're invoked as an aggregate, we can cheat and modify our first
3628 * parameter in-place to reduce palloc overhead. Otherwise we construct a
3629 * new array with the updated transition data and return it.
3630 */
3631 if (AggCheckCallContext(fcinfo, NULL))
3632 {
3633 transvalues1[0] = N;
3634 transvalues1[1] = Sx;
3635 transvalues1[2] = Sxx;
3636 transvalues1[3] = Sy;
3637 transvalues1[4] = Syy;
3638 transvalues1[5] = Sxy;
3639 transvalues1[6] = Cx;
3640 transvalues1[7] = Cy;
3641
3643 }
3644 else
3645 {
3646 Datum transdatums[8];
3647 ArrayType *result;
3648
3657
3659
3660 PG_RETURN_ARRAYTYPE_P(result);
3661 }
3662}
3663
3664
3665Datum
3667{
3670 float8 N,
3671 Sxx;
3672
3673 transvalues = check_float8_array(transarray, "float8_regr_sxx", 8);
3674 N = transvalues[0];
3675 Sxx = transvalues[2];
3676
3677 /* if N is 0 we should return NULL */
3678 if (N < 1.0)
3680
3681 /* Note that Sxx is guaranteed to be non-negative */
3682
3684}
3685
3686Datum
3688{
3691 float8 N,
3692 Syy;
3693
3694 transvalues = check_float8_array(transarray, "float8_regr_syy", 8);
3695 N = transvalues[0];
3696 Syy = transvalues[4];
3697
3698 /* if N is 0 we should return NULL */
3699 if (N < 1.0)
3701
3702 /* Note that Syy is guaranteed to be non-negative */
3703
3705}
3706
3707Datum
3709{
3712 float8 N,
3713 Sxy;
3714
3715 transvalues = check_float8_array(transarray, "float8_regr_sxy", 8);
3716 N = transvalues[0];
3717 Sxy = transvalues[5];
3718
3719 /* if N is 0 we should return NULL */
3720 if (N < 1.0)
3722
3723 /* A negative result is valid here */
3724
3726}
3727
3728Datum
3730{
3733 float8 N,
3734 Sx,
3735 commonX;
3736
3737 transvalues = check_float8_array(transarray, "float8_regr_avgx", 8);
3738 N = transvalues[0];
3739 Sx = transvalues[1];
3740 commonX = transvalues[6];
3741
3742 /* if N is 0 we should return NULL */
3743 if (N < 1.0)
3745
3746 /* if all inputs were the same just return that, avoiding roundoff error */
3747 if (!isnan(commonX))
3749
3750 PG_RETURN_FLOAT8(Sx / N);
3751}
3752
3753Datum
3755{
3758 float8 N,
3759 Sy,
3760 commonY;
3761
3762 transvalues = check_float8_array(transarray, "float8_regr_avgy", 8);
3763 N = transvalues[0];
3764 Sy = transvalues[3];
3765 commonY = transvalues[7];
3766
3767 /* if N is 0 we should return NULL */
3768 if (N < 1.0)
3770
3771 /* if all inputs were the same just return that, avoiding roundoff error */
3772 if (!isnan(commonY))
3774
3775 PG_RETURN_FLOAT8(Sy / N);
3776}
3777
3778Datum
3780{
3783 float8 N,
3784 Sxy;
3785
3786 transvalues = check_float8_array(transarray, "float8_covar_pop", 8);
3787 N = transvalues[0];
3788 Sxy = transvalues[5];
3789
3790 /* if N is 0 we should return NULL */
3791 if (N < 1.0)
3793
3794 PG_RETURN_FLOAT8(Sxy / N);
3795}
3796
3797Datum
3799{
3802 float8 N,
3803 Sxy;
3804
3805 transvalues = check_float8_array(transarray, "float8_covar_samp", 8);
3806 N = transvalues[0];
3807 Sxy = transvalues[5];
3808
3809 /* if N is <= 1 we should return NULL */
3810 if (N < 2.0)
3812
3813 PG_RETURN_FLOAT8(Sxy / (N - 1.0));
3814}
3815
3816Datum
3818{
3821 float8 N,
3822 Sxx,
3823 Syy,
3824 Sxy,
3825 product,
3827 result;
3828
3829 transvalues = check_float8_array(transarray, "float8_corr", 8);
3830 N = transvalues[0];
3831 Sxx = transvalues[2];
3832 Syy = transvalues[4];
3833 Sxy = transvalues[5];
3834
3835 /* if N is 0 we should return NULL */
3836 if (N < 1.0)
3838
3839 /* Note that Sxx and Syy are guaranteed to be non-negative */
3840
3841 /* per spec, return NULL for horizontal and vertical lines */
3842 if (Sxx == 0 || Syy == 0)
3844
3845 /*
3846 * The product Sxx * Syy might underflow or overflow. If so, we can
3847 * recover by computing sqrt(Sxx) * sqrt(Syy) instead of sqrt(Sxx * Syy).
3848 * However, the double sqrt() calculation is a bit slower and less
3849 * accurate, so don't do it if we don't have to.
3850 */
3851 product = Sxx * Syy;
3852 if (product == 0 || isinf(product))
3853 sqrtproduct = sqrt(Sxx) * sqrt(Syy);
3854 else
3856 result = Sxy / sqrtproduct;
3857
3858 /*
3859 * Despite all these precautions, this formula can yield results outside
3860 * [-1, 1] due to roundoff error. Clamp it to the expected range.
3861 */
3862 if (result < -1)
3863 result = -1;
3864 else if (result > 1)
3865 result = 1;
3866
3867 PG_RETURN_FLOAT8(result);
3868}
3869
3870Datum
3872{
3875 float8 N,
3876 Sxx,
3877 Syy,
3878 Sxy;
3879
3880 transvalues = check_float8_array(transarray, "float8_regr_r2", 8);
3881 N = transvalues[0];
3882 Sxx = transvalues[2];
3883 Syy = transvalues[4];
3884 Sxy = transvalues[5];
3885
3886 /* if N is 0 we should return NULL */
3887 if (N < 1.0)
3889
3890 /* Note that Sxx and Syy are guaranteed to be non-negative */
3891
3892 /* per spec, return NULL for a vertical line */
3893 if (Sxx == 0)
3895
3896 /* per spec, return 1.0 for a horizontal line */
3897 if (Syy == 0)
3898 PG_RETURN_FLOAT8(1.0);
3899
3900 PG_RETURN_FLOAT8((Sxy * Sxy) / (Sxx * Syy));
3901}
3902
3903Datum
3905{
3908 float8 N,
3909 Sxx,
3910 Sxy;
3911
3912 transvalues = check_float8_array(transarray, "float8_regr_slope", 8);
3913 N = transvalues[0];
3914 Sxx = transvalues[2];
3915 Sxy = transvalues[5];
3916
3917 /* if N is 0 we should return NULL */
3918 if (N < 1.0)
3920
3921 /* Note that Sxx is guaranteed to be non-negative */
3922
3923 /* per spec, return NULL for a vertical line */
3924 if (Sxx == 0)
3926
3928}
3929
3930Datum
3932{
3935 float8 N,
3936 Sx,
3937 Sxx,
3938 Sy,
3939 Sxy;
3940
3941 transvalues = check_float8_array(transarray, "float8_regr_intercept", 8);
3942 N = transvalues[0];
3943 Sx = transvalues[1];
3944 Sxx = transvalues[2];
3945 Sy = transvalues[3];
3946 Sxy = transvalues[5];
3947
3948 /* if N is 0 we should return NULL */
3949 if (N < 1.0)
3951
3952 /* Note that Sxx is guaranteed to be non-negative */
3953
3954 /* per spec, return NULL for a vertical line */
3955 if (Sxx == 0)
3957
3958 PG_RETURN_FLOAT8((Sy - Sx * Sxy / Sxx) / N);
3959}
3960
3961
3962/*
3963 * ====================================
3964 * MIXED-PRECISION ARITHMETIC OPERATORS
3965 * ====================================
3966 */
3967
3968/*
3969 * float48pl - returns arg1 + arg2
3970 * float48mi - returns arg1 - arg2
3971 * float48mul - returns arg1 * arg2
3972 * float48div - returns arg1 / arg2
3973 */
3974Datum
3982
3983Datum
3991
3992Datum
4000
4001Datum
4009
4010/*
4011 * float84pl - returns arg1 + arg2
4012 * float84mi - returns arg1 - arg2
4013 * float84mul - returns arg1 * arg2
4014 * float84div - returns arg1 / arg2
4015 */
4016Datum
4024
4025Datum
4033
4034Datum
4042
4043Datum
4051
4052/*
4053 * ====================
4054 * COMPARISON OPERATORS
4055 * ====================
4056 */
4057
4058/*
4059 * float48{eq,ne,lt,le,gt,ge} - float4/float8 comparison operations
4060 */
4061Datum
4069
4070Datum
4078
4079Datum
4087
4088Datum
4096
4097Datum
4105
4106Datum
4114
4115/*
4116 * float84{eq,ne,lt,le,gt,ge} - float8/float4 comparison operations
4117 */
4118Datum
4126
4127Datum
4135
4136Datum
4144
4145Datum
4153
4154Datum
4162
4163Datum
4171
4172/*
4173 * Implements the float8 version of the width_bucket() function
4174 * defined by SQL2003. See also width_bucket_numeric().
4175 *
4176 * 'bound1' and 'bound2' are the lower and upper bounds of the
4177 * histogram's range, respectively. 'count' is the number of buckets
4178 * in the histogram. width_bucket() returns an integer indicating the
4179 * bucket number that 'operand' belongs to in an equiwidth histogram
4180 * with the specified characteristics. An operand smaller than the
4181 * lower bound is assigned to bucket 0. An operand greater than or equal
4182 * to the upper bound is assigned to an additional bucket (with number
4183 * count+1). We don't allow the histogram bounds to be NaN or +/- infinity,
4184 * but we do allow those values for the operand (taking NaN to be larger
4185 * than any other value, as we do in comparisons).
4186 */
4187Datum
4189{
4190 float8 operand = PG_GETARG_FLOAT8(0);
4193 int32 count = PG_GETARG_INT32(3);
4194 int32 result;
4195
4196 if (count <= 0)
4197 ereport(ERROR,
4199 errmsg("count must be greater than zero")));
4200
4201 if (isnan(bound1) || isnan(bound2))
4202 ereport(ERROR,
4204 errmsg("lower and upper bounds cannot be NaN")));
4205
4206 if (isinf(bound1) || isinf(bound2))
4207 ereport(ERROR,
4209 errmsg("lower and upper bounds must be finite")));
4210
4211 if (bound1 < bound2)
4212 {
4213 if (isnan(operand) || operand >= bound2)
4214 {
4215 if (pg_add_s32_overflow(count, 1, &result))
4216 ereport(ERROR,
4218 errmsg("integer out of range")));
4219 }
4220 else if (operand < bound1)
4221 result = 0;
4222 else
4223 {
4224 if (!isinf(bound2 - bound1))
4225 {
4226 /* The quotient is surely in [0,1], so this can't overflow */
4227 result = count * ((operand - bound1) / (bound2 - bound1));
4228 }
4229 else
4230 {
4231 /*
4232 * We get here if bound2 - bound1 overflows DBL_MAX. Since
4233 * both bounds are finite, their difference can't exceed twice
4234 * DBL_MAX; so we can perform the computation without overflow
4235 * by dividing all the inputs by 2. That should be exact too,
4236 * except in the case where a very small operand underflows to
4237 * zero, which would have negligible impact on the result
4238 * given such large bounds.
4239 */
4240 result = count * ((operand / 2 - bound1 / 2) / (bound2 / 2 - bound1 / 2));
4241 }
4242 /* The quotient could round to 1.0, which would be a lie */
4243 if (result >= count)
4244 result = count - 1;
4245 /* Having done that, we can add 1 without fear of overflow */
4246 result++;
4247 }
4248 }
4249 else if (bound1 > bound2)
4250 {
4251 if (isnan(operand) || operand > bound1)
4252 result = 0;
4253 else if (operand <= bound2)
4254 {
4255 if (pg_add_s32_overflow(count, 1, &result))
4256 ereport(ERROR,
4258 errmsg("integer out of range")));
4259 }
4260 else
4261 {
4262 if (!isinf(bound1 - bound2))
4263 result = count * ((bound1 - operand) / (bound1 - bound2));
4264 else
4265 result = count * ((bound1 / 2 - operand / 2) / (bound1 / 2 - bound2 / 2));
4266 if (result >= count)
4267 result = count - 1;
4268 result++;
4269 }
4270 }
4271 else
4272 {
4273 ereport(ERROR,
4275 errmsg("lower bound cannot equal upper bound")));
4276 result = 0; /* keep the compiler quiet */
4277 }
4278
4279 PG_RETURN_INT32(result);
4280}
#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:1099
#define FLOAT8_FITS_IN_INT32(num)
Definition c.h:1105
#define pg_noinline
Definition c.h:307
#define FLOAT4_FITS_IN_INT16(num)
Definition c.h:1097
double float8
Definition c.h:656
int16_t int16
Definition c.h:553
int32_t int32
Definition c.h:554
#define FLOAT8_FITS_IN_INT16(num)
Definition c.h:1103
#define unlikely(x)
Definition c.h:424
float float4
Definition c.h:655
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
int errmsg(const char *fmt,...)
Definition elog.c:1093
#define ereturn(context, dummy_value,...)
Definition elog.h:278
#define ERROR
Definition elog.h:39
#define elog(elevel,...)
Definition elog.h:226
#define ereport(elevel,...)
Definition elog.h:150
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:395
Datum float4lt(PG_FUNCTION_ARGS)
Definition float.c:844
Datum dceil(PG_FUNCTION_ARGS)
Definition float.c:1380
Datum btfloat4cmp(PG_FUNCTION_ARGS)
Definition float.c:880
float8 degree_c_sixty
Definition float.c:68
static float8 acos_0_5
Definition float.c:47
Datum float84gt(PG_FUNCTION_ARGS)
Definition float.c:4155
Datum dasinh(PG_FUNCTION_ARGS)
Definition float.c:2672
Datum float84mi(PG_FUNCTION_ARGS)
Definition float.c:4026
static double sind_0_to_30(double x)
Definition float.c:2252
Datum dtof(PG_FUNCTION_ARGS)
Definition float.c:1195
Datum radians(PG_FUNCTION_ARGS)
Definition float.c:2583
pg_noinline void float_zero_divide_error(void)
Definition float.c:102
pg_noinline void float_overflow_error(void)
Definition float.c:86
Datum width_bucket_float8(PG_FUNCTION_ARGS)
Definition float.c:4188
Datum dasind(PG_FUNCTION_ARGS)
Definition float.c:2145
Datum float8_var_samp(PG_FUNCTION_ARGS)
Definition float.c:3255
Datum btfloat84cmp(PG_FUNCTION_ARGS)
Definition float.c:1011
Datum ftoi4(PG_FUNCTION_ARGS)
Definition float.c:1288
Datum dsind(PG_FUNCTION_ARGS)
Definition float.c:2439
Datum datan2(PG_FUNCTION_ARGS)
Definition float.c:1843
Datum derfc(PG_FUNCTION_ARGS)
Definition float.c:2772
Datum float8div(PG_FUNCTION_ARGS)
Definition float.c:797
Datum float8_regr_syy(PG_FUNCTION_ARGS)
Definition float.c:3687
Datum float48gt(PG_FUNCTION_ARGS)
Definition float.c:4098
Datum degrees(PG_FUNCTION_ARGS)
Definition float.c:2561
Datum btfloat4sortsupport(PG_FUNCTION_ARGS)
Definition float.c:898
Datum dlgamma(PG_FUNCTION_ARGS)
Definition float.c:2850
Datum dacosd(PG_FUNCTION_ARGS)
Definition float.c:2108
float8 degree_c_thirty
Definition float.c:66
int extra_float_digits
Definition float.c:40
static double acosd_q1(double x)
Definition float.c:2081
Datum float8_regr_r2(PG_FUNCTION_ARGS)
Definition float.c:3871
Datum float8_regr_combine(PG_FUNCTION_ARGS)
Definition float.c:3508
Datum float8_regr_slope(PG_FUNCTION_ARGS)
Definition float.c:3904
Datum float8eq(PG_FUNCTION_ARGS)
Definition float.c:920
Datum dtanh(PG_FUNCTION_ARGS)
Definition float.c:2652
static double cosd_q1(double x)
Definition float.c:2299
Datum dlog10(PG_FUNCTION_ARGS)
Definition float.c:1722
Datum float84mul(PG_FUNCTION_ARGS)
Definition float.c:4035
static bool degree_consts_set
Definition float.c:43
Datum datanh(PG_FUNCTION_ARGS)
Definition float.c:2714
Datum dcosd(PG_FUNCTION_ARGS)
Definition float.c:2318
static int btfloat8fastcmp(Datum x, Datum y, SortSupport ssup)
Definition float.c:983
Datum derf(PG_FUNCTION_ARGS)
Definition float.c:2752
Datum float4up(PG_FUNCTION_ARGS)
Definition float.c:612
static float8 atan_1_0
Definition float.c:48
Datum float48pl(PG_FUNCTION_ARGS)
Definition float.c:3975
Datum dsinh(PG_FUNCTION_ARGS)
Definition float.c:2598
Datum float8_combine(PG_FUNCTION_ARGS)
Definition float.c:2957
Datum float8_avg(PG_FUNCTION_ARGS)
Definition float.c:3213
Datum float8_covar_pop(PG_FUNCTION_ARGS)
Definition float.c:3779
Datum dtan(PG_FUNCTION_ARGS)
Definition float.c:1965
Datum float8ge(PG_FUNCTION_ARGS)
Definition float.c:965
Datum float8_stddev_pop(PG_FUNCTION_ARGS)
Definition float.c:3277
static double asind_q1(double x)
Definition float.c:2048
Datum dround(PG_FUNCTION_ARGS)
Definition float.c:1368
Datum float4um(PG_FUNCTION_ARGS)
Definition float.c:602
Datum dlog1(PG_FUNCTION_ARGS)
Definition float.c:1690
Datum datan2d(PG_FUNCTION_ARGS)
Definition float.c:2214
Datum float4abs(PG_FUNCTION_ARGS)
Definition float.c:591
Datum ftod(PG_FUNCTION_ARGS)
Definition float.c:1183
Datum float4mul(PG_FUNCTION_ARGS)
Definition float.c:746
Datum float4le(PG_FUNCTION_ARGS)
Definition float.c:853
Datum dcos(PG_FUNCTION_ARGS)
Definition float.c:1869
Datum float8_regr_intercept(PG_FUNCTION_ARGS)
Definition float.c:3931
Datum float8out(PG_FUNCTION_ARGS)
Definition float.c:522
Datum float84le(PG_FUNCTION_ARGS)
Definition float.c:4146
Datum dexp(PG_FUNCTION_ARGS)
Definition float.c:1644
Datum float8pl(PG_FUNCTION_ARGS)
Definition float.c:770
Datum float8lt(PG_FUNCTION_ARGS)
Definition float.c:938
Datum float4gt(PG_FUNCTION_ARGS)
Definition float.c:862
Datum float4out(PG_FUNCTION_ARGS)
Definition float.c:319
#define INIT_DEGREE_CONSTANTS()
Definition float.c:2031
Datum dsign(PG_FUNCTION_ARGS)
Definition float.c:1405
Datum float8recv(PG_FUNCTION_ARGS)
Definition float.c:556
Datum float4send(PG_FUNCTION_ARGS)
Definition float.c:350
static float8 cot_45
Definition float.c:50
Datum float4ne(PG_FUNCTION_ARGS)
Definition float.c:835
Datum float84eq(PG_FUNCTION_ARGS)
Definition float.c:4119
Datum float84lt(PG_FUNCTION_ARGS)
Definition float.c:4137
Datum float48mi(PG_FUNCTION_ARGS)
Definition float.c:3984
Datum float8le(PG_FUNCTION_ARGS)
Definition float.c:947
Datum dtrunc(PG_FUNCTION_ARGS)
Definition float.c:1428
Datum btfloat8cmp(PG_FUNCTION_ARGS)
Definition float.c:974
Datum float8in(PG_FUNCTION_ARGS)
Definition float.c:364
Datum float8ne(PG_FUNCTION_ARGS)
Definition float.c:929
Datum dpow(PG_FUNCTION_ARGS)
Definition float.c:1489
Datum float8mi(PG_FUNCTION_ARGS)
Definition float.c:779
static double sind_q1(double x)
Definition float.c:2279
Datum ftoi2(PG_FUNCTION_ARGS)
Definition float.c:1313
Datum float4mi(PG_FUNCTION_ARGS)
Definition float.c:737
Datum float8_accum(PG_FUNCTION_ARGS)
Definition float.c:3049
Datum float48eq(PG_FUNCTION_ARGS)
Definition float.c:4062
Datum i2tof(PG_FUNCTION_ARGS)
Definition float.c:1350
static float8 one_minus_cos_60
Definition float.c:45
Datum float84pl(PG_FUNCTION_ARGS)
Definition float.c:4017
Datum btfloat48cmp(PG_FUNCTION_ARGS)
Definition float.c:1001
Datum float48ge(PG_FUNCTION_ARGS)
Definition float.c:4107
Datum float84div(PG_FUNCTION_ARGS)
Definition float.c:4044
Datum dcotd(PG_FUNCTION_ARGS)
Definition float.c:2373
pg_noinline void float_underflow_error(void)
Definition float.c:94
Datum float8smaller(PG_FUNCTION_ARGS)
Definition float.c:701
float8 degree_c_forty_five
Definition float.c:67
Datum dsqrt(PG_FUNCTION_ARGS)
Definition float.c:1446
Datum float84ge(PG_FUNCTION_ARGS)
Definition float.c:4164
Datum float8_stddev_samp(PG_FUNCTION_ARGS)
Definition float.c:3299
Datum datand(PG_FUNCTION_ARGS)
Definition float.c:2182
Datum float8larger(PG_FUNCTION_ARGS)
Definition float.c:687
Datum dcbrt(PG_FUNCTION_ARGS)
Definition float.c:1470
Datum float4in(PG_FUNCTION_ARGS)
Definition float.c:164
static int btfloat4fastcmp(Datum x, Datum y, SortSupport ssup)
Definition float.c:889
Datum float8_regr_sxy(PG_FUNCTION_ARGS)
Definition float.c:3708
Datum float8_var_pop(PG_FUNCTION_ARGS)
Definition float.c:3233
Datum float48div(PG_FUNCTION_ARGS)
Definition float.c:4002
Datum float84ne(PG_FUNCTION_ARGS)
Definition float.c:4128
Datum float4_accum(PG_FUNCTION_ARGS)
Definition float.c:3130
Datum float8up(PG_FUNCTION_ARGS)
Definition float.c:679
int float4_cmp_internal(float4 a, float4 b)
Definition float.c:816
static float8 tan_45
Definition float.c:49
Datum float48le(PG_FUNCTION_ARGS)
Definition float.c:4089
Datum float8_regr_sxx(PG_FUNCTION_ARGS)
Definition float.c:3666
Datum float8_corr(PG_FUNCTION_ARGS)
Definition float.c:3817
static float8 sin_30
Definition float.c:44
float8 degree_c_one
Definition float.c:70
Datum float4recv(PG_FUNCTION_ARGS)
Definition float.c:339
float8 degree_c_one_half
Definition float.c:69
Datum in_range_float8_float8(PG_FUNCTION_ARGS)
Definition float.c:1027
Datum float48ne(PG_FUNCTION_ARGS)
Definition float.c:4071
Datum dpi(PG_FUNCTION_ARGS)
Definition float.c:2573
float4 float4in_internal(char *num, char **endptr_p, const char *type_name, const char *orig_string, struct Node *escontext)
Definition float.c:183
Datum dacos(PG_FUNCTION_ARGS)
Definition float.c:1755
Datum float48lt(PG_FUNCTION_ARGS)
Definition float.c:4080
static void init_degree_constants(void)
Definition float.c:2019
Datum dgamma(PG_FUNCTION_ARGS)
Definition float.c:2796
Datum float8mul(PG_FUNCTION_ARGS)
Definition float.c:788
Datum float4div(PG_FUNCTION_ARGS)
Definition float.c:755
Datum in_range_float4_float8(PG_FUNCTION_ARGS)
Definition float.c:1103
Datum dtand(PG_FUNCTION_ARGS)
Definition float.c:2495
Datum float8abs(PG_FUNCTION_ARGS)
Definition float.c:657
Datum i4tod(PG_FUNCTION_ARGS)
Definition float.c:1264
int is_infinite(double val)
Definition float.c:118
Datum i2tod(PG_FUNCTION_ARGS)
Definition float.c:1276
Datum dfloor(PG_FUNCTION_ARGS)
Definition float.c:1392
Datum btfloat8sortsupport(PG_FUNCTION_ARGS)
Definition float.c:992
Datum dcosh(PG_FUNCTION_ARGS)
Definition float.c:2627
Datum dacosh(PG_FUNCTION_ARGS)
Definition float.c:2689
Datum float4ge(PG_FUNCTION_ARGS)
Definition float.c:871
Datum dasin(PG_FUNCTION_ARGS)
Definition float.c:1786
Datum i4tof(PG_FUNCTION_ARGS)
Definition float.c:1338
Datum datan(PG_FUNCTION_ARGS)
Definition float.c:1817
Datum float8gt(PG_FUNCTION_ARGS)
Definition float.c:956
Datum float8_regr_avgx(PG_FUNCTION_ARGS)
Definition float.c:3729
Datum float8um(PG_FUNCTION_ARGS)
Definition float.c:669
Datum float8_regr_avgy(PG_FUNCTION_ARGS)
Definition float.c:3754
Datum dcot(PG_FUNCTION_ARGS)
Definition float.c:1910
Datum dsin(PG_FUNCTION_ARGS)
Definition float.c:1938
Datum dtoi4(PG_FUNCTION_ARGS)
Definition float.c:1214
Datum float4pl(PG_FUNCTION_ARGS)
Definition float.c:728
static float8 asin_0_5
Definition float.c:46
Datum float8_covar_samp(PG_FUNCTION_ARGS)
Definition float.c:3798
Datum float8send(PG_FUNCTION_ARGS)
Definition float.c:567
Datum float4larger(PG_FUNCTION_ARGS)
Definition float.c:620
Datum dtoi2(PG_FUNCTION_ARGS)
Definition float.c:1239
static float8 * check_float8_array(ArrayType *transarray, const char *caller, int n)
Definition float.c:2933
static double cosd_0_to_60(double x)
Definition float.c:2266
Datum float48mul(PG_FUNCTION_ARGS)
Definition float.c:3993
Datum float4smaller(PG_FUNCTION_ARGS)
Definition float.c:634
Datum float8_regr_accum(PG_FUNCTION_ARGS)
Definition float.c:3354
char * float8out_internal(double num)
Definition float.c:537
int float8_cmp_internal(float8 a, float8 b)
Definition float.c:910
Datum float4eq(PG_FUNCTION_ARGS)
Definition float.c:826
static float8 float8_mul(const float8 val1, const float8 val2)
Definition float.h:163
static float4 float4_div(const float4 val1, const float4 val2)
Definition float.h:177
#define RADIANS_PER_DEGREE
Definition float.h:26
static float4 get_float4_infinity(void)
Definition float.h:58
static bool float4_lt(const float4 val1, const float4 val2)
Definition float.h:241
static float8 float8_pl(const float8 val1, const float8 val2)
Definition float.h:113
static float8 float8_mi(const float8 val1, const float8 val2)
Definition float.h:137
static bool float4_ge(const float4 val1, const float4 val2)
Definition float.h:277
static float4 get_float4_nan(void)
Definition float.h:77
static bool float8_ne(const float8 val1, const float8 val2)
Definition float.h:235
static bool float4_ne(const float4 val1, const float4 val2)
Definition float.h:229
static float4 float4_pl(const float4 val1, const float4 val2)
Definition float.h:101
static bool float4_eq(const float4 val1, const float4 val2)
Definition float.h:217
static float4 float4_mul(const float4 val1, const float4 val2)
Definition float.h:149
static float8 get_float8_infinity(void)
Definition float.h:65
static bool float8_ge(const float8 val1, const float8 val2)
Definition float.h:283
static float4 float4_mi(const float4 val1, const float4 val2)
Definition float.h:125
static bool float8_le(const float8 val1, const float8 val2)
Definition float.h:259
static bool float4_gt(const float4 val1, const float4 val2)
Definition float.h:265
static bool float8_eq(const float8 val1, const float8 val2)
Definition float.h:223
static bool float4_le(const float4 val1, const float4 val2)
Definition float.h:253
static float8 get_float8_nan(void)
Definition float.h:84
static float8 float8_div(const float8 val1, const float8 val2)
Definition float.h:193
static bool float8_lt(const float8 val1, const float8 val2)
Definition float.h:247
static bool float8_gt(const float8 val1, const float8 val2)
Definition float.h:271
#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:4607
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:461
#define Float8GetDatumFast(X)
Definition postgres.h:537
static float8 DatumGetFloat8(Datum X)
Definition postgres.h:495
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 SortSupportData * SortSupport
Definition sortsupport.h:58
struct StringInfoData * StringInfo
Definition string.h:15
Definition nodes.h:135
int(* comparator)(Datum x, Datum y, SortSupport ssup)