mirror of https://github.com/postgres/postgres
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
185 lines
4.4 KiB
185 lines
4.4 KiB
|
29 years ago
|
/******************************************************************************
|
||
|
|
This file contains routines that can be bound to a Postgres backend and
|
||
|
|
called by the backend in the process of processing queries. The calling
|
||
|
|
format for these routines is dictated by Postgres architecture.
|
||
|
|
******************************************************************************/
|
||
|
|
|
||
|
30 years ago
|
#include <stdio.h>
|
||
|
|
/* do not include libpq-fe.h for backend-loaded functions*/
|
||
|
|
/* #include "libpq-fe.h" */
|
||
|
|
#include "postgres.h"
|
||
|
|
#include "utils/mcxt.h"
|
||
|
|
|
||
|
29 years ago
|
typedef struct Complex
|
||
|
|
{
|
||
|
29 years ago
|
double x;
|
||
|
|
double y;
|
||
|
|
} Complex;
|
||
|
30 years ago
|
|
||
|
29 years ago
|
/* These prototypes declare the requirements that Postgres places on these
|
||
|
|
user written functions.
|
||
|
|
*/
|
||
|
29 years ago
|
Complex *complex_in(char *str);
|
||
|
|
char *complex_out(Complex * complex);
|
||
|
|
Complex *complex_add(Complex * a, Complex * b);
|
||
|
|
bool complex_abs_lt(Complex * a, Complex * b);
|
||
|
|
bool complex_abs_le(Complex * a, Complex * b);
|
||
|
|
bool complex_abs_eq(Complex * a, Complex * b);
|
||
|
|
bool complex_abs_ge(Complex * a, Complex * b);
|
||
|
|
bool complex_abs_gt(Complex * a, Complex * b);
|
||
|
|
int4 complex_abs_cmp(Complex * a, Complex * b);
|
||
|
29 years ago
|
|
||
|
|
|
||
|
30 years ago
|
/*****************************************************************************
|
||
|
|
* Input/Output functions
|
||
|
|
*****************************************************************************/
|
||
|
|
|
||
|
29 years ago
|
Complex *
|
||
|
30 years ago
|
complex_in(char *str)
|
||
|
|
{
|
||
|
29 years ago
|
double x,
|
||
|
|
y;
|
||
|
|
Complex *result;
|
||
|
29 years ago
|
|
||
|
|
if (sscanf(str, " ( %lf , %lf )", &x, &y) != 2)
|
||
|
|
{
|
||
|
28 years ago
|
elog(ERROR, "complex_in: error in parsing \"%s\"", str);
|
||
|
29 years ago
|
return NULL;
|
||
|
|
}
|
||
|
|
result = (Complex *) palloc(sizeof(Complex));
|
||
|
|
result->x = x;
|
||
|
|
result->y = y;
|
||
|
|
return (result);
|
||
|
30 years ago
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
* You might have noticed a slight inconsistency between the following
|
||
|
|
* declaration and the SQL definition:
|
||
|
29 years ago
|
* CREATE FUNCTION complex_out(opaque) RETURNS opaque ...
|
||
|
30 years ago
|
* The reason is that the argument pass into complex_out is really just a
|
||
|
|
* pointer. POSTGRES thinks all output functions are:
|
||
|
29 years ago
|
* char *out_func(char *);
|
||
|
30 years ago
|
*/
|
||
|
28 years ago
|
char *
|
||
|
29 years ago
|
complex_out(Complex * complex)
|
||
|
30 years ago
|
{
|
||
|
29 years ago
|
char *result;
|
||
|
30 years ago
|
|
||
|
29 years ago
|
if (complex == NULL)
|
||
|
|
return (NULL);
|
||
|
30 years ago
|
|
||
|
29 years ago
|
result = (char *) palloc(60);
|
||
|
|
sprintf(result, "(%g,%g)", complex->x, complex->y);
|
||
|
|
return (result);
|
||
|
30 years ago
|
}
|
||
|
|
|
||
|
|
/*****************************************************************************
|
||
|
|
* New Operators
|
||
|
|
*****************************************************************************/
|
||
|
|
|
||
|
29 years ago
|
Complex *
|
||
|
29 years ago
|
complex_add(Complex * a, Complex * b)
|
||
|
30 years ago
|
{
|
||
|
29 years ago
|
Complex *result;
|
||
|
29 years ago
|
|
||
|
|
result = (Complex *) palloc(sizeof(Complex));
|
||
|
|
result->x = a->x + b->x;
|
||
|
|
result->y = a->y + b->y;
|
||
|
|
return (result);
|
||
|
30 years ago
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/*****************************************************************************
|
||
|
|
* Operator class for defining B-tree index
|
||
|
|
*****************************************************************************/
|
||
|
|
|
||
|
|
#define Mag(c) ((c)->x*(c)->x + (c)->y*(c)->y)
|
||
|
|
|
||
|
|
bool
|
||
|
29 years ago
|
complex_abs_lt(Complex * a, Complex * b)
|
||
|
30 years ago
|
{
|
||
|
29 years ago
|
double amag = Mag(a),
|
||
|
|
bmag = Mag(b);
|
||
|
29 years ago
|
|
||
|
|
return (amag < bmag);
|
||
|
30 years ago
|
}
|
||
|
|
|
||
|
|
bool
|
||
|
29 years ago
|
complex_abs_le(Complex * a, Complex * b)
|
||
|
30 years ago
|
{
|
||
|
29 years ago
|
double amag = Mag(a),
|
||
|
|
bmag = Mag(b);
|
||
|
29 years ago
|
|
||
|
|
return (amag <= bmag);
|
||
|
30 years ago
|
}
|
||
|
|
|
||
|
|
bool
|
||
|
29 years ago
|
complex_abs_eq(Complex * a, Complex * b)
|
||
|
30 years ago
|
{
|
||
|
29 years ago
|
double amag = Mag(a),
|
||
|
|
bmag = Mag(b);
|
||
|
29 years ago
|
|
||
|
|
return (amag == bmag);
|
||
|
30 years ago
|
}
|
||
|
|
|
||
|
|
bool
|
||
|
29 years ago
|
complex_abs_ge(Complex * a, Complex * b)
|
||
|
30 years ago
|
{
|
||
|
29 years ago
|
double amag = Mag(a),
|
||
|
|
bmag = Mag(b);
|
||
|
29 years ago
|
|
||
|
|
return (amag >= bmag);
|
||
|
30 years ago
|
}
|
||
|
|
|
||
|
|
bool
|
||
|
29 years ago
|
complex_abs_gt(Complex * a, Complex * b)
|
||
|
30 years ago
|
{
|
||
|
29 years ago
|
double amag = Mag(a),
|
||
|
|
bmag = Mag(b);
|
||
|
29 years ago
|
|
||
|
|
return (amag > bmag);
|
||
|
30 years ago
|
}
|
||
|
|
|
||
|
|
int4
|
||
|
29 years ago
|
complex_abs_cmp(Complex * a, Complex * b)
|
||
|
30 years ago
|
{
|
||
|
29 years ago
|
double amag = Mag(a),
|
||
|
|
bmag = Mag(b);
|
||
|
29 years ago
|
|
||
|
|
if (amag < bmag)
|
||
|
|
return -1;
|
||
|
|
else if (amag > bmag)
|
||
|
|
return 1;
|
||
|
|
else
|
||
|
|
return 0;
|
||
|
30 years ago
|
}
|
||
|
|
|
||
|
|
/*****************************************************************************
|
||
|
|
* test code
|
||
|
|
*****************************************************************************/
|
||
|
|
|
||
|
|
/*
|
||
|
|
* You should always test your code separately. Trust me, using POSTGRES to
|
||
|
|
* debug your C function will be very painful and unproductive. In case of
|
||
|
|
* POSTGRES crashing, it is impossible to tell whether the bug is in your
|
||
|
|
* code or POSTGRES's.
|
||
|
|
*/
|
||
|
29 years ago
|
void test_main(void);
|
||
|
30 years ago
|
void
|
||
|
|
test_main()
|
||
|
|
{
|
||
|
29 years ago
|
Complex *a;
|
||
|
|
Complex *b;
|
||
|
29 years ago
|
|
||
|
|
a = complex_in("(4.01, 3.77 )");
|
||
|
|
printf("a = %s\n", complex_out(a));
|
||
|
|
b = complex_in("(1.0,2.0)");
|
||
|
|
printf("b = %s\n", complex_out(b));
|
||
|
|
printf("a + b = %s\n", complex_out(complex_add(a, b)));
|
||
|
|
printf("a < b = %d\n", complex_abs_lt(a, b));
|
||
|
|
printf("a <= b = %d\n", complex_abs_le(a, b));
|
||
|
|
printf("a = b = %d\n", complex_abs_eq(a, b));
|
||
|
|
printf("a >= b = %d\n", complex_abs_ge(a, b));
|
||
|
|
printf("a > b = %d\n", complex_abs_gt(a, b));
|
||
|
30 years ago
|
}
|