Thread: Calling function from VFP changes character field to Memo

Calling function from VFP changes character field to Memo

From
Frank Cazabon
Date:
Hi,

I have a simple table Patients with one field FirstName of type 
character(30).

If I

SELECT FirstName From public.patients;

I get back the expected character(30) field.

If however I have a function defined like this

CREATE OR REPLACE FUNCTION public.testfunction(
     )
     RETURNS TABLE
     (
         Firstname character(30)
     )
     LANGUAGE 'plpgsql'


AS $BODY$
BEGIN
     RETURN QUERY SELECT p.cFirstName FROM patients p;
END;
$BODY$;

And I call:

SELECT * FROM public.testFunction();

Then FirstName returns as a Memo field (similar to a Text field).

Any idea what I need to do to get it to return the character(30) type?

-- 

Frank.

Frank Cazabon




Re: Calling function from VFP changes character field to Memo

From
Adrian Klaver
Date:
On 11/15/22 9:44 AM, Frank Cazabon wrote:
> Hi,
> 
> I have a simple table Patients with one field FirstName of type 
> character(30).
> 
> If I
> 
> SELECT FirstName From public.patients;
> 
> I get back the expected character(30) field.
> 
> If however I have a function defined like this
> 
> CREATE OR REPLACE FUNCTION public.testfunction(
>      )
>      RETURNS TABLE
>      (
>          Firstname character(30)
>      )
>      LANGUAGE 'plpgsql'
> 
> 
> AS $BODY$
> BEGIN
>      RETURN QUERY SELECT p.cFirstName FROM patients p;

In the first query the field name is FirstName not cFirstName.

Is this a typo or are they different fields?

> END;
> $BODY$;
> 
> And I call:
> 
> SELECT * FROM public.testFunction();

SELECT firstname from FROM public.testFunction();

> 
> Then FirstName returns as a Memo field (similar to a Text field).
> 
> Any idea what I need to do to get it to return the character(30) type?
> 


-- 
Adrian Klaver
adrian.klaver@aklaver.com



Re: Calling function from VFP changes character field to Memo

From
Tom Lane
Date:
Frank Cazabon <frank.cazabon@gmail.com> writes:
> If however I have a function defined like this

> CREATE OR REPLACE FUNCTION public.testfunction(
>      )
>      RETURNS TABLE
>      (
>          Firstname character(30)
>      )
>      LANGUAGE 'plpgsql'
> AS $BODY$
> BEGIN
>      RETURN QUERY SELECT p.cFirstName FROM patients p;
> END;
> $BODY$;

> And I call:
> SELECT * FROM public.testFunction();
> Then FirstName returns as a Memo field (similar to a Text field).

This is mostly about whatever software stack you're using on the
client side --- Memo is certainly not something Postgres knows about.

> Any idea what I need to do to get it to return the character(30) type?

There's no chance of getting back the "30" part with this structure,
because function signatures do not carry length restrictions.
What I expect is happening is that you get firstname as an
unspecified-length "character" type, and something on the client
side is deciding to cope with that by calling it "Memo" instead.

You could perhaps work around that by defining a named composite
type:

create type testfunction_result as (firstname character(30), ...);

create function testfunction() returns setof testfunction_result as ...

            regards, tom lane



Re: Calling function from VFP changes character field to Memo

From
Adrian Klaver
Date:
On 11/15/22 10:43 AM, Frank Cazabon wrote:

Please reply to list als.
Ccing list

>>> SELECT * FROM public.testFunction();
>>
>> SELECT firstname from FROM public.testFunction();
> This has the same result.

How about?:

SELECT firstname::varchar(30) from FROM public.testFunction();

>>
>>>
>>> Then FirstName returns as a Memo field (similar to a Text field).
>>>
>>> Any idea what I need to do to get it to return the character(30) type?
>>>
>>
>>


-- 
Adrian Klaver
adrian.klaver@aklaver.com



Re: Calling function from VFP changes character field to Memo

From
Adrian Klaver
Date:
On 11/15/22 10:44 AM, Tom Lane wrote:
> Frank Cazabon <frank.cazabon@gmail.com> writes:

