mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2025-02-25 18:55:31 -06:00
Adding support for the trigger functions node.
This commit is contained in:
parent
077075c765
commit
d2eaa8b3dd
@ -833,20 +833,30 @@ class FunctionView(PGChildNodeView, DataTypeReader):
|
||||
|
||||
try:
|
||||
if SQL and SQL.strip('\n') and SQL.strip(' '):
|
||||
|
||||
status, res = self.conn.execute_scalar(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
return make_json_response(
|
||||
success=1,
|
||||
info="Function Updated.",
|
||||
data={
|
||||
'id': fnid,
|
||||
'scid': scid,
|
||||
'sid': sid,
|
||||
'gid': gid,
|
||||
'did': did
|
||||
}
|
||||
resp_data = self._fetch_properties(gid, sid, did, scid, fnid)
|
||||
|
||||
if self.node_type == 'procedure':
|
||||
obj_name = resp_data['name_with_args']
|
||||
elif self.node_type == 'function':
|
||||
args = resp_data['proargs'] if resp_data['proargs'] else ''
|
||||
obj_name = resp_data['name'] + '({0})'.format(args)
|
||||
else:
|
||||
obj_name = resp_data['name'] + '()'
|
||||
|
||||
return jsonify(
|
||||
node=self.blueprint.generate_browser_node(
|
||||
fnid,
|
||||
resp_data['pronamespace'],
|
||||
obj_name,
|
||||
icon="icon-" + self.node_type,
|
||||
language=resp_data['lanname'],
|
||||
funcowner=resp_data['funcowner']
|
||||
)
|
||||
)
|
||||
else:
|
||||
return make_json_response(
|
||||
@ -878,6 +888,7 @@ class FunctionView(PGChildNodeView, DataTypeReader):
|
||||
"""
|
||||
|
||||
if self.node_type == 'procedure':
|
||||
object_type = 'procedure'
|
||||
resp_data = self._fetch_properties(gid, sid, did, scid, fnid)
|
||||
|
||||
# Get SQL to create Function
|
||||
@ -888,6 +899,7 @@ class FunctionView(PGChildNodeView, DataTypeReader):
|
||||
|
||||
name = resp_data['pronamespace'] + "." + resp_data['name_with_args']
|
||||
else:
|
||||
object_type = 'function'
|
||||
# Fetch the function definition.
|
||||
SQL = render_template("/".join([self.sql_template_path,
|
||||
'get_definition.sql']), fnid=fnid, scid=scid)
|
||||
@ -901,9 +913,10 @@ class FunctionView(PGChildNodeView, DataTypeReader):
|
||||
|
||||
-- DROP {0} {1};
|
||||
|
||||
""".format(self.node_type.upper(), name)
|
||||
""".format(object_type.upper(), name)
|
||||
|
||||
SQL = sql_header + func_def
|
||||
SQL = re.sub('\n{2,}', '\n\n', SQL)
|
||||
|
||||
return ajax_response(response=SQL)
|
||||
|
||||
@ -924,12 +937,15 @@ class FunctionView(PGChildNodeView, DataTypeReader):
|
||||
"""
|
||||
|
||||
status, SQL = self._get_sql(gid, sid, did, scid, self.request, fnid)
|
||||
|
||||
if status:
|
||||
SQL = re.sub('\n{2,}', '\n\n', SQL)
|
||||
return make_json_response(
|
||||
data=SQL,
|
||||
status=200
|
||||
)
|
||||
else:
|
||||
SQL = re.sub('\n{2,}', '\n\n', SQL)
|
||||
return SQL
|
||||
|
||||
def _get_sql(self, gid, sid, did, scid, data, fnid=None, is_sql=False):
|
||||
@ -1386,3 +1402,113 @@ class ProcedureView(FunctionView):
|
||||
)
|
||||
|
||||
ProcedureView.register_node_view(procedure_blueprint)
|
||||
|
||||
|
||||
class TriggerFunctionModule(SchemaChildModule):
|
||||
"""
|
||||
class TriggerFunctionModule(SchemaChildModule):
|
||||
|
||||
This class represents The Trigger function Module.
|
||||
|
||||
Methods:
|
||||
-------
|
||||
* __init__(*args, **kwargs)
|
||||
- Initialize the Trigger function Module.
|
||||
|
||||
* get_nodes(gid, sid, did, scid)
|
||||
- Generate the Trigger function collection node.
|
||||
|
||||
* node_inode():
|
||||
- Returns Trigger function node as leaf node.
|
||||
|
||||
* script_load()
|
||||
- Load the module script for Trigger function, when schema node is
|
||||
initialized.
|
||||
|
||||
"""
|
||||
|
||||
NODE_TYPE = 'trigger_function'
|
||||
COLLECTION_LABEL = gettext("Trigger function")
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""
|
||||
Initialize the Trigger function Module.
|
||||
Args:
|
||||
*args:
|
||||
**kwargs:
|
||||
"""
|
||||
super(TriggerFunctionModule, self).__init__(*args, **kwargs)
|
||||
|
||||
self.min_ver = 90100
|
||||
self.max_ver = None
|
||||
|
||||
def get_nodes(self, gid, sid, did, scid):
|
||||
"""
|
||||
Generate Trigger function collection node.
|
||||
"""
|
||||
yield self.generate_browser_collection_node(scid)
|
||||
|
||||
@property
|
||||
def node_inode(self):
|
||||
"""
|
||||
Make the node as leaf node.
|
||||
Returns:
|
||||
False as this node doesn't have child nodes.
|
||||
"""
|
||||
return False
|
||||
|
||||
@property
|
||||
def script_load(self):
|
||||
"""
|
||||
Load the module script for Trigger function, when the
|
||||
schema node is initialized.
|
||||
"""
|
||||
return schemas.SchemaModule.NODE_TYPE
|
||||
|
||||
|
||||
trigger_function_blueprint = TriggerFunctionModule(__name__)
|
||||
|
||||
|
||||
class TriggerFunctionView(FunctionView):
|
||||
|
||||
node_type = trigger_function_blueprint.node_type
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""
|
||||
Initialize the Function Module.
|
||||
Args:
|
||||
*args:
|
||||
**kwargs:
|
||||
"""
|
||||
super(TriggerFunctionView, self).__init__(*args, **kwargs)
|
||||
|
||||
@property
|
||||
def required_args(self):
|
||||
"""
|
||||
Returns Required arguments for trigger function node.
|
||||
Where
|
||||
Required Args:
|
||||
name: Name of the Trigger function
|
||||
pronamespace: Trigger function Namespace
|
||||
lanname: Trigger function Language Name
|
||||
prosrc: Trigger function Code
|
||||
"""
|
||||
return ['name',
|
||||
'pronamespace',
|
||||
'lanname',
|
||||
'prosrc']
|
||||
|
||||
def module_js(self):
|
||||
"""
|
||||
Load JS file (trigger_function.js) for this module.
|
||||
"""
|
||||
|
||||
return make_response(
|
||||
render_template(
|
||||
"trigger_function/js/trigger_functions.js",
|
||||
_=gettext
|
||||
),
|
||||
200, {'Content-Type': 'application/x-javascript'}
|
||||
)
|
||||
|
||||
TriggerFunctionView.register_node_view(trigger_function_blueprint)
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 358 B |
Binary file not shown.
After Width: | Height: | Size: 334 B |
@ -0,0 +1,3 @@
|
||||
.functions_code {
|
||||
height: 130px !important;
|
||||
}
|
@ -0,0 +1,405 @@
|
||||
/* 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-trigger_function']) {
|
||||
var trigger_functions = pgAdmin.Browser.Nodes['coll-trigger_function'] =
|
||||
pgAdmin.Browser.Collection.extend({
|
||||
node: 'trigger_function',
|
||||
label: '{{ _('Trigger functions') }}',
|
||||
type: 'coll-trigger_function',
|
||||
columns: ['name', 'funcowner', 'description']
|
||||
});
|
||||
};
|
||||
|
||||
if (!pgBrowser.Nodes['trigger_function']) {
|
||||
pgAdmin.Browser.Nodes['trigger_function'] = pgBrowser.Node.extend({
|
||||
type: 'trigger_function',
|
||||
sqlAlterHelp: 'plpgsql-trigger.html',
|
||||
sqlCreateHelp: 'plpgsql-trigger.html',
|
||||
dialogHelp: '{{ url_for('help.static', filename='create_trigger_function.html') }}',
|
||||
label: '{{ _('Trigger function') }}',
|
||||
collection_type: 'coll-trigger_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_trigger_function_on_coll', node: 'coll-trigger_function', module: this,
|
||||
applies: ['object', 'context'], callback: 'show_obj_properties',
|
||||
category: 'create', priority: 4, label: '{{ _('Trigger function...') }}',
|
||||
icon: 'wcTabIcon icon-trigger_function', data: {action: 'create', check: true},
|
||||
enable: 'canCreate'
|
||||
},{
|
||||
name: 'create_trigger_function', node: 'trigger_function', module: this,
|
||||
applies: ['object', 'context'], callback: 'show_obj_properties',
|
||||
category: 'create', priority: 4, label: '{{ _('Trigger function...') }}',
|
||||
icon: 'wcTabIcon icon-trigger_function', data: {action: 'create', check: true},
|
||||
enable: 'canCreate'
|
||||
},{
|
||||
name: 'create_trigger_function', node: 'schema', module: this,
|
||||
applies: ['object', 'context'], callback: 'show_obj_properties',
|
||||
category: 'create', priority: 4, label: '{{ _('Trigger function...') }}',
|
||||
icon: 'wcTabIcon icon-trigger_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: 'trigger', /* Return Type */
|
||||
lanname: 'plpgsql', /* 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: 'select2', type: 'text', group: '{{ _('Definition') }}',
|
||||
disabled: 'isDisabled', first_empty: true,
|
||||
select2: { width: "100%", allowClear: false },
|
||||
mode: ['create'], visible: 'isVisible', options: [
|
||||
{label: 'trigger', value: 'trigger'},
|
||||
{label: 'event_trigger', value: 'event_trigger'}
|
||||
]
|
||||
},{
|
||||
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', transform: function(d, self) {
|
||||
return _.reject(d, function(o){ return o.label == 'sql'; });
|
||||
}, select2: { allowClear: false }
|
||||
},{
|
||||
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', select2: { allowClear: false }
|
||||
},{
|
||||
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: 'variables', label: '{{ _('Parameters') }}', type: 'collection',
|
||||
group: '{{ _('Parameters') }}', 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: Backform.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(keys)
|
||||
{
|
||||
var err = {},
|
||||
errmsg,
|
||||
seclabels = this.get('seclabels');
|
||||
|
||||
// Nothing to validate
|
||||
if(keys && keys.length == 0) {
|
||||
this.errorModel.clear();
|
||||
return null;
|
||||
}
|
||||
|
||||
if (_.isUndefined(this.get('name')) || String(this.get('name')).replace(/^\s+|\s+$/g, '') == '') {
|
||||
err['name'] = '{{ _('Name cannot be empty.') }}';
|
||||
errmsg = errmsg || err['name'];
|
||||
}
|
||||
|
||||
if (_.isUndefined(this.get('funcowner')) || String(this.get('funcowner')).replace(/^\s+|\s+$/g, '') == '') {
|
||||
err['funcowner'] = '{{ _('Owner cannot be empty.') }}';
|
||||
errmsg = errmsg || err['funcowner'];
|
||||
}
|
||||
|
||||
if (_.isUndefined(this.get('pronamespace')) || String(this.get('pronamespace')).replace(/^\s+|\s+$/g, '') == '') {
|
||||
err['pronamespace'] = '{{ _('Schema cannot be empty.') }}';
|
||||
errmsg = errmsg || err['pronamespace'];
|
||||
}
|
||||
|
||||
if (_.isUndefined(this.get('prorettypename')) || String(this.get('prorettypename')).replace(/^\s+|\s+$/g, '') == '') {
|
||||
err['prorettypename'] = '{{ _('Return Type cannot be empty.') }}';
|
||||
errmsg = errmsg || err['prorettypename'];
|
||||
}
|
||||
|
||||
if (_.isUndefined(this.get('lanname')) || String(this.get('lanname')).replace(/^\s+|\s+$/g, '') == '') {
|
||||
err['lanname'] = '{{ _('Language cannot 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 cannot 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 cannot be empty.') }}';
|
||||
errmsg = errmsg || err['prosrc_c'];
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (_.isUndefined(this.get('prosrc')) || String(this.get('prosrc')).replace(/^\s+|\s+$/g, '') == '') {
|
||||
err['prosrc'] = '{{ _('Code cannot 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-trigger_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['trigger_function'];
|
||||
});
|
@ -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;
|
@ -0,0 +1,48 @@
|
||||
{% 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) }}()
|
||||
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 %}
|
||||
$BODY$
|
||||
{{ data.prosrc }}
|
||||
$BODY${% 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 %}
|
@ -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 = 'trigger'
|
||||
AND pr.oid = {{fnid}};
|
||||
{% endif %}
|
||||
|
||||
{% if name %}
|
||||
DROP FUNCTION {{ conn|qtIdent(nspname, name) }}{{func_args}}{% if cascade %} CASCADE{% endif %};
|
||||
{% endif %}
|
@ -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;
|
@ -0,0 +1,4 @@
|
||||
SELECT
|
||||
lanname as label, lanname as value
|
||||
FROM
|
||||
pg_language;
|
@ -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 = 'trigger' AND lanname != 'edbspl'
|
||||
AND pr.proname = {{ name|qtLiteral }};
|
@ -0,0 +1,6 @@
|
||||
SELECT
|
||||
format_type(oid, NULL) AS out_arg_type
|
||||
FROM
|
||||
pg_type
|
||||
WHERE
|
||||
oid = {{ out_arg_oid }}::oid;
|
@ -0,0 +1,6 @@
|
||||
SELECT
|
||||
nspname
|
||||
FROM
|
||||
pg_namespace
|
||||
WHERE
|
||||
oid = {{ scid }}::oid;
|
@ -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;
|
@ -0,0 +1,17 @@
|
||||
SELECT
|
||||
pr.oid, pr.proname || '()' as name,
|
||||
lanname, pg_get_userbyid(proowner) as funcowner, description
|
||||
FROM
|
||||
pg_proc pr
|
||||
JOIN
|
||||
pg_type typ ON typ.oid=prorettype
|
||||
JOIN
|
||||
pg_language lng ON lng.oid=prolang
|
||||
LEFT OUTER JOIN
|
||||
pg_description des ON (des.objoid=pr.oid AND des.classoid='pg_proc'::regclass)
|
||||
WHERE
|
||||
proisagg = FALSE
|
||||
AND pronamespace = {{scid}}::oid
|
||||
AND typname = 'trigger' AND lanname != 'edbspl'
|
||||
ORDER BY
|
||||
proname;
|
@ -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 = 'trigger' AND lanname != 'edbspl'
|
||||
{% if fnid %}
|
||||
AND pr.oid = {{fnid}}::oid
|
||||
{% endif %}
|
||||
ORDER BY
|
||||
proname;
|
@ -0,0 +1,100 @@
|
||||
{% 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) }}()
|
||||
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 %}
|
||||
$BODY${{ data.prosrc }}$BODY${% elif o_data.lanname == 'c' %}
|
||||
{{ o_data.probin|qtLiteral }}, {{ o_data.prosrc_c|qtLiteral }}{% else %}
|
||||
$BODY${{ o_data.prosrc }}$BODY${% 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 %}
|
@ -0,0 +1,6 @@
|
||||
SELECT
|
||||
name, vartype, min_val, max_val, enumvals
|
||||
FROM
|
||||
pg_settings
|
||||
WHERE
|
||||
context in ('user', 'superuser');
|
@ -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;
|
@ -0,0 +1,52 @@
|
||||
{% 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) }}()
|
||||
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 %}
|
||||
$BODY$
|
||||
{{ data.prosrc }}
|
||||
$BODY${% 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 -%}
|
@ -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 IN ('trigger', 'event_trigger')
|
||||
AND pr.oid = {{fnid}};
|
||||
{% endif %}
|
||||
|
||||
{% if name %}
|
||||
DROP FUNCTION {{ conn|qtIdent(nspname, name) }}{{func_args}}{% if cascade %} CASCADE{% endif %};
|
||||
{% endif %}
|
@ -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;
|
@ -0,0 +1,4 @@
|
||||
SELECT
|
||||
lanname as label, lanname as value
|
||||
FROM
|
||||
pg_language;
|
@ -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
|
||||
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 IN ('trigger', 'event_trigger')
|
||||
AND lanname NOT IN ('edbspl', 'sql', 'internal')
|
||||
AND pr.proname = {{ name|qtLiteral }};
|
@ -0,0 +1,6 @@
|
||||
SELECT
|
||||
format_type(oid, NULL) AS out_arg_type
|
||||
FROM
|
||||
pg_type
|
||||
WHERE
|
||||
oid = {{ out_arg_oid }}::oid;
|
@ -0,0 +1,6 @@
|
||||
SELECT
|
||||
nspname
|
||||
FROM
|
||||
pg_namespace
|
||||
WHERE
|
||||
oid = {{ scid }}::oid;
|
@ -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;
|
@ -0,0 +1,18 @@
|
||||
SELECT
|
||||
pr.oid, pr.proname || '()' as name,
|
||||
lanname, pg_get_userbyid(proowner) as funcowner, description
|
||||
FROM
|
||||
pg_proc pr
|
||||
JOIN
|
||||
pg_type typ ON typ.oid=prorettype
|
||||
JOIN
|
||||
pg_language lng ON lng.oid=prolang
|
||||
LEFT OUTER JOIN
|
||||
pg_description des ON (des.objoid=pr.oid AND des.classoid='pg_proc'::regclass)
|
||||
WHERE
|
||||
proisagg = FALSE
|
||||
AND pronamespace = {{scid}}::oid
|
||||
AND typname IN ('trigger', 'event_trigger')
|
||||
AND lanname NOT IN ('edbspl', 'sql', 'internal')
|
||||
ORDER BY
|
||||
proname;
|
@ -0,0 +1,32 @@
|
||||
SELECT
|
||||
pr.oid, pr.xmin, pr.*, pr.prosrc AS prosrc_c,
|
||||
pr.proname AS name, pg_get_function_result(pr.oid) AS prorettypename,
|
||||
typns.nspname AS typnsp, lanname, proargnames, oidvectortypes(proargtypes) AS proargtypenames,
|
||||
pg_get_expr(proargdefaults, 'pg_catalog.pg_class'::regclass) AS proargdefaultvals,
|
||||
pronargdefaults, proconfig, pg_get_userbyid(proowner) AS funcowner, description,
|
||||
(SELECT
|
||||
array_agg(provider || '=' || label)
|
||||
FROM
|
||||
pg_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 IN ('trigger', 'event_trigger')
|
||||
AND lanname NOT IN ('edbspl', 'sql', 'internal')
|
||||
{% if fnid %}
|
||||
AND pr.oid = {{fnid}}::oid
|
||||
{% endif %}
|
||||
ORDER BY
|
||||
proname;
|
@ -0,0 +1,109 @@
|
||||
{% 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) }}()
|
||||
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 %}
|
||||
$BODY${{ data.prosrc }}$BODY${% elif o_data.lanname == 'c' %}
|
||||
{{ o_data.probin|qtLiteral }}, {{ o_data.prosrc_c|qtLiteral }}{% else %}
|
||||
$BODY${{ o_data.prosrc }}$BODY${% 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 %}
|
@ -0,0 +1,6 @@
|
||||
SELECT
|
||||
name, vartype, min_val, max_val, enumvals
|
||||
FROM
|
||||
pg_settings
|
||||
WHERE
|
||||
context in ('user', 'superuser');
|
@ -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;
|
@ -0,0 +1,51 @@
|
||||
{% 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) }}()
|
||||
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 %}
|
||||
$BODY$
|
||||
{{ data.prosrc }}
|
||||
$BODY${% 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 %}
|
@ -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 IN ('trigger', 'event_trigger')
|
||||
AND pr.oid = {{fnid}};
|
||||
{% endif %}
|
||||
|
||||
{% if name %}
|
||||
DROP FUNCTION {{ conn|qtIdent(nspname, name) }}{{func_args}}{% if cascade %} CASCADE{% endif %};
|
||||
{% endif %}
|
@ -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;
|
@ -0,0 +1,4 @@
|
||||
SELECT
|
||||
lanname as label, lanname as value
|
||||
FROM
|
||||
pg_language;
|
@ -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
|
||||
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 IN ('trigger', 'event_trigger')
|
||||
AND lanname NOT IN ('edbspl', 'sql', 'internal')
|
||||
AND pr.proname = {{ name|qtLiteral }};
|
@ -0,0 +1,6 @@
|
||||
SELECT
|
||||
format_type(oid, NULL) AS out_arg_type
|
||||
FROM
|
||||
pg_type
|
||||
WHERE
|
||||
oid = {{ out_arg_oid }}::oid;
|
@ -0,0 +1,6 @@
|
||||
SELECT
|
||||
nspname
|
||||
FROM
|
||||
pg_namespace
|
||||
WHERE
|
||||
oid = {{ scid }}::oid;
|
@ -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;
|
@ -0,0 +1,18 @@
|
||||
SELECT
|
||||
pr.oid, pr.proname || '()' as name,
|
||||
lanname, pg_get_userbyid(proowner) as funcowner, description
|
||||
FROM
|
||||
pg_proc pr
|
||||
JOIN
|
||||
pg_type typ ON typ.oid=prorettype
|
||||
JOIN
|
||||
pg_language lng ON lng.oid=prolang
|
||||
LEFT OUTER JOIN
|
||||
pg_description des ON (des.objoid=pr.oid AND des.classoid='pg_proc'::regclass)
|
||||
WHERE
|
||||
proisagg = FALSE
|
||||
AND pronamespace = {{scid}}::oid
|
||||
AND typname IN ('trigger', 'event_trigger')
|
||||
AND lanname NOT IN ('edbspl', 'sql', 'internal')
|
||||
ORDER BY
|
||||
proname;
|
@ -0,0 +1,32 @@
|
||||
SELECT
|
||||
pr.oid, pr.xmin, pr.*, pr.prosrc AS prosrc_c,
|
||||
pr.proname AS name, pg_get_function_result(pr.oid) AS prorettypename,
|
||||
typns.nspname AS typnsp, lanname, proargnames, oidvectortypes(proargtypes) AS proargtypenames,
|
||||
pg_get_expr(proargdefaults, 'pg_catalog.pg_class'::regclass) AS proargdefaultvals,
|
||||
pronargdefaults, proconfig, pg_get_userbyid(proowner) AS funcowner, description,
|
||||
(SELECT
|
||||
array_agg(provider || '=' || label)
|
||||
FROM
|
||||
pg_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 IN ('trigger', 'event_trigger')
|
||||
AND lanname NOT IN ('edbspl', 'sql', 'internal')
|
||||
{% if fnid %}
|
||||
AND pr.oid = {{fnid}}::oid
|
||||
{% endif %}
|
||||
ORDER BY
|
||||
proname;
|
@ -0,0 +1,109 @@
|
||||
{% 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) }}()
|
||||
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 %}
|
||||
$BODY${{ data.prosrc }}$BODY${% elif o_data.lanname == 'c' %}
|
||||
{{ o_data.probin|qtLiteral }}, {{ o_data.prosrc_c|qtLiteral }}{% else %}
|
||||
$BODY${{ o_data.prosrc }}$BODY${% 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 %}
|
@ -0,0 +1,6 @@
|
||||
SELECT
|
||||
name, vartype, min_val, max_val, enumvals
|
||||
FROM
|
||||
pg_settings
|
||||
WHERE
|
||||
context in ('user', 'superuser');
|
@ -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;
|
@ -0,0 +1,48 @@
|
||||
{% 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) }}()
|
||||
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 %}
|
||||
$BODY$
|
||||
{{ data.prosrc }}
|
||||
$BODY${% 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 %}
|
@ -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 = 'trigger'
|
||||
AND pr.oid = {{fnid}};
|
||||
{% endif %}
|
||||
|
||||
{% if name %}
|
||||
DROP FUNCTION {{ conn|qtIdent(nspname, name) }}{{func_args}}{% if cascade %} CASCADE{% endif %};
|
||||
{% endif %}
|
@ -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;
|
@ -0,0 +1,4 @@
|
||||
SELECT
|
||||
lanname as label, lanname as value
|
||||
FROM
|
||||
pg_language;
|
@ -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 = 'trigger' AND lanname != 'edbspl'
|
||||
AND pr.proname = {{ name|qtLiteral }};
|
@ -0,0 +1,6 @@
|
||||
SELECT
|
||||
format_type(oid, NULL) AS out_arg_type
|
||||
FROM
|
||||
pg_type
|
||||
WHERE
|
||||
oid = {{ out_arg_oid }}::oid;
|
@ -0,0 +1,6 @@
|
||||
SELECT
|
||||
nspname
|
||||
FROM
|
||||
pg_namespace
|
||||
WHERE
|
||||
oid = {{ scid }}::oid;
|
@ -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;
|
@ -0,0 +1,17 @@
|
||||
SELECT
|
||||
pr.oid, pr.proname || '()' AS name,
|
||||
lanname, pg_get_userbyid(proowner) AS funcowner, description
|
||||
FROM
|
||||
pg_proc pr
|
||||
JOIN
|
||||
pg_type typ ON typ.oid=prorettype
|
||||
JOIN
|
||||
pg_language lng ON lng.oid=prolang
|
||||
LEFT OUTER JOIN
|
||||
pg_description des ON (des.objoid=pr.oid AND des.classoid='pg_proc'::regclass)
|
||||
WHERE
|
||||
proisagg = FALSE
|
||||
AND pronamespace = {{scid}}::oid
|
||||
AND typname = 'trigger' AND lanname != 'edbspl'
|
||||
ORDER BY
|
||||
proname;
|
@ -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 = 'trigger' AND lanname != 'edbspl'
|
||||
{% if fnid %}
|
||||
AND pr.oid = {{fnid}}::oid
|
||||
{% endif %}
|
||||
ORDER BY
|
||||
proname;
|
@ -0,0 +1,100 @@
|
||||
{% 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) }}()
|
||||
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 %}
|
||||
$BODY${{ data.prosrc }}$BODY${% elif o_data.lanname == 'c' %}
|
||||
{{ o_data.probin|qtLiteral }}, {{ o_data.prosrc_c|qtLiteral }}{% else %}
|
||||
$BODY${{ o_data.prosrc }}$BODY${% 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 %}
|
@ -0,0 +1,6 @@
|
||||
SELECT
|
||||
name, vartype, min_val, max_val, enumvals
|
||||
FROM
|
||||
pg_settings
|
||||
WHERE
|
||||
context in ('user', 'superuser');
|
@ -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;
|
@ -0,0 +1,52 @@
|
||||
{% 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) }}()
|
||||
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 %}
|
||||
$BODY$
|
||||
{{ data.prosrc }}
|
||||
$BODY${% 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 -%}
|
@ -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 IN ('trigger', 'event_trigger')
|
||||
AND pr.oid = {{fnid}};
|
||||
{% endif %}
|
||||
|
||||
{% if name %}
|
||||
DROP FUNCTION {{ conn|qtIdent(nspname, name) }}{{func_args}}{% if cascade%} CASCADE{%
|
||||
endif %};
|
||||
{% endif %}
|
@ -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;
|
@ -0,0 +1,4 @@
|
||||
SELECT
|
||||
lanname as label, lanname as value
|
||||
FROM
|
||||
pg_language;
|
@ -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
|
||||
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 IN ('trigger', 'event_trigger')
|
||||
AND lanname NOT IN ('edbspl', 'sql', 'internal')
|
||||
AND pr.proname = {{ name|qtLiteral }};
|
@ -0,0 +1,6 @@
|
||||
SELECT
|
||||
format_type(oid, NULL) AS out_arg_type
|
||||
FROM
|
||||
pg_type
|
||||
WHERE
|
||||
oid = {{ out_arg_oid }}::oid;
|
@ -0,0 +1,6 @@
|
||||
SELECT
|
||||
nspname
|
||||
FROM
|
||||
pg_namespace
|
||||
WHERE
|
||||
oid = {{ scid }}::oid;
|
@ -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;
|
@ -0,0 +1,18 @@
|
||||
SELECT
|
||||
pr.oid, pr.proname || '()' AS name,
|
||||
lanname, pg_get_userbyid(proowner) AS funcowner, description
|
||||
FROM
|
||||
pg_proc pr
|
||||
JOIN
|
||||
pg_type typ ON typ.oid=prorettype
|
||||
JOIN
|
||||
pg_language lng ON lng.oid=prolang
|
||||
LEFT OUTER JOIN
|
||||
pg_description des ON (des.objoid=pr.oid AND des.classoid='pg_proc'::regclass)
|
||||
WHERE
|
||||
proisagg = FALSE
|
||||
AND pronamespace = {{scid}}::oid
|
||||
AND typname IN ('trigger', 'event_trigger')
|
||||
AND lanname NOT IN ('edbspl', 'sql', 'internal')
|
||||
ORDER BY
|
||||
proname;
|
@ -0,0 +1,32 @@
|
||||
SELECT
|
||||
pr.oid, pr.xmin, pr.*, pr.prosrc AS prosrc_c,
|
||||
pr.proname AS name, pg_get_function_result(pr.oid) AS prorettypename,
|
||||
typns.nspname AS typnsp, lanname, proargnames, oidvectortypes(proargtypes) AS proargtypenames,
|
||||
pg_get_expr(proargdefaults, 'pg_catalog.pg_class'::regclass) AS proargdefaultvals,
|
||||
pronargdefaults, proconfig, pg_get_userbyid(proowner) AS funcowner, description,
|
||||
(SELECT
|
||||
array_agg(provider || '=' || label)
|
||||
FROM
|
||||
pg_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 IN ('trigger', 'event_trigger')
|
||||
AND lanname NOT IN ('edbspl', 'sql', 'internal')
|
||||
{% if fnid %}
|
||||
AND pr.oid = {{fnid}}::oid
|
||||
{% endif %}
|
||||
ORDER BY
|
||||
proname;
|
@ -0,0 +1,109 @@
|
||||
{% 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) }}()
|
||||
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 %}
|
||||
$BODY${{ data.prosrc }}$BODY${% elif o_data.lanname == 'c' %}
|
||||
{{ o_data.probin|qtLiteral }}, {{ o_data.prosrc_c|qtLiteral }}{% else %}
|
||||
$BODY${{ o_data.prosrc }}$BODY${% 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 %}
|
@ -0,0 +1,6 @@
|
||||
SELECT
|
||||
name, vartype, min_val, max_val, enumvals
|
||||
FROM
|
||||
pg_settings
|
||||
WHERE
|
||||
context in ('user', 'superuser');
|
@ -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;
|
@ -0,0 +1,51 @@
|
||||
{% 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) }}()
|
||||
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 %}
|
||||
$BODY$
|
||||
{{ data.prosrc }}
|
||||
$BODY${% 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 %}
|
@ -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 IN ('trigger', 'event_trigger')
|
||||
AND pr.oid = {{fnid}};
|
||||
{% endif %}
|
||||
|
||||
{% if name %}
|
||||
DROP FUNCTION {{ conn|qtIdent(nspname, name) }}{{func_args}}{% if cascade %} CASCADE{% endif %};
|
||||
{% endif %}
|
@ -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;
|
@ -0,0 +1,4 @@
|
||||
SELECT
|
||||
lanname as label, lanname as value
|
||||
FROM
|
||||
pg_language;
|
@ -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
|
||||
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 IN ('trigger', 'event_trigger')
|
||||
AND lanname NOT IN ('edbspl', 'sql', 'internal')
|
||||
AND pr.proname = {{ name|qtLiteral }};
|
@ -0,0 +1,6 @@
|
||||
SELECT
|
||||
format_type(oid, NULL) AS out_arg_type
|
||||
FROM
|
||||
pg_type
|
||||
WHERE
|
||||
oid = {{ out_arg_oid }}::oid;
|
@ -0,0 +1,6 @@
|
||||
SELECT
|
||||
nspname
|
||||
FROM
|
||||
pg_namespace
|
||||
WHERE
|
||||
oid = {{ scid }}::oid;
|
@ -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;
|
@ -0,0 +1,18 @@
|
||||
SELECT
|
||||
pr.oid, pr.proname || '()' AS name,
|
||||
lanname, pg_get_userbyid(proowner) AS funcowner, description
|
||||
FROM
|
||||
pg_proc pr
|
||||
JOIN
|
||||
pg_type typ ON typ.oid=prorettype
|
||||
JOIN
|
||||
pg_language lng ON lng.oid=prolang
|
||||
LEFT OUTER JOIN
|
||||
pg_description des ON (des.objoid=pr.oid AND des.classoid='pg_proc'::regclass)
|
||||
WHERE
|
||||
proisagg = FALSE
|
||||
AND pronamespace = {{scid}}::oid
|
||||
AND typname IN ('trigger', 'event_trigger')
|
||||
AND lanname NOT IN ('edbspl', 'sql', 'internal')
|
||||
ORDER BY
|
||||
proname;
|
@ -0,0 +1,32 @@
|
||||
SELECT
|
||||
pr.oid, pr.xmin, pr.*, pr.prosrc AS prosrc_c,
|
||||
pr.proname AS name, pg_get_function_result(pr.oid) AS prorettypename,
|
||||
typns.nspname AS typnsp, lanname, proargnames, oidvectortypes(proargtypes) AS proargtypenames,
|
||||
pg_get_expr(proargdefaults, 'pg_catalog.pg_class'::regclass) AS proargdefaultvals,
|
||||
pronargdefaults, proconfig, pg_get_userbyid(proowner) AS funcowner, description,
|
||||
(SELECT
|
||||
array_agg(provider || '=' || label)
|
||||
FROM
|
||||
pg_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 IN ('trigger', 'event_trigger')
|
||||
AND lanname NOT IN ('edbspl', 'sql', 'internal')
|
||||
{% if fnid %}
|
||||
AND pr.oid = {{fnid}}::oid
|
||||
{% endif %}
|
||||
ORDER BY
|
||||
proname;
|
@ -0,0 +1,109 @@
|
||||
{% 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) }}()
|
||||
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 %}
|
||||
$BODY${{ data.prosrc }}$BODY${% elif o_data.lanname == 'c' %}
|
||||
{{ o_data.probin|qtLiteral }}, {{ o_data.prosrc_c|qtLiteral }}{% else %}
|
||||
$BODY${{ o_data.prosrc }}$BODY${% 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 %}
|
@ -0,0 +1,6 @@
|
||||
SELECT
|
||||
name, vartype, min_val, max_val, enumvals
|
||||
FROM
|
||||
pg_settings
|
||||
WHERE
|
||||
context in ('user', 'superuser');
|
@ -2,12 +2,18 @@
|
||||
{# Macros for Variables (functions module) #}
|
||||
{################################################}
|
||||
{% macro SET(conn, object_type, object_name, options, schema, func_args) -%}
|
||||
|
||||
{% for opt in options %}
|
||||
ALTER {{object_type}} {{ conn|qtIdent(schema, object_name) }}({{func_args}})
|
||||
SET ({% for opt in options %}{% if loop.index != 1 %}
|
||||
, {% endif %}{{ conn|qtIdent(opt.name) }}={{ opt.value|qtLiteral }}{% endfor %});
|
||||
SET {{ conn|qtIdent(opt.name) }}={{ opt.value|qtLiteral }};
|
||||
|
||||
{% endfor %}
|
||||
{%- endmacro %}
|
||||
{% macro UNSET(conn, object_type, object_name, options, schema, func_args) -%}
|
||||
|
||||
{% for opt in options %}
|
||||
ALTER {{object_type}} {{ conn|qtIdent(schema, object_name) }}({{func_args}})
|
||||
RESET ({% for opt in options %}{% if loop.index != 1 %}
|
||||
, {% endif %}{{ conn|qtIdent(opt.name) }}{% endfor %});
|
||||
RESET {{ conn|qtIdent(opt.name) }};
|
||||
|
||||
{% endfor %}
|
||||
{%- endmacro %}
|
||||
|
Loading…
Reference in New Issue
Block a user