Está en la página 1de 19

Crear funciones en C para PostgreSQL

Crear funciones en C para PostgreSQL (acá v 12)

PostgreSQL permite extender las funciones predefinidas en PL/pgsql usando un mecanismo para
crear funciones en su lenguaje nativo de programación como es C .

Esto permite ampliar nuestro abanico de posibilidades al desarrollar nuestra propias funciones
para que ejecuten tareas específicas o que sean críticas para el motor de base de datos, donde la
opciones de PL/pgsql o PL/python u otro lenguaje procedural que no nos satisface por completo.

Lo primero que debemos tener en cuenta es que no debemos confundir un lenguaje procedural PL
con funciones UDF, un lenguaje procedural implementa mecanismos propios para soportar ese
lenguaje por ejemplo PL/python que evidentemente también están escritos en C.

Implementar un lenguaje procedural es uno de los aspectos más avanzados que tiene PostgreSQL
y para la finalidad de este artículo no lo vamos a tomar en cuenta.

Usaremos Ubuntu Desktop 18.04 para ejecutar nuestras pruebas.

Preparar nuestro entorno de trabajo.


Antes de entrar en acción debemos preparar nuestro entorno de trabajo cumpliendo con lo
siguiente pasos.

Actualizar vía apt lo siguiente:

1.- Upgrade de los repositorios de Ubuntu

sudo apt update


sudo apt –y upgrade

2.- Instalar el compilador de C y “C++” entre otras herramientas como el editor Nano y
las net-tools

sudo apt –y install build-essential


sudo apt –y net-tools
sudo apt –y install nano

P ágin a |1
Crear funciones en C para PostgreSQL

3.- Agregar los repositorios de PostgreSQL v 12

wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -


echo "deb http://apt.postgresql.org/pub/repos/apt/ `lsb_release -cs`-pgdg main" |sudo tee
/etc

4.- Instalar PostgreSQL más los archivos de desarrollo server-side

sudo apt -y install postgresql-12 postgresql-client-12 postgresql-server-dev-12

Hasta aquí ya PostgreSQL está instalado en ámbito local (localhost) y ejecutándose en espera de
comandos por parte del usuario, lo podemos comprobar mostrando los procesos de la cuenta
postgres

ps –u postgres u

5.- Instalar pgAdmin versión 4 la herramienta de gestión de PostgreSQL

sudo apt –y install pgAdmin4

PgAdmin es la herramienta de gestión de base de datos por excelencia de PostgreSQL se ejecuta


lanzando el ícono del elefante que está en el docker, este se mostrará en el navegador
predeterminado.

P ágin a |2
Crear funciones en C para PostgreSQL

6.- Configurar PostgreSQL

Por defecto la cuenta de gestión de la base de datos se llama postgres, pero es costumbre crear
una propia con suficiente privilegios para desenvolvernos en él, la configuración estándar no
permite mostrar la base de datos fuera de tu ámbito local (localhost) cambiaremos este
comportamiento más adelante para que podamos usar pgAdmin sin problemas

Vamos a crear un cuenta llamada sqlman y le daremos privilegios administrativos dentro de


PostgreSQL, con esa cuenta podemos crear usuarios y base de datos y con eso será más que
suficiente.

sudo su – postgres
createuser –s –d –P sqlman

Al ejecutar el comando createuser se ejecutarán con las siguientes opciones:

-s la cuenta tendrá privilegios de superususario


-d la cuenta puede crear o borrar base de datos
-P la cuenta tendrá contraseña que será solicitada dos veces al momento de crearla

P ágin a |3
Crear funciones en C para PostgreSQL

También debemos hacer cambios en dos archivos de configuración para que pgAdmin pueda
conectarse a PostgreSQL estos archivos son postgresql.conf y pg_hba.conf ambos están en la
carpeta /etc/postgresql/12/main. Se usa un editor de texto como nano para realizar dichos
cambios con las siguientes llamadas:

