OSDN Git Service

Message editing: remove gratuitous variations in message wording, standardize
[pg-rex/syncrep.git] / src / backend / utils / adt / int8.c
1 /*-------------------------------------------------------------------------
2  *
3  * int8.c
4  *        Internal 64-bit integer operations
5  *
6  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  * IDENTIFICATION
10  *        $Header: /cvsroot/pgsql/src/backend/utils/adt/int8.c,v 1.48 2003/09/25 06:58:04 petere Exp $
11  *
12  *-------------------------------------------------------------------------
13  */
14 #include "postgres.h"
15
16 #include <ctype.h>
17 #include <math.h>
18
19 #include "libpq/pqformat.h"
20 #include "utils/int8.h"
21
22
23 #define MAXINT8LEN              25
24
25
26 /***********************************************************************
27  **
28  **             Routines for 64-bit integers.
29  **
30  ***********************************************************************/
31
32 /*----------------------------------------------------------
33  * Formatting and conversion routines.
34  *---------------------------------------------------------*/
35
36 /*
37  * scanint8 --- try to parse a string into an int8.
38  *
39  * If errorOK is false, ereport a useful error message if the string is bad.
40  * If errorOK is true, just return "false" for bad input.
41  */
42 bool
43 scanint8(const char *str, bool errorOK, int64 *result)
44 {
45         const char *ptr = str;
46         int64           tmp = 0;
47         int                     sign = 1;
48
49         /*
50          * Do our own scan, rather than relying on sscanf which might be
51          * broken for long long.
52          */
53
54         /* skip leading spaces */
55         while (*ptr && isspace((unsigned char) *ptr))
56                 ptr++;
57
58         /* handle sign */
59         if (*ptr == '-')
60         {
61                 ptr++;
62                 sign = -1;
63
64                 /*
65                  * Do an explicit check for INT64_MIN.  Ugly though this is, it's
66                  * cleaner than trying to get the loop below to handle it
67                  * portably.
68                  */
69 #ifndef INT64_IS_BUSTED
70                 if (strcmp(ptr, "9223372036854775808") == 0)
71                 {
72                         *result = -INT64CONST(0x7fffffffffffffff) - 1;
73                         return true;
74                 }
75 #endif
76         }
77         else if (*ptr == '+')
78                 ptr++;
79
80         /* require at least one digit */
81         if (!isdigit((unsigned char) *ptr))
82         {
83                 if (errorOK)
84                         return false;
85                 else
86                         ereport(ERROR,
87                                         (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
88                                   errmsg("invalid input syntax for type bigint: \"%s\"", str)));
89         }
90
91         /* process digits */
92         while (*ptr && isdigit((unsigned char) *ptr))
93         {
94                 int64           newtmp = tmp * 10 + (*ptr++ - '0');
95
96                 if ((newtmp / 10) != tmp)               /* overflow? */
97                 {
98                         if (errorOK)
99                                 return false;
100                         else
101                                 ereport(ERROR,
102                                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
103                                                  errmsg("integer out of range")));
104                 }
105                 tmp = newtmp;
106         }
107
108         /* trailing junk? */
109         if (*ptr)
110         {
111                 if (errorOK)
112                         return false;
113                 else
114                         ereport(ERROR,
115                                         (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
116                                   errmsg("invalid input syntax for type bigint: \"%s\"", str)));
117         }
118
119         *result = (sign < 0) ? -tmp : tmp;
120
121         return true;
122 }
123
124 /* int8in()
125  */
126 Datum
127 int8in(PG_FUNCTION_ARGS)
128 {
129         char       *str = PG_GETARG_CSTRING(0);
130         int64           result;
131
132         (void) scanint8(str, false, &result);
133         PG_RETURN_INT64(result);
134 }
135
136
137 /* int8out()
138  */
139 Datum
140 int8out(PG_FUNCTION_ARGS)
141 {
142         int64           val = PG_GETARG_INT64(0);
143         char       *result;
144         int                     len;
145         char            buf[MAXINT8LEN + 1];
146
147         if ((len = snprintf(buf, MAXINT8LEN, INT64_FORMAT, val)) < 0)
148                 elog(ERROR, "could not format int8");
149
150         result = pstrdup(buf);
151         PG_RETURN_CSTRING(result);
152 }
153
154 /*
155  *              int8recv                        - converts external binary format to int8
156  */
157 Datum
158 int8recv(PG_FUNCTION_ARGS)
159 {
160         StringInfo      buf = (StringInfo) PG_GETARG_POINTER(0);
161
162         PG_RETURN_INT64(pq_getmsgint64(buf));
163 }
164
165 /*
166  *              int8send                        - converts int8 to binary format
167  */
168 Datum
169 int8send(PG_FUNCTION_ARGS)
170 {
171         int64           arg1 = PG_GETARG_INT64(0);
172         StringInfoData buf;
173
174         pq_begintypsend(&buf);
175         pq_sendint64(&buf, arg1);
176         PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
177 }
178
179
180 /*----------------------------------------------------------
181  *      Relational operators for int8s, including cross-data-type comparisons.
182  *---------------------------------------------------------*/
183
184 /* int8relop()
185  * Is val1 relop val2?
186  */
187 Datum
188 int8eq(PG_FUNCTION_ARGS)
189 {
190         int64           val1 = PG_GETARG_INT64(0);
191         int64           val2 = PG_GETARG_INT64(1);
192
193         PG_RETURN_BOOL(val1 == val2);
194 }
195
196 Datum
197 int8ne(PG_FUNCTION_ARGS)
198 {
199         int64           val1 = PG_GETARG_INT64(0);
200         int64           val2 = PG_GETARG_INT64(1);
201
202         PG_RETURN_BOOL(val1 != val2);
203 }
204
205 Datum
206 int8lt(PG_FUNCTION_ARGS)
207 {
208         int64           val1 = PG_GETARG_INT64(0);
209         int64           val2 = PG_GETARG_INT64(1);
210
211         PG_RETURN_BOOL(val1 < val2);
212 }
213
214 Datum
215 int8gt(PG_FUNCTION_ARGS)
216 {
217         int64           val1 = PG_GETARG_INT64(0);
218         int64           val2 = PG_GETARG_INT64(1);
219
220         PG_RETURN_BOOL(val1 > val2);
221 }
222
223 Datum
224 int8le(PG_FUNCTION_ARGS)
225 {
226         int64           val1 = PG_GETARG_INT64(0);
227         int64           val2 = PG_GETARG_INT64(1);
228
229         PG_RETURN_BOOL(val1 <= val2);
230 }
231
232 Datum
233 int8ge(PG_FUNCTION_ARGS)
234 {
235         int64           val1 = PG_GETARG_INT64(0);
236         int64           val2 = PG_GETARG_INT64(1);
237
238         PG_RETURN_BOOL(val1 >= val2);
239 }
240
241 /* int84relop()
242  * Is 64-bit val1 relop 32-bit val2?
243  */
244 Datum
245 int84eq(PG_FUNCTION_ARGS)
246 {
247         int64           val1 = PG_GETARG_INT64(0);
248         int32           val2 = PG_GETARG_INT32(1);
249
250         PG_RETURN_BOOL(val1 == val2);
251 }
252
253 Datum
254 int84ne(PG_FUNCTION_ARGS)
255 {
256         int64           val1 = PG_GETARG_INT64(0);
257         int32           val2 = PG_GETARG_INT32(1);
258
259         PG_RETURN_BOOL(val1 != val2);
260 }
261
262 Datum
263 int84lt(PG_FUNCTION_ARGS)
264 {
265         int64           val1 = PG_GETARG_INT64(0);
266         int32           val2 = PG_GETARG_INT32(1);
267
268         PG_RETURN_BOOL(val1 < val2);
269 }
270
271 Datum
272 int84gt(PG_FUNCTION_ARGS)
273 {
274         int64           val1 = PG_GETARG_INT64(0);
275         int32           val2 = PG_GETARG_INT32(1);
276
277         PG_RETURN_BOOL(val1 > val2);
278 }
279
280 Datum
281 int84le(PG_FUNCTION_ARGS)
282 {
283         int64           val1 = PG_GETARG_INT64(0);
284         int32           val2 = PG_GETARG_INT32(1);
285
286         PG_RETURN_BOOL(val1 <= val2);
287 }
288
289 Datum
290 int84ge(PG_FUNCTION_ARGS)
291 {
292         int64           val1 = PG_GETARG_INT64(0);
293         int32           val2 = PG_GETARG_INT32(1);
294
295         PG_RETURN_BOOL(val1 >= val2);
296 }
297
298 /* int48relop()
299  * Is 32-bit val1 relop 64-bit val2?
300  */
301 Datum
302 int48eq(PG_FUNCTION_ARGS)
303 {
304         int32           val1 = PG_GETARG_INT32(0);
305         int64           val2 = PG_GETARG_INT64(1);
306
307         PG_RETURN_BOOL(val1 == val2);
308 }
309
310 Datum
311 int48ne(PG_FUNCTION_ARGS)
312 {
313         int32           val1 = PG_GETARG_INT32(0);
314         int64           val2 = PG_GETARG_INT64(1);
315
316         PG_RETURN_BOOL(val1 != val2);
317 }
318
319 Datum
320 int48lt(PG_FUNCTION_ARGS)
321 {
322         int32           val1 = PG_GETARG_INT32(0);
323         int64           val2 = PG_GETARG_INT64(1);
324
325         PG_RETURN_BOOL(val1 < val2);
326 }
327
328 Datum
329 int48gt(PG_FUNCTION_ARGS)
330 {
331         int32           val1 = PG_GETARG_INT32(0);
332         int64           val2 = PG_GETARG_INT64(1);
333
334         PG_RETURN_BOOL(val1 > val2);
335 }
336
337 Datum
338 int48le(PG_FUNCTION_ARGS)
339 {
340         int32           val1 = PG_GETARG_INT32(0);
341         int64           val2 = PG_GETARG_INT64(1);
342
343         PG_RETURN_BOOL(val1 <= val2);
344 }
345
346 Datum
347 int48ge(PG_FUNCTION_ARGS)
348 {
349         int32           val1 = PG_GETARG_INT32(0);
350         int64           val2 = PG_GETARG_INT64(1);
351
352         PG_RETURN_BOOL(val1 >= val2);
353 }
354
355 /* int82relop()
356  * Is 64-bit val1 relop 16-bit val2?
357  */
358 Datum
359 int82eq(PG_FUNCTION_ARGS)
360 {
361         int64           val1 = PG_GETARG_INT64(0);
362         int16           val2 = PG_GETARG_INT16(1);
363
364         PG_RETURN_BOOL(val1 == val2);
365 }
366
367 Datum
368 int82ne(PG_FUNCTION_ARGS)
369 {
370         int64           val1 = PG_GETARG_INT64(0);
371         int16           val2 = PG_GETARG_INT16(1);
372
373         PG_RETURN_BOOL(val1 != val2);
374 }
375
376 Datum
377 int82lt(PG_FUNCTION_ARGS)
378 {
379         int64           val1 = PG_GETARG_INT64(0);
380         int16           val2 = PG_GETARG_INT16(1);
381
382         PG_RETURN_BOOL(val1 < val2);
383 }
384
385 Datum
386 int82gt(PG_FUNCTION_ARGS)
387 {
388         int64           val1 = PG_GETARG_INT64(0);
389         int16           val2 = PG_GETARG_INT16(1);
390
391         PG_RETURN_BOOL(val1 > val2);
392 }
393
394 Datum
395 int82le(PG_FUNCTION_ARGS)
396 {
397         int64           val1 = PG_GETARG_INT64(0);
398         int16           val2 = PG_GETARG_INT16(1);
399
400         PG_RETURN_BOOL(val1 <= val2);
401 }
402
403 Datum
404 int82ge(PG_FUNCTION_ARGS)
405 {
406         int64           val1 = PG_GETARG_INT64(0);
407         int16           val2 = PG_GETARG_INT16(1);
408
409         PG_RETURN_BOOL(val1 >= val2);
410 }
411
412 /* int28relop()
413  * Is 16-bit val1 relop 64-bit val2?
414  */
415 Datum
416 int28eq(PG_FUNCTION_ARGS)
417 {
418         int16           val1 = PG_GETARG_INT16(0);
419         int64           val2 = PG_GETARG_INT64(1);
420
421         PG_RETURN_BOOL(val1 == val2);
422 }
423
424 Datum
425 int28ne(PG_FUNCTION_ARGS)
426 {
427         int16           val1 = PG_GETARG_INT16(0);
428         int64           val2 = PG_GETARG_INT64(1);
429
430         PG_RETURN_BOOL(val1 != val2);
431 }
432
433 Datum
434 int28lt(PG_FUNCTION_ARGS)
435 {
436         int16           val1 = PG_GETARG_INT16(0);
437         int64           val2 = PG_GETARG_INT64(1);
438
439         PG_RETURN_BOOL(val1 < val2);
440 }
441
442 Datum
443 int28gt(PG_FUNCTION_ARGS)
444 {
445         int16           val1 = PG_GETARG_INT16(0);
446         int64           val2 = PG_GETARG_INT64(1);
447
448         PG_RETURN_BOOL(val1 > val2);
449 }
450
451 Datum
452 int28le(PG_FUNCTION_ARGS)
453 {
454         int16           val1 = PG_GETARG_INT16(0);
455         int64           val2 = PG_GETARG_INT64(1);
456
457         PG_RETURN_BOOL(val1 <= val2);
458 }
459
460 Datum
461 int28ge(PG_FUNCTION_ARGS)
462 {
463         int16           val1 = PG_GETARG_INT16(0);
464         int64           val2 = PG_GETARG_INT64(1);
465
466         PG_RETURN_BOOL(val1 >= val2);
467 }
468
469
470 /*----------------------------------------------------------
471  *      Arithmetic operators on 64-bit integers.
472  *---------------------------------------------------------*/
473
474 Datum
475 int8um(PG_FUNCTION_ARGS)
476 {
477         int64           val = PG_GETARG_INT64(0);
478
479         PG_RETURN_INT64(-val);
480 }
481
482 Datum
483 int8up(PG_FUNCTION_ARGS)
484 {
485         int64           val = PG_GETARG_INT64(0);
486
487         PG_RETURN_INT64(val);
488 }
489
490 Datum
491 int8pl(PG_FUNCTION_ARGS)
492 {
493         int64           val1 = PG_GETARG_INT64(0);
494         int64           val2 = PG_GETARG_INT64(1);
495
496         PG_RETURN_INT64(val1 + val2);
497 }
498
499 Datum
500 int8mi(PG_FUNCTION_ARGS)
501 {
502         int64           val1 = PG_GETARG_INT64(0);
503         int64           val2 = PG_GETARG_INT64(1);
504
505         PG_RETURN_INT64(val1 - val2);
506 }
507
508 Datum
509 int8mul(PG_FUNCTION_ARGS)
510 {
511         int64           val1 = PG_GETARG_INT64(0);
512         int64           val2 = PG_GETARG_INT64(1);
513
514         PG_RETURN_INT64(val1 * val2);
515 }
516
517 Datum
518 int8div(PG_FUNCTION_ARGS)
519 {
520         int64           val1 = PG_GETARG_INT64(0);
521         int64           val2 = PG_GETARG_INT64(1);
522
523         if (val2 == 0)
524                 ereport(ERROR,
525                                 (errcode(ERRCODE_DIVISION_BY_ZERO),
526                                  errmsg("division by zero")));
527
528         PG_RETURN_INT64(val1 / val2);
529 }
530
531 /* int8abs()
532  * Absolute value
533  */
534 Datum
535 int8abs(PG_FUNCTION_ARGS)
536 {
537         int64           arg1 = PG_GETARG_INT64(0);
538
539         PG_RETURN_INT64((arg1 < 0) ? -arg1 : arg1);
540 }
541
542 /* int8mod()
543  * Modulo operation.
544  */
545 Datum
546 int8mod(PG_FUNCTION_ARGS)
547 {
548         int64           val1 = PG_GETARG_INT64(0);
549         int64           val2 = PG_GETARG_INT64(1);
550         int64           result;
551
552         if (val2 == 0)
553                 ereport(ERROR,
554                                 (errcode(ERRCODE_DIVISION_BY_ZERO),
555                                  errmsg("division by zero")));
556
557         result = val1 / val2;
558         result *= val2;
559         result = val1 - result;
560
561         PG_RETURN_INT64(result);
562 }
563
564 /* int8fac()
565  * Factorial
566  */
567 Datum
568 int8fac(PG_FUNCTION_ARGS)
569 {
570         int64           arg1 = PG_GETARG_INT64(0);
571         int64           result;
572         int64           i;
573
574         if (arg1 == 0)
575                 result = 1;
576         else if (arg1 < 1)
577                 result = 0;
578         else
579                 for (i = arg1, result = 1; i > 0; --i)
580                         result *= i;
581
582         PG_RETURN_INT64(result);
583 }
584
585 Datum
586 int8inc(PG_FUNCTION_ARGS)
587 {
588         int64           arg = PG_GETARG_INT64(0);
589
590         PG_RETURN_INT64(arg + 1);
591 }
592
593 Datum
594 int8larger(PG_FUNCTION_ARGS)
595 {
596         int64           val1 = PG_GETARG_INT64(0);
597         int64           val2 = PG_GETARG_INT64(1);
598         int64           result;
599
600         result = ((val1 > val2) ? val1 : val2);
601
602         PG_RETURN_INT64(result);
603 }
604
605 Datum
606 int8smaller(PG_FUNCTION_ARGS)
607 {
608         int64           val1 = PG_GETARG_INT64(0);
609         int64           val2 = PG_GETARG_INT64(1);
610         int64           result;
611
612         result = ((val1 < val2) ? val1 : val2);
613
614         PG_RETURN_INT64(result);
615 }
616
617 Datum
618 int84pl(PG_FUNCTION_ARGS)
619 {
620         int64           val1 = PG_GETARG_INT64(0);
621         int32           val2 = PG_GETARG_INT32(1);
622
623         PG_RETURN_INT64(val1 + val2);
624 }
625
626 Datum
627 int84mi(PG_FUNCTION_ARGS)
628 {
629         int64           val1 = PG_GETARG_INT64(0);
630         int32           val2 = PG_GETARG_INT32(1);
631
632         PG_RETURN_INT64(val1 - val2);
633 }
634
635 Datum
636 int84mul(PG_FUNCTION_ARGS)
637 {
638         int64           val1 = PG_GETARG_INT64(0);
639         int32           val2 = PG_GETARG_INT32(1);
640
641         PG_RETURN_INT64(val1 * val2);
642 }
643
644 Datum
645 int84div(PG_FUNCTION_ARGS)
646 {
647         int64           val1 = PG_GETARG_INT64(0);
648         int32           val2 = PG_GETARG_INT32(1);
649
650         if (val2 == 0)
651                 ereport(ERROR,
652                                 (errcode(ERRCODE_DIVISION_BY_ZERO),
653                                  errmsg("division by zero")));
654
655         PG_RETURN_INT64(val1 / val2);
656 }
657
658 Datum
659 int48pl(PG_FUNCTION_ARGS)
660 {
661         int32           val1 = PG_GETARG_INT32(0);
662         int64           val2 = PG_GETARG_INT64(1);
663
664         PG_RETURN_INT64(val1 + val2);
665 }
666
667 Datum
668 int48mi(PG_FUNCTION_ARGS)
669 {
670         int32           val1 = PG_GETARG_INT32(0);
671         int64           val2 = PG_GETARG_INT64(1);
672
673         PG_RETURN_INT64(val1 - val2);
674 }
675
676 Datum
677 int48mul(PG_FUNCTION_ARGS)
678 {
679         int32           val1 = PG_GETARG_INT32(0);
680         int64           val2 = PG_GETARG_INT64(1);
681
682         PG_RETURN_INT64(val1 * val2);
683 }
684
685 Datum
686 int48div(PG_FUNCTION_ARGS)
687 {
688         int32           val1 = PG_GETARG_INT32(0);
689         int64           val2 = PG_GETARG_INT64(1);
690
691         if (val2 == 0)
692                 ereport(ERROR,
693                                 (errcode(ERRCODE_DIVISION_BY_ZERO),
694                                  errmsg("division by zero")));
695
696         PG_RETURN_INT64(val1 / val2);
697 }
698
699 /* Binary arithmetics
700  *
701  *              int8and         - returns arg1 & arg2
702  *              int8or          - returns arg1 | arg2
703  *              int8xor         - returns arg1 # arg2
704  *              int8not         - returns ~arg1
705  *              int8shl         - returns arg1 << arg2
706  *              int8shr         - returns arg1 >> arg2
707  */
708
709 Datum
710 int8and(PG_FUNCTION_ARGS)
711 {
712         int64           arg1 = PG_GETARG_INT64(0);
713         int64           arg2 = PG_GETARG_INT64(1);
714
715         PG_RETURN_INT64(arg1 & arg2);
716 }
717
718 Datum
719 int8or(PG_FUNCTION_ARGS)
720 {
721         int64           arg1 = PG_GETARG_INT64(0);
722         int64           arg2 = PG_GETARG_INT64(1);
723
724         PG_RETURN_INT64(arg1 | arg2);
725 }
726
727 Datum
728 int8xor(PG_FUNCTION_ARGS)
729 {
730         int64           arg1 = PG_GETARG_INT64(0);
731         int64           arg2 = PG_GETARG_INT64(1);
732
733         PG_RETURN_INT64(arg1 ^ arg2);
734 }
735
736 Datum
737 int8not(PG_FUNCTION_ARGS)
738 {
739         int64           arg1 = PG_GETARG_INT64(0);
740
741         PG_RETURN_INT64(~arg1);
742 }
743
744 Datum
745 int8shl(PG_FUNCTION_ARGS)
746 {
747         int64           arg1 = PG_GETARG_INT64(0);
748         int32           arg2 = PG_GETARG_INT32(1);
749
750         PG_RETURN_INT64(arg1 << arg2);
751 }
752
753 Datum
754 int8shr(PG_FUNCTION_ARGS)
755 {
756         int64           arg1 = PG_GETARG_INT64(0);
757         int32           arg2 = PG_GETARG_INT32(1);
758
759         PG_RETURN_INT64(arg1 >> arg2);
760 }
761
762 /*----------------------------------------------------------
763  *      Conversion operators.
764  *---------------------------------------------------------*/
765
766 Datum
767 int48(PG_FUNCTION_ARGS)
768 {
769         int32           val = PG_GETARG_INT32(0);
770
771         PG_RETURN_INT64((int64) val);
772 }
773
774 Datum
775 int84(PG_FUNCTION_ARGS)
776 {
777         int64           val = PG_GETARG_INT64(0);
778         int32           result;
779
780         result = (int32) val;
781
782         /* Test for overflow by reverse-conversion. */
783         if ((int64) result != val)
784                 ereport(ERROR,
785                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
786                                  errmsg("integer out of range")));
787
788         PG_RETURN_INT32(result);
789 }
790
791 Datum
792 int28(PG_FUNCTION_ARGS)
793 {
794         int16           val = PG_GETARG_INT16(0);
795
796         PG_RETURN_INT64((int64) val);
797 }
798
799 Datum
800 int82(PG_FUNCTION_ARGS)
801 {
802         int64           val = PG_GETARG_INT64(0);
803         int16           result;
804
805         result = (int16) val;
806
807         /* Test for overflow by reverse-conversion. */
808         if ((int64) result != val)
809                 ereport(ERROR,
810                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
811                                  errmsg("integer out of range")));
812
813         PG_RETURN_INT16(result);
814 }
815
816 Datum
817 i8tod(PG_FUNCTION_ARGS)
818 {
819         int64           val = PG_GETARG_INT64(0);
820         float8          result;
821
822         result = val;
823
824         PG_RETURN_FLOAT8(result);
825 }
826
827 /* dtoi8()
828  * Convert float8 to 8-byte integer.
829  */
830 Datum
831 dtoi8(PG_FUNCTION_ARGS)
832 {
833         float8          val = PG_GETARG_FLOAT8(0);
834         int64           result;
835
836         /* Round val to nearest integer (but it's still in float form) */
837         val = rint(val);
838
839         /*
840          * Does it fit in an int64?  Avoid assuming that we have handy
841          * constants defined for the range boundaries, instead test for
842          * overflow by reverse-conversion.
843          */
844         result = (int64) val;
845
846         if ((float8) result != val)
847                 ereport(ERROR,
848                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
849                                  errmsg("integer out of range")));
850
851         PG_RETURN_INT64(result);
852 }
853
854 Datum
855 i8tof(PG_FUNCTION_ARGS)
856 {
857         int64           val = PG_GETARG_INT64(0);
858         float4          result;
859
860         result = val;
861
862         PG_RETURN_FLOAT4(result);
863 }
864
865 /* ftoi8()
866  * Convert float4 to 8-byte integer.
867  */
868 Datum
869 ftoi8(PG_FUNCTION_ARGS)
870 {
871         float4          val = PG_GETARG_FLOAT4(0);
872         int64           result;
873         float8          dval;
874
875         /* Round val to nearest integer (but it's still in float form) */
876         dval = rint(val);
877
878         /*
879          * Does it fit in an int64?  Avoid assuming that we have handy
880          * constants defined for the range boundaries, instead test for
881          * overflow by reverse-conversion.
882          */
883         result = (int64) dval;
884
885         if ((float8) result != dval)
886                 ereport(ERROR,
887                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
888                                  errmsg("integer out of range")));
889
890         PG_RETURN_INT64(result);
891 }
892
893 Datum
894 i8tooid(PG_FUNCTION_ARGS)
895 {
896         int64           val = PG_GETARG_INT64(0);
897         Oid                     result;
898
899         result = (Oid) val;
900
901         /* Test for overflow by reverse-conversion. */
902         if ((int64) result != val)
903                 ereport(ERROR,
904                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
905                                  errmsg("OID out of range")));
906
907         PG_RETURN_OID(result);
908 }
909
910 Datum
911 oidtoi8(PG_FUNCTION_ARGS)
912 {
913         Oid                     val = PG_GETARG_OID(0);
914
915         PG_RETURN_INT64((int64) val);
916 }
917
918 Datum
919 text_int8(PG_FUNCTION_ARGS)
920 {
921         text       *str = PG_GETARG_TEXT_P(0);
922         int                     len;
923         char       *s;
924         Datum           result;
925
926         len = (VARSIZE(str) - VARHDRSZ);
927         s = palloc(len + 1);
928         memcpy(s, VARDATA(str), len);
929         *(s + len) = '\0';
930
931         result = DirectFunctionCall1(int8in, CStringGetDatum(s));
932
933         pfree(s);
934
935         return result;
936 }
937
938 Datum
939 int8_text(PG_FUNCTION_ARGS)
940 {
941         /* val is int64, but easier to leave it as Datum */
942         Datum           val = PG_GETARG_DATUM(0);
943         char       *s;
944         int                     len;
945         text       *result;
946
947         s = DatumGetCString(DirectFunctionCall1(int8out, val));
948         len = strlen(s);
949
950         result = (text *) palloc(VARHDRSZ + len);
951
952         VARATT_SIZEP(result) = len + VARHDRSZ;
953         memcpy(VARDATA(result), s, len);
954
955         pfree(s);
956
957         PG_RETURN_TEXT_P(result);
958 }