PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
cash.c File Reference
#include "postgres.h"
#include <limits.h>
#include <ctype.h>
#include <math.h>
#include "libpq/pqformat.h"
#include "utils/builtins.h"
#include "utils/cash.h"
#include "utils/int8.h"
#include "utils/numeric.h"
#include "utils/pg_locale.h"
Include dependency graph for cash.c:

Go to the source code of this file.

Functions

static const char * num_word (Cash value)
 
Datum cash_in (PG_FUNCTION_ARGS)
 
Datum cash_out (PG_FUNCTION_ARGS)
 
Datum cash_recv (PG_FUNCTION_ARGS)
 
Datum cash_send (PG_FUNCTION_ARGS)
 
Datum cash_eq (PG_FUNCTION_ARGS)
 
Datum cash_ne (PG_FUNCTION_ARGS)
 
Datum cash_lt (PG_FUNCTION_ARGS)
 
Datum cash_le (PG_FUNCTION_ARGS)
 
Datum cash_gt (PG_FUNCTION_ARGS)
 
Datum cash_ge (PG_FUNCTION_ARGS)
 
Datum cash_cmp (PG_FUNCTION_ARGS)
 
Datum cash_pl (PG_FUNCTION_ARGS)
 
Datum cash_mi (PG_FUNCTION_ARGS)
 
Datum cash_div_cash (PG_FUNCTION_ARGS)
 
Datum cash_mul_flt8 (PG_FUNCTION_ARGS)
 
Datum flt8_mul_cash (PG_FUNCTION_ARGS)
 
Datum cash_div_flt8 (PG_FUNCTION_ARGS)
 
Datum cash_mul_flt4 (PG_FUNCTION_ARGS)
 
Datum flt4_mul_cash (PG_FUNCTION_ARGS)
 
Datum cash_div_flt4 (PG_FUNCTION_ARGS)
 
Datum cash_mul_int8 (PG_FUNCTION_ARGS)
 
Datum int8_mul_cash (PG_FUNCTION_ARGS)
 
Datum cash_div_int8 (PG_FUNCTION_ARGS)
 
Datum cash_mul_int4 (PG_FUNCTION_ARGS)
 
Datum int4_mul_cash (PG_FUNCTION_ARGS)
 
Datum cash_div_int4 (PG_FUNCTION_ARGS)
 
Datum cash_mul_int2 (PG_FUNCTION_ARGS)
 
Datum int2_mul_cash (PG_FUNCTION_ARGS)
 
Datum cash_div_int2 (PG_FUNCTION_ARGS)
 
Datum cashlarger (PG_FUNCTION_ARGS)
 
Datum cashsmaller (PG_FUNCTION_ARGS)
 
Datum cash_words (PG_FUNCTION_ARGS)
 
Datum cash_numeric (PG_FUNCTION_ARGS)
 
Datum numeric_cash (PG_FUNCTION_ARGS)
 
Datum int4_cash (PG_FUNCTION_ARGS)
 
Datum int8_cash (PG_FUNCTION_ARGS)
 

Function Documentation

Datum cash_cmp ( PG_FUNCTION_ARGS  )

Definition at line 594 of file cash.c.

References PG_GETARG_CASH, and PG_RETURN_INT32.

595 {
596  Cash c1 = PG_GETARG_CASH(0);
597  Cash c2 = PG_GETARG_CASH(1);
598 
599  if (c1 > c2)
600  PG_RETURN_INT32(1);
601  else if (c1 == c2)
602  PG_RETURN_INT32(0);
603  else
604  PG_RETURN_INT32(-1);
605 }
#define PG_RETURN_INT32(x)
Definition: fmgr.h:314
#define PG_GETARG_CASH(n)
Definition: cash.h:22
int64 Cash
Definition: cash.h:17
Datum cash_div_cash ( PG_FUNCTION_ARGS  )

Definition at line 644 of file cash.c.

References ereport, errcode(), errmsg(), ERROR, PG_GETARG_CASH, and PG_RETURN_FLOAT8.

645 {
646  Cash dividend = PG_GETARG_CASH(0);
647  Cash divisor = PG_GETARG_CASH(1);
648  float8 quotient;
649 
650  if (divisor == 0)
651  ereport(ERROR,
652  (errcode(ERRCODE_DIVISION_BY_ZERO),
653  errmsg("division by zero")));
654 
655  quotient = (float8) dividend / (float8) divisor;
656  PG_RETURN_FLOAT8(quotient);
657 }
#define PG_RETURN_FLOAT8(x)
Definition: fmgr.h:326
int errcode(int sqlerrcode)
Definition: elog.c:575
#define ERROR
Definition: elog.h:43
double float8
Definition: c.h:375
#define PG_GETARG_CASH(n)
Definition: cash.h:22
#define ereport(elevel, rest)
Definition: elog.h:122
int64 Cash
Definition: cash.h:17
int errmsg(const char *fmt,...)
Definition: elog.c:797
Datum cash_div_flt4 ( PG_FUNCTION_ARGS  )

Definition at line 745 of file cash.c.

References ereport, errcode(), errmsg(), ERROR, PG_GETARG_CASH, PG_GETARG_FLOAT4, PG_RETURN_CASH, and rint().

746 {
747  Cash c = PG_GETARG_CASH(0);
748  float4 f = PG_GETARG_FLOAT4(1);
749  Cash result;
750 
751  if (f == 0.0)
752  ereport(ERROR,
753  (errcode(ERRCODE_DIVISION_BY_ZERO),
754  errmsg("division by zero")));
755 
756  result = rint(c / (float8) f);
757  PG_RETURN_CASH(result);
758 }
int errcode(int sqlerrcode)
Definition: elog.c:575
#define ERROR
Definition: elog.h:43
double float8
Definition: c.h:375
#define PG_GETARG_CASH(n)
Definition: cash.h:22
char * c
double rint(double x)
Definition: rint.c:22
#define PG_GETARG_FLOAT4(n)
Definition: fmgr.h:245
#define ereport(elevel, rest)
Definition: elog.h:122
float float4
Definition: c.h:374
int64 Cash
Definition: cash.h:17
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define PG_RETURN_CASH(x)
Definition: cash.h:23
Datum cash_div_flt8 ( PG_FUNCTION_ARGS  )

Definition at line 694 of file cash.c.

References ereport, errcode(), errmsg(), ERROR, PG_GETARG_CASH, PG_GETARG_FLOAT8, PG_RETURN_CASH, and rint().

