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

From: "Pavel Stehule" <pavel(dot)stehule(at)gmail(dot)com>
To: "Rafael Martinez" <r(dot)m(dot)guerrero(at)usit(dot)uio(dot)no>
Cc: pgsql-general <pgsql-general(at)postgresql(dot)org>
Subject: Re: Problems with a C function, pg_uname(), and String concatenation.
Date: 2008-07-01 09:56:15
Message-ID: 162867790807010256k212a097t4e14fb1e808c98ed@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-general

hello
try

memcpy(VARDATA(result),uname_pointer.release,strlen(uname_pointer.release));
SET_VARSIZE(result, strlen(uname_pointer.release) + VARHDRSZ);

Regards
Pave Stehule

2008/7/1 Rafael Martinez <r(dot)m(dot)guerrero(at)usit(dot)uio(dot)no>:
> 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(dot)m(dot)guerrero(at)usit(dot)uio(dot)no>
> Center for Information Technology Services
> University of Oslo, Norway
>
> PGP Public Key: http://folk.uio.no/rafael/
>
> --
> Sent via pgsql-general mailing list (pgsql-general(at)postgresql(dot)org)
> To make changes to your subscription:
> http://www.postgresql.org/mailpref/pgsql-general
>

In response to

Responses

Browse pgsql-general by date

  From Date Subject
Next Message Oleg Bartunov 2008-07-01 10:25:00 Re: multi-word expression full-text searching
Previous Message hubert depesz lubaczewski 2008-07-01 09:52:46 Re: FTS question