mirror of
				https://github.com/postgres/postgres.git
				synced 2025-10-29 22:49:41 +03:00 
			
		
		
		
	
		
			
				
	
	
		
			392 lines
		
	
	
		
			7.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			392 lines
		
	
	
		
			7.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*-------------------------------------------------------------------------
 | |
|  *
 | |
|  * int8.c--
 | |
|  *	  Internal 64-bit integer operations
 | |
|  *
 | |
|  *-------------------------------------------------------------------------
 | |
|  */
 | |
| #include <stdio.h>				/* for sprintf proto, etc. */
 | |
| #include <stdlib.h>				/* for strtod, etc. */
 | |
| #include <string.h>
 | |
| #include <ctype.h>
 | |
| #include <time.h>
 | |
| #include <math.h>
 | |
| #include <float.h>
 | |
| #include <limits.h>
 | |
| 
 | |
| #include "postgres.h"
 | |
| #include "utils/palloc.h"
 | |
| 
 | |
| #define MAXINT8LEN		25
 | |
| 
 | |
| #define USE_LOCAL_CODE	1
 | |
| 
 | |
| #if defined(__alpha) || defined(__GNUC__)
 | |
| #define HAVE_64BIT_INTS 1
 | |
| #endif
 | |
| 
 | |
| #ifndef HAVE_64BIT_INTS
 | |
| typedef char[8] int64;
 | |
| 
 | |
| #elif defined(__alpha)
 | |
| typedef long int int64;
 | |
| 
 | |
| #define INT64_FORMAT "%ld"
 | |
| 
 | |
| #elif defined(__GNUC__)
 | |
| typedef long long int int64;
 | |
| 
 | |
| #define INT64_FORMAT "%Ld"
 | |
| 
 | |
| #else
 | |
| typedef long int int64;
 | |
| 
 | |
| #define INT64_FORMAT "%ld"
 | |
| #endif
 | |
| 
 | |
| int64	   *int8in(char *str);
 | |
| char	   *int8out(int64 * val);
 | |
| 
 | |
| bool		int8eq(int64 * val1, int64 * val2);
 | |
| bool		int8ne(int64 * val1, int64 * val2);
 | |
| bool		int8lt(int64 * val1, int64 * val2);
 | |
| bool		int8gt(int64 * val1, int64 * val2);
 | |
| bool		int8le(int64 * val1, int64 * val2);
 | |
| bool		int8ge(int64 * val1, int64 * val2);
 | |
| 
 | |
| bool		int84eq(int64 * val1, int32 val2);
 | |
| bool		int84ne(int64 * val1, int32 val2);
 | |
| bool		int84lt(int64 * val1, int32 val2);
 | |
| bool		int84gt(int64 * val1, int32 val2);
 | |
| bool		int84le(int64 * val1, int32 val2);
 | |
| bool		int84ge(int64 * val1, int32 val2);
 | |
| 
 | |
| int64	   *int8um(int64 * val);
 | |
| int64	   *int8pl(int64 * val1, int64 * val2);
 | |
| int64	   *int8mi(int64 * val1, int64 * val2);
 | |
| int64	   *int8mul(int64 * val1, int64 * val2);
 | |
| int64	   *int8div(int64 * val1, int64 * val2);
 | |
| 
 | |
| int64	   *int48(int32 val);
 | |
| int32		int84(int64 * val);
 | |
| 
 | |
| #if FALSE
 | |
| int64	   *int28 (int16 val);
 | |
| int16		int82(int64 * val);
 | |
| 
 | |
| #endif
 | |
| 
 | |
| float64		i8tod(int64 * val);
 | |
| int64	   *dtoi8(float64 val);
 | |
| 
 | |
| #if USE_LOCAL_CODE
 | |
| 
 | |
| #ifndef PALLOC
 | |
| #define PALLOC(p) palloc(p)
 | |
| #endif
 | |
| 
 | |
| #ifndef PALLOCTYPE
 | |
| #define PALLOCTYPE(p) palloc(sizeof(p))
 | |
| #endif
 | |
| 
 | |
| #endif
 | |
| 
 | |
| /***********************************************************************
 | |
|  **
 | |
|  **		Routines for 64-bit integers.
 | |
|  **
 | |
|  ***********************************************************************/
 | |
| 
 | |
| /*----------------------------------------------------------
 | |
|  * Formatting and conversion routines.
 | |
|  *---------------------------------------------------------*/
 | |
| 
 | |
| /* int8in()
 | |
|  */
 | |
| int64	   *
 | |
| int8in(char *str)
 | |
| {
 | |
| 	int64	   *result = PALLOCTYPE(int64);
 | |
| 
 | |
| #if HAVE_64BIT_INTS
 | |
| 	if (!PointerIsValid(str))
 | |
| 		elog(WARN, "Bad (null) int8 external representation", NULL);
 | |
| 
 | |
| 	if (sscanf(str, INT64_FORMAT, result) != 1)
 | |
| 		elog(WARN, "Bad int8 external representation '%s'", str);
 | |
| 
 | |
| #else
 | |
| 	elog(WARN, "64-bit integers are not supported", NULL);
 | |
| 	result = NULL;
 | |
| #endif
 | |
| 
 | |
| 	return (result);
 | |
| }								/* int8in() */
 | |
