OSDN Git Service

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