> 
>> Any idea what I need to do to get it to return the character(30) type?
> 
> There's no chance of getting back the "30" part with this structure,
> because function signatures do not carry length restrictions.
> What I expect is happening is that you get firstname as an
> unspecified-length "character" type, and something on the client
> side is deciding to cope with that by calling it "Memo" instead.

My experience is that frameworks 'see' ::text as Memo/Textarea and 
::char/varchar as Input.

> 
> You could perhaps work around that by defining a named composite
> type:
> 
> create type testfunction_result as (firstname character(30), ...);
> 
> create function testfunction() returns setof testfunction_result as ...
> 
>             regards, tom lane
> 
> 


-- 
Adrian Klaver
adrian.klaver@aklaver.com



Re: Calling function from VFP changes character field to Memo

From
Frank Cazabon
Date:
On 15/11/2022 2:48 pm, Adrian Klaver wrote:
> On 11/15/22 10:43 AM, Frank Cazabon wrote:
>
> Please reply to list als.
> Ccing list
Sorry about that, first time using this list and just assumed I was 
replying to the list and the list would then notify you
>
>>>> SELECT * FROM public.testFunction();
>>>
>>> SELECT firstname from FROM public.testFunction();
>> This has the same result.
>
> How about?:
>
> SELECT firstname::varchar(30) from FROM public.testFunction();

That does work, thanks, but it may cause me some logic problems in the 
rest of the code. I'll try the type suggestion from Tom and see if that 
works and then decide which is my best approach.

Thanks

>
>>>
>>>>
>>>> Then FirstName returns as a Memo field (similar to a Text field).
>>>>
>>>> Any idea what I need to do to get it to return the character(30) type?
>>>>
>>>
>>>
>
>



Re: Calling function from VFP changes character field to Memo

From
Frank Cazabon
Date:
On 15/11/2022 2:44 pm, Tom Lane wrote:
> Frank Cazabon <frank.cazabon@gmail.com> writes:
>> If however I have a function defined like this
>> CREATE OR REPLACE FUNCTION public.testfunction(
>>       )
>>       RETURNS TABLE
>>       (
>>           Firstname character(30)
>>       )
>>       LANGUAGE 'plpgsql'
>> AS $BODY$
>> BEGIN
>>       RETURN QUERY SELECT p.cFirstName FROM patients p;
>> END;
>> $BODY$;
>> And I call:
>> SELECT * FROM public.testFunction();
>> Then FirstName returns as a Memo field (similar to a Text field).
> This is mostly about whatever software stack you're using on the
> client side --- Memo is certainly not something Postgres knows about.
>
>> Any idea what I need to do to get it to return the character(30) type?
> There's no chance of getting back the "30" part with this structure,
> because function signatures do not carry length restrictions.
> What I expect is happening is that you get firstname as an
> unspecified-length "character" type, and something on the client
> side is deciding to cope with that by calling it "Memo" instead.
>
> You could perhaps work around that by defining a named composite
> type:
>
> create type testfunction_result as (firstname character(30), ...);
>
> create function testfunction() returns setof testfunction_result as ...
>
>             regards, tom lane
Thanks, so I could define the function like this - removed the (30):

CREATE OR REPLACE FUNCTION public.testfunction(
      )
      RETURNS TABLE
      (
          Firstname character
      )
      LANGUAGE 'plpgsql'

I'll try the type definition and see if that helps.



Re: Calling function from VFP changes character field to Memo

