1 /* src/tutorial/funcs.c */
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.
9 *****************************************************************************/
11 #include "postgres.h" /* general Postgres declarations */
13 #include "executor/executor.h" /* for GetAttributeByName() */
14 #include "utils/geo_decls.h" /* for point type */
21 PG_FUNCTION_INFO_V1(add_one
);
24 add_one(PG_FUNCTION_ARGS
)
26 int32 arg
= PG_GETARG_INT32(0);
28 PG_RETURN_INT32(arg
+ 1);
31 /* By Reference, Fixed Length */
33 PG_FUNCTION_INFO_V1(add_one_float8
);
36 add_one_float8(PG_FUNCTION_ARGS
)
38 /* The macros for FLOAT8 hide its pass-by-reference nature */
39 float8 arg
= PG_GETARG_FLOAT8(0);
41 PG_RETURN_FLOAT8(arg
+ 1.0);
44 PG_FUNCTION_INFO_V1(makepoint
);
47 makepoint(PG_FUNCTION_ARGS
)
49 Point
*pointx
= PG_GETARG_POINT_P(0);
50 Point
*pointy
= PG_GETARG_POINT_P(1);
51 Point
*new_point
= (Point
*) palloc(sizeof(Point
));
53 new_point
->x
= pointx
->x
;
54 new_point
->y
= pointy
->y
;
56 PG_RETURN_POINT_P(new_point
);
59 /* By Reference, Variable Length */
61 PG_FUNCTION_INFO_V1(copytext
);
64 copytext(PG_FUNCTION_ARGS
)
66 text
*t
= PG_GETARG_TEXT_PP(0);
69 * VARSIZE_ANY_EXHDR is the size of the struct in bytes, minus the
70 * VARHDRSZ or VARHDRSZ_SHORT of its header. Construct the copy with a
73 text
*new_t
= (text
*) palloc(VARSIZE_ANY_EXHDR(t
) + VARHDRSZ
);
75 SET_VARSIZE(new_t
, VARSIZE_ANY_EXHDR(t
) + VARHDRSZ
);
78 * VARDATA is a pointer to the data region of the new struct. The source
79 * could be a short datum, so retrieve its data through VARDATA_ANY.
81 memcpy((void *) VARDATA(new_t
), /* destination */
82 (void *) VARDATA_ANY(t
), /* source */
83 VARSIZE_ANY_EXHDR(t
)); /* how many bytes */
84 PG_RETURN_TEXT_P(new_t
);
87 PG_FUNCTION_INFO_V1(concat_text
);
90 concat_text(PG_FUNCTION_ARGS
)
92 text
*arg1
= PG_GETARG_TEXT_PP(0);
93 text
*arg2
= PG_GETARG_TEXT_PP(1);
94 int32 arg1_size
= VARSIZE_ANY_EXHDR(arg1
);
95 int32 arg2_size
= VARSIZE_ANY_EXHDR(arg2
);
96 int32 new_text_size
= arg1_size
+ arg2_size
+ VARHDRSZ
;
97 text
*new_text
= (text
*) palloc(new_text_size
);
99 SET_VARSIZE(new_text
, new_text_size
);
100 memcpy(VARDATA(new_text
), VARDATA_ANY(arg1
), arg1_size
);
101 memcpy(VARDATA(new_text
) + arg1_size
, VARDATA_ANY(arg2
), arg2_size
);
102 PG_RETURN_TEXT_P(new_text
);
105 /* Composite types */
107 PG_FUNCTION_INFO_V1(c_overpaid
);
110 c_overpaid(PG_FUNCTION_ARGS
)
112 HeapTupleHeader t
= PG_GETARG_HEAPTUPLEHEADER(0);
113 int32 limit
= PG_GETARG_INT32(1);
117 salary
= DatumGetInt32(GetAttributeByName(t
, "salary", &isnull
));
119 PG_RETURN_BOOL(false);
122 * Alternatively, we might prefer to do PG_RETURN_NULL() for null salary
125 PG_RETURN_BOOL(salary
> limit
);