| 
 | |
| 
 | |
| /* int8out()
 | |
|  */
 | |
| char	   *
 | |
| int8out(int64 * val)
 | |
| {
 | |
| 	char	   *result;
 | |
| 
 | |
| 	int			len;
 | |
| 	char		buf[MAXINT8LEN + 1];
 | |
| 
 | |
| #if HAVE_64BIT_INTS
 | |
| 	if (!PointerIsValid(val))
 | |
| 		return (NULL);
 | |
| 
 | |
| 	if ((len = snprintf(buf, MAXINT8LEN, INT64_FORMAT, *val)) < 0)
 | |
| 		elog(WARN, "Unable to format int8", NULL);
 | |
| 
 | |
| 	result = PALLOC(len + 1);
 | |
| 
 | |
| 	strcpy(result, buf);
 | |
| 
 | |
| #else
 | |
| 	elog(WARN, "64-bit integers are not supported", NULL);
 | |
| 	result = NULL;
 | |
| #endif
 | |
| 
 | |
| 	return (result);
 | |
| }								/* int8out() */
 | |
| 
 | |
| 
 | |
| /*----------------------------------------------------------
 | |
|  *	Relational operators for int8s.
 | |
|  *---------------------------------------------------------*/
 | |
| 
 | |
| /* int8relop()
 | |
|  * Is val1 relop val2?
 | |
|  */
 | |
| bool
 | |
| int8eq(int64 * val1, int64 * val2)
 | |
| {
 | |
| 	return (*val1 == *val2);
 | |
| }								/* int8eq() */
 | |
| 
 | |
| bool
 | |
| int8ne(int64 * val1, int64 * val2)
 | |
| {
 | |
| 	return (*val1 != *val2);
 | |
| }								/* int8ne() */
 | |
| 
 | |
| bool
 | |
| int8lt(int64 * val1, int64 * val2)
 | |
| {
 | |
| 	return (*val1 < *val2);
 | |
| }								/* int8lt() */
 | |
| 
 | |
| bool
 | |
| int8gt(int64 * val1, int64 * val2)
 | |
| {
 | |
| 	return (*val1 > *val2);
 | |
| }								/* int8gt() */
 | |
| 
 | |
| bool
 | |
| int8le(int64 * val1, int64 * val2)
 | |
| {
 | |
| 	return (*val1 <= *val2);
 | |
| }								/* int8le() */
 | |
| 
 | |
| bool
 | |
| int8ge(int64 * val1, int64 * val2)
 | |
| {
 | |
| 	return (*val1 >= *val2);
 | |
| }								/* int8ge() */
 | |
| 
 | |
| 
 | |
| /* int84relop()
 | |
|  * Is 64-bit val1 relop 32-bit val2?
 | |
|  */
 | |
| bool
 | |
| int84eq(int64 * val1, int32 val2)
 | |
| {
 | |
| 	return (*val1 == val2);
 | |
| }								/* int84eq() */
 | |
| 
 | |
| bool
 | |
| int84ne(int64 * val1, int32 val2)
 | |
| {
 | |
| 	return (*val1 != val2);
 | |
| }								/* int84ne() */
 | |
| 
 | |
| bool
 | |
| int84lt(int64 * val1, int32 val2)
 | |
| {
 | |
| 	return (*val1 < val2);
 | |
| }								/* int84lt() */
 | |
| 
 | |
| bool
 | |
| int84gt(int64 * val1, int32 val2)
 | |
| {
 | |
| 	return (*val1 > val2);
 | |
| }								/* int84gt() */
 | |
| 
 | |
| bool
 | |
| int84le(int64 * val1, int32 val2)
 | |
| {
 | |
| 	return (*val1 <= val2);
 | |
| }								/* int84le() */
 | |
| 
 | |
| bool
 | |
| int84ge(int64 * val1, int32 val2)
 | |
| {
 | |
| 	return (*val1 >= val2);
 | |
| }								/* int84ge() */
 | |
| 
 | |
| 
 | |
| /*----------------------------------------------------------
 | |
|  *	Arithmetic operators on 64-bit integers.
 | |
|  *---------------------------------------------------------*/
 | |
| 
 | |
| int64	   *
 | |
| int8um(int64 * val)
 | |
| {
 | |
| 	int64	   *result = PALLOCTYPE(int64);
 | |
| 
 | |
| 	if (!PointerIsValid(val))
 | |
| 		return NULL;
 | |
| 
 | |
| 	*result = (-*val);
 | |
| 
 | |
| 	return (result);
 | |
| }								/* int8um() */
 | |
