]> granicus.if.org Git - postgresql/blob - src/tutorial/funcs.c
61ad1417a869496e0af397fe20f192209c82569a
[postgresql] / src / tutorial / funcs.c
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
35 add_one(int arg)
36 {
37         return arg + 1;
38 }
39
40 /* By Reference, Fixed Length */
41
42 float8 *
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 *
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 *
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 *
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
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 }