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