]> granicus.if.org Git - postgresql/blob - src/tutorial/funcs_new.c
Reindent table partitioning code.
[postgresql] / src / tutorial / funcs_new.c
1 /* src/tutorial/funcs_new.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 "new style" function call conventions.
11   See funcs.c for examples of "old 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
22 /* By Value */
23
24 PG_FUNCTION_INFO_V1(add_one);
25
26 Datum
27 add_one(PG_FUNCTION_ARGS)
28 {
29         int32           arg = PG_GETARG_INT32(0);
30
31         PG_RETURN_INT32(arg + 1);
32 }
33
34 /* By Reference, Fixed Length */
35
36 PG_FUNCTION_INFO_V1(add_one_float8);
37
38 Datum
39 add_one_float8(PG_FUNCTION_ARGS)
40 {
41         /* The macros for FLOAT8 hide its pass-by-reference nature */
42         float8          arg = PG_GETARG_FLOAT8(0);
43
44         PG_RETURN_FLOAT8(arg + 1.0);
45 }
46
47 PG_FUNCTION_INFO_V1(makepoint);
48
49 Datum
50 makepoint(PG_FUNCTION_ARGS)
51 {
52         Point      *pointx = PG_GETARG_POINT_P(0);
53         Point      *pointy = PG_GETARG_POINT_P(1);
54         Point      *new_point = (Point *) palloc(sizeof(Point));
55
56         new_point->x = pointx->x;
57         new_point->y = pointy->y;
58
59         PG_RETURN_POINT_P(new_point);
60 }
61
62 /* By Reference, Variable Length */
63
64 PG_FUNCTION_INFO_V1(copytext);
65
66 Datum
67 copytext(PG_FUNCTION_ARGS)
68 {
69         text       *t = PG_GETARG_TEXT_P(0);
70
71         /*
72          * VARSIZE is the total size of the struct in bytes.
73          */
74         text       *new_t = (text *) palloc(VARSIZE(t));
75
76         SET_VARSIZE(new_t, VARSIZE(t));
77
78         /*
79          * VARDATA is a pointer to the data region of the struct.
80          */
81         memcpy((void *) VARDATA(new_t),         /* destination */
82                    (void *) VARDATA(t), /* source */
83                    VARSIZE(t) - VARHDRSZ);              /* how many bytes */
84         PG_RETURN_TEXT_P(new_t);
85 }
86
87 PG_FUNCTION_INFO_V1(concat_text);
88
89 Datum
90 concat_text(PG_FUNCTION_ARGS)
91 {
92         text       *arg1 = PG_GETARG_TEXT_P(0);
93         text       *arg2 = PG_GETARG_TEXT_P(1);
94         int32           arg1_size = VARSIZE(arg1) - VARHDRSZ;
95         int32           arg2_size = VARSIZE(arg2) - VARHDRSZ;
96         int32           new_text_size = arg1_size + arg2_size + VARHDRSZ;
97         text       *new_text = (text *) palloc(new_text_size);
98
99         SET_VARSIZE(new_text, new_text_size);
100         memcpy(VARDATA(new_text), VARDATA(arg1), arg1_size);
101         memcpy(VARDATA(new_text) + arg1_size, VARDATA(arg2), arg2_size);
102         PG_RETURN_TEXT_P(new_text);
103 }
104
105 /* Composite types */
106
107 PG_FUNCTION_INFO_V1(c_overpaid);
108
109 Datum
110 c_overpaid(PG_FUNCTION_ARGS)
111 {
112         HeapTupleHeader t = PG_GETARG_HEAPTUPLEHEADER(0);
113         int32           limit = PG_GETARG_INT32(1);
114         bool            isnull;
115         int32           salary;
116
117         salary = DatumGetInt32(GetAttributeByName(t, "salary", &isnull));
118         if (isnull)
119                 PG_RETURN_BOOL(false);
120
121         /*
122          * Alternatively, we might prefer to do PG_RETURN_NULL() for null salary
123          */
124
125         PG_RETURN_BOOL(salary > limit);
126 }