695 {
696  Cash c = PG_GETARG_CASH(0);
697  float8 f = PG_GETARG_FLOAT8(1);
698  Cash result;
699 
700  if (f == 0.0)
701  ereport(ERROR,
702  (errcode(ERRCODE_DIVISION_BY_ZERO),
703  errmsg("division by zero")));
704 
705  result = rint(c / f);
706  PG_RETURN_CASH(result);
707 }
#define PG_GETARG_FLOAT8(n)
Definition: fmgr.h:246
int errcode(int sqlerrcode)
Definition: elog.c:575
#define ERROR
Definition: elog.h:43
double float8
Definition: c.h:375
#define PG_GETARG_CASH(n)
Definition: cash.h:22
char * c
double rint(double x)
Definition: rint.c:22
#define ereport(elevel, rest)
Definition: elog.h:122
int64 Cash
Definition: cash.h:17
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define PG_RETURN_CASH(x)
Definition: cash.h:23
Datum cash_div_int2 ( PG_FUNCTION_ARGS  )

Definition at line 896 of file cash.c.

References ereport, errcode(), errmsg(), ERROR, PG_GETARG_CASH, PG_GETARG_INT16, and PG_RETURN_CASH.

897 {
898  Cash c = PG_GETARG_CASH(0);
899  int16 s = PG_GETARG_INT16(1);
900  Cash result;
901 
902  if (s == 0)
903  ereport(ERROR,
904  (errcode(ERRCODE_DIVISION_BY_ZERO),
905  errmsg("division by zero")));
906 
907  result = c / s;
908  PG_RETURN_CASH(result);
909 }
signed short int16
Definition: c.h:245
int errcode(int sqlerrcode)
Definition: elog.c:575
#define ERROR
Definition: elog.h:43
#define PG_GETARG_CASH(n)
Definition: cash.h:22
char * c
#define ereport(elevel, rest)
Definition: elog.h:122
#define PG_GETARG_INT16(n)
Definition: fmgr.h:236
int64 Cash
Definition: cash.h:17
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define PG_RETURN_CASH(x)
Definition: cash.h:23
Datum cash_div_int4 ( PG_FUNCTION_ARGS  )

Definition at line 846 of file cash.c.

References ereport, errcode(), errmsg(), ERROR, i, PG_GETARG_CASH, PG_GETARG_INT32, and PG_RETURN_CASH.

847 {
848  Cash c = PG_GETARG_CASH(0);
849  int32 i = PG_GETARG_INT32(1);
850  Cash result;
851 
852  if (i == 0)
853  ereport(ERROR,
854  (errcode(ERRCODE_DIVISION_BY_ZERO),
855  errmsg("division by zero")));
856 
857  result = c / i;
858 
859  PG_RETURN_CASH(result);
860 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:234
int errcode(int sqlerrcode)
Definition: elog.c:575
signed int int32
Definition: c.h:246
#define ERROR
Definition: elog.h:43
#define PG_GETARG_CASH(n)
Definition: cash.h:22
char * c
#define ereport(elevel, rest)
Definition: elog.h:122
int64 Cash
Definition: cash.h:17
int errmsg(const char *fmt,...)
Definition: elog.c:797
int i
#define PG_RETURN_CASH(x)
Definition: cash.h:23
Datum cash_div_int8 ( PG_FUNCTION_ARGS  )

Definition at line 794 of file cash.c.

References ereport, errcode(), errmsg(), ERROR, i, PG_GETARG_CASH, PG_GETARG_INT64, and PG_RETURN_CASH.

795 {
796  Cash c = PG_GETARG_CASH(0);
797  int64 i = PG_GETARG_INT64(1);
798  Cash result;
799 
800  if (i == 0)
801  ereport(ERROR,
802  (errcode(ERRCODE_DIVISION_BY_ZERO),
803  errmsg("division by zero")));
804 
805  result = c / i;
806 
807  PG_RETURN_CASH(result);
808 }
int errcode(int sqlerrcode)
Definition: elog.c:575
#define ERROR
Definition: elog.h:43
#define PG_GETARG_CASH(n)
Definition: cash.h:22
char * c
#define ereport(elevel, rest)
Definition: elog.h:122
int64 Cash
Definition: cash.h:17
int errmsg(const char *fmt,...)
Definition: elog.c:797
int i
#define PG_RETURN_CASH(x)
Definition: cash.h:23
#define PG_GETARG_INT64(n)
Definition: fmgr.h:247
Datum cash_eq ( PG_FUNCTION_ARGS  )

Definition at line 540 of file cash.c.

References PG_GETARG_CASH, and PG_RETURN_BOOL.

541 {
542  Cash c1 = PG_GETARG_CASH(0);
543  Cash c2 = PG_GETARG_CASH(1);
544 
545  PG_RETURN_BOOL(c1 == c2);
546 }
#define PG_GETARG_CASH(n)
Definition: cash.h:22
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:319
int64 Cash
Definition: cash.h:17
Datum cash_ge ( PG_FUNCTION_ARGS  )

Definition at line 585 of file cash.c.

References PG_GETARG_CASH, and PG_RETURN_BOOL.

586 {
587  Cash c1 = PG_GETARG_CASH(0);
588  Cash c2 = PG_GETARG_CASH(1);
589 
590  PG_RETURN_BOOL(c1 >= c2);
591 }
#define PG_GETARG_CASH(n)
Definition: cash.h:22
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:319
int64 Cash
Definition: cash.h:17
Datum cash_gt ( PG_FUNCTION_ARGS  )

Definition at line 576 of file cash.c.

References PG_GETARG_CASH, and PG_RETURN_BOOL.

577 {
578  Cash c1 = PG_GETARG_CASH(0);
579  Cash c2 = PG_GETARG_CASH(1);
580 
581  PG_RETURN_BOOL(c1 > c2);
582 }
#define PG_GETARG_CASH(n)
Definition: cash.h:22
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:319
int64 Cash
Definition: cash.h:17
Datum cash_in ( PG_FUNCTION_ARGS  )

Definition at line 96 of file cash.c.

References ereport, errcode(), errmsg(), ERROR, INT64_FORMAT, PG_GETARG_CSTRING, PG_RETURN_CASH, PGLC_localeconv(), and value.

97 {
98  char *str = PG_GETARG_CSTRING(0);
99  Cash result;
100  Cash value = 0;
101  Cash dec = 0;
102  Cash sgn = 1;
103  bool seen_dot = false;
104  const char *s = str;
105  int fpoint;
106  char dsymbol;
107  const char *ssymbol,
108  *psymbol,
109  *nsymbol,
110  *csymbol;
111  struct lconv *lconvert = PGLC_localeconv();
112 
113  /*
114  * frac_digits will be CHAR_MAX in some locales, notably C. However, just
115  * testing for == CHAR_MAX is risky, because of compilers like gcc that
116  * "helpfully" let you alter the platform-standard definition of whether
117  * char is signed or not. If we are so unfortunate as to get compiled
118  * with a nonstandard -fsigned-char or -funsigned-char switch, then our
119  * idea of CHAR_MAX will not agree with libc's. The safest course is not
120  * to test for CHAR_MAX at all, but to impose a range check for plausible
121  * frac_digits values.
122  */
123  fpoint = lconvert->frac_digits;
124  if (fpoint < 0 || fpoint > 10)
125  fpoint = 2; /* best guess in this case, I think */
126 
127  /* we restrict dsymbol to be a single byte, but not the other symbols */
128  if (*lconvert->mon_decimal_point != '\0' &&
129  lconvert->mon_decimal_point[1] == '\0')
130  dsymbol = *lconvert->mon_decimal_point;
131  else
132  dsymbol = '.';
133  if (*lconvert->mon_thousands_sep != '\0')
134  ssymbol = lconvert->mon_thousands_sep;
135  else /* ssymbol should not equal dsymbol */
136  ssymbol = (dsymbol != ',') ? "," : ".";
137  csymbol = (*lconvert->currency_symbol != '\0') ? lconvert->currency_symbol : "$";
138  psymbol = (*lconvert->positive_sign != '\0') ? lconvert->positive_sign : "+";
139  nsymbol = (*lconvert->negative_sign != '\0') ? lconvert->negative_sign : "-";
140 
141 #ifdef CASHDEBUG
142  printf("cashin- precision '%d'; decimal '%c'; thousands '%s'; currency '%s'; positive '%s'; negative '%s'\n",
143  fpoint, dsymbol, ssymbol, csymbol, psymbol, nsymbol);
144 #endif
145 
146  /* we need to add all sorts of checking here. For now just */
147  /* strip all leading whitespace and any leading currency symbol */
148  while (isspace((unsigned char) *s))
149  s++;
150  if (strncmp(s, csymbol, strlen(csymbol)) == 0)
151  s += strlen(csymbol);
152  while (isspace((unsigned char) *s))
153  s++;
154 
155 #ifdef CASHDEBUG
156  printf("cashin- string is '%s'\n", s);
157 #endif
158 
159  /* a leading minus or paren signifies a negative number */
160  /* again, better heuristics needed */
161  /* XXX - doesn't properly check for balanced parens - djmc */
162  if (strncmp(s, nsymbol, strlen(nsymbol)) == 0)
163  {
164  sgn = -1;
165  s += strlen(nsymbol);
166  }
167  else if (*s == '(')
168  {
169  sgn = -1;
170  s++;
171  }
172  else if (strncmp(s, psymbol, strlen(psymbol)) == 0)
173  s += strlen(psymbol);
174 
175 #ifdef CASHDEBUG
176  printf("cashin- string is '%s'\n", s);
177 #endif
178 
179  /* allow whitespace and currency symbol after the sign, too */
180  while (isspace((unsigned char) *s))
181  s++;
182  if (strncmp(s, csymbol, strlen(csymbol)) == 0)
183  s += strlen(csymbol);
184  while (isspace((unsigned char) *s))
185  s++;
186 
187 #ifdef CASHDEBUG
188  printf("cashin- string is '%s'\n", s);
189 #endif
190 
191  /*
192  * We accumulate the absolute amount in "value" and then apply the sign at
193  * the end. (The sign can appear before or after the digits, so it would
194  * be more complicated to do otherwise.) Because of the larger range of
195  * negative signed integers, we build "value" in the negative and then
196  * flip the sign at the end, catching most-negative-number overflow if
197  * necessary.
198  */
199 
200  for (; *s; s++)
201  {
202  /* we look for digits as long as we have found less */
203  /* than the required number of decimal places */
204  if (isdigit((unsigned char) *s) && (!seen_dot || dec < fpoint))
205  {
206  Cash newvalue = (value * 10) - (*s - '0');
207 
208  if (newvalue / 10 != value)
209  ereport(ERROR,
210  (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
211  errmsg("value \"%s\" is out of range for type %s",
212  str, "money")));
213 
214  value = newvalue;
215 
216  if (seen_dot)
217  dec++;
218  }
219  /* decimal point? then start counting fractions... */
220  else if (*s == dsymbol && !seen_dot)
221  {
222  seen_dot = true;
223  }
224  /* ignore if "thousands" separator, else we're done */
225  else if (strncmp(s, ssymbol, strlen(ssymbol)) == 0)
226  s += strlen(ssymbol) - 1;
227  else
228  break;
229  }
230 
231  /* round off if there's another digit */
232  if (isdigit((unsigned char) *s) && *s >= '5')
233  value--; /* remember we build the value in the negative */
234 
235  if (value > 0)
236  ereport(ERROR,
237  (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
238  errmsg("value \"%s\" is out of range for type %s",
239  str, "money")));
240 
241  /* adjust for less than required decimal places */
242  for (; dec < fpoint; dec++)
243  {
244  Cash newvalue = value * 10;
245 
246  if (newvalue / 10 != value)
247  ereport(ERROR,
248  (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
249  errmsg("value \"%s\" is out of range for type %s",
250  str, "money")));
251 
252  value = newvalue;
253  }
254 
255  /*
256  * should only be trailing digits followed by whitespace, right paren,
257  * trailing sign, and/or trailing currency symbol
258  */
259  while (isdigit((unsigned char) *s))
260  s++;
261 
262  while (*s)
263  {
264  if (isspace((unsigned char) *s) || *s == ')')
265  s++;
266  else if (strncmp(s, nsymbol, strlen(nsymbol)) == 0)
267  {
268  sgn = -1;
269  s += strlen(nsymbol);
270  }
271  else if (strncmp(s, psymbol, strlen(psymbol)) == 0)
272  s += strlen(psymbol);
273  else if (strncmp(s, csymbol, strlen(csymbol)) == 0)
274  s += strlen(csymbol);
275  else
276  ereport(ERROR,
277  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
278  errmsg("invalid input syntax for type %s: \"%s\"",
279  "money", str)));
280  }
281 
282  /*
283  * If the value is supposed to be positive, flip the sign, but check for
284  * the most negative number.
285  */
286  if (sgn > 0)
287  {
288  result = -value;
289  if (result < 0)
290  ereport(ERROR,
291  (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
292  errmsg("value \"%s\" is out of range for type %s",
293  str, "money")));
294  }
295  else
296  result = value;
297 
298 #ifdef CASHDEBUG
299  printf("cashin- result is " INT64_FORMAT "\n", result);
300 #endif
301 
302  PG_RETURN_CASH(result);
303 }
int errcode(int sqlerrcode)
Definition: elog.c:575
#define ERROR
Definition: elog.h:43
static struct @121 value
#define ereport(elevel, rest)
Definition: elog.h:122
struct lconv * PGLC_localeconv(void)
Definition: pg_locale.c:483
#define INT64_FORMAT
Definition: c.h:300
int64 Cash
Definition: cash.h:17
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define PG_GETARG_CSTRING(n)
Definition: fmgr.h:242
#define PG_RETURN_CASH(x)
Definition: cash.h:23
Datum cash_le ( PG_FUNCTION_ARGS  )

