Skip site navigation (1) Skip section navigation (2)

Re: C-Language Functions: VarChar and Text arguments

From: Brian Modra <brian(at)zwartberg(dot)com>
To: Carel Combrink <s25291930(at)tuks(dot)co(dot)za>
Cc: pgsql-novice(at)postgresql(dot)org
Subject: Re: C-Language Functions: VarChar and Text arguments
Date: 2010-04-06 12:10:28
Message-ID: g2n5a9699851004060510yd0de35bdxf05ca2d1c63dacc3@mail.gmail.com (view raw or flat)
Thread:
Lists: pgsql-novice
On 06/04/2010, Carel Combrink <s25291930(at)tuks(dot)co(dot)za> wrote:
> Quoting Brian Modra <brian(at)zwartberg(dot)com>:
>
>> On 06/04/2010, Carel Combrink <s25291930(at)tuks(dot)co(dot)za> wrote:
>>> Quoting Carel Combrink <s25291930(at)tuks(dot)co(dot)za>:
>>>
>>>> Quoting Brian Modra <brian(at)zwartberg(dot)com>:
>>>>
>>>>> On 06/04/2010, Carel Combrink <s25291930(at)tuks(dot)co(dot)za> wrote:
>>>>>> Hi,
>>>>>>
>>>>>> I have problems using 'varchar' and 'text' arguments for C functions.
>>>>>> Perhaps I am doing something wrong. I get garbage when I want to use
>>>>>> the arguments passed to the function. See the example:
>>>>>>
>>>>>> My function as defined in my C program:
>>>>>> /*===========================================*/
>>>>>> PG_FUNCTION_INFO_V1(Test_Function);
>>>>>>
>>>>>> Datum Test_Function(PG_FUNCTION_ARGS) /* varChar(10) varChar Text*/
>>>>>> {
>>>>>>     VarChar* arg0_varChar10 = PG_GETARG_VARCHAR_P(0);
>>>>>>     VarChar* arg1_varChar = PG_GETARG_VARCHAR_P(1);
>>>>>>     text* arg2_textp = PG_GETARG_VARCHAR_P(2);
>>>>>>
>>>>>>     ereport( INFO, ( errcode( ERRCODE_SUCCESSFUL_COMPLETION ),
>>>>>> errmsg("Inputs :\n\targ0: %s\n\targ1: %s\n\targ2:
>>>>>> %s\n",VARDATA(arg0_varChar10), VARDATA(arg1_varChar),
>>>>>> VARDATA(arg2_textp))));
>>>>>>
>>>>>>     PG_RETURN_INT32(0);
>>>>>> }
>>>>>> /*=============================================*/
>>>>>>
>>>>>> I run the following in PostgreSQL 8.4 to create the function:
>>>>>> ------------------------------------------------
>>>>>> CREATE OR REPLACE FUNCTION Test_Function(varchar(10), varchar, text)
>>>>>> RETURNS integer
>>>>>>   AS '$libdir/myDir/myLib', 'Test_Function'
>>>>>>   LANGUAGE C
>>>>>>   VOLATILE
>>>>>>   STRICT
>>>>>>   SECURITY DEFINER;
>>>>>> ------------------------------------------------
>>>>>>
>>>>>> The output I get when I call the function:
>>>>>> --------------------------------------------
>>>>>> My_database=# SELECT Test_Function('arg0', 'arg1', 'arg2');
>>>>>>
>>>>>> is:
>>>>>>
>>>>>> INFO:  Inputs :
>>>>>>         arg0: arg&#65533;V"&#65533;
>>>>>>         arg1: arg1&#65533;&#65533;O"
>>>>>>         arg2: arg2&#65533;&#65533;O"
>>>>>>
>>>>>>  test_function
>>>>>> ---------------
>>>>>>              0
>>>>>> (1 row)
>>>>>> --------------------------------------------
>>>>>>
>>>>>> What is the 'garbage' I see at the end of the output?
>>>>>> Am I calling the correct functions in my C code to retrieve the
>>>>>> arguments and then the correct ones to display them?
>>>>>
>>>>> You need to use a text* structure. See this page, it explains it all:
>>>>> http://www.postgresql.org/docs/8.2/static/xfunc-c.html
>>>>>
>>>>
>>>> One thing I noted: in my function I used "text* arg2_textp =
>>>> PG_GETARG_VARCHAR_P(2);" I changed this to
>>>> "PG_GETARG_TEXT_P(2)" but it made no difference.
>>>> If you look closely to the function I am using the text* structure.
>>
>> Sorry I replied too hastily... I have not compiled your program, but
>> its probably just that the strings are not null terminated. The text
>> structure does have the size in it, use VARSIZE.
>>
>>>> If I copy and paste the function "copytext" into my library and compile
>>>> and create the funciton (see
>>>> http://www.postgresql.org/docs/8.4/static/xfunc-c.html)
>>>> an add the line
>>>> "ereport( INFO, ( errcode( ERRCODE_SUCCESSFUL_COMPLETION ),
>>>> errmsg("Text: %s", VARDATA(new_t))));"
>>>> and call the function from postgreSQL I get the following output:
>>>> SELECT copytext('test_string');
>>>> INFO:  Text: test_stringES/postgres-8.4.mo
>>>>   copytext
>>>> -------------
>>>>  test_string
>>>> (1 row)
>>>>
>>>> (NOTE: after the first call to the function it all seems fine, but when
>>>> I rerun the same command (press up and enter) I get the above output)
>>>>
>>>> I can see that the string that gets returned is correct but when I try
>>>> to access the data part of the argument in the function using the
>>>> VARDATA(new_t) command I get garbage. Am I using the correct command to
>>>> access the data portion of the text* structure. According to the
>>>> documentation at the link the VARDATA should return the data portions
>>>> of the text* structure but it is giving me garbage.
>>>>
>>>> I get the same output when using "new_t->vl_dat" in stead of
>>>> "VARDATA(new_t)".
>>
>> If you are just printing the string it gets a bit painful, because all
>> the C functions assume null terminated strings. But sized strings are
>> quite convenient too, because the size is known.
>>
>> Just for printing (debuggong purposes, why not make yourself a
>> function, e.g. (not compiled or tested, I hope it works) ...
>>
>> void printText(FILE *stream, text* t)
>> {
>>     int32 sz = VARSIZE(t);
>>     const char* str = VARDATA(t);
>>     for (int32 i = 0; i < sz; i++) {
>>         fputc(str[i], stream);
>>     }
>> }
>
> I Created a function that takes in a sized string and returns a sized
> string. The function creates a new string that is one char longer than
> the input string and copy the data from the input string and null
> terminate the last char, returning the new string.

ok, that will work, watch out for memory leaks though.

>
> Thank you for the help

Its a pleasure!

>
>>
>>>>
>>>>>>
>>>>>> In my original function I want to send the name of an entity to the
>>>>>> database and then add the name to a table but this is a problem if the
>>>>>> name is garbled.
>>>>>>
>>>>>> Using: PostgreSQL 8.4
>>>>>> OS: Linux Ubuntu 9.10 Karmic Koala
>>>>>>
>>>>>> --
>>>>>> Carel Combrink
>>>>>> s25291930(at)tuks(dot)co(dot)za
>>>>>>
>>>>>> This message and attachments are subject to a disclaimer. Please refer
>>>>>> to www.it.up.ac.za/documentation/governance/disclaimer/ for full
>>>>>> details. / Hierdie boodskap en aanhangsels is aan 'n
>>>>>> vrywaringsklousule
>>>>>> onderhewig. Volledige besonderhede is by
>>>>>> www.it.up.ac.za/documentation/governance/disclaimer/ beskikbaar.
>>>>>>
>>>>>>
>>>>>>
>>>>>> --
>>>>>> Sent via pgsql-novice mailing list (pgsql-novice(at)postgresql(dot)org)
>>>>>> To make changes to your subscription:
>>>>>> http://www.postgresql.org/mailpref/pgsql-novice
>>>>>>
>>>>>
>>>>> --
>>>>> Brian Modra   Land line: +27 23 5411 462
>>>>> Mobile: +27 79 69 77 082
>>>>> 5 Jan Louw Str, Prince Albert, 6930
>>>>> Postal: P.O. Box 2, Prince Albert 6930
>>>>> South Africa
>>>>> http://www.zwartberg.com/
>>>>>
>>>>
>>>>
>>>>
>>>> --
>>>> Carel Combrink
>>>> s25291930(at)tuks(dot)co(dot)za
>>>>
>>>> This message and attachments are subject to a disclaimer. Please refer
>>>> to www.it.up.ac.za/documentation/governance/disclaimer/ for full
>>>> details. / Hierdie boodskap en aanhangsels is aan 'n vrywaringsklousule
>>>> onderhewig. Volledige besonderhede is by
>>>> www.it.up.ac.za/documentation/governance/disclaimer/ beskikbaar.
>>>
>>>  From the output I can assume the string is not null terminated, if it
>>> is not I assume once again that I should do this on my own (null
>>> terminate it).
>>>
>>> Isn't there an easier way to use the data (text*) in a printf() type
>>> way, I need to construct a SQL query from the input data and I am
>>> using the printf() notation and %s only works on zero terminated
>>> strings.
>>>
>>> --
>>> Carel Combrink
>>> s25291930(at)tuks(dot)co(dot)za
>>>
>>> This message and attachments are subject to a disclaimer. Please refer
>>> to www.it.up.ac.za/documentation/governance/disclaimer/ for full
>>> details. / Hierdie boodskap en aanhangsels is aan 'n vrywaringsklousule
>>> onderhewig. Volledige besonderhede is by
>>> www.it.up.ac.za/documentation/governance/disclaimer/ beskikbaar.
>>>
>>>
>>>
>>
>>
>> --
>> Brian Modra   Land line: +27 23 5411 462
>> Mobile: +27 79 69 77 082
>> 5 Jan Louw Str, Prince Albert, 6930
>> Postal: P.O. Box 2, Prince Albert 6930
>> South Africa
>> http://www.zwartberg.com/
>>
>
>
>
> --
> Carel Combrink
> s25291930(at)tuks(dot)co(dot)za
>
> This message and attachments are subject to a disclaimer. Please refer
> to www.it.up.ac.za/documentation/governance/disclaimer/ for full
> details. / Hierdie boodskap en aanhangsels is aan 'n vrywaringsklousule
> onderhewig. Volledige besonderhede is by
> www.it.up.ac.za/documentation/governance/disclaimer/ beskikbaar.
>
>
>
> --
> Sent via pgsql-novice mailing list (pgsql-novice(at)postgresql(dot)org)
> To make changes to your subscription:
> http://www.postgresql.org/mailpref/pgsql-novice
>


-- 
Brian Modra   Land line: +27 23 5411 462
Mobile: +27 79 69 77 082
5 Jan Louw Str, Prince Albert, 6930
Postal: P.O. Box 2, Prince Albert 6930
South Africa
http://www.zwartberg.com/

In response to

pgsql-novice by date

Next:From: JORGE MALDONADODate: 2010-04-06 18:23:52
Subject: TRANSACTION FOR AN UPDATE COMMAND WITH ONE TABLE
Previous:From: Carel CombrinkDate: 2010-04-06 11:23:01
Subject: Re: C-Language Functions: VarChar and Text arguments

Privacy Policy | About PostgreSQL
Copyright © 1996-2014 The PostgreSQL Global Development Group