mirror of
				https://github.com/postgres/postgres.git
				synced 2025-11-03 09:13:20 +03:00 
			
		
		
		
	
		
			
				
	
	
		
			362 lines
		
	
	
		
			6.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			362 lines
		
	
	
		
			6.9 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() */
 | 
						|
 |