mirror of
				https://github.com/postgres/postgres.git
				synced 2025-11-03 09:13:20 +03:00 
			
		
		
		
	Includes compiled code to support pre-7.0 backends, but for 7.0 only requires executing odbc.sql.
		
			
				
	
	
		
			414 lines
		
	
	
		
			6.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			414 lines
		
	
	
		
			6.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
#include <stdlib.h>
 | 
						|
#include <ctype.h>
 | 
						|
#include <errno.h>
 | 
						|
 | 
						|
#include <float.h>				/* faked on sunos4 */
 | 
						|
 | 
						|
#include <math.h>
 | 
						|
 | 
						|
#include "postgres.h"
 | 
						|
#ifdef HAVE_LIMITS_H
 | 
						|
#include <limits.h>
 | 
						|
#ifndef MAXINT
 | 
						|
#define MAXINT		  INT_MAX
 | 
						|
#endif
 | 
						|
#else
 | 
						|
#ifdef HAVE_VALUES_H
 | 
						|
#include <values.h>
 | 
						|
#endif
 | 
						|
#endif
 | 
						|
#include "fmgr.h"
 | 
						|
#include "utils/timestamp.h"
 | 
						|
#include "utils/builtins.h"
 | 
						|
 | 
						|
 | 
						|
int4 ascii(text *string);
 | 
						|
text *ichar(int4 cvalue);
 | 
						|
text *repeat(text *string, int4 count);
 | 
						|
Interval *interval_mul(Interval *span1, float8 *arg2);
 | 
						|
float64 dasin(float64 arg1);
 | 
						|
float64 datan(float64 arg1);
 | 
						|
float64 datan2(float64 arg1, float64 arg2);
 | 
						|
float64 dcos(float64 arg1);
 | 
						|
float64 dcot(float64 arg1);
 | 
						|
float64 dsin(float64 arg1);
 | 
						|
float64 dtan(float64 arg1);
 | 
						|
float64 degrees(float64 arg1);
 | 
						|
float64 dpi(void);
 | 
						|
float64 radians(float64 arg1);
 | 
						|
float64 drandom(void);
 | 
						|
void setseed(int32 seed);
 | 
						|
 | 
						|
 | 
						|
int4
 | 
						|
ascii(text *string)
 | 
						|
{
 | 
						|
	if (!PointerIsValid(string))
 | 
						|
		return 0;
 | 
						|
 | 
						|
	if (VARSIZE(string) <= VARHDRSZ)
 | 
						|
		return 0;
 | 
						|
 | 
						|
	return ((int) *(VARDATA(string)));
 | 
						|
} /* ascii() */
 | 
						|
 | 
						|
 | 
						|
text *
 | 
						|
ichar(int4 cvalue)
 | 
						|
{
 | 
						|
	text   *result;
 | 
						|
 | 
						|
	result = (text *) palloc(VARHDRSZ + 1);
 | 
						|
	VARSIZE(result) = VARHDRSZ + 1;
 | 
						|
	*VARDATA(result) = (char) cvalue;
 | 
						|
 | 
						|
	return result;
 | 
						|
} /* ichar() */
 | 
						|
 | 
						|
 | 
						|
text *
 | 
						|
repeat(text *string, int4 count)
 | 
						|
{
 | 
						|
	text   *result;
 | 
						|
	int		slen, tlen;
 | 
						|
	int		i;
 | 
						|
	char   *cp;
 | 
						|
 | 
						|
	if (count < 0)
 | 
						|
		count = 0;
 | 
						|
 | 
						|
	slen = (VARSIZE(string)-VARHDRSZ);
 | 
						|
	tlen = (VARHDRSZ + (count * slen));
 | 
						|
 | 
						|
	result = (text *) palloc(tlen);
 | 
						|
 | 
						|
	VARSIZE(result) = tlen;
 | 
						|
	cp = VARDATA(result);
 | 
						|
	for (i = 0; i < count; i++)
 | 
						|
	{
 | 
						|
		memcpy(cp, VARDATA(string), slen);
 | 
						|
		cp += slen;
 | 
						|
	}
 | 
						|
 | 
						|
	return result;
 | 
						|
} /* ichar() */
 | 
						|
 | 
						|
