diff --git a/docs/en_US/function_dialog.rst b/docs/en_US/function_dialog.rst index 31731845e..2f5283c51 100644 --- a/docs/en_US/function_dialog.rst +++ b/docs/en_US/function_dialog.rst @@ -35,8 +35,10 @@ Click the *Definition* tab to continue. Use the fields in the *Definition* tab to define the function: +* Move the *Custom return type?* switch to provide a user defined return type. * Use the drop-down listbox next to *Return type* to select the data type - returned by the function, if any. + returned by the function, if any. If *Custom return type?* is enabled this field + will change to an input text field. * Use the drop-down listbox next to *Language* to select the implementation language. The default is *sql*. * Use the fields in the *Arguments* to define an argument. Click the *Add* diff --git a/docs/en_US/images/function_definition.png b/docs/en_US/images/function_definition.png index 9db498957..0ce859793 100644 Binary files a/docs/en_US/images/function_definition.png and b/docs/en_US/images/function_definition.png differ 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 3697b9e3a..7296292a6 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 @@ -762,7 +762,7 @@ class FunctionView(PGChildNodeView, DataTypeReader, SchemaDiffObjectCompare): fnid: Function Id """ - res = [{'label': '', 'value': ''}] + res = [] try: sql = render_template("/".join([self.sql_template_path, 'get_languages.sql']) diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/function.ui.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/function.ui.js index f7ddf8be6..9a9106122 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/function.ui.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/function.ui.js @@ -125,6 +125,7 @@ export default class FunctionSchema extends BaseUISchema { acl: [], sysfunc: undefined, sysproc: undefined, + customreturn: false, ...initValues }); @@ -244,12 +245,33 @@ export default class FunctionSchema extends BaseUISchema { },{ id: 'proargtypenames', label: gettext('Signature arguments'), cell: 'string', type: 'text', group: gettext('Definition'), mode: ['properties'], + },{ + id: 'customreturn', label: gettext('Custom return type?'), type: 'switch', + mode: ['create'], group: gettext('Definition'), readonly: obj.isReadonly, + visible: obj.isVisible, },{ id: 'prorettypename', label: gettext('Return type'), cell: 'string', - type: 'select', group: gettext('Definition'), - options: this.fieldOptions.getTypes, + type: state => { + if(state.customreturn) { + return { + type: 'text', + }; + } else { + return { + type: 'select', + options: this.fieldOptions.getTypes, + }; + } + }, group: gettext('Definition'), deps:['customreturn'], readonly: obj.isReadonly, first_empty: true, mode: ['create'], visible: obj.isVisible, + depChange: (state, source) => { + if(source[0] === 'customreturn') { + return { + prorettypename: undefined + }; + } + }, },{ id: 'prorettypename', label: gettext('Return type'), cell: 'string', type: 'text', group: gettext('Definition'), diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/tests/pg/11_plus/test_function.json b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/tests/pg/11_plus/test_function.json index 9ff8bb6b6..217330ad9 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/tests/pg/11_plus/test_function.json +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/tests/pg/11_plus/test_function.json @@ -300,6 +300,53 @@ "expected_sql_file": "alter_function_delete_acl.sql", "expected_msql_file": "alter_function_delete_acl.msql" }, + { + "type": "delete", + "name": "Drop function", + "endpoint": "NODE-function.delete_id", + "data": { + } + }, + { + "type": "create", + "endpoint": "NODE-function.obj", + "msql_endpoint": "NODE-function.msql", + "sql_endpoint": "NODE-function.sql_id", + "name": "Create function with custom return type.", + "data": { + "name": "Function3_$%{}[]()&*^!@\"'`\\/#", + "funcowner": "postgres", + "pronamespace": 2200, + "prorettypename": "table(val character varying)", + "lanname": "plpgsql", + "provolatile": "v", + "proretset": false, + "proisstrict": true, + "prosecdef": true, + "proiswindow": true, + "proparallel": "u", + "procost": "100", + "prorows": "0", + "proleakproof": true, + "arguments": [ + { + "argtype": "character varying", + "argmode": "IN", + "argname": "param", + "argdefval": "'1'" + } + ], + "prosrc": "begin\n return query select '1'::character varying;\nend", + "probin": "$libdir/", + "options": [], + "variables": [], + "seclabels": [], + "acl": [], + "schema": "public" + }, + "expected_sql_file": "create_function_with_custom_return.sql", + "expected_msql_file": "create_function_with_custom_return.msql" + }, { "type": "delete", "name": "Drop function", diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/tests/pg/12_plus/test_function.json b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/tests/pg/12_plus/test_function.json index 9ff8bb6b6..217330ad9 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/tests/pg/12_plus/test_function.json +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/tests/pg/12_plus/test_function.json @@ -300,6 +300,53 @@ "expected_sql_file": "alter_function_delete_acl.sql", "expected_msql_file": "alter_function_delete_acl.msql" }, + { + "type": "delete", + "name": "Drop function", + "endpoint": "NODE-function.delete_id", + "data": { + } + }, + { + "type": "create", + "endpoint": "NODE-function.obj", + "msql_endpoint": "NODE-function.msql", + "sql_endpoint": "NODE-function.sql_id", + "name": "Create function with custom return type.", + "data": { + "name": "Function3_$%{}[]()&*^!@\"'`\\/#", + "funcowner": "postgres", + "pronamespace": 2200, + "prorettypename": "table(val character varying)", + "lanname": "plpgsql", + "provolatile": "v", + "proretset": false, + "proisstrict": true, + "prosecdef": true, + "proiswindow": true, + "proparallel": "u", + "procost": "100", + "prorows": "0", + "proleakproof": true, + "arguments": [ + { + "argtype": "character varying", + "argmode": "IN", + "argname": "param", + "argdefval": "'1'" + } + ], + "prosrc": "begin\n return query select '1'::character varying;\nend", + "probin": "$libdir/", + "options": [], + "variables": [], + "seclabels": [], + "acl": [], + "schema": "public" + }, + "expected_sql_file": "create_function_with_custom_return.sql", + "expected_msql_file": "create_function_with_custom_return.msql" + }, { "type": "delete", "name": "Drop function", diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/tests/pg/14_plus/test_function.json b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/tests/pg/14_plus/test_function.json index 4d1f216b5..790454aeb 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/tests/pg/14_plus/test_function.json +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/tests/pg/14_plus/test_function.json @@ -340,6 +340,53 @@ "expected_sql_file": "create_atomic_func.sql", "expected_msql_file": "create_atomic_func.msql" }, + { + "type": "delete", + "name": "Drop function", + "endpoint": "NODE-function.delete_id", + "data": { + } + }, + { + "type": "create", + "endpoint": "NODE-function.obj", + "msql_endpoint": "NODE-function.msql", + "sql_endpoint": "NODE-function.sql_id", + "name": "Create function with custom return type.", + "data": { + "name": "Function3_$%{}[]()&*^!@\"'`\\/#", + "funcowner": "postgres", + "pronamespace": 2200, + "prorettypename": "table(val character varying)", + "lanname": "plpgsql", + "provolatile": "v", + "proretset": false, + "proisstrict": true, + "prosecdef": true, + "proiswindow": true, + "proparallel": "u", + "procost": "100", + "prorows": "0", + "proleakproof": true, + "arguments": [ + { + "argtype": "character varying", + "argmode": "IN", + "argname": "param", + "argdefval": "'1'" + } + ], + "prosrc": "begin\n return query select '1'::character varying;\nend", + "probin": "$libdir/", + "options": [], + "variables": [], + "seclabels": [], + "acl": [], + "schema": "public" + }, + "expected_sql_file": "create_function_with_custom_return.sql", + "expected_msql_file": "create_function_with_custom_return.msql" + }, { "type": "delete", "name": "Drop function", diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/tests/pg/default/create_function_with_custom_return.msql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/tests/pg/default/create_function_with_custom_return.msql new file mode 100644 index 000000000..8257f9079 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/tests/pg/default/create_function_with_custom_return.msql @@ -0,0 +1,13 @@ +CREATE FUNCTION public."Function3_$%{}[]()&*^!@""'`\/#"(IN param character varying DEFAULT '1') + RETURNS table(val character varying) + LANGUAGE 'plpgsql' + COST 100 + VOLATILE LEAKPROOF STRICT SECURITY DEFINER WINDOW PARALLEL UNSAFE +AS $BODY$ +begin + return query select '1'::character varying; +end +$BODY$; + +ALTER FUNCTION public."Function3_$%{}[]()&*^!@""'`\/#"(character varying) + OWNER TO postgres; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/tests/pg/default/create_function_with_custom_return.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/tests/pg/default/create_function_with_custom_return.sql new file mode 100644 index 000000000..30c4d8493 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/tests/pg/default/create_function_with_custom_return.sql @@ -0,0 +1,21 @@ +-- FUNCTION: public.Function3_$%{}[]()&*^!@"'`\/#(character varying) + +-- DROP FUNCTION IF EXISTS public."Function3_$%{}[]()&*^!@""'`\/#"(character varying); + +CREATE OR REPLACE FUNCTION public."Function3_$%{}[]()&*^!@""'`\/#"( + param character varying DEFAULT '1'::character varying) + RETURNS TABLE(val character varying) + LANGUAGE 'plpgsql' + COST 100 + VOLATILE LEAKPROOF STRICT SECURITY DEFINER WINDOW PARALLEL UNSAFE + ROWS 1000 + +AS $BODY$ +begin + return query select '1'::character varying; +end +$BODY$; + +ALTER FUNCTION public."Function3_$%{}[]()&*^!@""'`\/#"(character varying) + OWNER TO postgres; + diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/tests/pg/default/test_function.json b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/tests/pg/default/test_function.json index 9ff8bb6b6..283465645 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/tests/pg/default/test_function.json +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/tests/pg/default/test_function.json @@ -300,6 +300,53 @@ "expected_sql_file": "alter_function_delete_acl.sql", "expected_msql_file": "alter_function_delete_acl.msql" }, + { + "type": "delete", + "name": "Drop function", + "endpoint": "NODE-function.delete_id", + "data": { + } + }, + { + "type": "create", + "endpoint": "NODE-function.obj", + "msql_endpoint": "NODE-function.msql", + "sql_endpoint": "NODE-function.sql_id", + "name": "Create function with custom return type.", + "data": { + "name": "Function3_$%{}[]()&*^!@\"'`\\/#", + "funcowner": "postgres", + "pronamespace": 2200, + "prorettypename": "table(val character varying)", + "lanname": "plpgsql", + "provolatile": "v", + "proretset": false, + "proisstrict": true, + "prosecdef": true, + "proiswindow": true, + "proparallel": "u", + "procost": "100", + "prorows": "0", + "proleakproof": true, + "arguments": [ + { + "argtype": "character varying", + "argmode": "IN", + "argname": "param", + "argdefval": "'1'" + } + ], + "prosrc": "begin\n return query select '1'::character varying;\nend", + "probin": "$libdir/", + "options": [], + "variables": [], + "seclabels": [], + "acl": [], + "schema": "public" + }, + "expected_sql_file": "create_function_with_custom_return.sql", + "expected_msql_file": "create_function_with_custom_return.msql" + }, { "type": "delete", "name": "Drop function", diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/tests/ppas/11_plus/test_function.json b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/tests/ppas/11_plus/test_function.json index e33cedd06..0187b4011 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/tests/ppas/11_plus/test_function.json +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/tests/ppas/11_plus/test_function.json @@ -312,6 +312,53 @@ "expected_sql_file": "alter_function_delete_acl.sql", "expected_msql_file": "alter_function_delete_acl.msql" }, + { + "type": "delete", + "name": "Drop function", + "endpoint": "NODE-function.delete_id", + "data": { + } + }, + { + "type": "create", + "endpoint": "NODE-function.obj", + "msql_endpoint": "NODE-function.msql", + "sql_endpoint": "NODE-function.sql_id", + "name": "Create function with custom return type.", + "data": { + "name": "Function3_$%{}[]()&*^!@\"'`\\/#", + "funcowner": "enterprisedb", + "pronamespace": 2200, + "prorettypename": "table(val character varying)", + "lanname": "plpgsql", + "provolatile": "v", + "proretset": false, + "proisstrict": true, + "prosecdef": true, + "proiswindow": true, + "proparallel": "u", + "procost": "100", + "prorows": "0", + "proleakproof": true, + "arguments": [ + { + "argtype": "character varying", + "argmode": "IN", + "argname": "param", + "argdefval": "'1'" + } + ], + "prosrc": "begin\n return query select '1'::character varying;\nend", + "probin": "$libdir/", + "options": [], + "variables": [], + "seclabels": [], + "acl": [], + "schema": "public" + }, + "expected_sql_file": "create_function_with_custom_return.sql", + "expected_msql_file": "create_function_with_custom_return.msql" + }, { "type": "delete", "name": "Drop function", diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/tests/ppas/12_plus/test_function.json b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/tests/ppas/12_plus/test_function.json index 22bf13586..25f346a04 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/tests/ppas/12_plus/test_function.json +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/tests/ppas/12_plus/test_function.json @@ -312,6 +312,53 @@ "expected_sql_file": "alter_function_delete_acl.sql", "expected_msql_file": "alter_function_delete_acl.msql" }, + { + "type": "delete", + "name": "Drop function", + "endpoint": "NODE-function.delete_id", + "data": { + } + }, + { + "type": "create", + "endpoint": "NODE-function.obj", + "msql_endpoint": "NODE-function.msql", + "sql_endpoint": "NODE-function.sql_id", + "name": "Create function with custom return type.", + "data": { + "name": "Function3_$%{}[]()&*^!@\"'`\\/#", + "funcowner": "enterprisedb", + "pronamespace": 2200, + "prorettypename": "table(val character varying)", + "lanname": "plpgsql", + "provolatile": "v", + "proretset": false, + "proisstrict": true, + "prosecdef": true, + "proiswindow": true, + "proparallel": "u", + "procost": "100", + "prorows": "0", + "proleakproof": true, + "arguments": [ + { + "argtype": "character varying", + "argmode": "IN", + "argname": "param", + "argdefval": "'1'" + } + ], + "prosrc": "begin\n return query select '1'::character varying;\nend", + "probin": "$libdir/", + "options": [], + "variables": [], + "seclabels": [], + "acl": [], + "schema": "public" + }, + "expected_sql_file": "create_function_with_custom_return.sql", + "expected_msql_file": "create_function_with_custom_return.msql" + }, { "type": "delete", "name": "Drop function", diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/tests/ppas/14_plus/test_function.json b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/tests/ppas/14_plus/test_function.json index 1798b0431..fe8bc4cd9 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/tests/ppas/14_plus/test_function.json +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/tests/ppas/14_plus/test_function.json @@ -352,6 +352,53 @@ "expected_sql_file": "create_atomic_func.sql", "expected_msql_file": "create_atomic_func.msql" }, + { + "type": "delete", + "name": "Drop function", + "endpoint": "NODE-function.delete_id", + "data": { + } + }, + { + "type": "create", + "endpoint": "NODE-function.obj", + "msql_endpoint": "NODE-function.msql", + "sql_endpoint": "NODE-function.sql_id", + "name": "Create function with custom return type.", + "data": { + "name": "Function3_$%{}[]()&*^!@\"'`\\/#", + "funcowner": "enterprisedb", + "pronamespace": 2200, + "prorettypename": "table(val character varying)", + "lanname": "plpgsql", + "provolatile": "v", + "proretset": false, + "proisstrict": true, + "prosecdef": true, + "proiswindow": true, + "proparallel": "u", + "procost": "100", + "prorows": "0", + "proleakproof": true, + "arguments": [ + { + "argtype": "character varying", + "argmode": "IN", + "argname": "param", + "argdefval": "'1'" + } + ], + "prosrc": "begin\n return query select '1'::character varying;\nend", + "probin": "$libdir/", + "options": [], + "variables": [], + "seclabels": [], + "acl": [], + "schema": "public" + }, + "expected_sql_file": "create_function_with_custom_return.sql", + "expected_msql_file": "create_function_with_custom_return.msql" + }, { "type": "delete", "name": "Drop function", diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/tests/ppas/default/create_function_with_custom_return.msql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/tests/ppas/default/create_function_with_custom_return.msql new file mode 100644 index 000000000..649e296ef --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/tests/ppas/default/create_function_with_custom_return.msql @@ -0,0 +1,13 @@ +CREATE FUNCTION public."Function3_$%{}[]()&*^!@""'`\/#"(IN param character varying DEFAULT '1') + RETURNS table(val character varying) + LANGUAGE 'plpgsql' + COST 100 + VOLATILE LEAKPROOF STRICT SECURITY DEFINER WINDOW PARALLEL UNSAFE +AS $BODY$ +begin + return query select '1'::character varying; +end +$BODY$; + +ALTER FUNCTION public."Function3_$%{}[]()&*^!@""'`\/#"(character varying) + OWNER TO enterprisedb; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/tests/ppas/default/create_function_with_custom_return.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/tests/ppas/default/create_function_with_custom_return.sql new file mode 100644 index 000000000..c7a07a4a5 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/tests/ppas/default/create_function_with_custom_return.sql @@ -0,0 +1,21 @@ +-- FUNCTION: public.Function3_$%{}[]()&*^!@"'`\/#(character varying) + +-- DROP FUNCTION IF EXISTS public."Function3_$%{}[]()&*^!@""'`\/#"(character varying); + +CREATE OR REPLACE FUNCTION public."Function3_$%{}[]()&*^!@""'`\/#"( + param character varying DEFAULT '1'::character varying) + RETURNS TABLE(val character varying) + LANGUAGE 'plpgsql' + COST 100 + VOLATILE LEAKPROOF STRICT SECURITY DEFINER WINDOW PARALLEL UNSAFE + ROWS 1000 + +AS $BODY$ +begin + return query select '1'::character varying; +end +$BODY$; + +ALTER FUNCTION public."Function3_$%{}[]()&*^!@""'`\/#"(character varying) + OWNER TO enterprisedb; + diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/tests/ppas/default/test_function.json b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/tests/ppas/default/test_function.json index 22bf13586..25f346a04 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/tests/ppas/default/test_function.json +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/tests/ppas/default/test_function.json @@ -312,6 +312,53 @@ "expected_sql_file": "alter_function_delete_acl.sql", "expected_msql_file": "alter_function_delete_acl.msql" }, + { + "type": "delete", + "name": "Drop function", + "endpoint": "NODE-function.delete_id", + "data": { + } + }, + { + "type": "create", + "endpoint": "NODE-function.obj", + "msql_endpoint": "NODE-function.msql", + "sql_endpoint": "NODE-function.sql_id", + "name": "Create function with custom return type.", + "data": { + "name": "Function3_$%{}[]()&*^!@\"'`\\/#", + "funcowner": "enterprisedb", + "pronamespace": 2200, + "prorettypename": "table(val character varying)", + "lanname": "plpgsql", + "provolatile": "v", + "proretset": false, + "proisstrict": true, + "prosecdef": true, + "proiswindow": true, + "proparallel": "u", + "procost": "100", + "prorows": "0", + "proleakproof": true, + "arguments": [ + { + "argtype": "character varying", + "argmode": "IN", + "argname": "param", + "argdefval": "'1'" + } + ], + "prosrc": "begin\n return query select '1'::character varying;\nend", + "probin": "$libdir/", + "options": [], + "variables": [], + "seclabels": [], + "acl": [], + "schema": "public" + }, + "expected_sql_file": "create_function_with_custom_return.sql", + "expected_msql_file": "create_function_with_custom_return.msql" + }, { "type": "delete", "name": "Drop function", diff --git a/web/pgadmin/browser/static/js/node.js b/web/pgadmin/browser/static/js/node.js index 31f34a0c4..5fc01e2cd 100644 --- a/web/pgadmin/browser/static/js/node.js +++ b/web/pgadmin/browser/static/js/node.js @@ -90,7 +90,7 @@ define('pgadmin.browser.node', [ title: function(d, action) { if(action == 'create') { - return gettext('Create - %s', this._label); + return gettext('Create - %s', this.label); } return d._label??''; }, diff --git a/web/pgadmin/tools/erd/static/js/erd_tool/components/ERDTool.jsx b/web/pgadmin/tools/erd/static/js/erd_tool/components/ERDTool.jsx index 0f2eb7205..bcb169214 100644 --- a/web/pgadmin/tools/erd/static/js/erd_tool/components/ERDTool.jsx +++ b/web/pgadmin/tools/erd/static/js/erd_tool/components/ERDTool.jsx @@ -85,7 +85,6 @@ const styles = ((theme)=>({ width: '100%', height: '100%', color: theme.palette.text.primary, - fontFamily: 'sans-serif', backgroundColor: theme.otherVars.erdCanvasBg, backgroundImage: getCanvasGrid(theme), cursor: 'unset',