Thread: Registring a C function in PostgreSQL

Registring a C function in PostgreSQL

From
Miguel González
Date:
I have followed the instructions in the Bruje Momjian´s book to register a
function, and i got this message:

 ERROR:/load of file /home/postgres/ctof.so failed: /home/postgres/ctof.so
ELF file´s phentsize not the expected size.

What is going on? I have tried to get more documentation about how to use C
functions in PostgreSQL, but I cant.

 Many thanks in advance

 Miguel


Re: Registring a C function in PostgreSQL

From
Peter Eisentraut
Date:
Miguel González writes:

>  ERROR:/load of file /home/postgres/ctof.so failed: /home/postgres/ctof.so
> ELF file´s phentsize not the expected size.

You probably didn't compile or link the code correctly.  See the
PostgreSQL Programmer's Guide for information.

-- 
Peter Eisentraut   peter_e@gmx.net   http://funkturm.homeip.net/~peter



Re: Registring a C function in PostgreSQL

From
Haller Christoph
Date:
Did you use the compiler option for generating 
position independent code (PIC) for use in building
shared libraries.
Did you use the linker option for creating 
a shared library - I think you did, the file 
suffix .so looks that way. 
I did it several times successfully using commands 
like 
CREATE FUNCTION byteatostr(bytea) RETURNS textAS './byteatostr.sl' LANGUAGE 'c';
and it worked. 
Maybe you should add some more information about 
what you did in detail. 
Regards, Christoph 


Re: Registring a C function in PostgreSQL

From
Miguel González
Date:
Many thanks for your answers. The thing that in the Bruce´s book doesnt
explain how to compile this kind of functions, anyway I found how to compile
it.
Now, I am still having problems. I want to create a function to send an
email. I pass to the function two arguments: the email to send, and the text
to send.
First, I tried with pointers to char. It worked when I just create a
function called "sendemail()" with no arguments and set inside the text and
the email arguments.
When I read some more documentation about how to use strings in PostgreSQL,
I discovered that I have to use the text type in my C program I just try it
but
although it worked before, now I doesnt work.
This is what I have tried:

#include <stdio.h>#include "postgres.h"
int sendemail(text *email,text *message){
    char string_tosend [300];
    sprintf(string_tosend,"echo \"%s\" >/tmp/mailtmp.txt
\n",VARDATA(message));
    system(string_tosend);
   sprintf(string_tosend,"mail -s \"message from PostgreSQL\" %s
</tmp/mailtmp.txt \n",VARDATA(message));
    system(string_tosend);
    system("rm /tmp/mailtmp.txt");
    return 0;

}

and then in the back-end of PostgreSQL and I declared
CREATE FUNCTION sendemail(text,text)RETURNS int4AS '/home/postgres/libpginvuimail.so'LANGUAGE 'c';
and then SELECT sendemail('postgres','test from backend');
and it didnt work. What am I doing wrong?
I have being testing and I guess is something to do with the text data type
and how to use it within a C program.
Many thanks in advance
Miguel







----- Original Message -----
From: "Haller Christoph" <ch@rodos.fzk.de>
To: "Miguel González" <iafmgc@unileon.es>
Cc: <pgsql-sql@postgresql.org>
Sent: Wednesday, September 19, 2001 12:24 PM
Subject: Re: [SQL] Registring a C function in PostgreSQL


> Did you use the compiler option for generating
> position independent code (PIC) for use in building
> shared libraries.
> Did you use the linker option for creating
> a shared library - I think you did, the file
> suffix .so looks that way.
> I did it several times successfully using commands
> like
> CREATE FUNCTION byteatostr(bytea) RETURNS text
>  AS './byteatostr.sl' LANGUAGE 'c';
> and it worked.
> Maybe you should add some more information about
> what you did in detail.
> Regards, Christoph
>



Re: Registring a C function in PostgreSQL II

From
Haller Christoph
Date:
I'm working on a HP-UX system, so some of the 
following has to be adapted, but in principle 
it's the same on every system and it works. 
First piece of code is a standalone program, 
which you should always write and test before 
you start creating C functions inside PostgreSQL. 
Second piece is your sendemail function slightly 
modified to make it run on my system. 
When I do a 
select sendemail('ch', 'was soll das?') ;
I'm receiving an email from postgres. 
Regards, Christoph 

First piece:

/*
cc -Aa -g -I/opt/pgsql/include/ -c sendemtest.c
cc sendemail.o sendemtest.o -o sendemtest
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "postgres.h"

void main() {  char buf[1024];  int ln;  text *res;  text *to;  int sendemail(text *email,text *message);
strcpy(buf,"Kissenminister Aussinger \n");  ln = strlen(buf);    res = (text *) malloc(VARHDRSZ + ln);  memset(res, 0,
VARHDRSZ+ ln);  res->vl_len = VARHDRSZ + ln;  memcpy(res->vl_dat, buf, (int) ln);    strcpy(buf, "ch");  ln =
strlen(buf);   to = (text *) malloc(VARHDRSZ + ln);  memset(to, 0, VARHDRSZ + ln);  to->vl_len = VARHDRSZ + ln;
memcpy(to->vl_dat,buf, (int) ln);    sendemail(to, res);
 
}

Second piece: 

/*
cc -Aa -g -I/opt/pgsql/include/ +z -c sendemail.c
ld -b -o sendemail.sl sendemail.o

CREATE FUNCTION sendemail(text,text) RETURNS int4AS '/fdsk2/users/ch/tools/pgsql.mydoc/sendemail.sl' LANGUAGE 'c';
DROP FUNCTION sendemail(text,text);
*/#include <stdio.h>#include <stdlib.h>#include "postgres.h"
int sendemail(text *email,text *message){    int result = 0 ; 
    char string_tosend [300];
    sprintf(string_tosend,"/usr/bin/echo \"%s\" >/tmp/mailtmp.txt\n",VARDATA(message));
    result += system(string_tosend);
    sprintf(string_tosend,"/usr/bin/mail -dt %s </tmp/mailtmp.txt \n",     VARDATA(email));
    result += system(string_tosend);
    result += system("/usr/bin/rm /tmp/mailtmp.txt");
    return result;

}