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