Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit86e4efc

Browse files
committed
Add documentation about calling version-1 C functions from C.
This topic wasn't really covered before, so fill in some details.Author: Florents Tselai <florents.tselai@gmail.com>Reviewed-by: Pavel Stehule <pavel.stehule@gmail.com>Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>Discussion:https://postgr.es/m/90853055-5BBD-493D-91E5-721677C7C59B@gmail.com
1 parent43830ec commit86e4efc

File tree

3 files changed

+112
-5
lines changed

3 files changed

+112
-5
lines changed

‎doc/src/sgml/xfunc.sgml

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2384,6 +2384,56 @@ PG_FUNCTION_INFO_V1(funcname);
23842384
takes as its argument the actual value to return.
23852385
</para>
23862386

2387+
<para>
2388+
To call another version-1 function, you can use
2389+
<function>DirectFunctionCall<replaceable>n</replaceable>(func,
2390+
arg1, ..., argn)</function>. This is particularly useful when you want
2391+
to call functions defined in the standard internal library, by using an
2392+
interface similar to their SQL signature.
2393+
</para>
2394+
2395+
<para>
2396+
These convenience functions and similar ones can be found
2397+
in <filename>fmgr.h</filename>.
2398+
The <function>DirectFunctionCall<replaceable>n</replaceable></function>
2399+
family expect a C function name as their first argument. There are also
2400+
<function>OidFunctionCall<replaceable>n</replaceable></function> which
2401+
take the OID of the target function, and some other variants. All of
2402+
these expect the function's arguments to be supplied
2403+
as <type>Datum</type>s, and likewise they return <type>Datum</type>.
2404+
Note that neither arguments nor result are allowed to be NULL when
2405+
using these convenience functions.
2406+
</para>
2407+
2408+
<para>
2409+
For example, to call the <function>starts_with(text, text)</function>
2410+
function from C, you can search through the catalog and find out that
2411+
its C implementation is the
2412+
<function>Datum text_starts_with(PG_FUNCTION_ARGS)</function>
2413+
function. Typically you would
2414+
use <literal>DirectFunctionCall2(text_starts_with, ...)</literal> to
2415+
call such a function. However, <function>starts_with(text,
2416+
text)</function> requires collation information, so it will fail
2417+
with <quote>could not determine which collation to use for string
2418+
comparison</quote> if called that way. Instead you must
2419+
use <literal>DirectFunctionCall2Coll(text_starts_with, ...)</literal>
2420+
and provide the desired collation, which typically is just passed
2421+
through from <function>PG_GET_COLLATION()</function>, as shown in the
2422+
example below.
2423+
</para>
2424+
2425+
<para>
2426+
<filename>fmgr.h</filename> also supplies macros that facilitate
2427+
conversions between C types and <type>Datum</type>. For example to
2428+
turn <type>Datum</type> into <type>text*</type>, you can
2429+
use <function>DatumGetTextPP(X)</function>. While some types have macros
2430+
named like <function>TypeGetDatum(X)</function> for the reverse
2431+
conversion, <type>text*</type> does not; it's sufficient to use the
2432+
generic macro <function>PointerGetDatum(X)</function> for that.
2433+
If your extension defines additional types, it is usually convenient to
2434+
define similar macros for your types too.
2435+
</para>
2436+
23872437
<para>
23882438
Here are some examples using the version-1 calling convention:
23892439
</para>
@@ -2482,6 +2532,25 @@ concat_text(PG_FUNCTION_ARGS)
24822532
memcpy(VARDATA(new_text) + arg1_size, VARDATA_ANY(arg2), arg2_size);
24832533
PG_RETURN_TEXT_P(new_text);
24842534
}
2535+
2536+
/* A wrapper around starts_with(text, text) */
2537+
2538+
PG_FUNCTION_INFO_V1(t_starts_with);
2539+
2540+
Datum
2541+
t_starts_with(PG_FUNCTION_ARGS)
2542+
{
2543+
text *t1 = PG_GETARG_TEXT_PP(0);
2544+
text *t2 = PG_GETARG_TEXT_PP(1);
2545+
Oid collid = PG_GET_COLLATION();
2546+
bool result;
2547+
2548+
result = DatumGetBool(DirectFunctionCall2Coll(text_starts_with,
2549+
collid,
2550+
PointerGetDatum(t1),
2551+
PointerGetDatum(t2)));
2552+
PG_RETURN_BOOL(result);
2553+
}
24852554
]]>
24862555
</programlisting>
24872556

