OSDN Git Service

Avoid creating init fork for unlogged indexes when it already exists.
[pg-rex/syncrep.git] / src / tutorial / complex.c
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
15
16 PG_MODULE_MAGIC;
17
18 typedef struct Complex
19 {
20         double          x;
21         double          y;
22 }       Complex;
23
24 /*
25  * Since we use V1 function calling convention, all these functions have
26  * the same signature as far as C is concerned.  We provide these prototypes
27  * just to forestall warnings when compiled with gcc -Wmissing-prototypes.
28  */
29 Datum           complex_in(PG_FUNCTION_ARGS);
30 Datum           complex_out(PG_FUNCTION_ARGS);
31 Datum           complex_recv(PG_FUNCTION_ARGS);
32 Datum           complex_send(PG_FUNCTION_ARGS);
33 Datum           complex_add(PG_FUNCTION_ARGS);
34 Datum           complex_abs_lt(PG_FUNCTION_ARGS);
35 Datum           complex_abs_le(PG_FUNCTION_ARGS);
36 Datum           complex_abs_eq(PG_FUNCTION_ARGS);
37 Datum           complex_abs_ge(PG_FUNCTION_ARGS);
38 Datum           complex_abs_gt(PG_FUNCTION_ARGS);
39 Datum           complex_abs_cmp(PG_FUNCTION_ARGS);
40
41
42 /*****************************************************************************
43  * Input/Output functions
44  *****************************************************************************/
45
46 PG_FUNCTION_INFO_V1(complex_in);
47
48 Datum
49 complex_in(PG_FUNCTION_ARGS)
50 {
51         char       *str = PG_GETARG_CSTRING(0);
52         double          x,
53                                 y;
54         Complex    *result;
55
56         if (sscanf(str, " ( %lf , %lf )", &x, &y) != 2)
57                 ereport(ERROR,
58                                 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
59                                  errmsg("invalid input syntax for complex: \"%s\"",
60                                                 str)));
61
62         result = (Complex *) palloc(sizeof(Complex));
63         result->x = x;
64         result->y = y;
65         PG_RETURN_POINTER(result);
66 }
67
68 PG_FUNCTION_INFO_V1(complex_out);
69
70 Datum
71 complex_out(PG_FUNCTION_ARGS)
72 {
73         Complex    *complex = (Complex *) PG_GETARG_POINTER(0);
74         char       *result;
75
76         result = (char *) palloc(100);
77         snprintf(result, 100, "(%g,%g)", complex->x, complex->y);
78         PG_RETURN_CSTRING(result);
79 }
80
81 /*****************************************************************************
82  * Binary Input/Output functions
83  *
84  * These are optional.
85  *****************************************************************************/
86
87 PG_FUNCTION_INFO_V1(complex_recv);
88
89 Datum
90 complex_recv(PG_FUNCTION_ARGS)
91 {
92         StringInfo      buf = (StringInfo) PG_GETARG_POINTER(0);
93         Complex    *result;
94
95         result = (Complex *) palloc(sizeof(Complex));
96         result->x = pq_getmsgfloat8(buf);
97         result->y = pq_getmsgfloat8(buf);
98         PG_RETURN_POINTER(result);
99 }
100
101 PG_FUNCTION_INFO_V1(complex_send);
102
103 Datum
104 complex_send(PG_FUNCTION_ARGS)
105 {
106         Complex    *complex = (Complex *) PG_GETARG_POINTER(0);
107         StringInfoData buf;
108
109         pq_begintypsend(&buf);
110         pq_sendfloat8(&buf, complex->x);
111         pq_sendfloat8(&buf, complex->y);
112         PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
113 }
114
115 /*****************************************************************************
116  * New Operators
117  *
118  * A practical Complex datatype would provide much more than this, of course.
119  *****************************************************************************/
120
121 PG_FUNCTION_INFO_V1(complex_add);
122
123 Datum
124 complex_add(PG_FUNCTION_ARGS)
125 {
126         Complex    *a = (Complex *) PG_GETARG_POINTER(0);
127         Complex    *b = (Complex *) PG_GETARG_POINTER(1);
128         Complex    *result;
129
130         result = (Complex *) palloc(sizeof(Complex));
131         result->x = a->x + b->x;
132         result->y = a->y + b->y;
133         PG_RETURN_POINTER(result);
134 }
135
136
137 /*****************************************************************************
138  * Operator class for defining B-tree index
139  *
140  * It's essential that the comparison operators and support function for a
141  * B-tree index opclass always agree on the relative ordering of any two
142  * data values.  Experience has shown that it's depressingly easy to write
143  * unintentionally inconsistent functions.      One way to reduce the odds of
144  * making a mistake is to make all the functions simple wrappers around
145  * an internal three-way-comparison function, as we do here.
146  *****************************************************************************/
147
148 #define Mag(c)  ((c)->x*(c)->x + (c)->y*(c)->y)
149
150 static int
151 complex_abs_cmp_internal(Complex * a, Complex * b)
152 {
153         double          amag = Mag(a),
154                                 bmag = Mag(b);
155
156         if (amag < bmag)
157                 return -1;
158         if (amag > bmag)
159                 return 1;
160         return 0;
161 }
162
163
164 PG_FUNCTION_INFO_V1(complex_abs_lt);
165
166 Datum
167 complex_abs_lt(PG_FUNCTION_ARGS)
168 {
169         Complex    *a = (Complex *) PG_GETARG_POINTER(0);
170         Complex    *b = (Complex *) PG_GETARG_POINTER(1);
171
172         PG_RETURN_BOOL(complex_abs_cmp_internal(a, b) < 0);
173 }
174
175 PG_FUNCTION_INFO_V1(complex_abs_le);
176
177 Datum
178 complex_abs_le(PG_FUNCTION_ARGS)
179 {
180         Complex    *a = (Complex *) PG_GETARG_POINTER(0);
181         Complex    *b = (Complex *) PG_GETARG_POINTER(1);
182
183         PG_RETURN_BOOL(complex_abs_cmp_internal(a, b) <= 0);
184 }
185
186 PG_FUNCTION_INFO_V1(complex_abs_eq);
187
188 Datum
189 complex_abs_eq(PG_FUNCTION_ARGS)
190 {
191         Complex    *a = (Complex *) PG_GETARG_POINTER(0);
192         Complex    *b = (Complex *) PG_GETARG_POINTER(1);
193
194         PG_RETURN_BOOL(complex_abs_cmp_internal(a, b) == 0);
195 }
196
197 PG_FUNCTION_INFO_V1(complex_abs_ge);
198
199 Datum
200 complex_abs_ge(PG_FUNCTION_ARGS)
201 {
202         Complex    *a = (Complex *) PG_GETARG_POINTER(0);
203         Complex    *b = (Complex *) PG_GETARG_POINTER(1);
204
205         PG_RETURN_BOOL(complex_abs_cmp_internal(a, b) >= 0);
206 }
207
208 PG_FUNCTION_INFO_V1(complex_abs_gt);
209
210 Datum
211 complex_abs_gt(PG_FUNCTION_ARGS)
212 {
213         Complex    *a = (Complex *) PG_GETARG_POINTER(0);
214         Complex    *b = (Complex *) PG_GETARG_POINTER(1);
215
216         PG_RETURN_BOOL(complex_abs_cmp_internal(a, b) > 0);
217 }
218
219 PG_FUNCTION_INFO_V1(complex_abs_cmp);
220
221 Datum
222 complex_abs_cmp(PG_FUNCTION_ARGS)
223 {
224         Complex    *a = (Complex *) PG_GETARG_POINTER(0);
225         Complex    *b = (Complex *) PG_GETARG_POINTER(1);
226
227         PG_RETURN_INT32(complex_abs_cmp_internal(a, b));
228 }