Consistently use "superuser" instead of "super user"
[pgsql.git] / src / tutorial / complex.c
blob6798a9e6ba6c086afc37ebd09b9a6ddf377f5b68
1 /*
2 * src/tutorial/complex.c
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 ******************************************************************************/
10 #include "postgres.h"
12 #include "fmgr.h"
13 #include "libpq/pqformat.h" /* needed for send/recv functions */
15 PG_MODULE_MAGIC;
17 typedef struct Complex
19 double x;
20 double y;
21 } Complex;
24 /*****************************************************************************
25 * Input/Output functions
26 *****************************************************************************/
28 PG_FUNCTION_INFO_V1(complex_in);
30 Datum
31 complex_in(PG_FUNCTION_ARGS)
33 char *str = PG_GETARG_CSTRING(0);
34 double x,
36 Complex *result;
38 if (sscanf(str, " ( %lf , %lf )", &x, &y) != 2)
39 ereport(ERROR,
40 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
41 errmsg("invalid input syntax for type %s: \"%s\"",
42 "complex", str)));
44 result = (Complex *) palloc(sizeof(Complex));
45 result->x = x;
46 result->y = y;
47 PG_RETURN_POINTER(result);
50 PG_FUNCTION_INFO_V1(complex_out);
52 Datum
53 complex_out(PG_FUNCTION_ARGS)
55 Complex *complex = (Complex *) PG_GETARG_POINTER(0);
56 char *result;
58 result = psprintf("(%g,%g)", complex->x, complex->y);
59 PG_RETURN_CSTRING(result);
62 /*****************************************************************************
63 * Binary Input/Output functions
65 * These are optional.
66 *****************************************************************************/
68 PG_FUNCTION_INFO_V1(complex_recv);
70 Datum
71 complex_recv(PG_FUNCTION_ARGS)
73 StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
74 Complex *result;
76 result = (Complex *) palloc(sizeof(Complex));
77 result->x = pq_getmsgfloat8(buf);
78 result->y = pq_getmsgfloat8(buf);
79 PG_RETURN_POINTER(result);
82 PG_FUNCTION_INFO_V1(complex_send);
84 Datum
85 complex_send(PG_FUNCTION_ARGS)
87 Complex *complex = (Complex *) PG_GETARG_POINTER(0);
88 StringInfoData buf;
90 pq_begintypsend(&buf);
91 pq_sendfloat8(&buf, complex->x);
92 pq_sendfloat8(&buf, complex->y);
93 PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
96 /*****************************************************************************
97 * New Operators
99 * A practical Complex datatype would provide much more than this, of course.
100 *****************************************************************************/
102 PG_FUNCTION_INFO_V1(complex_add);
104 Datum
105 complex_add(PG_FUNCTION_ARGS)
107 Complex *a = (Complex *) PG_GETARG_POINTER(0);
108 Complex *b = (Complex *) PG_GETARG_POINTER(1);
109 Complex *result;
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);
118 /*****************************************************************************
119 * Operator class for defining B-tree index
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 *****************************************************************************/
129 #define Mag(c) ((c)->x*(c)->x + (c)->y*(c)->y)
131 static int
132 complex_abs_cmp_internal(Complex * a, Complex * b)
134 double amag = Mag(a),
135 bmag = Mag(b);
137 if (amag < bmag)
138 return -1;
139 if (amag > bmag)
140 return 1;
141 return 0;
145 PG_FUNCTION_INFO_V1(complex_abs_lt);
147 Datum
148 complex_abs_lt(PG_FUNCTION_ARGS)
150 Complex *a = (Complex *) PG_GETARG_POINTER(0);
151 Complex *b = (Complex *) PG_GETARG_POINTER(1);
153 PG_RETURN_BOOL(complex_abs_cmp_internal(a, b) < 0);
156 PG_FUNCTION_INFO_V1(complex_abs_le);
158 Datum
159 complex_abs_le(PG_FUNCTION_ARGS)
161 Complex *a = (Complex *) PG_GETARG_POINTER(0);
162 Complex *b = (Complex *) PG_GETARG_POINTER(1);
164 PG_RETURN_BOOL(complex_abs_cmp_internal(a, b) <= 0);
167 PG_FUNCTION_INFO_V1(complex_abs_eq);
169 Datum
170 complex_abs_eq(PG_FUNCTION_ARGS)
172 Complex *a = (Complex *) PG_GETARG_POINTER(0);
173 Complex *b = (Complex *) PG_GETARG_POINTER(1);
175 PG_RETURN_BOOL(complex_abs_cmp_internal(a, b) == 0);
178 PG_FUNCTION_INFO_V1(complex_abs_ge);
180 Datum
181 complex_abs_ge(PG_FUNCTION_ARGS)
183 Complex *a = (Complex *) PG_GETARG_POINTER(0);
184 Complex *b = (Complex *) PG_GETARG_POINTER(1);
186 PG_RETURN_BOOL(complex_abs_cmp_internal(a, b) >= 0);
189 PG_FUNCTION_INFO_V1(complex_abs_gt);
191 Datum
192 complex_abs_gt(PG_FUNCTION_ARGS)
194 Complex *a = (Complex *) PG_GETARG_POINTER(0);
195 Complex *b = (Complex *) PG_GETARG_POINTER(1);
197 PG_RETURN_BOOL(complex_abs_cmp_internal(a, b) > 0);
200 PG_FUNCTION_INFO_V1(complex_abs_cmp);
202 Datum
203 complex_abs_cmp(PG_FUNCTION_ARGS)
205 Complex *a = (Complex *) PG_GETARG_POINTER(0);
206 Complex *b = (Complex *) PG_GETARG_POINTER(1);
208 PG_RETURN_INT32(complex_abs_cmp_internal(a, b));