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