~vcs-imports/mammoth-replicator/trunk

« back to all changes in this revision

Viewing changes to src/tutorial/complex.c

  • Committer: alvherre
  • Date: 2005-12-16 21:24:52 UTC
  • Revision ID: svn-v4:db760fc0-0f08-0410-9d63-cc6633f64896:trunk:1
Initial import of the REL8_0_3 sources from the Pgsql CVS repository.

Show diffs side-by-side

added added

removed removed

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