Various EPAS/PG11 function & procedure fixes. Fixes #3421. Fixes #3422

This commit is contained in:
Akshay Joshi 2018-06-25 14:58:02 +01:00 committed by Dave Page
parent 1f5ca1b540
commit 4a71c6d7af
23 changed files with 486 additions and 2 deletions

View File

@ -0,0 +1,20 @@
SELECT
funcname AS {{ conn|qtIdent(_('Name')) }},
calls AS {{ conn|qtIdent(_('Number of calls')) }},
total_time AS {{ conn|qtIdent(_('Total time')) }},
self_time AS {{ conn|qtIdent(_('Self time')) }}
FROM
pg_stat_user_functions
WHERE
schemaname = {{schema_name|qtLiteral}}
AND funcid IN (
SELECT p.oid
FROM
pg_proc p
JOIN
pg_type typ ON typ.oid=p.prorettype
WHERE
p.prokind IN ('f', 'w')
AND typname NOT IN ('trigger', 'event_trigger')
)
ORDER BY funcname;

View File

@ -0,0 +1,22 @@
{% if scid and fnid %}
SELECT
pr.proname as name, '(' || COALESCE(pg_catalog
.pg_get_function_identity_arguments(pr.oid), '') || ')' as func_args,
nspname
FROM
pg_proc pr
JOIN
pg_type typ ON typ.oid=prorettype
JOIN
pg_namespace nsp ON nsp.oid=pr.pronamespace
WHERE
pr.prokind IN ('f', 'w')
AND pronamespace = {{scid}}::oid
AND typname NOT IN ('trigger', 'event_trigger')
AND pr.oid = {{fnid}};
{% endif %}
{% if name %}
DROP FUNCTION {{ conn|qtIdent(nspname, name) }}{{func_args}}{% if cascade %} CASCADE{% endif %};
{% endif %}

View File

@ -0,0 +1,15 @@
SELECT
pg_get_functiondef({{fnid}}::oid) AS func_def,
COALESCE(pg_catalog.pg_get_function_identity_arguments(pr.oid), '') as
func_with_identity_arguments,
nspname,
pr.proname as proname,
COALESCE(pg_catalog.pg_get_function_arguments(pr.oid), '') as func_args
FROM
pg_proc pr
JOIN
pg_namespace nsp ON nsp.oid=pr.pronamespace
WHERE
pr.prokind IN ('f', 'w')
AND pronamespace = {{scid}}::oid
AND pr.oid = {{fnid}}::oid;

View File

@ -0,0 +1,17 @@
SELECT
pr.oid, pr.proname || '(' || COALESCE(pg_catalog
.pg_get_function_identity_arguments(pr.oid), '') || ')' as name,
lanname, pg_get_userbyid(proowner) as funcowner, pr.pronamespace as nsp
FROM
pg_proc pr
JOIN
pg_type typ ON typ.oid=prorettype
JOIN
pg_language lng ON lng.oid=prolang
JOIN
pg_namespace nsp ON nsp.oid=pr.pronamespace
AND nsp.nspname={{ nspname|qtLiteral }}
WHERE
pr.prokind IN ('f', 'w')
AND typname NOT IN ('trigger', 'event_trigger')
AND pr.proname = {{ name|qtLiteral }};

View File

@ -0,0 +1,23 @@
SELECT
pr.oid, pr.proname || '(' || COALESCE(pg_catalog.pg_get_function_identity_arguments(pr.oid), '') || ')' AS name,
lanname, pg_get_userbyid(proowner) AS funcowner, description
FROM
pg_proc pr
JOIN
pg_type typ ON typ.oid=prorettype
JOIN
pg_language lng ON lng.oid=prolang
LEFT OUTER JOIN
pg_description des ON (des.objoid=pr.oid AND des.classoid='pg_proc'::regclass)
WHERE
pr.prokind IN ('f', 'w')
AND pr.protype = '0'::char
{% if fnid %}
AND pr.oid = {{ fnid|qtLiteral }}
{% endif %}
{% if scid %}
AND pronamespace = {{scid}}::oid
{% endif %}
AND typname NOT IN ('trigger', 'event_trigger')
ORDER BY
proname;

View File

