diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/types/__init__.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/types/__init__.py index 6a46bb0..7e05fae 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/types/__init__.py +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/types/__init__.py @@ -16,7 +16,7 @@ from pgadmin.utils.ajax import make_json_response, \ make_response as ajax_response, internal_server_error from pgadmin.browser.utils import PGChildNodeView from pgadmin.browser.server_groups.servers.databases.schemas.utils \ - import SchemaChildModule + import SchemaChildModule, DataTypeReader import pgadmin.browser.server_groups.servers.databases as database from pgadmin.browser.server_groups.servers.utils import parse_priv_from_db, \ parse_priv_to_db @@ -87,7 +87,7 @@ class TypeModule(SchemaChildModule): blueprint = TypeModule(__name__) -class TypeView(PGChildNodeView): +class TypeView(PGChildNodeView, DataTypeReader): """ This class is responsible for generating routes for Type node @@ -335,7 +335,13 @@ class TypeView(PGChildNodeView): composite_lst = [] for row in rset['rows']: - typelist = ' '.join([row['attname'], row['typname']]) + # We will fetch Full type name + fulltype = self.get_full_type( + row['collnspname'], row['typname'], + row['isdup'], row['attndims'], row['atttypmod'] + ) + + typelist = ' '.join([row['attname'], fulltype]) if not row['collname'] or (row['collname'] == 'default' and row['collnspname'] == 'pg_catalog'): full_collate = '' @@ -349,19 +355,21 @@ class TypeView(PGChildNodeView): # Below logic will allow us to split length, precision from type name for grid import re - matchObj = re.match( r'(.*)\((.*?),(.*?)\)', row['typname']) + matchObj = re.search(r'(\d+),(\d+)', fulltype) if matchObj: - t_name = matchObj.group(1) - t_len = matchObj.group(2) - t_prec = matchObj.group(3) + t_len = matchObj.group(1) + t_prec = matchObj.group(2) else: - t_name = row['typname'] t_len = None t_prec = None + is_tlength = True if t_len else False + is_precision = True if t_prec else False + composite_lst.append({ - 'attnum':row['attnum'], 'member_name': row['attname'], 'type': t_name, 'collation': full_collate, - 'tlength': t_len, 'precision': t_prec }) + 'attnum':row['attnum'], 'member_name': row['attname'], 'type': row['typname'], 'collation': full_collate, + 'tlength': t_len, 'precision': t_prec, + 'is_tlength': is_tlength, 'is_precision': is_precision }) # Adding both results res['member_list'] = ', '.join(properties_list) diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/types/templates/type/js/type.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/types/templates/type/js/type.js index 5d79449..1be3447 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/types/templates/type/js/type.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/types/templates/type/js/type.js @@ -306,23 +306,15 @@ function($, _, S, pgAdmin, pgBrowser, alertify, Backgrid) { group: '{{ _('Definition') }}', mode: ['edit', 'create'], select2: { width: "50%" }, - options: function() { - if(!this.model.isNew()) { + options: function(obj) { return [ {label: "Composite", value: "c"}, {label: "Enumeration", value: "e"}, {label: "External", value: "b"}, {label: "Range", value: "r"}, + {label: "Shell (External type only)", value: "s"} ] - } else { - return [ - {label: "Composite", value: "c"}, - {label: "Enumeration", value: "e"}, - {label: "Range", value: "r"}, - ] - - } - }, + }, disabled: 'inSchemaWithModelCheck', // If create mode then by default open composite type control: Backform.Select2Control.extend({ @@ -343,10 +335,7 @@ function($, _, S, pgAdmin, pgBrowser, alertify, Backgrid) { canAdd: true, canEdit: true, canDelete: true, disabled: 'inSchema', deps: ['typtype'], deps: ['typtype'], visible: function(m) { - if (m.get('typtype') === 'c') { - return true; - } - return false; + return m.get('typtype') === 'c'; } },{ id: 'enum', label: '{{ _('Enumeration Type') }}', @@ -522,7 +511,7 @@ function($, _, S, pgAdmin, pgBrowser, alertify, Backgrid) { },{ type: 'nested', control: 'tab', group: '{{ _('Definition') }}', label: '{{ _('External Type') }}', deps: ['typtype'], - mode: ['edit'], + mode: ['create', 'edit'], visible: function(m) { return m.get('typtype') === 'b'; }, diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/types/templates/type/sql/9.1_plus/create.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/types/templates/type/sql/9.1_plus/create.sql index bd1f8b7..4c4929e 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/types/templates/type/sql/9.1_plus/create.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/types/templates/type/sql/9.1_plus/create.sql @@ -1,9 +1,19 @@ {% import 'macros/schemas/security.macros' as SECLABLE %} {% import 'macros/schemas/privilege.macros' as PRIVILEGE %} +{## If user selected shell type then just create type template ##} +{% if data and data.typtype == 's' %} +-- This is a shell type for creating 'External' type. +-- In order to use, You need to create respective Input/Output function +-- Once you created them, Use pgAdmin4 to create 'External' type. + +-- Refer http://www.postgresql.org/docs/[PG_VERSION]/static/sql-createtype.html + +CREATE TYPE {{ conn|qtIdent(data.schema, data.name) }}; +{% else %} {### Composite Type ###} {% if data and data.typtype == 'c' %} CREATE TYPE {% if data.schema %}{{ conn|qtIdent(data.schema, data.name) }}{% else %}{{ conn|qtIdent(data.name) }}{% endif %} AS - ({% if data.composite %}{% for d in data.composite %}{% if loop.index != 1 %}, {% endif %}{{ conn|qtIdent(d.member_name) }} {{ d.type }}{% if d.is_tlength and d.tlength %}({{d.tlength}}{% if d.is_precision and d.precision %},{{d.precision}}{% endif %}){% endif %}{% if d.collation %} COLLATE {{d.collation}}{% endif %}{% endfor %}{% endif %}); +({{"\n\t"}}{% if data.composite %}{% for d in data.composite %}{% if loop.index != 1 %},{{"\n\t"}}{% endif %}{{ conn|qtIdent(d.member_name) }} {{ d.type }}{% if d.is_tlength and d.tlength %}({{d.tlength}}{% if d.is_precision and d.precision %},{{d.precision}}{% endif %}){% endif %}{% if d.collation %} COLLATE {{d.collation}}{% endif %}{% endfor %}{% endif %}{{"\n"}}); {% endif %} {### Enum Type ###} {% if data and data.typtype == 'e' %} @@ -77,3 +87,5 @@ COMMENT ON TYPE {% if data.schema %}{{ conn|qtIdent(data.schema, data.name) }}{% {% endif %} {% endfor %} {% endif %} +{## End of shell type if ##} +{% endif %} \ No newline at end of file diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/types/templates/type/sql/9.1_plus/get_external_functions.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/types/templates/type/sql/9.1_plus/get_external_functions.sql index 86648a2..148256e 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/types/templates/type/sql/9.1_plus/get_external_functions.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/types/templates/type/sql/9.1_plus/get_external_functions.sql @@ -1,8 +1,10 @@ {### Input/Output/Send/Receive/Analyze function list also append into TypModeIN/TypModOUT ###} {% if extfunc %} SELECT proname, nspname, - CASE WHEN length(nspname) > 0 AND length(proname) > 0 THEN + CASE WHEN length(nspname) > 0 AND and length(nspname) != 'public' and length(proname) > 0 THEN concat(quote_ident(nspname), '.', quote_ident(proname)) + CASE length(proname) > 0 THEN + quote_ident(proname) ELSE '' END AS func FROM ( SELECT proname, nspname, max(proargtypes[0]) AS arg0, max(proargtypes[1]) AS arg1