]> granicus.if.org Git - postgresql/blob - src/backend/utils/adt/int8.c
Big warnings cleanup for Solaris/GCC. Down to about 40 now, but
[postgresql] / src / backend / utils / adt / int8.c
1 /*-------------------------------------------------------------------------
2  *
3  * int8.c
4  *        Internal 64-bit integer operations
5  *
6  * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
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.21 2000/06/14 18:17:44 petere Exp $
11  *
12  *-------------------------------------------------------------------------
13  */
14 #include <ctype.h>
15 #include <time.h>
16 #include <math.h>
17 #include <float.h>
18
19 #include "postgres.h"
20
21 #ifdef HAVE_LIMITS_H
22 #include <limits.h>
23 #endif
24
25 #include "utils/int8.h"
26
27 /* this should be set in config.h, but just in case it wasn't: */
28 #ifndef INT64_FORMAT
29 #define INT64_FORMAT "%ld"
30 #endif
31
32 #define MAXINT8LEN              25
33
34 #ifndef INT_MAX
35 #define INT_MAX (0x7FFFFFFFL)
36 #endif
37 #ifndef INT_MIN
38 #define INT_MIN (-INT_MAX-1)
39 #endif
40 #ifndef SHRT_MAX
41 #define SHRT_MAX (0x7FFF)
42 #endif
43 #ifndef SHRT_MIN
44 #define SHRT_MIN (-SHRT_MAX-1)
45 #endif
46
47
48 /***********************************************************************
49  **
50  **             Routines for 64-bit integers.
51  **
52  ***********************************************************************/
53
54 /*----------------------------------------------------------
55  * Formatting and conversion routines.
56  *---------------------------------------------------------*/
57
58 /* int8in()
59  */
60 Datum
61 int8in(PG_FUNCTION_ARGS)
62 {
63         char       *str = PG_GETARG_CSTRING(0);
64         int64           result;
65         char       *ptr = str;
66         int64           tmp = 0;
67         int                     sign = 1;
68
69         /*
70          * Do our own scan, rather than relying on sscanf which might be
71          * broken for long long.
72          */
73         while (*ptr && isspace((int) *ptr))             /* skip leading spaces */
74                 ptr++;
75         if (*ptr == '-')                        /* handle sign */
76                 sign = -1, ptr++;
77         else if (*ptr == '+')
78                 ptr++;
79         if (!isdigit((int) *ptr))                       /* require at least one digit */
80                 elog(ERROR, "Bad int8 external representation \"%s\"", str);
81         while (*ptr && isdigit((int) *ptr))             /* process digits */
82         {
83                 int64           newtmp = tmp * 10 + (*ptr++ - '0');
84
85                 if ((newtmp / 10) != tmp)               /* overflow? */
86                         elog(ERROR, "int8 value out of range: \"%s\"", str);
87                 tmp = newtmp;
88         }
89         if (*ptr)                                       /* trailing junk? */
90                 elog(ERROR, "Bad int8 external representation \"%s\"", str);
91
92         result = (sign < 0) ? -tmp : tmp;
93
94         PG_RETURN_INT64(result);
95 }
96
97
98 /* int8out()
99  */
100 Datum
101 int8out(PG_FUNCTION_ARGS)
102 {
103         int64           val = PG_GETARG_INT64(0);
104         char       *result;
105         int                     len;
106         char            buf[MAXINT8LEN + 1];
107
108         if ((len = snprintf(buf, MAXINT8LEN, INT64_FORMAT, val)) < 0)
109                 elog(ERROR, "Unable to format int8");
110
111         result = pstrdup(buf);
112         PG_RETURN_CSTRING(result);
113 }
114
115
116 /*----------------------------------------------------------
117  *      Relational operators for int8s.
118  *---------------------------------------------------------*/
119
120 /* int8relop()
121  * Is val1 relop val2?
122  */
123 Datum
124 int8eq(PG_FUNCTION_ARGS)
125 {
126         int64           val1 = PG_GETARG_INT64(0);
127         int64           val2 = PG_GETARG_INT64(1);
128
129         PG_RETURN_BOOL(val1 == val2);
130 }
131
132 Datum
133 int8ne(PG_FUNCTION_ARGS)
134 {
135         int64           val1 = PG_GETARG_INT64(0);
136         int64           val2 = PG_GETARG_INT64(1);
137
138         PG_RETURN_BOOL(val1 != val2);
139 }
140
141 Datum
142 int8lt(PG_FUNCTION_ARGS)
143 {
144         int64           val1 = PG_GETARG_INT64(0);
145         int64           val2 = PG_GETARG_INT64(1);
146
147         PG_RETURN_BOOL(val1 < val2);
148 }
149
150 Datum
151 int8gt(PG_FUNCTION_ARGS)
152 {
153         int64           val1 = PG_GETARG_INT64(0);
154         int64           val2 = PG_GETARG_INT64(1);
155
156         PG_RETURN_BOOL(val1 > val2);
157 }
158
159 Datum
160 int8le(PG_FUNCTION_ARGS)
161 {
162         int64           val1 = PG_GETARG_INT64(0);
163         int64           val2 = PG_GETARG_INT64(1);
164
165         PG_RETURN_BOOL(val1 <= val2);
166 }
167
168 Datum
169 int8ge(PG_FUNCTION_ARGS)
170 {
171         int64           val1 = PG_GETARG_INT64(0);
172         int64           val2 = PG_GETARG_INT64(1);
173
174         PG_RETURN_BOOL(val1 >= val2);
175 }
176
177 /* int84relop()
178  * Is 64-bit val1 relop 32-bit val2?
179  */
180 Datum
181 int84eq(PG_FUNCTION_ARGS)
182 {
183         int64           val1 = PG_GETARG_INT64(0);
184         int32           val2 = PG_GETARG_INT32(1);
185
186         PG_RETURN_BOOL(val1 == val2);
187 }
188
189 Datum
190 int84ne(PG_FUNCTION_ARGS)
191 {
192         int64           val1 = PG_GETARG_INT64(0);
193         int32           val2 = PG_GETARG_INT32(1);
194
195         PG_RETURN_BOOL(val1 != val2);
196 }
197
198 Datum
199 int84lt(PG_FUNCTION_ARGS)
200 {
201         int64           val1 = PG_GETARG_INT64(0);
202         int32           val2 = PG_GETARG_INT32(1);
203
204         PG_RETURN_BOOL(val1 < val2);
205 }
206
207 Datum
208 int84gt(PG_FUNCTION_ARGS)
209 {
210         int64           val1 = PG_GETARG_INT64(0);
211         int32           val2 = PG_GETARG_INT32(1);
212
213         PG_RETURN_BOOL(val1 > val2);
214 }
215
216 Datum
217 int84le(PG_FUNCTION_ARGS)
218 {
219         int64           val1 = PG_GETARG_INT64(0);
220         int32           val2 = PG_GETARG_INT32(1);
221
222         PG_RETURN_BOOL(val1 <= val2);
223 }
224
225 Datum
226 int84ge(PG_FUNCTION_ARGS)
227 {
228         int64           val1 = PG_GETARG_INT64(0);
229         int32           val2 = PG_GETARG_INT32(1);
230
231         PG_RETURN_BOOL(val1 >= val2);
232 }
233
234 /* int48relop()
235  * Is 32-bit val1 relop 64-bit val2?
236  */
237 Datum
238 int48eq(PG_FUNCTION_ARGS)
239 {
240         int32           val1 = PG_GETARG_INT32(0);
241         int64           val2 = PG_GETARG_INT64(1);
242
243         PG_RETURN_BOOL(val1 == val2);
244 }
245
246 Datum
247 int48ne(PG_FUNCTION_ARGS)
248 {
249         int32           val1 = PG_GETARG_INT32(0);
250         int64           val2 = PG_GETARG_INT64(1);
251
252         PG_RETURN_BOOL(val1 != val2);
253 }
254
255 Datum
256 int48lt(PG_FUNCTION_ARGS)
257 {
258         int32           val1 = PG_GETARG_INT32(0);
259         int64           val2 = PG_GETARG_INT64(1);
260
261         PG_RETURN_BOOL(val1 < val2);
262 }
263
264 Datum
265 int48gt(PG_FUNCTION_ARGS)
266 {
267         int32           val1 = PG_GETARG_INT32(0);
268         int64           val2 = PG_GETARG_INT64(1);
269
270         PG_RETURN_BOOL(val1 > val2);
271 }
272
273 Datum
274 int48le(PG_FUNCTION_ARGS)
275 {
276         int32           val1 = PG_GETARG_INT32(0);
277         int64           val2 = PG_GETARG_INT64(1);
278
279         PG_RETURN_BOOL(val1 <= val2);
280 }
281
282 Datum
283 int48ge(PG_FUNCTION_ARGS)
284 {
285         int32           val1 = PG_GETARG_INT32(0);
286         int64           val2 = PG_GETARG_INT64(1);
287
288         PG_RETURN_BOOL(val1 >= val2);
289 }
290
291
292 /*----------------------------------------------------------
293  *      Arithmetic operators on 64-bit integers.
294  *---------------------------------------------------------*/
295
296 Datum
297 int8um(PG_FUNCTION_ARGS)
298 {
299         int64           val = PG_GETARG_INT64(0);
300
301         PG_RETURN_INT64(- val);
302 }
303
304 Datum
305 int8pl(PG_FUNCTION_ARGS)
306 {
307         int64           val1 = PG_GETARG_INT64(0);
308         int64           val2 = PG_GETARG_INT64(1);
309
310         PG_RETURN_INT64(val1 + val2);
311 }
312
313 Datum
314 int8mi(PG_FUNCTION_ARGS)
315 {
316         int64           val1 = PG_GETARG_INT64(0);
317         int64           val2 = PG_GETARG_INT64(1);
318
319         PG_RETURN_INT64(val1 - val2);
320 }
321
322 Datum
323 int8mul(PG_FUNCTION_ARGS)
324 {
325         int64           val1 = PG_GETARG_INT64(0);
326         int64           val2 = PG_GETARG_INT64(1);
327
328         PG_RETURN_INT64(val1 * val2);
329 }
330
331 Datum
332 int8div(PG_FUNCTION_ARGS)
333 {
334         int64           val1 = PG_GETARG_INT64(0);
335         int64           val2 = PG_GETARG_INT64(1);
336
337         PG_RETURN_INT64(val1 / val2);
338 }
339
340 /* int8abs()
341  * Absolute value
342  */
343 Datum
344 int8abs(PG_FUNCTION_ARGS)
345 {
346         int64           arg1 = PG_GETARG_INT64(0);
347
348         PG_RETURN_INT64((arg1 < 0) ? -arg1 : arg1);
349 }
350
351 /* int8mod()
352  * Modulo operation.
353  */
354 Datum
355 int8mod(PG_FUNCTION_ARGS)
356 {
357         int64           val1 = PG_GETARG_INT64(0);
358         int64           val2 = PG_GETARG_INT64(1);
359         int64           result;
360
361         result = val1 / val2;
362         result *= val2;
363         result = val1 - result;
364
365         PG_RETURN_INT64(result);
366 }
367
368 /* int8fac()
369  * Factorial
370  */
371 Datum
372 int8fac(PG_FUNCTION_ARGS)
373 {
374         int64           arg1 = PG_GETARG_INT64(0);
375         int64           result;
376         int64           i;
377
378         if (arg1 < 1)
379                 result = 0;
380         else
381                 for (i = arg1, result = 1; i > 0; --i)
382                         result *= i;
383
384         PG_RETURN_INT64(result);
385 }
386
387 Datum
388 int8larger(PG_FUNCTION_ARGS)
389 {
390         int64           val1 = PG_GETARG_INT64(0);
391         int64           val2 = PG_GETARG_INT64(1);
392         int64           result;
393
394         result = ((val1 > val2) ? val1 : val2);
395
396         PG_RETURN_INT64(result);
397 }
398
399 Datum
400 int8smaller(PG_FUNCTION_ARGS)
401 {
402         int64           val1 = PG_GETARG_INT64(0);
403         int64           val2 = PG_GETARG_INT64(1);
404         int64           result;
405
406         result = ((val1 < val2) ? val1 : val2);
407
408         PG_RETURN_INT64(result);
409 }
410
411 Datum
412 int84pl(PG_FUNCTION_ARGS)
413 {
414         int64           val1 = PG_GETARG_INT64(0);
415         int32           val2 = PG_GETARG_INT32(1);
416
417         PG_RETURN_INT64(val1 + val2);
418 }
419
420 Datum
421 int84mi(PG_FUNCTION_ARGS)
422 {
423         int64           val1 = PG_GETARG_INT64(0);
424         int32           val2 = PG_GETARG_INT32(1);
425
426         PG_RETURN_INT64(val1 - val2);
427 }
428
429 Datum
430 int84mul(PG_FUNCTION_ARGS)
431 {
432         int64           val1 = PG_GETARG_INT64(0);
433         int32           val2 = PG_GETARG_INT32(1);
434
435         PG_RETURN_INT64(val1 * val2);
436 }
437
438 Datum
439 int84div(PG_FUNCTION_ARGS)
440 {
441         int64           val1 = PG_GETARG_INT64(0);
442         int32           val2 = PG_GETARG_INT32(1);
443
444         PG_RETURN_INT64(val1 / val2);
445 }
446
447 Datum
448 int48pl(PG_FUNCTION_ARGS)
449 {
450         int32           val1 = PG_GETARG_INT32(0);
451         int64           val2 = PG_GETARG_INT64(1);
452
453         PG_RETURN_INT64(val1 + val2);
454 }
455
456 Datum
457 int48mi(PG_FUNCTION_ARGS)
458 {
459         int32           val1 = PG_GETARG_INT32(0);
460         int64           val2 = PG_GETARG_INT64(1);
461
462         PG_RETURN_INT64(val1 - val2);
463 }
464
465 Datum
466 int48mul(PG_FUNCTION_ARGS)
467 {
468         int32           val1 = PG_GETARG_INT32(0);
469         int64           val2 = PG_GETARG_INT64(1);
470
471         PG_RETURN_INT64(val1 * val2);
472 }
473
474 Datum
475 int48div(PG_FUNCTION_ARGS)
476 {
477         int32           val1 = PG_GETARG_INT32(0);
478         int64           val2 = PG_GETARG_INT64(1);
479
480         PG_RETURN_INT64(val1 / val2);
481 }
482
483
484 /*----------------------------------------------------------
485  *      Conversion operators.
486  *---------------------------------------------------------*/
487
488 Datum
489 int48(PG_FUNCTION_ARGS)
490 {
491         int32           val = PG_GETARG_INT32(0);
492
493         PG_RETURN_INT64((int64) val);
494 }
495
496 Datum
497 int84(PG_FUNCTION_ARGS)
498 {
499         int64           val = PG_GETARG_INT64(0);
500         int32           result;
501
502         if ((val < INT_MIN) || (val > INT_MAX))
503                 elog(ERROR, "int8 conversion to int4 is out of range");
504
505         result = (int32) val;
506
507         PG_RETURN_INT32(result);
508 }
509
510 Datum
511 i8tod(PG_FUNCTION_ARGS)
512 {
513         int64           val = PG_GETARG_INT64(0);
514         float8          result;
515
516         result = val;
517
518         PG_RETURN_FLOAT8(result);
519 }
520
521 /* dtoi8()
522  * Convert double float to 8-byte integer.
523  * Do a range check before the conversion.
524  * Note that the comparison probably isn't quite right
525  *      since we only have ~52 bits of precision in a double float
526  *      and so subtracting one from a large number gives the large
527  *      number exactly. However, for some reason the comparison below
528  *      does the right thing on my i686/linux-rh4.2 box.
529  * - thomas 1998-06-16
530  */
531 Datum
532 dtoi8(PG_FUNCTION_ARGS)
533 {
534         float8          val = PG_GETARG_FLOAT8(0);
535         int64           result;
536
537         if ((val < (-pow(2.0, 63.0) + 1)) || (val > (pow(2.0, 63.0) - 1)))
538                 elog(ERROR, "Floating point conversion to int64 is out of range");
539
540         result = (int64) val;
541
542         PG_RETURN_INT64(result);
543 }
544
545 /* text_int8()
546  */
547 Datum
548 text_int8(PG_FUNCTION_ARGS)
549 {
550         text       *str = PG_GETARG_TEXT_P(0);
551         int                     len;
552         char       *s;
553         Datum           result;
554
555         len = (VARSIZE(str) - VARHDRSZ);
556         s = palloc(len + 1);
557         memcpy(s, VARDATA(str), len);
558         *(s + len) = '\0';
559
560         result = DirectFunctionCall1(int8in, CStringGetDatum(s));
561
562         pfree(s);
563
564         return result;
565 }
566
567
568 /* int8_text()
569  */
570 Datum
571 int8_text(PG_FUNCTION_ARGS)
572 {
573         /* val is int64, but easier to leave it as Datum */
574         Datum           val = PG_GETARG_DATUM(0);
575         char       *s;
576         int                     len;
577         text       *result;
578
579         s = DatumGetCString(DirectFunctionCall1(int8out, val));
580         len = strlen(s);
581
582         result = (text *) palloc(VARHDRSZ + len);
583
584         VARSIZE(result) = len + VARHDRSZ;
585         memcpy(VARDATA(result), s, len);
586
587         pfree(s);
588
589         PG_RETURN_TEXT_P(result);
590 }