mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-12-15 08:20:16 +08:00
378 lines
6.8 KiB
C
378 lines
6.8 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
|
|
|
|
#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);
|
|
|
|
/***********************************************************************
|
|
**
|
|
** Routines for 64-bit integers.
|
|
**
|
|
***********************************************************************/
|
|
|
|
/*----------------------------------------------------------
|
|
* Formatting and conversion routines.
|
|
*---------------------------------------------------------*/
|
|
|
|
/* int8in()
|
|
*/
|
|
int64 *
|
|
int8in(char *str)
|
|
{
|
|
int64 *result = palloc(sizeof(int64));
|
|
|
|
#if HAVE_64BIT_INTS
|
|
if (!PointerIsValid(str))
|
|
elog(ERROR, "Bad (null) int8 external representation", NULL);
|
|
|
|
if (sscanf(str, INT64_FORMAT, result) != 1)
|
|
elog(ERROR, "Bad int8 external representation '%s'", str);
|
|
|
|
#else
|
|
elog(ERROR, "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(ERROR, "Unable to format int8", NULL);
|
|
|
|
result = palloc(len + 1);
|
|
|
|
strcpy(result, buf);
|
|
|
|
#else
|
|
elog(ERROR, "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 = palloc(sizeof(int64));
|
|
|
|
if (!PointerIsValid(val))
|
|
return NULL;
|
|
|
|
*result = (-*val);
|
|
|
|
return (result);
|
|
} /* int8um() */
|
|
|
|
int64 *
|
|
int8pl(int64 * val1, int64 * val2)
|
|
{
|
|
int64 *result = palloc(sizeof(int64));
|
|
|
|
if ((!PointerIsValid(val1)) || (!PointerIsValid(val2)))
|
|
return NULL;
|
|
|
|
*result = *val1 + *val2;
|
|
|
|
return (result);
|
|
} /* int8pl() */
|
|
|
|
int64 *
|
|
int8mi(int64 * val1, int64 * val2)
|
|
{
|
|
int64 *result = palloc(sizeof(int64));
|
|
|
|
if ((!PointerIsValid(val1)) || (!PointerIsValid(val2)))
|
|
return NULL;
|
|
|
|
*result = *val1 - *val2;
|
|
|
|
return (result);
|
|
} /* int8mi() */
|
|
|
|
int64 *
|
|
int8mul(int64 * val1, int64 * val2)
|
|
{
|
|
int64 *result = palloc(sizeof(int64));
|
|
|
|
if ((!PointerIsValid(val1)) || (!PointerIsValid(val2)))
|
|
return NULL;
|
|
|
|
*result = *val1 * *val2;
|
|
|
|
return (result);
|
|
} /* int8mul() */
|
|
|
|
int64 *
|
|
int8div(int64 * val1, int64 * val2)
|
|
{
|
|
int64 *result = palloc(sizeof(int64));
|
|
|
|
if ((!PointerIsValid(val1)) || (!PointerIsValid(val2)))
|
|
return NULL;
|
|
|
|
*result = *val1 / *val2;
|
|
|
|
return (result);
|
|
} /* int8div() */
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
* Conversion operators.
|
|
*---------------------------------------------------------*/
|
|
|
|
int64 *
|
|
int48(int32 val)
|
|
{
|
|
int64 *result = palloc(sizeof(int64));
|
|
|
|
*result = val;
|
|
|
|
return (result);
|
|
} /* int48() */
|
|
|
|
int32
|
|
int84(int64 * val)
|
|
{
|
|
int32 result;
|
|
|
|
if (!PointerIsValid(val))
|
|
elog(ERROR, "Invalid (null) int64, can't convert int8 to int4", NULL);
|
|
|
|
if ((*val < INT_MIN) || (*val > INT_MAX))
|
|
elog(ERROR, "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 = palloc(sizeof(int64))))
|
|
elog(ERROR, "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(ERROR, "Invalid (null) int8, can't convert to int2", NULL);
|
|
|
|
result = *val;
|
|
|
|
return (result);
|
|
} /* int82() */
|
|
|
|
#endif
|
|
|
|
float64
|
|
i8tod(int64 * val)
|
|
{
|
|
float64 result = palloc(sizeof(float64data));
|
|
|
|
*result = *val;
|
|
|
|
return (result);
|
|
} /* i8tod() */
|
|
|
|
int64 *
|
|
dtoi8(float64 val)
|
|
{
|
|
int64 *result = palloc(sizeof(int64));
|
|
|
|
if ((*val < (-pow(2, 64) + 1)) || (*val > (pow(2, 64) - 1)))
|
|
elog(ERROR, "Floating point conversion to int64 is out of range", NULL);
|
|
|
|
*result = *val;
|
|
|
|
return (result);
|
|
} /* dtoi8() */
|