1--
2-- MONEY
3--
4-- Note that we assume lc_monetary has been set to C.
5--
6CREATE TABLE money_data (m money);
7INSERT INTO money_data VALUES ('123');
8SELECT * FROM money_data;
9    m
10---------
11 $123.00
12(1 row)
13
14SELECT m + '123' FROM money_data;
15 ?column?
16----------
17  $246.00
18(1 row)
19
20SELECT m + '123.45' FROM money_data;
21 ?column?
22----------
23  $246.45
24(1 row)
25
26SELECT m - '123.45' FROM money_data;
27 ?column?
28----------
29   -$0.45
30(1 row)
31
32SELECT m / '2'::money FROM money_data;
33 ?column?
34----------
35     61.5
36(1 row)
37
38SELECT m * 2 FROM money_data;
39 ?column?
40----------
41  $246.00
42(1 row)
43
44SELECT 2 * m FROM money_data;
45 ?column?
46----------
47  $246.00
48(1 row)
49
50SELECT m / 2 FROM money_data;
51 ?column?
52----------
53   $61.50
54(1 row)
55
56SELECT m * 2::int2 FROM money_data;
57 ?column?
58----------
59  $246.00
60(1 row)
61
62SELECT 2::int2 * m FROM money_data;
63 ?column?
64----------
65  $246.00
66(1 row)
67
68SELECT m / 2::int2 FROM money_data;
69 ?column?
70----------
71   $61.50
72(1 row)
73
74SELECT m * 2::int8 FROM money_data;
75 ?column?
76----------
77  $246.00
78(1 row)
79
80SELECT 2::int8 * m FROM money_data;
81 ?column?
82----------
83  $246.00
84(1 row)
85
86SELECT m / 2::int8 FROM money_data;
87 ?column?
88----------
89   $61.50
90(1 row)
91
92SELECT m * 2::float8 FROM money_data;
93 ?column?
94----------
95  $246.00
96(1 row)
97
98SELECT 2::float8 * m FROM money_data;
99 ?column?
100----------
101  $246.00
102(1 row)
103
104SELECT m / 2::float8 FROM money_data;
105 ?column?
106----------
107   $61.50
108(1 row)
109
110SELECT m * 2::float4 FROM money_data;
111 ?column?
112----------
113  $246.00
114(1 row)
115
116SELECT 2::float4 * m FROM money_data;
117 ?column?
118----------
119  $246.00
120(1 row)
121
122SELECT m / 2::float4 FROM money_data;
123 ?column?
124----------
125   $61.50
126(1 row)
127
128-- All true
129SELECT m = '$123.00' FROM money_data;
130 ?column?
131----------
132 t
133(1 row)
134
135SELECT m != '$124.00' FROM money_data;
136 ?column?
137----------
138 t
139(1 row)
140
141SELECT m <= '$123.00' FROM money_data;
142 ?column?
143----------
144 t
145(1 row)
146
147SELECT m >= '$123.00' FROM money_data;
148 ?column?
149----------
150 t
151(1 row)
152
153SELECT m < '$124.00' FROM money_data;
154 ?column?
155----------
156 t
157(1 row)
158
159SELECT m > '$122.00' FROM money_data;
160 ?column?
161----------
162 t
163(1 row)
164
165-- All false
166SELECT m = '$123.01' FROM money_data;
167 ?column?
168----------
169 f
170(1 row)
171
172SELECT m != '$123.00' FROM money_data;
173 ?column?
174----------
175 f
176(1 row)
177
178SELECT m <= '$122.99' FROM money_data;
179 ?column?
180----------
181 f
182(1 row)
183
184SELECT m >= '$123.01' FROM money_data;
185 ?column?
186----------
187 f
188(1 row)
189
190SELECT m > '$124.00' FROM money_data;
191 ?column?
192----------
193 f
194(1 row)
195
196SELECT m < '$122.00' FROM money_data;
197 ?column?
198----------
199 f
200(1 row)
201
202SELECT cashlarger(m, '$124.00') FROM money_data;
203 cashlarger
204------------
205    $124.00
206(1 row)
207
208SELECT cashsmaller(m, '$124.00') FROM money_data;
209 cashsmaller
210-------------
211     $123.00
212(1 row)
213
214SELECT cash_words(m) FROM money_data;
215                   cash_words
216-------------------------------------------------
217 One hundred twenty three dollars and zero cents
218(1 row)
219
220SELECT cash_words(m + '1.23') FROM money_data;
221                       cash_words
222--------------------------------------------------------
223 One hundred twenty four dollars and twenty three cents
224(1 row)
225
226DELETE FROM money_data;
227INSERT INTO money_data VALUES ('$123.45');
228SELECT * FROM money_data;
229    m
230---------
231 $123.45
232(1 row)
233
234DELETE FROM money_data;
235INSERT INTO money_data VALUES ('$123.451');
236SELECT * FROM money_data;
237    m
238---------
239 $123.45
240(1 row)
241
242DELETE FROM money_data;
243INSERT INTO money_data VALUES ('$123.454');
244SELECT * FROM money_data;
245    m
246---------
247 $123.45
248(1 row)
249
250DELETE FROM money_data;
251INSERT INTO money_data VALUES ('$123.455');
252SELECT * FROM money_data;
253    m
254---------
255 $123.46
256(1 row)
257
258DELETE FROM money_data;
259INSERT INTO money_data VALUES ('$123.456');
260SELECT * FROM money_data;
261    m
262---------
263 $123.46
264(1 row)
265
266DELETE FROM money_data;
267INSERT INTO money_data VALUES ('$123.459');
268SELECT * FROM money_data;
269    m
270---------
271 $123.46
272(1 row)
273
274-- input checks
275SELECT '1234567890'::money;
276       money
277-------------------
278 $1,234,567,890.00
279(1 row)
280
281SELECT '12345678901234567'::money;
282           money
283----------------------------
284 $12,345,678,901,234,567.00
285(1 row)
286
287SELECT '123456789012345678'::money;
288ERROR:  value "123456789012345678" is out of range for type money
289LINE 1: SELECT '123456789012345678'::money;
290               ^
291SELECT '9223372036854775807'::money;
292ERROR:  value "9223372036854775807" is out of range for type money
293LINE 1: SELECT '9223372036854775807'::money;
294               ^
295SELECT '-12345'::money;
296    money
297-------------
298 -$12,345.00
299(1 row)
300
301SELECT '-1234567890'::money;
302       money
303--------------------
304 -$1,234,567,890.00
305(1 row)
306
307SELECT '-12345678901234567'::money;
308            money
309-----------------------------
310 -$12,345,678,901,234,567.00
311(1 row)
312
313SELECT '-123456789012345678'::money;
314ERROR:  value "-123456789012345678" is out of range for type money
315LINE 1: SELECT '-123456789012345678'::money;
316               ^
317SELECT '-9223372036854775808'::money;
318ERROR:  value "-9223372036854775808" is out of range for type money
319LINE 1: SELECT '-9223372036854775808'::money;
320               ^
321-- special characters
322SELECT '(1)'::money;
323 money
324--------
325 -$1.00
326(1 row)
327
328SELECT '($123,456.78)'::money;
329    money
330--------------
331 -$123,456.78
332(1 row)
333
334-- documented minimums and maximums
335SELECT '-92233720368547758.08'::money;
336            money
337-----------------------------
338 -$92,233,720,368,547,758.08
339(1 row)
340
341SELECT '92233720368547758.07'::money;
342           money
343----------------------------
344 $92,233,720,368,547,758.07
345(1 row)
346
347SELECT '-92233720368547758.09'::money;
348ERROR:  value "-92233720368547758.09" is out of range for type money
349LINE 1: SELECT '-92233720368547758.09'::money;
350               ^
351SELECT '92233720368547758.08'::money;
352ERROR:  value "92233720368547758.08" is out of range for type money
353LINE 1: SELECT '92233720368547758.08'::money;
354               ^
355-- rounding
356SELECT '-92233720368547758.085'::money;
357ERROR:  value "-92233720368547758.085" is out of range for type money
358LINE 1: SELECT '-92233720368547758.085'::money;
359               ^
360SELECT '92233720368547758.075'::money;
361ERROR:  value "92233720368547758.075" is out of range for type money
362LINE 1: SELECT '92233720368547758.075'::money;
363               ^
364-- rounding vs. truncation in division
365SELECT '878.08'::money / 11::float8;
366 ?column?
367----------
368   $79.83
369(1 row)
370
371SELECT '878.08'::money / 11::float4;
372 ?column?
373----------
374   $79.83
375(1 row)
376
377SELECT '878.08'::money / 11::bigint;
378 ?column?
379----------
380   $79.82
381(1 row)
382
383SELECT '878.08'::money / 11::int;
384 ?column?
385----------
386   $79.82
387(1 row)
388
389SELECT '878.08'::money / 11::smallint;
390 ?column?
391----------
392   $79.82
393(1 row)
394
395-- check for precision loss in division
396SELECT '90000000000000099.00'::money / 10::bigint;
397         ?column?
398---------------------------
399 $9,000,000,000,000,009.90
400(1 row)
401
402SELECT '90000000000000099.00'::money / 10::int;
403         ?column?
404---------------------------
405 $9,000,000,000,000,009.90
406(1 row)
407
408SELECT '90000000000000099.00'::money / 10::smallint;
409         ?column?
410---------------------------
411 $9,000,000,000,000,009.90
412(1 row)
413
414-- Cast int4/int8/numeric to money
415SELECT 1234567890::money;
416       money
417-------------------
418 $1,234,567,890.00
419(1 row)
420
421SELECT 12345678901234567::money;
422           money
423----------------------------
424 $12,345,678,901,234,567.00
425(1 row)
426
427SELECT (-12345)::money;
428    money
429-------------
430 -$12,345.00
431(1 row)
432
433SELECT (-1234567890)::money;
434       money
435--------------------
436 -$1,234,567,890.00
437(1 row)
438
439SELECT (-12345678901234567)::money;
440            money
441-----------------------------
442 -$12,345,678,901,234,567.00
443(1 row)
444
445SELECT 1234567890::int4::money;
446       money
447-------------------
448 $1,234,567,890.00
449(1 row)
450
451SELECT 12345678901234567::int8::money;
452           money
453----------------------------
454 $12,345,678,901,234,567.00
455(1 row)
456
457SELECT 12345678901234567::numeric::money;
458           money
459----------------------------
460 $12,345,678,901,234,567.00
461(1 row)
462
463SELECT (-1234567890)::int4::money;
464       money
465--------------------
466 -$1,234,567,890.00
467(1 row)
468
469SELECT (-12345678901234567)::int8::money;
470            money
471-----------------------------
472 -$12,345,678,901,234,567.00
473(1 row)
474
475SELECT (-12345678901234567)::numeric::money;
476            money
477-----------------------------
478 -$12,345,678,901,234,567.00
479(1 row)
480
481-- Cast from money to numeric
482SELECT '12345678901234567'::money::numeric;
483       numeric
484----------------------
485 12345678901234567.00
486(1 row)
487
488SELECT '-12345678901234567'::money::numeric;
489        numeric
490-----------------------
491 -12345678901234567.00
492(1 row)
493
494SELECT '92233720368547758.07'::money::numeric;
495       numeric
496----------------------
497 92233720368547758.07
498(1 row)
499
500SELECT '-92233720368547758.08'::money::numeric;
501        numeric
502-----------------------
503 -92233720368547758.08
504(1 row)
505
506