could you please let me know, how can i get the function executed client(single client only) details inside the PL/pgSQL function(something $whoexecuted). i'm getting the current all active client details.
as per the following code.
begin
select ps.usename, ps.client_addr,ps.application_name from pg_stat_activity ps
where state = 'active'
and ps.usename in('user1') into pg_stat_activity_rowtype
;
The content of pg_stat_activity is available from PLpgSQL too. So you can use
do $$
declare r record;
begin
for r in select * from pg_stat_activity where pid = pg_backend_pid()
loop
raise notice '%', r;
end loop;
end;
$$;
These data can be collected from some source:
select current_user, session_user, current_database(), inet_client_addr(), current_setting('application_name');
┌──────────────┬──────────────┬──────────────────┬──────────────────┬─────────────────┐
│ current_user │ session_user │ current_database │ inet_client_addr │ current_setting │
╞══════════════╪══════════════╪══════════════════╪══════════════════╪═════════════════╡
│ pavel │ pavel │ postgres │ │ psql │
└──────────────┴──────────────┴──────────────────┴──────────────────┴─────────────────┘
(1 row)
More in documentation:
https://www.postgresql.org/docs/current/static/functions-admin.html
https://www.postgresql.org/docs/current/static/functions-info.html
Related
What is the data type of column_name in information_schema.columns?
i tried this but didnt get
code:
CREATE OR REPLACE FUNCTION table_name_sunitest118(
tbl character varying)
RETURNS TABLE(column_name text)
LANGUAGE 'plpgsql'
AS $BODY$
BEGIN
RETURN QUERY
EXECUTE FORMAT('SELECT column_name FROM information_schema.columns where table_name=$1')
using tbl;
END
$BODY$;
In general you can use pg_typeof() to get that information:
select pg_typeof(column_name) from information_schema.columns limit 1;
┌───────────────────────────────────┐
│ pg_typeof │
├───────────────────────────────────┤
│ information_schema.sql_identifier │
└───────────────────────────────────┘
(1 row)
The type is sql_identifier, and you can cast it to text with column_name::text in your function.
CREATE OR REPLACE FUNCTION table_name_sunitest118(
tbl character varying)
RETURNS TABLE(column_name text)
LANGUAGE 'plpgsql'
AS $BODY$
BEGIN
RETURN QUERY
EXECUTE FORMAT(
'SELECT column_name::text FROM information_schema.columns where table_name=$1'
) using tbl;
END
$BODY$;
CREATE FUNCTION
select * from table_name_sunitest118('users');
┌─────────────┐
│ column_name │
├─────────────┤
│ email │
│ pass │
│ role │
│ id │
│ email │
└─────────────┘
(5 rows)
In MySQL, describe information_schema.columns says varchar(64).
The Postgres docs for the columns table says it is a sql_identifier defined as...
A character string. This type is used for SQL identifiers, the type character_data is used for any other kind of text data.
In psql you can use \gdesc command. It shows type on client side.
postgres=# select column_name from information_schema.columns \gdesc
┌─────────────┬──────┐
│ Column │ Type │
╞═════════════╪══════╡
│ column_name │ name │
└─────────────┴──────┘
(1 row)
pg_typeof function shows type on server side
postgres=# select pg_typeof(column_name) from information_schema.columns limit 1;
┌───────────────────────────────────┐
│ pg_typeof │
╞═══════════════════════════════════╡
│ information_schema.sql_identifier │
└───────────────────────────────────┘
(1 row)
I am setting a session variable inside a postgres function and the values are not getting set.
Any help is most appreciated. Thanks in advance.
I am using "PostgreSQL 10.6, compiled by Visual C++ build 1800, 64-bit"
My code is as follows:
The function:
CREATE FUNCTION set_rp_vals(iv_rp_company varchar, iv_rp_portfolio varchar)
RETURNS integer
LANGUAGE plpgsql
SECURITY DEFINER
AS $function$
DECLARE
l_retval integer;
BEGIN
l_retval := 1;
RAISE NOTICE '1.iv_rp_company: >>> %', iv_rp_company;
RAISE NOTICE '2.iv_rp_portfolio: >>> %', iv_rp_portfolio;
--set the session variable
set rp.company = iv_rp_company;
set rp.portfolio = iv_rp_portfolio;
RETURN l_retval;
EXCEPTION
WHEN OTHERS THEN
RETURN 9;
END;
$function$
;
The function call:
SELECT set_rp_vals(iv_rp_company := 'COMPAN',iv_rp_portfolio := 'PORTOF');
--Retrieving the session variables:
select
current_setting('rp.company') as company,
current_setting('rp.portfolio') as portfolio;
The value returned by the above query:
I would use the set_config() function for this:
CREATE OR REPLACE FUNCTION set_rp_vals(iv_rp_company varchar, iv_rp_portfolio varchar)
RETURNS integer
LANGUAGE plpgsql
SECURITY DEFINER
AS $function$
DECLARE
l_retval integer;
BEGIN
l_retval := 1;
RAISE NOTICE '1.iv_rp_company: >>> %', iv_rp_company;
RAISE NOTICE '2.iv_rp_portfolio: >>> %', iv_rp_portfolio;
--set the session variable
perform set_config('rp.company', iv_rp_company, false);
perform set_config('rp.portfolio', iv_rp_portfolio, false);
RETURN l_retval;
EXCEPTION
WHEN OTHERS THEN
RETURN 9;
END;
$function$
;
CREATE FUNCTION
Execute with your values:
SELECT set_rp_vals(iv_rp_company := 'COMPAN',iv_rp_portfolio := 'PORTOF');
NOTICE: 1.iv_rp_company: >>> COMPAN
NOTICE: 2.iv_rp_portfolio: >>> PORTOF
┌─────────────┐
│ set_rp_vals │
├─────────────┤
│ 1 │
└─────────────┘
(1 row)
select
current_setting('rp.company') as company,
current_setting('rp.portfolio') as portfolio;
┌─────────┬───────────┐
│ company │ portfolio │
├─────────┼───────────┤
│ COMPAN │ PORTOF │
└─────────┴───────────┘
(1 row)
I need to pass dynamic number of parameters to a function as well as their data types and then return a table having those parameters as fields.
Is that possible to do that in postgres?
Any idea or example is appreciated
Here is an example that could probably be improved.
Beware of SQL injection!
CREATE OR REPLACE FUNCTION create_table(
tabname text,
VARIADIC coldef text[]
) RETURNS void
LANGUAGE plpgsql STRICT AS
$$DECLARE
l integer;
i integer;
sql text;
sep text := '';
BEGIN
l := array_upper(coldef, 1);
IF l % 2 <> 0 THEN
RAISE EXCEPTION 'Number of arguments must be odd';
END IF;
sql := 'CREATE TABLE ' || quote_ident(tabname) || '(';
FOR i IN 1 .. l/2 LOOP
sql := sql || sep || quote_ident(coldef[2*i-1]) || ' ' || quote_ident(coldef[2*i]);
sep := ', ';
END LOOP;
sql := sql || ')';
EXECUTE sql;
END;$$;
It can be used like this:
test=> SELECT create_table('tabname', 'col1', 'int4', 'col2', 'text');
test=> \d tabname
Table "laurenz.tabname"
┌────────┬─────────┬───────────┐
│ Column │ Type │ Modifiers │
├────────┼─────────┼───────────┤
│ col1 │ integer │ │
│ col2 │ text │ │
└────────┴─────────┴───────────┘
I have a Table "A" with one column "col1" where each record is a array of integers.
col1
-----
{1,2,3,4}
{1,2,6,7}
{1,2,3,8,9}
I like to have one row as result which contains the overlap or intersect of all arrays in "col1".
select overlap(col1) from A;
result
-----
{1,2}
You should to define custom aggregate for this purpose:
CREATE OR REPLACE FUNCTION public.overlap_array_aggregate(anyarray, anyarray)
RETURNS anyarray
LANGUAGE plpgsql STRICT
AS $function$
BEGIN
RETURN ARRAY(SELECT unnest($1) INTERSECT SELECT unnest($2));
END;
$function$
CREATE AGGREGATE array_overlap_agg (
basetype = anyarray,
sfunc = overlap_array_aggregate,
stype = anyarray );
Then it is working as you expect:
postgres=# SELECT * FROM foo;
┌─────────────┐
│ a │
╞═════════════╡
│ {1,2,3,4} │
│ {1,2,6,7} │
│ {1,2,3,8,9} │
└─────────────┘
(3 rows)
postgres=# SELECT array_overlap_agg(a) FROM foo;
┌───────────────────┐
│ array_overlap_agg │
╞═══════════════════╡
│ {1,2} │
└───────────────────┘
(1 row)
I need to join the max(id) with is a bigint (and a primary key) from one table to another table. So, if the max id is 1234567890, then I would want the results to be:
name, max_id
'foo', 1234567890
'bar', 1234567890
'noo', 1234567890
'boo', 1234567890
'zoo', 1234567890
My first thought was just to write a function and market it as STABLE
CREATE OR REPLACE FUNCTION get_max_id() RETURNS bigint AS
$$
DECLARE
result bigint;
BEGIN
RAISE NOTICE 'entering get_max_id';
SELECT INTO result max(id) FROM mytable;
RETURN result;
END;
$$
LANGUAGE plpgsql STABLE;
Then I called it via a SQL statement like:
SELECT name, get_max_id() FROM a_really_big_table;
But, from my raise notice, it seems like this is getting called for each each record in a_really_big_table.
What is the best way to write this so that I can keep the PostgreSQL from doing a lookup on mytable for each row in a_really_big_table?
I'm using PostgreSQL 9.4.1
Could it be a solution?
=# SELECT name AS name,
(SELECT MAX(id) FROM your_table) AS max_id
FROM really_big_table;
name │ max_id
──────────────────┼─────────
44e5f8fc1f75fad2 │ 5307021
97fc0aa3a5e3da98 │ 5307021
ccb83afb938ad758 │ 5307021
523bf25914e5c9c0 │ 5307021
d2362badeb2eb7ea │ 5307021
b6e0b87df6d41523 │ 5307021
da754db1fa226453 │ 5307021
865d0e177cb0a3e8 │ 5307021
5904a07a273d8cba │ 5307021
952c75ef37d47dab │ 5307021
(10 rows)