1 /* src/tutorial/funcs.c */
2 
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.
6 
7   The calling format for these functions is defined by the CREATE FUNCTION
8   SQL statement that binds them to the backend.
9 
10   NOTE: this file shows examples of "old style" function call conventions.
11   See funcs_new.c for examples of "new style".
12 *****************************************************************************/
13 
14 #include "postgres.h"			/* general Postgres declarations */
15 
16 #include "executor/executor.h"	/* for GetAttributeByName() */
17 #include "utils/geo_decls.h"	/* for point type */
18 
19 PG_MODULE_MAGIC;
20 
21 /* These prototypes just prevent possible warnings from gcc. */
22 
23 int			add_one(int arg);
24 float8	   *add_one_float8(float8 *arg);
25 Point	   *makepoint(Point *pointx, Point *pointy);
26 text	   *copytext(text *t);
27 text	   *concat_text(text *arg1, text *arg2);
28 bool c_overpaid(HeapTupleHeader t,		/* the current instance of EMP */
29 		   int32 limit);
30 
31 
32 /* By Value */
33 
34 int
add_one(int arg)35 add_one(int arg)
36 {
37 	return arg + 1;
38 }
39 
40 /* By Reference, Fixed Length */
41 
42 float8 *
add_one_float8(float8 * arg)43 add_one_float8(float8 *arg)
44 {
45 	float8	   *result = (float8 *) palloc(sizeof(float8));
46 
47 	*result = *arg + 1.0;
48 
49 	return result;
50 }
51 
52 Point *
makepoint(Point * pointx,Point * pointy)53 makepoint(Point *pointx, Point *pointy)
54 {
55 	Point	   *new_point = (Point *) palloc(sizeof(Point));
56 
57 	new_point->x = pointx->x;
58 	new_point->y = pointy->y;
59 
60 	return new_point;
61 }
62 
63 /* By Reference, Variable Length */
64 
65 text *
copytext(text * t)66 copytext(text *t)
67 {
68 	/*
69 	 * VARSIZE is the total size of the struct in bytes.
70 	 */
71 	text	   *new_t = (text *) palloc(VARSIZE(t));
72 
73 	SET_VARSIZE(new_t, VARSIZE(t));
74 
75 	/*
76 	 * VARDATA is a pointer to the data region of the struct.
77 	 */
78 	memcpy((void *) VARDATA(new_t), /* destination */
79 		   (void *) VARDATA(t), /* source */
80 		   VARSIZE(t) - VARHDRSZ);	/* how many bytes */
81 	return new_t;
82 }
83 
84 text *
concat_text(text * arg1,text * arg2)85 concat_text(text *arg1, text *arg2)
86 {
87 	int32		arg1_size = VARSIZE(arg1) - VARHDRSZ;
88 	int32		arg2_size = VARSIZE(arg2) - VARHDRSZ;
89 	int32		new_text_size = arg1_size + arg2_size + VARHDRSZ;
90 	text	   *new_text = (text *) palloc(new_text_size);
91 
92 	SET_VARSIZE(new_text, new_text_size);
93 	memcpy(VARDATA(new_text), VARDATA(arg1), arg1_size);
94 	memcpy(VARDATA(new_text) + arg1_size, VARDATA(arg2), arg2_size);
95 	return new_text;
96 }
97 
98 /* Composite types */
99 
100 bool
c_overpaid(HeapTupleHeader t,int32 limit)101 c_overpaid(HeapTupleHeader t,	/* the current instance of EMP */
102 		   int32 limit)
103 {
104 	bool		isnull;
105 	int32		salary;
106 
107 	salary = DatumGetInt32(GetAttributeByName(t, "salary", &isnull));
108 	if (isnull)
109 		return false;
110 	return salary > limit;
111 }
112