From 107795db1097367b5090e30869046377106c9eef Mon Sep 17 00:00:00 2001 From: Khushboo Vashi Date: Wed, 13 Dec 2017 15:44:10 +0000 Subject: [PATCH] Ensure column collation isn't lost when changing field size. Fixes #2779 --- .../schemas/tables/column/static/js/column.js | 4 +- .../templates/column/sql/9.2_plus/update.sql | 4 +- .../templates/column/sql/default/update.sql | 4 +- .../servers/databases/schemas/tables/utils.py | 41 +++++++++++-------- .../macros/get_full_type_sql_format.macros | 6 +-- .../servers/databases/schemas/utils.py | 2 +- 6 files changed, 33 insertions(+), 28 deletions(-) diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/column/static/js/column.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/column/static/js/column.js index dcedd7e9e..8f14eaf4a 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/column/static/js/column.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/column/static/js/column.js @@ -417,7 +417,7 @@ define('pgadmin.node.column', [ _.each(m.datatypes, function(o) { if ( of_type == o.value ) { if(o.precision) { - m.set('min_val', o.min_val, {silent: true}); + m.set('min_val', 0, {silent: true}); m.set('max_val', o.max_val, {silent: true}); flag = false; } @@ -447,7 +447,7 @@ define('pgadmin.node.column', [ _.each(m.datatypes, function(o) { if ( of_type == o.value ) { if(o.precision) { - m.set('min_val', o.min_val, {silent: true}); + m.set('min_val', 0, {silent: true}); m.set('max_val', o.max_val, {silent: true}); flag = true; } diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/column/sql/9.2_plus/update.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/column/sql/9.2_plus/update.sql index 385e40e3c..d7b9d7e89 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/column/sql/9.2_plus/update.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/column/sql/9.2_plus/update.sql @@ -9,10 +9,10 @@ ALTER TABLE {{conn|qtIdent(data.schema, data.table)}} {% endif %} {### Alter column type and collation ###} -{% if (data.cltype and data.cltype != o_data.cltype) or (data.attlen is defined and data.attlen != o_data.attlen) or (data.attprecision is defined and data.attprecision != o_data.attprecision) %} +{% if (data.cltype and data.cltype != o_data.cltype) or (data.attlen is defined and data.attlen != o_data.attlen) or (data.attprecision is defined and data.attprecision != o_data.attprecision) or (data.collspcname and data.collspcname != o_data.collspcname)%} ALTER TABLE {{conn|qtIdent(data.schema, data.table)}} ALTER COLUMN {% if data.name %}{{conn|qtTypeIdent(data.name)}}{% else %}{{conn|qtTypeIdent(o_data.name)}}{% endif %} TYPE {{ GET_TYPE.UPDATE_TYPE_SQL(conn, data, o_data) }}{% if data.collspcname and data.collspcname != o_data.collspcname %} - COLLATE {{data.collspcname}}{% endif %}; + COLLATE {{data.collspcname}}{% elif o_data.collspcname %} COLLATE {{o_data.collspcname}}{% endif %}; {% endif %} {### Alter column default value ###} {% if data.defval is defined and data.defval is not none and data.defval != '' and data.defval != o_data.defval %} diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/column/sql/default/update.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/column/sql/default/update.sql index 6b1748130..681444502 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/column/sql/default/update.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/column/sql/default/update.sql @@ -9,10 +9,10 @@ ALTER TABLE {{conn|qtIdent(data.schema, data.table)}} {% endif %} {### Alter column type and collation ###} -{% if (data.cltype and data.cltype != o_data.cltype) or (data.attlen is defined and data.attlen != o_data.attlen) or (data.attprecision is defined and data.attprecision != o_data.attprecision) %} +{% if (data.cltype and data.cltype != o_data.cltype) or (data.attlen is defined and data.attlen != o_data.attlen) or (data.attprecision is defined and data.attprecision != o_data.attprecision) or (data.collspcname and data.collspcname != o_data.collspcname) %} ALTER TABLE {{conn|qtIdent(data.schema, data.table)}} ALTER COLUMN {% if data.name %}{{conn|qtTypeIdent(data.name)}}{% else %}{{conn|qtTypeIdent(o_data.name)}}{% endif %} TYPE {{ GET_TYPE.UPDATE_TYPE_SQL(conn, data, o_data) }}{% if data.collspcname and data.collspcname != o_data.collspcname %} - COLLATE {{data.collspcname}}{% endif %}; + COLLATE {{data.collspcname}}{% elif o_data.collspcname %} COLLATE {{o_data.collspcname}}{% endif %}; {% endif %} {### Alter column default value ###} {% if data.defval is defined and data.defval is not none and data.defval != '' and data.defval != o_data.defval %} diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/utils.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/utils.py index d9b69ec27..c7127e69c 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/utils.py +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/utils.py @@ -1691,32 +1691,37 @@ class BaseTableView(PGChildNodeView): length = False precision = False - if 'elemoid' in c: + + # If the column data type has not changed then fetch old length and precision + if 'elemoid' in old_data and 'cltype' not in c: length, precision, typeval = \ - self.get_length_precision(c['elemoid']) + self.get_length_precision(old_data['elemoid']) - - # Set length and precision to None - c['attlen'] = None - c['attprecision'] = None - - # If we have length & precision both - if length and precision: - matchObj = re.search(r'(\d+),(\d+)', fulltype) - if matchObj: - c['attlen'] = matchObj.group(1) - c['attprecision'] = matchObj.group(2) - elif length: - # If we have length only - matchObj = re.search(r'(\d+)', fulltype) - if matchObj: - c['attlen'] = matchObj.group(1) + # If we have length & precision both + if length and precision: + matchObj = re.search(r'(\d+),(\d+)', fulltype) + if matchObj: + c['attlen'] = ('attlen' in c and c['attlen']) or matchObj.group(1) + c['attprecision'] = ('attprecision' in c and c['attprecision']) or matchObj.group(2) + elif length: + # If we have length only + matchObj = re.search(r'(\d+)', fulltype) + if matchObj: + c['attlen'] = ('attlen' in c and c['attlen']) or matchObj.group(1) + c['attprecision'] = None + else: + c['attlen'] = None c['attprecision'] = None old_data['cltype'] = DataTypeReader.parse_type_name( old_data['cltype'] ) + if int(old_data['attlen']) == -1: + old_data['attlen'] = None + if 'attprecision' not in old_data: + old_data['attprecision'] = None + # Sql for alter column if 'inheritedfrom' not in c: column_sql += render_template("/".join( diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/types/templates/type/macros/get_full_type_sql_format.macros b/web/pgadmin/browser/server_groups/servers/databases/schemas/types/templates/type/macros/get_full_type_sql_format.macros index c3f77079f..9e7276f3c 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/types/templates/type/macros/get_full_type_sql_format.macros +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/types/templates/type/macros/get_full_type_sql_format.macros @@ -54,10 +54,10 @@ time({{ data.attlen }}) with time zone {% endif %}{% if o_data.hasSqrBracket %}[ {#############################################################} {########## We will create SQL for other types here ##########} {#############################################################} -{% if data.cltype %}{{conn|qtTypeIdent(data.cltype)}} {% elif o_data.typnspname != 'pg_catalog' %}{{conn|qtTypeIdent(o_data.typnspname, o_data.cltype)}}{% else %}{{conn|qtTypeIdent(o_data.cltype)}} {% endif %}{% if (data.attlen and data.attlen != 'None') or (data.attprecision and data.attprecision != 'None') %} +{% if data.cltype %}{{conn|qtTypeIdent(data.cltype)}} {% elif o_data.typnspname != 'pg_catalog' %}{{conn|qtTypeIdent(o_data.typnspname, o_data.cltype)}}{% else %}{{conn|qtTypeIdent(o_data.cltype)}} {% endif %}{% if (data.attlen and data.attlen != 'None') or (data.attprecision and data.attprecision != 'None') or (o_data.attlen and o_data.attlen != 'None' and o_data.attlen|int >0) or (o_data.attprecision and o_data.attprecision != 'None') %} {% if data.attlen and data.attlen != 'None' %} -({{ data.attlen }}{% elif data.attprecision and data.attprecision != 'None' %}({{ o_data.attlen }}{% endif %}{% if data.attprecision and data.attprecision != 'None' %} +({{ data.attlen }}{% elif o_data.attlen and o_data.attlen != 'None' %}({{ o_data.attlen }}{% endif %}{% if data.attprecision and data.attprecision != 'None' %} , {{ data.attprecision }}){% elif o_data.attprecision and o_data.attprecision != 'None' %}, {{ o_data.attprecision }}){% else %}){% endif %} {% endif %} {% endif %} -{% endmacro %} \ No newline at end of file +{% endmacro %} diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/utils.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/utils.py index 3993ddcb7..a79ac2976 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/utils.py +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/utils.py @@ -220,7 +220,7 @@ class DataTypeReader: _len = (typmod - 4) >> 16; _prec = (typmod - 4) & 0xffff; length += str(_len) - if (_prec): + if _prec is not None: length += ',' + str(_prec) elif name == 'time' or \ name == 'timetz' or \