mirror of
https://github.com/zebrajr/postgres.git
synced 2025-12-07 00:20:24 +01:00
1. Make 'all' works without complaint. Don't have to add the .exp files to the files list. They are made automagically when making the respective shared lib file. Only port that actually uses EXPSUFF (from makefiles/Makefile.*) is Aix, so if this breaks anybody else, let me know, asap. 2. Make 'clean' actually cleans up correctly. Previously, it would leave the .o files in C-code directory. 3. Changed references to reflect new location of .c files. 4. Added DELETE statements to complex.source so that it tidies up when done. Previously, it would leave things in pg_amop, pg_amproc and pg_opclass. Only possible to do this with the new SUBSELECT code in 6.3. Nice work, fellas... Not deleting the index entries would cause a non-fatal error if complex.sql was run again on the same database. Much tidier now. 5. Corrected the README. obj directory hasn't existed since Bryan redid the make way back when. Also changed the snipet from psql to match the current version. POSTGRES95?!? I don't think so. :)
185 lines
4.4 KiB
C
185 lines
4.4 KiB
C
/******************************************************************************
|
|
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.
|
|
******************************************************************************/
|
|
|
|
#include <stdio.h>
|
|
/* do not include libpq-fe.h for backend-loaded functions*/
|
|
/* #include "libpq-fe.h" */
|
|
#include "postgres.h"
|
|
#include "utils/mcxt.h"
|
|
|
|
typedef struct Complex
|
|
{
|
|
double x;
|
|
double y;
|
|
} Complex;
|
|
|
|
/* These prototypes declare the requirements that Postgres places on these
|
|
user written functions.
|
|
*/
|
|
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);
|
|
|
|
|
|
/*****************************************************************************
|
|
* Input/Output functions
|
|
*****************************************************************************/
|
|
|
|
Complex *
|
|
complex_in(char *str)
|
|
{
|
|
double x,
|
|
y;
|
|
Complex *result;
|
|
|
|
if (sscanf(str, " ( %lf , %lf )", &x, &y) != 2)
|
|
{
|
|
elog(ERROR, "complex_in: error in parsing \"%s\"", str);
|
|
return NULL;
|
|
}
|
|
result = (Complex *) palloc(sizeof(Complex));
|
|
result->x = x;
|
|
result->y = y;
|
|
return (result);
|
|
}
|
|
|
|
/*
|
|
* You might have noticed a slight inconsistency between the following
|
|
* declaration and the SQL definition:
|
|
* CREATE FUNCTION complex_out(opaque) RETURNS opaque ...
|
|
* The reason is that the argument pass into complex_out is really just a
|
|
* pointer. POSTGRES thinks all output functions are:
|
|
* char *out_func(char *);
|
|
*/
|
|
char *
|
|
complex_out(Complex * complex)
|
|
{
|
|
char *result;
|
|
|
|
if (complex == NULL)
|
|
return (NULL);
|
|
|
|
result = (char *) palloc(60);
|
|
sprintf(result, "(%g,%g)", complex->x, complex->y);
|
|
return (result);
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* New Operators
|
|
*****************************************************************************/
|
|
|
|
Complex *
|
|
complex_add(Complex * a, Complex * b)
|
|
{
|
|
Complex *result;
|
|
|
|
result = (Complex *) palloc(sizeof(Complex));
|
|
result->x = a->x + b->x;
|
|
result->y = a->y + b->y;
|
|
return (result);
|
|
}
|
|
|
|
|
|
/*****************************************************************************
|
|
* Operator class for defining B-tree index
|
|
*****************************************************************************/
|
|
|
|
#define Mag(c) ((c)->x*(c)->x + (c)->y*(c)->y)
|
|
|
|
bool
|
|
complex_abs_lt(Complex * a, Complex * b)
|
|
{
|
|
double amag = Mag(a),
|
|
bmag = Mag(b);
|
|
|
|
return (amag < bmag);
|
|
}
|
|
|
|
bool
|
|
complex_abs_le(Complex * a, Complex * b)
|
|
{
|
|
double amag = Mag(a),
|
|
bmag = Mag(b);
|
|
|
|
return (amag <= bmag);
|
|
}
|
|
|
|
bool
|
|
complex_abs_eq(Complex * a, Complex * b)
|
|
{
|
|
double amag = Mag(a),
|
|
bmag = Mag(b);
|
|
|
|
return (amag == bmag);
|
|
}
|
|
|
|
bool
|
|
complex_abs_ge(Complex * a, Complex * b)
|
|
{
|
|
double amag = Mag(a),
|
|
bmag = Mag(b);
|
|
|
|
return (amag >= bmag);
|
|
}
|
|
|
|
bool
|
|
complex_abs_gt(Complex * a, Complex * b)
|
|
{
|
|
double amag = Mag(a),
|
|
bmag = Mag(b);
|
|
|
|
return (amag > bmag);
|
|
}
|
|
|
|
int4
|
|
complex_abs_cmp(Complex * a, Complex * b)
|
|
{
|
|
double amag = Mag(a),
|
|
bmag = Mag(b);
|
|
|
|
if (amag < bmag)
|
|
return -1;
|
|
else if (amag > bmag)
|
|
return 1;
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* 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.
|
|
*/
|
|
void test_main(void);
|
|
void
|
|
test_main()
|
|
{
|
|
Complex *a;
|
|
Complex *b;
|
|
|
|
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));
|
|
}
|