Definition at line 567 of file cash.c.

References PG_GETARG_CASH, and PG_RETURN_BOOL.

568 {
569  Cash c1 = PG_GETARG_CASH(0);
570  Cash c2 = PG_GETARG_CASH(1);
571 
572  PG_RETURN_BOOL(c1 <= c2);
573 }
#define PG_GETARG_CASH(n)
Definition: cash.h:22
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:319
int64 Cash
Definition: cash.h:17
Datum cash_lt ( PG_FUNCTION_ARGS  )

Definition at line 558 of file cash.c.

References PG_GETARG_CASH, and PG_RETURN_BOOL.

559 {
560  Cash c1 = PG_GETARG_CASH(0);
561  Cash c2 = PG_GETARG_CASH(1);
562 
563  PG_RETURN_BOOL(c1 < c2);
564 }
#define PG_GETARG_CASH(n)
Definition: cash.h:22
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:319
int64 Cash
Definition: cash.h:17
Datum cash_mi ( PG_FUNCTION_ARGS  )

Definition at line 628 of file cash.c.

References PG_GETARG_CASH, and PG_RETURN_CASH.

629 {
630  Cash c1 = PG_GETARG_CASH(0);
631  Cash c2 = PG_GETARG_CASH(1);
632  Cash result;
633 
634  result = c1 - c2;
635 
636  PG_RETURN_CASH(result);
637 }
#define PG_GETARG_CASH(n)
Definition: cash.h:22
int64 Cash
Definition: cash.h:17
#define PG_RETURN_CASH(x)
Definition: cash.h:23
Datum cash_mul_flt4 ( PG_FUNCTION_ARGS  )

Definition at line 714 of file cash.c.

References PG_GETARG_CASH, PG_GETARG_FLOAT4, PG_RETURN_CASH, and rint().

715 {
716  Cash c = PG_GETARG_CASH(0);
717  float4 f = PG_GETARG_FLOAT4(1);
718  Cash result;
719 
720  result = rint(c * (float8) f);
721  PG_RETURN_CASH(result);
722 }
double float8
Definition: c.h:375
#define PG_GETARG_CASH(n)
Definition: cash.h:22
char * c
double rint(double x)
Definition: rint.c:22
#define PG_GETARG_FLOAT4(n)
Definition: fmgr.h:245
float float4
Definition: c.h:374
int64 Cash
Definition: cash.h:17
#define PG_RETURN_CASH(x)
Definition: cash.h:23
Datum cash_mul_flt8 ( PG_FUNCTION_ARGS  )

Definition at line 664 of file cash.c.

References PG_GETARG_CASH, PG_GETARG_FLOAT8, PG_RETURN_CASH, and rint().

665 {
666  Cash c = PG_GETARG_CASH(0);
667  float8 f = PG_GETARG_FLOAT8(1);
668  Cash result;
669 
670  result = rint(c * f);
671  PG_RETURN_CASH(result);
672 }
#define PG_GETARG_FLOAT8(n)
Definition: fmgr.h:246
double float8
Definition: c.h:375
#define PG_GETARG_CASH(n)
Definition: cash.h:22
char * c
double rint(double x)
Definition: rint.c:22
int64 Cash
Definition: cash.h:17
#define PG_RETURN_CASH(x)
Definition: cash.h:23
Datum cash_mul_int2 ( PG_FUNCTION_ARGS  )

Definition at line 867 of file cash.c.

References PG_GETARG_CASH, PG_GETARG_INT16, and PG_RETURN_CASH.

868 {
869  Cash c = PG_GETARG_CASH(0);
870  int16 s = PG_GETARG_INT16(1);
871  Cash result;
872 
873  result = c * s;
874  PG_RETURN_CASH(result);
875 }
signed short int16
Definition: c.h:245
#define PG_GETARG_CASH(n)
Definition: cash.h:22
char * c
#define PG_GETARG_INT16(n)
Definition: fmgr.h:236
int64 Cash
Definition: cash.h:17
#define PG_RETURN_CASH(x)
Definition: cash.h:23
Datum cash_mul_int4 ( PG_FUNCTION_ARGS  )

Definition at line 815 of file cash.c.

References i, PG_GETARG_CASH, PG_GETARG_INT32, and PG_RETURN_CASH.

816 {
817  Cash c = PG_GETARG_CASH(0);
818  int32 i = PG_GETARG_INT32(1);
819  Cash result;
820 
821  result = c * i;
822  PG_RETURN_CASH(result);
823 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:234
signed int int32
Definition: c.h:246
#define PG_GETARG_CASH(n)
Definition: cash.h:22
char * c
int64 Cash
Definition: cash.h:17
int i
#define PG_RETURN_CASH(x)
Definition: cash.h:23
Datum cash_mul_int8 ( PG_FUNCTION_ARGS  )

Definition at line 765 of file cash.c.

References i, PG_GETARG_CASH, PG_GETARG_INT64, and PG_RETURN_CASH.

766 {
767  Cash c = PG_GETARG_CASH(0);
768  int64 i = PG_GETARG_INT64(1);
769  Cash result;
770 
771  result = c * i;
772  PG_RETURN_CASH(result);
773 }
#define PG_GETARG_CASH(n)
Definition: cash.h:22
char * c
int64 Cash
Definition: cash.h:17
int i
#define PG_RETURN_CASH(x)
Definition: cash.h:23
#define PG_GETARG_INT64(n)
Definition: fmgr.h:247
Datum cash_ne ( PG_FUNCTION_ARGS  )

Definition at line 549 of file cash.c.

References PG_GETARG_CASH, and PG_RETURN_BOOL.

550 {
551  Cash c1 = PG_GETARG_CASH(0);
552  Cash c2 = PG_GETARG_CASH(1);
553 
554  PG_RETURN_BOOL(c1 != c2);
555 }
#define PG_GETARG_CASH(n)
Definition: cash.h:22
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:319
int64 Cash
Definition: cash.h:17
Datum cash_numeric ( PG_FUNCTION_ARGS  )

Definition at line 1033 of file cash.c.

References DatumGetNumeric, DirectFunctionCall1, DirectFunctionCall2, i, Int32GetDatum, Int64GetDatum(), int8_numeric(), numeric_div(), numeric_round(), numeric_scale(), PG_GETARG_CASH, PG_RETURN_NUMERIC, PGLC_localeconv(), and scale.

1034 {
1035  Cash money = PG_GETARG_CASH(0);
1036  Numeric result;
1037  int fpoint;
1038  int64 scale;
1039  int i;
1040  Datum amount;
1042  Datum quotient;
1043  struct lconv *lconvert = PGLC_localeconv();
1044 
1045  /* see comments about frac_digits in cash_in() */
1046  fpoint = lconvert->frac_digits;
1047  if (fpoint < 0 || fpoint > 10)
1048  fpoint = 2;
1049 
1050  /* compute required scale factor */
1051  scale = 1;
1052  for (i = 0; i < fpoint; i++)
1053  scale *= 10;
1054 
1055  /* form the result as money / scale */
1057  numeric_scale = DirectFunctionCall1(int8_numeric, Int64GetDatum(scale));
1058  quotient = DirectFunctionCall2(numeric_div, amount, numeric_scale);
1059 
1060  /* forcibly round to exactly the intended number of digits */
1062  quotient,
1063  Int32GetDatum(fpoint)));
1064 
1065  PG_RETURN_NUMERIC(result);
1066 }
#define PG_RETURN_NUMERIC(x)
Definition: numeric.h:54
int scale
Definition: pgbench.c:106
Datum numeric_round(PG_FUNCTION_ARGS)
Definition: numeric.c:1221
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:585
Datum numeric_scale(PG_FUNCTION_ARGS)
Definition: numeric.c:2951
Datum int8_numeric(PG_FUNCTION_ARGS)
Definition: numeric.c:3038
Datum numeric_div(PG_FUNCTION_ARGS)
Definition: numeric.c:2436
#define PG_GETARG_CASH(n)
Definition: cash.h:22
Datum Int64GetDatum(int64 X)
Definition: fmgr.c:1786
uintptr_t Datum
Definition: postgres.h:372
#define DatumGetNumeric(X)
Definition: numeric.h:49
struct lconv * PGLC_localeconv(void)
Definition: pg_locale.c:483
int64 Cash
Definition: cash.h:17
#define Int32GetDatum(X)
Definition: postgres.h:485
int i
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:587
Datum cash_out ( PG_FUNCTION_ARGS  )