| 
 | |
| int64	   *
 | |
| int8pl(int64 * val1, int64 * val2)
 | |
| {
 | |
| 	int64	   *result = PALLOCTYPE(int64);
 | |
| 
 | |
| 	if ((!PointerIsValid(val1)) || (!PointerIsValid(val2)))
 | |
| 		return NULL;
 | |
| 
 | |
| 	*result = *val1 + *val2;
 | |
| 
 | |
| 	return (result);
 | |
| }								/* int8pl() */
 | |
| 
 | |
| int64	   *
 | |
| int8mi(int64 * val1, int64 * val2)
 | |
| {
 | |
| 	int64	   *result = PALLOCTYPE(int64);
 | |
| 
 | |
| 	if ((!PointerIsValid(val1)) || (!PointerIsValid(val2)))
 | |
| 		return NULL;
 | |
| 
 | |
| 	*result = *val1 - *val2;
 | |
| 
 | |
| 	return (result);
 | |
| }								/* int8mi() */
 | |
| 
 | |
| int64	   *
 | |
| int8mul(int64 * val1, int64 * val2)
 | |
| {
 | |
| 	int64	   *result = PALLOCTYPE(int64);
 | |
| 
 | |
| 	if ((!PointerIsValid(val1)) || (!PointerIsValid(val2)))
 | |
| 		return NULL;
 | |
| 
 | |
| 	*result = *val1 * *val2;
 | |
| 
 | |
| 	return (result);
 | |
| }								/* int8mul() */
 | |
| 
 | |
| int64	   *
 | |
| int8div(int64 * val1, int64 * val2)
 | |
| {
 | |
| 	int64	   *result = PALLOCTYPE(int64);
 | |
| 
 | |
| 	if ((!PointerIsValid(val1)) || (!PointerIsValid(val2)))
 | |
| 		return NULL;
 | |
| 
 | |
| 	*result = *val1 / *val2;
 | |
| 
 | |
| 	return (result);
 | |
| }								/* int8div() */
 | |
| 
 | |
| 
 | |
| /*----------------------------------------------------------
 | |
|  *	Conversion operators.
 | |
|  *---------------------------------------------------------*/
 | |
| 
 | |
| int64	   *
 | |
| int48(int32 val)
 | |
| {
 | |
| 	int64	   *result = PALLOCTYPE(int64);
 | |
| 
 | |
| 	*result = val;
 | |
| 
 | |
| 	return (result);
 | |
| }								/* int48() */
 | |
| 
 | |
| int32
 | |
| int84(int64 * val)
 | |
| {
 | |
| 	int32		result;
 | |
| 
 | |
| 	if (!PointerIsValid(val))
 | |
| 		elog(WARN, "Invalid (null) int64, can't convert int8 to int4", NULL);
 | |
| 
 | |
| 	if ((*val < INT_MIN) || (*val > INT_MAX))
 | |
| 		elog(WARN, "int8 conversion to int4 is out of range", NULL);
 | |
| 
 | |
| 	result = *val;
 | |
| 
 | |
| 	return (result);
 | |
| }								/* int84() */
 | |
| 
 | |
| #if FALSE
 | |
| int64	   *
 | |
| int28		(int16 val)
 | |
| {
 | |
| 	int64	   *result;
 | |
| 
 | |
| 	if (!PointerIsValid(result = PALLOCTYPE(int64)))
 | |
| 		elog(WARN, "Memory allocation failed, can't convert int8 to int2", NULL);
 | |
| 
 | |
| 	*result = val;
 | |
| 
 | |
| 	return (result);
 | |
| }								/* int28() */
 | |
| 
 | |
| int16
 | |
| int82(int64 * val)
 | |
| {
 | |
| 	int16		result;
 | |
| 
 | |
| 	if (!PointerIsValid(val))
 | |
| 		elog(WARN, "Invalid (null) int8, can't convert to int2", NULL);
 | |
| 
 | |
| 	result = *val;
 | |
| 
 | |
| 	return (result);
 | |
| }								/* int82() */
 | |
| 
 | |
| #endif
 | |
| 
 | |
| float64
 | |
| i8tod(int64 * val)
 | |
| {
 | |
| 	float64		result = PALLOCTYPE(float64data);
 | |
| 
 | |
| 	*result = *val;
 | |
| 
 | |
| 	return (result);
 | |
| }								/* i8tod() */
 | |
| 
 | |
| int64	   *
 | |
| dtoi8(float64 val)
 | |
| {
 | |
| 	int64	   *result = PALLOCTYPE(int64);
 | |
| 
 | |
| 	if ((*val < (-pow(2, 64) + 1)) || (*val > (pow(2, 64) - 1)))
 | |
| 		elog(WARN, "Floating point conversion to int64 is out of range", NULL);
 | |
| 
 | |
| 	*result = *val;
 | |
| 
 | |
| 	return (result);
 | |
| }								/* dtoi8() */
 |