PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
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 
17 typedef struct Complex
18 {
19  double x;
20  double y;
21 } Complex;
22 
23 
24 /*****************************************************************************
25  * Input/Output functions
26  *****************************************************************************/
27 
29 
30 Datum
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)
39  ereport(ERROR,
40  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
41  errmsg("invalid input syntax for complex: \"%s\"",
42  str)));
43 
44  result = (Complex *) palloc(sizeof(Complex));
45  result->x = x;
46  result->y = y;
47  PG_RETURN_POINTER(result);
48 }
49 
51 
52 Datum
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 
70 Datum
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 
84 Datum
86 {
87  Complex *complex = (Complex *) PG_GETARG_POINTER(0);
89 
90  pq_begintypsend(&buf);
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 
104 Datum
106 {
107  Complex *a = (Complex *) PG_GETARG_POINTER(0);
108  Complex *b = (Complex *) PG_GETARG_POINTER(1);
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 
131 static 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 
147 Datum
149 {
150  Complex *a = (Complex *) PG_GETARG_POINTER(0);
151  Complex *b = (Complex *) PG_GETARG_POINTER(1);
152 
154 }
155 
157 
158 Datum
160 {
161  Complex *a = (Complex *) PG_GETARG_POINTER(0);
162  Complex *b = (Complex *) PG_GETARG_POINTER(1);
163 
165 }
166 
168 
169 Datum
171 {
172  Complex *a = (Complex *) PG_GETARG_POINTER(0);
173  Complex *b = (Complex *) PG_GETARG_POINTER(1);
174 
176 }
177 
179 
180 Datum
182 {
183  Complex *a = (Complex *) PG_GETARG_POINTER(0);
184  Complex *b = (Complex *) PG_GETARG_POINTER(1);
185 
187 }
188 
190 
191 Datum
193 {
194  Complex *a = (Complex *) PG_GETARG_POINTER(0);
195  Complex *b = (Complex *) PG_GETARG_POINTER(1);
196 
198 }
199 
201 
202 Datum
204 {
205  Complex *a = (Complex *) PG_GETARG_POINTER(0);
206  Complex *b = (Complex *) PG_GETARG_POINTER(1);
207 
209 }
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:321
PG_MODULE_MAGIC
Definition: complex.c:15
void pq_begintypsend(StringInfo buf)
Definition: pqformat.c:359
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46
void pq_sendfloat8(StringInfo buf, float8 f)
Definition: pqformat.c:324
StringInfoData * StringInfo
Definition: stringinfo.h:43
#define PG_RETURN_INT32(x)
Definition: fmgr.h:314
int errcode(int sqlerrcode)
Definition: elog.c:575
Datum complex_abs_ge(PG_FUNCTION_ARGS)
Definition: complex.c:181
return result
Definition: formatting.c:1633
Datum complex_send(PG_FUNCTION_ARGS)
Definition: complex.c:85
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:241
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:330
struct Complex Complex
bytea * pq_endtypsend(StringInfo buf)
Definition: pqformat.c:379
Datum complex_recv(PG_FUNCTION_ARGS)
Definition: complex.c:71
#define ERROR
Definition: elog.h:43
PG_FUNCTION_INFO_V1(complex_in)
static char * buf
Definition: pg_test_fsync.c:67
#define ereport(elevel, rest)
Definition: elog.h:122
Datum complex_abs_eq(PG_FUNCTION_ARGS)
Definition: complex.c:170
Datum complex_abs_cmp(PG_FUNCTION_ARGS)
Definition: complex.c:203
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:319
uintptr_t Datum
Definition: postgres.h:372
Datum complex_abs_gt(PG_FUNCTION_ARGS)
Definition: complex.c:192
static int complex_abs_cmp_internal(Complex *a, Complex *b)
Definition: complex.c:132
#define Mag(c)
Definition: complex.c:129
Datum complex_in(PG_FUNCTION_ARGS)
Definition: complex.c:31
double y
Definition: complex.c:20
float8 pq_getmsgfloat8(StringInfo msg)
Definition: pqformat.c:530
Datum complex_add(PG_FUNCTION_ARGS)
Definition: complex.c:105
#define PG_RETURN_CSTRING(x)
Definition: fmgr.h:322
void * palloc(Size size)
Definition: mcxt.c:848
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define PG_GETARG_CSTRING(n)
Definition: fmgr.h:242
#define PG_FUNCTION_ARGS
Definition: fmgr.h:158
double x
Definition: complex.c:19
Datum complex_abs_lt(PG_FUNCTION_ARGS)
Definition: complex.c:148
Datum complex_abs_le(PG_FUNCTION_ARGS)
Definition: complex.c:159
Datum complex_out(PG_FUNCTION_ARGS)
Definition: complex.c:53