Definition at line 311 of file cash.c.

References buf, PG_GETARG_CASH, PG_RETURN_CSTRING, PGLC_localeconv(), psprintf(), and value.

312 {
314  char *result;
315  char buf[128];
316  char *bufptr;
317  int digit_pos;
318  int points,
319  mon_group;
320  char dsymbol;
321  const char *ssymbol,
322  *csymbol,
323  *signsymbol;
324  char sign_posn,
325  cs_precedes,
326  sep_by_space;
327  struct lconv *lconvert = PGLC_localeconv();
328 
329  /* see comments about frac_digits in cash_in() */
330  points = lconvert->frac_digits;
331  if (points < 0 || points > 10)
332  points = 2; /* best guess in this case, I think */
333 
334  /*
335  * As with frac_digits, must apply a range check to mon_grouping to avoid
336  * being fooled by variant CHAR_MAX values.
337  */
338  mon_group = *lconvert->mon_grouping;
339  if (mon_group <= 0 || mon_group > 6)
340  mon_group = 3;
341 
342  /* we restrict dsymbol to be a single byte, but not the other symbols */
343  if (*lconvert->mon_decimal_point != '\0' &&
344  lconvert->mon_decimal_point[1] == '\0')
345  dsymbol = *lconvert->mon_decimal_point;
346  else
347  dsymbol = '.';
348  if (*lconvert->mon_thousands_sep != '\0')
349  ssymbol = lconvert->mon_thousands_sep;
350  else /* ssymbol should not equal dsymbol */
351  ssymbol = (dsymbol != ',') ? "," : ".";
352  csymbol = (*lconvert->currency_symbol != '\0') ? lconvert->currency_symbol : "$";
353 
354  if (value < 0)
355  {
356  /* make the amount positive for digit-reconstruction loop */
357  value = -value;
358  /* set up formatting data */
359  signsymbol = (*lconvert->negative_sign != '\0') ? lconvert->negative_sign : "-";
360  sign_posn = lconvert->n_sign_posn;
361  cs_precedes = lconvert->n_cs_precedes;
362  sep_by_space = lconvert->n_sep_by_space;
363  }
364  else
365  {
366  signsymbol = lconvert->positive_sign;
367  sign_posn = lconvert->p_sign_posn;
368  cs_precedes = lconvert->p_cs_precedes;
369  sep_by_space = lconvert->p_sep_by_space;
370  }
371 
372  /* we build the digits+decimal-point+sep string right-to-left in buf[] */
373  bufptr = buf + sizeof(buf) - 1;
374  *bufptr = '\0';
375 
376  /*
377  * Generate digits till there are no non-zero digits left and we emitted
378  * at least one to the left of the decimal point. digit_pos is the
379  * current digit position, with zero as the digit just left of the decimal
380  * point, increasing to the right.
381  */
382  digit_pos = points;
383  do
384  {
385  if (points && digit_pos == 0)
386  {
387  /* insert decimal point, but not if value cannot be fractional */
388  *(--bufptr) = dsymbol;
389  }
390  else if (digit_pos < 0 && (digit_pos % mon_group) == 0)
391  {
392  /* insert thousands sep, but only to left of radix point */
393  bufptr -= strlen(ssymbol);
394  memcpy(bufptr, ssymbol, strlen(ssymbol));
395  }
396 
397  *(--bufptr) = ((uint64) value % 10) + '0';
398  value = ((uint64) value) / 10;
399  digit_pos--;
400  } while (value || digit_pos >= 0);
401 
402  /*----------
403  * Now, attach currency symbol and sign symbol in the correct order.
404  *
405  * The POSIX spec defines these values controlling this code:
406  *
407  * p/n_sign_posn:
408  * 0 Parentheses enclose the quantity and the currency_symbol.
409  * 1 The sign string precedes the quantity and the currency_symbol.
410  * 2 The sign string succeeds the quantity and the currency_symbol.
411  * 3 The sign string precedes the currency_symbol.
412  * 4 The sign string succeeds the currency_symbol.
413  *
414  * p/n_cs_precedes: 0 means currency symbol after value, else before it.
415  *
416  * p/n_sep_by_space:
417  * 0 No <space> separates the currency symbol and value.
418  * 1 If the currency symbol and sign string are adjacent, a <space>
419  * separates them from the value; otherwise, a <space> separates
420  * the currency symbol from the value.
421  * 2 If the currency symbol and sign string are adjacent, a <space>
422  * separates them; otherwise, a <space> separates the sign string
423  * from the value.
424  *----------
425  */
426  switch (sign_posn)
427  {
428  case 0:
429  if (cs_precedes)
430  result = psprintf("(%s%s%s)",
431  csymbol,
432  (sep_by_space == 1) ? " " : "",
433  bufptr);
434  else
435  result = psprintf("(%s%s%s)",
436  bufptr,
437  (sep_by_space == 1) ? " " : "",
438  csymbol);
439  break;
440  case 1:
441  default:
442  if (cs_precedes)
443  result = psprintf("%s%s%s%s%s",
444  signsymbol,
445  (sep_by_space == 2) ? " " : "",
446  csymbol,
447  (sep_by_space == 1) ? " " : "",
448  bufptr);
449  else
450  result = psprintf("%s%s%s%s%s",
451  signsymbol,
452  (sep_by_space == 2) ? " " : "",
453  bufptr,
454  (sep_by_space == 1) ? " " : "",
455  csymbol);
456  break;
457  case 2:
458  if (cs_precedes)
459  result = psprintf("%s%s%s%s%s",
460  csymbol,
461  (sep_by_space == 1) ? " " : "",
462  bufptr,
463  (sep_by_space == 2) ? " " : "",
464  signsymbol);
465  else
466  result = psprintf("%s%s%s%s%s",
467  bufptr,
468  (sep_by_space == 1) ? " " : "",
469  csymbol,
470  (sep_by_space == 2) ? " " : "",
471  signsymbol);
472  break;
473  case 3:
474  if (cs_precedes)
475  result = psprintf("%s%s%s%s%s",
476  signsymbol,
477  (sep_by_space == 2) ? " " : "",
478  csymbol,
479  (sep_by_space == 1) ? " " : "",
480  bufptr);
481  else
482  result = psprintf("%s%s%s%s%s",
483  bufptr,
484  (sep_by_space == 1) ? " " : "",
485  signsymbol,
486  (sep_by_space == 2) ? " " : "",
487  csymbol);
488  break;
489  case 4:
490  if (cs_precedes)
491  result = psprintf("%s%s%s%s%s",
492  csymbol,
493  (sep_by_space == 2) ? " " : "",
494  signsymbol,
495  (sep_by_space == 1) ? " " : "",
496  bufptr);
497  else
498  result = psprintf("%s%s%s%s%s",
499  bufptr,
500  (sep_by_space == 1) ? " " : "",
501  csymbol,
502  (sep_by_space == 2) ? " " : "",
503  signsymbol);
504  break;
505  }
506 
507  PG_RETURN_CSTRING(result);
508 }
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46
#define PG_GETARG_CASH(n)
Definition: cash.h:22
static struct @121 value
static char * buf
Definition: pg_test_fsync.c:67
#define PG_RETURN_CSTRING(x)
Definition: fmgr.h:322
struct lconv * PGLC_localeconv(void)
Definition: pg_locale.c:483
int64 Cash
Definition: cash.h:17
Datum cash_pl ( PG_FUNCTION_ARGS  )