Interval   *
 | 
						|
interval_mul(Interval *span1, float8 *arg2)
 | 
						|
{
 | 
						|
	Interval   *result;
 | 
						|
	double		months;
 | 
						|
 | 
						|
	if ((!PointerIsValid(span1)) || (!PointerIsValid(arg2)))
 | 
						|
		return NULL;
 | 
						|
 | 
						|
	if (!PointerIsValid(result = palloc(sizeof(Interval))))
 | 
						|
		elog(ERROR, "Memory allocation failed, can't divide intervals");
 | 
						|
 | 
						|
	months = (span1->month * *arg2);
 | 
						|
	result->month = rint(months);
 | 
						|
	result->time = JROUND(span1->time * *arg2);
 | 
						|
	result->time += JROUND((months - result->month) * 30);
 | 
						|
 | 
						|
	return result;
 | 
						|
}	/* interval_mul() */
 | 
						|
 | 
						|
/*
 | 
						|
 *		dasin			- returns a pointer to the arcsin of arg1 (radians)
 | 
						|
 */
 | 
						|
float64
 | 
						|
dasin(float64 arg1)
 | 
						|
{
 | 
						|
	float64		result;
 | 
						|
	double		tmp;
 | 
						|
 | 
						|
	if (!PointerIsValid(arg1))
 | 
						|
		return (float64) NULL;
 | 
						|
 | 
						|
	result = (float64) palloc(sizeof(float64data));
 | 
						|
 | 
						|
	tmp = *arg1;
 | 
						|
	errno = 0;
 | 
						|
	*result = (float64data) asin(tmp);
 | 
						|
	if (errno != 0
 | 
						|
#ifdef HAVE_FINITE
 | 
						|
		|| !finite(*result)
 | 
						|
#endif
 | 
						|
		)
 | 
						|
		elog(ERROR, "dasin(%f) input is out of range", *arg1);
 | 
						|
 | 
						|
	CheckFloat8Val(*result);
 | 
						|
	return result;
 | 
						|
} /* dasin() */
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 *		datan			- returns a pointer to the arctan of arg1 (radians)
 | 
						|
 */
 | 
						|
float64
 | 
						|
datan(float64 arg1)
 | 
						|
{
 | 
						|
	float64		result;
 | 
						|
	double		tmp;
 | 
						|
 | 
						|
	if (!PointerIsValid(arg1))
 | 
						|
		return (float64) NULL;
 | 
						|
 | 
						|
	result = (float64) palloc(sizeof(float64data));
 | 
						|
 | 
						|
	tmp = *arg1;
 | 
						|
	errno = 0;
 | 
						|
	*result = (float64data) atan(tmp);
 | 
						|
	if (errno != 0
 | 
						|
#ifdef HAVE_FINITE
 | 
						|
		|| !finite(*result)
 | 
						|
#endif
 | 
						|
		)
 | 
						|
		elog(ERROR, "atan(%f) input is out of range", *arg1);
 | 
						|
 | 
						|
	CheckFloat8Val(*result);
 | 
						|
	return result;
 | 
						|
} /* datan() */
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 *		atan2			- returns a pointer to the arctan2 of arg1 (radians)
 | 
						|
 */
 | 
						|
float64
 | 
						|
