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-2022, 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/pg_prng.h"
25 #include "common/shortest_dec.h"
26 #include "libpq/pqformat.h"
27 #include "miscadmin.h"
28 #include "utils/array.h"
29 #include "utils/float.h"
30 #include "utils/fmgrprotos.h"
31 #include "utils/sortsupport.h"
32 #include "utils/timestamp.h"
33 
34 
35 /*
36  * Configurable GUC parameter
37  *
38  * If >0, use shortest-decimal format for output; this is both the default and
39  * allows for compatibility with clients that explicitly set a value here to
40  * get round-trip-accurate results. If 0 or less, then use the old, slow,
41  * decimal rounding method.
42  */
44 
45 /* Cached constants for degree-based trig functions */
46 static bool degree_consts_set = false;
47 static float8 sin_30 = 0;
49 static float8 asin_0_5 = 0;
50 static float8 acos_0_5 = 0;
51 static float8 atan_1_0 = 0;
52 static float8 tan_45 = 0;
53 static float8 cot_45 = 0;
54 
55 /*
56  * These are intentionally not static; don't "fix" them. They will never
57  * be referenced by other files, much less changed; but we don't want the
58  * compiler to know that, else it might try to precompute expressions
59  * involving them. See comments for init_degree_constants().
60  */
66 
67 /* State for drandom() and setseed() */
68 static bool drandom_seed_set = false;
70 
71 /* Local function prototypes */
72 static double sind_q1(double x);
73 static double cosd_q1(double x);
74 static void init_degree_constants(void);
75 
76 
77 /*
78  * We use these out-of-line ereport() calls to report float overflow,
79  * underflow, and zero-divide, because following our usual practice of
80  * repeating them at each call site would lead to a lot of code bloat.
81  *
82  * This does mean that you don't get a useful error location indicator.
83  */
84 pg_noinline void
86 {
87  ereport(ERROR,
88  (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
89  errmsg("value out of range: overflow")));
90 }
91 
92 pg_noinline void
94 {
95  ereport(ERROR,
96  (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
97  errmsg("value out of range: underflow")));
98 }
99 
100 pg_noinline void
102 {
103  ereport(ERROR,
104  (errcode(ERRCODE_DIVISION_BY_ZERO),
105  errmsg("division by zero")));
106 }
107 
108 
109 /*
110  * Returns -1 if 'val' represents negative infinity, 1 if 'val'
111  * represents (positive) infinity, and 0 otherwise. On some platforms,
112  * this is equivalent to the isinf() macro, but not everywhere: C99
113  * does not specify that isinf() needs to distinguish between positive
114  * and negative infinity.
115  */
116 int
118 {
119  int inf = isinf(val);
120 
121  if (inf == 0)
122  return 0;
123  else if (val > 0)
124  return 1;
125  else
126  return -1;
127 }
128 
129 
130 /* ========== USER I/O ROUTINES ========== */
131 
132 
133 /*
134  * float4in - converts "num" to float4
135  *
136  * Note that this code now uses strtof(), where it used to use strtod().
137  *
138  * The motivation for using strtof() is to avoid a double-rounding problem:
139  * for certain decimal inputs, if you round the input correctly to a double,
140  * and then round the double to a float, the result is incorrect in that it
141  * does not match the result of rounding the decimal value to float directly.
142  *
143  * One of the best examples is 7.038531e-26:
144  *
145  * 0xAE43FDp-107 = 7.03853069185120912085...e-26
146  * midpoint 7.03853100000000022281...e-26
147  * 0xAE43FEp-107 = 7.03853130814879132477...e-26
148  *
149  * making 0xAE43FDp-107 the correct float result, but if you do the conversion
150  * via a double, you get
151  *
152  * 0xAE43FD.7FFFFFF8p-107 = 7.03853099999999907487...e-26
153  * midpoint 7.03853099999999964884...e-26
154  * 0xAE43FD.80000000p-107 = 7.03853100000000022281...e-26
155  * 0xAE43FD.80000008p-107 = 7.03853100000000137076...e-26
156  *
157  * so the value rounds to the double exactly on the midpoint between the two
158  * nearest floats, and then rounding again to a float gives the incorrect
159  * result of 0xAE43FEp-107.
160  *
161  */
162 Datum
164 {
165  char *num = PG_GETARG_CSTRING(0);
166  char *orig_num;
167  float val;
168  char *endptr;
169 
170  /*
171  * endptr points to the first character _after_ the sequence we recognized
172  * as a valid floating point number. orig_num points to the original input
173  * string.
174  */
175  orig_num = num;
176 
177  /* skip leading whitespace */
178  while (*num != '\0' && isspace((unsigned char) *num))
179  num++;
180 
181  /*
182  * Check for an empty-string input to begin with, to avoid the vagaries of
183  * strtod() on different platforms.
184  */
185  if (*num == '\0')
186  ereport(ERROR,
187  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
188  errmsg("invalid input syntax for type %s: \"%s\"",
189  "real", orig_num)));
190 
191  errno = 0;
192  val = strtof(num, &endptr);
193 
194  /* did we not see anything that looks like a double? */
195  if (endptr == num || errno != 0)
196  {
197  int save_errno = errno;
198 
199  /*
200  * C99 requires that strtof() accept NaN, [+-]Infinity, and [+-]Inf,
201  * but not all platforms support all of these (and some accept them
202  * but set ERANGE anyway...) Therefore, we check for these inputs
203  * ourselves if strtof() fails.
204  *
205  * Note: C99 also requires hexadecimal input as well as some extended
206  * forms of NaN, but we consider these forms unportable and don't try
207  * to support them. You can use 'em if your strtof() takes 'em.
208  */
209  if (pg_strncasecmp(num, "NaN", 3) == 0)
210  {
211  val = get_float4_nan();
212  endptr = num + 3;
213  }
214  else if (pg_strncasecmp(num, "Infinity", 8) == 0)
215  {
217  endptr = num + 8;
218  }
219  else if (pg_strncasecmp(num, "+Infinity", 9) == 0)
220  {
222  endptr = num + 9;
223  }
224  else if (pg_strncasecmp(num, "-Infinity", 9) == 0)
225  {
227  endptr = num + 9;
228  }
229  else if (pg_strncasecmp(num, "inf", 3) == 0)
230  {
232  endptr = num + 3;
233  }
234  else if (pg_strncasecmp(num, "+inf", 4) == 0)
235  {
237  endptr = num + 4;
238  }
239  else if (pg_strncasecmp(num, "-inf", 4) == 0)
240  {
242  endptr = num + 4;
243  }
244  else if (save_errno == ERANGE)
245  {
246  /*
247  * Some platforms return ERANGE for denormalized numbers (those
248  * that are not zero, but are too close to zero to have full
249  * precision). We'd prefer not to throw error for that, so try to
250  * detect whether it's a "real" out-of-range condition by checking
251  * to see if the result is zero or huge.
252  */
253  if (val == 0.0 ||
254 #if !defined(HUGE_VALF)
255  isinf(val)
256 #else
257  (val >= HUGE_VALF || val <= -HUGE_VALF)
258 #endif
259  )
260  ereport(ERROR,
261  (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
262  errmsg("\"%s\" is out of range for type real",
263  orig_num)));
264  }
265  else
266  ereport(ERROR,
267  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
268  errmsg("invalid input syntax for type %s: \"%s\"",
269  "real", orig_num)));
270  }
271 
272  /* skip trailing whitespace */
273  while (*endptr != '\0' && isspace((unsigned char) *endptr))
274  endptr++;
275 
276  /* if there is any junk left at the end of the string, bail out */
277  if (*endptr != '\0')
278  ereport(ERROR,
279  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
280  errmsg("invalid input syntax for type %s: \"%s\"",
281  "real", orig_num)));
282 
284 }
285 
286 /*
287  * float4out - converts a float4 number to a string
288  * using a standard output format
289  */
290 Datum
292 {
293  float4 num = PG_GETARG_FLOAT4(0);
294  char *ascii = (char *) palloc(32);
295  int ndig = FLT_DIG + extra_float_digits;
296 
297  if (extra_float_digits > 0)
298  {
301  }
302 
303  (void) pg_strfromd(ascii, 32, ndig, num);
305 }
306 
307 /*
308  * float4recv - converts external binary format to float4
309  */
310 Datum
312 {
314 
316 }
317 
318 /*
319  * float4send - converts float4 to binary format
320  */
321 Datum
323 {
324  float4 num = PG_GETARG_FLOAT4(0);
326 
328  pq_sendfloat4(&buf, num);
330 }
331 
332 /*
333  * float8in - converts "num" to float8
334  */
335 Datum
337 {
338  char *num = PG_GETARG_CSTRING(0);
339 
340  PG_RETURN_FLOAT8(float8in_internal(num, NULL, "double precision", num));
341 }
342 
343 /* Convenience macro: set *have_error flag (if provided) or throw error */
344 #define RETURN_ERROR(throw_error, have_error) \
345 do { \
346  if (have_error) { \
347  *have_error = true; \
348  return 0.0; \
349  } else { \
350  throw_error; \
351  } \
352 } while (0)
353 
354 /*
355  * float8in_internal_opt_error - guts of float8in()
356  *
357  * This is exposed for use by functions that want a reasonably
358  * platform-independent way of inputting doubles. The behavior is
359  * essentially like strtod + ereport on error, but note the following
360  * differences:
361  * 1. Both leading and trailing whitespace are skipped.
362  * 2. If endptr_p is NULL, we throw error if there's trailing junk.
363  * Otherwise, it's up to the caller to complain about trailing junk.
364  * 3. In event of a syntax error, the report mentions the given type_name
365  * and prints orig_string as the input; this is meant to support use of
366  * this function with types such as "box" and "point", where what we are
367  * parsing here is just a substring of orig_string.
368  *
369  * "num" could validly be declared "const char *", but that results in an
370  * unreasonable amount of extra casting both here and in callers, so we don't.
371  *
372  * When "*have_error" flag is provided, it's set instead of throwing an
373  * error. This is helpful when caller need to handle errors by itself.
374  */
375 double
376 float8in_internal_opt_error(char *num, char **endptr_p,
377  const char *type_name, const char *orig_string,
378  bool *have_error)
379 {
380  double val;
381  char *endptr;
382 
383  if (have_error)
384  *have_error = false;
385 
386  /* skip leading whitespace */
387  while (*num != '\0' && isspace((unsigned char) *num))
388  num++;
389 
390  /*
391  * Check for an empty-string input to begin with, to avoid the vagaries of
392  * strtod() on different platforms.
393  */
394  if (*num == '\0')
396  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
397  errmsg("invalid input syntax for type %s: \"%s\"",
398  type_name, orig_string))),
399  have_error);
400 
401  errno = 0;
402  val = strtod(num, &endptr);
403 
404  /* did we not see anything that looks like a double? */
405  if (endptr == num || errno != 0)
406  {
407  int save_errno = errno;
408 
409  /*
410  * C99 requires that strtod() accept NaN, [+-]Infinity, and [+-]Inf,
411  * but not all platforms support all of these (and some accept them
412  * but set ERANGE anyway...) Therefore, we check for these inputs
413  * ourselves if strtod() fails.
414  *
415  * Note: C99 also requires hexadecimal input as well as some extended
416  * forms of NaN, but we consider these forms unportable and don't try
417  * to support them. You can use 'em if your strtod() takes 'em.
418  */
419  if (pg_strncasecmp(num, "NaN", 3) == 0)
420  {
421  val = get_float8_nan();
422  endptr = num + 3;
423  }
424  else if (pg_strncasecmp(num, "Infinity", 8) == 0)
425  {
427  endptr = num + 8;
428  }
429  else if (pg_strncasecmp(num, "+Infinity", 9) == 0)
430  {
432  endptr = num + 9;
433  }
434  else if (pg_strncasecmp(num, "-Infinity", 9) == 0)
435  {
437  endptr = num + 9;
438  }
439  else if (pg_strncasecmp(num, "inf", 3) == 0)
440  {
442  endptr = num + 3;
443  }
444  else if (pg_strncasecmp(num, "+inf", 4) == 0)
445  {
447  endptr = num + 4;
448  }
449  else if (pg_strncasecmp(num, "-inf", 4) == 0)
450  {
452  endptr = num + 4;
453  }
454  else if (save_errno == ERANGE)
455  {
456  /*
457  * Some platforms return ERANGE for denormalized numbers (those
458  * that are not zero, but are too close to zero to have full
459  * precision). We'd prefer not to throw error for that, so try to
460  * detect whether it's a "real" out-of-range condition by checking
461  * to see if the result is zero or huge.
462  *
463  * On error, we intentionally complain about double precision not
464  * the given type name, and we print only the part of the string
465  * that is the current number.
466  */
467  if (val == 0.0 || val >= HUGE_VAL || val <= -HUGE_VAL)
468  {
469  char *errnumber = pstrdup(num);
470 
471  errnumber[endptr - num] = '\0';
473  (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
474  errmsg("\"%s\" is out of range for type double precision",
475  errnumber))),
476  have_error);
477  }
478  }
479  else
481  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
482  errmsg("invalid input syntax for type "
483  "%s: \"%s\"",
484  type_name, orig_string))),
485  have_error);
486  }
487 
488  /* skip trailing whitespace */
489  while (*endptr != '\0' && isspace((unsigned char) *endptr))
490  endptr++;
491 
492  /* report stopping point if wanted, else complain if not end of string */
493  if (endptr_p)
494  *endptr_p = endptr;
495  else if (*endptr != '\0')
497  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
498  errmsg("invalid input syntax for type "
499  "%s: \"%s\"",
500  type_name, orig_string))),
501  have_error);
502 
503  return val;
504 }
505 
506 /*
507  * Interface to float8in_internal_opt_error() without "have_error" argument.
508  */
509 double
510 float8in_internal(char *num, char **endptr_p,
511  const char *type_name, const char *orig_string)
512 {
513  return float8in_internal_opt_error(num, endptr_p, type_name,
514  orig_string, NULL);
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 /*
2747  * drandom - returns a random number
2748  */
2749 Datum
2751 {
2752  float8 result;
2753 
2754  /* Initialize random seed, if not done yet in this process */
2755  if (unlikely(!drandom_seed_set))
2756  {
2757  /*
2758  * If possible, initialize the seed using high-quality random bits.
2759  * Should that fail for some reason, we fall back on a lower-quality
2760  * seed based on current time and PID.
2761  */
2763  {
2765  uint64 iseed;
2766 
2767  /* Mix the PID with the most predictable bits of the timestamp */
2768  iseed = (uint64) now ^ ((uint64) MyProcPid << 32);
2769  pg_prng_seed(&drandom_seed, iseed);
2770  }
2771  drandom_seed_set = true;
2772  }
2773 
2774  /* pg_prng_double produces desired result range [0.0 - 1.0) */
2775  result = pg_prng_double(&drandom_seed);
2776 
2777  PG_RETURN_FLOAT8(result);
2778 }
2779 
2780 
2781 /*
2782  * setseed - set seed for the random number generator
2783  */
2784 Datum
2786 {
2787  float8 seed = PG_GETARG_FLOAT8(0);
2788 
2789  if (seed < -1 || seed > 1 || isnan(seed))
2790  ereport(ERROR,
2791  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
2792  errmsg("setseed parameter %g is out of allowed range [-1,1]",
2793  seed)));
2794 
2795  pg_prng_fseed(&drandom_seed, seed);
2796  drandom_seed_set = true;
2797 
2798  PG_RETURN_VOID();
2799 }
2800 
2801 
2802 
2803 /*
2804  * =========================
2805  * FLOAT AGGREGATE OPERATORS
2806  * =========================
2807  *
2808  * float8_accum - accumulate for AVG(), variance aggregates, etc.
2809  * float4_accum - same, but input data is float4
2810  * float8_avg - produce final result for float AVG()
2811  * float8_var_samp - produce final result for float VAR_SAMP()
2812  * float8_var_pop - produce final result for float VAR_POP()
2813  * float8_stddev_samp - produce final result for float STDDEV_SAMP()
2814  * float8_stddev_pop - produce final result for float STDDEV_POP()
2815  *
2816  * The naive schoolbook implementation of these aggregates works by
2817  * accumulating sum(X) and sum(X^2). However, this approach suffers from
2818  * large rounding errors in the final computation of quantities like the
2819  * population variance (N*sum(X^2) - sum(X)^2) / N^2, since each of the
2820  * intermediate terms is potentially very large, while the difference is often
2821  * quite small.
2822  *
2823  * Instead we use the Youngs-Cramer algorithm [1] which works by accumulating
2824  * Sx=sum(X) and Sxx=sum((X-Sx/N)^2), using a numerically stable algorithm to
2825  * incrementally update those quantities. The final computations of each of
2826  * the aggregate values is then trivial and gives more accurate results (for
2827  * example, the population variance is just Sxx/N). This algorithm is also
2828  * fairly easy to generalize to allow parallel execution without loss of
2829  * precision (see, for example, [2]). For more details, and a comparison of
2830  * this with other algorithms, see [3].
2831  *
2832  * The transition datatype for all these aggregates is a 3-element array
2833  * of float8, holding the values N, Sx, Sxx in that order.
2834  *
2835  * Note that we represent N as a float to avoid having to build a special
2836  * datatype. Given a reasonable floating-point implementation, there should
2837  * be no accuracy loss unless N exceeds 2 ^ 52 or so (by which time the
2838  * user will have doubtless lost interest anyway...)
2839  *
2840  * [1] Some Results Relevant to Choice of Sum and Sum-of-Product Algorithms,
2841  * E. A. Youngs and E. M. Cramer, Technometrics Vol 13, No 3, August 1971.
2842  *
2843  * [2] Updating Formulae and a Pairwise Algorithm for Computing Sample
2844  * Variances, T. F. Chan, G. H. Golub & R. J. LeVeque, COMPSTAT 1982.
2845  *
2846  * [3] Numerically Stable Parallel Computation of (Co-)Variance, Erich
2847  * Schubert and Michael Gertz, Proceedings of the 30th International
2848  * Conference on Scientific and Statistical Database Management, 2018.
2849  */
2850 
2851 static float8 *
2852 check_float8_array(ArrayType *transarray, const char *caller, int n)
2853 {
2854  /*
2855  * We expect the input to be an N-element float array; verify that. We
2856  * don't need to use deconstruct_array() since the array data is just
2857  * going to look like a C array of N float8 values.
2858  */
2859  if (ARR_NDIM(transarray) != 1 ||
2860  ARR_DIMS(transarray)[0] != n ||
2861  ARR_HASNULL(transarray) ||
2862  ARR_ELEMTYPE(transarray) != FLOAT8OID)
2863  elog(ERROR, "%s: expected %d-element float8 array", caller, n);
2864  return (float8 *) ARR_DATA_PTR(transarray);
2865 }
2866 
2867 /*
2868  * float8_combine
2869  *
2870  * An aggregate combine function used to combine two 3 fields
2871  * aggregate transition data into a single transition data.
2872  * This function is used only in two stage aggregation and
2873  * shouldn't be called outside aggregate context.
2874  */
2875 Datum
2877 {
2878  ArrayType *transarray1 = PG_GETARG_ARRAYTYPE_P(0);
2879  ArrayType *transarray2 = PG_GETARG_ARRAYTYPE_P(1);
2880  float8 *transvalues1;
2881  float8 *transvalues2;
2882  float8 N1,
2883  Sx1,
2884  Sxx1,
2885  N2,
2886  Sx2,
2887  Sxx2,
2888  tmp,
2889  N,
2890  Sx,
2891  Sxx;
2892 
2893  transvalues1 = check_float8_array(transarray1, "float8_combine", 3);
2894  transvalues2 = check_float8_array(transarray2, "float8_combine", 3);
2895 
2896  N1 = transvalues1[0];
2897  Sx1 = transvalues1[1];
2898  Sxx1 = transvalues1[2];
2899 
2900  N2 = transvalues2[0];
2901  Sx2 = transvalues2[1];
2902  Sxx2 = transvalues2[2];
2903 
2904  /*--------------------
2905  * The transition values combine using a generalization of the
2906  * Youngs-Cramer algorithm as follows:
2907  *
2908  * N = N1 + N2
2909  * Sx = Sx1 + Sx2
2910  * Sxx = Sxx1 + Sxx2 + N1 * N2 * (Sx1/N1 - Sx2/N2)^2 / N;
2911  *
2912  * It's worth handling the special cases N1 = 0 and N2 = 0 separately
2913  * since those cases are trivial, and we then don't need to worry about
2914  * division-by-zero errors in the general case.
2915  *--------------------
2916  */
2917  if (N1 == 0.0)
2918  {
2919  N = N2;
2920  Sx = Sx2;
2921  Sxx = Sxx2;
2922  }
2923  else if (N2 == 0.0)
2924  {
2925  N = N1;
2926  Sx = Sx1;
2927  Sxx = Sxx1;
2928  }
2929  else
2930  {
2931  N = N1 + N2;
2932  Sx = float8_pl(Sx1, Sx2);
2933  tmp = Sx1 / N1 - Sx2 / N2;
2934  Sxx = Sxx1 + Sxx2 + N1 * N2 * tmp * tmp / N;
2935  if (unlikely(isinf(Sxx)) && !isinf(Sxx1) && !isinf(Sxx2))
2937  }
2938 
2939  /*
2940  * If we're invoked as an aggregate, we can cheat and modify our first
2941  * parameter in-place to reduce palloc overhead. Otherwise we construct a
2942  * new array with the updated transition data and return it.
2943  */
2944  if (AggCheckCallContext(fcinfo, NULL))
2945  {
2946  transvalues1[0] = N;
2947  transvalues1[1] = Sx;
2948  transvalues1[2] = Sxx;
2949 
2950  PG_RETURN_ARRAYTYPE_P(transarray1);
2951  }
2952  else
2953  {
2954  Datum transdatums[3];
2955  ArrayType *result;
2956 
2957  transdatums[0] = Float8GetDatumFast(N);
2958  transdatums[1] = Float8GetDatumFast(Sx);
2959  transdatums[2] = Float8GetDatumFast(Sxx);
2960 
2961  result = construct_array(transdatums, 3,
2962  FLOAT8OID,
2963  sizeof(float8), FLOAT8PASSBYVAL, TYPALIGN_DOUBLE);
2964 
2965  PG_RETURN_ARRAYTYPE_P(result);
2966  }
2967 }
2968 
2969 Datum
2971 {
2972  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
2974  float8 *transvalues;
2975  float8 N,
2976  Sx,
2977  Sxx,
2978  tmp;
2979 
2980  transvalues = check_float8_array(transarray, "float8_accum", 3);
2981  N = transvalues[0];
2982  Sx = transvalues[1];
2983  Sxx = transvalues[2];
2984 
2985  /*
2986  * Use the Youngs-Cramer algorithm to incorporate the new value into the
2987  * transition values.
2988  */
2989  N += 1.0;
2990  Sx += newval;
2991  if (transvalues[0] > 0.0)
2992  {
2993  tmp = newval * N - Sx;
2994  Sxx += tmp * tmp / (N * transvalues[0]);
2995 
2996  /*
2997  * Overflow check. We only report an overflow error when finite
2998  * inputs lead to infinite results. Note also that Sxx should be NaN
2999  * if any of the inputs are infinite, so we intentionally prevent Sxx
3000  * from becoming infinite.
3001  */
3002  if (isinf(Sx) || isinf(Sxx))
3003  {
3004  if (!isinf(transvalues[1]) && !isinf(newval))
3006 
3007  Sxx = get_float8_nan();
3008  }
3009  }
3010  else
3011  {
3012  /*
3013  * At the first input, we normally can leave Sxx as 0. However, if
3014  * the first input is Inf or NaN, we'd better force Sxx to NaN;
3015  * otherwise we will falsely report variance zero when there are no
3016  * more inputs.
3017  */
3018  if (isnan(newval) || isinf(newval))
3019  Sxx = get_float8_nan();
3020  }
3021 
3022  /*
3023  * If we're invoked as an aggregate, we can cheat and modify our first
3024  * parameter in-place to reduce palloc overhead. Otherwise we construct a
3025  * new array with the updated transition data and return it.
3026  */
3027  if (AggCheckCallContext(fcinfo, NULL))
3028  {
3029  transvalues[0] = N;
3030  transvalues[1] = Sx;
3031  transvalues[2] = Sxx;
3032 
3033  PG_RETURN_ARRAYTYPE_P(transarray);
3034  }
3035  else
3036  {
3037  Datum transdatums[3];
3038  ArrayType *result;
3039 
3040  transdatums[0] = Float8GetDatumFast(N);
3041  transdatums[1] = Float8GetDatumFast(Sx);
3042  transdatums[2] = Float8GetDatumFast(Sxx);
3043 
3044  result = construct_array(transdatums, 3,
3045  FLOAT8OID,
3046  sizeof(float8), FLOAT8PASSBYVAL, TYPALIGN_DOUBLE);
3047 
3048  PG_RETURN_ARRAYTYPE_P(result);
3049  }
3050 }
3051 
3052 Datum
3054 {
3055  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3056 
3057  /* do computations as float8 */
3059  float8 *transvalues;
3060  float8 N,
3061  Sx,
3062  Sxx,
3063  tmp;
3064 
3065  transvalues = check_float8_array(transarray, "float4_accum", 3);
3066  N = transvalues[0];
3067  Sx = transvalues[1];
3068  Sxx = transvalues[2];
3069 
3070  /*
3071  * Use the Youngs-Cramer algorithm to incorporate the new value into the
3072  * transition values.
3073  */
3074  N += 1.0;
3075  Sx += newval;
3076  if (transvalues[0] > 0.0)
3077  {
3078  tmp = newval * N - Sx;
3079  Sxx += tmp * tmp / (N * transvalues[0]);
3080 
3081  /*
3082  * Overflow check. We only report an overflow error when finite
3083  * inputs lead to infinite results. Note also that Sxx should be NaN
3084  * if any of the inputs are infinite, so we intentionally prevent Sxx
3085  * from becoming infinite.
3086  */
3087  if (isinf(Sx) || isinf(Sxx))
3088  {
3089  if (!isinf(transvalues[1]) && !isinf(newval))
3091 
3092  Sxx = get_float8_nan();
3093  }
3094  }
3095  else
3096  {
3097  /*
3098  * At the first input, we normally can leave Sxx as 0. However, if
3099  * the first input is Inf or NaN, we'd better force Sxx to NaN;
3100  * otherwise we will falsely report variance zero when there are no
3101  * more inputs.
3102  */
3103  if (isnan(newval) || isinf(newval))
3104  Sxx = get_float8_nan();
3105  }
3106 
3107  /*
3108  * If we're invoked as an aggregate, we can cheat and modify our first
3109  * parameter in-place to reduce palloc overhead. Otherwise we construct a
3110  * new array with the updated transition data and return it.
3111  */
3112  if (AggCheckCallContext(fcinfo, NULL))
3113  {
3114  transvalues[0] = N;
3115  transvalues[1] = Sx;
3116  transvalues[2] = Sxx;
3117 
3118  PG_RETURN_ARRAYTYPE_P(transarray);
3119  }
3120  else
3121  {
3122  Datum transdatums[3];
3123  ArrayType *result;
3124 
3125  transdatums[0] = Float8GetDatumFast(N);
3126  transdatums[1] = Float8GetDatumFast(Sx);
3127  transdatums[2] = Float8GetDatumFast(Sxx);
3128 
3129  result = construct_array(transdatums, 3,
3130  FLOAT8OID,
3131  sizeof(float8), FLOAT8PASSBYVAL, TYPALIGN_DOUBLE);
3132 
3133  PG_RETURN_ARRAYTYPE_P(result);
3134  }
3135 }
3136 
3137 Datum
3139 {
3140  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3141  float8 *transvalues;
3142  float8 N,
3143  Sx;
3144 
3145  transvalues = check_float8_array(transarray, "float8_avg", 3);
3146  N = transvalues[0];
3147  Sx = transvalues[1];
3148  /* ignore Sxx */
3149 
3150  /* SQL defines AVG of no values to be NULL */
3151  if (N == 0.0)
3152  PG_RETURN_NULL();
3153 
3154  PG_RETURN_FLOAT8(Sx / N);
3155 }
3156 
3157 Datum
3159 {
3160  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3161  float8 *transvalues;
3162  float8 N,
3163  Sxx;
3164 
3165  transvalues = check_float8_array(transarray, "float8_var_pop", 3);
3166  N = transvalues[0];
3167  /* ignore Sx */
3168  Sxx = transvalues[2];
3169 
3170  /* Population variance is undefined when N is 0, so return NULL */
3171  if (N == 0.0)
3172  PG_RETURN_NULL();
3173 
3174  /* Note that Sxx is guaranteed to be non-negative */
3175 
3176  PG_RETURN_FLOAT8(Sxx / N);
3177 }
3178 
3179 Datum
3181 {
3182  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3183  float8 *transvalues;
3184  float8 N,
3185  Sxx;
3186 
3187  transvalues = check_float8_array(transarray, "float8_var_samp", 3);
3188  N = transvalues[0];
3189  /* ignore Sx */
3190  Sxx = transvalues[2];
3191 
3192  /* Sample variance is undefined when N is 0 or 1, so return NULL */
3193  if (N <= 1.0)
3194  PG_RETURN_NULL();
3195 
3196  /* Note that Sxx is guaranteed to be non-negative */
3197 
3198  PG_RETURN_FLOAT8(Sxx / (N - 1.0));
3199 }
3200 
3201 Datum
3203 {
3204  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3205  float8 *transvalues;
3206  float8 N,
3207  Sxx;
3208 
3209  transvalues = check_float8_array(transarray, "float8_stddev_pop", 3);
3210  N = transvalues[0];
3211  /* ignore Sx */
3212  Sxx = transvalues[2];
3213 
3214  /* Population stddev is undefined when N is 0, so return NULL */
3215  if (N == 0.0)
3216  PG_RETURN_NULL();
3217 
3218  /* Note that Sxx is guaranteed to be non-negative */
3219 
3220  PG_RETURN_FLOAT8(sqrt(Sxx / N));
3221 }
3222 
3223 Datum
3225 {
3226  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3227  float8 *transvalues;
3228  float8 N,
3229  Sxx;
3230 
3231  transvalues = check_float8_array(transarray, "float8_stddev_samp", 3);
3232  N = transvalues[0];
3233  /* ignore Sx */
3234  Sxx = transvalues[2];
3235 
3236  /* Sample stddev is undefined when N is 0 or 1, so return NULL */
3237  if (N <= 1.0)
3238  PG_RETURN_NULL();
3239 
3240  /* Note that Sxx is guaranteed to be non-negative */
3241 
3242  PG_RETURN_FLOAT8(sqrt(Sxx / (N - 1.0)));
3243 }
3244 
3245 /*
3246  * =========================
3247  * SQL2003 BINARY AGGREGATES
3248  * =========================
3249  *
3250  * As with the preceding aggregates, we use the Youngs-Cramer algorithm to
3251  * reduce rounding errors in the aggregate final functions.
3252  *
3253  * The transition datatype for all these aggregates is a 6-element array of
3254  * float8, holding the values N, Sx=sum(X), Sxx=sum((X-Sx/N)^2), Sy=sum(Y),
3255  * Syy=sum((Y-Sy/N)^2), Sxy=sum((X-Sx/N)*(Y-Sy/N)) in that order.
3256  *
3257  * Note that Y is the first argument to all these aggregates!
3258  *
3259  * It might seem attractive to optimize this by having multiple accumulator
3260  * functions that only calculate the sums actually needed. But on most
3261  * modern machines, a couple of extra floating-point multiplies will be
3262  * insignificant compared to the other per-tuple overhead, so I've chosen
3263  * to minimize code space instead.
3264  */
3265 
3266 Datum
3268 {
3269  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3270  float8 newvalY = PG_GETARG_FLOAT8(1);
3271  float8 newvalX = PG_GETARG_FLOAT8(2);
3272  float8 *transvalues;
3273  float8 N,
3274  Sx,
3275  Sxx,
3276  Sy,
3277  Syy,
3278  Sxy,
3279  tmpX,
3280  tmpY,
3281  scale;
3282 
3283  transvalues = check_float8_array(transarray, "float8_regr_accum", 6);
3284  N = transvalues[0];
3285  Sx = transvalues[1];
3286  Sxx = transvalues[2];
3287  Sy = transvalues[3];
3288  Syy = transvalues[4];
3289  Sxy = transvalues[5];
3290 
3291  /*
3292  * Use the Youngs-Cramer algorithm to incorporate the new values into the
3293  * transition values.
3294  */
3295  N += 1.0;
3296  Sx += newvalX;
3297  Sy += newvalY;
3298  if (transvalues[0] > 0.0)
3299  {
3300  tmpX = newvalX * N - Sx;
3301  tmpY = newvalY * N - Sy;
3302  scale = 1.0 / (N * transvalues[0]);
3303  Sxx += tmpX * tmpX * scale;
3304  Syy += tmpY * tmpY * scale;
3305  Sxy += tmpX * tmpY * scale;
3306 
3307  /*
3308  * Overflow check. We only report an overflow error when finite
3309  * inputs lead to infinite results. Note also that Sxx, Syy and Sxy
3310  * should be NaN if any of the relevant inputs are infinite, so we
3311  * intentionally prevent them from becoming infinite.
3312  */
3313  if (isinf(Sx) || isinf(Sxx) || isinf(Sy) || isinf(Syy) || isinf(Sxy))
3314  {
3315  if (((isinf(Sx) || isinf(Sxx)) &&
3316  !isinf(transvalues[1]) && !isinf(newvalX)) ||
3317  ((isinf(Sy) || isinf(Syy)) &&
3318  !isinf(transvalues[3]) && !isinf(newvalY)) ||
3319  (isinf(Sxy) &&
3320  !isinf(transvalues[1]) && !isinf(newvalX) &&
3321  !isinf(transvalues[3]) && !isinf(newvalY)))
3323 
3324  if (isinf(Sxx))
3325  Sxx = get_float8_nan();
3326  if (isinf(Syy))
3327  Syy = get_float8_nan();
3328  if (isinf(Sxy))
3329  Sxy = get_float8_nan();
3330  }
3331  }
3332  else
3333  {
3334  /*
3335  * At the first input, we normally can leave Sxx et al as 0. However,
3336  * if the first input is Inf or NaN, we'd better force the dependent
3337  * sums to NaN; otherwise we will falsely report variance zero when
3338  * there are no more inputs.
3339  */
3340  if (isnan(newvalX) || isinf(newvalX))
3341  Sxx = Sxy = get_float8_nan();
3342  if (isnan(newvalY) || isinf(newvalY))
3343  Syy = Sxy = get_float8_nan();
3344  }
3345 
3346  /*
3347  * If we're invoked as an aggregate, we can cheat and modify our first
3348  * parameter in-place to reduce palloc overhead. Otherwise we construct a
3349  * new array with the updated transition data and return it.
3350  */
3351  if (AggCheckCallContext(fcinfo, NULL))
3352  {
3353  transvalues[0] = N;
3354  transvalues[1] = Sx;
3355  transvalues[2] = Sxx;
3356  transvalues[3] = Sy;
3357  transvalues[4] = Syy;
3358  transvalues[5] = Sxy;
3359 
3360  PG_RETURN_ARRAYTYPE_P(transarray);
3361  }
3362  else
3363  {
3364  Datum transdatums[6];
3365  ArrayType *result;
3366 
3367  transdatums[0] = Float8GetDatumFast(N);
3368  transdatums[1] = Float8GetDatumFast(Sx);
3369  transdatums[2] = Float8GetDatumFast(Sxx);
3370  transdatums[3] = Float8GetDatumFast(Sy);
3371  transdatums[4] = Float8GetDatumFast(Syy);
3372  transdatums[5] = Float8GetDatumFast(Sxy);
3373 
3374  result = construct_array(transdatums, 6,
3375  FLOAT8OID,
3376  sizeof(float8), FLOAT8PASSBYVAL, TYPALIGN_DOUBLE);
3377 
3378  PG_RETURN_ARRAYTYPE_P(result);
3379  }
3380 }
3381 
3382 /*
3383  * float8_regr_combine
3384  *
3385  * An aggregate combine function used to combine two 6 fields
3386  * aggregate transition data into a single transition data.
3387  * This function is used only in two stage aggregation and
3388  * shouldn't be called outside aggregate context.
3389  */
3390 Datum
3392 {
3393  ArrayType *transarray1 = PG_GETARG_ARRAYTYPE_P(0);
3394  ArrayType *transarray2 = PG_GETARG_ARRAYTYPE_P(1);
3395  float8 *transvalues1;
3396  float8 *transvalues2;
3397  float8 N1,
3398  Sx1,
3399  Sxx1,
3400  Sy1,
3401  Syy1,
3402  Sxy1,
3403  N2,
3404  Sx2,
3405  Sxx2,
3406  Sy2,
3407  Syy2,
3408  Sxy2,
3409  tmp1,
3410  tmp2,
3411  N,
3412  Sx,
3413  Sxx,
3414  Sy,
3415  Syy,
3416  Sxy;
3417 
3418  transvalues1 = check_float8_array(transarray1, "float8_regr_combine", 6);
3419  transvalues2 = check_float8_array(transarray2, "float8_regr_combine", 6);
3420 
3421  N1 = transvalues1[0];
3422  Sx1 = transvalues1[1];
3423  Sxx1 = transvalues1[2];
3424  Sy1 = transvalues1[3];
3425  Syy1 = transvalues1[4];
3426  Sxy1 = transvalues1[5];
3427 
3428  N2 = transvalues2[0];
3429  Sx2 = transvalues2[1];
3430  Sxx2 = transvalues2[2];
3431  Sy2 = transvalues2[3];
3432  Syy2 = transvalues2[4];
3433  Sxy2 = transvalues2[5];
3434 
3435  /*--------------------
3436  * The transition values combine using a generalization of the
3437  * Youngs-Cramer algorithm as follows:
3438  *
3439  * N = N1 + N2
3440  * Sx = Sx1 + Sx2
3441  * Sxx = Sxx1 + Sxx2 + N1 * N2 * (Sx1/N1 - Sx2/N2)^2 / N
3442  * Sy = Sy1 + Sy2
3443  * Syy = Syy1 + Syy2 + N1 * N2 * (Sy1/N1 - Sy2/N2)^2 / N
3444  * Sxy = Sxy1 + Sxy2 + N1 * N2 * (Sx1/N1 - Sx2/N2) * (Sy1/N1 - Sy2/N2) / N
3445  *
3446  * It's worth handling the special cases N1 = 0 and N2 = 0 separately
3447  * since those cases are trivial, and we then don't need to worry about
3448  * division-by-zero errors in the general case.
3449  *--------------------
3450  */
3451  if (N1 == 0.0)
3452  {
3453  N = N2;
3454  Sx = Sx2;
3455  Sxx = Sxx2;
3456  Sy = Sy2;
3457  Syy = Syy2;
3458  Sxy = Sxy2;
3459  }
3460  else if (N2 == 0.0)
3461  {
3462  N = N1;
3463  Sx = Sx1;
3464  Sxx = Sxx1;
3465  Sy = Sy1;
3466  Syy = Syy1;
3467  Sxy = Sxy1;
3468  }
3469  else
3470  {
3471  N = N1 + N2;
3472  Sx = float8_pl(Sx1, Sx2);
3473  tmp1 = Sx1 / N1 - Sx2 / N2;
3474  Sxx = Sxx1 + Sxx2 + N1 * N2 * tmp1 * tmp1 / N;
3475  if (unlikely(isinf(Sxx)) && !isinf(Sxx1) && !isinf(Sxx2))
3477  Sy = float8_pl(Sy1, Sy2);
3478  tmp2 = Sy1 / N1 - Sy2 / N2;
3479  Syy = Syy1 + Syy2 + N1 * N2 * tmp2 * tmp2 / N;
3480  if (unlikely(isinf(Syy)) && !isinf(Syy1) && !isinf(Syy2))
3482  Sxy = Sxy1 + Sxy2 + N1 * N2 * tmp1 * tmp2 / N;
3483  if (unlikely(isinf(Sxy)) && !isinf(Sxy1) && !isinf(Sxy2))
3485  }
3486 
3487  /*
3488  * If we're invoked as an aggregate, we can cheat and modify our first
3489  * parameter in-place to reduce palloc overhead. Otherwise we construct a
3490  * new array with the updated transition data and return it.
3491  */
3492  if (AggCheckCallContext(fcinfo, NULL))
3493  {
3494  transvalues1[0] = N;
3495  transvalues1[1] = Sx;
3496  transvalues1[2] = Sxx;
3497  transvalues1[3] = Sy;
3498  transvalues1[4] = Syy;
3499  transvalues1[5] = Sxy;
3500 
3501  PG_RETURN_ARRAYTYPE_P(transarray1);
3502  }
3503  else
3504  {
3505  Datum transdatums[6];
3506  ArrayType *result;
3507 
3508  transdatums[0] = Float8GetDatumFast(N);
3509  transdatums[1] = Float8GetDatumFast(Sx);
3510  transdatums[2] = Float8GetDatumFast(Sxx);
3511  transdatums[3] = Float8GetDatumFast(Sy);
3512  transdatums[4] = Float8GetDatumFast(Syy);
3513  transdatums[5] = Float8GetDatumFast(Sxy);
3514 
3515  result = construct_array(transdatums, 6,
3516  FLOAT8OID,
3517  sizeof(float8), FLOAT8PASSBYVAL, TYPALIGN_DOUBLE);
3518 
3519  PG_RETURN_ARRAYTYPE_P(result);
3520  }
3521 }
3522 
3523 
3524 Datum
3526 {
3527  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3528  float8 *transvalues;
3529  float8 N,
3530  Sxx;
3531 
3532  transvalues = check_float8_array(transarray, "float8_regr_sxx", 6);
3533  N = transvalues[0];
3534  Sxx = transvalues[2];
3535 
3536  /* if N is 0 we should return NULL */
3537  if (N < 1.0)
3538  PG_RETURN_NULL();
3539 
3540  /* Note that Sxx is guaranteed to be non-negative */
3541 
3542  PG_RETURN_FLOAT8(Sxx);
3543 }
3544 
3545 Datum
3547 {
3548  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3549  float8 *transvalues;
3550  float8 N,
3551  Syy;
3552 
3553  transvalues = check_float8_array(transarray, "float8_regr_syy", 6);
3554  N = transvalues[0];
3555  Syy = transvalues[4];
3556 
3557  /* if N is 0 we should return NULL */
3558  if (N < 1.0)
3559  PG_RETURN_NULL();
3560 
3561  /* Note that Syy is guaranteed to be non-negative */
3562 
3563  PG_RETURN_FLOAT8(Syy);
3564 }
3565 
3566 Datum
3568 {
3569  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3570  float8 *transvalues;
3571  float8 N,
3572  Sxy;
3573 
3574  transvalues = check_float8_array(transarray, "float8_regr_sxy", 6);
3575  N = transvalues[0];
3576  Sxy = transvalues[5];
3577 
3578  /* if N is 0 we should return NULL */
3579  if (N < 1.0)
3580  PG_RETURN_NULL();
3581 
3582  /* A negative result is valid here */
3583 
3584  PG_RETURN_FLOAT8(Sxy);
3585 }
3586 
3587 Datum
3589 {
3590  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3591  float8 *transvalues;
3592  float8 N,
3593  Sx;
3594 
3595  transvalues = check_float8_array(transarray, "float8_regr_avgx", 6);
3596  N = transvalues[0];
3597  Sx = transvalues[1];
3598 
3599  /* if N is 0 we should return NULL */
3600  if (N < 1.0)
3601  PG_RETURN_NULL();
3602 
3603  PG_RETURN_FLOAT8(Sx / N);
3604 }
3605 
3606 Datum
3608 {
3609  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3610  float8 *transvalues;
3611  float8 N,
3612  Sy;
3613 
3614  transvalues = check_float8_array(transarray, "float8_regr_avgy", 6);
3615  N = transvalues[0];
3616  Sy = transvalues[3];
3617 
3618  /* if N is 0 we should return NULL */
3619  if (N < 1.0)
3620  PG_RETURN_NULL();
3621 
3622  PG_RETURN_FLOAT8(Sy / N);
3623 }
3624 
3625 Datum
3627 {
3628  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3629  float8 *transvalues;
3630  float8 N,
3631  Sxy;
3632 
3633  transvalues = check_float8_array(transarray, "float8_covar_pop", 6);
3634  N = transvalues[0];
3635  Sxy = transvalues[5];
3636 
3637  /* if N is 0 we should return NULL */
3638  if (N < 1.0)
3639  PG_RETURN_NULL();
3640 
3641  PG_RETURN_FLOAT8(Sxy / N);
3642 }
3643 
3644 Datum
3646 {
3647  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3648  float8 *transvalues;
3649  float8 N,
3650  Sxy;
3651 
3652  transvalues = check_float8_array(transarray, "float8_covar_samp", 6);
3653  N = transvalues[0];
3654  Sxy = transvalues[5];
3655 
3656  /* if N is <= 1 we should return NULL */
3657  if (N < 2.0)
3658  PG_RETURN_NULL();
3659 
3660  PG_RETURN_FLOAT8(Sxy / (N - 1.0));
3661 }
3662 
3663 Datum
3665 {
3666  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3667  float8 *transvalues;
3668  float8 N,
3669  Sxx,
3670  Syy,
3671  Sxy;
3672 
3673  transvalues = check_float8_array(transarray, "float8_corr", 6);
3674  N = transvalues[0];
3675  Sxx = transvalues[2];
3676  Syy = transvalues[4];
3677  Sxy = transvalues[5];
3678 
3679  /* if N is 0 we should return NULL */
3680  if (N < 1.0)
3681  PG_RETURN_NULL();
3682 
3683  /* Note that Sxx and Syy are guaranteed to be non-negative */
3684 
3685  /* per spec, return NULL for horizontal and vertical lines */
3686  if (Sxx == 0 || Syy == 0)
3687  PG_RETURN_NULL();
3688 
3689  PG_RETURN_FLOAT8(Sxy / sqrt(Sxx * Syy));
3690 }
3691 
3692 Datum
3694 {
3695  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3696  float8 *transvalues;
3697  float8 N,
3698  Sxx,
3699  Syy,
3700  Sxy;
3701 
3702  transvalues = check_float8_array(transarray, "float8_regr_r2", 6);
3703  N = transvalues[0];
3704  Sxx = transvalues[2];
3705  Syy = transvalues[4];
3706  Sxy = transvalues[5];
3707 
3708  /* if N is 0 we should return NULL */
3709  if (N < 1.0)
3710  PG_RETURN_NULL();
3711 
3712  /* Note that Sxx and Syy are guaranteed to be non-negative */
3713 
3714  /* per spec, return NULL for a vertical line */
3715  if (Sxx == 0)
3716  PG_RETURN_NULL();
3717 
3718  /* per spec, return 1.0 for a horizontal line */
3719  if (Syy == 0)
3720  PG_RETURN_FLOAT8(1.0);
3721 
3722  PG_RETURN_FLOAT8((Sxy * Sxy) / (Sxx * Syy));
3723 }
3724 
3725 Datum
3727 {
3728  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3729  float8 *transvalues;
3730  float8 N,
3731  Sxx,
3732  Sxy;
3733 
3734  transvalues = check_float8_array(transarray, "float8_regr_slope", 6);
3735  N = transvalues[0];
3736  Sxx = transvalues[2];
3737  Sxy = transvalues[5];
3738 
3739  /* if N is 0 we should return NULL */
3740  if (N < 1.0)
3741  PG_RETURN_NULL();
3742 
3743  /* Note that Sxx is guaranteed to be non-negative */
3744 
3745  /* per spec, return NULL for a vertical line */
3746  if (Sxx == 0)
3747  PG_RETURN_NULL();
3748 
3749  PG_RETURN_FLOAT8(Sxy / Sxx);
3750 }
3751 
3752 Datum
3754 {
3755  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3756  float8 *transvalues;
3757  float8 N,
3758  Sx,
3759  Sxx,
3760  Sy,
3761  Sxy;
3762 
3763  transvalues = check_float8_array(transarray, "float8_regr_intercept", 6);
3764  N = transvalues[0];
3765  Sx = transvalues[1];
3766  Sxx = transvalues[2];
3767  Sy = transvalues[3];
3768  Sxy = transvalues[5];
3769 
3770  /* if N is 0 we should return NULL */
3771  if (N < 1.0)
3772  PG_RETURN_NULL();
3773 
3774  /* Note that Sxx is guaranteed to be non-negative */
3775 
3776  /* per spec, return NULL for a vertical line */
3777  if (Sxx == 0)
3778  PG_RETURN_NULL();
3779 
3780  PG_RETURN_FLOAT8((Sy - Sx * Sxy / Sxx) / N);
3781 }
3782 
3783 
3784 /*
3785  * ====================================
3786  * MIXED-PRECISION ARITHMETIC OPERATORS
3787  * ====================================
3788  */
3789 
3790 /*
3791  * float48pl - returns arg1 + arg2
3792  * float48mi - returns arg1 - arg2
3793  * float48mul - returns arg1 * arg2
3794  * float48div - returns arg1 / arg2
3795  */
3796 Datum
3798 {
3799  float4 arg1 = PG_GETARG_FLOAT4(0);
3800  float8 arg2 = PG_GETARG_FLOAT8(1);
3801 
3802  PG_RETURN_FLOAT8(float8_pl((float8) arg1, arg2));
3803 }
3804 
3805 Datum
3807 {
3808  float4 arg1 = PG_GETARG_FLOAT4(0);
3809  float8 arg2 = PG_GETARG_FLOAT8(1);
3810 
3811  PG_RETURN_FLOAT8(float8_mi((float8) arg1, arg2));
3812 }
3813 
3814 Datum
3816 {
3817  float4 arg1 = PG_GETARG_FLOAT4(0);
3818  float8 arg2 = PG_GETARG_FLOAT8(1);
3819 
3820  PG_RETURN_FLOAT8(float8_mul((float8) arg1, arg2));
3821 }
3822 
3823 Datum
3825 {
3826  float4 arg1 = PG_GETARG_FLOAT4(0);
3827  float8 arg2 = PG_GETARG_FLOAT8(1);
3828 
3829  PG_RETURN_FLOAT8(float8_div((float8) arg1, arg2));
3830 }
3831 
3832 /*
3833  * float84pl - returns arg1 + arg2
3834  * float84mi - returns arg1 - arg2
3835  * float84mul - returns arg1 * arg2
3836  * float84div - returns arg1 / arg2
3837  */
3838 Datum
3840 {
3841  float8 arg1 = PG_GETARG_FLOAT8(0);
3842  float4 arg2 = PG_GETARG_FLOAT4(1);
3843 
3844  PG_RETURN_FLOAT8(float8_pl(arg1, (float8) arg2));
3845 }
3846 
3847 Datum
3849 {
3850  float8 arg1 = PG_GETARG_FLOAT8(0);
3851  float4 arg2 = PG_GETARG_FLOAT4(1);
3852 
3853  PG_RETURN_FLOAT8(float8_mi(arg1, (float8) arg2));
3854 }
3855 
3856 Datum
3858 {
3859  float8 arg1 = PG_GETARG_FLOAT8(0);
3860  float4 arg2 = PG_GETARG_FLOAT4(1);
3861 
3862  PG_RETURN_FLOAT8(float8_mul(arg1, (float8) arg2));
3863 }
3864 
3865 Datum
3867 {
3868  float8 arg1 = PG_GETARG_FLOAT8(0);
3869  float4 arg2 = PG_GETARG_FLOAT4(1);
3870 
3871  PG_RETURN_FLOAT8(float8_div(arg1, (float8) arg2));
3872 }
3873 
3874 /*
3875  * ====================
3876  * COMPARISON OPERATORS
3877  * ====================
3878  */
3879 
3880 /*
3881  * float48{eq,ne,lt,le,gt,ge} - float4/float8 comparison operations
3882  */
3883 Datum
3885 {
3886  float4 arg1 = PG_GETARG_FLOAT4(0);
3887  float8 arg2 = PG_GETARG_FLOAT8(1);
3888 
3889  PG_RETURN_BOOL(float8_eq((float8) arg1, arg2));
3890 }
3891 
3892 Datum
3894 {
3895  float4 arg1 = PG_GETARG_FLOAT4(0);
3896  float8 arg2 = PG_GETARG_FLOAT8(1);
3897 
3898  PG_RETURN_BOOL(float8_ne((float8) arg1, arg2));
3899 }
3900 
3901 Datum
3903 {
3904  float4 arg1 = PG_GETARG_FLOAT4(0);
3905  float8 arg2 = PG_GETARG_FLOAT8(1);
3906 
3907  PG_RETURN_BOOL(float8_lt((float8) arg1, arg2));
3908 }
3909 
3910 Datum
3912 {
3913  float4 arg1 = PG_GETARG_FLOAT4(0);
3914  float8 arg2 = PG_GETARG_FLOAT8(1);
3915 
3916  PG_RETURN_BOOL(float8_le((float8) arg1, arg2));
3917 }
3918 
3919 Datum
3921 {
3922  float4 arg1 = PG_GETARG_FLOAT4(0);
3923  float8 arg2 = PG_GETARG_FLOAT8(1);
3924 
3925  PG_RETURN_BOOL(float8_gt((float8) arg1, arg2));
3926 }
3927 
3928 Datum
3930 {
3931  float4 arg1 = PG_GETARG_FLOAT4(0);
3932  float8 arg2 = PG_GETARG_FLOAT8(1);
3933 
3934  PG_RETURN_BOOL(float8_ge((float8) arg1, arg2));
3935 }
3936 
3937 /*
3938  * float84{eq,ne,lt,le,gt,ge} - float8/float4 comparison operations
3939  */
3940 Datum
3942 {
3943  float8 arg1 = PG_GETARG_FLOAT8(0);
3944  float4 arg2 = PG_GETARG_FLOAT4(1);
3945 
3946  PG_RETURN_BOOL(float8_eq(arg1, (float8) arg2));
3947 }
3948 
3949 Datum
3951 {
3952  float8 arg1 = PG_GETARG_FLOAT8(0);
3953  float4 arg2 = PG_GETARG_FLOAT4(1);
3954 
3955  PG_RETURN_BOOL(float8_ne(arg1, (float8) arg2));
3956 }
3957 
3958 Datum
3960 {
3961  float8 arg1 = PG_GETARG_FLOAT8(0);
3962  float4 arg2 = PG_GETARG_FLOAT4(1);
3963 
3964  PG_RETURN_BOOL(float8_lt(arg1, (float8) arg2));
3965 }
3966 
3967 Datum
3969 {
3970  float8 arg1 = PG_GETARG_FLOAT8(0);
3971  float4 arg2 = PG_GETARG_FLOAT4(1);
3972 
3973  PG_RETURN_BOOL(float8_le(arg1, (float8) arg2));
3974 }
3975 
3976 Datum
3978 {
3979  float8 arg1 = PG_GETARG_FLOAT8(0);
3980  float4 arg2 = PG_GETARG_FLOAT4(1);
3981 
3982  PG_RETURN_BOOL(float8_gt(arg1, (float8) arg2));
3983 }
3984 
3985 Datum
3987 {
3988  float8 arg1 = PG_GETARG_FLOAT8(0);
3989  float4 arg2 = PG_GETARG_FLOAT4(1);
3990 
3991  PG_RETURN_BOOL(float8_ge(arg1, (float8) arg2));
3992 }
3993 
3994 /*
3995  * Implements the float8 version of the width_bucket() function
3996  * defined by SQL2003. See also width_bucket_numeric().
3997  *
3998  * 'bound1' and 'bound2' are the lower and upper bounds of the
3999  * histogram's range, respectively. 'count' is the number of buckets
4000  * in the histogram. width_bucket() returns an integer indicating the
4001  * bucket number that 'operand' belongs to in an equiwidth histogram
4002  * with the specified characteristics. An operand smaller than the
4003  * lower bound is assigned to bucket 0. An operand greater than the
4004  * upper bound is assigned to an additional bucket (with number
4005  * count+1). We don't allow "NaN" for any of the float8 inputs, and we
4006  * don't allow either of the histogram bounds to be +/- infinity.
4007  */
4008 Datum
4010 {
4011  float8 operand = PG_GETARG_FLOAT8(0);
4012  float8 bound1 = PG_GETARG_FLOAT8(1);
4013  float8 bound2 = PG_GETARG_FLOAT8(2);
4014  int32 count = PG_GETARG_INT32(3);
4015  int32 result;
4016 
4017  if (count <= 0.0)
4018  ereport(ERROR,
4019  (errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
4020  errmsg("count must be greater than zero")));
4021 
4022  if (isnan(operand) || isnan(bound1) || isnan(bound2))
4023  ereport(ERROR,
4024  (errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
4025  errmsg("operand, lower bound, and upper bound cannot be NaN")));
4026 
4027  /* Note that we allow "operand" to be infinite */
4028  if (isinf(bound1) || isinf(bound2))
4029  ereport(ERROR,
4030  (errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
4031  errmsg("lower and upper bounds must be finite")));
4032 
4033  if (bound1 < bound2)
4034  {
4035  if (operand < bound1)
4036  result = 0;
4037  else if (operand >= bound2)
4038  {
4039  if (pg_add_s32_overflow(count, 1, &result))
4040  ereport(ERROR,
4041  (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
4042  errmsg("integer out of range")));
4043  }
4044  else
4045  result = ((float8) count * (operand - bound1) / (bound2 - bound1)) + 1;
4046  }
4047  else if (bound1 > bound2)
4048  {
4049  if (operand > bound1)
4050  result = 0;
4051  else if (operand <= bound2)
4052  {
4053  if (pg_add_s32_overflow(count, 1, &result))
4054  ereport(ERROR,
4055  (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
4056  errmsg("integer out of range")));
4057  }
4058  else
4059  result = ((float8) count * (bound1 - operand) / (bound1 - bound2)) + 1;
4060  }
4061  else
4062  {
4063  ereport(ERROR,
4064  (errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
4065  errmsg("lower bound cannot equal upper bound")));
4066  result = 0; /* keep the compiler quiet */
4067  }
4068 
4069  PG_RETURN_INT32(result);
4070 }
#define ARR_NDIM(a)
Definition: array.h:283
#define PG_GETARG_ARRAYTYPE_P(n)
Definition: array.h:256
#define ARR_DATA_PTR(a)
Definition: array.h:315
#define ARR_ELEMTYPE(a)
Definition: array.h:285
#define PG_RETURN_ARRAYTYPE_P(x)
Definition: array.h:258
#define ARR_DIMS(a)
Definition: array.h:287
#define ARR_HASNULL(a)
Definition: array.h:284
ArrayType * construct_array(Datum *elems, int nelems, Oid elmtype, int elmlen, bool elmbyval, char elmalign)
Definition: arrayfuncs.c:3318
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1573
Datum now(PG_FUNCTION_ARGS)
Definition: timestamp.c:1537
#define FLOAT4_FITS_IN_INT32(num)
Definition: c.h:1041
#define FLOAT8_FITS_IN_INT32(num)
Definition: c.h:1047
#define pg_noinline
Definition: c.h:234
signed short int16
Definition: c.h:429
signed int int32
Definition: c.h:430
#define FLOAT4_FITS_IN_INT16(num)
Definition: c.h:1039
double float8
Definition: c.h:566
#define FLOAT8PASSBYVAL
Definition: c.h:571
#define FLOAT8_FITS_IN_INT16(num)
Definition: c.h:1045
#define unlikely(x)
Definition: c.h:295
float float4
Definition: c.h:565
int double_to_shortest_decimal_buf(double f, char *result)
Definition: d2s.c:1053
int64 TimestampTz
Definition: timestamp.h:39
#define M_PI
Definition: earthdistance.c:10
int errcode(int sqlerrcode)
Definition: elog.c:695
int errmsg(const char *fmt,...)
Definition: elog.c:906
#define ERROR
Definition: elog.h:35
#define ereport(elevel,...)
Definition: elog.h:145
int float_to_shortest_decimal_buf(float f, char *result)
Definition: f2s.c:780
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:2852
float8 degree_c_sixty
Definition: float.c:63
static float8 acos_0_5
Definition: float.c:50
Datum float84gt(PG_FUNCTION_ARGS)
Definition: float.c:3977
double float8in_internal(char *num, char **endptr_p, const char *type_name, const char *orig_string)
Definition: float.c:510
Datum dasinh(PG_FUNCTION_ARGS)
Definition: float.c:2673
Datum float84mi(PG_FUNCTION_ARGS)
Definition: float.c:3848
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:101
pg_noinline void float_overflow_error(void)
Definition: float.c:85
Datum width_bucket_float8(PG_FUNCTION_ARGS)
Definition: float.c:4009
Datum dasind(PG_FUNCTION_ARGS)
Definition: float.c:2146
Datum float8_var_samp(PG_FUNCTION_ARGS)
Definition: float.c:3180
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 float8div(PG_FUNCTION_ARGS)
Definition: float.c:798
Datum float8_regr_syy(PG_FUNCTION_ARGS)
Definition: float.c:3546
Datum float48gt(PG_FUNCTION_ARGS)
Definition: float.c:3920
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:61
int extra_float_digits
Definition: float.c:43
static double acosd_q1(double x)
Definition: float.c:2082
Datum float8_regr_r2(PG_FUNCTION_ARGS)
Definition: float.c:3693
Datum float8_regr_combine(PG_FUNCTION_ARGS)
Definition: float.c:3391
Datum float8_regr_slope(PG_FUNCTION_ARGS)
Definition: float.c:3726
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:3857
static bool degree_consts_set
Definition: float.c:46
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 float4up(PG_FUNCTION_ARGS)
Definition: float.c:613
static float8 atan_1_0
Definition: float.c:51
Datum float48pl(PG_FUNCTION_ARGS)
Definition: float.c:3797
Datum dsinh(PG_FUNCTION_ARGS)
Definition: float.c:2599
Datum float8_combine(PG_FUNCTION_ARGS)
Definition: float.c:2876
Datum float8_avg(PG_FUNCTION_ARGS)
Definition: float.c:3138
Datum float8_covar_pop(PG_FUNCTION_ARGS)
Definition: float.c:3626
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:3202
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
double float8in_internal_opt_error(char *num, char **endptr_p, const char *type_name, const char *orig_string, bool *have_error)
Definition: float.c:376
Datum float8_regr_intercept(PG_FUNCTION_ARGS)
Definition: float.c:3753
Datum float8out(PG_FUNCTION_ARGS)
Definition: float.c:523
Datum float84le(PG_FUNCTION_ARGS)
Definition: float.c:3968
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:291
#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:322
static float8 cot_45
Definition: float.c:53
Datum float4ne(PG_FUNCTION_ARGS)
Definition: float.c:836
Datum float84eq(PG_FUNCTION_ARGS)
Definition: float.c:3941
Datum float84lt(PG_FUNCTION_ARGS)
Definition: float.c:3959
Datum float48mi(PG_FUNCTION_ARGS)
Definition: float.c:3806
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:336
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
static bool drandom_seed_set
Definition: float.c:68
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:2970
Datum float48eq(PG_FUNCTION_ARGS)
Definition: float.c:3884
Datum i2tof(PG_FUNCTION_ARGS)
Definition: float.c:1351
static float8 one_minus_cos_60
Definition: float.c:48
Datum float84pl(PG_FUNCTION_ARGS)
Definition: float.c:3839
Datum btfloat48cmp(PG_FUNCTION_ARGS)
Definition: float.c:1002
Datum float48ge(PG_FUNCTION_ARGS)
Definition: float.c:3929
Datum float84div(PG_FUNCTION_ARGS)
Definition: float.c:3866
Datum dcotd(PG_FUNCTION_ARGS)
Definition: float.c:2374
pg_noinline void float_underflow_error(void)
Definition: float.c:93
Datum float8smaller(PG_FUNCTION_ARGS)
Definition: float.c:702
float8 degree_c_forty_five
Definition: float.c:62
Datum dsqrt(PG_FUNCTION_ARGS)
Definition: float.c:1447
Datum float84ge(PG_FUNCTION_ARGS)
Definition: float.c:3986
Datum float8_stddev_samp(PG_FUNCTION_ARGS)
Definition: float.c:3224
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
static pg_prng_state drandom_seed
Definition: float.c:69
Datum float4in(PG_FUNCTION_ARGS)
Definition: float.c:163
static int btfloat4fastcmp(Datum x, Datum y, SortSupport ssup)
Definition: float.c:890
Datum float8_regr_sxy(PG_FUNCTION_ARGS)
Definition: float.c:3567
Datum float8_var_pop(PG_FUNCTION_ARGS)
Definition: float.c:3158
Datum float48div(PG_FUNCTION_ARGS)
Definition: float.c:3824
Datum float84ne(PG_FUNCTION_ARGS)
Definition: float.c:3950
Datum float4_accum(PG_FUNCTION_ARGS)
Definition: float.c:3053
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:52
Datum float48le(PG_FUNCTION_ARGS)
Definition: float.c:3911
Datum float8_regr_sxx(PG_FUNCTION_ARGS)
Definition: float.c:3525
Datum float8_corr(PG_FUNCTION_ARGS)
Definition: float.c:3664
#define RETURN_ERROR(throw_error, have_error)
Definition: float.c:344
static float8 sin_30
Definition: float.c:47
float8 degree_c_one
Definition: float.c:65
Datum float4recv(PG_FUNCTION_ARGS)
Definition: float.c:311
float8 degree_c_one_half
Definition: float.c:64
Datum in_range_float8_float8(PG_FUNCTION_ARGS)
Definition: float.c:1028
Datum float48ne(PG_FUNCTION_ARGS)
Definition: float.c:3893
Datum dpi(PG_FUNCTION_ARGS)
Definition: float.c:2574
Datum dacos(PG_FUNCTION_ARGS)
Definition: float.c:1756
Datum float48lt(PG_FUNCTION_ARGS)
Definition: float.c:3902
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 setseed(PG_FUNCTION_ARGS)
Definition: float.c:2785
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:117
Datum i2tod(PG_FUNCTION_ARGS)
Definition: float.c:1277
Datum dfloor(PG_FUNCTION_ARGS)
Definition: float.c:1393
Datum drandom(PG_FUNCTION_ARGS)
Definition: float.c:2750
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:3588
Datum float8um(PG_FUNCTION_ARGS)
Definition: float.c:670
Datum float8_regr_avgy(PG_FUNCTION_ARGS)
Definition: float.c:3607
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:49
Datum float8_covar_samp(PG_FUNCTION_ARGS)
Definition: float.c:3645
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:3815
Datum float4smaller(PG_FUNCTION_ARGS)
Definition: float.c:635
Datum float8_regr_accum(PG_FUNCTION_ARGS)
Definition: float.c:3267
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:207
static float4 float4_div(const float4 val1, const float4 val2)
Definition: float.h:221
#define RADIANS_PER_DEGREE
Definition: float.h:26
static float4 get_float4_infinity(void)
Definition: float.h:73
static bool float4_lt(const float4 val1, const float4 val2)
Definition: float.h:285
static float8 float8_pl(const float8 val1, const float8 val2)
Definition: float.h:157
static float8 float8_mi(const float8 val1, const float8 val2)
Definition: float.h:181
static bool float4_ge(const float4 val1, const float4 val2)
Definition: float.h:321
static float4 get_float4_nan(void)
Definition: float.h:110
static bool float8_ne(const float8 val1, const float8 val2)
Definition: float.h:279
static bool float4_ne(const float4 val1, const float4 val2)
Definition: float.h:273
static float4 float4_pl(const float4 val1, const float4 val2)
Definition: float.h:145
static bool float4_eq(const float4 val1, const float4 val2)
Definition: float.h:261
static float4 float4_mul(const float4 val1, const float4 val2)
Definition: float.h:193
static float8 get_float8_infinity(void)
Definition: float.h:93
static bool float8_ge(const float8 val1, const float8 val2)
Definition: float.h:327
static float4 float4_mi(const float4 val1, const float4 val2)
Definition: float.h:169
static bool float8_le(const float8 val1, const float8 val2)
Definition: float.h:303
static bool float4_gt(const float4 val1, const float4 val2)
Definition: float.h:309
static bool float8_eq(const float8 val1, const float8 val2)
Definition: float.h:267
static bool float4_le(const float4 val1, const float4 val2)
Definition: float.h:297
static float8 get_float8_nan(void)
Definition: float.h:122
static float8 float8_div(const float8 val1, const float8 val2)
Definition: float.h:237
static bool float8_lt(const float8 val1, const float8 val2)
Definition: float.h:291
static bool float8_gt(const float8 val1, const float8 val2)
Definition: float.h:315
#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
int MyProcPid
Definition: globals.c:44
#define newval
long val
Definition: informix.c:664
char sign
Definition: informix.c:668
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:1483
void * palloc(Size size)
Definition: mcxt.c:1199
int AggCheckCallContext(FunctionCallInfo fcinfo, MemoryContext *aggcontext)
Definition: nodeAgg.c:4509
Datum ascii(PG_FUNCTION_ARGS)
void * arg
double pg_prng_double(pg_prng_state *state)
Definition: pg_prng.c:226
void pg_prng_seed(pg_prng_state *state, uint64 seed)
Definition: pg_prng.c:83
void pg_prng_fseed(pg_prng_state *state, double fseed)
Definition: pg_prng.c:96
#define pg_prng_strong_seed(state)
Definition: pg_prng.h:46
static char * buf
Definition: pg_test_fsync.c:67
int scale
Definition: pgbench.c:190
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:412
static float4 DatumGetFloat4(Datum X)
Definition: postgres.h:806
#define Float8GetDatumFast(X)
Definition: postgres.h:904
static float8 DatumGetFloat8(Datum X)
Definition: postgres.h:842
float4 pq_getmsgfloat4(StringInfo msg)
Definition: pqformat.c:471
float8 pq_getmsgfloat8(StringInfo msg)
Definition: pqformat.c:490
void pq_begintypsend(StringInfo buf)
Definition: pqformat.c:328
void pq_sendfloat4(StringInfo buf, float4 f)
Definition: pqformat.c:254
bytea * pq_endtypsend(StringInfo buf)
Definition: pqformat.c:348
void pq_sendfloat8(StringInfo buf, float8 f)
Definition: pqformat.c:278
struct SortSupportData * SortSupport
Definition: sortsupport.h:58
StringInfoData * StringInfo
Definition: stringinfo.h:44
int(* comparator)(Datum x, Datum y, SortSupport ssup)
Definition: sortsupport.h:106