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