Definition at line 612 of file cash.c.

References PG_GETARG_CASH, and PG_RETURN_CASH.

613 {
614  Cash c1 = PG_GETARG_CASH(0);
615  Cash c2 = PG_GETARG_CASH(1);
616  Cash result;
617 
618  result = c1 + c2;
619 
620  PG_RETURN_CASH(result);
621 }
#define PG_GETARG_CASH(n)
Definition: cash.h:22
int64 Cash
Definition: cash.h:17
#define PG_RETURN_CASH(x)
Definition: cash.h:23
Datum cash_recv ( PG_FUNCTION_ARGS  )

Definition at line 514 of file cash.c.

References buf, PG_GETARG_POINTER, PG_RETURN_CASH, and pq_getmsgint64().

515 {
517 
519 }
StringInfoData * StringInfo
Definition: stringinfo.h:43
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:241
static char * buf
Definition: pg_test_fsync.c:67
int64 Cash
Definition: cash.h:17
int64 pq_getmsgint64(StringInfo msg)
Definition: pqformat.c:455
#define PG_RETURN_CASH(x)
Definition: cash.h:23
Datum cash_send ( PG_FUNCTION_ARGS  )

Definition at line 525 of file cash.c.

References buf, PG_GETARG_CASH, PG_RETURN_BYTEA_P, pq_begintypsend(), pq_endtypsend(), and pq_sendint64().

526 {
527  Cash arg1 = PG_GETARG_CASH(0);
529 
530  pq_begintypsend(&buf);
531  pq_sendint64(&buf, arg1);
533 }
void pq_begintypsend(StringInfo buf)
Definition: pqformat.c:328
static void pq_sendint64(StringInfo buf, int64 i)
Definition: pqformat.h:156
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:330
bytea * pq_endtypsend(StringInfo buf)
Definition: pqformat.c:348
#define PG_GETARG_CASH(n)
Definition: cash.h:22
static char * buf
Definition: pg_test_fsync.c:67
int64 Cash
Definition: cash.h:17
Datum cash_words ( PG_FUNCTION_ARGS  )

Definition at line 946 of file cash.c.

References buf, cstring_to_text(), num_word(), PG_GETARG_CASH, PG_RETURN_TEXT_P, pg_toupper(), val, and value.

947 {
949  uint64 val;
950  char buf[256];
951  char *p = buf;
952  Cash m0;
953  Cash m1;
954  Cash m2;
955  Cash m3;
956  Cash m4;
957  Cash m5;
958  Cash m6;
959 
960  /* work with positive numbers */
961  if (value < 0)
962  {
963  value = -value;
964  strcpy(buf, "minus ");
965  p += 6;
966  }
967  else
968  buf[0] = '\0';
969 
970  /* Now treat as unsigned, to avoid trouble at INT_MIN */
971  val = (uint64) value;
972 
973  m0 = val % INT64CONST(100); /* cents */
974  m1 = (val / INT64CONST(100)) % 1000; /* hundreds */
975  m2 = (val / INT64CONST(100000)) % 1000; /* thousands */
976  m3 = (val / INT64CONST(100000000)) % 1000; /* millions */
977  m4 = (val / INT64CONST(100000000000)) % 1000; /* billions */
978  m5 = (val / INT64CONST(100000000000000)) % 1000; /* trillions */
979  m6 = (val / INT64CONST(100000000000000000)) % 1000; /* quadrillions */
980 
981  if (m6)
982  {
983  strcat(buf, num_word(m6));
984  strcat(buf, " quadrillion ");
985  }
986 
987  if (m5)
988  {
989  strcat(buf, num_word(m5));
990  strcat(buf, " trillion ");
991  }
992 
993  if (m4)
994  {
995  strcat(buf, num_word(m4));
996  strcat(buf, " billion ");
997  }
998 
999  if (m3)
1000  {
1001  strcat(buf, num_word(m3));
1002  strcat(buf, " million ");
1003  }
1004 
1005  if (m2)
1006  {
1007  strcat(buf, num_word(m2));
1008  strcat(buf, " thousand ");
1009  }
1010 
1011  if (m1)
1012  strcat(buf, num_word(m1));
1013 
1014  if (!*p)
1015  strcat(buf, "zero");
1016 
1017  strcat(buf, (val / 100) == 1 ? " dollar and " : " dollars and ");
1018  strcat(buf, num_word(m0));
1019  strcat(buf, m0 == 1 ? " cent" : " cents");
1020 
1021  /* capitalize output */
1022  buf[0] = pg_toupper((unsigned char) buf[0]);
1023 
1024  /* return as text datum */
1026 }
static const char * num_word(Cash value)
Definition: cash.c:38
#define PG_GETARG_CASH(n)
Definition: cash.h:22
static struct @121 value
static char * buf
Definition: pg_test_fsync.c:67
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:331
text * cstring_to_text(const char *s)
Definition: varlena.c:149
int64 Cash
Definition: cash.h:17
unsigned char pg_toupper(unsigned char ch)
Definition: pgstrcasecmp.c:105
long val
Definition: informix.c:689
Datum cashlarger ( PG_FUNCTION_ARGS  )