datan2(float64 arg1, float64 arg2)
 | 
						|
{
 | 
						|
	float64		result;
 | 
						|
 | 
						|
	if (!PointerIsValid(arg1) || !PointerIsValid(arg1))
 | 
						|
		return (float64) NULL;
 | 
						|
 | 
						|
	result = (float64) palloc(sizeof(float64data));
 | 
						|
 | 
						|
	errno = 0;
 | 
						|
	*result = (float64data) atan2(*arg1, *arg2);
 | 
						|
	if (errno != 0
 | 
						|
#ifdef HAVE_FINITE
 | 
						|
		|| !finite(*result)
 | 
						|
#endif
 | 
						|
		)
 | 
						|
		elog(ERROR, "atan2(%f,%f) input is out of range", *arg1, *arg2);
 | 
						|
 | 
						|
	CheckFloat8Val(*result);
 | 
						|
	return result;
 | 
						|
} /* datan2() */
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 *		dcos			- returns a pointer to the cosine of arg1 (radians)
 | 
						|
 */
 | 
						|
float64
 | 
						|
dcos(float64 arg1)
 | 
						|
{
 | 
						|
	float64		result;
 | 
						|
	double		tmp;
 | 
						|
 | 
						|
	if (!PointerIsValid(arg1))
 | 
						|
		return (float64) NULL;
 | 
						|
 | 
						|
	result = (float64) palloc(sizeof(float64data));
 | 
						|
 | 
						|
	tmp = *arg1;
 | 
						|
	errno = 0;
 | 
						|
	*result = (float64data) cos(tmp);
 | 
						|
	if (errno != 0
 | 
						|
#ifdef HAVE_FINITE
 | 
						|
		|| !finite(*result)
 | 
						|
#endif
 | 
						|
		)
 | 
						|
		elog(ERROR, "dcos(%f) input is out of range", *arg1);
 | 
						|
 | 
						|
	CheckFloat8Val(*result);
 | 
						|
	return result;
 | 
						|
} /* dcos() */
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 *		dcot			- returns a pointer to the cotangent of arg1 (radians)
 | 
						|
 */
 | 
						|
float64
 | 
						|
dcot(float64 arg1)
 | 
						|
{
 | 
						|
	float64		result;
 | 
						|
	double		tmp;
 | 
						|
 | 
						|
	if (!PointerIsValid(arg1))
 | 
						|
		return (float64) NULL;
 | 
						|
 | 
						|
	result = (float64) palloc(sizeof(float64data));
 | 
						|
 | 
						|
	tmp = *arg1;
 | 
						|
	errno = 0;
 | 
						|
	*result = (float64data) tan(tmp);
 | 
						|
	if ((errno != 0) || (*result == 0.0)
 | 
						|
#ifdef HAVE_FINITE
 | 
						|
		|| !finite(*result)
 | 
						|
#endif
 | 
						|
		)
 | 
						|
		elog(ERROR, "dcot(%f) input is out of range", *arg1);
 | 
						|
 | 
						|
	*result = 1.0/(*result);
 | 
						|
	CheckFloat8Val(*result);
 | 
						|
	return result;
 | 
						|
} /* dcot() */
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 *		dsin			- returns a pointer to the sine of arg1 (radians)
 | 
						|
 */
 | 
						|
float64
 | 
						|
dsin(float64 arg1)
 | 
						|
{
 | 
						|
	float64		result;
 | 
						|
	double		tmp;
 | 
						|
 | 
						|
	if (!PointerIsValid(arg1))
 | 
						|
		return (float64) NULL;
 | 
						|
 | 
						|
	result = (float64) palloc(sizeof(float64data));
 | 
						|
 | 
						|
	tmp = *arg1;
 | 
						|
	errno = 0;
 | 
						|
	*result = (float64data) sin(tmp);
 | 
						|
	if (errno != 0
 | 
						|
#ifdef HAVE_FINITE
 | 
						|
		|| !finite(*result)
 | 
						|
#endif
 | 
						|
		)
 | 
						|
		elog(ERROR, "dsin(%f) input is out of range", *arg1);
 | 
						|
 | 
						|
	CheckFloat8Val(*result);
 | 
						|
	return result;
 | 
						|
} /* dsin() */
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 *		dtan			- returns a pointer to the tangent of arg1 (radians)
 | 
						|
 */
 | 
						|
float64
 | 
						|
