From: | Rob Sargent <robjsargent(at)gmail(dot)com> |
---|---|
To: | Adrian Klaver <adrian(dot)klaver(at)aklaver(dot)com>, pgsql-general(at)lists(dot)postgresql(dot)org |
Subject: | Re: schema agnostic functions in language sql |
Date: | 2020-05-15 23:07:07 |
Message-ID: | cbea3b73-54e8-acd7-3f32-30c29ac30b26@gmail.com |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-general |
On 5/15/20 4:58 PM, Adrian Klaver wrote:
> On 5/15/20 3:53 PM, Rob Sargent wrote:
>>
>>
>> On 5/15/20 4:43 PM, Adrian Klaver wrote:
>>> On 5/15/20 3:26 PM, Rob Sargent wrote:
>>>> I'm using postgres 12.2, with multiple identical schema per
>>>> database (each with a matching role). I can write public plpgsql
>>>> functions without using a schema identifier and let the runtime
>>>> search_path find the correct schema-dependent table. The same does
>>>> not appear to be true for plain sql functions. The 'parser'? does
>>>> not recognize the tables (sans schema qualifier):
>>>>
>>>> ERROR: relation "<tablename>" does not exist.
>>>
>>> You probably need to show example code, because I don't see this:
>>>
>>> show search_path ;
>>> search_path
>>> ------------------------------------------------------------------
>>> public,accounting,history,main,utility,timeclock,table_templates
>>>
>>> \d utility.login_info
>>> Table "utility.login_info"
>>> Column | Type | Collation | Nullable
>>> | Default
>>> -------------+--------------------------------+-----------+----------+------------------
>>>
>>> user_name | character varying | | not null |
>>> user_pwd | character varying | | not null |
>>> user_role | character varying | | |
>>> ts_insert | timestamp(0) without time zone | | | now()
>>> ts_update | timestamp(0) without time zone | | |
>>> user_update | character varying(20) | | |
>>> user_insert | character varying(20) | | |
>>> "session_user"()
>>>
>>>
>>> CREATE FUNCTION getli(varchar) RETURNS login_info AS $$
>>> SELECT * FROM login_info WHERE user_name = $1;
>>> $$ LANGUAGE SQL;
>>>
>>> select * from getli('aklaver');
>>> user_name | user_pwd | user_role | ts_insert | ts_update
>>> | user_update | user_insert
>>> -----------+----------+-----------+---------------------+---------------------+-------------+-------------
>>>
>>> aklaver | ranger | | 12/29/2012 12:23:17 | 05/15/2020
>>> 15:41:14 | | postgres
>>> (1 row)
>>>
>> Isn't "utility" in your path above?
>
> Yes. In your OP you had:
>
> "I can write public plpgsql functions without using a schema
> identifier and let the runtime search_path find the correct
> schema-dependent table. The same does not appear to be true for plain
> sql functions."
>
> I was showing that search_path works with SQL functions, which you
> indicated was not happening for you.
>
> Are you talking about some other case?
>
I'm terribly sorry: I needed to add that plpgsql works without any
knowledge of the schema, where as defining a plain sql functions does
not work without schema qualification.
sarge=# \dn
List of schemas
Name | Owner
--------+----------
base | postgres
bulk | postgres
gt | postgres
public | postgres
sss | postgres
(5 rows)
sarge=# show search_path;
search_path
-----------------
"$user", public
(1 row)
sarge=#
sarge=# create or replace function public.segment_calls(segid uuid)
returns table (name text, firsti int, lasti int, calls text)
as
$$
select
p.name,
s.firstmarker,
s.lastmarker,
regexp_replace(substr(g.calls,1+(2*s.firstmarker),
2*(s.lastmarker-s.firstmarker+1))::text, '(..)', ' \1','g') as calls
from
segment s
join probandset b on s.probandset_id = b.id
join people l on b.people_id = l.id
join people_member m on l.id = m.people_id
join person p on m.person_id = p.id
join genotype g on g.markerset_id = s.markerset_id and g.person_id
= p.id
where s.id = segid;
$$
language sql
;
sarge-# ERROR: relation "segment" does not exist
LINE 11: segment s
^
sarge=# create or replace function public.segment_calls(segid uuid)
returns table (name text, firsti int, lasti int, calls text)
as
$$
begin
select
p.name,
s.firstmarker,
s.lastmarker,
regexp_replace(substr(g.calls,1+(2*s.firstmarker),
2*(s.lastmarker-s.firstmarker+1))::text, '(..)', ' \1','g') as calls
from
segment s
join probandset b on s.probandset_id = b.id
join people l on b.people_id = l.id
join people_member m on l.id = m.people_id
join person p on m.person_id = p.id
join genotype g on g.markerset_id = s.markerset_id and g.person_id
= p.id
where s.id = segid;
end;
$$
language plpgsql;
sarge-# CREATE FUNCTION
sarge=# Query buffer reset (cleared).
sarge=# \dt gt.*
List of relations
Schema | Name | Type | Owner
--------+-------------------------+-------+----------
gt | chaseable | table | postgres
gt | duo_chaseable | table | postgres
gt | genotype | table | postgres
gt | ld | table | postgres
gt | probandset | table | postgres
gt | probandset_group | table | postgres
gt | probandset_group_member | table | postgres
gt | process | table | postgres
gt | process_arg | table | postgres
gt | process_input | table | postgres
gt | process_output | table | postgres
gt | projectfile | table | postgres
gt | segment | table | postgres
gt | segmentset | table | postgres
gt | threshold | table | postgres
gt | threshold_duo_segment | table | postgres
gt | threshold_segment | table | postgres
(17 rows)
From | Date | Subject | |
---|---|---|---|
Next Message | David G. Johnston | 2020-05-15 23:16:54 | Re: schema agnostic functions in language sql |
Previous Message | Michael Nolan | 2020-05-15 23:01:43 | Re: Inherited an 18TB DB & need to backup |