sudo nano /etc/postgresql/12/main/postgresql.conf

y después de haber trabajado con ese archivo se llama al siguiente:

sudo nano /etc/postgresql/12/main/pg_hbla.conf

En postregsql.conf se debe descomentar en listen_addresses y modificar su valor ‘localhost’ por


‘*’ quedando así:

Original

#------------------------------------------------------------------------------
# CONNECTIONS AND AUTHENTICATION
#------------------------------------------------------------------------------

# - Connection Settings –

#listen_addresses = 'localhost' # what IP address(es) to listen on;

Modificado

#------------------------------------------------------------------------------
# CONNECTIONS AND AUTHENTICATION
#------------------------------------------------------------------------------

# - Connection Settings -

listen_addresses = '*' # what IP address(es) to listen on;

Se guarda el archivo postgresql.conf y trabajaremos ahora con el siguiente archivo pg_hba.conf.

P ágin a |4
Crear funciones en C para PostgreSQL

Antes que nada debemos conocer cuál es nuestra dirección IP para poder crear la entrada
correspondiente dentro del archivo, usaremos el siguiente comando:

ifconfig

enp0s3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500


inet 192.168.2.59 netmask 255.255.255.0 broadcast 192.168.2.255
inet6 fe80::7689:a11e:83b7:f899 prefixlen 64 scopeid 0x20<link>
ether 08:00:27:17:e0:18 txqueuelen 1000 (Ethernet)
RX packets 1132 bytes 75865 (75.8 KB)
RX errors 0 dropped 4 overruns 0 frame 0
TX packets 1311 bytes 103614 (103.6 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536


inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (Bucle local)
RX packets 812 bytes 220263 (220.2 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 812 bytes 220263 (220.2 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

La dirección IP que buscamos está en la primera interface activa enp0s3 allí está la inet que en mi
máquina de pruebas es 192.168.2.59, es posible que en tu caso aparezca eth0 o lan0 u otra
diferente

Ya con este valor vamos a nuestro archivo pg_hba.conf y agregamos la siguiente línea que esta
remarcada en negrillas en IPV4 local connections

# DO NOT DISABLE!
# If you change this first entry you will need to make sure that the
# database superuser can access the database using some other method.
# Noninteractive access to all databases is required during automatic
# maintenance (custom daily cronjobs, replication, and similar tasks).
#
# Database administrative login by Unix domain socket
local all postgres peer

# TYPE DATABASE USER ADDRESS METHOD

# "local" is for Unix domain socket connections only


local all all peer
# IPv4 local connections:
host all all 127.0.0.1/32 md5
host all all 192.168.2.59/32 md5
# IPv6 local connections:
host all all ::1/128 md5
# Allow replication connections from localhost, by a user with the
# replication privilege.
local replication all peer
host replication all 127.0.0.1/32 md5
host replication all ::1/128 md5

P ágin a |5
Crear funciones en C para PostgreSQL

Guardamos los cambios y reiniciamos el servicio de PostgreSQL de la siguiente forma:

sudo service postgresql restart

7.- Lanzar pgAdmin y agregar el servidor localhost

Desde pgAdmin agregaremos nuestro servidor localhost, lo primero que pide la primera vez es
especificar una contraseña maestra la cual quedara registrada y que se usara cada vez que le lance
el pgAdmin nuevamente.

Marcamos Servers y con el botón derecho seleccionamos Create > Server…

En la ficha General

 Name colocamos localhost

En la ficha Connection

 Host name address colocamos localhost


 Username colocamos sqlman
 Password la contraseña que especificamos cuando se creó la cuenta sqlman
 Save password lo marcamos

Damos clic en botón Save y deberá aparece como en esta imagen

P ágin a |6
Crear funciones en C para PostgreSQL

8.- Verificar las versiones del compilador, linker y make

Trabajaremos con las siguientes versiones de las herramientas gcc 7.5.0, g++ 7.5.0, ld 2.30 y make
4.1. Ejecute para cada programa en su terminal de la siguiente forma:

gcc –-version

g++ --version

ld –-version

make –version

Si por alguna razón no coinciden alguna de las versiones se debe proceder a reinstalar las build-
essential con apt.

9.- Selección del IDE o Editor de Texto

Desde el punto de vista de un programador se puede escribir código C usando un simple editor de
texto como vim o nano y ejecutar la compilación usando la terminal con apoyo de make.

Si no es de tu gusto también puedes usar editores alternos como sublime-text o vscode, pero si
quieres más potencia entonces te recomiendo Code::Blocks, para instalar Code::Blocks ejecuta lo
siguiente:

sudo add-apt-repository ppa:codeblocks-devs/release


sudo apt update
sudo apt –y install codeblocks codeblocks-contrib

P ágin a |7
Crear funciones en C para PostgreSQL

Al ejecutar Code::Blocks verás una pantalla similar a esta:

En youtube existen muchos tutoriales sobre cómo usar este IDE para sacarle el mayor provecho
posible

P ágin a |8
Crear funciones en C para PostgreSQL

Entendiendo las funciones definidas por usuario (UDF) en PostgreSQL


PostgreSQL provee cuatro tipos de funciones

 Funciones en lenguaje de consulta SQL


 Funciones en lenguaje procedural como PL/pgsql o PL/python
 Funciones internas
 Funciones en lenguaje C

Desde SQL se crean las sentencias necesarias para crear las funciones según su tipo, en este caso
nos enfocamos en las funciones de C, la sentencia seria de la siguiente manera:

CREATE OR REPLACE FUNCTION suma_uno(integer)


RETURNS integer
AS '/path/lib/lib_test', 'suma_uno'
LANGUAGE C STRICT;

Observe que lib_test es el nombre de la biblioteca lib_test.so que se encuentra en la ruta


/path/lib/, esta ruta se denomina ruta fija o absoluta.

Otra manera de hacerlo sería de la siguiente forma:

CREATE OR REPLACE FUNCTION suma_uno(integer)


RETURNS integer
AS '$libdir/lib_test', 'suma_uno'
LANGUAGE C STRICT;

En este caso $libdir es reemplazado por PostgreSQL por la ruta por defecto que le fue indicada
cuando se hizo la compilación.

La función suma_uno será referenciada por PostgreSQL, donde será ejecutado en el momento
que se precise.

Todas las funciones son compiladas en objetos de carga dinámica (también llamadas bibliotecas
compartidas que tienen extensiones .so) y son cargadas por el servidor PostgreSQL bajo demanda.

Si una biblioteca o función no está definida o no se encuentra en la ruta especificada, PostgreSQL


devolverá alguno de los siguientes errores:

ERROR: no se pudo acceder al archivo «path/lib/lib_test»: No existe el archivo o el


directorio
SQL state: 58P01

P ágin a |9
Crear funciones en C para PostgreSQL

ERROR: no se pudo cargar la biblioteca «/path/lib/lib_test»: /path/lib/lib_test: no se


pueden leer los datos del archivo: Es un directorio
SQL state: 58P01

ERROR: no se pudo encontrar la función «suma_uno» en el archivo «/path/lib/lib_test.so»


SQL state: 42883

Comprender el paso de parámetros a nuestras UDF


El pase de parámetros en PostgreSQL posee 4 formas

1. Por posición: los parámetros se introducen en el mismo orden como fueron declarados
2. Dinámicos: la función soporta un número indeterminado de parámetros
3. Por posición notacional: los argumentos se pasan asociados a los nombres de los
parámetros
4. Por defecto: parámetros con valores por DEFAULT

Observe el siguiente ejemplo:

CREATE OR REPLACE FUNCTION suma_uno(integer)


RETURNS integer
AS '$libdir/lib_test', 'suma_uno'
LANGUAGE C STRICT;

El uso de la palabra reservada STRICT significa que cualquier parámetro pasado a la función con
valor NULL el resultado a devolver por la función también será NULL, más adelante veremos cómo
controlar los parámetros pasados como NULL dentro de nuestras funciones.

Una sentencia como se muestra a continuación también es valido

CREATE OR REPLACE FUNCTION suma_uno(integer DEFAULT 500)


RETURNS integer
AS '$libdir/lib_test', 'suma_uno'
LANGUAGE C STRICT;

En este caso el parámetro tiene un valor por defecto de 500 y será pasado a nuestra función. No
es lo mismo llamar a la función suma_uno() que suma_uno(NULL), la primera toma el valor por
DEFAULT y la segunda se está pasando un valor NULL explícitamente por lo cual la función
devolverá NULL.

Las funciones en PostgeSQL pueden ser declaradas para aceptar un número de argumentos
variables que deberán ser del mismo tipo, estos argumentos serán pasados a la función como un

P á g i n a | 10
Crear funciones en C para PostgreSQL

array. Este parámetro tiene que ser declarado como el último dentro de la posición con VARIADIC
y a su vez declararlo como tipo array según su tipo. Por ejemplo:

CREATE OR REPLACE FUNCTION suma_todos(VARIADIC numeros integer[])


RETURNS integer
AS '$libdir/lib_test', 'suma_todos'
LANGUAGE C STRICT;

La llamada a la función desde SQL se haría de la siguiente manera:

SELECT suma_todo(VARIADIC numeros => ARRAY[1,2,3,4,5,6]);

También puede ejecutarse de esta otra forma:

SELECT suma_todo(VARIADIC ARRAY[1,2,3,4,5,6]);

La posición notacional asocia el nombre del parámetro con el valor del argumento y es pasada a la
función. Su utilidad radica en que permite pasar fácilmente muchos parámetros sin importar el
orden. Por ejemplo:

CREATE OR REPLACE FUNCTION suma_todo(a integer, b integer, c integer)


RETURNS integer
AS '$libdir/lib_test', 'suma_todo'
LANGUAGE C STRICT;

El llamado de la función seria de la siguiente manera:

SELECT suma_todo(
b => 10,
c => 5,
a => 1
);

P á g i n a | 11
Crear funciones en C para PostgreSQL

La sobrecarga de funciones
En PostgreSQL una función se dice que esta sobrecargada cuando la misma función puede pasarle
uno o más argumentos de tipo diferentes o puede retornar un valor con un tipo diferente, el
concepto pareciera ser bastante simple, pero hay que prestarle atención. Veamos la siguiente
declaración de las siguientes funciones:

CREATE OR REPLACE FUNCTION suma_uno(integer)


RETURNS integer
AS '$libdir/lib_test', 'suma_uno'
LANGUAGE C STRICT;

CREATE OR REPLACE FUNCTION suma_uno(double precision)


RETURNS double precision
AS '$libdir/lib_test', 'suma_uno_float8'
LANGUAGE C STRICT;

Como muestra el ejemplo la función suma_uno tiene dos variantes: la primera pasa el parámetro
tipo integer mientras que la segunda pasa el parámetro tipo double precision, ambas devuelven el
tipo correspondiente la primera tipo integer y la segunda tipo double precision. Si observa bien
se llama a la función correspondiente en su biblioteca; suma_uno pasa un integer como
argumento porque así está declarada en biblioteca mientras que suma_uno_float8 recibe un
argumento de tipo float8 en C que equivale decir double precision desde PostgreSQL. Si
ejecutamos:

SELECT suma_uno(10);

Devolverá un integer porque se hizo el llamado a la función suma_uno(integer) en cambio sí


ejecutamos de esta otra forma:

SELECT suma_uno(10.5);

Devolverá un double precision porque se hizo el llamado a la función suma_uno(double precision)

Ya preparado nuestro entorno deb trabajo y visto la teoría de las llamadas a las funciones,
pasaremos a crear una función sencilla el famoso “Hola Mundo!!!”

P á g i n a | 12
Crear funciones en C para PostgreSQL

Código fuente, compilación, enlace y prueba de una función en C


Las funciones definidas del usuario o UDF pueden ser escritas en C (o un lenguaje que sea
compatible con C como C++). Como se dijo anteriormente las funciones se compilan en objetos
cargables dinámicamente (también denominadas bibliotecas compartidas) que tienen la
extensión .so o .dll según sea Linux o Windows

Las funciones en C para PostgreSQL siguen unas convenciones muy particulares que se deben
respetar siempre.

Los tipos de datos base en funciones con lenguaje C


Para saber cómo escribir las funciones en lenguaje C, necesitas conocer como PostgreSQL
representa internamente los tipos de datos base y como se pueden pasar argumentos a la
funciones o retornarlos de las mismas. Internamente, PostgreSQL representa los tipos de datos
base como una “burbuja de memoria”. Las UDF que definas sobre un tipo de datos a su vez
definen la forma en que PostgreSQL puede operar en él. Es decir, PostgreSQL solo almacenara y
recuperara los datos del disco y usara las UDF para ingresar, procesar y generar los datos.

Los tipos de datos base pueden tener tres formatos internos.

 Paso por valor, longitud fija


 Paso por referencia, longitud fija
 Paso por referencia, longitud variable

Los tipos por valor pueden ser solamente de una longitud de 1, 2 o 4 bytes. Debes ser cuidadoso al
definir tus tipos de datos porque deben tener el mismo tamaño en todas las arquitecturas. Por
ejemplo el tipo long es peligroso porque tiene 4 bytes en algunas máquinas y 8 bytes en otras,
mientras que el tipo int son 4 bytes en la mayoría de las máquinas Unix.

La convención de tipo de C indica el tamaño para los tipos de datos donde un intxx indica xx bits,
en cambio en SQL un tipo de datos intx indica x bytes, por ejemplo el tipo smallint de SQL tiene un
tamaño de 2 bytes (int2) que en C equivale a int16 o sea 16 bits.

En la siguiente tabla se muestran las equivalencias entre los tipos de SQL y tipos de C

Tipo SQL Tipo C Definido en


boolean bool postgres.h
box BOX* utils/geo_decls.h
bytea bytea* postgres.h
“char” char (ya incorporado por el compilador)
character BpChar* postgres.h
cid CommandId postgres.h
date DateADT utils/date.h
smallint (int2) int16 postgres.h
int2vector int2vector* postgres.h

P á g i n a | 13
Crear funciones en C para PostgreSQL

integer (int4) int32 postgres.h


real (float4) float4* postgres.h
double precision (float8) float8* postgres.h
interval Interval* datatype/timestamp.h
lseg LSEG* utils/geo_decls.h
name Name postgres.h
oid Oid postgres.h
oidvector oidvector* postgres.h
path PATH* utils/geo_decls.h
point POINT* utils/geo_decls.h
regproc regproc postgres.h
text text* postgres.h
tid ItemPointer Storage/itemptr.h
time TimeADT utils/date.h
time with time zone TimeTzADT utils/date.h
timestamp Timestamp* datatype/timestamp.h
varchar VarChar* postgres.h
xid TransactionId postgres.h

Ahora que sabes cómo definir los tipos de datos entre SQL y C, es tiempo de conocer como ubicar
los archivos que contiene las definiciones de esos tipos, los famosos archivos de cabecera.

Conocer donde esta cada cosa: el pg_config


El pg_config es un programa utilitario de PostgreSQL cuya finalidad es devolver información acerca
de la versión instalada del mismo. En su ejecución más básica muestra todos los aspectos
relevantes en cuanto a la instalación y configuración al momento de ser compilado. Disponemos
de una ayuda para una ejecución más precisa.

pg_config --help

pg_config provee información sobre la versión instalada de PostgreSQL.

Empleo:
pg_config [OPCIÓN]...

Opciones:
--bindir muestra la ubicación de ejecutables de usuario
--docdir muestra la ubicación de archivos de documentación
--htmldir muestra la ubicación de archivos de documentación HTML
--includedir muestra la ubicación de archivos de encabezados C
de las interfaces cliente
--pkgincludedir muestra la ubicación de otros archivos de
encabezados C
--includedir-server muestra la ubicación de archivos de encabezados C
del servidor
--libdir muestra la ubicación de bibliotecas
de código objeto
--pkglibdir muestra la ubicación de módulos para carga dinámica
--localedir muestra la ubicación de archivos de soporte de
configuraciones locales
--mandir muestra la ubicación de páginas de manual
--sharedir muestra la ubicación de archivos de soporte

P á g i n a | 14
Crear funciones en C para PostgreSQL

independientes de arquitectura
--sysconfdir muestra la ubicación de archivos de configuración
global del sistema
--pgxs muestra la ubicación del archivo makefile
para extensiones
--configure muestra las opciones que se dieron a «configure»
cuando PostgreSQL fue construido
--cc muestra el valor de CC cuando PostgreSQL fue construido
--cppflags muestra el valor de CPPFLAGS cuando PostgreSQL fue
construido
--cflags muestra el valor de CFLAGS cuando PostgreSQL fue
construido
--cflags_sl muestra el valor de CFLAGS_SL cuando PostgreSQL fue
construido
--ldflags muestra el valor de LDFLAGS cuando PostgreSQL fue
construido
--ldflags_ex muestra el valor de LDFLAGS_EX cuando PostgreSQL fue
construido
--ldflags_sl muestra el valor de LDFLAGS_SL cuando PostgreSQL fue
construido
--libs muestra el valor de LIBS cuando PostgreSQL fue
construido
--version muestra la versión de PostgreSQL
-?, --help muestra esta ayuda, luego sale

Si no se pasa ningún argumento, se muestra toda la información conocida

Para poder desarrollar nuestra funciones debemos conocer donde se encuentra los archivos
cabecera que necesita el compilador de C ejecutando

pg_config –-includedir-server
/usr/include/postgresql/12/server

pg_config –-pkgincludedir
/usr/incldue/postgresql

Y para ubicar las librerías

pg_config –-libdir
/usr/lib/x86_64-linux-gnu

pg_config –-pkglibdir
/usr/lib/postgresql/12/lib

Estos resultados pueden variar dependiendo de cómo se hizo la instalación o compilación de


PostgreSQL, para demostrar si efectivamente hay archivos en las rutas indicadas podemos ejecutar
de manera individual lo siguiente:

ls `pg_config –-includedir-server`

P á g i n a | 15
Crear funciones en C para PostgreSQL

ls `pg_config -–pkgincludedir`

ls `pg_config –-libdir`

Ls `pg_config –-pkglibdir`

El resultado de la ejecución debe mostrar los archivos correspondientes de cada carpeta, sabiendo
esto aprenderás a continuación como estructurar una función en C diseñada para PostgreSQL.

Estructurar un código fuente en C para Postgres


Como te decía antes, para poder escribir código en C para funciones que serán llamadas por
PostgresSQL, se deben seguir una serie de convenciones establecidas, lo veremos mejor con el
siguiente código con una función que devuelva un texto.

Listado saludar.c

Las líneas 1 y 2 se deben declarar los archivos de cabecera postgres.h y fmgr.h en ese orden.

El archivo postgres.h contiene las definiciones de los tipos base entre otras cosas, el archivo
fmgr.h contiene la macros que gestionan las funciones y hace la interface de llamadas a las
mismas.

P á g i n a | 16
Crear funciones en C para PostgreSQL

En la línea 3 es establece una definición denominada PG_MODULE_MAGIC, esta definición es muy


especial ya que asegura que la biblioteca que se está construyendo no sea cargada en un servidor
incompatible, PostgreSQL se asegura que el archivo contenga un “bloque mágico” con el
contenido apropiado. Esto permite al servidor detectar incompatibilidades obvias, tal como código
compilado para una version superior de PostgreSQL diferente. Se debe incluir este “bloque
mágico” solo una única vez y nada más.

En caso de que por error lo definas en otro archivo el compilador devolverá el siguiente error:

obj/Release/saludar.o: En la función `Pg_magic_func':


saludar.c:(.text+0x0): definiciones múltiples de `Pg_magic_func'
obj/Release/sumar_uno.o:sumar_uno.c:(.text+0x0): primero se definió aquí
collect2: error: ld returned 1 exit status

Como se muestra en el error PG_MODULE_MAGIC (luego de pre-procesado por el compilador se


traduce a Pg_magic_func y nos dice que en el archivo sumar_uno.c es donde ya se había
predefinido primeramente. En otras palabras está definido más de una vez.

En la línea 8 PG_FUNCTION_INFO_V1 es una macro construye una estructura que estará asociada
al nombre de la función dada, se le pasa como argumento el nombre de la función a declarar, esto
es obligatorio y debe estar declarado para cada función que vayamos a crear.

El Datum, en la línea 10, contiene un valor cualquiera de un tipo pasado por valor o un puntero a
un tipo pasado por referencia de la función declarada

Al definir la función saludar en la línea 11, se recibe como argumento PG_FUNCTION_ARGS, esta
macro se encarga de gestionar todos los argumentos pasados a la función incluyendo los
argumentos con valor NULL o cuando no se pasa argumento alguno a la función.

La línea 13 declara un puntero text donde se asignara el valor del argumento que es devuelto por
la macro PG_GETARG_TEXT_PP, observe que a la macro se le pasa el índice de la posición del
argumento que comienza en cero (0).

Cada macro de la forma PG_GET_ARG…(n) devuelve el valor en la posición del argumento para el
tipo que fue declarado.

En la línea 15 la macro PG_RETURN_TEXT_P, se encarga de hacer la devolución de llamada, en este


caso devuelve el valor o contenido apuntado por la variable t.

Cada macro de la forma PG_RETURN…(valor) retornara el valor de la función según el tipo


especificado.

P á g i n a | 17
Crear funciones en C para PostgreSQL

Compilación y enlace del código fuente


El GNU gcc es el compilador de C y C++ por excelencia en el mundo Linux, tiene la habilidad de
pre-procesar, compilar, ensamblar y enlazar automáticamente el código fuente que le indiquemos,
gcc se usa para compilar código C y g++ se usa para compilar código C++.

Para compilar el código saludar debemos invocar al compilador gcc con una serie de opciones
específica para el modelo de compilación.

Desarrollaremos los siguientes pasos:

1.- Llamar al terminal

2.- crear una carpeta llamada pgtest.

$ mkdir pgtest

3.- Dentro de la carpeta pgtest crear dos carpetas una se llamara source y la otra lib.

$ cd pgtest
$ mkdir source
$ mkdir lib

5.- Dentro de la carpeta source llamamos a nuestro editor y transcribimos el código y lo


guardamos como saludar.c, para guardar un archivo en nano se pulsa las teclas Ctrl+O y es
confirma la respuesta. Para salir de nano se pulsa las teclas Ctrl+X.

$ cd pgtest
$ nano saludar.c

P á g i n a | 18
Crear funciones en C para PostgreSQL

Se transcribe el siguiente código.

#include "postgres.h"
#include "fmgr.h"

PG_MODULE_MAGIC;

/* by reference, variable length */

PG_FUNCTION_INFO_V1(saludar);

Datum
saludar(PG_FUNCTION_ARGS)
{
text *t = PG_GETARG_TEXT_PP(0);

PG_RETURN_TEXT_P(t);
}

P á g i n a | 19

También podría gustarte