Definition at line 915 of file cash.c.

References PG_GETARG_CASH, and PG_RETURN_CASH.

916 {
917  Cash c1 = PG_GETARG_CASH(0);
918  Cash c2 = PG_GETARG_CASH(1);
919  Cash result;
920 
921  result = (c1 > c2) ? c1 : c2;
922 
923  PG_RETURN_CASH(result);
924 }
#define PG_GETARG_CASH(n)
Definition: cash.h:22
int64 Cash
Definition: cash.h:17
#define PG_RETURN_CASH(x)
Definition: cash.h:23
Datum cashsmaller ( PG_FUNCTION_ARGS  )

Definition at line 930 of file cash.c.

References PG_GETARG_CASH, and PG_RETURN_CASH.

931 {
932  Cash c1 = PG_GETARG_CASH(0);
933  Cash c2 = PG_GETARG_CASH(1);
934  Cash result;
935 
936  result = (c1 < c2) ? c1 : c2;
937 
938  PG_RETURN_CASH(result);
939 }
#define PG_GETARG_CASH(n)
Definition: cash.h:22
int64 Cash
Definition: cash.h:17
#define PG_RETURN_CASH(x)
Definition: cash.h:23
Datum flt4_mul_cash ( PG_FUNCTION_ARGS  )

Definition at line 729 of file cash.c.

References PG_GETARG_CASH, PG_GETARG_FLOAT4, PG_RETURN_CASH, and rint().

730 {
731  float4 f = PG_GETARG_FLOAT4(0);
732  Cash c = PG_GETARG_CASH(1);
733  Cash result;
734 
735  result = rint((float8) f * c);
736  PG_RETURN_CASH(result);
737 }
double float8
Definition: c.h:375
#define PG_GETARG_CASH(n)
Definition: cash.h:22
char * c
double rint(double x)
Definition: rint.c:22
#define PG_GETARG_FLOAT4(n)
Definition: fmgr.h:245
float float4
Definition: c.h:374
int64 Cash
Definition: cash.h:17
#define PG_RETURN_CASH(x)
Definition: cash.h:23
Datum flt8_mul_cash ( PG_FUNCTION_ARGS  )

Definition at line 679 of file cash.c.

References PG_GETARG_CASH, PG_GETARG_FLOAT8, PG_RETURN_CASH, and rint().

680 {
681  float8 f = PG_GETARG_FLOAT8(0);
682  Cash c = PG_GETARG_CASH(1);
683  Cash result;
684 
685  result = rint(f * c);
686  PG_RETURN_CASH(result);
687 }
#define PG_GETARG_FLOAT8(n)
Definition: fmgr.h:246
double float8
Definition: c.h:375
#define PG_GETARG_CASH(n)
Definition: cash.h:22
char * c
double rint(double x)
Definition: rint.c:22
int64 Cash
Definition: cash.h:17
#define PG_RETURN_CASH(x)
Definition: cash.h:23
Datum int2_mul_cash ( PG_FUNCTION_ARGS  )

Definition at line 881 of file cash.c.

References PG_GETARG_CASH, PG_GETARG_INT16, and PG_RETURN_CASH.

882 {
883  int16 s = PG_GETARG_INT16(0);
884  Cash c = PG_GETARG_CASH(1);
885  Cash result;
886 
887  result = s * c;
888  PG_RETURN_CASH(result);
889 }
signed short int16
Definition: c.h:245
#define PG_GETARG_CASH(n)
Definition: cash.h:22
char * c
#define PG_GETARG_INT16(n)
Definition: fmgr.h:236
int64 Cash
Definition: cash.h:17
#define PG_RETURN_CASH(x)
Definition: cash.h:23
Datum int4_cash ( PG_FUNCTION_ARGS  )

Definition at line 1106 of file cash.c.

References DatumGetInt64, DirectFunctionCall2, i, Int64GetDatum(), int8mul(), PG_GETARG_INT32, PG_RETURN_CASH, PGLC_localeconv(), and scale.

1107 {
1108  int32 amount = PG_GETARG_INT32(0);
1109  Cash result;
1110  int fpoint;
1111  int64 scale;
1112  int i;
1113  struct lconv *lconvert = PGLC_localeconv();
1114 
1115  /* see comments about frac_digits in cash_in() */
1116  fpoint = lconvert->frac_digits;
1117  if (fpoint < 0 || fpoint > 10)
1118  fpoint = 2;
1119 
1120  /* compute required scale factor */
1121  scale = 1;
1122  for (i = 0; i < fpoint; i++)
1123  scale *= 10;
1124 
1125  /* compute amount * scale, checking for overflow */
1127  Int64GetDatum(scale)));
1128 
1129  PG_RETURN_CASH(result);
1130 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:234
int scale
Definition: pgbench.c:106
signed int int32
Definition: c.h:246
#define DatumGetInt64(X)
Definition: postgres.h:613
Datum int8mul(PG_FUNCTION_ARGS)
Definition: int8.c:555
Datum Int64GetDatum(int64 X)
Definition: fmgr.c:1786
struct lconv * PGLC_localeconv(void)
Definition: pg_locale.c:483
int64 Cash
Definition: cash.h:17
int i
#define PG_RETURN_CASH(x)
Definition: cash.h:23
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:587
Datum int4_mul_cash ( PG_FUNCTION_ARGS  )

Definition at line 830 of file cash.c.

References i, PG_GETARG_CASH, PG_GETARG_INT32, and PG_RETURN_CASH.

