diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/__init__.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/__init__.py index 9f2e5d3ab..fc4645acb 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/__init__.py +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/__init__.py @@ -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) diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/img/coll-trigger_function.png b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/img/coll-trigger_function.png new file mode 100644 index 000000000..d310acbf8 Binary files /dev/null and b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/img/coll-trigger_function.png differ diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/img/trigger_function.png b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/img/trigger_function.png new file mode 100644 index 000000000..2b8ba80ba Binary files /dev/null and b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/img/trigger_function.png differ diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/css/function.css b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/css/function.css new file mode 100644 index 000000000..16b2e7198 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/css/function.css @@ -0,0 +1,3 @@ +.functions_code { + height: 130px !important; +} \ No newline at end of file diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/js/trigger_functions.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/js/trigger_functions.js new file mode 100644 index 000000000..346b895b4 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/js/trigger_functions.js @@ -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']; +}); diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.1_plus/acl.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.1_plus/acl.sql new file mode 100644 index 000000000..ad3e0d156 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.1_plus/acl.sql @@ -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; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.1_plus/create.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.1_plus/create.sql new file mode 100644 index 000000000..deae7475a --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.1_plus/create.sql @@ -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 %} diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.1_plus/delete.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.1_plus/delete.sql new file mode 100644 index 000000000..b005e536e --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.1_plus/delete.sql @@ -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 %} diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.1_plus/get_definition.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.1_plus/get_definition.sql new file mode 100644 index 000000000..589eccee6 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.1_plus/get_definition.sql @@ -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; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.1_plus/get_languages.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.1_plus/get_languages.sql new file mode 100644 index 000000000..f81ddfbda --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.1_plus/get_languages.sql @@ -0,0 +1,4 @@ +SELECT + lanname as label, lanname as value +FROM + pg_language; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.1_plus/get_oid.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.1_plus/get_oid.sql new file mode 100644 index 000000000..8a7f49010 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.1_plus/get_oid.sql @@ -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 }}; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.1_plus/get_out_types.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.1_plus/get_out_types.sql new file mode 100644 index 000000000..64a11875f --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.1_plus/get_out_types.sql @@ -0,0 +1,6 @@ +SELECT + format_type(oid, NULL) AS out_arg_type +FROM + pg_type +WHERE + oid = {{ out_arg_oid }}::oid; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.1_plus/get_schema.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.1_plus/get_schema.sql new file mode 100644 index 000000000..127d4b9db --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.1_plus/get_schema.sql @@ -0,0 +1,6 @@ +SELECT + nspname +FROM + pg_namespace +WHERE + oid = {{ scid }}::oid; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.1_plus/get_types.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.1_plus/get_types.sql new file mode 100644 index 000000000..2a5582ee9 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.1_plus/get_types.sql @@ -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; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.1_plus/node.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.1_plus/node.sql new file mode 100644 index 000000000..1bcc813db --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.1_plus/node.sql @@ -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; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.1_plus/properties.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.1_plus/properties.sql new file mode 100644 index 000000000..4319618d9 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.1_plus/properties.sql @@ -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; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.1_plus/update.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.1_plus/update.sql new file mode 100644 index 000000000..6796a889f --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.1_plus/update.sql @@ -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 %} diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.1_plus/variables.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.1_plus/variables.sql new file mode 100644 index 000000000..5233c71ec --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.1_plus/variables.sql @@ -0,0 +1,6 @@ +SELECT + name, vartype, min_val, max_val, enumvals +FROM + pg_settings +WHERE + context in ('user', 'superuser'); diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.2_plus/acl.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.2_plus/acl.sql new file mode 100644 index 000000000..ad3e0d156 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.2_plus/acl.sql @@ -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; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.2_plus/create.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.2_plus/create.sql new file mode 100644 index 000000000..ef38d5e1f --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.2_plus/create.sql @@ -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 -%} diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.2_plus/delete.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.2_plus/delete.sql new file mode 100644 index 000000000..cdf93c8e5 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.2_plus/delete.sql @@ -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 %} diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.2_plus/get_definition.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.2_plus/get_definition.sql new file mode 100644 index 000000000..589eccee6 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.2_plus/get_definition.sql @@ -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; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.2_plus/get_languages.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.2_plus/get_languages.sql new file mode 100644 index 000000000..f81ddfbda --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.2_plus/get_languages.sql @@ -0,0 +1,4 @@ +SELECT + lanname as label, lanname as value +FROM + pg_language; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.2_plus/get_oid.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.2_plus/get_oid.sql new file mode 100644 index 000000000..b4540a4a3 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.2_plus/get_oid.sql @@ -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 }}; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.2_plus/get_out_types.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.2_plus/get_out_types.sql new file mode 100644 index 000000000..64a11875f --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.2_plus/get_out_types.sql @@ -0,0 +1,6 @@ +SELECT + format_type(oid, NULL) AS out_arg_type +FROM + pg_type +WHERE + oid = {{ out_arg_oid }}::oid; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.2_plus/get_schema.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.2_plus/get_schema.sql new file mode 100644 index 000000000..127d4b9db --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.2_plus/get_schema.sql @@ -0,0 +1,6 @@ +SELECT + nspname +FROM + pg_namespace +WHERE + oid = {{ scid }}::oid; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.2_plus/get_types.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.2_plus/get_types.sql new file mode 100644 index 000000000..2a5582ee9 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.2_plus/get_types.sql @@ -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; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.2_plus/node.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.2_plus/node.sql new file mode 100644 index 000000000..12bb3b5c9 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.2_plus/node.sql @@ -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; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.2_plus/properties.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.2_plus/properties.sql new file mode 100644 index 000000000..946887125 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.2_plus/properties.sql @@ -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; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.2_plus/update.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.2_plus/update.sql new file mode 100644 index 000000000..c82736052 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.2_plus/update.sql @@ -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 %} diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.2_plus/variables.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.2_plus/variables.sql new file mode 100644 index 000000000..5233c71ec --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.2_plus/variables.sql @@ -0,0 +1,6 @@ +SELECT + name, vartype, min_val, max_val, enumvals +FROM + pg_settings +WHERE + context in ('user', 'superuser'); diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.5_plus/acl.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.5_plus/acl.sql new file mode 100644 index 000000000..ad3e0d156 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.5_plus/acl.sql @@ -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; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.5_plus/create.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.5_plus/create.sql new file mode 100644 index 000000000..54002c3f3 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.5_plus/create.sql @@ -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 %} diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.5_plus/delete.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.5_plus/delete.sql new file mode 100644 index 000000000..cdf93c8e5 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.5_plus/delete.sql @@ -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 %} diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.5_plus/get_definition.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.5_plus/get_definition.sql new file mode 100644 index 000000000..589eccee6 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.5_plus/get_definition.sql @@ -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; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.5_plus/get_languages.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.5_plus/get_languages.sql new file mode 100644 index 000000000..f81ddfbda --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.5_plus/get_languages.sql @@ -0,0 +1,4 @@ +SELECT + lanname as label, lanname as value +FROM + pg_language; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.5_plus/get_oid.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.5_plus/get_oid.sql new file mode 100644 index 000000000..b4540a4a3 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.5_plus/get_oid.sql @@ -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 }}; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.5_plus/get_out_types.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.5_plus/get_out_types.sql new file mode 100644 index 000000000..64a11875f --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.5_plus/get_out_types.sql @@ -0,0 +1,6 @@ +SELECT + format_type(oid, NULL) AS out_arg_type +FROM + pg_type +WHERE + oid = {{ out_arg_oid }}::oid; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.5_plus/get_schema.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.5_plus/get_schema.sql new file mode 100644 index 000000000..127d4b9db --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.5_plus/get_schema.sql @@ -0,0 +1,6 @@ +SELECT + nspname +FROM + pg_namespace +WHERE + oid = {{ scid }}::oid; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.5_plus/get_types.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.5_plus/get_types.sql new file mode 100644 index 000000000..2a5582ee9 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.5_plus/get_types.sql @@ -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; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.5_plus/node.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.5_plus/node.sql new file mode 100644 index 000000000..12bb3b5c9 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.5_plus/node.sql @@ -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; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.5_plus/properties.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.5_plus/properties.sql new file mode 100644 index 000000000..946887125 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.5_plus/properties.sql @@ -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; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.5_plus/update.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.5_plus/update.sql new file mode 100644 index 000000000..45e00a708 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.5_plus/update.sql @@ -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 %} diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.5_plus/variables.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.5_plus/variables.sql new file mode 100644 index 000000000..5233c71ec --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/pg/sql/9.5_plus/variables.sql @@ -0,0 +1,6 @@ +SELECT + name, vartype, min_val, max_val, enumvals +FROM + pg_settings +WHERE + context in ('user', 'superuser'); diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.1_plus/acl.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.1_plus/acl.sql new file mode 100644 index 000000000..ad3e0d156 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.1_plus/acl.sql @@ -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; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.1_plus/create.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.1_plus/create.sql new file mode 100644 index 000000000..deae7475a --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.1_plus/create.sql @@ -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 %} diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.1_plus/delete.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.1_plus/delete.sql new file mode 100644 index 000000000..b005e536e --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.1_plus/delete.sql @@ -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 %} diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.1_plus/get_definition.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.1_plus/get_definition.sql new file mode 100644 index 000000000..589eccee6 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.1_plus/get_definition.sql @@ -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; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.1_plus/get_languages.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.1_plus/get_languages.sql new file mode 100644 index 000000000..f81ddfbda --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.1_plus/get_languages.sql @@ -0,0 +1,4 @@ +SELECT + lanname as label, lanname as value +FROM + pg_language; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.1_plus/get_oid.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.1_plus/get_oid.sql new file mode 100644 index 000000000..8a7f49010 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.1_plus/get_oid.sql @@ -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 }}; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.1_plus/get_out_types.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.1_plus/get_out_types.sql new file mode 100644 index 000000000..64a11875f --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.1_plus/get_out_types.sql @@ -0,0 +1,6 @@ +SELECT + format_type(oid, NULL) AS out_arg_type +FROM + pg_type +WHERE + oid = {{ out_arg_oid }}::oid; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.1_plus/get_schema.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.1_plus/get_schema.sql new file mode 100644 index 000000000..127d4b9db --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.1_plus/get_schema.sql @@ -0,0 +1,6 @@ +SELECT + nspname +FROM + pg_namespace +WHERE + oid = {{ scid }}::oid; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.1_plus/get_types.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.1_plus/get_types.sql new file mode 100644 index 000000000..2a5582ee9 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.1_plus/get_types.sql @@ -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; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.1_plus/node.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.1_plus/node.sql new file mode 100644 index 000000000..c2aaee354 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.1_plus/node.sql @@ -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; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.1_plus/properties.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.1_plus/properties.sql new file mode 100644 index 000000000..4319618d9 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.1_plus/properties.sql @@ -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; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.1_plus/update.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.1_plus/update.sql new file mode 100644 index 000000000..6796a889f --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.1_plus/update.sql @@ -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 %} diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.1_plus/variables.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.1_plus/variables.sql new file mode 100644 index 000000000..5233c71ec --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.1_plus/variables.sql @@ -0,0 +1,6 @@ +SELECT + name, vartype, min_val, max_val, enumvals +FROM + pg_settings +WHERE + context in ('user', 'superuser'); diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.2_plus/acl.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.2_plus/acl.sql new file mode 100644 index 000000000..ad3e0d156 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.2_plus/acl.sql @@ -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; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.2_plus/create.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.2_plus/create.sql new file mode 100644 index 000000000..5a0a3ba9b --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.2_plus/create.sql @@ -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 -%} diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.2_plus/delete.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.2_plus/delete.sql new file mode 100644 index 000000000..f781a6ee3 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.2_plus/delete.sql @@ -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 %} diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.2_plus/get_definition.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.2_plus/get_definition.sql new file mode 100644 index 000000000..589eccee6 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.2_plus/get_definition.sql @@ -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; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.2_plus/get_languages.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.2_plus/get_languages.sql new file mode 100644 index 000000000..f81ddfbda --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.2_plus/get_languages.sql @@ -0,0 +1,4 @@ +SELECT + lanname as label, lanname as value +FROM + pg_language; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.2_plus/get_oid.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.2_plus/get_oid.sql new file mode 100644 index 000000000..b4540a4a3 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.2_plus/get_oid.sql @@ -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 }}; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.2_plus/get_out_types.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.2_plus/get_out_types.sql new file mode 100644 index 000000000..64a11875f --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.2_plus/get_out_types.sql @@ -0,0 +1,6 @@ +SELECT + format_type(oid, NULL) AS out_arg_type +FROM + pg_type +WHERE + oid = {{ out_arg_oid }}::oid; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.2_plus/get_schema.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.2_plus/get_schema.sql new file mode 100644 index 000000000..127d4b9db --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.2_plus/get_schema.sql @@ -0,0 +1,6 @@ +SELECT + nspname +FROM + pg_namespace +WHERE + oid = {{ scid }}::oid; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.2_plus/get_types.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.2_plus/get_types.sql new file mode 100644 index 000000000..2a5582ee9 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.2_plus/get_types.sql @@ -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; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.2_plus/node.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.2_plus/node.sql new file mode 100644 index 000000000..e690cac44 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.2_plus/node.sql @@ -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; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.2_plus/properties.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.2_plus/properties.sql new file mode 100644 index 000000000..946887125 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.2_plus/properties.sql @@ -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; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.2_plus/update.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.2_plus/update.sql new file mode 100644 index 000000000..05a9ec8f0 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.2_plus/update.sql @@ -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 %} diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.2_plus/variables.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.2_plus/variables.sql new file mode 100644 index 000000000..5233c71ec --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.2_plus/variables.sql @@ -0,0 +1,6 @@ +SELECT + name, vartype, min_val, max_val, enumvals +FROM + pg_settings +WHERE + context in ('user', 'superuser'); diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.5_plus/acl.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.5_plus/acl.sql new file mode 100644 index 000000000..ad3e0d156 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.5_plus/acl.sql @@ -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; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.5_plus/create.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.5_plus/create.sql new file mode 100644 index 000000000..54002c3f3 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.5_plus/create.sql @@ -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 %} diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.5_plus/delete.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.5_plus/delete.sql new file mode 100644 index 000000000..cdf93c8e5 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.5_plus/delete.sql @@ -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 %} diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.5_plus/get_definition.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.5_plus/get_definition.sql new file mode 100644 index 000000000..589eccee6 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.5_plus/get_definition.sql @@ -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; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.5_plus/get_languages.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.5_plus/get_languages.sql new file mode 100644 index 000000000..f81ddfbda --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.5_plus/get_languages.sql @@ -0,0 +1,4 @@ +SELECT + lanname as label, lanname as value +FROM + pg_language; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.5_plus/get_oid.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.5_plus/get_oid.sql new file mode 100644 index 000000000..b4540a4a3 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.5_plus/get_oid.sql @@ -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 }}; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.5_plus/get_out_types.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.5_plus/get_out_types.sql new file mode 100644 index 000000000..64a11875f --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.5_plus/get_out_types.sql @@ -0,0 +1,6 @@ +SELECT + format_type(oid, NULL) AS out_arg_type +FROM + pg_type +WHERE + oid = {{ out_arg_oid }}::oid; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.5_plus/get_schema.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.5_plus/get_schema.sql new file mode 100644 index 000000000..127d4b9db --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.5_plus/get_schema.sql @@ -0,0 +1,6 @@ +SELECT + nspname +FROM + pg_namespace +WHERE + oid = {{ scid }}::oid; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.5_plus/get_types.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.5_plus/get_types.sql new file mode 100644 index 000000000..2a5582ee9 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.5_plus/get_types.sql @@ -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; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.5_plus/node.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.5_plus/node.sql new file mode 100644 index 000000000..e690cac44 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.5_plus/node.sql @@ -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; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.5_plus/properties.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.5_plus/properties.sql new file mode 100644 index 000000000..946887125 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.5_plus/properties.sql @@ -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; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.5_plus/update.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.5_plus/update.sql new file mode 100644 index 000000000..45e00a708 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.5_plus/update.sql @@ -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 %} diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.5_plus/variables.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.5_plus/variables.sql new file mode 100644 index 000000000..5233c71ec --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/templates/trigger_function/ppas/sql/9.5_plus/variables.sql @@ -0,0 +1,6 @@ +SELECT + name, vartype, min_val, max_val, enumvals +FROM + pg_settings +WHERE + context in ('user', 'superuser'); diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/macros/functions/variable.macros b/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/macros/functions/variable.macros index 02f330709..23052b191 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/macros/functions/variable.macros +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/macros/functions/variable.macros @@ -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 %}