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 <locale.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 593 of file cash.c.

References PG_GETARG_CASH, and PG_RETURN_INT32.

594 {
595  Cash c1 = PG_GETARG_CASH(0);
596  Cash c2 = PG_GETARG_CASH(1);
597 
598  if (c1 > c2)
599  PG_RETURN_INT32(1);
600  else if (c1 == c2)
601  PG_RETURN_INT32(0);
602  else
603  PG_RETURN_INT32(-1);
604 }
#define PG_RETURN_INT32(x)
Definition: fmgr.h:298
#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 643 of file cash.c.

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

644 {
645  Cash dividend = PG_GETARG_CASH(0);
646  Cash divisor = PG_GETARG_CASH(1);
647  float8 quotient;
648 
649  if (divisor == 0)
650  ereport(ERROR,
651  (errcode(ERRCODE_DIVISION_BY_ZERO),
652  errmsg("division by zero")));
653 
654  quotient = (float8) dividend / (float8) divisor;
655  PG_RETURN_FLOAT8(quotient);
656 }
#define PG_RETURN_FLOAT8(x)
Definition: fmgr.h:310
int errcode(int sqlerrcode)
Definition: elog.c:575
#define ERROR
Definition: elog.h:43
double float8
Definition: c.h:377
#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 744 of file cash.c.

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

745 {
746  Cash c = PG_GETARG_CASH(0);
747  float4 f = PG_GETARG_FLOAT4(1);
748  Cash result;
749 
750  if (f == 0.0)
751  ereport(ERROR,
752  (errcode(ERRCODE_DIVISION_BY_ZERO),
753  errmsg("division by zero")));
754 
755  result = rint(c / f);
756  PG_RETURN_CASH(result);
757 }
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
double rint(double x)
Definition: rint.c:22
#define PG_GETARG_FLOAT4(n)
Definition: fmgr.h:236
#define ereport(elevel, rest)
Definition: elog.h:122
float float4
Definition: c.h:376
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 693 of file cash.c.

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

694 {
695  Cash c = PG_GETARG_CASH(0);
696  float8 f = PG_GETARG_FLOAT8(1);
697  Cash result;
698 
699  if (f == 0.0)
700  ereport(ERROR,
701  (errcode(ERRCODE_DIVISION_BY_ZERO),
702  errmsg("division by zero")));
703 
704  result = rint(c / f);
705  PG_RETURN_CASH(result);
706 }
#define PG_GETARG_FLOAT8(n)
Definition: fmgr.h:237
int errcode(int sqlerrcode)
Definition: elog.c:575
#define ERROR
Definition: elog.h:43
double float8
Definition: c.h:377
#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 895 of file cash.c.

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

896 {
897  Cash c = PG_GETARG_CASH(0);
898  int16 s = PG_GETARG_INT16(1);
899  Cash result;
900 
901  if (s == 0)
902  ereport(ERROR,
903  (errcode(ERRCODE_DIVISION_BY_ZERO),
904  errmsg("division by zero")));
905 
906  result = rint(c / s);
907  PG_RETURN_CASH(result);
908 }
signed short int16
Definition: c.h:252
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
double rint(double x)
Definition: rint.c:22
#define ereport(elevel, rest)
Definition: elog.h:122
#define PG_GETARG_INT16(n)
Definition: fmgr.h:227
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 845 of file cash.c.

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