@ -0,0 +1,32 @@
SELECT
pr.oid, pr.xmin, pr.*, pr.prosrc AS prosrc_c,
pr.proname AS name, pg_get_function_result(pr.oid) AS prorettypename,
typns.nspname AS typnsp, lanname, proargnames, oidvectortypes(proargtypes) AS proargtypenames,
pg_get_expr(proargdefaults, 'pg_catalog.pg_class'::regclass) AS proargdefaultvals,
pronargdefaults, proconfig, pg_get_userbyid(proowner) AS funcowner, description,
(SELECT
array_agg(provider || '=' || label)
FROM
pg_seclabel sl1
WHERE
sl1.objoid=pr.oid) AS seclabels
FROM
pg_proc pr
JOIN
pg_type typ ON typ.oid=prorettype
JOIN
pg_namespace typns ON typns.oid=typ.typnamespace
JOIN
pg_language lng ON lng.oid=prolang
LEFT OUTER JOIN
pg_description des ON (des.objoid=pr.oid AND des.classoid='pg_proc'::regclass)
WHERE
pr.prokind IN ('f', 'w')
AND typname NOT IN ('trigger', 'event_trigger')
{% if fnid %}
AND pr.oid = {{fnid}}::oid
{% else %}
AND pronamespace = {{scid}}::oid
{% endif %}
ORDER BY
proname;

View File

@ -0,0 +1,20 @@
SELECT
funcname AS {{ conn|qtIdent(_('Name')) }},
calls AS {{ conn|qtIdent(_('Number of calls')) }},
total_time AS {{ conn|qtIdent(_('Total time')) }},
self_time AS {{ conn|qtIdent(_('Self time')) }}
FROM
pg_stat_user_functions
WHERE
schemaname = {{schema_name|qtLiteral}}
AND funcid IN (
SELECT p.oid
FROM
pg_proc p
JOIN
pg_type typ ON typ.oid=p.prorettype
WHERE
p.prokind = 'p'::char
AND typname NOT IN ('trigger', 'event_trigger')
)
ORDER BY funcname;

View File

@ -0,0 +1,21 @@
{% if scid and fnid %}
SELECT
pr.proname as name, '(' || COALESCE(pg_catalog
.pg_get_function_identity_arguments(pr.oid), '') || ')' as func_args,
nspname
FROM
pg_proc pr
JOIN
pg_type typ ON typ.oid=prorettype
JOIN
pg_namespace nsp ON nsp.oid=pr.pronamespace
WHERE
pr.prokind = 'p'::char
AND pronamespace = {{scid}}::oid
AND typname NOT IN ('trigger', 'event_trigger')
AND pr.oid = {{fnid}};
{% endif %}
{% if name %}
DROP PROCEDURE {{ conn|qtIdent(nspname, name) }};
{% endif %}

View File

@ -0,0 +1,15 @@
SELECT
pg_get_functiondef({{fnid}}::oid) AS func_def,
COALESCE(pg_catalog.pg_get_function_identity_arguments(pr.oid), '') as
func_with_identity_arguments,
nspname,
pr.proname as proname,
COALESCE(pg_catalog.pg_get_function_arguments(pr.oid), '') as func_args
FROM
pg_proc pr
JOIN
pg_namespace nsp ON nsp.oid=pr.pronamespace
WHERE
pr.prokind = 'p'::char
AND pronamespace = {{scid}}::oid
AND pr.oid = {{fnid}}::oid;

View File

@ -0,0 +1,17 @@
SELECT
pr.oid, pr.proname || '(' || COALESCE(pg_catalog
.pg_get_function_identity_arguments(pr.oid), '') || ')' as name,
lanname, pg_get_userbyid(proowner) as funcowner, pr.pronamespace AS nsp
FROM
pg_proc pr
JOIN
pg_type typ ON typ.oid=prorettype
JOIN
pg_language lng ON lng.oid=prolang
JOIN
pg_namespace nsp ON nsp.oid=pr.pronamespace
AND nsp.nspname={{ nspname|qtLiteral }}
WHERE
pr.prokind = 'p'::char
AND typname NOT IN ('trigger', 'event_trigger')
AND pr.proname = {{ name|qtLiteral }};

View File