831 {
832  int32 i = PG_GETARG_INT32(0);
833  Cash c = PG_GETARG_CASH(1);
834  Cash result;
835 
836  result = i * c;
837  PG_RETURN_CASH(result);
838 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:234
signed int int32
Definition: c.h:246
#define PG_GETARG_CASH(n)
Definition: cash.h:22
char * c
int64 Cash
Definition: cash.h:17
int i
#define PG_RETURN_CASH(x)
Definition: cash.h:23
Datum int8_cash ( PG_FUNCTION_ARGS  )

Definition at line 1136 of file cash.c.

References DatumGetInt64, DirectFunctionCall2, i, Int64GetDatum(), int8mul(), PG_GETARG_INT64, PG_RETURN_CASH, PGLC_localeconv(), and scale.

1137 {
1138  int64 amount = PG_GETARG_INT64(0);
1139  Cash result;
1140  int fpoint;
1141  int64 scale;
1142  int i;
1143  struct lconv *lconvert = PGLC_localeconv();
1144 
1145  /* see comments about frac_digits in cash_in() */
1146  fpoint = lconvert->frac_digits;
1147  if (fpoint < 0 || fpoint > 10)
1148  fpoint = 2;
1149 
1150  /* compute required scale factor */
1151  scale = 1;
1152  for (i = 0; i < fpoint; i++)
1153  scale *= 10;
1154 
1155  /* compute amount * scale, checking for overflow */
1157  Int64GetDatum(scale)));
1158 
1159  PG_RETURN_CASH(result);
1160 }
int scale
Definition: pgbench.c:106
#define DatumGetInt64(X)
Definition: postgres.h:613
Datum int8mul(PG_FUNCTION_ARGS)
Definition: int8.c:555
Datum Int64GetDatum(int64 X)
Definition: fmgr.c:1786
struct lconv * PGLC_localeconv(void)
Definition: pg_locale.c:483
int64 Cash
Definition: cash.h:17
int i
#define PG_RETURN_CASH(x)
Definition: cash.h:23
#define PG_GETARG_INT64(n)
Definition: fmgr.h:247
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:587
Datum int8_mul_cash ( PG_FUNCTION_ARGS  )

Definition at line 780 of file cash.c.

References i, PG_GETARG_CASH, PG_GETARG_INT64, and PG_RETURN_CASH.

781 {
782  int64 i = PG_GETARG_INT64(0);
783  Cash c = PG_GETARG_CASH(1);
784  Cash result;
785 
786  result = i * c;
787  PG_RETURN_CASH(result);
788 }
#define PG_GETARG_CASH(n)
Definition: cash.h:22
char * c
int64 Cash
Definition: cash.h:17
int i
#define PG_RETURN_CASH(x)
Definition: cash.h:23
#define PG_GETARG_INT64(n)
Definition: fmgr.h:247
static const char* num_word ( Cash  value)
static

Definition at line 38 of file cash.c.

References buf, and value.

Referenced by cash_words().

39 {
40  static char buf[128];
41  static const char *small[] = {
42  "zero", "one", "two", "three", "four", "five", "six", "seven",
43  "eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen",
44  "fifteen", "sixteen", "seventeen", "eighteen", "nineteen", "twenty",
45  "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety"
46  };
47  const char **big = small + 18;
48  int tu = value % 100;
49 
50  /* deal with the simple cases first */
51  if (value <= 20)
52  return small[value];
53 
54  /* is it an even multiple of 100? */
55  if (!tu)
56  {
57  sprintf(buf, "%s hundred", small[value / 100]);
58  return buf;
59  }
60 
61  /* more than 99? */
62  if (value > 99)
63  {
64  /* is it an even multiple of 10 other than 10? */
65  if (value % 10 == 0 && tu > 10)
66  sprintf(buf, "%s hundred %s",
67  small[value / 100], big[tu / 10]);
68  else if (tu < 20)
69  sprintf(buf, "%s hundred and %s",
70  small[value / 100], small[tu]);
71  else
72  sprintf(buf, "%s hundred %s %s",
73  small[value / 100], big[tu / 10], small[tu % 10]);
74  }
75  else
76  {
77  /* is it an even multiple of 10 other than 10? */
78  if (value % 10 == 0 && tu > 10)
79  sprintf(buf, "%s", big[tu / 10]);
80  else if (tu < 20)
81  sprintf(buf, "%s", small[tu]);
82  else
83  sprintf(buf, "%s %s", big[tu / 10], small[tu % 10]);
84  }
85 
86  return buf;
87 } /* num_word() */
static struct @121 value
static char * buf
Definition: pg_test_fsync.c:67
Datum numeric_cash ( PG_FUNCTION_ARGS  )

Definition at line 1072 of file cash.c.

References DatumGetInt64, DirectFunctionCall1, DirectFunctionCall2, i, Int64GetDatum(), int8_numeric(), numeric_int8(), numeric_mul(), numeric_scale(), PG_GETARG_DATUM, PG_RETURN_CASH, PGLC_localeconv(), and scale.

1073 {
1074  Datum amount = PG_GETARG_DATUM(0);
1075  Cash result;
1076  int fpoint;
1077  int64 scale;
1078  int i;
1080  struct lconv *lconvert = PGLC_localeconv();
1081 
1082  /* see comments about frac_digits in cash_in() */
1083  fpoint = lconvert->frac_digits;
1084  if (fpoint < 0 || fpoint > 10)
1085  fpoint = 2;
1086 
1087  /* compute required scale factor */
1088  scale = 1;
1089  for (i = 0; i < fpoint; i++)
1090  scale *= 10;
1091 
1092  /* multiply the input amount by scale factor */
1093  numeric_scale = DirectFunctionCall1(int8_numeric, Int64GetDatum(scale));
1094  amount = DirectFunctionCall2(numeric_mul, amount, numeric_scale);
1095 
1096  /* note that numeric_int8 will round to nearest integer for us */
1097  result = DatumGetInt64(DirectFunctionCall1(numeric_int8, amount));
1098 
1099  PG_RETURN_CASH(result);
1100 }
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:233
Datum numeric_int8(PG_FUNCTION_ARGS)
Definition: numeric.c:3057
int scale
Definition: pgbench.c:106
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:585
Datum numeric_scale(PG_FUNCTION_ARGS)
Definition: numeric.c:2951
Datum int8_numeric(PG_FUNCTION_ARGS)
Definition: numeric.c:3038
#define DatumGetInt64(X)
Definition: postgres.h:613
Datum Int64GetDatum(int64 X)
Definition: fmgr.c:1786
Datum numeric_mul(PG_FUNCTION_ARGS)
Definition: numeric.c:2394
uintptr_t Datum
Definition: postgres.h:372
struct lconv * PGLC_localeconv(void)
Definition: pg_locale.c:483
int64 Cash
Definition: cash.h:17
int i
#define PG_RETURN_CASH(x)
Definition: cash.h:23
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:587