Skip to content

Commit d9eb7d8

Browse files
committed
Update funcs tutorial for new function manager.
1 parent 782c16c commit d9eb7d8

File tree

2 files changed

+183
-38
lines changed

2 files changed

+183
-38
lines changed

src/tutorial/funcs.c

Lines changed: 67 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -4,75 +4,104 @@
44
55
The calling format for these functions is defined by the CREATE FUNCTION
66
SQL statement that binds them to the backend.
7+
8+
NOTE: this file shows examples of "old style" function call conventions.
9+
See funcs_new.c for examples of "new style".
710
*****************************************************************************/
811

9-
#include "postgres.h" /* for variable length type */
12+
#include <string.h>
13+
14+
#include "postgres.h" /* general Postgres declarations */
15+
1016
#include "executor/executor.h" /* for GetAttributeByName() */
1117
#include "utils/geo_decls.h" /* for point type */
1218

13-
/* The following prototypes declare what we assume the user declares to
14-
Postgres in his CREATE FUNCTION statement.
15-
*/
19+
20+
/* These prototypes just prevent possible warnings from gcc. */
1621

1722
int add_one(int arg);
23+
float8 *add_one_float8(float8 *arg);
1824
Point *makepoint(Point *pointx, Point *pointy);
1925
text *copytext(text *t);
20-
26+
text *concat_text(text *arg1, text *arg2);
2127
bool c_overpaid(TupleTableSlot *t, /* the current instance of EMP */
22-
int4 limit);
23-
28+
int32 limit);
2429

2530

31+
/* By Value */
32+
2633
int
2734
add_one(int arg)
2835
{
29-
return arg + 1;
36+
return arg + 1;
37+
}
38+
39+
/* By Reference, Fixed Length */
40+
41+
float8 *
42+
add_one_float8(float8 *arg)
43+
{
44+
float8 *result = (float8 *) palloc(sizeof(float8));
45+
46+
*result = *arg + 1.0;
47+
48+
return result;
3049
}
3150

3251
Point *
3352
makepoint(Point *pointx, Point *pointy)
3453
{
35-
Point *new_point = (Point *) palloc(sizeof(Point));
54+
Point *new_point = (Point *) palloc(sizeof(Point));
3655

37-
new_point->x = pointx->x;
38-
new_point->y = pointy->y;
39-
40-
return new_point;
56+
new_point->x = pointx->x;
57+
new_point->y = pointy->y;
58+
59+
return new_point;
4160
}
4261

62+
/* By Reference, Variable Length */
63+
4364
text *
4465
copytext(text *t)
4566
{
67+
/*
68+
* VARSIZE is the total size of the struct in bytes.
69+
*/
70+
text *new_t = (text *) palloc(VARSIZE(t));
71+
VARATT_SIZEP(new_t) = VARSIZE(t);
72+
/*
73+
* VARDATA is a pointer to the data region of the struct.
74+
*/
75+
memcpy((void *) VARDATA(new_t), /* destination */
76+
(void *) VARDATA(t), /* source */
77+
VARSIZE(t)-VARHDRSZ); /* how many bytes */
78+
return new_t;
79+
}
4680

47-
/*
48-
* VARSIZE is the total size of the struct in bytes.
49-
*/
50-
text *new_t = (text *) palloc(VARSIZE(t));
51-
52-
MemSet(new_t, 0, VARSIZE(t));
53-
54-
VARSIZE(new_t) = VARSIZE(t);
55-
56-
/*
57-
* VARDATA is a pointer to the data region of the struct.
58-
*/
59-
memcpy((void *) VARDATA(new_t), /* destination */
60-
(void *) VARDATA(t), /* source */
61-
VARSIZE(t) - VARHDRSZ); /* how many bytes */
62-
63-
return new_t;
81+
text *
82+
concat_text(text *arg1, text *arg2)
83+
{
84+
int32 new_text_size = VARSIZE(arg1) + VARSIZE(arg2) - VARHDRSZ;
85+
text *new_text = (text *) palloc(new_text_size);
86+
87+
memset((void *) new_text, 0, new_text_size);
88+
VARATT_SIZEP(new_text) = new_text_size;
89+
strncpy(VARDATA(new_text), VARDATA(arg1), VARSIZE(arg1)-VARHDRSZ);
90+
strncat(VARDATA(new_text), VARDATA(arg2), VARSIZE(arg2)-VARHDRSZ);
91+
return new_text;
6492
}
6593

94+
/* Composite types */
95+
6696
bool
6797
c_overpaid(TupleTableSlot *t, /* the current instance of EMP */
68-
int4 limit)
98+
int32 limit)
6999
{
70-
bool isnull = false;
71-
int4 salary;
72-
73-
salary = (int4) GetAttributeByName(t, "salary", &isnull);
100+
bool isnull;
101+
int32 salary;
74102

75-
if (isnull)
76-
return false;
77-
return salary > limit;
103+
salary = DatumGetInt32(GetAttributeByName(t, "salary", &isnull));
104+
if (isnull)
105+
return (false);
106+
return salary > limit;
78107
}

