3 /******************************************************************************
4 These are user-defined functions that can be bound to a Postgres backend
5 and called by Postgres to execute SQL functions of the same name.
7 The calling format for these functions is defined by the CREATE FUNCTION
8 SQL statement that binds them to the backend.
10 NOTE: this file shows examples of "new style" function call conventions.
11 See funcs.c for examples of "old style".
12 *****************************************************************************/
14 #include "postgres.h" /* general Postgres declarations */
16 #include "executor/executor.h" /* for GetAttributeByName() */
17 #include "utils/geo_decls.h" /* for point type */
22 /* These prototypes just prevent possible warnings from gcc. */
24 Datum
add_one(PG_FUNCTION_ARGS
);
25 Datum
add_one_float8(PG_FUNCTION_ARGS
);
26 Datum
makepoint(PG_FUNCTION_ARGS
);
27 Datum
copytext(PG_FUNCTION_ARGS
);
28 Datum
concat_text(PG_FUNCTION_ARGS
);
29 Datum
c_overpaid(PG_FUNCTION_ARGS
);
34 PG_FUNCTION_INFO_V1(add_one
);
37 add_one(PG_FUNCTION_ARGS
)
39 int32 arg
= PG_GETARG_INT32(0);
41 PG_RETURN_INT32(arg
+ 1);
44 /* By Reference, Fixed Length */
46 PG_FUNCTION_INFO_V1(add_one_float8
);
49 add_one_float8(PG_FUNCTION_ARGS
)
51 /* The macros for FLOAT8 hide its pass-by-reference nature */
52 float8 arg
= PG_GETARG_FLOAT8(0);
54 PG_RETURN_FLOAT8(arg
+ 1.0);
57 PG_FUNCTION_INFO_V1(makepoint
);
60 makepoint(PG_FUNCTION_ARGS
)
62 Point
*pointx
= PG_GETARG_POINT_P(0);
63 Point
*pointy
= PG_GETARG_POINT_P(1);
64 Point
*new_point
= (Point
*) palloc(sizeof(Point
));
66 new_point
->x
= pointx
->x
;
67 new_point
->y
= pointy
->y
;
69 PG_RETURN_POINT_P(new_point
);
72 /* By Reference, Variable Length */
74 PG_FUNCTION_INFO_V1(copytext
);
77 copytext(PG_FUNCTION_ARGS
)
79 text
*t
= PG_GETARG_TEXT_P(0);
82 * VARSIZE is the total size of the struct in bytes.
84 text
*new_t
= (text
*) palloc(VARSIZE(t
));
86 SET_VARSIZE(new_t
, VARSIZE(t
));
89 * VARDATA is a pointer to the data region of the struct.
91 memcpy((void *) VARDATA(new_t
), /* destination */
92 (void *) VARDATA(t
), /* source */
93 VARSIZE(t
) - VARHDRSZ
); /* how many bytes */
94 PG_RETURN_TEXT_P(new_t
);
97 PG_FUNCTION_INFO_V1(concat_text
);
100 concat_text(PG_FUNCTION_ARGS
)
102 text
*arg1
= PG_GETARG_TEXT_P(0);
103 text
*arg2
= PG_GETARG_TEXT_P(1);
104 int32 arg1_size
= VARSIZE(arg1
) - VARHDRSZ
;
105 int32 arg2_size
= VARSIZE(arg2
) - VARHDRSZ
;
106 int32 new_text_size
= arg1_size
+ arg2_size
+ VARHDRSZ
;
107 text
*new_text
= (text
*) palloc(new_text_size
);
109 SET_VARSIZE(new_text
, new_text_size
);
110 memcpy(VARDATA(new_text
), VARDATA(arg1
), arg1_size
);
111 memcpy(VARDATA(new_text
) + arg1_size
, VARDATA(arg2
), arg2_size
);
112 PG_RETURN_TEXT_P(new_text
);
115 /* Composite types */
117 PG_FUNCTION_INFO_V1(c_overpaid
);
120 c_overpaid(PG_FUNCTION_ARGS
)
122 HeapTupleHeader t
= PG_GETARG_HEAPTUPLEHEADER(0);
123 int32 limit
= PG_GETARG_INT32(1);
127 salary
= DatumGetInt32(GetAttributeByName(t
, "salary", &isnull
));
129 PG_RETURN_BOOL(false);
132 * Alternatively, we might prefer to do PG_RETURN_NULL() for null salary
135 PG_RETURN_BOOL(salary
> limit
);