]> granicus.if.org Git - postgresql/blob - src/backend/utils/adt/int.c
Attached is a patch implementing factorial(), returning numeric. Points
[postgresql] / src / backend / utils / adt / int.c
1 /*-------------------------------------------------------------------------
2  *
3  * int.c
4  *        Functions for the built-in integer types (except int8).
5  *
6  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  *
10  * IDENTIFICATION
11  *        $PostgreSQL: pgsql/src/backend/utils/adt/int.c,v 1.59 2003/12/01 21:52:37 momjian Exp $
12  *
13  *-------------------------------------------------------------------------
14  */
15 /*
16  * OLD COMMENTS
17  *              I/O routines:
18  *               int2in, int2out, int2recv, int2send
19  *               int4in, int4out, int4recv, int4send
20  *               int2vectorin, int2vectorout, int2vectorrecv, int2vectorsend
21  *              Conversion routines:
22  *               itoi, int2_text, int4_text
23  *              Boolean operators:
24  *               inteq, intne, intlt, intle, intgt, intge
25  *              Arithmetic operators:
26  *               intpl, intmi, int4mul, intdiv
27  *
28  *              Arithmetic operators:
29  *               intmod
30  */
31
32 #include "postgres.h"
33
34 #include <ctype.h>
35 #include <limits.h>
36
37 #include "libpq/pqformat.h"
38 #include "utils/builtins.h"
39
40 #ifndef SHRT_MAX
41 #define SHRT_MAX (0x7FFF)
42 #endif
43 #ifndef SHRT_MIN
44 #define SHRT_MIN (-0x8000)
45 #endif
46
47 /*****************************************************************************
48  *       USER I/O ROUTINES                                                                                                               *
49  *****************************************************************************/
50
51 /*
52  *              int2in                  - converts "num" to short
53  */
54 Datum
55 int2in(PG_FUNCTION_ARGS)
56 {
57         char       *num = PG_GETARG_CSTRING(0);
58
59         PG_RETURN_INT16(pg_atoi(num, sizeof(int16), '\0'));
60 }
61
62 /*
63  *              int2out                 - converts short to "num"
64  */
65 Datum
66 int2out(PG_FUNCTION_ARGS)
67 {
68         int16           arg1 = PG_GETARG_INT16(0);
69         char       *result = (char *) palloc(7);        /* sign, 5 digits, '\0' */
70
71         pg_itoa(arg1, result);
72         PG_RETURN_CSTRING(result);
73 }
74
75 /*
76  *              int2recv                        - converts external binary format to int2
77  */
78 Datum
79 int2recv(PG_FUNCTION_ARGS)
80 {
81         StringInfo      buf = (StringInfo) PG_GETARG_POINTER(0);
82
83         PG_RETURN_INT16((int16) pq_getmsgint(buf, sizeof(int16)));
84 }
85
86 /*
87  *              int2send                        - converts int2 to binary format
88  */
89 Datum
90 int2send(PG_FUNCTION_ARGS)
91 {
92         int16           arg1 = PG_GETARG_INT16(0);
93         StringInfoData buf;
94
95         pq_begintypsend(&buf);
96         pq_sendint(&buf, arg1, sizeof(int16));
97         PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
98 }
99
100 /*
101  *              int2vectorin                    - converts "num num ..." to internal form
102  *
103  *              Note: Fills any missing slots with zeroes.
104  */
105 Datum
106 int2vectorin(PG_FUNCTION_ARGS)
107 {
108         char       *intString = PG_GETARG_CSTRING(0);
109         int16      *result = (int16 *) palloc(sizeof(int16[INDEX_MAX_KEYS]));
110         int                     slot;
111
112         for (slot = 0; *intString && slot < INDEX_MAX_KEYS; slot++)
113         {
114                 if (sscanf(intString, "%hd", &result[slot]) != 1)
115                         break;
116                 while (*intString && isspace((unsigned char) *intString))
117                         intString++;
118                 while (*intString && !isspace((unsigned char) *intString))
119                         intString++;
120         }
121         while (*intString && isspace((unsigned char) *intString))
122                 intString++;
123         if (*intString)
124                 ereport(ERROR,
125                                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
126                                  errmsg("int2vector has too many elements")));
127
128         while (slot < INDEX_MAX_KEYS)
129                 result[slot++] = 0;
130
131         PG_RETURN_POINTER(result);
132 }
133
134 /*
135  *              int2vectorout           - converts internal form to "num num ..."
136  */
137 Datum
138 int2vectorout(PG_FUNCTION_ARGS)
139 {
140         int16      *int2Array = (int16 *) PG_GETARG_POINTER(0);
141         int                     num,
142                                 maxnum;
143         char       *rp;
144         char       *result;
145
146         /* find last non-zero value in vector */
147         for (maxnum = INDEX_MAX_KEYS - 1; maxnum >= 0; maxnum--)
148                 if (int2Array[maxnum] != 0)
149                         break;
150
151         /* assumes sign, 5 digits, ' ' */
152         rp = result = (char *) palloc((maxnum + 1) * 7 + 1);
153         for (num = 0; num <= maxnum; num++)
154         {
155                 if (num != 0)
156                         *rp++ = ' ';
157                 pg_itoa(int2Array[num], rp);
158                 while (*++rp != '\0')
159                         ;
160         }
161         *rp = '\0';
162         PG_RETURN_CSTRING(result);
163 }
164
165 /*
166  *              int2vectorrecv                  - converts external binary format to int2vector
167  */
168 Datum
169 int2vectorrecv(PG_FUNCTION_ARGS)
170 {
171         StringInfo      buf = (StringInfo) PG_GETARG_POINTER(0);
172         int16      *result = (int16 *) palloc(sizeof(int16[INDEX_MAX_KEYS]));
173         int                     slot;
174
175         for (slot = 0; slot < INDEX_MAX_KEYS; slot++)
176                 result[slot] = (int16) pq_getmsgint(buf, sizeof(int16));
177         PG_RETURN_POINTER(result);
178 }
179
180 /*
181  *              int2vectorsend                  - converts int2vector to binary format
182  */
183 Datum
184 int2vectorsend(PG_FUNCTION_ARGS)
185 {
186         int16      *int2Array = (int16 *) PG_GETARG_POINTER(0);
187         StringInfoData buf;
188         int                     slot;
189
190         pq_begintypsend(&buf);
191         for (slot = 0; slot < INDEX_MAX_KEYS; slot++)
192                 pq_sendint(&buf, int2Array[slot], sizeof(int16));
193         PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
194 }
195
196 /*
197  * We don't have a complete set of int2vector support routines,
198  * but we need int2vectoreq for catcache indexing.
199  */
200 Datum
201 int2vectoreq(PG_FUNCTION_ARGS)
202 {
203         int16      *arg1 = (int16 *) PG_GETARG_POINTER(0);
204         int16      *arg2 = (int16 *) PG_GETARG_POINTER(1);
205
206         PG_RETURN_BOOL(memcmp(arg1, arg2, INDEX_MAX_KEYS * sizeof(int16)) == 0);
207 }
208
209
210 /*****************************************************************************
211  *       PUBLIC ROUTINES                                                                                                                 *
212  *****************************************************************************/
213
214 /*
215  *              int4in                  - converts "num" to int4
216  */
217 Datum
218 int4in(PG_FUNCTION_ARGS)
219 {
220         char       *num = PG_GETARG_CSTRING(0);
221
222         PG_RETURN_INT32(pg_atoi(num, sizeof(int32), '\0'));
223 }
224
225 /*
226  *              int4out                 - converts int4 to "num"
227  */
228 Datum
229 int4out(PG_FUNCTION_ARGS)
230 {
231         int32           arg1 = PG_GETARG_INT32(0);
232         char       *result = (char *) palloc(12);       /* sign, 10 digits, '\0' */
233
234         pg_ltoa(arg1, result);
235         PG_RETURN_CSTRING(result);
236 }
237
238 /*
239  *              int4recv                        - converts external binary format to int4
240  */
241 Datum
242 int4recv(PG_FUNCTION_ARGS)
243 {
244         StringInfo      buf = (StringInfo) PG_GETARG_POINTER(0);
245
246         PG_RETURN_INT32((int32) pq_getmsgint(buf, sizeof(int32)));
247 }
248
249 /*
250  *              int4send                        - converts int4 to binary format
251  */
252 Datum
253 int4send(PG_FUNCTION_ARGS)
254 {
255         int32           arg1 = PG_GETARG_INT32(0);
256         StringInfoData buf;
257
258         pq_begintypsend(&buf);
259         pq_sendint(&buf, arg1, sizeof(int32));
260         PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
261 }
262
263
264 /*
265  *              ===================
266  *              CONVERSION ROUTINES
267  *              ===================
268  */
269
270 Datum
271 i2toi4(PG_FUNCTION_ARGS)
272 {
273         int16           arg1 = PG_GETARG_INT16(0);
274
275         PG_RETURN_INT32((int32) arg1);
276 }
277
278 Datum
279 i4toi2(PG_FUNCTION_ARGS)
280 {
281         int32           arg1 = PG_GETARG_INT32(0);
282
283         if (arg1 < SHRT_MIN || arg1 > SHRT_MAX)
284                 ereport(ERROR,
285                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
286                                  errmsg("integer out of range")));
287
288         PG_RETURN_INT16((int16) arg1);
289 }
290
291 Datum
292 int2_text(PG_FUNCTION_ARGS)
293 {
294         int16           arg1 = PG_GETARG_INT16(0);
295         text       *result = (text *) palloc(7 + VARHDRSZ); /* sign,5 digits, '\0' */
296
297         pg_itoa(arg1, VARDATA(result));
298         VARATT_SIZEP(result) = strlen(VARDATA(result)) + VARHDRSZ;
299         PG_RETURN_TEXT_P(result);
300 }
301
302 Datum
303 text_int2(PG_FUNCTION_ARGS)
304 {
305         text       *string = PG_GETARG_TEXT_P(0);
306         Datum           result;
307         int                     len;
308         char       *str;
309
310         len = VARSIZE(string) - VARHDRSZ;
311
312         str = palloc(len + 1);
313         memcpy(str, VARDATA(string), len);
314         *(str + len) = '\0';
315
316         result = DirectFunctionCall1(int2in, CStringGetDatum(str));
317         pfree(str);
318
319         return result;
320 }
321
322 Datum
323 int4_text(PG_FUNCTION_ARGS)
324 {
325         int32           arg1 = PG_GETARG_INT32(0);
326         text       *result = (text *) palloc(12 + VARHDRSZ);            /* sign,10 digits,'\0' */
327
328         pg_ltoa(arg1, VARDATA(result));
329         VARATT_SIZEP(result) = strlen(VARDATA(result)) + VARHDRSZ;
330         PG_RETURN_TEXT_P(result);
331 }
332
333 Datum
334 text_int4(PG_FUNCTION_ARGS)
335 {
336         text       *string = PG_GETARG_TEXT_P(0);
337         Datum           result;
338         int                     len;
339         char       *str;
340
341         len = VARSIZE(string) - VARHDRSZ;
342
343         str = palloc(len + 1);
344         memcpy(str, VARDATA(string), len);
345         *(str + len) = '\0';
346
347         result = DirectFunctionCall1(int4in, CStringGetDatum(str));
348         pfree(str);
349
350         return result;
351 }
352
353
354 /*
355  *              ============================
356  *              COMPARISON OPERATOR ROUTINES
357  *              ============================
358  */
359
360 /*
361  *              inteq                   - returns 1 iff arg1 == arg2
362  *              intne                   - returns 1 iff arg1 != arg2
363  *              intlt                   - returns 1 iff arg1 < arg2
364  *              intle                   - returns 1 iff arg1 <= arg2
365  *              intgt                   - returns 1 iff arg1 > arg2
366  *              intge                   - returns 1 iff arg1 >= arg2
367  */
368
369 Datum
370 int4eq(PG_FUNCTION_ARGS)
371 {
372         int32           arg1 = PG_GETARG_INT32(0);
373         int32           arg2 = PG_GETARG_INT32(1);
374
375         PG_RETURN_BOOL(arg1 == arg2);
376 }
377
378 Datum
379 int4ne(PG_FUNCTION_ARGS)
380 {
381         int32           arg1 = PG_GETARG_INT32(0);
382         int32           arg2 = PG_GETARG_INT32(1);
383
384         PG_RETURN_BOOL(arg1 != arg2);
385 }
386
387 Datum
388 int4lt(PG_FUNCTION_ARGS)
389 {
390         int32           arg1 = PG_GETARG_INT32(0);
391         int32           arg2 = PG_GETARG_INT32(1);
392
393         PG_RETURN_BOOL(arg1 < arg2);
394 }
395
396 Datum
397 int4le(PG_FUNCTION_ARGS)
398 {
399         int32           arg1 = PG_GETARG_INT32(0);
400         int32           arg2 = PG_GETARG_INT32(1);
401
402         PG_RETURN_BOOL(arg1 <= arg2);
403 }
404
405 Datum
406 int4gt(PG_FUNCTION_ARGS)
407 {
408         int32           arg1 = PG_GETARG_INT32(0);
409         int32           arg2 = PG_GETARG_INT32(1);
410
411         PG_RETURN_BOOL(arg1 > arg2);
412 }
413
414 Datum
415 int4ge(PG_FUNCTION_ARGS)
416 {
417         int32           arg1 = PG_GETARG_INT32(0);
418         int32           arg2 = PG_GETARG_INT32(1);
419
420         PG_RETURN_BOOL(arg1 >= arg2);
421 }
422
423 Datum
424 int2eq(PG_FUNCTION_ARGS)
425 {
426         int16           arg1 = PG_GETARG_INT16(0);
427         int16           arg2 = PG_GETARG_INT16(1);
428
429         PG_RETURN_BOOL(arg1 == arg2);
430 }
431
432 Datum
433 int2ne(PG_FUNCTION_ARGS)
434 {
435         int16           arg1 = PG_GETARG_INT16(0);
436         int16           arg2 = PG_GETARG_INT16(1);
437
438         PG_RETURN_BOOL(arg1 != arg2);
439 }
440
441 Datum
442 int2lt(PG_FUNCTION_ARGS)
443 {
444         int16           arg1 = PG_GETARG_INT16(0);
445         int16           arg2 = PG_GETARG_INT16(1);
446
447         PG_RETURN_BOOL(arg1 < arg2);
448 }
449
450 Datum
451 int2le(PG_FUNCTION_ARGS)
452 {
453         int16           arg1 = PG_GETARG_INT16(0);
454         int16           arg2 = PG_GETARG_INT16(1);
455
456         PG_RETURN_BOOL(arg1 <= arg2);
457 }
458
459 Datum
460 int2gt(PG_FUNCTION_ARGS)
461 {
462         int16           arg1 = PG_GETARG_INT16(0);
463         int16           arg2 = PG_GETARG_INT16(1);
464
465         PG_RETURN_BOOL(arg1 > arg2);
466 }
467
468 Datum
469 int2ge(PG_FUNCTION_ARGS)
470 {
471         int16           arg1 = PG_GETARG_INT16(0);
472         int16           arg2 = PG_GETARG_INT16(1);
473
474         PG_RETURN_BOOL(arg1 >= arg2);
475 }
476
477 Datum
478 int24eq(PG_FUNCTION_ARGS)
479 {
480         int16           arg1 = PG_GETARG_INT16(0);
481         int32           arg2 = PG_GETARG_INT32(1);
482
483         PG_RETURN_BOOL(arg1 == arg2);
484 }
485
486 Datum
487 int24ne(PG_FUNCTION_ARGS)
488 {
489         int16           arg1 = PG_GETARG_INT16(0);
490         int32           arg2 = PG_GETARG_INT32(1);
491
492         PG_RETURN_BOOL(arg1 != arg2);
493 }
494
495 Datum
496 int24lt(PG_FUNCTION_ARGS)
497 {
498         int16           arg1 = PG_GETARG_INT16(0);
499         int32           arg2 = PG_GETARG_INT32(1);
500
501         PG_RETURN_BOOL(arg1 < arg2);
502 }
503
504 Datum
505 int24le(PG_FUNCTION_ARGS)
506 {
507         int16           arg1 = PG_GETARG_INT16(0);
508         int32           arg2 = PG_GETARG_INT32(1);
509
510         PG_RETURN_BOOL(arg1 <= arg2);
511 }
512
513 Datum
514 int24gt(PG_FUNCTION_ARGS)
515 {
516         int16           arg1 = PG_GETARG_INT16(0);
517         int32           arg2 = PG_GETARG_INT32(1);
518
519         PG_RETURN_BOOL(arg1 > arg2);
520 }
521
522 Datum
523 int24ge(PG_FUNCTION_ARGS)
524 {
525         int16           arg1 = PG_GETARG_INT16(0);
526         int32           arg2 = PG_GETARG_INT32(1);
527
528         PG_RETURN_BOOL(arg1 >= arg2);
529 }
530
531 Datum
532 int42eq(PG_FUNCTION_ARGS)
533 {
534         int32           arg1 = PG_GETARG_INT32(0);
535         int16           arg2 = PG_GETARG_INT16(1);
536
537         PG_RETURN_BOOL(arg1 == arg2);
538 }
539
540 Datum
541 int42ne(PG_FUNCTION_ARGS)
542 {
543         int32           arg1 = PG_GETARG_INT32(0);
544         int16           arg2 = PG_GETARG_INT16(1);
545
546         PG_RETURN_BOOL(arg1 != arg2);
547 }
548
549 Datum
550 int42lt(PG_FUNCTION_ARGS)
551 {
552         int32           arg1 = PG_GETARG_INT32(0);
553         int16           arg2 = PG_GETARG_INT16(1);
554
555         PG_RETURN_BOOL(arg1 < arg2);
556 }
557
558 Datum
559 int42le(PG_FUNCTION_ARGS)
560 {
561         int32           arg1 = PG_GETARG_INT32(0);
562         int16           arg2 = PG_GETARG_INT16(1);
563
564         PG_RETURN_BOOL(arg1 <= arg2);
565 }
566
567 Datum
568 int42gt(PG_FUNCTION_ARGS)
569 {
570         int32           arg1 = PG_GETARG_INT32(0);
571         int16           arg2 = PG_GETARG_INT16(1);
572
573         PG_RETURN_BOOL(arg1 > arg2);
574 }
575
576 Datum
577 int42ge(PG_FUNCTION_ARGS)
578 {
579         int32           arg1 = PG_GETARG_INT32(0);
580         int16           arg2 = PG_GETARG_INT16(1);
581
582         PG_RETURN_BOOL(arg1 >= arg2);
583 }
584
585 /*
586  *              int[24]pl               - returns arg1 + arg2
587  *              int[24]mi               - returns arg1 - arg2
588  *              int[24]mul              - returns arg1 * arg2
589  *              int[24]div              - returns arg1 / arg2
590  */
591
592 Datum
593 int4um(PG_FUNCTION_ARGS)
594 {
595         int32           arg = PG_GETARG_INT32(0);
596
597         PG_RETURN_INT32(-arg);
598 }
599
600 Datum
601 int4up(PG_FUNCTION_ARGS)
602 {
603         int32           arg = PG_GETARG_INT32(0);
604
605         PG_RETURN_INT32(arg);
606 }
607
608 Datum
609 int4pl(PG_FUNCTION_ARGS)
610 {
611         int32           arg1 = PG_GETARG_INT32(0);
612         int32           arg2 = PG_GETARG_INT32(1);
613
614         PG_RETURN_INT32(arg1 + arg2);
615 }
616
617 Datum
618 int4mi(PG_FUNCTION_ARGS)
619 {
620         int32           arg1 = PG_GETARG_INT32(0);
621         int32           arg2 = PG_GETARG_INT32(1);
622
623         PG_RETURN_INT32(arg1 - arg2);
624 }
625
626 Datum
627 int4mul(PG_FUNCTION_ARGS)
628 {
629         int32           arg1 = PG_GETARG_INT32(0);
630         int32           arg2 = PG_GETARG_INT32(1);
631
632         PG_RETURN_INT32(arg1 * arg2);
633 }
634
635 Datum
636 int4div(PG_FUNCTION_ARGS)
637 {
638         int32           arg1 = PG_GETARG_INT32(0);
639         int32           arg2 = PG_GETARG_INT32(1);
640
641         if (arg2 == 0)
642                 ereport(ERROR,
643                                 (errcode(ERRCODE_DIVISION_BY_ZERO),
644                                  errmsg("division by zero")));
645
646         PG_RETURN_INT32(arg1 / arg2);
647 }
648
649 Datum
650 int4inc(PG_FUNCTION_ARGS)
651 {
652         int32           arg = PG_GETARG_INT32(0);
653
654         PG_RETURN_INT32(arg + 1);
655 }
656
657 Datum
658 int2um(PG_FUNCTION_ARGS)
659 {
660         int16           arg = PG_GETARG_INT16(0);
661
662         PG_RETURN_INT16(-arg);
663 }
664
665 Datum
666 int2up(PG_FUNCTION_ARGS)
667 {
668         int16           arg = PG_GETARG_INT16(0);
669
670         PG_RETURN_INT16(arg);
671 }
672
673 Datum
674 int2pl(PG_FUNCTION_ARGS)
675 {
676         int16           arg1 = PG_GETARG_INT16(0);
677         int16           arg2 = PG_GETARG_INT16(1);
678
679         PG_RETURN_INT16(arg1 + arg2);
680 }
681
682 Datum
683 int2mi(PG_FUNCTION_ARGS)
684 {
685         int16           arg1 = PG_GETARG_INT16(0);
686         int16           arg2 = PG_GETARG_INT16(1);
687
688         PG_RETURN_INT16(arg1 - arg2);
689 }
690
691 Datum
692 int2mul(PG_FUNCTION_ARGS)
693 {
694         int16           arg1 = PG_GETARG_INT16(0);
695         int16           arg2 = PG_GETARG_INT16(1);
696
697         PG_RETURN_INT16(arg1 * arg2);
698 }
699
700 Datum
701 int2div(PG_FUNCTION_ARGS)
702 {
703         int16           arg1 = PG_GETARG_INT16(0);
704         int16           arg2 = PG_GETARG_INT16(1);
705
706         if (arg2 == 0)
707                 ereport(ERROR,
708                                 (errcode(ERRCODE_DIVISION_BY_ZERO),
709                                  errmsg("division by zero")));
710
711         PG_RETURN_INT16(arg1 / arg2);
712 }
713
714 Datum
715 int24pl(PG_FUNCTION_ARGS)
716 {
717         int16           arg1 = PG_GETARG_INT16(0);
718         int32           arg2 = PG_GETARG_INT32(1);
719
720         PG_RETURN_INT32(arg1 + arg2);
721 }
722
723 Datum
724 int24mi(PG_FUNCTION_ARGS)
725 {
726         int16           arg1 = PG_GETARG_INT16(0);
727         int32           arg2 = PG_GETARG_INT32(1);
728
729         PG_RETURN_INT32(arg1 - arg2);
730 }
731
732 Datum
733 int24mul(PG_FUNCTION_ARGS)
734 {
735         int16           arg1 = PG_GETARG_INT16(0);
736         int32           arg2 = PG_GETARG_INT32(1);
737
738         PG_RETURN_INT32(arg1 * arg2);
739 }
740
741 Datum
742 int24div(PG_FUNCTION_ARGS)
743 {
744         int16           arg1 = PG_GETARG_INT16(0);
745         int32           arg2 = PG_GETARG_INT32(1);
746
747         if (arg2 == 0)
748                 ereport(ERROR,
749                                 (errcode(ERRCODE_DIVISION_BY_ZERO),
750                                  errmsg("division by zero")));
751
752         PG_RETURN_INT32(arg1 / arg2);
753 }
754
755 Datum
756 int42pl(PG_FUNCTION_ARGS)
757 {
758         int32           arg1 = PG_GETARG_INT32(0);
759         int16           arg2 = PG_GETARG_INT16(1);
760
761         PG_RETURN_INT32(arg1 + arg2);
762 }
763
764 Datum
765 int42mi(PG_FUNCTION_ARGS)
766 {
767         int32           arg1 = PG_GETARG_INT32(0);
768         int16           arg2 = PG_GETARG_INT16(1);
769
770         PG_RETURN_INT32(arg1 - arg2);
771 }
772
773 Datum
774 int42mul(PG_FUNCTION_ARGS)
775 {
776         int32           arg1 = PG_GETARG_INT32(0);
777         int16           arg2 = PG_GETARG_INT16(1);
778
779         PG_RETURN_INT32(arg1 * arg2);
780 }
781
782 Datum
783 int42div(PG_FUNCTION_ARGS)
784 {
785         int32           arg1 = PG_GETARG_INT32(0);
786         int16           arg2 = PG_GETARG_INT16(1);
787
788         if (arg2 == 0)
789                 ereport(ERROR,
790                                 (errcode(ERRCODE_DIVISION_BY_ZERO),
791                                  errmsg("division by zero")));
792
793         PG_RETURN_INT32(arg1 / arg2);
794 }
795
796 Datum
797 int4mod(PG_FUNCTION_ARGS)
798 {
799         int32           arg1 = PG_GETARG_INT32(0);
800         int32           arg2 = PG_GETARG_INT32(1);
801
802         if (arg2 == 0)
803                 ereport(ERROR,
804                                 (errcode(ERRCODE_DIVISION_BY_ZERO),
805                                  errmsg("division by zero")));
806
807         PG_RETURN_INT32(arg1 % arg2);
808 }
809
810 Datum
811 int2mod(PG_FUNCTION_ARGS)
812 {
813         int16           arg1 = PG_GETARG_INT16(0);
814         int16           arg2 = PG_GETARG_INT16(1);
815
816         if (arg2 == 0)
817                 ereport(ERROR,
818                                 (errcode(ERRCODE_DIVISION_BY_ZERO),
819                                  errmsg("division by zero")));
820
821         PG_RETURN_INT16(arg1 % arg2);
822 }
823
824 Datum
825 int24mod(PG_FUNCTION_ARGS)
826 {
827         int16           arg1 = PG_GETARG_INT16(0);
828         int32           arg2 = PG_GETARG_INT32(1);
829
830         if (arg2 == 0)
831                 ereport(ERROR,
832                                 (errcode(ERRCODE_DIVISION_BY_ZERO),
833                                  errmsg("division by zero")));
834
835         PG_RETURN_INT32(arg1 % arg2);
836 }
837
838 Datum
839 int42mod(PG_FUNCTION_ARGS)
840 {
841         int32           arg1 = PG_GETARG_INT32(0);
842         int16           arg2 = PG_GETARG_INT16(1);
843
844         if (arg2 == 0)
845                 ereport(ERROR,
846                                 (errcode(ERRCODE_DIVISION_BY_ZERO),
847                                  errmsg("division by zero")));
848
849         PG_RETURN_INT32(arg1 % arg2);
850 }
851
852
853 /* int[24]abs()
854  * Absolute value
855  */
856 Datum
857 int4abs(PG_FUNCTION_ARGS)
858 {
859         int32           arg1 = PG_GETARG_INT32(0);
860
861         PG_RETURN_INT32((arg1 < 0) ? -arg1 : arg1);
862 }
863
864 Datum
865 int2abs(PG_FUNCTION_ARGS)
866 {
867         int16           arg1 = PG_GETARG_INT16(0);
868
869         PG_RETURN_INT16((arg1 < 0) ? -arg1 : arg1);
870 }
871
872 Datum
873 int2larger(PG_FUNCTION_ARGS)
874 {
875         int16           arg1 = PG_GETARG_INT16(0);
876         int16           arg2 = PG_GETARG_INT16(1);
877
878         PG_RETURN_INT16((arg1 > arg2) ? arg1 : arg2);
879 }
880
881 Datum
882 int2smaller(PG_FUNCTION_ARGS)
883 {
884         int16           arg1 = PG_GETARG_INT16(0);
885         int16           arg2 = PG_GETARG_INT16(1);
886
887         PG_RETURN_INT16((arg1 < arg2) ? arg1 : arg2);
888 }
889
890 Datum
891 int4larger(PG_FUNCTION_ARGS)
892 {
893         int32           arg1 = PG_GETARG_INT32(0);
894         int32           arg2 = PG_GETARG_INT32(1);
895
896         PG_RETURN_INT32((arg1 > arg2) ? arg1 : arg2);
897 }
898
899 Datum
900 int4smaller(PG_FUNCTION_ARGS)
901 {
902         int32           arg1 = PG_GETARG_INT32(0);
903         int32           arg2 = PG_GETARG_INT32(1);
904
905         PG_RETURN_INT32((arg1 < arg2) ? arg1 : arg2);
906 }
907
908 /* Binary arithmetics
909  *
910  *              int[24]and              - returns arg1 & arg2
911  *              int[24]or               - returns arg1 | arg2
912  *              int[24]xor              - returns arg1 # arg2
913  *              int[24]not              - returns ~arg1
914  *              int[24]shl              - returns arg1 << arg2
915  *              int[24]shr              - returns arg1 >> arg2
916  */
917
918 Datum
919 int4and(PG_FUNCTION_ARGS)
920 {
921         int32           arg1 = PG_GETARG_INT32(0);
922         int32           arg2 = PG_GETARG_INT32(1);
923
924         PG_RETURN_INT32(arg1 & arg2);
925 }
926
927 Datum
928 int4or(PG_FUNCTION_ARGS)
929 {
930         int32           arg1 = PG_GETARG_INT32(0);
931         int32           arg2 = PG_GETARG_INT32(1);
932
933         PG_RETURN_INT32(arg1 | arg2);
934 }
935
936 Datum
937 int4xor(PG_FUNCTION_ARGS)
938 {
939         int32           arg1 = PG_GETARG_INT32(0);
940         int32           arg2 = PG_GETARG_INT32(1);
941
942         PG_RETURN_INT32(arg1 ^ arg2);
943 }
944
945 Datum
946 int4shl(PG_FUNCTION_ARGS)
947 {
948         int32           arg1 = PG_GETARG_INT32(0);
949         int32           arg2 = PG_GETARG_INT32(1);
950
951         PG_RETURN_INT32(arg1 << arg2);
952 }
953
954 Datum
955 int4shr(PG_FUNCTION_ARGS)
956 {
957         int32           arg1 = PG_GETARG_INT32(0);
958         int32           arg2 = PG_GETARG_INT32(1);
959
960         PG_RETURN_INT32(arg1 >> arg2);
961 }
962
963 Datum
964 int4not(PG_FUNCTION_ARGS)
965 {
966         int32           arg1 = PG_GETARG_INT32(0);
967
968         PG_RETURN_INT32(~arg1);
969 }
970
971 Datum
972 int2and(PG_FUNCTION_ARGS)
973 {
974         int16           arg1 = PG_GETARG_INT16(0);
975         int16           arg2 = PG_GETARG_INT16(1);
976
977         PG_RETURN_INT16(arg1 & arg2);
978 }
979
980 Datum
981 int2or(PG_FUNCTION_ARGS)
982 {
983         int16           arg1 = PG_GETARG_INT16(0);
984         int16           arg2 = PG_GETARG_INT16(1);
985
986         PG_RETURN_INT16(arg1 | arg2);
987 }
988
989 Datum
990 int2xor(PG_FUNCTION_ARGS)
991 {
992         int16           arg1 = PG_GETARG_INT16(0);
993         int16           arg2 = PG_GETARG_INT16(1);
994
995         PG_RETURN_INT16(arg1 ^ arg2);
996 }
997
998 Datum
999 int2not(PG_FUNCTION_ARGS)
1000 {
1001         int16           arg1 = PG_GETARG_INT16(0);
1002
1003         PG_RETURN_INT16(~arg1);
1004 }
1005
1006
1007 Datum
1008 int2shl(PG_FUNCTION_ARGS)
1009 {
1010         int16           arg1 = PG_GETARG_INT16(0);
1011         int32           arg2 = PG_GETARG_INT32(1);
1012
1013         PG_RETURN_INT16(arg1 << arg2);
1014 }
1015
1016 Datum
1017 int2shr(PG_FUNCTION_ARGS)
1018 {
1019         int16           arg1 = PG_GETARG_INT16(0);
1020         int32           arg2 = PG_GETARG_INT32(1);
1021
1022         PG_RETURN_INT16(arg1 >> arg2);
1023 }