@ -0,0 +1,29 @@
SELECT
pr.oid,
CASE WHEN
pg_catalog.pg_get_function_identity_arguments(pr.oid) <> ''
THEN
pr.proname || '(' || pg_catalog.pg_get_function_identity_arguments(pr.oid) || ')'
ELSE
pr.proname
END AS name,
lanname, pg_get_userbyid(proowner) AS funcowner, description
FROM
pg_proc pr
JOIN
pg_type typ ON typ.oid=prorettype
JOIN
pg_language lng ON lng.oid=prolang
LEFT OUTER JOIN
pg_description des ON (des.objoid=pr.oid AND des.classoid='pg_proc'::regclass)
WHERE
pr.prokind = 'p'::char
{% if fnid %}
AND pr.oid = {{ fnid|qtLiteral }}
{% endif %}
{% if scid %}
AND pronamespace = {{scid}}::oid
{% endif %}
AND typname NOT IN ('trigger', 'event_trigger')
ORDER BY
proname;

View File

@ -0,0 +1,39 @@
SELECT
pr.oid, pr.xmin, pr.*, pr.prosrc AS prosrc_c,
pr.proname AS name, pg_get_function_result(pr.oid) AS prorettypename,
typns.nspname AS typnsp, lanname, proargnames, oidvectortypes(proargtypes) AS proargtypenames,
pg_get_expr(proargdefaults, 'pg_catalog.pg_class'::regclass) AS proargdefaultvals,
pronargdefaults, proconfig, pg_get_userbyid(proowner) AS funcowner, description,
(CASE WHEN
pg_catalog.pg_get_function_identity_arguments(pr.oid) <> ''
THEN
pr.proname || '(' || pg_catalog.pg_get_function_identity_arguments(pr.oid) || ')'
ELSE
pr.proname
END) AS name_with_args,
(SELECT
array_agg(provider || '=' || label)
FROM
pg_seclabel sl1
WHERE
sl1.objoid=pr.oid) AS seclabels
FROM
pg_proc pr
JOIN
pg_type typ ON typ.oid=prorettype
JOIN
pg_namespace typns ON typns.oid=typ.typnamespace
JOIN
pg_language lng ON lng.oid=prolang
LEFT OUTER JOIN
pg_description des ON (des.objoid=pr.oid AND des.classoid='pg_proc'::regclass)
WHERE
pr.prokind = 'p'::char
AND typname NOT IN ('trigger', 'event_trigger')
{% if fnid %}
AND pr.oid = {{fnid}}::oid
{% else %}
AND pronamespace = {{scid}}::oid
{% endif %}
ORDER BY
proname;

View File

@ -0,0 +1,20 @@
SELECT
funcname AS {{ conn|qtIdent(_('Name')) }},
calls AS {{ conn|qtIdent(_('Number of calls')) }},
total_time AS {{ conn|qtIdent(_('Total time')) }},
self_time AS {{ conn|qtIdent(_('Self time')) }}
FROM
pg_stat_user_functions
WHERE
schemaname = {{schema_name|qtLiteral}}
AND funcid IN (
SELECT p.oid
FROM
pg_proc p
JOIN
pg_type typ ON typ.oid=p.prorettype
WHERE
p.prokind IN ('f', 'w')
AND typname = 'trigger'
)
ORDER BY funcname;

View File

@ -0,0 +1,21 @@
{% if scid and fnid %}
SELECT
pr.proname as name, '(' || COALESCE(pg_catalog
.pg_get_function_identity_arguments(pr.oid), '') || ')' as func_args,
nspname
FROM
pg_proc pr
JOIN
pg_type typ ON typ.oid=prorettype
JOIN
pg_namespace nsp ON nsp.oid=pr.pronamespace
WHERE
pr.prokind IN ('f', 'w')
AND pronamespace = {{scid}}::oid
AND typname = 'trigger'
AND pr.oid = {{fnid}};
{% endif %}
{% if name %}
DROP FUNCTION {{ conn|qtIdent(nspname, name) }}{{func_args}}{% if cascade %} CASCADE{% endif %};
{% endif %}

View File