846 {
847  Cash c = PG_GETARG_CASH(0);
848  int32 i = PG_GETARG_INT32(1);
849  Cash result;
850 
851  if (i == 0)
852  ereport(ERROR,
853  (errcode(ERRCODE_DIVISION_BY_ZERO),
854  errmsg("division by zero")));
855 
856  result = rint(c / i);
857 
858  PG_RETURN_CASH(result);
859 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:225
int errcode(int sqlerrcode)
Definition: elog.c:575
signed int int32
Definition: c.h:253
#define ERROR
Definition: elog.h:43
#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
int i
#define PG_RETURN_CASH(x)
Definition: cash.h:23
Datum cash_div_int8 ( PG_FUNCTION_ARGS  )

Definition at line 793 of file cash.c.

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

794 {
795  Cash c = PG_GETARG_CASH(0);
796  int64 i = PG_GETARG_INT64(1);
797  Cash result;
798 
799  if (i == 0)
800  ereport(ERROR,
801  (errcode(ERRCODE_DIVISION_BY_ZERO),
802  errmsg("division by zero")));
803 
804  result = rint(c / i);
805 
806  PG_RETURN_CASH(result);
807 }
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
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
int i
#define PG_RETURN_CASH(x)
Definition: cash.h:23
#define PG_GETARG_INT64(n)
Definition: fmgr.h:238
Datum cash_eq ( PG_FUNCTION_ARGS  )

Definition at line 539 of file cash.c.

References PG_GETARG_CASH, and PG_RETURN_BOOL.

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

Definition at line 584 of file cash.c.

References PG_GETARG_CASH, and PG_RETURN_BOOL.

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

Definition at line 575 of file cash.c.

References PG_GETARG_CASH, and PG_RETURN_BOOL.

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

Definition at line 97 of file cash.c.

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

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

Definition at line 566 of file cash.c.

References PG_GETARG_CASH, and PG_RETURN_BOOL.

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

Definition at line 557 of file cash.c.

References PG_GETARG_CASH, and PG_RETURN_BOOL.

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

Definition at line 627 of file cash.c.

References PG_GETARG_CASH, and PG_RETURN_CASH.

628 {
629  Cash c1 = PG_GETARG_CASH(0);
630  Cash c2 = PG_GETARG_CASH(1);
631  Cash result;
632 
633  result = c1 - c2;
634 
635  PG_RETURN_CASH(result);
636 }
#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 713 of file cash.c.

References PG_GETARG_CASH, PG_GETARG_FLOAT4, and PG_RETURN_CASH.

714 {
715  Cash c = PG_GETARG_CASH(0);
716  float4 f = PG_GETARG_FLOAT4(1);
717  Cash result;
718 
719  result = c * f;
720  PG_RETURN_CASH(result);
721 }
#define PG_GETARG_CASH(n)
Definition: cash.h:22
char * c
#define PG_GETARG_FLOAT4(n)
Definition: fmgr.h:236
float float4
Definition: c.h:376
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 663 of file cash.c.

References PG_GETARG_CASH, PG_GETARG_FLOAT8, and PG_RETURN_CASH.

664 {
665  Cash c = PG_GETARG_CASH(0);
666  float8 f = PG_GETARG_FLOAT8(1);
667  Cash result;
668 
669  result = c * f;
670  PG_RETURN_CASH(result);
671 }
#define PG_GETARG_FLOAT8(n)
Definition: fmgr.h:237
double float8
Definition: c.h:377
#define PG_GETARG_CASH(n)
Definition: cash.h:22
char * c
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 866 of file cash.c.

References PG_GETARG_CASH, PG_GETARG_INT16, and PG_RETURN_CASH.

867 {
868  Cash c = PG_GETARG_CASH(0);
869  int16 s = PG_GETARG_INT16(1);
870  Cash result;
871 
872  result = c * s;
873  PG_RETURN_CASH(result);
874 }
signed short int16
Definition: c.h:252
#define PG_GETARG_CASH(n)
Definition: cash.h:22
char * c
#define PG_GETARG_INT16(n)
Definition: fmgr.h:227
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 814 of file cash.c.

References i, PG_GETARG_CASH, PG_GETARG_INT32, and PG_RETURN_CASH.

815 {
816  Cash c = PG_GETARG_CASH(0);
817  int32 i = PG_GETARG_INT32(1);
818  Cash result;
819 
820  result = c * i;
821  PG_RETURN_CASH(result);
822 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:225
signed int int32
Definition: c.h:253
#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 764 of file cash.c.

References i, PG_GETARG_CASH, PG_GETARG_INT64, and PG_RETURN_CASH.

765 {
766  Cash c = PG_GETARG_CASH(0);
767  int64 i = PG_GETARG_INT64(1);
768  Cash result;
769 
770  result = c * i;
771  PG_RETURN_CASH(result);
772 }
#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:238
Datum cash_ne ( PG_FUNCTION_ARGS  )

Definition at line 548 of file cash.c.

References PG_GETARG_CASH, and PG_RETURN_BOOL.

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

Definition at line 1032 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.

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

Definition at line 310 of file cash.c.

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

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

Definition at line 611 of file cash.c.

References PG_GETARG_CASH, and PG_RETURN_CASH.

612 {
613  Cash c1 = PG_GETARG_CASH(0);
614  Cash c2 = PG_GETARG_CASH(1);
615  Cash result;
616 
617  result = c1 + c2;
618 
619  PG_RETURN_CASH(result);
620 }
#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 513 of file cash.c.

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

514 {
516 
518 }
StringInfoData * StringInfo
Definition: stringinfo.h:46
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:232
static char * buf
Definition: pg_test_fsync.c:65
int64 Cash
Definition: cash.h:17
int64 pq_getmsgint64(StringInfo msg)
Definition: pqformat.c:486
#define PG_RETURN_CASH(x)
Definition: cash.h:23
Datum cash_send ( PG_FUNCTION_ARGS  )

Definition at line 524 of file cash.c.

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

525 {
526  Cash arg1 = PG_GETARG_CASH(0);
528 
529  pq_begintypsend(&buf);
530  pq_sendint64(&buf, arg1);
532 }
void pq_begintypsend(StringInfo buf)
Definition: pqformat.c:359
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:313
bytea * pq_endtypsend(StringInfo buf)
Definition: pqformat.c:379
#define PG_GETARG_CASH(n)
Definition: cash.h:22
static char * buf
Definition: pg_test_fsync.c:65
int64 Cash
Definition: cash.h:17
void pq_sendint64(StringInfo buf, int64 i)
Definition: pqformat.c:271
Datum cash_words ( PG_FUNCTION_ARGS  )

Definition at line 945 of file cash.c.

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

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

References PG_GETARG_CASH, and PG_RETURN_CASH.

915 {
916  Cash c1 = PG_GETARG_CASH(0);
917  Cash c2 = PG_GETARG_CASH(1);
918  Cash result;
919 
920  result = (c1 > c2) ? c1 : c2;
921 
922  PG_RETURN_CASH(result);
923 }
#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 929 of file cash.c.

References PG_GETARG_CASH, and PG_RETURN_CASH.

930 {
931  Cash c1 = PG_GETARG_CASH(0);
932  Cash c2 = PG_GETARG_CASH(1);
933  Cash result;
934 
935  result = (c1 < c2) ? c1 : c2;
936 
937  PG_RETURN_CASH(result);
938 }
#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 728 of file cash.c.

References PG_GETARG_CASH, PG_GETARG_FLOAT4, and PG_RETURN_CASH.

729 {
730  float4 f = PG_GETARG_FLOAT4(0);
731  Cash c = PG_GETARG_CASH(1);
732  Cash result;
733 
734  result = f * c;
735  PG_RETURN_CASH(result);
736 }
#define PG_GETARG_CASH(n)
Definition: cash.h:22
char * c
#define PG_GETARG_FLOAT4(n)
Definition: fmgr.h:236
float float4
Definition: c.h:376
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 678 of file cash.c.

References PG_GETARG_CASH, PG_GETARG_FLOAT8, and PG_RETURN_CASH.

679 {
680  float8 f = PG_GETARG_FLOAT8(0);
681  Cash c = PG_GETARG_CASH(1);
682  Cash result;
683 
684  result = f * c;
685  PG_RETURN_CASH(result);
686 }
#define PG_GETARG_FLOAT8(n)
Definition: fmgr.h:237
double float8
Definition: c.h:377
#define PG_GETARG_CASH(n)
Definition: cash.h:22
char * c
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 880 of file cash.c.

References PG_GETARG_CASH, PG_GETARG_INT16, and PG_RETURN_CASH.

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

Definition at line 1105 of file cash.c.

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

1106 {
1107  int32 amount = PG_GETARG_INT32(0);
1108  Cash result;
1109  int fpoint;
1110  int64 scale;
1111  int i;
1112  struct lconv *lconvert = PGLC_localeconv();
1113 
1114  /* see comments about frac_digits in cash_in() */
1115  fpoint = lconvert->frac_digits;
1116  if (fpoint < 0 || fpoint > 10)
1117  fpoint = 2;
1118 
1119  /* compute required scale factor */
1120  scale = 1;
1121  for (i = 0; i < fpoint; i++)
1122  scale *= 10;
1123 
1124  /* compute amount * scale, checking for overflow */
1126  Int64GetDatum(scale)));
1127 
1128  PG_RETURN_CASH(result);
1129 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:225
int scale
Definition: pgbench.c:106
signed int int32
Definition: c.h:253
#define DatumGetInt64(X)
Definition: postgres.h:615
Datum int8mul(PG_FUNCTION_ARGS)
Definition: int8.c:555
Datum Int64GetDatum(int64 X)
Definition: fmgr.c:2102
struct lconv * PGLC_localeconv(void)
Definition: pg_locale.c:478
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:557
Datum int4_mul_cash ( PG_FUNCTION_ARGS  )

Definition at line 829 of file cash.c.

References i, PG_GETARG_CASH, PG_GETARG_INT32, and PG_RETURN_CASH.

830 {
831  int32 i = PG_GETARG_INT32(0);
832  Cash c = PG_GETARG_CASH(1);
833  Cash result;
834 
835  result = i * c;
836  PG_RETURN_CASH(result);
837 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:225
signed int int32
Definition: c.h:253
#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 1135 of file cash.c.

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

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

Definition at line 779 of file cash.c.

References i, PG_GETARG_CASH, PG_GETARG_INT64, and PG_RETURN_CASH.

780 {
781  int64 i = PG_GETARG_INT64(0);
782  Cash c = PG_GETARG_CASH(1);
783  Cash result;
784 
785  result = i * c;
786  PG_RETURN_CASH(result);
787 }
#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:238
static const char* num_word ( Cash  value)
static

Definition at line 39 of file cash.c.

References buf, and value.

Referenced by cash_words().

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

Definition at line 1071 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.

1072 {
1073  Datum amount = PG_GETARG_DATUM(0);
1074  Cash result;
1075  int fpoint;
1076  int64 scale;
1077  int i;
1079  struct lconv *lconvert = PGLC_localeconv();
1080 
1081  /* see comments about frac_digits in cash_in() */
1082  fpoint = lconvert->frac_digits;
1083  if (fpoint < 0 || fpoint > 10)
1084  fpoint = 2;
1085 
1086  /* compute required scale factor */
1087  scale = 1;
1088  for (i = 0; i < fpoint; i++)
1089  scale *= 10;
1090 
1091  /* multiply the input amount by scale factor */
1092  numeric_scale = DirectFunctionCall1(int8_numeric, Int64GetDatum(scale));
1093  amount = DirectFunctionCall2(numeric_mul, amount, numeric_scale);
1094 
1095  /* note that numeric_int8 will round to nearest integer for us */
1096  result = DatumGetInt64(DirectFunctionCall1(numeric_int8, amount));
1097 
1098  PG_RETURN_CASH(result);
1099 }
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:224
Datum numeric_int8(PG_FUNCTION_ARGS)
Definition: numeric.c:2988
int scale
Definition: pgbench.c:106
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:555
Datum numeric_scale(PG_FUNCTION_ARGS)
Definition: numeric.c:2882
Datum int8_numeric(PG_FUNCTION_ARGS)
Definition: numeric.c:2969
#define DatumGetInt64(X)
Definition: postgres.h:615
Datum Int64GetDatum(int64 X)
Definition: fmgr.c:2102
Datum numeric_mul(PG_FUNCTION_ARGS)
Definition: numeric.c:2325
uintptr_t Datum
Definition: postgres.h:374
struct lconv * PGLC_localeconv(void)
Definition: pg_locale.c:478
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:557