PostgreSQL Source Code git master
complex.c
Go to the documentation of this file.
1/*
2 * src/tutorial/complex.c
3 *
4 ******************************************************************************
5 This file contains routines that can be bound to a Postgres backend and
6 called by the backend in the process of processing queries. The calling
7 format for these routines is dictated by Postgres architecture.
8******************************************************************************/
9
10#include "postgres.h"
11
12#include "fmgr.h"
13#include "libpq/pqformat.h" /* needed for send/recv functions */
14
16
17typedef struct Complex
18{
19 double x;
20 double y;
22
23
24/*****************************************************************************
25 * Input/Output functions
26 *****************************************************************************/
27
29
32{
33 char *str = PG_GETARG_CSTRING(0);
34 double x,
35 y;
36 Complex *result;
37
38 if (sscanf(str, " ( %lf , %lf )", &x, &y) != 2)
40 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
41 errmsg("invalid input syntax for type %s: \"%s\"",
42 "complex", str)));
43
44 result = (Complex *) palloc(sizeof(Complex));
45 result->x = x;
46 result->y = y;
47 PG_RETURN_POINTER(result);
48}
49
51
54{
55 Complex *complex = (Complex *) PG_GETARG_POINTER(0);
56 char *result;
57
58 result = psprintf("(%g,%g)", complex->x, complex->y);
59 PG_RETURN_CSTRING(result);
60}
61
62/*****************************************************************************
63 * Binary Input/Output functions
64 *
65 * These are optional.
66 *****************************************************************************/
67
69
72{
74 Complex *result;
75
76 result = (Complex *) palloc(sizeof(Complex));
77 result->x = pq_getmsgfloat8(buf);
78 result->y = pq_getmsgfloat8(buf);
79 PG_RETURN_POINTER(result);
80}
81
83
86{
87 Complex *complex = (Complex *) PG_GETARG_POINTER(0);
89
91 pq_sendfloat8(&buf, complex->x);
92 pq_sendfloat8(&buf, complex->y);
94}
95
96/*****************************************************************************
97 * New Operators
98 *
99 * A practical Complex datatype would provide much more than this, of course.
100 *****************************************************************************/
101
103
104Datum
106{
109 Complex *result;
110
111 result = (Complex *) palloc(sizeof(Complex));
112 result->x = a->x + b->x;
113 result->y = a->y + b->y;
114 PG_RETURN_POINTER(result);
115}
116
117
118/*****************************************************************************
119 * Operator class for defining B-tree index
120 *
121 * It's essential that the comparison operators and support function for a
122 * B-tree index opclass always agree on the relative ordering of any two
123 * data values. Experience has shown that it's depressingly easy to write
124 * unintentionally inconsistent functions. One way to reduce the odds of
125 * making a mistake is to make all the functions simple wrappers around
126 * an internal three-way-comparison function, as we do here.
127 *****************************************************************************/
128
129#define Mag(c) ((c)->x*(c)->x + (c)->y*(c)->y)
130
131static int
133{
134 double amag = Mag(a),
135 bmag = Mag(b);
136
137 if (amag < bmag)
138 return -1;
139 if (amag > bmag)
140 return 1;
141 return 0;
142}
143
144
146
147Datum
149{
152
154}
155
157
158Datum
160{
163
165}
166
168
169Datum
171{
174
176}
177
179
180Datum
182{
185
187}
188
190
191Datum
193{
196
198}
199
201
202Datum
204{
207
209}
Datum complex_in(PG_FUNCTION_ARGS)
Definition: complex.c:31
Datum complex_abs_cmp(PG_FUNCTION_ARGS)
Definition: complex.c:203
static int complex_abs_cmp_internal(Complex *a, Complex *b)
Definition: complex.c:132
Datum complex_add(PG_FUNCTION_ARGS)
Definition: complex.c:105
struct Complex Complex
Datum complex_send(PG_FUNCTION_ARGS)
Definition: complex.c:85
PG_MODULE_MAGIC
Definition: complex.c:15
Datum complex_recv(PG_FUNCTION_ARGS)
Definition: complex.c:71
#define Mag(c)
Definition: complex.c:129
PG_FUNCTION_INFO_V1(complex_in)
Datum complex_abs_ge(PG_FUNCTION_ARGS)
Definition: complex.c:181
Datum complex_abs_gt(PG_FUNCTION_ARGS)
Definition: complex.c:192
Datum complex_abs_lt(PG_FUNCTION_ARGS)
Definition: complex.c:148
Datum complex_abs_le(PG_FUNCTION_ARGS)
Definition: complex.c:159
Datum complex_abs_eq(PG_FUNCTION_ARGS)
Definition: complex.c:170
Datum complex_out(PG_FUNCTION_ARGS)
Definition: complex.c:53
int errcode(int sqlerrcode)
Definition: elog.c:853
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:371
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:276
#define PG_RETURN_CSTRING(x)
Definition: fmgr.h:362
#define PG_GETARG_CSTRING(n)
Definition: fmgr.h:277
#define PG_RETURN_INT32(x)
Definition: fmgr.h:354
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:361
#define PG_FUNCTION_ARGS
Definition: fmgr.h:193
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
const char * str
int y
Definition: isn.c:71
int b
Definition: isn.c:69
int x
Definition: isn.c:70
int a
Definition: isn.c:68
void * palloc(Size size)
Definition: mcxt.c:1317
static char * buf
Definition: pg_test_fsync.c:72
uintptr_t Datum
Definition: postgres.h:69
float8 pq_getmsgfloat8(StringInfo msg)
Definition: pqformat.c:488
void pq_begintypsend(StringInfo buf)
Definition: pqformat.c:326
bytea * pq_endtypsend(StringInfo buf)
Definition: pqformat.c:346
void pq_sendfloat8(StringInfo buf, float8 f)
Definition: pqformat.c:276
char * psprintf(const char *fmt,...)
Definition: psprintf.c:43
StringInfoData * StringInfo
Definition: stringinfo.h:54
double y
Definition: complex.c:20
double x
Definition: complex.c:19