@ -0,0 +1,15 @@
SELECT
pg_get_functiondef({{fnid}}::oid) AS func_def,
COALESCE(pg_catalog.pg_get_function_identity_arguments(pr.oid), '') as
func_with_identity_arguments,
nspname,
pr.proname as proname,
COALESCE(pg_catalog.pg_get_function_arguments(pr.oid), '') as func_args
FROM
pg_proc pr
JOIN
pg_namespace nsp ON nsp.oid=pr.pronamespace
WHERE
pr.prokind IN ('f', 'w')
AND pronamespace = {{scid}}::oid
AND pr.oid = {{fnid}}::oid;

View File

@ -0,0 +1,18 @@
SELECT
pr.oid, pr.proname || '(' || COALESCE(pg_catalog
.pg_get_function_identity_arguments(pr.oid), '') || ')' as name,
lanname, pg_get_userbyid(proowner) as funcowner, pr.pronamespace AS nsp
FROM
pg_proc pr
JOIN
pg_type typ ON typ.oid=prorettype
JOIN
pg_language lng ON lng.oid=prolang
JOIN
pg_namespace nsp ON nsp.oid=pr.pronamespace
AND nsp.nspname={{ nspname|qtLiteral }}
WHERE
pr.prokind IN ('f', 'w')
AND typname IN ('trigger', 'event_trigger')
AND lanname NOT IN ('edbspl', 'sql', 'internal')
AND pr.proname = {{ name|qtLiteral }};

View File

@ -0,0 +1,22 @@
SELECT
pr.oid, pr.proname || '()' AS name,
lanname, pg_get_userbyid(proowner) AS funcowner, description
FROM
pg_proc pr
JOIN
pg_type typ ON typ.oid=prorettype
JOIN
pg_language lng ON lng.oid=prolang
LEFT OUTER JOIN
pg_description des ON (des.objoid=pr.oid AND des.classoid='pg_proc'::regclass)
WHERE
pr.prokind IN ('f', 'w')
{% if fnid %}
AND pr.oid = {{ fnid|qtLiteral }}
{% endif %}
{% if scid %}
AND pronamespace = {{scid}}::oid
{% endif %}
AND typname = 'trigger' AND lanname != 'edbspl'
ORDER BY
proname;

View File

@ -0,0 +1,32 @@
SELECT
pr.oid, pr.xmin, pr.*, pr.prosrc AS prosrc_c,
pr.proname AS name, pg_get_function_result(pr.oid) AS prorettypename,
typns.nspname AS typnsp, lanname, proargnames, oidvectortypes(proargtypes) AS proargtypenames,
pg_get_expr(proargdefaults, 'pg_catalog.pg_class'::regclass) AS proargdefaultvals,
pronargdefaults, proconfig, pg_get_userbyid(proowner) AS funcowner, description,
(SELECT
array_agg(provider || '=' || label)
FROM
pg_seclabel sl1
WHERE
sl1.objoid=pr.oid) AS seclabels
FROM
pg_proc pr
JOIN
pg_type typ ON typ.oid=prorettype
JOIN
pg_namespace typns ON typns.oid=typ.typnamespace
JOIN
pg_language lng ON lng.oid=prolang
LEFT OUTER JOIN
pg_description des ON (des.objoid=pr.oid AND des.classoid='pg_proc'::regclass)
WHERE
pr.prokind IN ('f', 'w')
AND typname = 'trigger' AND lanname != 'edbspl'
{% if fnid %}
AND pr.oid = {{fnid}}::oid
{% else %}
AND pronamespace = {{scid}}::oid
{% endif %}
ORDER BY
proname;

View File

