/*
* src / tutorial / complex . 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 "postgres.h"
#include "fmgr.h"
#include "libpq/pqformat.h" /* needed for send/recv functions */
PG_MODULE_MAGIC;
typedef struct Complex
{
double x;
double y;
} Complex;
/*****************************************************************************
* Input / Output functions
*****************************************************************************/
PG_FUNCTION_INFO_V1(complex_in);
Datum
complex_in(PG_FUNCTION_ARGS)
{
char *str = PG_GETARG_CSTRING(0 );
double x,
y;
Complex *result;
if (sscanf(str, " ( %lf , %lf )" , &x, &y) != 2 )
ereport(ERROR,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
errmsg("invalid input syntax for type %s: \" %s\"" ,
"complex" , str)));
result = (Complex *) palloc(sizeof (Complex));
result->x = x;
result->y = y;
PG_RETURN_POINTER(result);
}
PG_FUNCTION_INFO_V1(complex_out);
Datum
complex_out(PG_FUNCTION_ARGS)
{
Complex *complex = (Complex *) PG_GETARG_POINTER(0 );
char *result;
result = psprintf("(%g,%g)" , complex->x, complex->y);
PG_RETURN_CSTRING(result);
}
/*****************************************************************************
* Binary Input / Output functions
*
* These are optional .
*****************************************************************************/
PG_FUNCTION_INFO_V1(complex_recv);
Datum
complex_recv(PG_FUNCTION_ARGS)
{
StringInfo buf = (StringInfo) PG_GETARG_POINTER(0 );
Complex *result;
result = (Complex *) palloc(sizeof (Complex));
result->x = pq_getmsgfloat8(buf);
result->y = pq_getmsgfloat8(buf);
PG_RETURN_POINTER(result);
}
PG_FUNCTION_INFO_V1(complex_send);
Datum
complex_send(PG_FUNCTION_ARGS)
{
Complex *complex = (Complex *) PG_GETARG_POINTER(0 );
StringInfoData buf;
pq_begintypsend(&buf);
pq_sendfloat8(&buf, complex->x);
pq_sendfloat8(&buf, complex->y);
PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
}
/*****************************************************************************
* New Operators
*
* A practical Complex datatype would provide much more than this , of course .
*****************************************************************************/
PG_FUNCTION_INFO_V1(complex_add);
Datum
complex_add(PG_FUNCTION_ARGS)
{
Complex *a = (Complex *) PG_GETARG_POINTER(0 );
Complex *b = (Complex *) PG_GETARG_POINTER(1 );
Complex *result;
result = (Complex *) palloc(sizeof (Complex));
result->x = a->x + b->x;
result->y = a->y + b->y;
PG_RETURN_POINTER(result);
}
/*****************************************************************************
* Operator class for defining B - tree index
*
* It ' s essential that the comparison operators and support function for a
* B - tree index opclass always agree on the relative ordering of any two
* data values . Experience has shown that it ' s depressingly easy to write
* unintentionally inconsistent functions . One way to reduce the odds of
* making a mistake is to make all the functions simple wrappers around
* an internal three - way - comparison function , as we do here .
*****************************************************************************/
#define Mag(c) ((c)->x*(c)->x + (c)->y*(c)->y)
static int
complex_abs_cmp_internal(Complex * a, Complex * b)
{
double amag = Mag(a),
bmag = Mag(b);
if (amag < bmag)
return -1 ;
if (amag > bmag)
return 1 ;
return 0 ;
}
PG_FUNCTION_INFO_V1(complex_abs_lt);
Datum
complex_abs_lt(PG_FUNCTION_ARGS)
{
Complex *a = (Complex *) PG_GETARG_POINTER(0 );
Complex *b = (Complex *) PG_GETARG_POINTER(1 );
PG_RETURN_BOOL(complex_abs_cmp_internal(a, b) < 0 );
}
PG_FUNCTION_INFO_V1(complex_abs_le);
Datum
complex_abs_le(PG_FUNCTION_ARGS)
{
Complex *a = (Complex *) PG_GETARG_POINTER(0 );
Complex *b = (Complex *) PG_GETARG_POINTER(1 );
PG_RETURN_BOOL(complex_abs_cmp_internal(a, b) <= 0 );
}
PG_FUNCTION_INFO_V1(complex_abs_eq);
Datum
complex_abs_eq(PG_FUNCTION_ARGS)
{
Complex *a = (Complex *) PG_GETARG_POINTER(0 );
Complex *b = (Complex *) PG_GETARG_POINTER(1 );
PG_RETURN_BOOL(complex_abs_cmp_internal(a, b) == 0 );
}
PG_FUNCTION_INFO_V1(complex_abs_ge);
Datum
complex_abs_ge(PG_FUNCTION_ARGS)
{
Complex *a = (Complex *) PG_GETARG_POINTER(0 );
Complex *b = (Complex *) PG_GETARG_POINTER(1 );
PG_RETURN_BOOL(complex_abs_cmp_internal(a, b) >= 0 );
}
PG_FUNCTION_INFO_V1(complex_abs_gt);
Datum
complex_abs_gt(PG_FUNCTION_ARGS)
{
Complex *a = (Complex *) PG_GETARG_POINTER(0 );
Complex *b = (Complex *) PG_GETARG_POINTER(1 );
PG_RETURN_BOOL(complex_abs_cmp_internal(a, b) > 0 );
}
PG_FUNCTION_INFO_V1(complex_abs_cmp);
Datum
complex_abs_cmp(PG_FUNCTION_ARGS)
{
Complex *a = (Complex *) PG_GETARG_POINTER(0 );
Complex *b = (Complex *) PG_GETARG_POINTER(1 );
PG_RETURN_INT32(complex_abs_cmp_internal(a, b));
}
Messung V0.5 in Prozent C=98 H=100 G=98
¤ Dauer der Verarbeitung: 0.14 Sekunden
(vorverarbeitet am 2026-08-04)
¤
*© Formatika GbR, Deutschland