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