From
Adrian Klaver
Date:
On 11/15/22 10:54 AM, Frank Cazabon wrote:
> 
> On 15/11/2022 2:44 pm, Tom Lane wrote:
>> Frank Cazabon <frank.cazabon@gmail.com> writes:
>>> If however I have a function defined like this
>>> CREATE OR REPLACE FUNCTION public.testfunction(
>>>       )
>>>       RETURNS TABLE
>>>       (
>>>           Firstname character(30)
>>>       )
>>>       LANGUAGE 'plpgsql'
>>> AS $BODY$
>>> BEGIN
>>>       RETURN QUERY SELECT p.cFirstName FROM patients p;
>>> END;
>>> $BODY$;
>>> And I call:
>>> SELECT * FROM public.testFunction();
>>> Then FirstName returns as a Memo field (similar to a Text field).
>> This is mostly about whatever software stack you're using on the
>> client side --- Memo is certainly not something Postgres knows about.
>>
>>> Any idea what I need to do to get it to return the character(30) type?
>> There's no chance of getting back the "30" part with this structure,
>> because function signatures do not carry length restrictions.
>> What I expect is happening is that you get firstname as an
>> unspecified-length "character" type, and something on the client
>> side is deciding to cope with that by calling it "Memo" instead.
>>
>> You could perhaps work around that by defining a named composite
>> type:
>>
>> create type testfunction_result as (firstname character(30), ...);
>>
>> create function testfunction() returns setof testfunction_result as ...
>>
>>             regards, tom lane
> Thanks, so I could define the function like this - removed the (30):
> 
> CREATE OR REPLACE FUNCTION public.testfunction(
>       )
>       RETURNS TABLE
>       (
>           Firstname character
>       )
>       LANGUAGE 'plpgsql'

No you don't want to do that:

select 'test'::char;
  bpchar
--------
  t

vs

select 'test'::varchar;
  varchar
---------
  test

Besides you missed the important part, after creating the type 
testfunction_result:

create function testfunction() returns setof testfunction_result as ...


> 
> I'll try the type definition and see if that helps.
> 
> 


-- 
Adrian Klaver
adrian.klaver@aklaver.com



Re: Calling function from VFP changes character field to Memo

From
Ron
Date:
On 11/15/22 12:54, Frank Cazabon wrote:
>
> On 15/11/2022 2:44 pm, Tom Lane wrote:
>> Frank Cazabon <frank.cazabon@gmail.com> writes:
>>> If however I have a function defined like this
>>> CREATE OR REPLACE FUNCTION public.testfunction(
>>>       )
>>>       RETURNS TABLE
>>>       (
>>>           Firstname character(30)
>>>       )
>>>       LANGUAGE 'plpgsql'
>>> AS $BODY$
>>> BEGIN
>>>       RETURN QUERY SELECT p.cFirstName FROM patients p;
>>> END;
>>> $BODY$;
>>> And I call:
>>> SELECT * FROM public.testFunction();
>>> Then FirstName returns as a Memo field (similar to a Text field).
>> This is mostly about whatever software stack you're using on the
>> client side --- Memo is certainly not something Postgres knows about.
>>
>>> Any idea what I need to do to get it to return the character(30) type?
>> There's no chance of getting back the "30" part with this structure,
>> because function signatures do not carry length restrictions.
>> What I expect is happening is that you get firstname as an
>> unspecified-length "character" type, and something on the client
>> side is deciding to cope with that by calling it "Memo" instead.
>>
>> You could perhaps work around that by defining a named composite
>> type:
>>
>> create type testfunction_result as (firstname character(30), ...);
>>
>> create function testfunction() returns setof testfunction_result as ...
>>
>>             regards, tom lane
> Thanks, so I could define the function like this - removed the (30):
>
> CREATE OR REPLACE FUNCTION public.testfunction(
>      )
>      RETURNS TABLE
>      (
>          Firstname character
>      )
>      LANGUAGE 'plpgsql'
>
> I'll try the type definition and see if that helps.

I think you should try the original function in psql.  That will delineate 
Postgresql from framework.

-- 
Angular momentum makes the world go 'round.



Re: Calling function from VFP changes character field to Memo

From
Frank Cazabon
Date:
I don't think that's necessary, I'm 100% certain that it's VFP not able to interpret the size of what is coming back to
itso it just gives it the biggest type it can. 

Thanks

15 Nov 2022 14:59:59 Ron <ronljohnsonjr@gmail.com>:

