Re: C-Language Functions: VarChar and Text arguments

From: Carel Combrink <s25291930(at)tuks(dot)co(dot)za>
To: Brian Modra <brian(at)zwartberg(dot)com>
Cc: pgsql-novice(at)postgresql(dot)org
Subject: Re: C-Language Functions: VarChar and Text arguments
Date: 2010-04-06 11:23:01
Message-ID: 20100406132301.4ouu8itmizkowk44@student.up.ac.za
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-novice

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.

Thank you for the help

>
>>>
>>>>>
>>>>> 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.

In response to

Responses

Browse pgsql-novice by date

  From Date Subject
Next Message Brian Modra 2010-04-06 12:10:28 Re: C-Language Functions: VarChar and Text arguments
Previous Message Brian Modra 2010-04-06 10:58:25 Re: C-Language Functions: VarChar and Text arguments