Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "postgres.h"
00011
00012 #include "fmgr.h"
00013 #include "libpq/pqformat.h"
00014
00015
00016 PG_MODULE_MAGIC;
00017
00018 typedef struct Complex
00019 {
00020 double x;
00021 double y;
00022 } Complex;
00023
00024
00025
00026
00027
00028
00029 Datum complex_in(PG_FUNCTION_ARGS);
00030 Datum complex_out(PG_FUNCTION_ARGS);
00031 Datum complex_recv(PG_FUNCTION_ARGS);
00032 Datum complex_send(PG_FUNCTION_ARGS);
00033 Datum complex_add(PG_FUNCTION_ARGS);
00034 Datum complex_abs_lt(PG_FUNCTION_ARGS);
00035 Datum complex_abs_le(PG_FUNCTION_ARGS);
00036 Datum complex_abs_eq(PG_FUNCTION_ARGS);
00037 Datum complex_abs_ge(PG_FUNCTION_ARGS);
00038 Datum complex_abs_gt(PG_FUNCTION_ARGS);
00039 Datum complex_abs_cmp(PG_FUNCTION_ARGS);
00040
00041
00042
00043
00044
00045
00046 PG_FUNCTION_INFO_V1(complex_in);
00047
00048 Datum
00049 complex_in(PG_FUNCTION_ARGS)
00050 {
00051 char *str = PG_GETARG_CSTRING(0);
00052 double x,
00053 y;
00054 Complex *result;
00055
00056 if (sscanf(str, " ( %lf , %lf )", &x, &y) != 2)
00057 ereport(ERROR,
00058 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
00059 errmsg("invalid input syntax for complex: \"%s\"",
00060 str)));
00061
00062 result = (Complex *) palloc(sizeof(Complex));
00063 result->x = x;
00064 result->y = y;
00065 PG_RETURN_POINTER(result);
00066 }
00067
00068 PG_FUNCTION_INFO_V1(complex_out);
00069
00070 Datum
00071 complex_out(PG_FUNCTION_ARGS)
00072 {
00073 Complex *complex = (Complex *) PG_GETARG_POINTER(0);
00074 char *result;
00075
00076 result = (char *) palloc(100);
00077 snprintf(result, 100, "(%g,%g)", complex->x, complex->y);
00078 PG_RETURN_CSTRING(result);
00079 }
00080
00081
00082
00083
00084
00085
00086
00087 PG_FUNCTION_INFO_V1(complex_recv);
00088
00089 Datum
00090 complex_recv(PG_FUNCTION_ARGS)
00091 {
00092 StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
00093 Complex *result;
00094
00095 result = (Complex *) palloc(sizeof(Complex));
00096 result->x = pq_getmsgfloat8(buf);
00097 result->y = pq_getmsgfloat8(buf);
00098 PG_RETURN_POINTER(result);
00099 }
00100
00101 PG_FUNCTION_INFO_V1(complex_send);
00102
00103 Datum
00104 complex_send(PG_FUNCTION_ARGS)
00105 {
00106 Complex *complex = (Complex *) PG_GETARG_POINTER(0);
00107 StringInfoData buf;
00108
00109 pq_begintypsend(&buf);
00110 pq_sendfloat8(&buf, complex->x);
00111 pq_sendfloat8(&buf, complex->y);
00112 PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
00113 }
00114
00115
00116
00117
00118
00119
00120
00121 PG_FUNCTION_INFO_V1(complex_add);
00122
00123 Datum
00124 complex_add(PG_FUNCTION_ARGS)
00125 {
00126 Complex *a = (Complex *) PG_GETARG_POINTER(0);
00127 Complex *b = (Complex *) PG_GETARG_POINTER(1);
00128 Complex *result;
00129
00130 result = (Complex *) palloc(sizeof(Complex));
00131 result->x = a->x + b->x;
00132 result->y = a->y + b->y;
00133 PG_RETURN_POINTER(result);
00134 }
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148 #define Mag(c) ((c)->x*(c)->x + (c)->y*(c)->y)
00149
00150 static int
00151 complex_abs_cmp_internal(Complex * a, Complex * b)
00152 {
00153 double amag = Mag(a),
00154 bmag = Mag(b);
00155
00156 if (amag < bmag)
00157 return -1;
00158 if (amag > bmag)
00159 return 1;
00160 return 0;
00161 }
00162
00163
00164 PG_FUNCTION_INFO_V1(complex_abs_lt);
00165
00166 Datum
00167 complex_abs_lt(PG_FUNCTION_ARGS)
00168 {
00169 Complex *a = (Complex *) PG_GETARG_POINTER(0);
00170 Complex *b = (Complex *) PG_GETARG_POINTER(1);
00171
00172 PG_RETURN_BOOL(complex_abs_cmp_internal(a, b) < 0);
00173 }
00174
00175 PG_FUNCTION_INFO_V1(complex_abs_le);
00176
00177 Datum
00178 complex_abs_le(PG_FUNCTION_ARGS)
00179 {
00180 Complex *a = (Complex *) PG_GETARG_POINTER(0);
00181 Complex *b = (Complex *) PG_GETARG_POINTER(1);
00182
00183 PG_RETURN_BOOL(complex_abs_cmp_internal(a, b) <= 0);
00184 }
00185
00186 PG_FUNCTION_INFO_V1(complex_abs_eq);
00187
00188 Datum
00189 complex_abs_eq(PG_FUNCTION_ARGS)
00190 {
00191 Complex *a = (Complex *) PG_GETARG_POINTER(0);
00192 Complex *b = (Complex *) PG_GETARG_POINTER(1);
00193
00194 PG_RETURN_BOOL(complex_abs_cmp_internal(a, b) == 0);
00195 }
00196
00197 PG_FUNCTION_INFO_V1(complex_abs_ge);
00198
00199 Datum
00200 complex_abs_ge(PG_FUNCTION_ARGS)
00201 {
00202 Complex *a = (Complex *) PG_GETARG_POINTER(0);
00203 Complex *b = (Complex *) PG_GETARG_POINTER(1);
00204
00205 PG_RETURN_BOOL(complex_abs_cmp_internal(a, b) >= 0);
00206 }
00207
00208 PG_FUNCTION_INFO_V1(complex_abs_gt);
00209
00210 Datum
00211 complex_abs_gt(PG_FUNCTION_ARGS)
00212 {
00213 Complex *a = (Complex *) PG_GETARG_POINTER(0);
00214 Complex *b = (Complex *) PG_GETARG_POINTER(1);
00215
00216 PG_RETURN_BOOL(complex_abs_cmp_internal(a, b) > 0);
00217 }
00218
00219 PG_FUNCTION_INFO_V1(complex_abs_cmp);
00220
00221 Datum
00222 complex_abs_cmp(PG_FUNCTION_ARGS)
00223 {
00224 Complex *a = (Complex *) PG_GETARG_POINTER(0);
00225 Complex *b = (Complex *) PG_GETARG_POINTER(1);
00226
00227 PG_RETURN_INT32(complex_abs_cmp_internal(a, b));
00228 }