src/tutorial/funcs_new.c

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
/******************************************************************************
2+
These are user-defined functions that can be bound to a Postgres backend
3+
and called by Postgres to execute SQL functions of the same name.
4+
5+
The calling format for these functions is defined by the CREATE FUNCTION
6+
SQL statement that binds them to the backend.
7+
8+
NOTE: this file shows examples of "new style" function call conventions.
9+
See funcs.c for examples of "old style".
10+
*****************************************************************************/
11+
12+
#include <string.h>
13+
14+
#include "postgres.h" /* general Postgres declarations */
15+
16+
#include "fmgr.h" /* for argument/result macros */
17+
#include "executor/executor.h" /* for GetAttributeByName() */
18+
#include "utils/geo_decls.h" /* for point type */
19+
20+
21+
/* These prototypes just prevent possible warnings from gcc. */
22+
23+
Datum add_one(PG_FUNCTION_ARGS);
24+
Datum add_one_float8(PG_FUNCTION_ARGS);
25+
Datum makepoint(PG_FUNCTION_ARGS);
26+
Datum copytext(PG_FUNCTION_ARGS);
27+
Datum concat_text(PG_FUNCTION_ARGS);
28+
Datum c_overpaid(PG_FUNCTION_ARGS);
29+
30+
31+
/* By Value */
32+
33+
Datum
34+
add_one(PG_FUNCTION_ARGS)
35+
{
36+
int32 arg = PG_GETARG_INT32(0);
37+
38+
PG_RETURN_INT32(arg + 1);
39+
}
40+
41+
/* By Reference, Fixed Length */
42+
43+
Datum
44+
add_one_float8(PG_FUNCTION_ARGS)
45+
{
46+
/* The macros for FLOAT8 hide its pass-by-reference nature */
47+
float8 arg = PG_GETARG_FLOAT8(0);
48+
49+
PG_RETURN_FLOAT8(arg + 1.0);
50+
}
51+
52+
Datum
53+
makepoint(PG_FUNCTION_ARGS)
54+
{
55+
Point *pointx = PG_GETARG_POINT_P(0);
56+
Point *pointy = PG_GETARG_POINT_P(1);
57+
Point *new_point = (Point *) palloc(sizeof(Point));
58+
59+
new_point->x = pointx->x;
60+
new_point->y = pointy->y;
61+
62+
PG_RETURN_POINT_P(new_point);
63+
}
64+
65+
/* By Reference, Variable Length */
66+
67+
Datum
68+
copytext(PG_FUNCTION_ARGS)
69+
{
70+
text *t = PG_GETARG_TEXT_P(0);
71+
/*
72+
* VARSIZE is the total size of the struct in bytes.
73+
*/
74+
text *new_t = (text *) palloc(VARSIZE(t));
75+
VARATT_SIZEP(new_t) = VARSIZE(t);
76+
/*
77+
* VARDATA is a pointer to the data region of the struct.
78+
*/
79+
memcpy((void *) VARDATA(new_t), /* destination */
80+
(void *) VARDATA(t), /* source */
81+
VARSIZE(t)-VARHDRSZ); /* how many bytes */
82+
PG_RETURN_TEXT_P(new_t);
83+
}
84+
85+
Datum
86+
concat_text(PG_FUNCTION_ARGS)
87+
{
88+
text *arg1 = PG_GETARG_TEXT_P(0);
89+
text *arg2 = PG_GETARG_TEXT_P(1);
90+
int32 new_text_size = VARSIZE(arg1) + VARSIZE(arg2) - VARHDRSZ;
91+
text *new_text = (text *) palloc(new_text_size);
92+
93+
memset((void *) new_text, 0, new_text_size);
94+
VARATT_SIZEP(new_text) = new_text_size;
95+
strncpy(VARDATA(new_text), VARDATA(arg1), VARSIZE(arg1)-VARHDRSZ);
96+
strncat(VARDATA(new_text), VARDATA(arg2), VARSIZE(arg2)-VARHDRSZ);
97+
PG_RETURN_TEXT_P(new_text);
98+
}
99+
100+
/* Composite types */
101+
102+
Datum
103+
c_overpaid(PG_FUNCTION_ARGS)
104+
{
105+
TupleTableSlot *t = (TupleTableSlot *) PG_GETARG_POINTER(0);
106+
int32 limit = PG_GETARG_INT32(1);
107+
bool isnull;
108+
int32 salary;
109+
110+
salary = DatumGetInt32(GetAttributeByName(t, "salary", &isnull));
111+
if (isnull)
112+
PG_RETURN_BOOL(false);
113+
/* Alternatively, we might prefer to do PG_RETURN_NULL() for null salary */
114+
115+
PG_RETURN_BOOL(salary > limit);
116+
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy