Add support for functions and procedures.

This commit is contained in:
Khushboo Vashi 2016-04-05 16:14:10 +01:00 committed by Dave Page
parent 40165f2d1e
commit 5ed7015ebc
125 changed files with 4972 additions and 0 deletions

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 349 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 337 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 325 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 322 B

View File

@ -0,0 +1,3 @@
.functions_code {
height: 130px !important;
}

View File

@ -0,0 +1,482 @@
/* Create and Register Function Collection and Node. */
define(
['jquery', 'underscore', 'underscore.string',
'pgadmin', 'pgadmin.browser', 'alertify',
'pgadmin.browser.collection', 'pgadmin.browser.server.privilege'],
function($, _, S, pgAdmin, pgBrowser, alertify) {
if (!pgBrowser.Nodes['coll-function']) {
var functions = pgAdmin.Browser.Nodes['coll-function'] =
pgAdmin.Browser.Collection.extend({
node: 'function',
label: '{{ _('Functions') }}',
type: 'coll-function',
columns: ['name', 'funcowner', 'description']
});
};
// Security Model
var SecurityModel = Backform.SecurityModel = pgAdmin.Browser.Node.Model.extend({
defaults: {
provider: null,
label: null
},
schema: [{
id: 'provider', label: '{{ _('Provider') }}',
type: 'text', editable: true, cellHeaderClasses:'width_percent_50'
},{
id: 'security_label', label: '{{ _('Security Label') }}',
type: 'text', editable: true, cellHeaderClasses:'width_percent_50'
}],
validate: function() {
var err = {},
errmsg = null,
data = this.toJSON();
if (_.isUndefined(data.label) ||
_.isNull(data.label) ||
String(data.label).replace(/^\s+|\s+$/g, '') == '') {
return _("Please specify the value for all the security providers.");
}
return null;
}
});
// Argument Model
var ArgumentModel = pgAdmin.Browser.Node.Model.extend({
idAttribute: 'argid',
defaults: {
argid: undefined,
argtype: undefined,
argmode: undefined,
argname: undefined,
argdefval: undefined
},
schema: [{
id: 'argid', visible: false, type: 'text',
mode: ['properties', 'edit','create']
},{
id: 'argtype', label:'{{ _('Data Type') }}', cell:
'node-ajax-options', cellHeaderClasses: 'width_percent_30',
control: 'node-ajax-options', type: 'text', url: 'get_types',
editable: function(m) {
node_info = this.get('node_info');
if(node_info && 'catalog' in node_info) {
return false;
}
return _.isUndefined(m.isNew) ? true : m.isNew();
}, first_empty: true
},{
id: 'argmode', label:'{{ _('Mode') }}', type: 'options',
control: 'node-ajax-options', cellHeaderClasses:'width_percent_20',
options:[
{'label': 'IN', 'value': 'IN'},
{'label': 'OUT', 'value': 'OUT'},
{'label': 'INOUT', 'value': 'INOUT'},
{'label': 'VARIADIC', 'value': 'VARIADIC'}
], editable: function(m) {
node_info = this.get('node_info');
if(node_info && 'catalog' in node_info) {
return false;
}
return _.isUndefined(m.isNew) ? true : m.isNew();
}
},{
id: 'argname', label:'{{ _('Argument Name') }}', type: 'text',
cell: 'string', editable: 'isInCatalog', cellHeaderClasses:'width_percent_30'
},{
id: 'argdefval', label:'{{ _('Default Value') }}', type: 'text',
cell: 'string', editable: 'isInCatalog', cellHeaderClasses:'width_percent_20'
}
],
toJSON: Backbone.Model.prototype.toJSON,
isInCatalog: function(m){
node_info = this.get('node_info');
if(node_info && 'catalog' in node_info) {
return false;
}
return true;
},
});
if (!pgBrowser.Nodes['function']) {
pgAdmin.Browser.Nodes['function'] = pgBrowser.Node.extend({
type: 'function',
label: '{{ _('Function') }}',
collection_type: 'coll-function',
hasSQL: true,
hasDepends: true,
parent_type: ['schema', 'catalog'],
Init: function(args) {
/* Avoid mulitple registration of menus */
if (this.initialized)
return;
this.initialized = true;
pgBrowser.add_menus([{
name: 'create_function_on_coll', node: 'coll-function', module: this,
applies: ['object', 'context'], callback: 'show_obj_properties',
category: 'create', priority: 4, label: '{{ _('Function...') }}',
icon: 'wcTabIcon icon-function', data: {action: 'create', check: true},
enable: 'canCreate'
},{
name: 'create_function', node: 'function', module: this,
applies: ['object', 'context'], callback: 'show_obj_properties',
category: 'create', priority: 4, label: '{{ _('Function...') }}',
icon: 'wcTabIcon icon-function', data: {action: 'create', check: true},
enable: 'canCreate'
},{
name: 'create_function', node: 'schema', module: this,
applies: ['object', 'context'], callback: 'show_obj_properties',
category: 'create', priority: 4, label: '{{ _('Function...') }}',
icon: 'wcTabIcon icon-function', data: {action: 'create', check: false},
enable: 'canCreate'
}
]);
},
canDrop: pgBrowser.Nodes['schema'].canChildDrop,
canDropCascade: pgBrowser.Nodes['schema'].canChildDrop,
model: pgAdmin.Browser.Node.Model.extend({
initialize: function(attrs, args) {
var isNew = (_.size(attrs) === 0);
if (isNew) {
// Set Selected Schema
schema_id = args.node_info.schema._id
this.set({'pronamespace': schema_id}, {silent: true});
// Set Current User
var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
this.set({'funcowner': userInfo.name}, {silent: true});
}
pgAdmin.Browser.Node.Model.prototype.initialize.apply(this, arguments);
},
defaults: {
name: undefined,
oid: undefined,
xmin: undefined,
funcowner: undefined,
pronamespace: undefined,
description: undefined,
pronargs: undefined, /* Argument Count */
proargs: undefined, /* Arguments */
proargtypenames: undefined, /* Argument Signature */
prorettypename: undefined, /* Return Type */
lanname: 'sql', /* Language Name in which function is being written */
provolatile: undefined, /* Volatility */
proretset: undefined, /* Return Set */
proisstrict: undefined,
prosecdef: undefined, /* Security of definer */
proiswindow: undefined, /* Window Function ? */
procost: undefined, /* Estimated execution Cost */
prorows: undefined, /* Estimated number of rows */
proleakproof: undefined,
arguments: [],
prosrc: undefined,
prosrc_c: undefined,
probin: '$libdir/',
options: [],
variables: [],
proacl: undefined,
seclabels: [],
acl: [],
sysfunc: undefined,
sysproc: undefined
},
schema: [{
id: 'name', label: '{{ _('Name') }}', cell: 'string',
type: 'text', mode: ['properties', 'create', 'edit'],
disabled: 'isDisabled'
},{
id: 'oid', label: '{{ _('OID') }}', cell: 'string',
type: 'text' , mode: ['properties']
},{
id: 'funcowner', label: '{{ _('Owner') }}', cell: 'string',
control: Backform.NodeListByNameControl, node: 'role', type:
'text', disabled: 'isDisabled'
},{
id: 'pronamespace', label: '{{ _('Schema') }}', cell: 'string',
control: 'node-list-by-id', type: 'text', cache_level: 'database',
node: 'schema', disabled: 'isDisabled', mode: ['create', 'edit']
},{
id: 'sysfunc', label: '{{ _('System function?') }}',
cell:'boolean', type: 'switch',
mode: ['properties'], visible: 'isVisible'
},{
id: 'sysproc', label: '{{ _('System procedure?') }}',
cell:'boolean', type: 'switch',
mode: ['properties'], visible: 'isVisible'
},{
id: 'description', label: '{{ _('Comment') }}', cell: 'string',
type: 'multiline', disabled: 'isDisabled'
},{
id: 'pronargs', label: '{{ _('Argument count') }}', cell: 'string',
type: 'text', group: '{{ _('Definition') }}', mode: ['properties']
},{
id: 'proargs', label: '{{ _('Arguments') }}', cell: 'string',
type: 'text', group: '{{ _('Definition') }}', mode: ['properties', 'edit'],
disabled: 'isDisabled'
},{
id: 'proargtypenames', label: '{{ _('Signature arguments') }}', cell:
'string', type: 'text', group: '{{ _('Definition') }}', mode: ['properties'],
disabled: 'isDisabled'
},{
id: 'prorettypename', label: '{{ _('Return type') }}', cell: 'string',
control: 'node-ajax-options', type: 'text', group: '{{ _('Definition') }}',
url: 'get_types', disabled: 'isDisabled', first_empty: true,
mode: ['create'], visible: 'isVisible'
},{
id: 'prorettypename', label: '{{ _('Return type') }}', cell: 'string',
type: 'text', group: '{{ _('Definition') }}', disabled: true,
mode: ['properties', 'edit'], disabled: 'isDisabled', visible: 'isVisible'
}, {
id: 'lanname', label: '{{ _('Language') }}', cell: 'string',
control: 'node-ajax-options', type: 'text', group: '{{ _('Definition') }}',
url: 'get_languages', disabled: 'isDisabled'
},{
id: 'prosrc', label: '{{ _('Code') }}', cell: 'string',
type: 'text', mode: ['properties', 'create', 'edit'],
group: '{{ _('Definition') }}', deps: ['lanname'],
control: Backform.SqlFieldControl,
extraClasses:['custom_height_css_class'],
visible: function(m) {
if (m.get('lanname') == 'c') {
return false;
}
return true;
}, disabled: 'isDisabled'
},{
id: 'probin', label: '{{ _('Object file') }}', cell: 'string',
type: 'text', group: '{{ _('Definition') }}', deps: ['lanname'], visible:
function(m) {
if (m.get('lanname') == 'c') { return true; }
return false;
}, disabled: 'isDisabled'
},{
id: 'prosrc_c', label: '{{ _('Link symbol') }}', cell: 'string',
type: 'text', group: '{{ _('Definition') }}', deps: ['lanname'], visible:
function(m) {
if (m.get('lanname') == 'c') { return true; }
return false;
}, disabled: 'isDisabled'
},{
id: 'provolatile', label: '{{ _('Volatility') }}', cell: 'string',
control: 'node-ajax-options', type: 'text', group: '{{ _('Options') }}',
options:[
{'label': 'VOLATILE', 'value': 'v'},
{'label': 'STABLE', 'value': 's'},
{'label': 'IMMUTABLE', 'value': 'i'},
], disabled: 'isDisabled'
},{
id: 'proretset', label: '{{ _('Returns a set?') }}', group: '{{ _('Options') }}',
cell:'boolean', type: 'switch', disabled: 'isDisabled',
visible: 'isVisible'
},{
id: 'proisstrict', label: '{{ _('Strict?') }}', group: '{{ _
('Options') }}',
cell:'boolean', type: 'switch', disabled: 'isDisabled',
options: {
'onText': 'Yes', 'offText': 'No',
'onColor': 'success', 'offColor': 'primary',
'size': 'small'
}
},{
id: 'prosecdef', label: '{{ _('Security of definer?') }}',
group: '{{ _('Options') }}', cell:'boolean', type: 'switch',
disabled: 'isDisabled'
},{
id: 'proiswindow', label: '{{ _('Window?') }}',
group: '{{ _('Options') }}', cell:'boolean', type: 'switch',
disabled: 'isDisabled', visible: 'isVisible'
},{
id: 'procost', label: '{{ _('Estimated cost') }}', group: '{{ _('Options') }}',
cell:'string', type: 'text', disabled: 'isDisabled'
},{
id: 'prorows', label: '{{ _('Estimated rows') }}', group: '{{ _
('Options') }}',
cell:'string', type: 'text', disabled: 'isDisabled',
deps: ['proretset'], visible: 'isVisible'
},{
id: 'proleakproof', label: '{{ _('Leak proof?') }}',
group: '{{ _('Options') }}', cell:'boolean', type: 'switch', min_version: 90200,
disabled: 'isDisabled'
},{
id: 'proacl', label: '{{ _('Privileges') }}',
group: '{{ _('Security') }}', cell:'boolean', type: 'text', cell: 'string',
mode: ['properties']
},{
id: 'arguments', label: '{{ _('Parameters') }}', cell: 'string',
group: '{{ _('Parameters') }}', type: 'collection', canAdd: function(m){
return m.isNew();
},
canDelete: true, model: ArgumentModel, mode: ['create', 'edit'],
columns: ['argtype', 'argmode', 'argname', 'argdefval'],
disabled: 'isDisabled'
},{
id: 'variables', label: '{{ _('Variables') }}', type: 'collection',
group: '{{ _('Variables') }}', control: 'variable-collection',
model: pgAdmin.Browser.Node.VariableModel,
mode: ['edit', 'create'], canAdd: 'canVarAdd', canEdit: false,
canDelete: true, disabled: 'isDisabled'
},{
id: 'acl', label: '{{ _('Privileges') }}', model: pgAdmin
.Browser.Node.PrivilegeRoleModel.extend(
{privileges: ['X']}), uniqueCol : ['grantee', 'grantor'],
editable: false, type: 'collection', group: '{{ _('Security') }}',
mode: ['edit', 'create'],
canAdd: true, canDelete: true, control: 'unique-col-collection',
disabled: 'isDisabled'
},
{
id: 'seclabels', label: '{{ _('Security Labels') }}',
model: SecurityModel, type: 'collection',
group: '{{ _('Security') }}', mode: ['edit', 'create'],
min_version: 90100, canAdd: true,
canEdit: true, canDelete: true,
control: 'unique-col-collection', uniqueCol : ['provider'],
disabled: 'isDisabled'
}
],
validate: function()
{
var err = {},
errmsg,
seclabels = this.get('seclabels');
if (_.isUndefined(this.get('name')) || String(this.get('name')).replace(/^\s+|\s+$/g, '') == '') {
err['name'] = '{{ _('Name can not be empty!') }}';
errmsg = errmsg || err['name'];
}
if (_.isUndefined(this.get('funcowner')) || String(this.get('funcowner')).replace(/^\s+|\s+$/g, '') == '') {
err['funcowner'] = '{{ _('Owner can not be empty!') }}';
errmsg = errmsg || err['funcowner'];
}
if (_.isUndefined(this.get('pronamespace')) || String(this.get('pronamespace')).replace(/^\s+|\s+$/g, '') == '') {
err['pronamespace'] = '{{ _('Schema can not be empty!') }}';
errmsg = errmsg || err['pronamespace'];
}
if (_.isUndefined(this.get('prorettypename')) || String(this.get('prorettypename')).replace(/^\s+|\s+$/g, '') == '') {
err['prorettypename'] = '{{ _('Return Type can not be empty!') }}';
errmsg = errmsg || err['prorettypename'];
}
if (_.isUndefined(this.get('lanname')) || String(this.get('lanname')).replace(/^\s+|\s+$/g, '') == '') {
err['lanname'] = '{{ _('Language can not be empty!') }}';
errmsg = errmsg || err['lanname'];
}
if (String(this.get('lanname')) == 'c') {
if (_.isUndefined(this.get('probin')) || String(this.get('probin'))
.replace(/^\s+|\s+$/g, '') == '') {
err['probin'] = '{{ _('Object File can not be empty!') }}';
errmsg = errmsg || err['probin'];
}
if (_.isUndefined(this.get('prosrc_c')) || String(this.get('prosrc_c')).replace(/^\s+|\s+$/g, '') == '') {
err['prosrc_c'] = '{{ _('Link Symbol can not be empty!') }}';
errmsg = errmsg || err['prosrc_c'];
}
}
else {
if (_.isUndefined(this.get('prosrc')) || String(this.get('prosrc')).replace(/^\s+|\s+$/g, '') == '') {
err['prosrc'] = '{{ _('Code can not be empty!') }}';
errmsg = errmsg || err['prosrc'];
}
}
if (seclabels) {
var secLabelsErr;
for (var i = 0; i < seclabels.models.length && !secLabelsErr; i++) {
secLabelsErr = (seclabels.models[i]).validate.apply(seclabels.models[i]);
if (secLabelsErr) {
err['seclabels'] = secLabelsErr;
errmsg = errmsg || secLabelsErr;
}
}
}
this.errorModel.clear().set(err);
if (_.size(err)) {
this.trigger('on-status', {msg: errmsg});
return errmsg;
}
return null;
},
isVisible: function(m){
if (this.name == 'sysproc') { return false; }
return true;
},
isDisabled: function(m){
if(this.node_info && 'catalog' in this.node_info) {
return true;
}
name = this.name;
switch(name){
case 'proargs':
case 'proargtypenames':
case 'prorettypename':
case 'proretset':
case 'proiswindow':
return !m.isNew();
break;
case 'prorows':
if(m.get('proretset') == true) {
return false;
}
else {
return true;
}
break;
default:
return false;
break;
}
return false;
},
canVarAdd: function(m) {
if(this.node_info && 'catalog' in this.node_info) {
return false;
}
return true;
}
}),
canCreate: function(itemData, item, data) {
//If check is false then , we will allow create menu
if (data && data.check == false)
return true;
var t = pgBrowser.tree, i = item, d = itemData;
// To iterate over tree to check parent node
while (i) {
// If it is schema then allow user to create Function
if (_.indexOf(['schema'], d._type) > -1)
return true;
if ('coll-function' == d._type) {
//Check if we are not child of catalog
prev_i = t.hasParent(i) ? t.parent(i) : null;
prev_d = prev_i ? t.itemData(prev_i) : null;
if( prev_d._type == 'catalog') {
return false;
} else {
return true;
}
}
i = t.hasParent(i) ? t.parent(i) : null;
d = i ? t.itemData(i) : null;
}
// by default we do not want to allow create menu
return true;
}
});
}
return pgBrowser.Nodes['function'];
});

View File

@ -0,0 +1,35 @@
SELECT
COALESCE(gt.rolname, 'public') AS grantee,
g.rolname AS grantor, array_agg(privilege_type) AS privileges,
array_agg(is_grantable) AS grantable
FROM
(SELECT
d.grantee, d.grantor, d.is_grantable,
CASE d.privilege_type
WHEN 'CONNECT' THEN 'c'
WHEN 'CREATE' THEN 'C'
WHEN 'DELETE' THEN 'd'
WHEN 'EXECUTE' THEN 'X'
WHEN 'INSERT' THEN 'a'
WHEN 'REFERENCES' THEN 'x'
WHEN 'SELECT' THEN 'r'
WHEN 'TEMPORARY' THEN 'T'
WHEN 'TRIGGER' THEN 't'
WHEN 'TRUNCATE' THEN 'D'
WHEN 'UPDATE' THEN 'w'
WHEN 'USAGE' THEN 'U'
ELSE 'UNKNOWN'
END AS privilege_type
FROM
(SELECT
(d).grantee AS grantee, (d).grantor AS grantor,
(d).is_grantable AS is_grantable,
(d).privilege_type AS privilege_type
FROM
(SELECT aclexplode(db.proacl) AS d FROM pg_proc db
WHERE db.oid = {{fnid}}::OID) a
) d
) d
LEFT JOIN pg_catalog.pg_roles g ON (d.grantor = g.oid)
LEFT JOIN pg_catalog.pg_roles gt ON (d.grantee = gt.oid)
GROUP BY g.rolname, gt.rolname;

View File

@ -0,0 +1,53 @@
{% import 'macros/functions/security.macros' as SECLABEL %}
{% import 'macros/functions/privilege.macros' as PRIVILEGE %}
{% import 'macros/functions/variable.macros' as VARIABLE %}
{% set is_columns = [] %}
{% if data %}
CREATE FUNCTION {{ conn|qtIdent(data.pronamespace, data.name) }}({% if data.arguments %}
{% for p in data.arguments %}{% if p.argmode %}{{p.argmode}} {% endif %}{% if p.argname %}{{ conn|qtIdent(p.argname)}} {% endif %}{% if p.argtype %}{{p.argtype}}{% endif %}{% if p.argdefval %} DEFAULT {{p.argdefval}}{% endif %}
{% if not loop.last %},{% endif %}
{% endfor %}
{% endif -%}
)
RETURNS{% if data.proretset %} SETOF{% endif %} {{ conn|qtTypeIdent(data.prorettypename) }}
LANGUAGE {{ data.lanname|qtLiteral }}
{% if data.provolatile %}{{ data.provolatile }} {% endif %}{% if data.proisstrict %}STRICT {% endif %}{% if data.prosecdef %}SECURITY DEFINER {% endif %}{% if data.proiswindow %}WINDOW{% endif -%}{% if data.procost %}
COST {{data.procost}}{% endif %}{% if data.prorows %}
ROWS {{data.prorows}}{% endif -%}{% if data.variables %}{% for v in data.variables %}
SET {{ conn|qtIdent(v.name) }}={{ v.value|qtLiteral }}{% endfor %}
{% endif %}
AS {% if data.lanname == 'c' %}
{{ data.probin|qtLiteral }}, {{ data.prosrc_c|qtLiteral }}
{% else %}
$function$
{{ data.prosrc }}
$function${% endif %};
{% if data.funcowner %}
ALTER FUNCTION {{ conn|qtIdent(data.pronamespace, data.name) }}({{data.func_args}})
OWNER TO {{ data.funcowner }};
{% endif %}
{% if data.acl %}
{% for p in data.acl %}
{{ PRIVILEGE.SET(conn, "FUNCTION", p.grantee, data.name, p.without_grant, p.with_grant, data.pronamespace, data.func_args)}}
{% endfor %}{% endif %}
{% if data.description %}
COMMENT ON FUNCTION {{ conn|qtIdent(data.pronamespace, data.name) }}({{data.func_args}})
IS '{{ data.description }}';
{% endif -%}
{% if data.seclabels %}
{% for r in data.seclabels %}
{% if r.security_label and r.provider %}
{{ SECLABEL.SET(conn, 'FUNCTION', data.name, r.provider, r.security_label, data.pronamespace, data.func_args) }}
{% endif %}
{% endfor %}
{% endif -%}
{% endif %}

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
proisagg = FALSE
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,11 @@
SELECT
pg_get_functiondef({{fnid}}::oid) AS func_def,
nspname || '.' || pr.proname || '(' || COALESCE(pg_catalog.pg_get_function_identity_arguments(pr.oid), '') || ')' as name
FROM
pg_proc pr
JOIN
pg_namespace nsp ON nsp.oid=pr.pronamespace
WHERE
proisagg = FALSE
AND pronamespace = {{scid}}::oid
AND pr.oid = {{fnid}}::oid;

View File

@ -0,0 +1,4 @@
SELECT
lanname as label, lanname as value
FROM
pg_language;

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
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
proisagg = FALSE
AND typname NOT IN ('trigger', 'event_trigger')
AND pr.proname = {{ name|qtLiteral }};

View File

@ -0,0 +1,6 @@
SELECT
format_type(oid, NULL) AS out_arg_type
FROM
pg_type
WHERE
oid = {{ out_arg_oid }}::oid;

View File

@ -0,0 +1,6 @@
SELECT
nspname
FROM
pg_namespace
WHERE
oid = {{ scid }}::oid;

View File

@ -0,0 +1,20 @@
SELECT
*
FROM
(SELECT
format_type(t.oid,NULL) AS typname,
CASE WHEN typelem > 0 THEN typelem ELSE t.oid END as elemoid, typlen, typtype, t.oid, nspname,
(SELECT COUNT(1) FROM pg_type t2 WHERE t2.typname = t.typname) > 1 AS isdup
FROM
pg_type t
JOIN
pg_namespace nsp ON typnamespace=nsp.oid
WHERE
(NOT (typname = 'unknown' AND nspname = 'pg_catalog'))
AND
(
typtype IN ('b', 'c', 'd', 'e', 'p', 'r')
AND typname NOT IN ('any', 'trigger', 'language_handler', 'event_trigger')
)
) AS dummy
ORDER BY nspname <> 'pg_catalog', nspname <> 'public', nspname, 1;

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, 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
proisagg = FALSE
AND pronamespace = {{scid}}::oid
AND typname NOT IN ('trigger', 'event_trigger')
ORDER BY
proname;

View File

@ -0,0 +1,31 @@
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
proisagg = FALSE
AND pronamespace = {{scid}}::oid
AND typname NOT IN ('trigger', 'event_trigger')
{% if fnid %}
AND pr.oid = {{fnid}}::oid
{% endif %}
ORDER BY
proname;

View File

@ -0,0 +1,105 @@
{% import 'macros/functions/security.macros' as SECLABEL %}
{% import 'macros/functions/privilege.macros' as PRIVILEGE %}
{% import 'macros/functions/variable.macros' as VARIABLE %}{% if data %}
{% set name = o_data.name %}
{% if data.name %}
{% if data.name != o_data.name %}
ALTER FUNCTION {{ conn|qtIdent(o_data.pronamespace, o_data.name) }}({{o_data.proargtypenames }})
RENAME TO {{ conn|qtIdent(data.name) }};
{% set name = data.name %}
{% endif %}
{% endif -%}
{% if data.change_func %}
CREATE OR REPLACE FUNCTION {{ conn|qtIdent(o_data.pronamespace, name) }}({% if data.arguments %}
{% for p in data.arguments %}{% if p.argmode %}{{p.argmode}} {% endif %}{% if p.argname %}{{ conn|qtIdent(p.argname) }} {% endif %}{% if p.argtype %}{{p.argtype}}{% endif %}{% if p.argdefval %} DEFAULT {{p.argdefval}}{% endif %}
{% if not loop.last %}, {% endif %}
{% endfor %}
{% endif -%}
)
RETURNS {{ o_data.prorettypename }}
{% if 'lanname' in data %}
LANGUAGE {{ data.lanname|qtLiteral }} {% else %}
LANGUAGE {{ o_data.lanname|qtLiteral }}
{% endif %}{% if 'provolatile' in data and data.provolatile %}{{ data.provolatile }} {% elif 'provolatile' not in data and o_data.provolatile %}{{ o_data.provolatile }}{% endif %}
{% if ('proisstrict' in data and data.proisstrict) or ('proisstrict' not in data and o_data.proisstrict) %} STRICT{% endif %}
{% if ('prosecdef' in data and data.prosecdef) or ('prosecdef' not in data and o_data.prosecdef) %} SECURITY DEFINER{% endif %}
{% if ('proiswindow' in data and data.proiswindow) or ('proiswindow' not in data and o_data.proiswindow) %} WINDOW{% endif %}
{% if data.procost %}COST {{data.procost}}{% elif o_data.procost %}COST {{o_data.procost}}{% endif %}{% if data.prorows %}
ROWS {{data.prorows}}{% elif o_data.prorows %}ROWS {{o_data.prorows}}{%endif -%}{% if data.merged_variables %}{% for v in data.merged_variables %}
SET {{ conn|qtIdent(v.name) }}={{ v.value|qtLiteral }}{% endfor -%}
{% endif %}
AS {% if 'probin' in data or 'prosrc_c' in data %}
{% if 'probin' in data %}{{ data.probin|qtLiteral }}{% else %}{{ o_data.probin|qtLiteral }}{% endif %}, {% if 'prosrc_c' in data %}{{ data.prosrc_c|qtLiteral }}{% else %}{{ o_data.prosrc_c|qtLiteral }}{% endif %}{% elif 'prosrc' in data %}
$function${{ data.prosrc }}$function${% elif o_data.lanname == 'c' %}
{{ o_data.probin|qtLiteral }}, {{ o_data.prosrc_c|qtLiteral }}{% else %}
$function${{ o_data.prosrc }}$function${% endif -%};
{% endif -%}
{% if data.funcowner %}
ALTER FUNCTION {{ conn|qtIdent(o_data.pronamespace, name) }}({{ o_data.proargtypenames }})
OWNER TO {{ data.funcowner }};
{% endif -%}
{# The SQL generated below will change priviledges #}
{% if data.acl %}
{% if 'deleted' in data.acl %}
{% for priv in data.acl.deleted %}
{{ PRIVILEGE.UNSETALL(conn, 'FUNCTION', priv.grantee, name, o_data.pronamespace, o_data.proargtypenames) }}
{% endfor %}{% endif %}
{% if 'changed' in data.acl %}
{% for priv in data.acl.changed %}
{{ PRIVILEGE.UNSETALL(conn, 'FUNCTION', priv.grantee, name, o_data.pronamespace, o_data.proargtypenames) }}
{{ PRIVILEGE.SET(conn, 'FUNCTION', priv.grantee, name, priv.without_grant, priv.with_grant, o_data.pronamespace, o_data.proargtypenames) }}
{% endfor %}{% endif %}
{% if 'added' in data.acl %}
{% for priv in data.acl.added %}
{{ PRIVILEGE.SET(conn, 'FUNCTION', priv.grantee, name, priv.without_grant, priv.with_grant, o_data.pronamespace, o_data.proargtypenames) }}
{% endfor %}{% endif %}{% endif %}
{% if data.change_func == False %}
{% if data.variables %}
{% if 'deleted' in data.variables and data.variables.deleted|length > 0 %}
{{ VARIABLE.UNSET(conn, 'FUNCTION', name, data.variables.deleted, o_data.pronamespace, o_data.proargtypenames ) }}
{% endif -%}
{% if 'merged_variables' in data and data.merged_variables|length > 0 %}
{{ VARIABLE.SET(conn, 'FUNCTION', name, data.merged_variables, o_data.pronamespace, o_data.proargtypenames ) }}
{% endif %}
{% endif %}{% endif %}
{% set seclabels = data.seclabels %}
{% if 'deleted' in seclabels and seclabels.deleted|length > 0 %}
{% for r in seclabels.deleted %}
{{ SECLABEL.UNSET(conn, 'FUNCTION', name, r.provider, o_data.pronamespace, o_data.proargtypenames) }}
{% endfor %}
{% endif -%}
{% if 'added' in seclabels and seclabels.added|length > 0 %}
{% for r in seclabels.added %}
{{ SECLABEL.SET(conn, 'FUNCTION', name, r.provider, r.security_label, o_data.pronamespace, o_data.proargtypenames) }}
{% endfor %}
{% endif -%}
{% if 'changed' in seclabels and seclabels.changed|length > 0 %}
{% for r in seclabels.changed %}
{{ SECLABEL.SET(conn, 'FUNCTION', name, r.provider, r.security_label, o_data.pronamespace, o_data.proargtypenames) }}
{% endfor %}{% endif -%}
{% if data.description %}
COMMENT ON FUNCTION {{ conn|qtIdent(o_data.pronamespace, name) }}({{o_data.proargtypenames }})
IS {{ data.description|qtLiteral }};
{% endif -%}
{% if data.pronamespace %}
ALTER FUNCTION {{ conn|qtIdent(o_data.pronamespace, name) }}({{o_data.proargtypenames }})
SET SCHEMA {{ conn|qtIdent(data.pronamespace) }};
{% endif -%}
{% endif %}

View File

@ -0,0 +1,6 @@
SELECT
name, vartype, min_val, max_val, enumvals
FROM
pg_settings
WHERE
context in ('user', 'superuser');

View File

@ -0,0 +1,35 @@
SELECT
COALESCE(gt.rolname, 'public') AS grantee,
g.rolname AS grantor, array_agg(privilege_type) AS privileges,
array_agg(is_grantable) AS grantable
FROM
(SELECT
d.grantee, d.grantor, d.is_grantable,
CASE d.privilege_type
WHEN 'CONNECT' THEN 'c'
WHEN 'CREATE' THEN 'C'
WHEN 'DELETE' THEN 'd'
WHEN 'EXECUTE' THEN 'X'
WHEN 'INSERT' THEN 'a'
WHEN 'REFERENCES' THEN 'x'
WHEN 'SELECT' THEN 'r'
WHEN 'TEMPORARY' THEN 'T'
WHEN 'TRIGGER' THEN 't'
WHEN 'TRUNCATE' THEN 'D'
WHEN 'UPDATE' THEN 'w'
WHEN 'USAGE' THEN 'U'
ELSE 'UNKNOWN'
END AS privilege_type
FROM
(SELECT
(d).grantee AS grantee, (d).grantor AS grantor,
(d).is_grantable AS is_grantable,
(d).privilege_type AS privilege_type
FROM
(SELECT aclexplode(db.proacl) AS d FROM pg_proc db
WHERE db.oid = {{fnid}}::OID) a
) d
) d
LEFT JOIN pg_catalog.pg_roles g ON (d.grantor = g.oid)
LEFT JOIN pg_catalog.pg_roles gt ON (d.grantee = gt.oid)
GROUP BY g.rolname, gt.rolname;

View File

@ -0,0 +1,57 @@
{% import 'macros/functions/security.macros' as SECLABLE %}
{% import 'macros/functions/privilege.macros' as PRIVILEGE %}
{% import 'macros/functions/variable.macros' as VARIABLE %}
{% set is_columns = [] %}
{% if data %}
CREATE FUNCTION {{ conn|qtIdent(data.pronamespace, data.name) }}({% if data.arguments %}
{% for p in data.arguments %}{% if p.argmode %}{{p.argmode}} {% endif %}{% if p.argname %}{{ conn|qtIdent(p.argname)}} {% endif %}{% if p.argtype %}{{p.argtype}}{% endif %}{% if p.argdefval %} DEFAULT {{p.argdefval}}{% endif %}
{% if not loop.last %},{% endif %}
{% endfor %}
{% endif -%}
)
RETURNS{% if data.proretset %} SETOF{% endif %} {{ conn|qtTypeIdent(data.prorettypename) }}
LANGUAGE {{ data.lanname|qtLiteral }}
{% if data.provolatile %}{{ data.provolatile }} {% endif %}{% if data.proleakproof %}LEAKPROOF {% else %}NOT LEAKPROOF {% endif %}
{% if data.proisstrict %}STRICT {% endif %}
{% if data.prosecdef %}SECURITY DEFINER {% endif %}
{% if data.proiswindow %}WINDOW{% endif %}{% if data.procost %}
COST {{data.procost}}{% endif %}{% if data.prorows %}
ROWS {{data.prorows}}{% endif -%}{% if data.variables %}{% for v in data.variables %}
SET {{ conn|qtIdent(v.name) }}={{ v.value|qtLiteral }}{% endfor %}
{% endif %}
AS {% if data.lanname == 'c' %}
{{ data.probin|qtLiteral }}, {{ data.prosrc_c|qtLiteral }}
{% else %}
$function$
{{ data.prosrc }}
$function${% endif -%};
{% if data.funcowner %}
ALTER FUNCTION {{ conn|qtIdent(data.pronamespace, data.name) }}({{data.func_args}})
OWNER TO {{ data.funcowner }};
{% endif -%}
{% if data.acl %}
{% for p in data.acl %}
{{ PRIVILEGE.SET(conn, "FUNCTION", p.grantee, data.name, p.without_grant, p.with_grant, data.pronamespace, data.func_args)}}
{% endfor -%}
{% endif -%}
{% if data.description %}
COMMENT ON FUNCTION {{ conn|qtIdent(data.pronamespace, data.name) }}({{data.func_args}})
IS '{{ data.description }}';
{% endif -%}
{% if data.seclabels %}
{% for r in data.seclabels %}
{% if r.security_label and r.provider %}
{{ SECLABLE.SET(conn, 'FUNCTION', data.name, r.provider, r.security_label, data.pronamespace, data.func_args) }}
{% endif %}
{% endfor %}
{% endif -%}
{% endif -%}

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
proisagg = FALSE
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,11 @@
SELECT
pg_get_functiondef({{fnid}}::oid) AS func_def,
nspname || '.' || pr.proname || '(' || COALESCE(pg_catalog.pg_get_function_identity_arguments(pr.oid), '') || ')' as name
FROM
pg_proc pr
JOIN
pg_namespace nsp ON nsp.oid=pr.pronamespace
WHERE
proisagg = FALSE
AND pronamespace = {{scid}}::oid
AND pr.oid = {{fnid}}::oid;

View File

@ -0,0 +1,4 @@
SELECT
lanname as label, lanname as value
FROM
pg_language;

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
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
proisagg = FALSE
AND typname NOT IN ('trigger', 'event_trigger')
AND pr.proname = {{ name|qtLiteral }};

View File

@ -0,0 +1,6 @@
SELECT
format_type(oid, NULL) AS out_arg_type
FROM
pg_type
WHERE
oid = {{ out_arg_oid }}::oid;

View File

@ -0,0 +1,6 @@
SELECT
nspname
FROM
pg_namespace
WHERE
oid = {{ scid }}::oid;

View File

@ -0,0 +1,20 @@
SELECT
*
FROM
(SELECT
format_type(t.oid,NULL) AS typname,
CASE WHEN typelem > 0 THEN typelem ELSE t.oid END as elemoid, typlen, typtype, t.oid, nspname,
(SELECT COUNT(1) FROM pg_type t2 WHERE t2.typname = t.typname) > 1 AS isdup
FROM
pg_type t
JOIN
pg_namespace nsp ON typnamespace=nsp.oid
WHERE
(NOT (typname = 'unknown' AND nspname = 'pg_catalog'))
AND
(
typtype IN ('b', 'c', 'd', 'e', 'p', 'r')
AND typname NOT IN ('any', 'trigger', 'language_handler', 'event_trigger')
)
) AS dummy
ORDER BY nspname <> 'pg_catalog', nspname <> 'public', nspname, 1;

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, 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
proisagg = FALSE
AND pronamespace = {{scid}}::oid
AND typname NOT IN ('trigger', 'event_trigger')
ORDER BY
proname;

View File

@ -0,0 +1,31 @@
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_shseclabel 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
proisagg = FALSE
AND pronamespace = {{scid}}::oid
AND typname NOT IN ('trigger', 'event_trigger')
{% if fnid %}
AND pr.oid = {{fnid}}::oid
{% endif %}
ORDER BY
proname;

View File

@ -0,0 +1,114 @@
{% import 'macros/functions/security.macros' as SECLABEL %}
{% import 'macros/functions/privilege.macros' as PRIVILEGE %}
{% import 'macros/functions/variable.macros' as VARIABLE %}{% if data %}
{% set name = o_data.name %}
{% if data.name %}
{% if data.name != o_data.name %}
ALTER FUNCTION {{ conn|qtIdent(o_data.pronamespace, o_data.name) }}({{o_data.proargtypenames }})
RENAME TO {{ conn|qtIdent(data.name) }};
{% set name = data.name %}
{% endif %}
{% endif -%}
{% if data.change_func %}
CREATE OR REPLACE FUNCTION {{ conn|qtIdent(o_data.pronamespace, name) }}({% if data.arguments %}
{% for p in data.arguments %}{% if p.argmode %}{{p.argmode}} {% endif %}{% if p.argname %}{{conn|qtIdent(p.argname)}} {% endif %}{% if p.argtype %}{{p.argtype}}{% endif %}{% if p.argdefval %} DEFAULT {{p.argdefval}}{% endif %}
{% if not loop.last %}, {% endif %}
{% endfor %}
{% endif -%}
)
RETURNS {{ o_data.prorettypename }}
{% if 'lanname' in data %}
LANGUAGE {{ data.lanname|qtLiteral }} {% else %}
LANGUAGE {{ o_data.lanname|qtLiteral }}
{% endif %}{% if 'provolatile' in data and data.provolatile %}{{ data.provolatile }} {% elif 'provolatile' not in data and o_data.provolatile %}{{ o_data.provolatile }}{% endif %}
{% if ('proleakproof' in data and data.proleakproof) or ('proleakproof' not in data and o_data.proleakproof) %}LEAKPROOF{% elif 'proleakproof' in data and not data.proleakproof %}NOT LEAKPROOF{% endif %}
{% if ('proisstrict' in data and data.proisstrict) or ('proisstrict' not in data and o_data.proisstrict) %} STRICT{% endif %}
{% if ('prosecdef' in data and data.prosecdef) or ('prosecdef' not in data and o_data.prosecdef) %} SECURITY DEFINER{% endif %}
{% if ('proiswindow' in data and data.proiswindow) or ('proiswindow' not in data and o_data.proiswindow) %} WINDOW{% endif %}
{% if data.procost %}COST {{data.procost}}{% elif o_data.procost %}COST {{o_data.procost}}{% endif %}{% if data.prorows %}
ROWS {{data.prorows}}{% elif o_data.prorows %}ROWS {{o_data.prorows}}{% endif -%}{% if data.merged_variables %}{% for v in data.merged_variables %}
SET {{ conn|qtIdent(v.name) }}={{ v.value|qtLiteral }}{% endfor -%}
{% endif %}
AS {% if 'probin' in data or 'prosrc_c' in data %}
{% if 'probin' in data %}{{ data.probin|qtLiteral }}{% else %}{{ o_data.probin|qtLiteral }}{% endif %}, {% if 'prosrc_c' in data %}{{ data.prosrc_c|qtLiteral }}{% else %}{{ o_data.prosrc_c|qtLiteral }}{% endif %}{% elif 'prosrc' in data %}
$function${{ data.prosrc }}$function${% elif o_data.lanname == 'c' %}
{{ o_data.probin|qtLiteral }}, {{ o_data.prosrc_c|qtLiteral }}{% else %}
$function${{ o_data.prosrc }}$function${% endif -%};
{% endif -%}
{% if data.funcowner %}
ALTER FUNCTION {{ conn|qtIdent(o_data.pronamespace, name) }}({{ o_data.proargtypenames }})
OWNER TO {{ data.funcowner }};
{% endif -%}
{# The SQL generated below will change priviledges #}
{% if data.acl %}
{% if 'deleted' in data.acl %}
{% for priv in data.acl.deleted %}
{{ PRIVILEGE.UNSETALL(conn, 'FUNCTION', priv.grantee, name, o_data.pronamespace, o_data.proargtypenames) }}
{% endfor %}
{% endif -%}
{% if 'changed' in data.acl %}
{% for priv in data.acl.changed %}
{{ PRIVILEGE.UNSETALL(conn, 'FUNCTION', priv.grantee, name, o_data.pronamespace, o_data.proargtypenames) }}
{{ PRIVILEGE.SET(conn, 'FUNCTION', priv.grantee, name, priv.without_grant, priv.with_grant, o_data.pronamespace, o_data.proargtypenames) }}
{% endfor %}
{% endif -%}
{% if 'added' in data.acl %}
{% for priv in data.acl.added %}
{{ PRIVILEGE.SET(conn, 'FUNCTION', priv.grantee, name, priv.without_grant, priv.with_grant, o_data.pronamespace, o_data.proargtypenames) }}
{% endfor %}
{% endif %}
{% endif -%}
{% if data.change_func == False %}
{% if data.variables %}
{% if 'deleted' in data.variables and data.variables.deleted|length > 0 %}
{{ VARIABLE.UNSET(conn, 'FUNCTION', name, data.variables.deleted, o_data.pronamespace, o_data.proargtypenames ) }}
{% endif -%}
{% if 'merged_variables' in data and data.merged_variables|length > 0 %}
{{ VARIABLE.SET(conn, 'FUNCTION', name, data.merged_variables, o_data.pronamespace, o_data.proargtypenames ) }}
{% endif -%}
{% endif -%}
{% endif -%}
{% set seclabels = data.seclabels %}
{% if 'deleted' in seclabels and seclabels.deleted|length > 0 %}
{% for r in seclabels.deleted %}
{{ SECLABEL.UNSET(conn, 'FUNCTION', name, r.provider, o_data.pronamespace, o_data.proargtypenames) }}
{% endfor %}
{% endif -%}
{% if 'added' in seclabels and seclabels.added|length > 0 %}
{% for r in seclabels.added %}
{{ SECLABEL.SET(conn, 'FUNCTION', name, r.provider, r.security_label, o_data.pronamespace, o_data.proargtypenames) }}
{% endfor %}
{% endif -%}
{% if 'changed' in seclabels and seclabels.changed|length > 0 %}
{% for r in seclabels.changed %}
{{ SECLABEL.SET(conn, 'FUNCTION', name, r.provider, r.security_label, o_data.pronamespace, o_data.proargtypenames) }}
{% endfor %}
{% endif -%}
{% if data.description %}
COMMENT ON FUNCTION {{ conn|qtIdent(o_data.pronamespace, name) }}({{ o_data.proargtypenames }})
IS {{ data.description|qtLiteral }};
{% endif -%}
{% if data.pronamespace %}
ALTER FUNCTION {{ conn|qtIdent(o_data.pronamespace, name) }}({{ o_data.proargtypenames }})
SET SCHEMA {{ conn|qtIdent(data.pronamespace) }};
{% endif -%}
{% endif %}

View File

@ -0,0 +1,6 @@
SELECT
name, vartype, min_val, max_val, enumvals
FROM
pg_settings
WHERE
context in ('user', 'superuser');

View File

@ -0,0 +1,35 @@
SELECT
COALESCE(gt.rolname, 'public') AS grantee,
g.rolname AS grantor, array_agg(privilege_type) AS privileges,
array_agg(is_grantable) AS grantable
FROM
(SELECT
d.grantee, d.grantor, d.is_grantable,
CASE d.privilege_type
WHEN 'CONNECT' THEN 'c'
WHEN 'CREATE' THEN 'C'
WHEN 'DELETE' THEN 'd'
WHEN 'EXECUTE' THEN 'X'
WHEN 'INSERT' THEN 'a'
WHEN 'REFERENCES' THEN 'x'
WHEN 'SELECT' THEN 'r'
WHEN 'TEMPORARY' THEN 'T'
WHEN 'TRIGGER' THEN 't'
WHEN 'TRUNCATE' THEN 'D'
WHEN 'UPDATE' THEN 'w'
WHEN 'USAGE' THEN 'U'
ELSE 'UNKNOWN'
END AS privilege_type
FROM
(SELECT
(d).grantee AS grantee, (d).grantor AS grantor,
(d).is_grantable AS is_grantable,
(d).privilege_type AS privilege_type
FROM
(SELECT aclexplode(db.proacl) AS d FROM pg_proc db
WHERE db.oid = {{fnid}}::OID) a
) d
) d
LEFT JOIN pg_catalog.pg_roles g ON (d.grantor = g.oid)
LEFT JOIN pg_catalog.pg_roles gt ON (d.grantee = gt.oid)
GROUP BY g.rolname, gt.rolname;

View File

@ -0,0 +1,57 @@
{% import 'macros/functions/security.macros' as SECLABEL %}
{% import 'macros/functions/privilege.macros' as PRIVILEGE %}
{% import 'macros/functions/variable.macros' as VARIABLE %}
{% set is_columns = [] %}
{% if data %}
CREATE FUNCTION {{ conn|qtIdent(data.pronamespace, data.name) }}({% if data
.arguments %}
{% for p in data.arguments %}{% if p.argmode %}{{p.argmode}} {% endif %}{% if p.argname %}{{ conn|qtIdent(p.argname)}}{% endif %}{% if p.argtype %}{{p.argtype}}{% endif %}{% if p.argdefval %} DEFAULT {{p.argdefval}}{% endif %}
{% if not loop.last %},{% endif %}
{% endfor %}
{% endif -%}
)
RETURNS{% if data.proretset %} SETOF{% endif %} {{ conn|qtTypeIdent(data.prorettypename) }}
LANGUAGE {{ data.lanname|qtLiteral }}
{% if data.provolatile %}{{ data.provolatile }} {% endif %}{% if data.proleakproof %}LEAKPROOF {% else %}NOT LEAKPROOF {% endif %}
{% if data.proisstrict %}STRICT {% endif %}
{% if data.prosecdef %}SECURITY DEFINER {% endif %}
{% if data.proiswindow %}WINDOW{% endif %}{% if data.procost %}
COST {{data.procost}}{% endif %}{% if data.prorows %}
ROWS {{data.prorows}}{% endif -%}{% if data.variables %}{% for v in data.variables %}
SET {{ conn|qtIdent(v.name) }}={{ v.value|qtLiteral }}{% endfor %}
{% endif %}
AS {% if data.lanname == 'c' %}
{{ data.probin|qtLiteral }}, {{ data.prosrc_c|qtLiteral }}
{% else %}
$function$
{{ data.prosrc }}
$function${% endif -%};
{% if data.funcowner %}
ALTER FUNCTION {{ conn|qtIdent(data.pronamespace, data.name) }}({{data.func_args}})
OWNER TO {{ data.funcowner }};
{% endif -%}
{% if data.acl %}
{% for p in data.acl %}
{{ PRIVILEGE.SET(conn, "FUNCTION", p.grantee, data.name, p.without_grant, p.with_grant, data.pronamespace, data.func_args)}}
{% endfor %}{% endif %}
{% if data.description %}
COMMENT ON FUNCTION {{ conn|qtIdent(data.pronamespace, data.name) }}({{data.func_args}})
IS '{{ data.description }}';
{% endif -%}
{% if data.seclabels %}
{% for r in data.seclabels %}
{% if r.security_label and r.provider %}
{{ SECLABEL.SET(conn, 'FUNCTION', data.name, r.provider, r.security_label, data.pronamespace, data.func_args) }}
{% endif %}
{% endfor %}
{% endif -%}
{% endif %}

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
proisagg = FALSE
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,11 @@
SELECT
pg_get_functiondef({{fnid}}::oid) AS func_def,
nspname || '.' || pr.proname || '(' || COALESCE(pg_catalog.pg_get_function_identity_arguments(pr.oid), '') || ')' as name
FROM
pg_proc pr
JOIN
pg_namespace nsp ON nsp.oid=pr.pronamespace
WHERE
proisagg = FALSE
AND pronamespace = {{scid}}::oid
AND pr.oid = {{fnid}}::oid;

View File

@ -0,0 +1,4 @@
SELECT
lanname as label, lanname as value
FROM
pg_language;

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
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
proisagg = FALSE
AND typname NOT IN ('trigger', 'event_trigger')
AND pr.proname = {{ name|qtLiteral }};

View File

@ -0,0 +1,6 @@
SELECT
format_type(oid, NULL) AS out_arg_type
FROM
pg_type
WHERE
oid = {{ out_arg_oid }}::oid;

View File

@ -0,0 +1,6 @@
SELECT
nspname
FROM
pg_namespace
WHERE
oid = {{ scid }}::oid;

View File

@ -0,0 +1,20 @@
SELECT
*
FROM
(SELECT
format_type(t.oid,NULL) AS typname,
CASE WHEN typelem > 0 THEN typelem ELSE t.oid END as elemoid, typlen, typtype, t.oid, nspname,
(SELECT COUNT(1) FROM pg_type t2 WHERE t2.typname = t.typname) > 1 AS isdup
FROM
pg_type t
JOIN
pg_namespace nsp ON typnamespace=nsp.oid
WHERE
(NOT (typname = 'unknown' AND nspname = 'pg_catalog'))
AND
(
typtype IN ('b', 'c', 'd', 'e', 'p', 'r')
AND typname NOT IN ('any', 'trigger', 'language_handler', 'event_trigger')
)
) AS dummy
ORDER BY nspname <> 'pg_catalog', nspname <> 'public', nspname, 1;

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, 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
proisagg = FALSE
AND pronamespace = {{scid}}::oid
AND typname NOT IN ('trigger', 'event_trigger')
ORDER BY
proname;

View File

@ -0,0 +1,31 @@
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_shseclabel 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
proisagg = FALSE
AND pronamespace = {{scid}}::oid
AND typname NOT IN ('trigger', 'event_trigger')
{% if fnid %}
AND pr.oid = {{fnid}}::oid
{% endif %}
ORDER BY
proname;

View File

@ -0,0 +1,114 @@
{% import 'macros/functions/security.macros' as SECLABEL %}
{% import 'macros/functions/privilege.macros' as PRIVILEGE %}
{% import 'macros/functions/variable.macros' as VARIABLE %}{% if data %}
{% set name = o_data.name %}
{% if data.name %}
{% if data.name != o_data.name %}
ALTER FUNCTION {{ conn|qtIdent(o_data.pronamespace, o_data.name) }}({{
o_data.proargtypenames }})
RENAME TO {{ conn|qtIdent(data.name) }};
{% set name = data.name %}
{% endif %}
{% endif -%}
{% if data.change_func %}
CREATE OR REPLACE FUNCTION {{ conn|qtIdent(o_data.pronamespace, name) }}({% if data.arguments %}
{% for p in data.arguments %}{% if p.argmode %}{{p.argmode}} {% endif %}{% if p.argname %}{{ conn|qtIdent(p.argname) }} {% endif %}{% if p.argtype %}{{p.argtype}}{% endif %}{% if p.argdefval %} DEFAULT {{p.argdefval}}{% endif %}
{% if not loop.last %},{% endif %}
{% endfor %}
{% endif -%}
)
RETURNS {{ o_data.prorettypename }}
{% if 'lanname' in data %}
LANGUAGE {{ data.lanname|qtLiteral }} {% else %}
LANGUAGE {{ o_data.lanname|qtLiteral }}
{% endif %}{% if 'provolatile' in data and data.provolatile %}{{ data.provolatile }} {% elif 'provolatile' not in data and o_data.provolatile %}{{ o_data.provolatile }}{% endif %}
{% if ('proleakproof' in data and data.proleakproof) or ('proleakproof' not in data and o_data.proleakproof) %}LEAKPROOF{% elif 'proleakproof' in data and not data.proleakproof %}NOT LEAKPROOF{% endif %}
{% if ('proisstrict' in data and data.proisstrict) or ('proisstrict' not in data and o_data.proisstrict) %} STRICT{% endif %}
{% if ('prosecdef' in data and data.prosecdef) or ('prosecdef' not in data and o_data.prosecdef) %} SECURITY DEFINER{% endif %}
{% if ('proiswindow' in data and data.proiswindow) or ('proiswindow' not in data and o_data.proiswindow) %} WINDOW{% endif %}
{% if data.procost %}COST {{data.procost}}{% elif o_data.procost %}COST {{o_data.procost}}{% endif %}{% if data.prorows %}
ROWS {{data.prorows}}{% elif o_data.prorows %}ROWS {{o_data.prorows}} {%endif -%}{% if data.merged_variables %}{% for v in data.merged_variables %}
SET {{ conn|qtIdent(v.name) }}={{ v.value|qtLiteral }}{% endfor -%}
{% endif %}
AS {% if 'probin' in data or 'prosrc_c' in data %}
{% if 'probin' in data %}{{ data.probin|qtLiteral }}{% else %}{{ o_data.probin|qtLiteral }}{% endif %}, {% if 'prosrc_c' in data %}{{ data.prosrc_c|qtLiteral }}{% else %}{{ o_data.prosrc_c|qtLiteral }}{% endif %}{% elif 'prosrc' in data %}
$function${{ data.prosrc }}$function${% elif o_data.lanname == 'c' %}
{{ o_data.probin|qtLiteral }}, {{ o_data.prosrc_c|qtLiteral }}{% else %}
$function${{ o_data.prosrc }}$function${% endif -%};
{% endif -%}
{% if data.funcowner %}
ALTER FUNCTION {{ conn|qtIdent(o_data.pronamespace, name) }}({{o_data.proargtypenames }})
OWNER TO {{ data.funcowner }};
{% endif -%}
{# The SQL generated below will change priviledges #}
{% if data.acl %}
{% if 'deleted' in data.acl %}
{% for priv in data.acl.deleted %}
{{ PRIVILEGE.UNSETALL(conn, 'FUNCTION', priv.grantee, name, o_data.pronamespace, o_data.proargtypenames) }}
{% endfor %}
{% endif -%}
{% if 'changed' in data.datacl %}
{% for priv in data.acl.changed %}
{{ PRIVILEGE.UNSETALL(conn, 'FUNCTION', priv.grantee, name, o_data.pronamespace, o_data.proargtypenames) }}
{{ PRIVILEGE.SET(conn, 'FUNCTION', priv.grantee, name, priv.without_grant, priv.with_grant, o_data.pronamespace, o_data.proargtypenames) }}
{% endfor %}
{% endif -%}
{% if 'added' in data.acl %}
{% for priv in data.acl.added %}
{{ PRIVILEGE.SET(conn, 'FUNCTION', priv.grantee, name, priv.without_grant, priv.with_grant, o_data.pronamespace, o_data.proargtypenames) }}
{% endfor %}{% endif -%}
{% endif -%}
{% if data.change_func == False %}
{% if data.variables %}
{% if 'deleted' in data.variables and data.variables.deleted|length > 0 %}
{{ VARIABLE.UNSET(conn, 'FUNCTION', name, data.variables.deleted, o_data.pronamespace, o_data.proargtypenames) }}
{% endif -%}
{% if 'merged_variables' in data and data.merged_variables|length > 0 %}
{{ VARIABLE.SET(conn, 'FUNCTION', name, data.merged_variables, o_data.pronamespace, o_data.proargtypenames) }}
{% endif -%}
{% endif -%}
{% endif -%}
{% set seclabels = data.seclabels %}
{% if 'deleted' in seclabels and seclabels.deleted|length > 0 %}
{% for r in seclabels.deleted %}
{{ SECLABEL.UNSET(conn, 'FUNCTION', name, r.provider, o_data.pronamespace, o_data.proargtypenames) }}
{% endfor %}
{% endif -%}
{% if 'added' in seclabels and seclabels.added|length > 0 %}
{% for r in seclabels.added %}
{{ SECLABEL.SET(conn, 'FUNCTION', name, r.provider, r.security_label, o_data.pronamespace, o_data.proargtypenames) }}
{% endfor %}
{% endif -%}
{% if 'changed' in seclabels and seclabels.changed|length > 0 %}
{% for r in seclabels.changed %}
{{ SECLABEL.SET(conn, 'FUNCTION', name, r.provider, r.security_label, o_data.pronamespace, o_data.proargtypenames) }}
{% endfor %}
{% endif -%}
{% if data.description %}
COMMENT ON FUNCTION {{ conn|qtIdent(o_data.pronamespace, name) }}({{o_data.proargtypenames }})
IS {{ data.description|qtLiteral }};
{% endif -%}
{% if data.pronamespace %}
ALTER FUNCTION {{ conn|qtIdent(o_data.pronamespace, name) }}({{o_data.proargtypenames }})
SET SCHEMA {{ conn|qtIdent(data.pronamespace) }};
{% endif -%}
{% endif %}

View File

@ -0,0 +1,6 @@
SELECT
name, vartype, min_val, max_val, enumvals
FROM
pg_settings
WHERE
context in ('user', 'superuser');

View File

@ -0,0 +1,35 @@
SELECT
COALESCE(gt.rolname, 'public') AS grantee,
g.rolname AS grantor, array_agg(privilege_type) AS privileges,
array_agg(is_grantable) AS grantable
FROM
(SELECT
d.grantee, d.grantor, d.is_grantable,
CASE d.privilege_type
WHEN 'CONNECT' THEN 'c'
WHEN 'CREATE' THEN 'C'
WHEN 'DELETE' THEN 'd'
WHEN 'EXECUTE' THEN 'X'
WHEN 'INSERT' THEN 'a'
WHEN 'REFERENCES' THEN 'x'
WHEN 'SELECT' THEN 'r'
WHEN 'TEMPORARY' THEN 'T'
WHEN 'TRIGGER' THEN 't'
WHEN 'TRUNCATE' THEN 'D'
WHEN 'UPDATE' THEN 'w'
WHEN 'USAGE' THEN 'U'
ELSE 'UNKNOWN'
END AS privilege_type
FROM
(SELECT
(d).grantee AS grantee, (d).grantor AS grantor,
(d).is_grantable AS is_grantable,
(d).privilege_type AS privilege_type
FROM
(SELECT aclexplode(db.proacl) AS d FROM pg_proc db
WHERE db.oid = {{fnid}}::OID) a
) d
) d
LEFT JOIN pg_catalog.pg_roles g ON (d.grantor = g.oid)
LEFT JOIN pg_catalog.pg_roles gt ON (d.grantee = gt.oid)
GROUP BY g.rolname, gt.rolname;

View File

@ -0,0 +1,53 @@
{% import 'macros/functions/security.macros' as SECLABEL %}
{% import 'macros/functions/privilege.macros' as PRIVILEGE %}
{% import 'macros/functions/variable.macros' as VARIABLE %}
{% set is_columns = [] %}
{% if data %}
CREATE FUNCTION {{ conn|qtIdent(data.pronamespace, data.name) }}({% if data.arguments %}
{% for p in data.arguments %}{% if p.argmode %}{{p.argmode}} {% endif %}{% if p.argname %}{{ conn|qtIdent(p.argname)}} {% endif %}{% if p.argtype %}{{p.argtype}}{% endif %}{% if p.argdefval %} DEFAULT {{p.argdefval}}{% endif %}
{% if not loop.last %},{% endif %}
{% endfor %}
{% endif -%}
)
RETURNS{% if data.proretset %} SETOF{% endif %} {{ conn|qtTypeIdent(data.prorettypename) }}
LANGUAGE {{ data.lanname|qtLiteral }}
{% if data.provolatile %}{{ data.provolatile }} {% endif %}{% if data.proisstrict %}STRICT {% endif %}{% if data.prosecdef %}SECURITY DEFINER {% endif %}{% if data.proiswindow %}WINDOW{% endif -%}{% if data.procost %}
COST {{data.procost}}{% endif %}{% if data.prorows %}
ROWS {{data.prorows}}{% endif -%}{% if data.variables %}{% for v in data.variables %}
SET {{ conn|qtIdent(v.name) }}={{ v.value|qtLiteral }}{% endfor %}
{% endif %}
AS {% if data.lanname == 'c' %}
{{ data.probin|qtLiteral }}, {{ data.prosrc_c|qtLiteral }}
{% else %}
$function$
{{ data.prosrc }}
$function${% endif %};
{% if data.funcowner %}
ALTER FUNCTION {{ conn|qtIdent(data.pronamespace, data.name) }}({{data.func_args}})
OWNER TO {{ data.funcowner }};
{% endif %}
{% if data.acl %}
{% for p in data.acl %}
{{ PRIVILEGE.SET(conn, "FUNCTION", p.grantee, data.name, p.without_grant, p.with_grant, data.pronamespace, data.func_args)}}
{% endfor %}{% endif %}
{% if data.description %}
COMMENT ON FUNCTION {{ conn|qtIdent(data.pronamespace, data.name) }}({{data.func_args}})
IS '{{ data.description }}';
{% endif -%}
{% if data.seclabels %}
{% for r in data.seclabels %}
{% if r.security_label and r.provider %}
{{ SECLABEL.SET(conn, 'FUNCTION', data.name, r.provider, r.security_label, data.pronamespace, data.func_args) }}
{% endif %}
{% endfor %}
{% endif -%}
{% endif %}

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
proisagg = FALSE
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,11 @@
SELECT
pg_get_functiondef({{fnid}}::oid) AS func_def,
nspname || '.' || pr.proname || '(' || COALESCE(pg_catalog.pg_get_function_identity_arguments(pr.oid), '') || ')' as name
FROM
pg_proc pr
JOIN
pg_namespace nsp ON nsp.oid=pr.pronamespace
WHERE
proisagg = FALSE
AND pronamespace = {{scid}}::oid
AND pr.oid = {{fnid}}::oid;

View File

@ -0,0 +1,4 @@
SELECT
lanname as label, lanname as value
FROM
pg_language;

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
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
proisagg = FALSE
AND typname NOT IN ('trigger', 'event_trigger')
AND pr.proname = {{ name|qtLiteral }};

View File

@ -0,0 +1,6 @@
SELECT
format_type(oid, NULL) AS out_arg_type
FROM
pg_type
WHERE
oid = {{ out_arg_oid }}::oid;

View File

@ -0,0 +1,6 @@
SELECT
nspname
FROM
pg_namespace
WHERE
oid = {{ scid }}::oid;

View File

@ -0,0 +1,20 @@
SELECT
*
FROM
(SELECT
format_type(t.oid,NULL) AS typname,
CASE WHEN typelem > 0 THEN typelem ELSE t.oid END as elemoid, typlen, typtype, t.oid, nspname,
(SELECT COUNT(1) FROM pg_type t2 WHERE t2.typname = t.typname) > 1 AS isdup
FROM
pg_type t
JOIN
pg_namespace nsp ON typnamespace=nsp.oid
WHERE
(NOT (typname = 'unknown' AND nspname = 'pg_catalog'))
AND
(
typtype IN ('b', 'c', 'd', 'e', 'p', 'r')
AND typname NOT IN ('any', 'trigger', 'language_handler', 'event_trigger')
)
) AS dummy
ORDER BY nspname <> 'pg_catalog', nspname <> 'public', nspname, 1;

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, 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
proisagg = FALSE
AND pr.protype = '0'::char
AND pronamespace = {{scid}}::oid
AND typname NOT IN ('trigger', 'event_trigger')
ORDER BY
proname;

View File

@ -0,0 +1,31 @@
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
proisagg = FALSE
AND pronamespace = {{scid}}::oid
AND typname NOT IN ('trigger', 'event_trigger')
{% if fnid %}
AND pr.oid = {{fnid}}::oid
{% endif %}
ORDER BY
proname;

View File

@ -0,0 +1,105 @@
{% import 'macros/functions/security.macros' as SECLABEL %}
{% import 'macros/functions/privilege.macros' as PRIVILEGE %}
{% import 'macros/functions/variable.macros' as VARIABLE %}{% if data %}
{% set name = o_data.name %}
{% if data.name %}
{% if data.name != o_data.name %}
ALTER FUNCTION {{ conn|qtIdent(o_data.pronamespace, o_data.name) }}({{o_data.proargtypenames }})
RENAME TO {{ conn|qtIdent(data.name) }};
{% set name = data.name %}
{% endif %}
{% endif -%}
{% if data.change_func %}
CREATE OR REPLACE FUNCTION {{ conn|qtIdent(o_data.pronamespace, name) }}({% if data.arguments %}
{% for p in data.arguments %}{% if p.argmode %}{{p.argmode}} {% endif %}{% if p.argname %}{{ conn|qtIdent(p.argname) }} {% endif %}{% if p.argtype %}{{p.argtype}}{% endif %}{% if p.argdefval %} DEFAULT {{p.argdefval}}{% endif %}
{% if not loop.last %}, {% endif %}
{% endfor %}
{% endif -%}
)
RETURNS {{ o_data.prorettypename }}
{% if 'lanname' in data %}
LANGUAGE {{ data.lanname|qtLiteral }} {% else %}
LANGUAGE {{ o_data.lanname|qtLiteral }}
{% endif %}{% if 'provolatile' in data and data.provolatile %}{{ data.provolatile }} {% elif 'provolatile' not in data and o_data.provolatile %}{{ o_data.provolatile }}{% endif %}
{% if ('proisstrict' in data and data.proisstrict) or ('proisstrict' not in data and o_data.proisstrict) %} STRICT{% endif %}
{% if ('prosecdef' in data and data.prosecdef) or ('prosecdef' not in data and o_data.prosecdef) %} SECURITY DEFINER{% endif %}
{% if ('proiswindow' in data and data.proiswindow) or ('proiswindow' not in data and o_data.proiswindow) %} WINDOW{% endif %}
{% if data.procost %}COST {{data.procost}}{% elif o_data.procost %}COST {{o_data.procost}}{% endif %}{% if data.prorows %}
ROWS {{data.prorows}}{% elif o_data.prorows %}ROWS {{o_data.prorows}}{%endif -%}{% if data.merged_variables %}{% for v in data.merged_variables %}
SET {{ conn|qtIdent(v.name) }}={{ v.value|qtLiteral }}{% endfor -%}
{% endif %}
AS {% if 'probin' in data or 'prosrc_c' in data %}
{% if 'probin' in data %}{{ data.probin|qtLiteral }}{% else %}{{ o_data.probin|qtLiteral }}{% endif %}, {% if 'prosrc_c' in data %}{{ data.prosrc_c|qtLiteral }}{% else %}{{ o_data.prosrc_c|qtLiteral }}{% endif %}{% elif 'prosrc' in data %}
$function${{ data.prosrc }}$function${% elif o_data.lanname == 'c' %}
{{ o_data.probin|qtLiteral }}, {{ o_data.prosrc_c|qtLiteral }}{% else %}
$function${{ o_data.prosrc }}$function${% endif -%};
{% endif -%}
{% if data.funcowner %}
ALTER FUNCTION {{ conn|qtIdent(o_data.pronamespace, name) }}({{ o_data.proargtypenames }})
OWNER TO {{ data.funcowner }};
{% endif -%}
{# The SQL generated below will change priviledges #}
{% if data.acl %}
{% if 'deleted' in data.acl %}
{% for priv in data.acl.deleted %}
{{ PRIVILEGE.UNSETALL(conn, 'FUNCTION', priv.grantee, name, o_data.pronamespace, o_data.proargtypenames) }}
{% endfor %}{% endif %}
{% if 'changed' in data.acl %}
{% for priv in data.acl.changed %}
{{ PRIVILEGE.UNSETALL(conn, 'FUNCTION', priv.grantee, name, o_data.pronamespace, o_data.proargtypenames) }}
{{ PRIVILEGE.SET(conn, 'FUNCTION', priv.grantee, name, priv.without_grant, priv.with_grant, o_data.pronamespace, o_data.proargtypenames) }}
{% endfor %}{% endif %}
{% if 'added' in data.acl %}
{% for priv in data.acl.added %}
{{ PRIVILEGE.SET(conn, 'FUNCTION', priv.grantee, name, priv.without_grant, priv.with_grant, o_data.pronamespace, o_data.proargtypenames) }}
{% endfor %}{% endif %}{% endif %}
{% if data.change_func == False %}
{% if data.variables %}
{% if 'deleted' in data.variables and data.variables.deleted|length > 0 %}
{{ VARIABLE.UNSET(conn, 'FUNCTION', name, data.variables.deleted, o_data.pronamespace, o_data.proargtypenames ) }}
{% endif -%}
{% if 'merged_variables' in data and data.merged_variables|length > 0 %}
{{ VARIABLE.SET(conn, 'FUNCTION', name, data.merged_variables, o_data.pronamespace, o_data.proargtypenames ) }}
{% endif %}
{% endif %}{% endif %}
{% set seclabels = data.seclabels %}
{% if 'deleted' in seclabels and seclabels.deleted|length > 0 %}
{% for r in seclabels.deleted %}
{{ SECLABEL.UNSET(conn, 'FUNCTION', name, r.provider, o_data.pronamespace, o_data.proargtypenames) }}
{% endfor %}
{% endif -%}
{% if 'added' in seclabels and seclabels.added|length > 0 %}
{% for r in seclabels.added %}
{{ SECLABEL.SET(conn, 'FUNCTION', name, r.provider, r.security_label, o_data.pronamespace, o_data.proargtypenames) }}
{% endfor %}
{% endif -%}
{% if 'changed' in seclabels and seclabels.changed|length > 0 %}
{% for r in seclabels.changed %}
{{ SECLABEL.SET(conn, 'FUNCTION', name, r.provider, r.security_label, o_data.pronamespace, o_data.proargtypenames) }}
{% endfor %}{% endif -%}
{% if data.description %}
COMMENT ON FUNCTION {{ conn|qtIdent(o_data.pronamespace, name) }}({{o_data.proargtypenames }})
IS {{ data.description|qtLiteral }};
{% endif -%}
{% if data.pronamespace %}
ALTER FUNCTION {{ conn|qtIdent(o_data.pronamespace, name) }}({{o_data.proargtypenames }})
SET SCHEMA {{ conn|qtIdent(data.pronamespace) }};
{% endif -%}
{% endif %}

View File

@ -0,0 +1,6 @@
SELECT
name, vartype, min_val, max_val, enumvals
FROM
pg_settings
WHERE
context in ('user', 'superuser');

View File

@ -0,0 +1,35 @@
SELECT
COALESCE(gt.rolname, 'public') AS grantee,
g.rolname AS grantor, array_agg(privilege_type) AS privileges,
array_agg(is_grantable) AS grantable
FROM
(SELECT
d.grantee, d.grantor, d.is_grantable,
CASE d.privilege_type
WHEN 'CONNECT' THEN 'c'
WHEN 'CREATE' THEN 'C'
WHEN 'DELETE' THEN 'd'
WHEN 'EXECUTE' THEN 'X'
WHEN 'INSERT' THEN 'a'
WHEN 'REFERENCES' THEN 'x'
WHEN 'SELECT' THEN 'r'
WHEN 'TEMPORARY' THEN 'T'
WHEN 'TRIGGER' THEN 't'
WHEN 'TRUNCATE' THEN 'D'
WHEN 'UPDATE' THEN 'w'
WHEN 'USAGE' THEN 'U'
ELSE 'UNKNOWN'
END AS privilege_type
FROM
(SELECT
(d).grantee AS grantee, (d).grantor AS grantor,
(d).is_grantable AS is_grantable,
(d).privilege_type AS privilege_type
FROM
(SELECT aclexplode(db.proacl) AS d FROM pg_proc db
WHERE db.oid = {{fnid}}::OID) a
) d
) d
LEFT JOIN pg_catalog.pg_roles g ON (d.grantor = g.oid)
LEFT JOIN pg_catalog.pg_roles gt ON (d.grantee = gt.oid)
GROUP BY g.rolname, gt.rolname;

View File

@ -0,0 +1,57 @@
{% import 'macros/functions/security.macros' as SECLABEL %}
{% import 'macros/functions/privilege.macros' as PRIVILEGE %}
{% import 'macros/functions/variable.macros' as VARIABLE %}
{% set is_columns = [] %}
{% if data %}
CREATE FUNCTION {{ conn|qtIdent(data.pronamespace, data.name) }}({% if data.arguments %}
{% for p in data.arguments %}{% if p.argmode %}{{p.argmode}} {% endif %}{% if p.argname %}{{ conn|qtIdent(p.argname)}} {% endif %}{% if p.argtype %}{{p.argtype}}{% endif %}{% if p.argdefval %} DEFAULT {{p.argdefval}}{% endif %}
{% if not loop.last %},{% endif %}
{% endfor %}
{% endif -%}
)
RETURNS{% if data.proretset %} SETOF{% endif %} {{ conn|qtTypeIdent(data.prorettypename) }}
LANGUAGE {{ data.lanname|qtLiteral }}
{% if data.provolatile %}{{ data.provolatile }} {% endif %}{% if data.proleakproof %} LEAKPROOF {% else %} NOT LEAKPROOF {% endif %}
{% if data.proisstrict %}STRICT {% endif %}
{% if data.prosecdef %}SECURITY DEFINER {% endif %}
{% if data.proiswindow %}WINDOW{% endif %}{% if data.procost %}
COST {{data.procost}}{% endif %}{% if data.prorows %}
ROWS {{data.prorows}}{% endif -%}{% if data.variables %}{% for v in data.variables %}
SET {{ conn|qtIdent(v.name) }}={{ v.value|qtLiteral }}{% endfor %}
{% endif %}
AS {% if data.lanname == 'c' %}
{{ data.probin|qtLiteral }}, {{ data.prosrc_c|qtLiteral }}
{% else %}
$function$
{{ data.prosrc }}
$function${% endif -%};
{% if data.funcowner %}
ALTER FUNCTION {{ conn|qtIdent(data.pronamespace, data.name) }}({{data.func_args}})
OWNER TO {{ data.funcowner }};
{% endif -%}
{% if data.acl %}
{% for p in data.acl %}
{{ PRIVILEGE.SET(conn, "FUNCTION", p.grantee, data.name, p.without_grant, p.with_grant, data.pronamespace, data.func_args)}}
{% endfor -%}
{% endif -%}
{% if data.description %}
COMMENT ON FUNCTION {{ conn|qtIdent(data.pronamespace, data.name) }}({{data.func_args}})
IS '{{ data.description }}';
{% endif -%}
{% if data.seclabels %}
{% for r in data.seclabels %}
{% if r.security_label and r.provider %}
{{ SECLABEL.SET(conn, 'FUNCTION', data.name, r.provider, r.security_label, data.pronamespace, data.func_args) }}
{% endif %}
{% endfor %}
{% endif -%}
{% endif -%}

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
proisagg = FALSE
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,11 @@
SELECT
pg_get_functiondef({{fnid}}::oid) AS func_def,
nspname || '.' || pr.proname || '(' || COALESCE(pg_catalog.pg_get_function_identity_arguments(pr.oid), '') || ')' as name
FROM
pg_proc pr
JOIN
pg_namespace nsp ON nsp.oid=pr.pronamespace
WHERE
proisagg = FALSE
AND pronamespace = {{scid}}::oid
AND pr.oid = {{fnid}}::oid;

View File

@ -0,0 +1,4 @@
SELECT
lanname as label, lanname as value
FROM
pg_language;

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
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
proisagg = FALSE
AND typname NOT IN ('trigger', 'event_trigger')
AND pr.proname = {{ name|qtLiteral }};

View File

@ -0,0 +1,6 @@
SELECT
format_type(oid, NULL) AS out_arg_type
FROM
pg_type
WHERE
oid = {{ out_arg_oid }}::oid;

View File

@ -0,0 +1,6 @@
SELECT
nspname
FROM
pg_namespace
WHERE
oid = {{ scid }}::oid;

View File

@ -0,0 +1,20 @@
SELECT
*
FROM
(SELECT
format_type(t.oid,NULL) AS typname,
CASE WHEN typelem > 0 THEN typelem ELSE t.oid END as elemoid, typlen, typtype, t.oid, nspname,
(SELECT COUNT(1) FROM pg_type t2 WHERE t2.typname = t.typname) > 1 AS isdup
FROM
pg_type t
JOIN
pg_namespace nsp ON typnamespace=nsp.oid
WHERE
(NOT (typname = 'unknown' AND nspname = 'pg_catalog'))
AND
(
typtype IN ('b', 'c', 'd', 'e', 'p', 'r')
AND typname NOT IN ('any', 'trigger', 'language_handler', 'event_trigger')
)
) AS dummy
ORDER BY nspname <> 'pg_catalog', nspname <> 'public', nspname, 1;

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, 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
proisagg = FALSE
AND pr.protype = '0'::char
AND pronamespace = {{scid}}::oid
AND typname NOT IN ('trigger', 'event_trigger')
ORDER BY
proname;

View File

@ -0,0 +1,31 @@
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_shseclabel 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
proisagg = FALSE
AND pronamespace = {{scid}}::oid
AND typname NOT IN ('trigger', 'event_trigger')
{% if fnid %}
AND pr.oid = {{fnid}}::oid
{% endif %}
ORDER BY
proname;

View File

@ -0,0 +1,114 @@
{% import 'macros/functions/security.macros' as SECLABEL %}
{% import 'macros/functions/privilege.macros' as PRIVILEGE %}
{% import 'macros/functions/variable.macros' as VARIABLE %}{% if data %}
{% set name = o_data.name %}
{% if data.name %}
{% if data.name != o_data.name %}
ALTER FUNCTION {{ conn|qtIdent(o_data.pronamespace, o_data.name) }}({{o_data.proargtypenames }})
RENAME TO {{ conn|qtIdent(data.name) }};
{% set name = data.name %}
{% endif %}
{% endif -%}
{% if data.change_func %}
CREATE OR REPLACE FUNCTION {{ conn|qtIdent(o_data.pronamespace, name) }}({% if data.arguments %}
{% for p in data.arguments %}{% if p.argmode %}{{p.argmode}} {% endif %}{% if p.argname %}{{conn|qtIdent(p.argname)}} {% endif %}{% if p.argtype %}{{p.argtype}}{% endif %}{% if p.argdefval %} DEFAULT {{p.argdefval}}{% endif %}
{% if not loop.last %}, {% endif %}
{% endfor %}
{% endif -%}
)
RETURNS {{ o_data.prorettypename }}
{% if 'lanname' in data %}
LANGUAGE {{ data.lanname|qtLiteral }} {% else %}
LANGUAGE {{ o_data.lanname|qtLiteral }}
{% endif %}{% if 'provolatile' in data and data.provolatile %}{{ data.provolatile }} {% elif 'provolatile' not in data and o_data.provolatile %}{{ o_data.provolatile }}{% endif %}
{% if ('proleakproof' in data and data.proleakproof) or ('proleakproof' not in data and o_data.proleakproof) %} LEAKPROOF{% elif 'proleakproof' in data and not data.proleakproof %} NOT LEAKPROOF{% endif %}
{% if ('proisstrict' in data and data.proisstrict) or ('proisstrict' not in data and o_data.proisstrict) %} STRICT{% endif %}
{% if ('prosecdef' in data and data.prosecdef) or ('prosecdef' not in data and o_data.prosecdef) %} SECURITY DEFINER{% endif %}
{% if ('proiswindow' in data and data.proiswindow) or ('proiswindow' not in data and o_data.proiswindow) %} WINDOW{% endif %}
{% if data.procost %}COST {{data.procost}}{% elif o_data.procost %}COST {{o_data.procost}}{% endif %}{% if data.prorows %}
ROWS {{data.prorows}}{% elif o_data.prorows %}ROWS {{o_data.prorows}}{% endif -%}{% if data.merged_variables %}{% for v in data.merged_variables %}
SET {{ conn|qtIdent(v.name) }}={{ v.value|qtLiteral }}{% endfor -%}
{% endif %}
AS {% if 'probin' in data or 'prosrc_c' in data %}
{% if 'probin' in data %}{{ data.probin|qtLiteral }}{% else %}{{ o_data.probin|qtLiteral }}{% endif %}, {% if 'prosrc_c' in data %}{{ data.prosrc_c|qtLiteral }}{% else %}{{ o_data.prosrc_c|qtLiteral }}{% endif %}{% elif 'prosrc' in data %}
$function${{ data.prosrc }}$function${% elif o_data.lanname == 'c' %}
{{ o_data.probin|qtLiteral }}, {{ o_data.prosrc_c|qtLiteral }}{% else %}
$function${{ o_data.prosrc }}$function${% endif -%};
{% endif -%}
{% if data.funcowner %}
ALTER FUNCTION {{ conn|qtIdent(o_data.pronamespace, name) }}({{ o_data.proargtypenames }})
OWNER TO {{ data.funcowner }};
{% endif -%}
{# The SQL generated below will change priviledges #}
{% if data.acl %}
{% if 'deleted' in data.acl %}
{% for priv in data.acl.deleted %}
{{ PRIVILEGE.UNSETALL(conn, 'FUNCTION', priv.grantee, name, o_data.pronamespace, o_data.proargtypenames) }}
{% endfor %}
{% endif -%}
{% if 'changed' in data.acl %}
{% for priv in data.acl.changed %}
{{ PRIVILEGE.UNSETALL(conn, 'FUNCTION', priv.grantee, name, o_data.pronamespace, o_data.proargtypenames) }}
{{ PRIVILEGE.SET(conn, 'FUNCTION', priv.grantee, name, priv.without_grant, priv.with_grant, o_data.pronamespace, o_data.proargtypenames) }}
{% endfor %}
{% endif -%}
{% if 'added' in data.acl %}
{% for priv in data.acl.added %}
{{ PRIVILEGE.SET(conn, 'FUNCTION', priv.grantee, name, priv.without_grant, priv.with_grant, o_data.pronamespace, o_data.proargtypenames) }}
{% endfor %}
{% endif %}
{% endif -%}
{% if data.change_func == False %}
{% if data.variables %}
{% if 'deleted' in data.variables and data.variables.deleted|length > 0 %}
{{ VARIABLE.UNSET(conn, 'FUNCTION', name, data.variables.deleted, o_data.pronamespace, o_data.proargtypenames ) }}
{% endif -%}
{% if 'merged_variables' in data and data.merged_variables|length > 0 %}
{{ VARIABLE.SET(conn, 'FUNCTION', name, data.merged_variables, o_data.pronamespace, o_data.proargtypenames ) }}
{% endif -%}
{% endif -%}
{% endif -%}
{% set seclabels = data.seclabels %}
{% if 'deleted' in seclabels and seclabels.deleted|length > 0 %}
{% for r in seclabels.deleted %}
{{ SECLABEL.UNSET(conn, 'FUNCTION', name, r.provider, o_data.pronamespace, o_data.proargtypenames) }}
{% endfor %}
{% endif -%}
{% if 'added' in seclabels and seclabels.added|length > 0 %}
{% for r in seclabels.added %}
{{ SECLABEL.SET(conn, 'FUNCTION', name, r.provider, r.security_label, o_data.pronamespace, o_data.proargtypenames) }}
{% endfor %}
{% endif -%}
{% if 'changed' in seclabels and seclabels.changed|length > 0 %}
{% for r in seclabels.changed %}
{{ SECLABEL.SET(conn, 'FUNCTION', name, r.provider, r.security_label, o_data.pronamespace, o_data.proargtypenames) }}
{% endfor %}
{% endif -%}
{% if data.description %}
COMMENT ON FUNCTION {{ conn|qtIdent(o_data.pronamespace, name) }}({{ o_data.proargtypenames }})
IS {{ data.description|qtLiteral }};
{% endif -%}
{% if data.pronamespace %}
ALTER FUNCTION {{ conn|qtIdent(o_data.pronamespace, name) }}({{ o_data.proargtypenames }})
SET SCHEMA {{ conn|qtIdent(data.pronamespace) }};
{% endif -%}
{% endif %}

View File

@ -0,0 +1,6 @@
SELECT
name, vartype, min_val, max_val, enumvals
FROM
pg_settings
WHERE
context in ('user', 'superuser');

View File

@ -0,0 +1,35 @@
SELECT
COALESCE(gt.rolname, 'public') AS grantee,
g.rolname AS grantor, array_agg(privilege_type) AS privileges,
array_agg(is_grantable) AS grantable
FROM
(SELECT
d.grantee, d.grantor, d.is_grantable,
CASE d.privilege_type
WHEN 'CONNECT' THEN 'c'
WHEN 'CREATE' THEN 'C'
WHEN 'DELETE' THEN 'd'
WHEN 'EXECUTE' THEN 'X'
WHEN 'INSERT' THEN 'a'
WHEN 'REFERENCES' THEN 'x'
WHEN 'SELECT' THEN 'r'
WHEN 'TEMPORARY' THEN 'T'
WHEN 'TRIGGER' THEN 't'
WHEN 'TRUNCATE' THEN 'D'
WHEN 'UPDATE' THEN 'w'
WHEN 'USAGE' THEN 'U'
ELSE 'UNKNOWN'
END AS privilege_type
FROM
(SELECT
(d).grantee AS grantee, (d).grantor AS grantor,
(d).is_grantable AS is_grantable,
(d).privilege_type AS privilege_type
FROM
(SELECT aclexplode(db.proacl) AS d FROM pg_proc db
WHERE db.oid = {{fnid}}::OID) a
) d
) d
LEFT JOIN pg_catalog.pg_roles g ON (d.grantor = g.oid)
LEFT JOIN pg_catalog.pg_roles gt ON (d.grantee = gt.oid)
GROUP BY g.rolname, gt.rolname;

View File

@ -0,0 +1,57 @@
{% import 'macros/functions/security.macros' as SECLABEL %}
{% import 'macros/functions/privilege.macros' as PRIVILEGE %}
{% import 'macros/functions/variable.macros' as VARIABLE %}
{% set is_columns = [] %}
{% if data %}
CREATE FUNCTION {{ conn|qtIdent(data.pronamespace, data.name) }}({% if data
.arguments %}
{% for p in data.arguments %}{% if p.argmode %}{{p.argmode}} {% endif %}{% if p.argname %}{{ conn|qtIdent(p.argname)}}{% endif %}{% if p.argtype %}{{p.argtype}}{% endif %}{% if p.argdefval %} DEFAULT {{p.argdefval}}{% endif %}
{% if not loop.last %},{% endif %}
{% endfor %}
{% endif -%}
)
RETURNS{% if data.proretset %} SETOF{% endif %} {{ conn|qtTypeIdent(data.prorettypename) }}
LANGUAGE {{ data.lanname|qtLiteral }}
{% if data.provolatile %}{{ data.provolatile }} {% endif %}{% if data.proleakproof %}LEAKPROOF {% else %}NOT LEAKPROOF {% endif %}
{% if data.proisstrict %}STRICT {% endif %}
{% if data.prosecdef %}SECURITY DEFINER {% endif %}
{% if data.proiswindow %}WINDOW{% endif %}{% if data.procost %}
COST {{data.procost}}{% endif %}{% if data.prorows %}
ROWS {{data.prorows}}{% endif -%}{% if data.variables %}{% for v in data.variables %}
SET {{ conn|qtIdent(v.name) }}={{ v.value|qtLiteral }}{% endfor %}
{% endif %}
AS {% if data.lanname == 'c' %}
{{ data.probin|qtLiteral }}, {{ data.prosrc_c|qtLiteral }}
{% else %}
$function$
{{ data.prosrc }}
$function${% endif -%};
{% if data.funcowner %}
ALTER FUNCTION {{ conn|qtIdent(data.pronamespace, data.name) }}({{data.func_args}})
OWNER TO {{ data.funcowner }};
{% endif -%}
{% if data.acl %}
{% for p in data.acl %}
{{ PRIVILEGE.SET(conn, "FUNCTION", p.grantee, data.name, p.without_grant, p.with_grant, data.pronamespace, data.func_args)}}
{% endfor %}{% endif %}
{% if data.description %}
COMMENT ON FUNCTION {{ conn|qtIdent(data.pronamespace, data.name) }}({{data.func_args}})
IS '{{ data.description }}';
{% endif -%}
{% if data.seclabels %}
{% for r in data.seclabels %}
{% if r.security_label and r.provider %}
{{ SECLABEL.SET(conn, 'FUNCTION', data.name, r.provider, r.security_label, data.pronamespace, data.func_args) }}
{% endif %}
{% endfor %}
{% endif -%}
{% endif %}

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
proisagg = FALSE
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,11 @@
SELECT
pg_get_functiondef({{fnid}}::oid) AS func_def,
nspname || '.' || pr.proname || '(' || COALESCE(pg_catalog.pg_get_function_identity_arguments(pr.oid), '') || ')' as name
FROM
pg_proc pr
JOIN
pg_namespace nsp ON nsp.oid=pr.pronamespace
WHERE
proisagg = FALSE
AND pronamespace = {{scid}}::oid
AND pr.oid = {{fnid}}::oid;

View File

@ -0,0 +1,4 @@
SELECT
lanname as label, lanname as value
FROM
pg_language;

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
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
proisagg = FALSE
AND typname NOT IN ('trigger', 'event_trigger')
AND pr.proname = {{ name|qtLiteral }};

View File

@ -0,0 +1,6 @@
SELECT
format_type(oid, NULL) AS out_arg_type
FROM
pg_type
WHERE
oid = {{ out_arg_oid }}::oid;

View File

@ -0,0 +1,6 @@
SELECT
nspname
FROM
pg_namespace
WHERE
oid = {{ scid }}::oid;

View File

@ -0,0 +1,20 @@
SELECT
*
FROM
(SELECT
format_type(t.oid,NULL) AS typname,
CASE WHEN typelem > 0 THEN typelem ELSE t.oid END as elemoid, typlen, typtype, t.oid, nspname,
(SELECT COUNT(1) FROM pg_type t2 WHERE t2.typname = t.typname) > 1 AS isdup
FROM
pg_type t
JOIN
pg_namespace nsp ON typnamespace=nsp.oid
WHERE
(NOT (typname = 'unknown' AND nspname = 'pg_catalog'))
AND
(
typtype IN ('b', 'c', 'd', 'e', 'p', 'r')
AND typname NOT IN ('any', 'trigger', 'language_handler', 'event_trigger')
)
) AS dummy
ORDER BY nspname <> 'pg_catalog', nspname <> 'public', nspname, 1;

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, 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
proisagg = FALSE
AND pr.protype = '0'::char
AND pronamespace = {{scid}}::oid
AND typname NOT IN ('trigger', 'event_trigger')
ORDER BY
proname;

View File

@ -0,0 +1,31 @@
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_shseclabel 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
proisagg = FALSE
AND pronamespace = {{scid}}::oid
AND typname NOT IN ('trigger', 'event_trigger')
{% if fnid %}
AND pr.oid = {{fnid}}::oid
{% endif %}
ORDER BY
proname;

View File

@ -0,0 +1,114 @@
{% import 'macros/functions/security.macros' as SECLABEL %}
{% import 'macros/functions/privilege.macros' as PRIVILEGE %}
{% import 'macros/functions/variable.macros' as VARIABLE %}{% if data %}
{% set name = o_data.name %}
{% if data.name %}
{% if data.name != o_data.name %}
ALTER FUNCTION {{ conn|qtIdent(o_data.pronamespace, o_data.name) }}({{
o_data.proargtypenames }})
RENAME TO {{ conn|qtIdent(data.name) }};
{% set name = data.name %}
{% endif %}
{% endif -%}
{% if data.change_func %}
CREATE OR REPLACE FUNCTION {{ conn|qtIdent(o_data.pronamespace, name) }}({% if data.arguments %}
{% for p in data.arguments %}{% if p.argmode %}{{p.argmode}} {% endif %}{% if p.argname %}{{ conn|qtIdent(p.argname) }} {% endif %}{% if p.argtype %}{{p.argtype}}{% endif %}{% if p.argdefval %} DEFAULT {{p.argdefval}}{% endif %}
{% if not loop.last %},{% endif %}
{% endfor %}
{% endif -%}
)
RETURNS {{ o_data.prorettypename }}
{% if 'lanname' in data %}
LANGUAGE {{ data.lanname|qtLiteral }} {% else %}
LANGUAGE {{ o_data.lanname|qtLiteral }}
{% endif %}{% if 'provolatile' in data and data.provolatile %}{{ data.provolatile }} {% elif 'provolatile' not in data and o_data.provolatile %}{{ o_data.provolatile }}{% endif %}
{% if ('proleakproof' in data and data.proleakproof) or ('proleakproof' not in data and o_data.proleakproof) %} LEAKPROOF{% elif 'proleakproof' in data and not data.proleakproof %} NOT LEAKPROOF{% endif %}
{% if ('proisstrict' in data and data.proisstrict) or ('proisstrict' not in data and o_data.proisstrict) %} STRICT{% endif %}
{% if ('prosecdef' in data and data.prosecdef) or ('prosecdef' not in data and o_data.prosecdef) %} SECURITY DEFINER{% endif %}
{% if ('proiswindow' in data and data.proiswindow) or ('proiswindow' not in data and o_data.proiswindow) %} WINDOW{% endif %}
{% if data.procost %}COST {{data.procost}}{% elif o_data.procost %}COST {{o_data.procost}}{% endif %}{% if data.prorows %}
ROWS {{data.prorows}}{% elif o_data.prorows %}ROWS {{o_data.prorows}} {%endif -%}{% if data.merged_variables %}{% for v in data.merged_variables %}
SET {{ conn|qtIdent(v.name) }}={{ v.value|qtLiteral }}{% endfor -%}
{% endif %}
AS {% if 'probin' in data or 'prosrc_c' in data %}
{% if 'probin' in data %}{{ data.probin|qtLiteral }}{% else %}{{ o_data.probin|qtLiteral }}{% endif %}, {% if 'prosrc_c' in data %}{{ data.prosrc_c|qtLiteral }}{% else %}{{ o_data.prosrc_c|qtLiteral }}{% endif %}{% elif 'prosrc' in data %}
$function${{ data.prosrc }}$function${% elif o_data.lanname == 'c' %}
{{ o_data.probin|qtLiteral }}, {{ o_data.prosrc_c|qtLiteral }}{% else %}
$function${{ o_data.prosrc }}$function${% endif -%};
{% endif -%}
{% if data.funcowner %}
ALTER FUNCTION {{ conn|qtIdent(o_data.pronamespace, name) }}({{o_data.proargtypenames }})
OWNER TO {{ data.funcowner }};
{% endif -%}
{# The SQL generated below will change priviledges #}
{% if data.acl %}
{% if 'deleted' in data.acl %}
{% for priv in data.acl.deleted %}
{{ PRIVILEGE.UNSETALL(conn, 'FUNCTION', priv.grantee, name, o_data.pronamespace, o_data.proargtypenames) }}
{% endfor %}
{% endif -%}
{% if 'changed' in data.datacl %}
{% for priv in data.acl.changed %}
{{ PRIVILEGE.UNSETALL(conn, 'FUNCTION', priv.grantee, name, o_data.pronamespace, o_data.proargtypenames) }}
{{ PRIVILEGE.SET(conn, 'FUNCTION', priv.grantee, name, priv.without_grant, priv.with_grant, o_data.pronamespace, o_data.proargtypenames) }}
{% endfor %}
{% endif -%}
{% if 'added' in data.acl %}
{% for priv in data.acl.added %}
{{ PRIVILEGE.SET(conn, 'FUNCTION', priv.grantee, name, priv.without_grant, priv.with_grant, o_data.pronamespace, o_data.proargtypenames) }}
{% endfor %}{% endif -%}
{% endif -%}
{% if data.change_func == False %}
{% if data.variables %}
{% if 'deleted' in data.variables and data.variables.deleted|length > 0 %}
{{ VARIABLE.UNSET(conn, 'FUNCTION', name, data.variables.deleted, o_data.pronamespace, o_data.proargtypenames) }}
{% endif -%}
{% if 'merged_variables' in data and data.merged_variables|length > 0 %}
{{ VARIABLE.SET(conn, 'FUNCTION', name, data.merged_variables, o_data.pronamespace, o_data.proargtypenames) }}
{% endif -%}
{% endif -%}
{% endif -%}
{% set seclabels = data.seclabels %}
{% if 'deleted' in seclabels and seclabels.deleted|length > 0 %}
{% for r in seclabels.deleted %}
{{ SECLABEL.UNSET(conn, 'FUNCTION', name, r.provider, o_data.pronamespace, o_data.proargtypenames) }}
{% endfor %}
{% endif -%}
{% if 'added' in seclabels and seclabels.added|length > 0 %}
{% for r in seclabels.added %}
{{ SECLABEL.SET(conn, 'FUNCTION', name, r.provider, r.security_label, o_data.pronamespace, o_data.proargtypenames) }}
{% endfor %}
{% endif -%}
{% if 'changed' in seclabels and seclabels.changed|length > 0 %}
{% for r in seclabels.changed %}
{{ SECLABEL.SET(conn, 'FUNCTION', name, r.provider, r.security_label, o_data.pronamespace, o_data.proargtypenames) }}
{% endfor %}
{% endif -%}
{% if data.description %}
COMMENT ON FUNCTION {{ conn|qtIdent(o_data.pronamespace, name) }}({{o_data.proargtypenames }})
IS {{ data.description|qtLiteral }};
{% endif -%}
{% if data.pronamespace %}
ALTER FUNCTION {{ conn|qtIdent(o_data.pronamespace, name) }}({{o_data.proargtypenames }})
SET SCHEMA {{ conn|qtIdent(data.pronamespace) }};
{% endif -%}
{% endif %}

View File

@ -0,0 +1,6 @@
SELECT
name, vartype, min_val, max_val, enumvals
FROM
pg_settings
WHERE
context in ('user', 'superuser');

View File

@ -0,0 +1,184 @@
/* Create and Register Procedure Collection and Node. */
define(
['jquery', 'underscore', 'underscore.string',
'pgadmin', 'pgadmin.browser', 'alertify',
'pgadmin.node.function', 'pgadmin.browser.collection',
'pgadmin.browser.server.privilege'],
function($, _, S, pgAdmin, pgBrowser, alertify, Function) {
if (!pgBrowser.Nodes['coll-procedure']) {
var procedures = pgAdmin.Browser.Nodes['coll-procedure'] =
pgAdmin.Browser.Collection.extend({
node: 'procedure',
label: '{{ _('Procedures') }}',
type: 'coll-procedure',
columns: ['name', 'funcowner', 'description']
});
};
pgSchemaNode = pgBrowser.Nodes['schema'];
// Inherit Functions Node
if (!pgBrowser.Nodes['procedure']) {
pgAdmin.Browser.Nodes['procedure'] = Function.extend({
type: 'procedure',
label: '{{ _('Procedure') }}',
collection_type: 'coll-procedure',
hasSQL: true,
hasDepends: true,
parent_type: ['schema'],
Init: function() {
/* Avoid mulitple registration of menus */
if (this.proc_initialized)
return;
this.proc_initialized = true;
pgBrowser.add_menus([{
name: 'create_procedure_on_coll', node: 'coll-procedure', module:
this,
applies: ['object', 'context'], callback: 'show_obj_properties',
category: 'create', priority: 4, label: '{{ _('Procedure...') }}',
icon: 'wcTabIcon icon-procedure', data: {action: 'create', check:
false}
},{
name: 'create_procedure', node: 'procedure', module: this,
applies: ['object', 'context'], callback: 'show_obj_properties',
category: 'create', priority: 4, label: '{{ _('Procedure...') }}',
icon: 'wcTabIcon icon-procedure', data: {action: 'create', check:
true},
},{
name: 'create_procedure', node: 'schema', module: this,
applies: ['object', 'context'], callback: 'show_obj_properties',
category: 'create', priority: 4, label: '{{ _('Procedure...') }}',
icon: 'wcTabIcon icon-procedure', data: {action: 'create', check:
true}, enable: 'canCreateProc'
}
]);
},
canDrop: pgSchemaNode.canChildDrop,
canDropCascade: pgSchemaNode.canChildDrop,
model: Function.model.extend({
defaults: _.extend({},
Function.model.prototype.defaults,
{
lanname: 'edbspl'
}
),
canVarAdd: function(m){
var server = this.node_info.server;
if (server.version < 90500) {
return false;
}
else {
return true;
}
},
isVisible: function(m){
if (this.name == 'sysfunc') { return false; }
else if (this.name == 'sysproc') { return true; }
return false;
},
isDisabled: function(m) {
if(this.node_info && 'catalog' in this.node_info) {
return true;
}
name = this.name;
switch(name){
case 'provolatility':
case 'proisstrict':
case 'prosecdef':
case 'procost':
case 'proleakproof':
case 'variables':
var server = this.node_info.server;
if (server.version < 90500) {
return true;
}
else {
return false;
}
break;
case 'prorows':
var server = this.node_info.server;
if(server.version >= 90500 && m.get('proretset') == true) {
return false;
}
else {
return true;
}
break;
case 'funcowner':
case 'lanname':
case 'proargs':
return true;
default:
return false;
break;
}
return false;
},
validate: function()
{
var err = {},
errmsg,
seclabels = this.get('seclabels');
if (_.isUndefined(this.get('name')) || String(this.get('name')).replace(/^\s+|\s+$/g, '') == '') {
err['name'] = '{{ _('Name can not be empty!') }}';
errmsg = errmsg || err['name'];
}
if (_.isUndefined(this.get('pronamespace')) || String(this.get('pronamespace')).replace(/^\s+|\s+$/g, '') == '') {
err['pronamespace'] = '{{ _('Schema can not be empty!') }}';
errmsg = errmsg || err['pronamespace'];
}
if (_.isUndefined(this.get('lanname')) || String(this.get('lanname')).replace(/^\s+|\s+$/g, '') == '') {
err['lanname'] = '{{ _('Language can not be empty!') }}';
errmsg = errmsg || err['lanname'];
}
if (_.isUndefined(this.get('prosrc')) || String(this.get('prosrc')).replace(/^\s+|\s+$/g, '') == '') {
err['prosrc'] = '{{ _('Code can not be empty!') }}';
errmsg = errmsg || err['prosrc'];
}
if (seclabels) {
var secLabelsErr;
for (var i = 0; i < seclabels.models.length && !secLabelsErr; i++) {
secLabelsErr = (seclabels.models[i]).validate.apply(seclabels.models[i]);
if (secLabelsErr) {
err['seclabels'] = secLabelsErr;
errmsg = errmsg || secLabelsErr;
}
}
}
this.errorModel.clear().set(err);
return null;
},
}
),
canCreateProc: function(itemData, item, data) {
var node_hierarchy = this.getTreeNodeHierarchy.apply(this, [item]);
// Do not provide Create option in catalog
if ('catalog' in node_hierarchy)
return false;
// Procedures supported only in PPAS
if ('server' in node_hierarchy && node_hierarchy['server'].type == "ppas")
return true;
return false;
}
});
}
return pgBrowser.Nodes['procedure'];
});

View File

@ -0,0 +1,35 @@
SELECT
COALESCE(gt.rolname, 'public') AS grantee,
g.rolname AS grantor, array_agg(privilege_type) AS privileges,
array_agg(is_grantable) AS grantable
FROM
(SELECT
d.grantee, d.grantor, d.is_grantable,
CASE d.privilege_type
WHEN 'CONNECT' THEN 'c'
WHEN 'CREATE' THEN 'C'
WHEN 'DELETE' THEN 'd'
WHEN 'EXECUTE' THEN 'X'
WHEN 'INSERT' THEN 'a'
WHEN 'REFERENCES' THEN 'x'
WHEN 'SELECT' THEN 'r'
WHEN 'TEMPORARY' THEN 'T'
WHEN 'TRIGGER' THEN 't'
WHEN 'TRUNCATE' THEN 'D'
WHEN 'UPDATE' THEN 'w'
WHEN 'USAGE' THEN 'U'
ELSE 'UNKNOWN'
END AS privilege_type
FROM
(SELECT
(d).grantee AS grantee, (d).grantor AS grantor,
(d).is_grantable AS is_grantable,
(d).privilege_type AS privilege_type
FROM
(SELECT aclexplode(db.proacl) AS d FROM pg_proc db
WHERE db.oid = {{fnid}}::OID) a
) d
) d
LEFT JOIN pg_catalog.pg_roles g ON (d.grantor = g.oid)
LEFT JOIN pg_catalog.pg_roles gt ON (d.grantee = gt.oid)
GROUP BY g.rolname, gt.rolname;

View File

@ -0,0 +1,33 @@
{% import 'macros/functions/security.macros' as SECLABEL %}
{% import 'macros/functions/privilege.macros' as PRIVILEGE %}
{% import 'macros/functions/variable.macros' as VARIABLE %}
{% set is_columns = [] %}
{% if data %}
CREATE OR REPLACE PROCEDURE {{ conn|qtIdent(data.pronamespace, data.name) }}{% if data.arguments %}(
{% for p in data.arguments %}{% if p.argmode %}{{p.argmode}} {% endif %}{% if p.argname %}{{ conn|qtIdent(p.argname)}} {% endif %}{% if p.argtype %}{{p.argtype}}{% endif %}{% if p.argdefval %} DEFAULT {{p.argdefval}}{% endif %}
{% if not loop.last %},{% endif %}
{% endfor %})
{% endif %}
AS
{{ data.prosrc }};
{% if data.acl and not is_sql %}
{% for p in data.acl %}
{{ PRIVILEGE.SET(conn, "PROCEDURE", p.grantee, data.name, p.without_grant, p.with_grant, data.pronamespace, data.func_args)}}
{% endfor %}{% endif %}
{% if data.description %}
COMMENT ON PROCEDURE {{ conn|qtIdent(data.pronamespace, data.name) }}
IS '{{ data.description }}';
{% endif -%}
{% if data.seclabels %}
{% for r in data.seclabels %}
{% if r.label and r.provider %}
{{ SECLABEL.SET(conn, 'PROCEDURE', data.name, r.provider, r.label, data.pronamespace, data.func_args) }}
{% endif %}
{% endfor %}
{% endif -%}
{% endif %}

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
proisagg = FALSE
AND pronamespace = {{scid}}::oid
AND typname NOT IN ('trigger', 'event_trigger')
AND pr.oid = {{fnid}};
{% endif %}
{% if name %}
DROP PROCEDURE {{ conn|qtIdent(nspname, name) }}{{func_args}}{% if cascade %} CASCADE{% endif %};
{% endif %}

View File

@ -0,0 +1,12 @@
SELECT
pg_get_functiondef({{fnid}}::oid) AS func_def,
nspname || '.' || pr.proname || '(' || COALESCE(pg_catalog
.pg_get_function_identity_arguments(pr.oid), '') || ')' as name
FROM
pg_proc pr
JOIN
pg_namespace nsp ON nsp.oid=pr.pronamespace
WHERE
proisagg = FALSE
AND pronamespace = {{scid}}::oid
AND pr.oid = {{fnid}}::oid;

View File

@ -0,0 +1,4 @@
SELECT
lanname as label, lanname as value
FROM
pg_language;

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
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
proisagg = FALSE
AND typname NOT IN ('trigger', 'event_trigger')
AND pr.proname = {{ name|qtLiteral }};

View File

@ -0,0 +1,6 @@
SELECT
format_type(oid, NULL) AS out_arg_type
FROM
pg_type
WHERE
oid = {{ out_arg_oid }}::oid;

View File

@ -0,0 +1,6 @@
SELECT
nspname
FROM
pg_namespace
WHERE
oid = {{ scid }}::oid;

View File

@ -0,0 +1,20 @@
SELECT
*
FROM
(SELECT
format_type(t.oid,NULL) AS typname,
CASE WHEN typelem > 0 THEN typelem ELSE t.oid END as elemoid, typlen, typtype, t.oid, nspname,
(SELECT COUNT(1) FROM pg_type t2 WHERE t2.typname = t.typname) > 1 AS isdup
FROM
pg_type t
JOIN
pg_namespace nsp ON typnamespace=nsp.oid
WHERE
(NOT (typname = 'unknown' AND nspname = 'pg_catalog'))
AND
(
typtype IN ('b', 'c', 'd', 'e', 'p', 'r')
AND typname NOT IN ('any', 'trigger', 'language_handler', 'event_trigger')
)
) AS dummy
ORDER BY nspname <> 'pg_catalog', nspname <> 'public', nspname, 1;

View File

@ -0,0 +1,25 @@
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
proisagg = FALSE
AND pr.protype = '1'::char
AND pronamespace = {{scid}}::oid
AND typname NOT IN ('trigger', 'event_trigger')
ORDER BY
proname;

View File

@ -0,0 +1,38 @@
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
proisagg = FALSE
AND pronamespace = {{scid}}::oid
AND typname NOT IN ('trigger', 'event_trigger')
{% if fnid %}
AND pr.oid = {{fnid}}::oid
{% endif %}
ORDER BY
proname;

View File

@ -0,0 +1,82 @@
{% import 'macros/functions/security.macros' as SECLABEL %}
{% import 'macros/functions/privilege.macros' as PRIVILEGE %}{% if data %}
{% set name = o_data.name %}
{% if data.name %}
{% if data.name != o_data.name %}
ALTER PROCEDURE {{ conn|qtIdent(o_data.pronamespace, o_data.name) }}{% if o_data.proargtypenames %}({{ o_data.proargtypenames }}){% endif %}
RENAME TO {{ conn|qtIdent(data.name) }};
{% set name = data.name %}
{% endif %}
{% endif -%}
{% if data.change_func %}
CREATE OR REPLACE PROCEDURE {{ conn|qtIdent(o_data.pronamespace, name) }}{% if data.arguments %}({% for p in data.arguments %}{% if p.argmode %}{{p.argmode}} {% endif %}{% if p.argname %}{{ conn|qtIdent(p.argname) }} {% endif %}{% if p.argtype %}{{p.argtype}}{% endif %}{% if p.argdefval %} DEFAULT {{p.argdefval}}{% endif %}
{% if not loop.last %}, {% endif %}
{% endfor %}
)
{% endif %}
AS
{% if data.prosrc %}{{ data.prosrc }}{% else %}{{ o_data.prosrc }}{% endif -%};
{% endif -%}
{% if data.funcowner %}
ALTER PROCEDURE {{ conn|qtIdent(o_data.pronamespace, name) }}{% if o_data.proargtypenames %}({{ o_data.proargtypenames }}){% endif %}
OWNER TO {{ data.funcowner }};
{% endif -%}
{# The SQL generated below will change priviledges #}
{% if data.acl %}
{% if 'deleted' in data.acl %}
{% for priv in data.acl.deleted %}
{{ PRIVILEGE.UNSETALL(conn, 'PROCEDURE', priv.grantee, name, o_data.pronamespace, o_data.proargtypenames) }}
{% endfor %}
{% endif -%}
{% if 'changed' in data.datacl %}
{% for priv in data.acl.changed %}
{{ PRIVILEGE.UNSETALL(conn, 'PROCEDURE', priv.grantee, name, o_data.pronamespace, o_data.proargtypenames) }}
{{ PRIVILEGE.SET(conn, 'PROCEDURE', priv.grantee, name, priv.without_grant,
priv.with_grant, o_data.pronamespace, o_data.proargtypenames) }}
{% endfor %}
{% endif -%}
{% if 'added' in data.acl %}
{% for priv in data.acl.added %}
{{ PRIVILEGE.SET(conn, 'PROCEDURE', priv.grantee, name, priv.without_grant, priv.with_grant, o_data.pronamespace, o_data.proargtypenames) }}
{% endfor %}
{% endif %}
{% endif -%}
{% set seclabels = data.seclabels %}
{% if 'deleted' in seclabels and seclabels.deleted|length > 0 %}
{% for r in seclabels.deleted %}
{{ SECLABEL.UNSET(conn, 'PROCEDURE', name, r.provider, o_data.pronamespace, o_data.proargtypenames) }}
{% endfor %}
{% endif -%}
{% if 'added' in seclabels and seclabels.added|length > 0 %}
{% for r in seclabels.added %}
{{ SECLABEL.SET(conn, 'PROCEDURE', name, r.provider, r.security_label, o_data.pronamespace, o_data.proargtypenames) }}
{% endfor %}
{% endif -%}
{% if 'changed' in seclabels and seclabels.changed|length > 0 %}
{% for r in seclabels.changed %}
{{ SECLABEL.SET(conn, 'PROCEDURE', name, r.provider, r.security_label, o_data.pronamespace, o_data.proargtypenames) }}
{% endfor %}
{% endif -%}
{% if data.description %}
COMMENT ON PROCEDURE {{ conn|qtIdent(o_data.pronamespace, name) }}
IS {{ data.description|qtLiteral }};
{% endif -%}
{% if data.pronamespace %}
ALTER PROCEDURE {{ conn|qtIdent(o_data.pronamespace, name) }}
SET SCHEMA {{ conn|qtIdent(data.pronamespace) }};
{% endif -%}
{% endif %}

View File

@ -0,0 +1,6 @@
SELECT
name, vartype, min_val, max_val, enumvals
FROM
pg_settings
WHERE
context in ('user', 'superuser');

View File

@ -0,0 +1,35 @@
SELECT
COALESCE(gt.rolname, 'public') AS grantee,
g.rolname AS grantor, array_agg(privilege_type) AS privileges,
array_agg(is_grantable) AS grantable
FROM
(SELECT
d.grantee, d.grantor, d.is_grantable,
CASE d.privilege_type
WHEN 'CONNECT' THEN 'c'
WHEN 'CREATE' THEN 'C'
WHEN 'DELETE' THEN 'd'
WHEN 'EXECUTE' THEN 'X'
WHEN 'INSERT' THEN 'a'
WHEN 'REFERENCES' THEN 'x'
WHEN 'SELECT' THEN 'r'
WHEN 'TEMPORARY' THEN 'T'
WHEN 'TRIGGER' THEN 't'
WHEN 'TRUNCATE' THEN 'D'
WHEN 'UPDATE' THEN 'w'
WHEN 'USAGE' THEN 'U'
ELSE 'UNKNOWN'
END AS privilege_type
FROM
(SELECT
(d).grantee AS grantee, (d).grantor AS grantor,
(d).is_grantable AS is_grantable,
(d).privilege_type AS privilege_type
FROM
(SELECT aclexplode(db.proacl) AS d FROM pg_proc db
WHERE db.oid = {{fnid}}::OID) a
) d
) d
LEFT JOIN pg_catalog.pg_roles g ON (d.grantor = g.oid)
LEFT JOIN pg_catalog.pg_roles gt ON (d.grantee = gt.oid)
GROUP BY g.rolname, gt.rolname;

Some files were not shown because too many files have changed in this diff Show More