> On 11/15/22 12:54, Frank Cazabon wrote:
>>
>> On 15/11/2022 2:44 pm, Tom Lane wrote:
>>> Frank Cazabon <frank.cazabon@gmail.com> writes:
>>>> If however I have a function defined like this
>>>> CREATE OR REPLACE FUNCTION public.testfunction(
>>>>       )
>>>>       RETURNS TABLE
>>>>       (
>>>>           Firstname character(30)
>>>>       )
>>>>       LANGUAGE 'plpgsql'
>>>> AS $BODY$
>>>> BEGIN
>>>>       RETURN QUERY SELECT p.cFirstName FROM patients p;
>>>> END;
>>>> $BODY$;
>>>> And I call:
>>>> SELECT * FROM public.testFunction();
>>>> Then FirstName returns as a Memo field (similar to a Text field).
>>> This is mostly about whatever software stack you're using on the
>>> client side --- Memo is certainly not something Postgres knows about.
>>>
>>>> Any idea what I need to do to get it to return the character(30) type?
>>> There's no chance of getting back the "30" part with this structure,
>>> because function signatures do not carry length restrictions.
>>> What I expect is happening is that you get firstname as an
>>> unspecified-length "character" type, and something on the client
>>> side is deciding to cope with that by calling it "Memo" instead.
>>>
>>> You could perhaps work around that by defining a named composite
>>> type:
>>>
>>> create type testfunction_result as (firstname character(30), ...);
>>>
>>> create function testfunction() returns setof testfunction_result as ...
>>>
>>>             regards, tom lane
>> Thanks, so I could define the function like this - removed the (30):
>>
>> CREATE OR REPLACE FUNCTION public.testfunction(
>>      )
>>      RETURNS TABLE
>>      (
>>          Firstname character
>>      )
>>      LANGUAGE 'plpgsql'
>>
>> I'll try the type definition and see if that helps.
>
> I think you should try the original function in psql.  That will delineate Postgresql from framework.
>
> --
> Angular momentum makes the world go 'round.



Re: Calling function from VFP changes character field to Memo

From
Frank Cazabon
Date:
On 15/11/2022 2:58 pm, Adrian Klaver wrote:
> On 11/15/22 10:54 AM, Frank Cazabon wrote:
>>
>> On 15/11/2022 2:44 pm, Tom Lane wrote:
>>> Frank Cazabon <frank.cazabon@gmail.com> writes:
>>>> If however I have a function defined like this
>>>> CREATE OR REPLACE FUNCTION public.testfunction(
>>>>       )
>>>>       RETURNS TABLE
>>>>       (
>>>>           Firstname character(30)
>>>>       )
>>>>       LANGUAGE 'plpgsql'
>>>> AS $BODY$
>>>> BEGIN
>>>>       RETURN QUERY SELECT p.cFirstName FROM patients p;
>>>> END;
>>>> $BODY$;
>>>> And I call:
>>>> SELECT * FROM public.testFunction();
>>>> Then FirstName returns as a Memo field (similar to a Text field).
>>> This is mostly about whatever software stack you're using on the
>>> client side --- Memo is certainly not something Postgres knows about.
>>>
>>>> Any idea what I need to do to get it to return the character(30) type?
>>> There's no chance of getting back the "30" part with this structure,
>>> because function signatures do not carry length restrictions.
>>> What I expect is happening is that you get firstname as an
>>> unspecified-length "character" type, and something on the client
>>> side is deciding to cope with that by calling it "Memo" instead.
>>>
>>> You could perhaps work around that by defining a named composite
>>> type:
>>>
>>> create type testfunction_result as (firstname character(30), ...);
>>>
>>> create function testfunction() returns setof testfunction_result as ...
>>>
>>>             regards, tom lane
>> Thanks, so I could define the function like this - removed the (30):
>>
>> CREATE OR REPLACE FUNCTION public.testfunction(
>>       )
>>       RETURNS TABLE
>>       (
>>           Firstname character
>>       )
>>       LANGUAGE 'plpgsql'
>
> No you don't want to do that:
>
> select 'test'::char;
>  bpchar
> --------
>  t
>
> vs
>
> select 'test'::varchar;
>  varchar
> ---------
>  test
>
> Besides you missed the important part, after creating the type 
> testfunction_result:
>
> create function testfunction() returns setof testfunction_result as ...
>

Sorry about the confusion, I have got it working using the type definition.

Thanks for the help

>
>>
>> I'll try the type definition and see if that helps.
>>
>>
>
>