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(transdatums, 3,
2950  FLOAT8OID,
2951  sizeof(float8), FLOAT8PASSBYVAL, TYPALIGN_DOUBLE);
2952 
2953  PG_RETURN_ARRAYTYPE_P(result);
2954  }
2955 }
2956 
2957 Datum
2959 {
2960  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
2962  float8 *transvalues;
2963  float8 N,
2964  Sx,
2965  Sxx,
2966  tmp;
2967 
2968  transvalues = check_float8_array(transarray, "float8_accum", 3);
2969  N = transvalues[0];
2970  Sx = transvalues[1];
2971  Sxx = transvalues[2];
2972 
2973  /*
2974  * Use the Youngs-Cramer algorithm to incorporate the new value into the
2975  * transition values.
2976  */
2977  N += 1.0;
2978  Sx += newval;
2979  if (transvalues[0] > 0.0)
2980  {
2981  tmp = newval * N - Sx;
2982  Sxx += tmp * tmp / (N * transvalues[0]);
2983 
2984  /*
2985  * Overflow check. We only report an overflow error when finite
2986  * inputs lead to infinite results. Note also that Sxx should be NaN
2987  * if any of the inputs are infinite, so we intentionally prevent Sxx
2988  * from becoming infinite.
2989  */
2990  if (isinf(Sx) || isinf(Sxx))
2991  {
2992  if (!isinf(transvalues[1]) && !isinf(newval))
2994 
2995  Sxx = get_float8_nan();
2996  }
2997  }
2998  else
2999  {
3000  /*
3001  * At the first input, we normally can leave Sxx as 0. However, if
3002  * the first input is Inf or NaN, we'd better force Sxx to NaN;
3003  * otherwise we will falsely report variance zero when there are no
3004  * more inputs.
3005  */
3006  if (isnan(newval) || isinf(newval))
3007  Sxx = get_float8_nan();
3008  }
3009 
3010  /*
3011  * If we're invoked as an aggregate, we can cheat and modify our first
3012  * parameter in-place to reduce palloc overhead. Otherwise we construct a
3013  * new array with the updated transition data and return it.
3014  */
3015  if (AggCheckCallContext(fcinfo, NULL))
3016  {
3017  transvalues[0] = N;
3018  transvalues[1] = Sx;
3019  transvalues[2] = Sxx;
3020 
3021  PG_RETURN_ARRAYTYPE_P(transarray);
3022  }
3023  else
3024  {
3025  Datum transdatums[3];
3026  ArrayType *result;
3027 
3028  transdatums[0] = Float8GetDatumFast(N);
3029  transdatums[1] = Float8GetDatumFast(Sx);
3030  transdatums[2] = Float8GetDatumFast(Sxx);
3031 
3032  result = construct_array(transdatums, 3,
3033  FLOAT8OID,
3034  sizeof(float8), FLOAT8PASSBYVAL, TYPALIGN_DOUBLE);
3035 
3036  PG_RETURN_ARRAYTYPE_P(result);
3037  }
3038 }
3039 
3040 Datum
3042 {
3043  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3044 
3045  /* do computations as float8 */
3047  float8 *transvalues;
3048  float8 N,
3049  Sx,
3050  Sxx,
3051  tmp;
3052 
3053  transvalues = check_float8_array(transarray, "float4_accum", 3);
3054  N = transvalues[0];
3055  Sx = transvalues[1];
3056  Sxx = transvalues[2];
3057 
3058  /*
3059  * Use the Youngs-Cramer algorithm to incorporate the new value into the
3060  * transition values.
3061  */
3062  N += 1.0;
3063  Sx += newval;
3064  if (transvalues[0] > 0.0)
3065  {
3066  tmp = newval * N - Sx;
3067  Sxx += tmp * tmp / (N * transvalues[0]);
3068 
3069  /*
3070  * Overflow check. We only report an overflow error when finite
3071  * inputs lead to infinite results. Note also that Sxx should be NaN
3072  * if any of the inputs are infinite, so we intentionally prevent Sxx
3073  * from becoming infinite.
3074  */
3075  if (isinf(Sx) || isinf(Sxx))
3076  {
3077  if (!isinf(transvalues[1]) && !isinf(newval))
3079 
3080  Sxx = get_float8_nan();
3081  }
3082  }
3083  else
3084  {
3085  /*
3086  * At the first input, we normally can leave Sxx as 0. However, if
3087  * the first input is Inf or NaN, we'd better force Sxx to NaN;
3088  * otherwise we will falsely report variance zero when there are no
3089  * more inputs.
3090  */
3091  if (isnan(newval) || isinf(newval))
3092  Sxx = get_float8_nan();
3093  }
3094 
3095  /*
3096  * If we're invoked as an aggregate, we can cheat and modify our first
3097  * parameter in-place to reduce palloc overhead. Otherwise we construct a
3098  * new array with the updated transition data and return it.
3099  */
3100  if (AggCheckCallContext(fcinfo, NULL))
3101  {
3102  transvalues[0] = N;
3103  transvalues[1] = Sx;
3104  transvalues[2] = Sxx;
3105 
3106  PG_RETURN_ARRAYTYPE_P(transarray);
3107  }
3108  else
3109  {
3110  Datum transdatums[3];
3111  ArrayType *result;
3112 
3113  transdatums[0] = Float8GetDatumFast(N);
3114  transdatums[1] = Float8GetDatumFast(Sx);
3115  transdatums[2] = Float8GetDatumFast(Sxx);
3116 
3117  result = construct_array(transdatums, 3,
3118  FLOAT8OID,
3119  sizeof(float8), FLOAT8PASSBYVAL, TYPALIGN_DOUBLE);
3120 
3121  PG_RETURN_ARRAYTYPE_P(result);
3122  }
3123 }
3124 
3125 Datum
3127 {
3128  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3129  float8 *transvalues;
3130  float8 N,
3131  Sx;
3132 
3133  transvalues = check_float8_array(transarray, "float8_avg", 3);
3134  N = transvalues[0];
3135  Sx = transvalues[1];
3136  /* ignore Sxx */
3137 
3138  /* SQL defines AVG of no values to be NULL */
3139  if (N == 0.0)
3140  PG_RETURN_NULL();
3141 
3142  PG_RETURN_FLOAT8(Sx / N);
3143 }
3144 
3145 Datum
3147 {
3148  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3149  float8 *transvalues;
3150  float8 N,
3151  Sxx;
3152 
3153  transvalues = check_float8_array(transarray, "float8_var_pop", 3);
3154  N = transvalues[0];
3155  /* ignore Sx */
3156  Sxx = transvalues[2];
3157 
3158  /* Population variance is undefined when N is 0, so return NULL */
3159  if (N == 0.0)
3160  PG_RETURN_NULL();
3161 
3162  /* Note that Sxx is guaranteed to be non-negative */
3163 
3164  PG_RETURN_FLOAT8(Sxx / N);
3165 }
3166 
3167 Datum
3169 {
3170  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3171  float8 *transvalues;
3172  float8 N,
3173  Sxx;
3174 
3175  transvalues = check_float8_array(transarray, "float8_var_samp", 3);
3176  N = transvalues[0];
3177  /* ignore Sx */
3178  Sxx = transvalues[2];
3179 
3180  /* Sample variance is undefined when N is 0 or 1, so return NULL */
3181  if (N <= 1.0)
3182  PG_RETURN_NULL();
3183 
3184  /* Note that Sxx is guaranteed to be non-negative */
3185 
3186  PG_RETURN_FLOAT8(Sxx / (N - 1.0));
3187 }
3188 
3189 Datum
3191 {
3192  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3193  float8 *transvalues;
3194  float8 N,
3195  Sxx;
3196 
3197  transvalues = check_float8_array(transarray, "float8_stddev_pop", 3);
3198  N = transvalues[0];
3199  /* ignore Sx */
3200  Sxx = transvalues[2];
3201 
3202  /* Population stddev is undefined when N is 0, so return NULL */
3203  if (N == 0.0)
3204  PG_RETURN_NULL();
3205 
3206  /* Note that Sxx is guaranteed to be non-negative */
3207 
3208  PG_RETURN_FLOAT8(sqrt(Sxx / N));
3209 }
3210 
3211 Datum
3213 {
3214  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3215  float8 *transvalues;
3216  float8 N,
3217  Sxx;
3218 
3219  transvalues = check_float8_array(transarray, "float8_stddev_samp", 3);
3220  N = transvalues[0];
3221  /* ignore Sx */
3222  Sxx = transvalues[2];
3223 
3224  /* Sample stddev is undefined when N is 0 or 1, so return NULL */
3225  if (N <= 1.0)
3226  PG_RETURN_NULL();
3227 
3228  /* Note that Sxx is guaranteed to be non-negative */
3229 
3230  PG_RETURN_FLOAT8(sqrt(Sxx / (N - 1.0)));
3231 }
3232 
3233 /*
3234  * =========================
3235  * SQL2003 BINARY AGGREGATES
3236  * =========================
3237  *
3238  * As with the preceding aggregates, we use the Youngs-Cramer algorithm to
3239  * reduce rounding errors in the aggregate final functions.
3240  *
3241  * The transition datatype for all these aggregates is a 6-element array of
3242  * float8, holding the values N, Sx=sum(X), Sxx=sum((X-Sx/N)^2), Sy=sum(Y),
3243  * Syy=sum((Y-Sy/N)^2), Sxy=sum((X-Sx/N)*(Y-Sy/N)) in that order.
3244  *
3245  * Note that Y is the first argument to all these aggregates!
3246  *
3247  * It might seem attractive to optimize this by having multiple accumulator
3248  * functions that only calculate the sums actually needed. But on most
3249  * modern machines, a couple of extra floating-point multiplies will be
3250  * insignificant compared to the other per-tuple overhead, so I've chosen
3251  * to minimize code space instead.
3252  */
3253 
3254 Datum
3256 {
3257  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3258  float8 newvalY = PG_GETARG_FLOAT8(1);
3259  float8 newvalX = PG_GETARG_FLOAT8(2);
3260  float8 *transvalues;
3261  float8 N,
3262  Sx,
3263  Sxx,
3264  Sy,
3265  Syy,
3266  Sxy,
3267  tmpX,
3268  tmpY,
3269  scale;
3270 
3271  transvalues = check_float8_array(transarray, "float8_regr_accum", 6);
3272  N = transvalues[0];
3273  Sx = transvalues[1];
3274  Sxx = transvalues[2];
3275  Sy = transvalues[3];
3276  Syy = transvalues[4];
3277  Sxy = transvalues[5];
3278 
3279  /*
3280  * Use the Youngs-Cramer algorithm to incorporate the new values into the
3281  * transition values.
3282  */
3283  N += 1.0;
3284  Sx += newvalX;
3285  Sy += newvalY;
3286  if (transvalues[0] > 0.0)
3287  {
3288  tmpX = newvalX * N - Sx;
3289  tmpY = newvalY * N - Sy;
3290  scale = 1.0 / (N * transvalues[0]);
3291  Sxx += tmpX * tmpX * scale;
3292  Syy += tmpY * tmpY * scale;
3293  Sxy += tmpX * tmpY * scale;
3294 
3295  /*
3296  * Overflow check. We only report an overflow error when finite
3297  * inputs lead to infinite results. Note also that Sxx, Syy and Sxy
3298  * should be NaN if any of the relevant inputs are infinite, so we
3299  * intentionally prevent them from becoming infinite.
3300  */
3301  if (isinf(Sx) || isinf(Sxx) || isinf(Sy) || isinf(Syy) || isinf(Sxy))
3302  {
3303  if (((isinf(Sx) || isinf(Sxx)) &&
3304  !isinf(transvalues[1]) && !isinf(newvalX)) ||
3305  ((isinf(Sy) || isinf(Syy)) &&
3306  !isinf(transvalues[3]) && !isinf(newvalY)) ||
3307  (isinf(Sxy) &&
3308  !isinf(transvalues[1]) && !isinf(newvalX) &&
3309  !isinf(transvalues[3]) && !isinf(newvalY)))
3311 
3312  if (isinf(Sxx))
3313  Sxx = get_float8_nan();
3314  if (isinf(Syy))
3315  Syy = get_float8_nan();
3316  if (isinf(Sxy))
3317  Sxy = get_float8_nan();
3318  }
3319  }
3320  else
3321  {
3322  /*
3323  * At the first input, we normally can leave Sxx et al as 0. However,
3324  * if the first input is Inf or NaN, we'd better force the dependent
3325  * sums to NaN; otherwise we will falsely report variance zero when
3326  * there are no more inputs.
3327  */
3328  if (isnan(newvalX) || isinf(newvalX))
3329  Sxx = Sxy = get_float8_nan();
3330  if (isnan(newvalY) || isinf(newvalY))
3331  Syy = Sxy = get_float8_nan();
3332  }
3333 
3334  /*
3335  * If we're invoked as an aggregate, we can cheat and modify our first
3336  * parameter in-place to reduce palloc overhead. Otherwise we construct a
3337  * new array with the updated transition data and return it.
3338  */
3339  if (AggCheckCallContext(fcinfo, NULL))
3340  {
3341  transvalues[0] = N;
3342  transvalues[1] = Sx;
3343  transvalues[2] = Sxx;
3344  transvalues[3] = Sy;
3345  transvalues[4] = Syy;
3346  transvalues[5] = Sxy;
3347 
3348  PG_RETURN_ARRAYTYPE_P(transarray);
3349  }
3350  else
3351  {
3352  Datum transdatums[6];
3353  ArrayType *result;
3354 
3355  transdatums[0] = Float8GetDatumFast(N);
3356  transdatums[1] = Float8GetDatumFast(Sx);
3357  transdatums[2] = Float8GetDatumFast(Sxx);
3358  transdatums[3] = Float8GetDatumFast(Sy);
3359  transdatums[4] = Float8GetDatumFast(Syy);
3360  transdatums[5] = Float8GetDatumFast(Sxy);
3361 
3362  result = construct_array(transdatums, 6,
3363  FLOAT8OID,
3364  sizeof(float8), FLOAT8PASSBYVAL, TYPALIGN_DOUBLE);
3365 
3366  PG_RETURN_ARRAYTYPE_P(result);
3367  }
3368 }
3369 
3370 /*
3371  * float8_regr_combine
3372  *
3373  * An aggregate combine function used to combine two 6 fields
3374  * aggregate transition data into a single transition data.
3375  * This function is used only in two stage aggregation and
3376  * shouldn't be called outside aggregate context.
3377  */
3378 Datum
3380 {
3381  ArrayType *transarray1 = PG_GETARG_ARRAYTYPE_P(0);
3382  ArrayType *transarray2 = PG_GETARG_ARRAYTYPE_P(1);
3383  float8 *transvalues1;
3384  float8 *transvalues2;
3385  float8 N1,
3386  Sx1,
3387  Sxx1,
3388  Sy1,
3389  Syy1,
3390  Sxy1,
3391  N2,
3392  Sx2,
3393  Sxx2,
3394  Sy2,
3395  Syy2,
3396  Sxy2,
3397  tmp1,
3398  tmp2,
3399  N,
3400  Sx,
3401  Sxx,
3402  Sy,
3403  Syy,
3404  Sxy;
3405 
3406  transvalues1 = check_float8_array(transarray1, "float8_regr_combine", 6);
3407  transvalues2 = check_float8_array(transarray2, "float8_regr_combine", 6);
3408 
3409  N1 = transvalues1[0];
3410  Sx1 = transvalues1[1];
3411  Sxx1 = transvalues1[2];
3412  Sy1 = transvalues1[3];
3413  Syy1 = transvalues1[4];
3414  Sxy1 = transvalues1[5];
3415 
3416  N2 = transvalues2[0];
3417  Sx2 = transvalues2[1];
3418  Sxx2 = transvalues2[2];
3419  Sy2 = transvalues2[3];
3420  Syy2 = transvalues2[4];
3421  Sxy2 = transvalues2[5];
3422 
3423  /*--------------------
3424  * The transition values combine using a generalization of the
3425  * Youngs-Cramer algorithm as follows:
3426  *
3427  * N = N1 + N2
3428  * Sx = Sx1 + Sx2
3429  * Sxx = Sxx1 + Sxx2 + N1 * N2 * (Sx1/N1 - Sx2/N2)^2 / N
3430  * Sy = Sy1 + Sy2
3431  * Syy = Syy1 + Syy2 + N1 * N2 * (Sy1/N1 - Sy2/N2)^2 / N
3432  * Sxy = Sxy1 + Sxy2 + N1 * N2 * (Sx1/N1 - Sx2/N2) * (Sy1/N1 - Sy2/N2) / N
3433  *
3434  * It's worth handling the special cases N1 = 0 and N2 = 0 separately
3435  * since those cases are trivial, and we then don't need to worry about
3436  * division-by-zero errors in the general case.
3437  *--------------------
3438  */
3439  if (N1 == 0.0)
3440  {
3441  N = N2;
3442  Sx = Sx2;
3443  Sxx = Sxx2;
3444  Sy = Sy2;
3445  Syy = Syy2;
3446  Sxy = Sxy2;
3447  }
3448  else if (N2 == 0.0)
3449  {
3450  N = N1;
3451  Sx = Sx1;
3452  Sxx = Sxx1;
3453  Sy = Sy1;
3454  Syy = Syy1;
3455  Sxy = Sxy1;
3456  }
3457  else
3458  {
3459  N = N1 + N2;
3460  Sx = float8_pl(Sx1, Sx2);
3461  tmp1 = Sx1 / N1 - Sx2 / N2;
3462  Sxx = Sxx1 + Sxx2 + N1 * N2 * tmp1 * tmp1 / N;
3463  if (unlikely(isinf(Sxx)) && !isinf(Sxx1) && !isinf(Sxx2))
3465  Sy = float8_pl(Sy1, Sy2);
3466  tmp2 = Sy1 / N1 - Sy2 / N2;
3467  Syy = Syy1 + Syy2 + N1 * N2 * tmp2 * tmp2 / N;
3468  if (unlikely(isinf(Syy)) && !isinf(Syy1) && !isinf(Syy2))
3470  Sxy = Sxy1 + Sxy2 + N1 * N2 * tmp1 * tmp2 / N;
3471  if (unlikely(isinf(Sxy)) && !isinf(Sxy1) && !isinf(Sxy2))
3473  }
3474 
3475  /*
3476  * If we're invoked as an aggregate, we can cheat and modify our first
3477  * parameter in-place to reduce palloc overhead. Otherwise we construct a
3478  * new array with the updated transition data and return it.
3479  */
3480  if (AggCheckCallContext(fcinfo, NULL))
3481  {
3482  transvalues1[0] = N;
3483  transvalues1[1] = Sx;
3484  transvalues1[2] = Sxx;
3485  transvalues1[3] = Sy;
3486  transvalues1[4] = Syy;
3487  transvalues1[5] = Sxy;
3488 
3489  PG_RETURN_ARRAYTYPE_P(transarray1);
3490  }
3491  else
3492  {
3493  Datum transdatums[6];
3494  ArrayType *result;
3495 
3496  transdatums[0] = Float8GetDatumFast(N);
3497  transdatums[1] = Float8GetDatumFast(Sx);
3498  transdatums[2] = Float8GetDatumFast(Sxx);
3499  transdatums[3] = Float8GetDatumFast(Sy);
3500  transdatums[4] = Float8GetDatumFast(Syy);
3501  transdatums[5] = Float8GetDatumFast(Sxy);
3502 
3503  result = construct_array(transdatums, 6,
3504  FLOAT8OID,
3505  sizeof(float8), FLOAT8PASSBYVAL, TYPALIGN_DOUBLE);
3506 
3507  PG_RETURN_ARRAYTYPE_P(result);
3508  }
3509 }
3510 
3511 
3512 Datum
3514 {
3515  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3516  float8 *transvalues;
3517  float8 N,
3518  Sxx;
3519 
3520  transvalues = check_float8_array(transarray, "float8_regr_sxx", 6);
3521  N = transvalues[0];
3522  Sxx = transvalues[2];
3523 
3524  /* if N is 0 we should return NULL */
3525  if (N < 1.0)
3526  PG_RETURN_NULL();
3527 
3528  /* Note that Sxx is guaranteed to be non-negative */
3529 
3530  PG_RETURN_FLOAT8(Sxx);
3531 }
3532 
3533 Datum
3535 {
3536  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3537  float8 *transvalues;
3538  float8 N,
3539  Syy;
3540 
3541  transvalues = check_float8_array(transarray, "float8_regr_syy", 6);
3542  N = transvalues[0];
3543  Syy = transvalues[4];
3544 
3545  /* if N is 0 we should return NULL */
3546  if (N < 1.0)
3547  PG_RETURN_NULL();
3548 
3549  /* Note that Syy is guaranteed to be non-negative */
3550 
3551  PG_RETURN_FLOAT8(Syy);
3552 }
3553 
3554 Datum
3556 {
3557  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3558  float8 *transvalues;
3559  float8 N,
3560  Sxy;
3561 
3562  transvalues = check_float8_array(transarray, "float8_regr_sxy", 6);
3563  N = transvalues[0];
3564  Sxy = transvalues[5];
3565 
3566  /* if N is 0 we should return NULL */
3567  if (N < 1.0)
3568  PG_RETURN_NULL();
3569 
3570  /* A negative result is valid here */
3571 
3572  PG_RETURN_FLOAT8(Sxy);
3573 }
3574 
3575 Datum
3577 {
3578  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3579  float8 *transvalues;
3580  float8 N,
3581  Sx;
3582 
3583  transvalues = check_float8_array(transarray, "float8_regr_avgx", 6);
3584  N = transvalues[0];
3585  Sx = transvalues[1];
3586 
3587  /* if N is 0 we should return NULL */
3588  if (N < 1.0)
3589  PG_RETURN_NULL();
3590 
3591  PG_RETURN_FLOAT8(Sx / N);
3592 }
3593 
3594 Datum
3596 {
3597  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3598  float8 *transvalues;
3599  float8 N,
3600  Sy;
3601 
3602  transvalues = check_float8_array(transarray, "float8_regr_avgy", 6);
3603  N = transvalues[0];
3604  Sy = transvalues[3];
3605 
3606  /* if N is 0 we should return NULL */
3607  if (N < 1.0)
3608  PG_RETURN_NULL();
3609 
3610  PG_RETURN_FLOAT8(Sy / N);
3611 }
3612 
3613 Datum
3615 {
3616  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3617  float8 *transvalues;
3618  float8 N,
3619  Sxy;
3620 
3621  transvalues = check_float8_array(transarray, "float8_covar_pop", 6);
3622  N = transvalues[0];
3623  Sxy = transvalues[5];
3624 
3625  /* if N is 0 we should return NULL */
3626  if (N < 1.0)
3627  PG_RETURN_NULL();
3628 
3629  PG_RETURN_FLOAT8(Sxy / N);
3630 }
3631 
3632 Datum
3634 {
3635  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3636  float8 *transvalues;
3637  float8 N,
3638  Sxy;
3639 
3640  transvalues = check_float8_array(transarray, "float8_covar_samp", 6);
3641  N = transvalues[0];
3642  Sxy = transvalues[5];
3643 
3644  /* if N is <= 1 we should return NULL */
3645  if (N < 2.0)
3646  PG_RETURN_NULL();
3647 
3648  PG_RETURN_FLOAT8(Sxy / (N - 1.0));
3649 }
3650 
3651 Datum
3653 {
3654  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3655  float8 *transvalues;
3656  float8 N,
3657  Sxx,
3658  Syy,
3659  Sxy;
3660 
3661  transvalues = check_float8_array(transarray, "float8_corr", 6);
3662  N = transvalues[0];
3663  Sxx = transvalues[2];
3664  Syy = transvalues[4];
3665  Sxy = transvalues[5];
3666 
3667  /* if N is 0 we should return NULL */
3668  if (N < 1.0)
3669  PG_RETURN_NULL();
3670 
3671  /* Note that Sxx and Syy are guaranteed to be non-negative */
3672 
3673  /* per spec, return NULL for horizontal and vertical lines */
3674  if (Sxx == 0 || Syy == 0)
3675  PG_RETURN_NULL();
3676 
3677  PG_RETURN_FLOAT8(Sxy / sqrt(Sxx * Syy));
3678 }
3679 
3680 Datum
3682 {
3683  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3684  float8 *transvalues;
3685  float8 N,
3686  Sxx,
3687  Syy,
3688  Sxy;
3689 
3690  transvalues = check_float8_array(transarray, "float8_regr_r2", 6);
3691  N = transvalues[0];
3692  Sxx = transvalues[2];
3693  Syy = transvalues[4];
3694  Sxy = transvalues[5];
3695 
3696  /* if N is 0 we should return NULL */
3697  if (N < 1.0)
3698  PG_RETURN_NULL();
3699 
3700  /* Note that Sxx and Syy are guaranteed to be non-negative */
3701 
3702  /* per spec, return NULL for a vertical line */
3703  if (Sxx == 0)
3704  PG_RETURN_NULL();
3705 
3706  /* per spec, return 1.0 for a horizontal line */
3707  if (Syy == 0)
3708  PG_RETURN_FLOAT8(1.0);
3709 
3710  PG_RETURN_FLOAT8((Sxy * Sxy) / (Sxx * Syy));
3711 }
3712 
3713 Datum
3715 {
3716  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3717  float8 *transvalues;
3718  float8 N,
3719  Sxx,
3720  Sxy;
3721 
3722  transvalues = check_float8_array(transarray, "float8_regr_slope", 6);
3723  N = transvalues[0];
3724  Sxx = transvalues[2];
3725  Sxy = transvalues[5];
3726 
3727  /* if N is 0 we should return NULL */
3728  if (N < 1.0)
3729  PG_RETURN_NULL();
3730 
3731  /* Note that Sxx is guaranteed to be non-negative */
3732 
3733  /* per spec, return NULL for a vertical line */
3734  if (Sxx == 0)
3735  PG_RETURN_NULL();
3736 
3737  PG_RETURN_FLOAT8(Sxy / Sxx);
3738 }
3739 
3740 Datum
3742 {
3743  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3744  float8 *transvalues;
3745  float8 N,
3746  Sx,
3747  Sxx,
3748  Sy,
3749  Sxy;
3750 
3751  transvalues = check_float8_array(transarray, "float8_regr_intercept", 6);
3752  N = transvalues[0];
3753  Sx = transvalues[1];
3754  Sxx = transvalues[2];
3755  Sy = transvalues[3];
3756  Sxy = transvalues[5];
3757 
3758  /* if N is 0 we should return NULL */
3759  if (N < 1.0)
3760  PG_RETURN_NULL();
3761 
3762  /* Note that Sxx is guaranteed to be non-negative */
3763 
3764  /* per spec, return NULL for a vertical line */
3765  if (Sxx == 0)
3766  PG_RETURN_NULL();
3767 
3768  PG_RETURN_FLOAT8((Sy - Sx * Sxy / Sxx) / N);
3769 }
3770 
3771 
3772 /*
3773  * ====================================
3774  * MIXED-PRECISION ARITHMETIC OPERATORS
3775  * ====================================
3776  */
3777 
3778 /*
3779  * float48pl - returns arg1 + arg2
3780  * float48mi - returns arg1 - arg2
3781  * float48mul - returns arg1 * arg2
3782  * float48div - returns arg1 / arg2
3783  */
3784 Datum
3786 {
3787  float4 arg1 = PG_GETARG_FLOAT4(0);
3788  float8 arg2 = PG_GETARG_FLOAT8(1);
3789 
3790  PG_RETURN_FLOAT8(float8_pl((float8) arg1, arg2));
3791 }
3792 
3793 Datum
3795 {
3796  float4 arg1 = PG_GETARG_FLOAT4(0);
3797  float8 arg2 = PG_GETARG_FLOAT8(1);
3798 
3799  PG_RETURN_FLOAT8(float8_mi((float8) arg1, arg2));
3800 }
3801 
3802 Datum
3804 {
3805  float4 arg1 = PG_GETARG_FLOAT4(0);
3806  float8 arg2 = PG_GETARG_FLOAT8(1);
3807 
3808  PG_RETURN_FLOAT8(float8_mul((float8) arg1, arg2));
3809 }
3810 
3811 Datum
3813 {
3814  float4 arg1 = PG_GETARG_FLOAT4(0);
3815  float8 arg2 = PG_GETARG_FLOAT8(1);
3816 
3817  PG_RETURN_FLOAT8(float8_div((float8) arg1, arg2));
3818 }
3819 
3820 /*
3821  * float84pl - returns arg1 + arg2
3822  * float84mi - returns arg1 - arg2
3823  * float84mul - returns arg1 * arg2
3824  * float84div - returns arg1 / arg2
3825  */
3826 Datum
3828 {
3829  float8 arg1 = PG_GETARG_FLOAT8(0);
3830  float4 arg2 = PG_GETARG_FLOAT4(1);
3831 
3832  PG_RETURN_FLOAT8(float8_pl(arg1, (float8) arg2));
3833 }
3834 
3835 Datum
3837 {
3838  float8 arg1 = PG_GETARG_FLOAT8(0);
3839  float4 arg2 = PG_GETARG_FLOAT4(1);
3840 
3841  PG_RETURN_FLOAT8(float8_mi(arg1, (float8) arg2));
3842 }
3843 
3844 Datum
3846 {
3847  float8 arg1 = PG_GETARG_FLOAT8(0);
3848  float4 arg2 = PG_GETARG_FLOAT4(1);
3849 
3850  PG_RETURN_FLOAT8(float8_mul(arg1, (float8) arg2));
3851 }
3852 
3853 Datum
3855 {
3856  float8 arg1 = PG_GETARG_FLOAT8(0);
3857  float4 arg2 = PG_GETARG_FLOAT4(1);
3858 
3859  PG_RETURN_FLOAT8(float8_div(arg1, (float8) arg2));
3860 }
3861 
3862 /*
3863  * ====================
3864  * COMPARISON OPERATORS
3865  * ====================
3866  */
3867 
3868 /*
3869  * float48{eq,ne,lt,le,gt,ge} - float4/float8 comparison operations
3870  */
3871 Datum
3873 {
3874  float4 arg1 = PG_GETARG_FLOAT4(0);
3875  float8 arg2 = PG_GETARG_FLOAT8(1);
3876 
3877  PG_RETURN_BOOL(float8_eq((float8) arg1, arg2));
3878 }
3879 
3880 Datum
3882 {
3883  float4 arg1 = PG_GETARG_FLOAT4(0);
3884  float8 arg2 = PG_GETARG_FLOAT8(1);
3885 
3886  PG_RETURN_BOOL(float8_ne((float8) arg1, arg2));
3887 }
3888 
3889 Datum
3891 {
3892  float4 arg1 = PG_GETARG_FLOAT4(0);
3893  float8 arg2 = PG_GETARG_FLOAT8(1);
3894 
3895  PG_RETURN_BOOL(float8_lt((float8) arg1, arg2));
3896 }
3897 
3898 Datum
3900 {
3901  float4 arg1 = PG_GETARG_FLOAT4(0);
3902  float8 arg2 = PG_GETARG_FLOAT8(1);
3903 
3904  PG_RETURN_BOOL(float8_le((float8) arg1, arg2));
3905 }
3906 
3907 Datum
3909 {
3910  float4 arg1 = PG_GETARG_FLOAT4(0);
3911  float8 arg2 = PG_GETARG_FLOAT8(1);
3912 
3913  PG_RETURN_BOOL(float8_gt((float8) arg1, arg2));
3914 }
3915 
3916 Datum
3918 {
3919  float4 arg1 = PG_GETARG_FLOAT4(0);
3920  float8 arg2 = PG_GETARG_FLOAT8(1);
3921 
3922  PG_RETURN_BOOL(float8_ge((float8) arg1, arg2));
3923 }
3924 
3925 /*
3926  * float84{eq,ne,lt,le,gt,ge} - float8/float4 comparison operations
3927  */
3928 Datum
3930 {
3931  float8 arg1 = PG_GETARG_FLOAT8(0);
3932  float4 arg2 = PG_GETARG_FLOAT4(1);
3933 
3934  PG_RETURN_BOOL(float8_eq(arg1, (float8) arg2));
3935 }
3936 
3937 Datum
3939 {
3940  float8 arg1 = PG_GETARG_FLOAT8(0);
3941  float4 arg2 = PG_GETARG_FLOAT4(1);
3942 
3943  PG_RETURN_BOOL(float8_ne(arg1, (float8) arg2));
3944 }
3945 
3946 Datum
3948 {
3949  float8 arg1 = PG_GETARG_FLOAT8(0);
3950  float4 arg2 = PG_GETARG_FLOAT4(1);
3951 
3952  PG_RETURN_BOOL(float8_lt(arg1, (float8) arg2));
3953 }
3954 
3955 Datum
3957 {
3958  float8 arg1 = PG_GETARG_FLOAT8(0);
3959  float4 arg2 = PG_GETARG_FLOAT4(1);
3960 
3961  PG_RETURN_BOOL(float8_le(arg1, (float8) arg2));
3962 }
3963 
3964 Datum
3966 {
3967  float8 arg1 = PG_GETARG_FLOAT8(0);
3968  float4 arg2 = PG_GETARG_FLOAT4(1);
3969 
3970  PG_RETURN_BOOL(float8_gt(arg1, (float8) arg2));
3971 }
3972 
3973 Datum
3975 {
3976  float8 arg1 = PG_GETARG_FLOAT8(0);
3977  float4 arg2 = PG_GETARG_FLOAT4(1);
3978 
3979  PG_RETURN_BOOL(float8_ge(arg1, (float8) arg2));
3980 }
3981 
3982 /*
3983  * Implements the float8 version of the width_bucket() function
3984  * defined by SQL2003. See also width_bucket_numeric().
3985  *
3986  * 'bound1' and 'bound2' are the lower and upper bounds of the
3987  * histogram's range, respectively. 'count' is the number of buckets
3988  * in the histogram. width_bucket() returns an integer indicating the
3989  * bucket number that 'operand' belongs to in an equiwidth histogram
3990  * with the specified characteristics. An operand smaller than the
3991  * lower bound is assigned to bucket 0. An operand greater than the
3992  * upper bound is assigned to an additional bucket (with number
3993  * count+1). We don't allow "NaN" for any of the float8 inputs, and we
3994  * don't allow either of the histogram bounds to be +/- infinity.
3995  */
3996 Datum
3998 {
3999  float8 operand = PG_GETARG_FLOAT8(0);
4000  float8 bound1 = PG_GETARG_FLOAT8(1);
4001  float8 bound2 = PG_GETARG_FLOAT8(2);
4002  int32 count = PG_GETARG_INT32(3);
4003  int32 result;
4004 
4005  if (count <= 0)
4006  ereport(ERROR,
4007  (errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
4008  errmsg("count must be greater than zero")));
4009 
4010  if (isnan(operand) || isnan(bound1) || isnan(bound2))
4011  ereport(ERROR,
4012  (errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
4013  errmsg("operand, lower bound, and upper bound cannot be NaN")));
4014 
4015  /* Note that we allow "operand" to be infinite */
4016  if (isinf(bound1) || isinf(bound2))
4017  ereport(ERROR,
4018  (errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
4019  errmsg("lower and upper bounds must be finite")));
4020 
4021  if (bound1 < bound2)
4022  {
4023  if (operand < bound1)
4024  result = 0;
4025  else if (operand >= bound2)
4026  {
4027  if (pg_add_s32_overflow(count, 1, &result))
4028  ereport(ERROR,
4029  (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
4030  errmsg("integer out of range")));
4031  }
4032  else
4033  {
4034  if (!isinf(bound2 - bound1))
4035  {
4036  /* The quotient is surely in [0,1], so this can't overflow */
4037  result = count * ((operand - bound1) / (bound2 - bound1));
4038  }
4039  else
4040  {
4041  /*
4042  * We get here if bound2 - bound1 overflows DBL_MAX. Since
4043  * both bounds are finite, their difference can't exceed twice
4044  * DBL_MAX; so we can perform the computation without overflow
4045  * by dividing all the inputs by 2. That should be exact too,
4046  * except in the case where a very small operand underflows to
4047  * zero, which would have negligible impact on the result
4048  * given such large bounds.
4049  */
4050  result = count * ((operand / 2 - bound1 / 2) / (bound2 / 2 - bound1 / 2));
4051  }
4052  /* The quotient could round to 1.0, which would be a lie */
4053  if (result >= count)
4054  result = count - 1;
4055  /* Having done that, we can add 1 without fear of overflow */
4056  result++;
4057  }
4058  }
4059  else if (bound1 > bound2)
4060  {
4061  if (operand > bound1)
4062  result = 0;
4063  else if (operand <= bound2)
4064  {
4065  if (pg_add_s32_overflow(count, 1, &result))
4066  ereport(ERROR,
4067  (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
4068  errmsg("integer out of range")));
4069  }
4070  else
4071  {
4072  if (!isinf(bound1 - bound2))
4073  result = count * ((bound1 - operand) / (bound1 - bound2));
4074  else
4075  result = count * ((bound1 / 2 - operand / 2) / (bound1 / 2 - bound2 / 2));
4076  if (result >= count)
4077  result = count - 1;
4078  result++;
4079  }
4080  }
4081  else
4082  {
4083  ereport(ERROR,
4084  (errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
4085  errmsg("lower bound cannot equal upper bound")));
4086  result = 0; /* keep the compiler quiet */
4087  }
4088 
4089  PG_RETURN_INT32(result);
4090 }
#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(Datum *elems, int nelems, Oid elmtype, int elmlen, bool elmbyval, char elmalign)
Definition: arrayfuncs.c:3361
#define FLOAT4_FITS_IN_INT32(num)
Definition: c.h:1084
#define FLOAT8_FITS_IN_INT32(num)
Definition: c.h:1090
#define pg_noinline
Definition: c.h:250
signed short int16
Definition: c.h:493
signed int int32
Definition: c.h:494
#define FLOAT4_FITS_IN_INT16(num)
Definition: c.h:1082
double float8
Definition: c.h:630
#define FLOAT8PASSBYVAL
Definition: c.h:635
#define FLOAT8_FITS_IN_INT16(num)
Definition: c.h:1088
#define unlikely(x)
Definition: c.h:311
float float4
Definition: c.h:629
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:276
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:224
#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:3965
Datum dasinh(PG_FUNCTION_ARGS)
Definition: float.c:2673
Datum float84mi(PG_FUNCTION_ARGS)
Definition: float.c:3836
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:3997
Datum dasind(PG_FUNCTION_ARGS)
Definition: float.c:2146
Datum float8_var_samp(PG_FUNCTION_ARGS)
Definition: float.c:3168
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:3534
Datum float48gt(PG_FUNCTION_ARGS)
Definition: float.c:3908
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:3681
Datum float8_regr_combine(PG_FUNCTION_ARGS)
Definition: float.c:3379
Datum float8_regr_slope(PG_FUNCTION_ARGS)
Definition: float.c:3714
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:3845
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:3785
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:3126
Datum float8_covar_pop(PG_FUNCTION_ARGS)
Definition: float.c:3614
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:3190
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:3741
Datum float8out(PG_FUNCTION_ARGS)
Definition: float.c:523
Datum float84le(PG_FUNCTION_ARGS)
Definition: float.c:3956
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:3929
Datum float84lt(PG_FUNCTION_ARGS)
Definition: float.c:3947
Datum float48mi(PG_FUNCTION_ARGS)
Definition: float.c:3794
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:2958
Datum float48eq(PG_FUNCTION_ARGS)
Definition: float.c:3872
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:3827
Datum btfloat48cmp(PG_FUNCTION_ARGS)
Definition: float.c:1002
Datum float48ge(PG_FUNCTION_ARGS)
Definition: float.c:3917
Datum float84div(PG_FUNCTION_ARGS)
Definition: float.c:3854
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:3974
Datum float8_stddev_samp(PG_FUNCTION_ARGS)
Definition: float.c:3212
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:3555
Datum float8_var_pop(PG_FUNCTION_ARGS)
Definition: float.c:3146
Datum float48div(PG_FUNCTION_ARGS)
Definition: float.c:3812
Datum float84ne(PG_FUNCTION_ARGS)
Definition: float.c:3938
Datum float4_accum(PG_FUNCTION_ARGS)
Definition: float.c:3041
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:3899
Datum float8_regr_sxx(PG_FUNCTION_ARGS)
Definition: float.c:3513
Datum float8_corr(PG_FUNCTION_ARGS)
Definition: float.c:3652
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:3881
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:3890
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:3576
Datum float8um(PG_FUNCTION_ARGS)
Definition: float.c:670
Datum float8_regr_avgy(PG_FUNCTION_ARGS)
Definition: float.c:3595
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:3633
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:3803
Datum float4smaller(PG_FUNCTION_ARGS)
Definition: float.c:635
Datum float8_regr_accum(PG_FUNCTION_ARGS)
Definition: float.c:3255
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:670
char sign
Definition: informix.c:674
static bool pg_add_s32_overflow(int32 a, int32 b, int32 *result)
Definition: int.h:104
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