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