@ -81,6 +81,8 @@ class PartitionsModule(CollectionNodeModule):
super(PartitionsModule, self).__init__(*args, **kwargs)
self.min_ver = 100000
self.max_ver = None
self.min_ppasver = 100000
self.max_ppasver = None
def get_nodes(self, gid, sid, did, scid, **kwargs):
"""

View File

@ -0,0 +1,30 @@
{# ============= Fetch the list of functions based on given schema_names ============= #}
{% if func_name %}
SELECT n.nspname schema_name,
p.proname func_name,
pg_catalog.pg_get_function_arguments(p.oid) arg_list,
pg_catalog.pg_get_function_result(p.oid) return_type,
CASE WHEN p.prokind = 'a' THEN true ELSE false END is_aggregate,
CASE WHEN p.prokind = 'w' THEN true ELSE false END is_window,
p.proretset is_set_returning
FROM pg_catalog.pg_proc p
INNER JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace
WHERE n.nspname = '{{schema_name}}' AND p.proname = '{{func_name}}'
AND p.proretset
ORDER BY 1, 2
{% else %}
SELECT n.nspname schema_name,
p.proname object_name,
pg_catalog.pg_get_function_arguments(p.oid) arg_list,
pg_catalog.pg_get_function_result(p.oid) return_type,
CASE WHEN p.prokind = 'a' THEN true ELSE false END is_aggregate,
CASE WHEN p.prokind = 'w' THEN true ELSE false END is_window,
p.proretset is_set_returning
FROM pg_catalog.pg_proc p
INNER JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace
WHERE n.nspname IN ({{schema_names}})
{% if is_set_returning %}
AND p.proretset
{% endif %}
ORDER BY 1, 2
{% endif %}

View File

@ -240,9 +240,11 @@ def properties(sid, did, node_id, node_type):
res_data.extend(res['rows'])
# Fetch procedures only if server type is ppas
# Fetch procedures only if server type is EPAS or PG >= 11
if (len(server_prop) > 0 and
server_prop['server_type'] == 'ppas' and
(server_prop['server_type'] == 'ppas' or
(server_prop['server_type'] == 'pg' and
server_prop['version'] >= 11000)) and
ntype in ['schema', 'procedure']):
SQL = render_template("/".join(
[server_prop['template_path'], '/sql/function.sql']),

View File

@ -0,0 +1,26 @@
{# ===== Fetch list of Database object types(Functions) ====== #}
{% if type and node_id %}
{% set func_type = 'Trigger Function' if type == 'trigger_function' else 'Procedure' if type == 'procedure' else 'Function' %}
{% set icon = 'icon-function' if type == 'function' else 'icon-procedure' if type == 'procedure' else 'icon-trigger_function' %}
{% set kind = 'p' if type == 'procedure' else 'f' %}
SELECT
pr.oid,
pg_get_function_identity_arguments(pr.oid) AS proargs,
pr.proname AS name,
nsp.nspname AS nspname,
'{{ func_type }}' AS object_type,
'{{ icon }}' AS icon
FROM
pg_proc pr
JOIN pg_namespace nsp ON nsp.oid=pr.pronamespace
JOIN pg_type typ ON typ.oid=prorettype
JOIN pg_namespace typns ON typns.oid=typ.typnamespace
JOIN pg_language lng ON lng.oid=prolang
LEFT OUTER JOIN pg_description des ON (des.objoid=pr.oid AND des.classoid='pg_proc'::regclass)
WHERE
pronamespace = {{ node_id }}::oid
AND typname {{ 'NOT' if type != 'trigger_function' else '' }} IN ('trigger', 'event_trigger')
AND pr.prokind = '{{ kind }}'
ORDER BY
proname
{% endif %}

View File

@ -0,0 +1,26 @@
{# ===== Fetch list of Database object types(Functions) ====== #}
{% if type and node_id %}
{% set func_type = 'Trigger Function' if type == 'trigger_function' else 'Procedure' if type == 'procedure' else 'Function' %}
{% set icon = 'icon-function' if type == 'function' else 'icon-procedure' if type == 'procedure' else 'icon-trigger_function' %}
{% set kind = 'p' if type == 'procedure' else 'f' %}
SELECT
pr.oid,
pg_get_function_identity_arguments(pr.oid) AS proargs,
pr.proname AS name,
nsp.nspname AS nspname,
'{{ func_type }}' AS object_type,
'{{ icon }}' AS icon
FROM
pg_proc pr
JOIN pg_namespace nsp ON nsp.oid=pr.pronamespace
JOIN pg_type typ ON typ.oid=prorettype
JOIN pg_namespace typns ON typns.oid=typ.typnamespace
JOIN pg_language lng ON lng.oid=prolang
LEFT OUTER JOIN pg_description des ON (des.objoid=pr.oid AND des.classoid='pg_proc'::regclass)
WHERE
pronamespace = {{ node_id }}::oid
AND typname {{ 'NOT' if type != 'trigger_function' else '' }} IN ('trigger', 'event_trigger')
AND pr.prokind = '{{ kind }}'
ORDER BY
proname
{% endif %}