Thread: C-Language Functions: VarChar and Text arguments

C-Language Functions: VarChar and Text arguments

From
Carel Combrink
Date:
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�V"�
         arg1: arg1��O"
         arg2: arg2��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?

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@tuks.co.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.



Re: C-Language Functions: VarChar and Text arguments

From
Carel Combrink
Date:
Quoting Brian Modra <brian@zwartberg.com>:

> On 06/04/2010, Carel Combrink <s25291930@tuks.co.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�V"�
>>          arg1: arg1��O"
>>          arg2: arg2��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.
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)".

>>
>> 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@tuks.co.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@postgresql.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@tuks.co.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.



Re: C-Language Functions: VarChar and Text arguments

From
Brian Modra
Date:
On 06/04/2010, Carel Combrink <s25291930@tuks.co.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�V"�
>          arg1: arg1��O"
>          arg2: arg2��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

>
> 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@tuks.co.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@postgresql.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/

Re: C-Language Functions: VarChar and Text arguments

From
Carel Combrink
Date:
Quoting Carel Combrink <s25291930@tuks.co.za>:

> Quoting Brian Modra <brian@zwartberg.com>:
>
>> On 06/04/2010, Carel Combrink <s25291930@tuks.co.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�V"�
>>>         arg1: arg1��O"
>>>         arg2: arg2��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.
> 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)".
>
>>>
>>> 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@tuks.co.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@postgresql.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@tuks.co.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@tuks.co.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.



Re: C-Language Functions: VarChar and Text arguments

From
Brian Modra
Date:
On 06/04/2010, Carel Combrink <s25291930@tuks.co.za> wrote:
> Quoting Carel Combrink <s25291930@tuks.co.za>:
>
>> Quoting Brian Modra <brian@zwartberg.com>:
>>
>>> On 06/04/2010, Carel Combrink <s25291930@tuks.co.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�V"�
>>>>         arg1: arg1��O"
>>>>         arg2: arg2��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@tuks.co.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@postgresql.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@tuks.co.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@tuks.co.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/

Re: C-Language Functions: VarChar and Text arguments

From
Carel Combrink
Date:
Quoting Brian Modra <brian@zwartberg.com>:

> On 06/04/2010, Carel Combrink <s25291930@tuks.co.za> wrote:
>> Quoting Carel Combrink <s25291930@tuks.co.za>:
>>
>>> Quoting Brian Modra <brian@zwartberg.com>:
>>>
>>>> On 06/04/2010, Carel Combrink <s25291930@tuks.co.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�V"�
>>>>>         arg1: arg1��O"
>>>>>         arg2: arg2��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@tuks.co.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@postgresql.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@tuks.co.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@tuks.co.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@tuks.co.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.



Re: C-Language Functions: VarChar and Text arguments

From
Brian Modra
Date:
On 06/04/2010, Carel Combrink <s25291930@tuks.co.za> wrote:
> Quoting Brian Modra <brian@zwartberg.com>:
>
>> On 06/04/2010, Carel Combrink <s25291930@tuks.co.za> wrote:
>>> Quoting Carel Combrink <s25291930@tuks.co.za>:
>>>
>>>> Quoting Brian Modra <brian@zwartberg.com>:
>>>>
>>>>> On 06/04/2010, Carel Combrink <s25291930@tuks.co.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�V"�
>>>>>>         arg1: arg1��O"
>>>>>>         arg2: arg2��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@tuks.co.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@postgresql.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@tuks.co.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@tuks.co.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@tuks.co.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@postgresql.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/

Re: C-Language Functions: VarChar and Text arguments

From
Jasen Betts
Date:
On 2010-04-06, Carel Combrink <s25291930@tuks.co.za> wrote:

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

???

  printf("%.*s",length,char_pointer);