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 10:58:25
Message-ID: u2u5a9699851004060358of187803anfa0701fb7b9b4ff7@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-novice

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);
}
}

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

In response to

Responses

Browse pgsql-novice by date

  From Date Subject
Next Message Carel Combrink 2010-04-06 11:23:01 Re: C-Language Functions: VarChar and Text arguments
Previous Message Carel Combrink 2010-04-06 10:12:01 Re: C-Language Functions: VarChar and Text arguments