2

I have wrote this method on postgresql 10 :

create or replace function get_users()
  returns TABLE(user_idd uuid, device_idd text, shapee text , datee timestamp) AS
$$
begin
  create temp table lines as
    SELECT DISTINCT user_id, device_id from olocations;
  select uuid_generate_v4(),
         o1.user_id,
         o1.device_id,
         st_astext(ST_Collect(o1.shape)),
         date(o1.creation_date_time) as date
  from olocations o1
      inner join lines on o1. device_id = lines.device_id and o1.user_id = lines.user_id
    where o1.user_id = 'd0edfc59-9923-44c3-9c34-ef5aad3cb810'
    and o1.device_id = '89984320001811791540'
group by o1.user_id, o1.device_id, date
order by date ASC ;
DROP TABLE lines;
end
$$
LANGUAGE 'plpgsql'
IMMUTABLE
SECURITY DEFINER
COST 100;

After create method without any problem, when i call my method: select * from get_users(); I got this error:

sql> select  from get_users()
[2018-09-30 17:23:23] [0A000] ERROR: CREATE TABLE AS is not allowed in a non-volatile function
[2018-09-30 17:23:23] Where: SQL statement "create temp table lines as
[2018-09-30 17:23:23] SELECT DISTINCT user_id, device_id from olocations"
[2018-09-30 17:23:23] PL/pgSQL function get_users() line 3 at SQL statement

I think i can not create table in method? right?

Cyrus the Great
  • 5,145
  • 5
  • 68
  • 149

1 Answers1

7

The function cannot be IMMUTABLE, define it as VOLATILE.

Per the documentation:

Any function with side-effects must be labeled VOLATILE, so that calls to it cannot be optimized away.

In this case this side-effect is the table creation.


Update.

Use return query to return rows generated by the query:

  ...
  return query  
  select uuid_generate_v4(),
         o1.user_id,
         o1.device_id,
         st_astext(ST_Collect(o1.shape)),
         date(o1.creation_date_time) as date
  ...
klin
  • 112,967
  • 15
  • 204
  • 232
  • Thank's dude i changed and method is created but after calling method i got `[42601] ERROR: query has no destination for result data Hint: If you want to discard the results of a SELECT, use PERFORM instead. Where: PL/pgSQL function get_users() line 5 at SQL statement` @klin – Cyrus the Great Oct 01 '18 at 06:07