dtan(float64 arg1)
 | 
						|
{
 | 
						|
	float64		result;
 | 
						|
	double		tmp;
 | 
						|
 | 
						|
	if (!PointerIsValid(arg1))
 | 
						|
		return (float64) NULL;
 | 
						|
 | 
						|
	result = (float64) palloc(sizeof(float64data));
 | 
						|
 | 
						|
	tmp = *arg1;
 | 
						|
	errno = 0;
 | 
						|
	*result = (float64data) tan(tmp);
 | 
						|
	if (errno != 0
 | 
						|
#ifdef HAVE_FINITE
 | 
						|
		|| !finite(*result)
 | 
						|
#endif
 | 
						|
		)
 | 
						|
		elog(ERROR, "dtan(%f) input is out of range", *arg1);
 | 
						|
 | 
						|
	CheckFloat8Val(*result);
 | 
						|
	return result;
 | 
						|
} /* dtan() */
 | 
						|
 | 
						|
 | 
						|
#ifndef M_PI
 | 
						|
/* from my RH5.2 gcc math.h file - thomas 2000-04-03 */
 | 
						|
#define M_PI 3.14159265358979323846
 | 
						|
#endif
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 *		degrees		- returns a pointer to degrees converted from radians
 | 
						|
 */
 | 
						|
float64
 | 
						|
degrees(float64 arg1)
 | 
						|
{
 | 
						|
	float64		result;
 | 
						|
 | 
						|
	if (!arg1)
 | 
						|
		return (float64) NULL;
 | 
						|
 | 
						|
	result = (float64) palloc(sizeof(float64data));
 | 
						|
 | 
						|
	*result = ((*arg1) * (180.0 / M_PI));
 | 
						|
 | 
						|
	CheckFloat8Val(*result);
 | 
						|
	return result;
 | 
						|
} /* degrees() */
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 *		dpi				- returns a pointer to degrees converted to radians
 | 
						|
 */
 | 
						|
float64
 | 
						|
dpi(void)
 | 
						|
{
 | 
						|
	float64		result;
 | 
						|
 | 
						|
	result = (float64) palloc(sizeof(float64data));
 | 
						|
 | 
						|
	*result = (M_PI);
 | 
						|
 | 
						|
	return result;
 | 
						|
} /* dpi() */
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 *		radians		- returns a pointer to radians converted from degrees
 | 
						|
 */
 | 
						|
float64
 | 
						|
radians(float64 arg1)
 | 
						|
{
 | 
						|
	float64		result;
 | 
						|
 | 
						|
	if (!arg1)
 | 
						|
		return (float64) NULL;
 | 
						|
 | 
						|
	result = (float64) palloc(sizeof(float64data));
 | 
						|
 | 
						|
	*result = ((*arg1) * (M_PI / 180.0));
 | 
						|
 | 
						|
	CheckFloat8Val(*result);
 | 
						|
	return result;
 | 
						|
} /* radians() */
 | 
						|
 | 
						|
 | 
						|
#ifdef RAND_MAX
 | 
						|
 | 
						|
/*
 | 
						|
 *		drandom   	- returns a random number
 | 
						|
 */
 | 
						|
float64
 | 
						|
drandom(void)
 | 
						|
{
 | 
						|
	float64		result;
 | 
						|
 | 
						|
	result = (float64) palloc(sizeof(float64data));
 | 
						|
 | 
						|
	/* result 0.0-1.0 */
 | 
						|
	*result = (((double)rand()) / RAND_MAX);
 | 
						|
 | 
						|
	CheckFloat8Val(*result);
 | 
						|
	return result;
 | 
						|
} /* drandom() */
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 *		setseed   	- set seed for the random number generator
 | 
						|
 */
 | 
						|
void
 | 
						|
setseed(int32 seed)
 | 
						|
{
 | 
						|
	srand(seed);
 | 
						|
 | 
						|
	return;
 | 
						|
} /* setseed() */
 | 
						|
 | 
						|
#endif
 | 
						|
 | 
						|
 |