Search Postgresql Archives

Problems with a C function, pg_uname(), and String concatenation.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello

We have a function in C which is accessed via a view and which produces a strange result when used together with || (String concatenation).

I can not find the problem. Any C/postgres guru with any idea of how to fix it?

Here is the function and the result when used with ||:

-------------------------------------------
PG_UNAME()
-------------------------------------------
#include "postgres.h"
#include <string.h>
#include "fmgr.h"
#include <sys/utsname.h>


#ifdef PG_MODULE_MAGIC
PG_MODULE_MAGIC;
#endif


PG_FUNCTION_INFO_V1(pg_uname);

Datum
pg_uname(PG_FUNCTION_ARGS)
{
    text *argument = PG_GETARG_TEXT_P(0);
    size_t argumentlen = VARSIZE(argument)-VARHDRSZ;

    text *result = (text *) palloc(256);
    char *option = (char *) palloc(argumentlen+1);

    char sysname[] = "sysname";
    char nodename[] = "nodename";
    char release[] = "release";
    char version[] = "version";
    char machine[] = "machine";
    char null[] = "null";

    struct utsname uname_pointer;
    uname(&uname_pointer);

    VARATT_SIZEP(result) = 256;

    memcpy(option,VARDATA(argument),argumentlen);
    option[argumentlen] = '\0';

    if (strcmp(option,sysname) == 0){

memcpy(VARDATA(result),uname_pointer.sysname,sizeof(uname_pointer.sysname));
    }
    else if (strcmp(option,nodename) == 0){

memcpy(VARDATA(result),uname_pointer.nodename,sizeof(uname_pointer.nodename));
    }
    else if (strcmp(option,release) == 0){

memcpy(VARDATA(result),uname_pointer.release,sizeof(uname_pointer.release));
    }
    else if (strcmp(option,version) == 0){

memcpy(VARDATA(result),uname_pointer.version,sizeof(uname_pointer.version));
    }
    else if (strcmp(option,machine) == 0){

memcpy(VARDATA(result),uname_pointer.machine,sizeof(uname_pointer.machine));
    }
    else{
        memcpy(VARDATA(result),null,sizeof(null));
    }

    pfree(option);
    PG_RETURN_TEXT_P(result);
}

-------------------------------------------

The view we use is this one:
-------------------------------------------
SELECT pg_uname('sysname'::text) AS sysname,
       pg_uname('nodename'::text) AS nodename,
       pg_uname('release'::text) AS kernel,
       pg_uname('version'::text) AS version,
       pg_uname('machine'::text) AS machine,
       substr(version(), 11, 7) AS pgversion,
to_char(pg_postmaster_start_time(),'YYYY-MM-DD HH24:MM:SS'::text) AS pg_start,
       age(now(),pg_postmaster_start_time()) AS pg_uptime;
-------------------------------------------

A normal output from this view looks like this:

pgadmin=# SELECT * from sysinfo;

-[ RECORD 1 ]----------------------------------
sysname   | Linux
nodename  | dbpg-rt.uio.no
kernel    | 2.6.9-67.0.4.ELsmp
version   | #1 SMP Fri Jan 18 05:00:00 EST 2008
machine   | x86_64
pgversion |  8.2.6
pg_start  | 2008-06-10 10:06:28
pg_uptime | 20 days 23:59:24.971497


But, when used with ||, everything comming after attributes delivered by pg_uname() disappears:

SELECT '***' || sysname || '***' as example from sysinfo ;

 example
----------
 ***Linux
(1 row)

Any ideas?
Thanks in advance for your time.

PS.- This is the section og the make file used to compile this function:
-----------------------------------------------------------------------
SERVER_INCLUDES += -I $(shell /usr/local/bin/pg_config --includedir)
SERVER_INCLUDES += -I $(shell /usr/local/bin/pg_config --includedir-server)

CFLAGS = $(SERVER_INCLUDES)
CC = gcc

pg_uname: pg_uname.c
	  $(CC) $(CFLAGS) -fpic -c $<
          $(CC) $(CFLAGS) -shared -o $(basename $<).so $(basename $<).o
-----------------------------------------------------------------------

regards
--
 Rafael Martinez, <r.m.guerrero@xxxxxxxxxxx>
 Center for Information Technology Services
 University of Oslo, Norway

 PGP Public Key: http://folk.uio.no/rafael/


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Postgresql Jobs]     [Postgresql Admin]     [Postgresql Performance]     [Linux Clusters]     [PHP Home]     [PHP on Windows]     [Kernel Newbies]     [PHP Classes]     [PHP Books]     [PHP Databases]     [Postgresql & PHP]     [Yosemite]
  Powered by Linux