@@ -2513,6 +2582,10 @@ CREATE FUNCTION copytext(text) RETURNS text
25132582
CREATE FUNCTION concat_text(text, text) RETURNS text
25142583
AS '<replaceable>DIRECTORY</replaceable>/funcs', 'concat_text'
25152584
LANGUAGE C STRICT;
2585+
2586+
CREATE FUNCTION t_starts_with(text, text) RETURNS boolean
2587+
AS '<replaceable>DIRECTORY</replaceable>/funcs', 't_starts_with'
2588+
LANGUAGE C STRICT;
25162589
</programlisting>
25172590

25182591
<para>

‎src/tutorial/funcs.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include"postgres.h"/* general Postgres declarations */
1212

1313
#include"executor/executor.h"/* for GetAttributeByName() */
14+
#include"utils/fmgrprotos.h"/* for text_starts_with() */
1415
#include"utils/geo_decls.h"/* for point type */
1516

1617
PG_MODULE_MAGIC;
@@ -102,6 +103,25 @@ concat_text(PG_FUNCTION_ARGS)
102103
PG_RETURN_TEXT_P(new_text);
103104
}
104105

106+
/* A wrapper around starts_with(text, text) */
107+
108+
PG_FUNCTION_INFO_V1(t_starts_with);
109+
110+
Datum
111+
t_starts_with(PG_FUNCTION_ARGS)
112+
{
113+
text*t1=PG_GETARG_TEXT_PP(0);
114+
text*t2=PG_GETARG_TEXT_PP(1);
115+
Oidcollid=PG_GET_COLLATION();
116+
boolresult;
117+
118+
result=DatumGetBool(DirectFunctionCall2Coll(text_starts_with,
119+
collid,
120+
PointerGetDatum(t1),
121+
PointerGetDatum(t2)));
122+
PG_RETURN_BOOL(result);
123+
}
124+
105125
/* Composite types */
106126

107127
PG_FUNCTION_INFO_V1(c_overpaid);

‎src/tutorial/funcs.source

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -123,34 +123,48 @@ SELECT * FROM EMP;
123123
-----------------------------
124124

125125
CREATE FUNCTION add_one(integer) RETURNS integer
126-
AS '_OBJWD_/funcs' LANGUAGE C;
126+
AS '_OBJWD_/funcs' LANGUAGE C STRICT;
127+
128+
CREATE FUNCTION add_one(double precision) RETURNS double precision
129+
AS '_OBJWD_/funcs' LANGUAGE C STRICT;
127130

128131
CREATE FUNCTION makepoint(point, point) RETURNS point
129-
AS '_OBJWD_/funcs' LANGUAGE C;
132+
AS '_OBJWD_/funcs' LANGUAGE C STRICT;
130133

131134
CREATE FUNCTION copytext(text) RETURNS text
132-
AS '_OBJWD_/funcs' LANGUAGE C;
135+
AS '_OBJWD_/funcs' LANGUAGE C STRICT;
136+
137+
CREATE FUNCTION concat_text(text, text) RETURNS text
138+
AS '_OBJWD_/funcs' LANGUAGE C STRICT;
139+
140+
CREATE FUNCTION t_starts_with(text, text) RETURNS boolean
141+
AS '_OBJWD_/funcs' LANGUAGE C STRICT;
133142

134143
CREATE FUNCTION c_overpaid(EMP, integer) RETURNS boolean
135-
AS '_OBJWD_/funcs' LANGUAGE C;
144+
AS '_OBJWD_/funcs' LANGUAGE C STRICT;
136145

137146
SELECT add_one(3) AS four;
138147

139148
SELECT makepoint('(1,2)'::point, '(3,4)'::point ) AS newpoint;
140149

141150
SELECT copytext('hello world!');
142151

152+
SELECT t_starts_with('foobar', 'foo');
153+
143154
SELECT name, c_overpaid(EMP, 1500) AS overpaid
144155
FROM EMP
145156
WHERE name = 'Bill' or name = 'Sam';
146157

147158
-- remove functions that were created in this file
148159

149160
DROP FUNCTION c_overpaid(EMP, integer);
161+
DROP FUNCTION t_starts_with(text, text);
162+
DROP FUNCTION concat_text(text, text);
150163
DROP FUNCTION copytext(text);
151164
DROP FUNCTION makepoint(point, point);
165+
DROP FUNCTION add_one(double precision);
152166
DROP FUNCTION add_one(integer);
153-
--DROP FUNCTION clean_EMP();
167+
DROP FUNCTION clean_EMP();
154168
DROP FUNCTION high_pay();
155169
DROP FUNCTION new_emp();
156170
DROP FUNCTION add_em(integer, integer);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp