public inbox for [email protected]  
help / color / mirror / Atom feed
Patch for RM1500 other issues [pgAdmin4]
6+ messages / 2 participants
[nested] [flat]

* Patch for RM1500 other issues [pgAdmin4]
@ 2016-08-03 06:36  Harshal Dhumal <[email protected]>
  0 siblings, 1 reply; 6+ messages in thread

From: Harshal Dhumal @ 2016-08-03 06:36 UTC (permalink / raw)
  To: pgadmin-hackers

Hi,

PFA patch for RM1500.

Changes/Issues fixed:

1] datamodel.js: For collection type added check before adding model into
"changed" list instead of adding it blindly.

2] Type casting from str to int of column properties like attlen,
attpricision.

3] Added missing data formating when adding new column to existing table
(from table edit mode).

4] Added more validation for Foreign key constraint.

5] Column.js: Column grid (in table edit mode) show proper disabled color
for disabled cell when grid renders.

6] All constraints and index js added idattribute to distinguish which
s/constraint or s/index is updated on server side.

7] Column update.sql: Fixed sql when altering column data type. The issue
was when we alter data type from which has length and precision to data
type which don't have these properties and vice versa.
For e.g. alter data type numeric(10,12) to real (and vice versa)

8] Renaming constraint (RM1500).

-- 
*Harshal Dhumal*
*Software Engineer*

EnterpriseDB India: http://www.enterprisedb.com
The Enterprise PostgreSQL Company


-- 
Sent via pgadmin-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgadmin-hackers


Attachments:

  [text/x-patch] RM1500.patch (38.2K, 3-RM1500.patch)
  download | inline diff:
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/__init__.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/__init__.py
index 02057bf..ece103f 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/__init__.py
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/__init__.py
@@ -187,9 +187,9 @@ class TableView(PGChildNodeView, DataTypeReader, VacuumSettings):
       - It will return formatted output of query result
         as per client model format for index constraint node
 
-    * _cltype_formatter(self, type):
+    * _cltype_formatter(type): (staticmethod)
       - We need to remove [] from type and append it
-        after length/precision so we will set flag for
+        after length/precision so we will send flag for
         sql template
 
     * _parse_format_columns(self, data, mode=None):
@@ -627,17 +627,16 @@ class TableView(PGChildNodeView, DataTypeReader, VacuumSettings):
                     column['isdup'], column['attndims'], column['atttypmod']
                 )
 
-                import re
                 # If we have length & precision both
                 matchObj = re.search(r'(\d+),(\d+)', fulltype)
                 if matchObj:
-                    column['attlen'] = matchObj.group(1)
-                    column['attprecision'] = matchObj.group(2)
+                    column['attlen'] = int(matchObj.group(1))
+                    column['attprecision'] = int(matchObj.group(2))
                 else:
                     # If we have length only
                     matchObj = re.search(r'(\d+)', fulltype)
                     if matchObj:
-                        column['attlen'] = matchObj.group(1)
+                        column['attlen'] = int(matchObj.group(1))
                         column['attprecision'] = None
                     else:
                         column['attlen'] = None
@@ -1045,7 +1044,6 @@ class TableView(PGChildNodeView, DataTypeReader, VacuumSettings):
         # Filter inherited columns from all columns
         if 'columns' in data and len(data['columns']) > 0 \
                 and len(all_columns) > 0:
-            columns = []
             for row in data['columns']:
                 for i, col in enumerate(all_columns):
                     # If both name are same then remove it
@@ -1271,24 +1269,22 @@ class TableView(PGChildNodeView, DataTypeReader, VacuumSettings):
         except Exception as e:
             return internal_server_error(errormsg=str(e))
 
-    def _cltype_formatter(self, type):
+    @staticmethod
+    def _cltype_formatter(data_type):
         """
 
         Args:
-            data: Type string
+            data_type: Type string
 
         Returns:
             We need to remove [] from type and append it
-            after length/precision so we will set flag for
+            after length/precision so we will send flag for
             sql template
         """
-        if '[]' in type:
-            type = type.replace('[]', '')
-            self.hasSqrBracket = True
+        if '[]' in data_type:
+            return data_type[:-2], True
         else:
-            self.hasSqrBracket = False
-
-        return type
+            return data_type, False
 
     def _parse_format_columns(self, data, mode=None):
         """
@@ -1313,9 +1309,9 @@ class TableView(PGChildNodeView, DataTypeReader, VacuumSettings):
                         if 'attacl' in c:
                             c['attacl'] = parse_priv_to_db(c['attacl'], self.column_acl)
 
-                        # check type for '[]' in it
-                        c['cltype'] = self._cltype_formatter(c['cltype'])
-                        c['hasSqrBracket'] = self.hasSqrBracket
+                        if 'cltype' in c:
+                            # check type for '[]' in it
+                            c['cltype'], c['hasSqrBracket'] = self._cltype_formatter(c['cltype'])
 
                     data['columns'][action] = final_columns
         else:
@@ -1333,9 +1329,9 @@ class TableView(PGChildNodeView, DataTypeReader, VacuumSettings):
                 if 'attacl' in c:
                     c['attacl'] = parse_priv_to_db(c['attacl'], self.column_acl)
 
-                # check type for '[]' in it
-                c['cltype'] = self._cltype_formatter(c['cltype'])
-                c['hasSqrBracket'] = self.hasSqrBracket
+                if 'cltype' in c:
+                    # check type for '[]' in it
+                    c['cltype'], c['hasSqrBracket'] = self._cltype_formatter(c['cltype'])
 
             data['columns'] = final_columns
 
@@ -1843,19 +1839,20 @@ class TableView(PGChildNodeView, DataTypeReader, VacuumSettings):
                         )
                         return '\n\n'.join(sql)
 
-                    cols = []
-                    for col in c['columns']:
-                        cols.append(col['local_column'])
+                    if 'columns' in c:
+                        cols = []
+                        for col in c['columns']:
+                            cols.append(col['local_column'])
 
-                    coveringindex = self.search_coveringindex(tid, cols)
+                        coveringindex = self.search_coveringindex(tid, cols)
 
-                    if coveringindex is None and 'autoindex' in c and c['autoindex'] and \
-                            ('coveringindex' in c and
-                                     c['coveringindex'] != ''):
-                        sql.append(render_template(
-                            "/".join([self.foreign_key_template_path, 'create_index.sql']),
-                            data=c, conn=self.conn).strip('\n')
-                                   )
+                        if coveringindex is None and 'autoindex' in c and c['autoindex'] and \
+                                ('coveringindex' in c and
+                                         c['coveringindex'] != ''):
+                            sql.append(render_template(
+                                "/".join([self.foreign_key_template_path, 'create_index.sql']),
+                                data=c, conn=self.conn).strip('\n')
+                                       )
 
             if 'added' in constraint:
                 for c in constraint['added']:
@@ -2163,9 +2160,46 @@ class TableView(PGChildNodeView, DataTypeReader, VacuumSettings):
                             return internal_server_error(errormsg=res)
                         old_data = res['rows'][0]
 
-                        old_data['cltype'] = self._cltype_formatter(old_data['cltype'])
-                        old_data['hasSqrBracket'] = self.hasSqrBracket
+                        old_data['cltype'], old_data['hasSqrBracket'] = self._cltype_formatter(old_data['cltype'])
+
+                        fulltype = self.get_full_type(
+                            old_data['typnspname'], old_data['typname'],
+                            old_data['isdup'], old_data['attndims'], old_data['atttypmod']
+                        )
 
+                        # If we have length & precision both
+                        matchObj = re.search(r'(\d+),(\d+)', fulltype)
+                        if matchObj:
+                            old_data['attlen'] = int(matchObj.group(1))
+                            old_data['attprecision'] = int(matchObj.group(2))
+                        else:
+                            # If we have length only
+                            matchObj = re.search(r'(\d+)', fulltype)
+                            if matchObj:
+                                old_data['attlen'] = int(matchObj.group(1))
+                                old_data['attprecision'] = None
+                            else:
+                                old_data['attlen'] = None
+                                old_data['attprecision'] = None
+
+                        # Manual Data type formatting
+                        # If data type has () with them then we need to remove them
+                        # eg bit(1) because we need to match the name with combobox
+                        isArray = False
+                        if old_data['cltype'].endswith('[]'):
+                            isArray = True
+                            old_data['cltype'] = old_data['cltype'].rstrip('[]')
+
+                        idx = old_data['cltype'].find('(')
+                        if idx and old_data['cltype'].endswith(')'):
+                            old_data['cltype'] = old_data['cltype'][:idx]
+
+                        if isArray:
+                            old_data['cltype'] += "[]"
+
+                        if old_data['typnspname'] != 'pg_catalog':
+                            old_data['cltype'] = self.qtIdent(self.conn, old_data['typnspname']) \
+                                               + '.' + old_data['cltype']
                         # Sql for alter column
                         if 'inheritedfrom' not in c:
                             column_sql += render_template("/".join(
@@ -2259,7 +2293,8 @@ class TableView(PGChildNodeView, DataTypeReader, VacuumSettings):
 
         return SQL
 
-    def validate_constrains(self, key, data):
+    @staticmethod
+    def validate_constrains(key, data):
 
         if key == 'primary_key' or key == 'unique_constraint':
             if 'columns' in data and len(data['columns']) > 0:
@@ -2267,15 +2302,17 @@ class TableView(PGChildNodeView, DataTypeReader, VacuumSettings):
             else:
                 return False
         elif key == 'foreign_key':
-            for arg in ['columns']:
-                if arg not in data:
+            if 'oid' not in data:
+                for arg in ['columns']:
+                    if arg not in data:
+                        return False
+                    elif isinstance(data[arg], list) and len(data[arg]) < 1:
+                        return False
+
+                if 'autoindex' in data and data['autoindex'] and \
+                        ('coveringindex' not in data or
+                                                  data['coveringindex'] == ''):
                     return False
-                elif isinstance(data[arg], list) and len(data[arg]) < 1:
-                    return False
-
-            if data['autoindex'] and ('coveringindex' not in data or
-                                              data['coveringindex'] == ''):
-                return False
 
             return True
 
@@ -2406,8 +2443,8 @@ class TableView(PGChildNodeView, DataTypeReader, VacuumSettings):
                     c['attacl'] = parse_priv_to_db(c['attacl'], self.column_acl)
 
                 # check type for '[]' in it
-                c['cltype'] = self._cltype_formatter(c['cltype'])
-                c['hasSqrBracket'] = self.hasSqrBracket
+                if 'cltype' in c:
+                    c['cltype'], c['hasSqrBracket'] = self._cltype_formatter(c['cltype'])
 
         sql_header = u"-- Table: {0}\n\n-- ".format(self.qtIdent(self.conn,
                                                                 data['schema'],
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/column/templates/column/js/column.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/column/templates/column/js/column.js
index d7fe5a4..072adaf 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/column/templates/column/js/column.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/column/templates/column/js/column.js
@@ -57,17 +57,29 @@ function($, _, S, pgAdmin, pgBrowser, Backform, alertify) {
       },
       dependentChanged: function () {
         this.$el.empty();
-        var model = this.model;
-        var column = this.column;
-        editable = this.column.get("editable");
+        var model = this.model,
+            column = this.column,
+            editable = this.column.get("editable"),
+            is_editable = _.isFunction(editable) ? !!editable.apply(column, [model]) : !!editable;
 
-        is_editable = _.isFunction(editable) ? !!editable.apply(column, [model]) : !!editable;
         if (is_editable){ this.$el.addClass("editable"); }
         else { this.$el.removeClass("editable"); }
 
         this.delegateEvents();
         return this;
       },
+      render: function() {
+        Backgrid.NumberCell.prototype.render.apply(this, arguments);
+
+        var model = this.model,
+            column = this.column,
+            editable = this.column.get("editable"),
+            is_editable = _.isFunction(editable) ? !!editable.apply(column, [model]) : !!editable;
+
+        if (is_editable){ this.$el.addClass("editable"); }
+        else { this.$el.removeClass("editable"); }
+        return this;
+      },
       remove: Backgrid.Extension.DependentCell.prototype.remove
     });
 
@@ -140,6 +152,8 @@ function($, _, S, pgAdmin, pgBrowser, Backform, alertify) {
         ]);
       },
       model: pgBrowser.Node.Model.extend({
+        idAttribute: 'attnum',
+
         defaults: {
           name: undefined,
           attowner: undefined,
@@ -156,7 +170,9 @@ function($, _, S, pgAdmin, pgBrowser, Backform, alertify) {
           is_primary_key: false,
           inheritedfrom: undefined,
           attstattarget:undefined,
-          attnotnull: false
+          attnotnull: false,
+          attlen: null,
+          attprecision: null
         },
         schema: [{
           id: 'name', label: '{{ _('Name') }}', cell: 'string',
@@ -322,16 +338,21 @@ function($, _, S, pgAdmin, pgBrowser, Backform, alertify) {
              if(!_.isUndefined(m.get('inheritedfrom'))) {
                 return false;
              }
+
+             if (!m.datatypes) {
+              // datatypes not loaded, may be this call is from CallByNeed from backgrid cell initialize.
+              return true;
+             }
              var of_type = m.get('cltype'),
                flag = false;
-              _.each(m.datatypes, function(o) {
-                if ( of_type == o.value ) {
-                    if(o.length)
-                    {
-                      m.set('min_val', o.min_val, {silent: true});
-                      m.set('max_val', o.max_val, {silent: true});
-                      flag = true;
-                    }
+
+               _.each(m.datatypes, function(o) {
+               if ( of_type == o.value ) {
+                 if(o.length) {
+                   m.set('min_val', o.min_val, {silent: true});
+                   m.set('max_val', o.max_val, {silent: true});
+                   flag = true;
+                 }
                 }
               });
 
@@ -351,12 +372,11 @@ function($, _, S, pgAdmin, pgBrowser, Backform, alertify) {
                flag = true;
               _.each(m.datatypes, function(o) {
                 if ( of_type == o.value ) {
-                    if(o.precision)
-                    {
-                      m.set('min_val', o.min_val, {silent: true});
-                      m.set('max_val', o.max_val, {silent: true});
-                      flag = false;
-                    }
+                  if(o.precision) {
+                    m.set('min_val', o.min_val, {silent: true});
+                    m.set('max_val', o.max_val, {silent: true});
+                    flag = false;
+                  }
                 }
               });
 
@@ -373,16 +393,20 @@ function($, _, S, pgAdmin, pgBrowser, Backform, alertify) {
                 return false;
              }
 
+             if (!m.datatypes) {
+              // datatypes not loaded yet, may be this call is from CallByNeed from backgrid cell initialize.
+              return true;
+             }
+
              var of_type = m.get('cltype'),
                flag = false;
               _.each(m.datatypes, function(o) {
                 if ( of_type == o.value ) {
-                    if(o.precision)
-                    {
-                      m.set('min_val', o.min_val, {silent: true});
-                      m.set('max_val', o.max_val, {silent: true});
-                      flag = true;
-                    }
+                  if(o.precision) {
+                    m.set('min_val', o.min_val, {silent: true});
+                    m.set('max_val', o.max_val, {silent: true});
+                    flag = true;
+                  }
                 }
               });
 
@@ -401,22 +425,22 @@ function($, _, S, pgAdmin, pgBrowser, Backform, alertify) {
           deps: ['cltype'], disabled: function(m) {
              var of_type = m.get('cltype'),
                flag = true;
-              _.each(m.datatypes, function(o) {
+             _.each(m.datatypes, function(o) {
                 if ( of_type == o.value ) {
                     if(o.is_collatable)
                     {
                       flag = false;
                     }
                 }
-              });
-              if (flag) {
+             });
+             if (flag) {
                 setTimeout(function(){
                   if(m.get('collspcname') && m.get('collspcname') !== '') {
                     m.set('collspcname', "");
                   }
                 }, 10);
-              }
-              return flag;
+             }
+             return flag;
           }
         },{
           id: 'defval', label:'{{ _('Default Value') }}', cell: 'string',
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/check_constraint/templates/check_constraint/js/check_constraint.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/check_constraint/templates/check_constraint/js/check_constraint.js
index cb33a1a..9389bc9 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/check_constraint/templates/check_constraint/js/check_constraint.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/check_constraint/templates/check_constraint/js/check_constraint.js
@@ -90,6 +90,8 @@ function($, _, S, pgAdmin, pgBrowser, Alertify) {
       },
       canDrop: pgBrowser.Nodes['schema'].canChildDrop,
       model: pgAdmin.Browser.Node.Model.extend({
+        idAttribute: 'oid',
+
         defaults: {
           name: undefined,
           oid: undefined,
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/exclusion_constraint/templates/exclusion_constraint/js/exclusion_constraint.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/exclusion_constraint/templates/exclusion_constraint/js/exclusion_constraint.js
index 9232677..abdd623 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/exclusion_constraint/templates/exclusion_constraint/js/exclusion_constraint.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/exclusion_constraint/templates/exclusion_constraint/js/exclusion_constraint.js
@@ -639,6 +639,8 @@ function($, _, S, pgAdmin, pgBrowser, Alertify) {
       },
       // Define the model for exclusion constraint node
       model: pgAdmin.Browser.Node.Model.extend({
+        idAttribute: 'oid',
+
         defaults: {
           name: undefined,
           oid: undefined,
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/foreign_key/templates/foreign_key/js/foreign_key.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/foreign_key/templates/foreign_key/js/foreign_key.js
index cae2efa..9da61f9 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/foreign_key/templates/foreign_key/js/foreign_key.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/foreign_key/templates/foreign_key/js/foreign_key.js
@@ -672,6 +672,8 @@ function($, _, S, pgAdmin, pgBrowser, Alertify) {
       },
       // Define the model for foreign key node
       model: pgAdmin.Browser.Node.Model.extend({
+        idAttribute: 'oid',
+
         defaults: {
           name: undefined,
           oid: undefined,
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/index_constraint/templates/index_constraint/js/index_constraint.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/index_constraint/templates/index_constraint/js/index_constraint.js
index 73a563b..7db68d5 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/index_constraint/templates/index_constraint/js/index_constraint.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/index_constraint/templates/index_constraint/js/index_constraint.js
@@ -79,6 +79,8 @@ function($, _, S, pgAdmin, pgBrowser, alertify) {
 
       // Define the model for index constraint node
       model: pgAdmin.Browser.Node.Model.extend({
+        idAttribute: 'oid',
+
         defaults: {
           name: undefined,
           oid: undefined,
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/templates/index/js/index.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/templates/index/js/index.js
index 3283582..8ff8359 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/templates/index/js/index.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/templates/index/js/index.js
@@ -238,8 +238,11 @@ function($, _, S, pgAdmin, pgBrowser, Backform, alertify) {
       canDrop: pgBrowser.Nodes['schema'].canChildDrop,
       canDropCascade: pgBrowser.Nodes['schema'].canChildDrop,
       model: pgAdmin.Browser.Node.Model.extend({
+        idAttribute: 'oid',
+
         defaults: {
           name: undefined,
+          oid: undefined,
           nspname: undefined,
           tabname: undefined,
           spcname: 'pg_default',
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/column/sql/9.1_plus/update.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/column/sql/9.1_plus/update.sql
index 2b1d5b9..454f964 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/column/sql/9.1_plus/update.sql
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/column/sql/9.1_plus/update.sql
@@ -2,7 +2,7 @@
 {% import 'column/macros/privilege.macros' as PRIVILEGE %}
 {% import 'macros/variable.macros' as VARIABLE %}
 {###  Rename column name ###}
-{% if data.name != o_data.name %}
+{% if data.name and data.name != o_data.name %}
 ALTER TABLE {{conn|qtIdent(data.schema, data.table)}}
     RENAME {{conn|qtIdent(o_data.name)}} TO {{conn|qtIdent(data.name)}};
 
@@ -10,8 +10,8 @@ ALTER TABLE {{conn|qtIdent(data.schema, data.table)}}
 {###  Alter column type and collation ###}
 {% if (data.cltype and data.cltype != o_data.cltype) or (data.attlen and data.attlen != o_data.attlen) or (data.attprecision and data.attprecision != o_data.attprecision) %}
 ALTER TABLE {{conn|qtIdent(data.schema, data.table)}}
-    ALTER COLUMN {{conn|qtIdent(data.name)}} TYPE {% if data.cltype %}{{conn|qtTypeIdent(data.cltype)}} {% else %}{{o_data.cltype}} {% endif %}{% if data.attlen %}
-({{data.attlen}}{% if data.attprecision%}, {{data.attprecision}}{% endif %}){% endif %}{% if data.hasSqrBracket %}
+    ALTER COLUMN {% if data.name %}{{conn|qtTypeIdent(data.name)}}{% else %}{{conn|qtTypeIdent(o_data.name)}}{% endif %} TYPE {% if data.cltype %}{{conn|qtTypeIdent(data.cltype)}} {% else %}{{conn|qtTypeIdent(o_data.cltype)}} {% endif %}
+{% if data.attlen %}({{data.attlen}}{% elif not data.cltype %}({{o_data.attlen}}{% endif %}{% if data.attprecision%}, {{data.attprecision}}){% elif not data.cltype %}, {{o_data.attprecision}}){% elif data.attlen %}){% endif %}{% if data.hasSqrBracket %}
 []{% endif %}{% if data.collspcname and data.collspcname != o_data.collspcname %}
  COLLATE {{data.collspcname}}{% endif %};
 
@@ -19,31 +19,35 @@ ALTER TABLE {{conn|qtIdent(data.schema, data.table)}}
 {###  Alter column default value ###}
 {% if data.defval and data.defval != o_data.defval %}
 ALTER TABLE {{conn|qtIdent(data.schema, data.table)}}
-    ALTER COLUMN {{conn|qtIdent(data.name)}} SET DEFAULT {{data.defval}};
+    ALTER COLUMN {% if data.name %}{{conn|qtTypeIdent(data.name)}}{% else %}{{conn|qtTypeIdent(o_data.name)}}{% endif %} SET DEFAULT {{data.defval}};
 
 {% endif %}
 {###  Alter column not null value ###}
 {% if 'attnotnull' in data and data.attnotnull != o_data.attnotnull %}
 ALTER TABLE {{conn|qtIdent(data.schema, data.table)}}
-    ALTER COLUMN {{conn|qtIdent(data.name)}} {% if data.attnotnull %}SET{% else %}DROP{% endif %} NOT NULL;
+    ALTER COLUMN {% if data.name %}{{conn|qtTypeIdent(data.name)}}{% else %}{{conn|qtTypeIdent(o_data.name)}}{% endif %} {% if data.attnotnull %}SET{% else %}DROP{% endif %} NOT NULL;
 
 {% endif %}
 {###  Alter column statistics value ###}
 {% if data.attstattarget and data.attstattarget != o_data.attstattarget %}
 ALTER TABLE {{conn|qtIdent(data.schema, data.table)}}
-    ALTER COLUMN {{conn|qtIdent(data.name)}} SET STATISTICS {{data.attstattarget}};
+    ALTER COLUMN {% if data.name %}{{conn|qtTypeIdent(data.name)}}{% else %}{{conn|qtTypeIdent(o_data.name)}}{% endif %} SET STATISTICS {{data.attstattarget}};
 
 {% endif %}
 {###  Alter column storage value ###}
 {% if data.attstorage and data.attstorage != o_data.attstorage %}
 ALTER TABLE {{conn|qtIdent(data.schema, data.table)}}
-    ALTER COLUMN {{conn|qtIdent(data.name)}} SET STORAGE {%if data.attstorage == 'p' %}
+    ALTER COLUMN {% if data.name %}{{conn|qtTypeIdent(data.name)}}{% else %}{{conn|qtTypeIdent(o_data.name)}}{% endif %} SET STORAGE {%if data.attstorage == 'p' %}
 PLAIN{% elif data.attstorage == 'm'%}MAIN{% elif data.attstorage == 'e'%}
 EXTERNAL{% elif data.attstorage == 'x'%}EXTENDED{% endif %};
 
 {% endif %}
 {% if data.description is defined %}
+{% if data.name %}
 COMMENT ON COLUMN {{conn|qtIdent(data.schema, data.table, data.name)}}
+{% else %}
+COMMENT ON COLUMN {{conn|qtIdent(data.schema, data.table, o_data.name)}}
+{% endif %}
     IS {{data.description|qtLiteral}};
 
 {% endif %}
@@ -52,15 +56,27 @@ COMMENT ON COLUMN {{conn|qtIdent(data.schema, data.table, data.name)}}
 {% set variables = data.attoptions %}
 {% if 'deleted' in variables and variables.deleted|length > 0 %}
 ALTER TABLE {{conn|qtIdent(data.schema, data.table)}}
+{% if data.name %}
     {{ VARIABLE.UNSET(conn, 'COLUMN', data.name, variables.deleted) }}
+{% else %}
+    {{ VARIABLE.UNSET(conn, 'COLUMN', o_data.name, variables.deleted) }}
+{% endif %}
 {% endif %}
 {% if 'added' in variables and variables.added|length > 0 %}
 ALTER TABLE {{conn|qtIdent(data.schema, data.table)}}
+{% if data.name %}
     {{ VARIABLE.SET(conn, 'COLUMN', data.name, variables.added) }}
+{% else %}
+    {{ VARIABLE.SET(conn, 'COLUMN', o_data.name, variables.added) }}
+{% endif %}
 {% endif %}
 {% if 'changed' in variables and variables.changed|length > 0 %}
 ALTER TABLE {{conn|qtIdent(data.schema, data.table)}}
+{% if data.name %}
     {{ VARIABLE.SET(conn, 'COLUMN', data.name, variables.changed) }}
+{% else %}
+    {{ VARIABLE.SET(conn, 'COLUMN', o_data.name, variables.changed) }}
+{% endif %}
 {% endif %}
 
 {% endif %}
@@ -69,18 +85,31 @@ ALTER TABLE {{conn|qtIdent(data.schema, data.table)}}
 {% if data.attacl %}
 {% if 'deleted' in data.attacl %}
 {% for priv in data.attacl.deleted %}
+{% if data.name %}
 {{ PRIVILEGE.RESETALL(conn, data.schema, data.table, data.name, priv.grantee) }}
+{% else %}
+{{ PRIVILEGE.RESETALL(conn, data.schema, data.table, o_data.name, priv.grantee) }}
+{% endif %}
 {% endfor %}
 {% endif %}
 {% if 'changed' in data.attacl %}
 {% for priv in data.attacl.changed %}
+{% if data.name %}
 {{ PRIVILEGE.RESETALL(conn, data.schema, data.table, data.name, priv.grantee) }}
 {{ PRIVILEGE.APPLY(conn, data.schema, data.table, data.name, priv.grantee, priv.without_grant, priv.with_grant) }}
+{% else %}
+{{ PRIVILEGE.RESETALL(conn, data.schema, data.table, o_data.name, priv.grantee) }}
+{{ PRIVILEGE.APPLY(conn, data.schema, data.table, o_data.name, priv.grantee, priv.without_grant, priv.with_grant) }}
+{% endif %}
 {% endfor %}
 {% endif %}
 {% if 'added' in data.attacl %}
 {% for priv in data.attacl.added %}
+{% if data.name %}
 {{ PRIVILEGE.APPLY(conn, data.schema, data.table, data.name, priv.grantee, priv.without_grant, priv.with_grant) }}
+{% else %}
+{{ PRIVILEGE.APPLY(conn, data.schema, data.table, o_data.name, priv.grantee, priv.without_grant, priv.with_grant) }}
+{% endif %}
 {% endfor %}
 {% endif %}
 {% endif %}
@@ -90,18 +119,30 @@ ALTER TABLE {{conn|qtIdent(data.schema, data.table)}}
 {% set seclabels = data.seclabels %}
 {% if 'deleted' in seclabels and seclabels.deleted|length > 0 %}
 {% for r in seclabels.deleted %}
+{% if data.name %}
 {{ SECLABEL.DROP(conn, 'COLUMN', data.schema, data.table, data.name, r.provider) }}
+{% else %}
+{{ SECLABEL.DROP(conn, 'COLUMN', data.schema, data.table, o_data.name, r.provider) }}
+{% endif %}
 {% endfor %}
 {% endif %}
 {% if 'added' in seclabels and seclabels.added|length > 0 %}
 {% for r in seclabels.added %}
+{% if data.name %}
 {{ SECLABEL.APPLY(conn, 'COLUMN',data.schema, data.table, data.name, r.provider, r.label) }}
+{% else %}
+{{ SECLABEL.APPLY(conn, 'COLUMN',data.schema, data.table, o_data.name, r.provider, r.label) }}
+{% endif %}
 {% endfor %}
 {% endif %}
 {% if 'changed' in seclabels and seclabels.changed|length > 0 %}
 {% for r in seclabels.changed %}
+{% if data.name %}
 {{ SECLABEL.APPLY(conn, 'COLUMN',data.schema, data.table, data.name, r.provider, r.label) }}
+{% else %}
+{{ SECLABEL.APPLY(conn, 'COLUMN',data.schema, data.table, o_data.name, r.provider, r.label) }}
+{% endif %}
 {% endfor %}
 {% endif %}
 
-{% endif %}
+{% endif %}
\ No newline at end of file
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 5445805..77ef8ea 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
@@ -2,7 +2,7 @@
 {% import 'column/macros/privilege.macros' as PRIVILEGE %}
 {% import 'macros/variable.macros' as VARIABLE %}
 {###  Rename column name ###}
-{% if data.name != o_data.name %}
+{% if data.name and data.name != o_data.name %}
 ALTER TABLE {{conn|qtIdent(data.schema, data.table)}}
     RENAME {{conn|qtIdent(o_data.name)}} TO {{conn|qtIdent(data.name)}};
 
@@ -10,40 +10,43 @@ ALTER TABLE {{conn|qtIdent(data.schema, data.table)}}
 {###  Alter column type and collation ###}
 {% if (data.cltype and data.cltype != o_data.cltype) or (data.attlen and data.attlen != o_data.attlen) or (data.attprecision and data.attprecision != o_data.attprecision) %}
 ALTER TABLE {{conn|qtIdent(data.schema, data.table)}}
-    ALTER COLUMN {{conn|qtIdent(data.name)}} TYPE {% if data.cltype %}{{conn|qtTypeIdent(data.cltype)}} {% else %}{{o_data.cltype}} {% endif %}{% if data.attlen %}
-({{data.attlen}}{% if data.attprecision%}, {{data.attprecision}}{% endif %}){% endif %}{% if data.hasSqrBracket %}
+    ALTER COLUMN {% if data.name %}{{conn|qtTypeIdent(data.name)}}{% else %}{{conn|qtTypeIdent(o_data.name)}}{% endif %} TYPE {% if data.cltype %}{{conn|qtTypeIdent(data.cltype)}} {% else %}{{conn|qtTypeIdent(o_data.cltype)}} {% endif %}
+{% if data.attlen %}({{data.attlen}}{% elif not data.cltype %}({{o_data.attlen}}{% endif %}{% if data.attprecision%}, {{data.attprecision}}){% elif not data.cltype %}, {{o_data.attprecision}}){% elif data.attlen %}){% endif %}{% if data.hasSqrBracket %}
 []{% endif %}{% if data.collspcname and data.collspcname != o_data.collspcname %}
  COLLATE {{data.collspcname}}{% endif %};
-
 {% endif %}
 {###  Alter column default value ###}
 {% if data.defval and data.defval != o_data.defval %}
 ALTER TABLE {{conn|qtIdent(data.schema, data.table)}}
-    ALTER COLUMN {{conn|qtIdent(data.name)}} SET DEFAULT {{data.defval}};
+    ALTER COLUMN {% if data.name %}{{conn|qtTypeIdent(data.name)}}{% else %}{{conn|qtTypeIdent(o_data.name)}}{% endif %} SET DEFAULT {{data.defval}};
 
 {% endif %}
 {###  Alter column not null value ###}
 {% if 'attnotnull' in data and data.attnotnull != o_data.attnotnull %}
 ALTER TABLE {{conn|qtIdent(data.schema, data.table)}}
-    ALTER COLUMN {{conn|qtIdent(data.name)}} {% if data.attnotnull %}SET{% else %}DROP{% endif %} NOT NULL;
+    ALTER COLUMN {% if data.name %}{{conn|qtTypeIdent(data.name)}}{% else %}{{conn|qtTypeIdent(o_data.name)}}{% endif %} {% if data.attnotnull %}SET{% else %}DROP{% endif %} NOT NULL;
 
 {% endif %}
 {###  Alter column statistics value ###}
 {% if data.attstattarget and data.attstattarget != o_data.attstattarget %}
 ALTER TABLE {{conn|qtIdent(data.schema, data.table)}}
-    ALTER COLUMN {{conn|qtIdent(data.name)}} SET STATISTICS {{data.attstattarget}};
+    ALTER COLUMN {% if data.name %}{{conn|qtTypeIdent(data.name)}}{% else %}{{conn|qtTypeIdent(o_data.name)}}{% endif %} SET STATISTICS {{data.attstattarget}};
 
 {% endif %}
 {###  Alter column storage value ###}
 {% if data.attstorage and data.attstorage != o_data.attstorage %}
 ALTER TABLE {{conn|qtIdent(data.schema, data.table)}}
-    ALTER COLUMN {{conn|qtIdent(data.name)}} SET STORAGE {%if data.attstorage == 'p' %}
+    ALTER COLUMN {% if data.name %}{{conn|qtTypeIdent(data.name)}}{% else %}{{conn|qtTypeIdent(o_data.name)}}{% endif %} SET STORAGE {%if data.attstorage == 'p' %}
 PLAIN{% elif data.attstorage == 'm'%}MAIN{% elif data.attstorage == 'e'%}
 EXTERNAL{% elif data.attstorage == 'x'%}EXTENDED{% endif %};
 
 {% endif %}
 {% if data.description is defined %}
+{% if data.name %}
 COMMENT ON COLUMN {{conn|qtIdent(data.schema, data.table, data.name)}}
+{% else %}
+COMMENT ON COLUMN {{conn|qtIdent(data.schema, data.table, o_data.name)}}
+{% endif %}
     IS {{data.description|qtLiteral}};
 
 {% endif %}
@@ -52,15 +55,27 @@ COMMENT ON COLUMN {{conn|qtIdent(data.schema, data.table, data.name)}}
 {% set variables = data.attoptions %}
 {% if 'deleted' in variables and variables.deleted|length > 0 %}
 ALTER TABLE {{conn|qtIdent(data.schema, data.table)}}
+{% if data.name %}
     {{ VARIABLE.UNSET(conn, 'COLUMN', data.name, variables.deleted) }}
+{% else %}
+    {{ VARIABLE.UNSET(conn, 'COLUMN', o_data.name, variables.deleted) }}
+{% endif %}
 {% endif %}
 {% if 'added' in variables and variables.added|length > 0 %}
 ALTER TABLE {{conn|qtIdent(data.schema, data.table)}}
+{% if data.name %}
     {{ VARIABLE.SET(conn, 'COLUMN', data.name, variables.added) }}
+{% else %}
+    {{ VARIABLE.SET(conn, 'COLUMN', o_data.name, variables.added) }}
+{% endif %}
 {% endif %}
 {% if 'changed' in variables and variables.changed|length > 0 %}
 ALTER TABLE {{conn|qtIdent(data.schema, data.table)}}
+{% if data.name %}
     {{ VARIABLE.SET(conn, 'COLUMN', data.name, variables.changed) }}
+{% else %}
+    {{ VARIABLE.SET(conn, 'COLUMN', o_data.name, variables.changed) }}
+{% endif %}
 {% endif %}
 {% endif %}
 {### Update column privileges ###}
@@ -68,18 +83,31 @@ ALTER TABLE {{conn|qtIdent(data.schema, data.table)}}
 {% if data.attacl %}
 {% if 'deleted' in data.attacl %}
 {% for priv in data.attacl.deleted %}
-{{ PRIVILEGE.RESETALL(conn, data.schema, data.table, data.name, priv.grantee) }}
+{% if data.name %}
+    {{ PRIVILEGE.RESETALL(conn, data.schema, data.table, data.name, priv.grantee) }}
+{% else %}
+    {{ PRIVILEGE.RESETALL(conn, data.schema, data.table, o_data.name, priv.grantee) }}
+{% endif %}
 {% endfor %}
 {% endif %}
 {% if 'changed' in data.attacl %}
 {% for priv in data.attacl.changed %}
-{{ PRIVILEGE.RESETALL(conn, data.schema, data.table, data.name, priv.grantee) }}
-{{ PRIVILEGE.APPLY(conn, data.schema, data.table, data.name, priv.grantee, priv.without_grant, priv.with_grant) }}
+{% if data.name %}
+    {{ PRIVILEGE.RESETALL(conn, data.schema, data.table, data.name, priv.grantee) }}
+    {{ PRIVILEGE.APPLY(conn, data.schema, data.table, data.name, priv.grantee, priv.without_grant, priv.with_grant) }}
+{% else %}
+    {{ PRIVILEGE.RESETALL(conn, data.schema, data.table, o_data.name, priv.grantee) }}
+    {{ PRIVILEGE.APPLY(conn, data.schema, data.table, o_data.name, priv.grantee, priv.without_grant, priv.with_grant) }}
+{% endif %}
 {% endfor %}
 {% endif %}
 {% if 'added' in data.attacl %}
 {% for priv in data.attacl.added %}
-{{ PRIVILEGE.APPLY(conn, data.schema, data.table, data.name, priv.grantee, priv.without_grant, priv.with_grant) }}
+{% if data.name %}
+    {{ PRIVILEGE.APPLY(conn, data.schema, data.table, data.name, priv.grantee, priv.without_grant, priv.with_grant) }}
+{% else %}
+    {{ PRIVILEGE.APPLY(conn, data.schema, data.table, o_data.name, priv.grantee, priv.without_grant, priv.with_grant) }}
+{% endif %}
 {% endfor %}
 {% endif %}
 {% endif %}
@@ -89,17 +117,29 @@ ALTER TABLE {{conn|qtIdent(data.schema, data.table)}}
 {% set seclabels = data.seclabels %}
 {% if 'deleted' in seclabels and seclabels.deleted|length > 0 %}
 {% for r in seclabels.deleted %}
+{% if data.name %}
 {{ SECLABEL.DROP(conn, 'COLUMN', data.schema, data.table, data.name, r.provider) }}
+{% else %}
+{{ SECLABEL.DROP(conn, 'COLUMN', data.schema, data.table, o_data.name, r.provider) }}
+{% endif %}
 {% endfor %}
 {% endif %}
 {% if 'added' in seclabels and seclabels.added|length > 0 %}
 {% for r in seclabels.added %}
+{% if data.name %}
 {{ SECLABEL.APPLY(conn, 'COLUMN',data.schema, data.table, data.name, r.provider, r.label) }}
+{% else %}
+{{ SECLABEL.APPLY(conn, 'COLUMN',data.schema, data.table, o_data.name, r.provider, r.label) }}
+{% endif %}
 {% endfor %}
 {% endif %}
 {% if 'changed' in seclabels and seclabels.changed|length > 0 %}
 {% for r in seclabels.changed %}
+{% if data.name %}
 {{ SECLABEL.APPLY(conn, 'COLUMN',data.schema, data.table, data.name, r.provider, r.label) }}
-{% endfor %}
+{% else %}
+{{ SECLABEL.APPLY(conn, 'COLUMN',data.schema, data.table, o_data.name, r.provider, r.label) }}
 {% endif %}
+{% endfor %}
 {% endif %}
+{% endif %}
\ No newline at end of file
diff --git a/web/pgadmin/browser/static/js/datamodel.js b/web/pgadmin/browser/static/js/datamodel.js
index 7b379ce..7d326f9 100644
--- a/web/pgadmin/browser/static/js/datamodel.js
+++ b/web/pgadmin/browser/static/js/datamodel.js
@@ -1065,8 +1065,10 @@ function(_, pgAdmin, $, Backbone) {
           return true;
         }
 
-        self.sessAttrs['changed'].push(obj);
-        (self.handler || self).trigger('pgadmin-session:changed', self, obj);
+        if (obj.sessChanged()) {
+          self.sessAttrs['changed'].push(obj);
+          (self.handler || self).trigger('pgadmin-session:changed', self, obj);
+        }
 
         return true;
       },


^ permalink  raw  reply  [nested|flat] 6+ messages in thread

* Re: Patch for RM1500 other issues [pgAdmin4]
@ 2016-08-03 10:42  Dave Page <[email protected]>
  parent: Harshal Dhumal <[email protected]>
  0 siblings, 1 reply; 6+ messages in thread

From: Dave Page @ 2016-08-03 10:42 UTC (permalink / raw)
  To: Harshal Dhumal <[email protected]>; +Cc: pgadmin-hackers

Hi

On Wed, Aug 3, 2016 at 7:36 AM, Harshal Dhumal
<[email protected]> wrote:
> Hi,
>
> PFA patch for RM1500.
>
> Changes/Issues fixed:
>
> 1] datamodel.js: For collection type added check before adding model into
> "changed" list instead of adding it blindly.
>
> 2] Type casting from str to int of column properties like attlen,
> attpricision.
>
> 3] Added missing data formating when adding new column to existing table
> (from table edit mode).
>
> 4] Added more validation for Foreign key constraint.
>
> 5] Column.js: Column grid (in table edit mode) show proper disabled color
> for disabled cell when grid renders.
>
> 6] All constraints and index js added idattribute to distinguish which
> s/constraint or s/index is updated on server side.
>
> 7] Column update.sql: Fixed sql when altering column data type. The issue
> was when we alter data type from which has length and precision to data type
> which don't have these properties and vice versa.
> For e.g. alter data type numeric(10,12) to real (and vice versa)
>
> 8] Renaming constraint (RM1500).

I get the following error when renaming a primary key. I have
restarted my app sever and done a hard reload/clear cache on my
browser. The generated SQL is:

ALTER TABLE public.foo
    RENAME CONSTRAINT foo_pkey TO foo_pkey1;


2016-08-03 11:39:43,764: INFO werkzeug: 127.0.0.1 - - [03/Aug/2016
11:39:43] "PUT /browser/table/obj/1/1/12403/2200/158521 HTTP/1.1" 500
-
Traceback (most recent call last):
  File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
line 2000, in __call__
    return self.wsgi_app(environ, start_response)
  File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
line 1991, in wsgi_app
    response = self.make_response(self.handle_exception(e))
  File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
line 1567, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
line 1988, in wsgi_app
    response = self.full_dispatch_request()
  File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
line 1641, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
line 1544, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
line 1639, in full_dispatch_request
    rv = self.dispatch_request()
  File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
line 1625, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/views.py",
line 84, in view
    return self.dispatch_request(*args, **kwargs)
  File "/Users/dpage/git/pgadmin4/web/pgadmin/browser/utils.py", line
235, in dispatch_request
    return method(*args, **kwargs)
  File "/Users/dpage/git/pgadmin4/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/__init__.py",
line 331, in wrap
    return f(*args, **kwargs)
  File "/Users/dpage/git/pgadmin4/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/__init__.py",
line 1446, in update
    data[k] = json.loads(v, encoding='utf-8')
  File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/simplejson/__init__.py",
line 533, in loads
    return cls(encoding=encoding, **kw).decode(s)
  File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/simplejson/decoder.py",
line 370, in decode
    obj, end = self.raw_decode(s)
  File "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/simplejson/decoder.py",
line 395, in raw_decode
    ord0 = ord(s[idx])
KeyError: 0

-- 
Dave Page
Blog: http://pgsnake.blogspot.com
Twitter: @pgsnake

EnterpriseDB UK: http://www.enterprisedb.com
The Enterprise PostgreSQL Company


-- 
Sent via pgadmin-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgadmin-hackers



^ permalink  raw  reply  [nested|flat] 6+ messages in thread

* Re: Patch for RM1500 other issues [pgAdmin4]
@ 2016-08-03 11:43  Harshal Dhumal <[email protected]>
  parent: Dave Page <[email protected]>
  0 siblings, 1 reply; 6+ messages in thread

From: Harshal Dhumal @ 2016-08-03 11:43 UTC (permalink / raw)
  To: Dave Page <[email protected]>; +Cc: pgadmin-hackers

Hi Dave,

This because on python 2.X simplejson throws KeyError instead of TypeError
if any error occurs while loading json data from given object. Now I have
handled that exception as well in attached patch.

I'm sending this as separate patch instead part of RM1500.


-- 
*Harshal Dhumal*
*Software Engineer*

EnterpriseDB India: http://www.enterprisedb.com
The Enterprise PostgreSQL Company

On Wed, Aug 3, 2016 at 4:12 PM, Dave Page <[email protected]> wrote:

> Hi
>
> On Wed, Aug 3, 2016 at 7:36 AM, Harshal Dhumal
> <[email protected]> wrote:
> > Hi,
> >
> > PFA patch for RM1500.
> >
> > Changes/Issues fixed:
> >
> > 1] datamodel.js: For collection type added check before adding model into
> > "changed" list instead of adding it blindly.
> >
> > 2] Type casting from str to int of column properties like attlen,
> > attpricision.
> >
> > 3] Added missing data formating when adding new column to existing table
> > (from table edit mode).
> >
> > 4] Added more validation for Foreign key constraint.
> >
> > 5] Column.js: Column grid (in table edit mode) show proper disabled color
> > for disabled cell when grid renders.
> >
> > 6] All constraints and index js added idattribute to distinguish which
> > s/constraint or s/index is updated on server side.
> >
> > 7] Column update.sql: Fixed sql when altering column data type. The issue
> > was when we alter data type from which has length and precision to data
> type
> > which don't have these properties and vice versa.
> > For e.g. alter data type numeric(10,12) to real (and vice versa)
> >
> > 8] Renaming constraint (RM1500).
>
> I get the following error when renaming a primary key. I have
> restarted my app sever and done a hard reload/clear cache on my
> browser. The generated SQL is:
>
> ALTER TABLE public.foo
>     RENAME CONSTRAINT foo_pkey TO foo_pkey1;
>
>
> 2016-08-03 11:39:43,764: INFO werkzeug: 127.0.0.1 - - [03/Aug/2016
> 11:39:43] "PUT /browser/table/obj/1/1/12403/2200/158521 HTTP/1.1" 500
> -
> Traceback (most recent call last):
>   File
> "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
> line 2000, in __call__
>     return self.wsgi_app(environ, start_response)
>   File
> "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
> line 1991, in wsgi_app
>     response = self.make_response(self.handle_exception(e))
>   File
> "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
> line 1567, in handle_exception
>     reraise(exc_type, exc_value, tb)
>   File
> "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
> line 1988, in wsgi_app
>     response = self.full_dispatch_request()
>   File
> "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
> line 1641, in full_dispatch_request
>     rv = self.handle_user_exception(e)
>   File
> "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
> line 1544, in handle_user_exception
>     reraise(exc_type, exc_value, tb)
>   File
> "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
> line 1639, in full_dispatch_request
>     rv = self.dispatch_request()
>   File
> "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
> line 1625, in dispatch_request
>     return self.view_functions[rule.endpoint](**req.view_args)
>   File
> "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/views.py",
> line 84, in view
>     return self.dispatch_request(*args, **kwargs)
>   File "/Users/dpage/git/pgadmin4/web/pgadmin/browser/utils.py", line
> 235, in dispatch_request
>     return method(*args, **kwargs)
>   File
> "/Users/dpage/git/pgadmin4/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/__init__.py",
> line 331, in wrap
>     return f(*args, **kwargs)
>   File
> "/Users/dpage/git/pgadmin4/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/__init__.py",
> line 1446, in update
>     data[k] = json.loads(v, encoding='utf-8')
>   File
> "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/simplejson/__init__.py",
> line 533, in loads
>     return cls(encoding=encoding, **kw).decode(s)
>   File
> "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/simplejson/decoder.py",
> line 370, in decode
>     obj, end = self.raw_decode(s)
>   File
> "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/simplejson/decoder.py",
> line 395, in raw_decode
>     ord0 = ord(s[idx])
> KeyError: 0
>
> --
> Dave Page
> Blog: http://pgsnake.blogspot.com
> Twitter: @pgsnake
>
> EnterpriseDB UK: http://www.enterprisedb.com
> The Enterprise PostgreSQL Company
>


-- 
Sent via pgadmin-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgadmin-hackers


Attachments:

  [text/x-patch] simplejson_handle_load_exception_on_python_2.X.X.patch (5.4K, 3-simplejson_handle_load_exception_on_python_2.X.X.patch)
  download | inline diff:
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/column/__init__.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/column/__init__.py
index b67783c..ef5cbe4 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/column/__init__.py
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/column/__init__.py
@@ -515,7 +515,7 @@ class ColumnsView(PGChildNodeView, DataTypeReader):
         for k, v in data.items():
             try:
                 data[k] = json.loads(v, encoding='utf-8')
-            except (ValueError, TypeError):
+            except (ValueError, TypeError, KeyError):
                 data[k] = v
 
         required_args = {
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/check_constraint/__init__.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/check_constraint/__init__.py
index 8f0a815..3405ded 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/check_constraint/__init__.py
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/check_constraint/__init__.py
@@ -403,7 +403,7 @@ class CheckConstraintView(PGChildNodeView):
         for k, v in data.items():
             try:
                 data[k] = json.loads(v, encoding='utf-8')
-            except (ValueError, TypeError):
+            except (ValueError, TypeError, KeyError):
                 data[k] = v
 
         for arg in required_args:
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/exclusion_constraint/__init__.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/exclusion_constraint/__init__.py
index 7a6396d..26115f7 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/exclusion_constraint/__init__.py
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/exclusion_constraint/__init__.py
@@ -448,7 +448,7 @@ class ExclusionConstraintView(PGChildNodeView):
         for k, v in data.items():
             try:
                 data[k] = json.loads(v, encoding='utf-8')
-            except (ValueError, TypeError):
+            except (ValueError, TypeError, KeyError):
                 data[k] = v
 
         for arg in required_args:
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/foreign_key/__init__.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/foreign_key/__init__.py
index b6d996b..9a2ee06 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/foreign_key/__init__.py
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/foreign_key/__init__.py
@@ -471,7 +471,7 @@ class ForeignKeyConstraintView(PGChildNodeView):
         for k, v in data.items():
             try:
                 data[k] = json.loads(v, encoding='utf-8')
-            except (ValueError, TypeError):
+            except (ValueError, TypeError, KeyError):
                 data[k] = v
 
         for arg in required_args:
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/index_constraint/__init__.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/index_constraint/__init__.py
index 37fb8f2..ecdbd8b 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/index_constraint/__init__.py
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/index_constraint/__init__.py
@@ -451,7 +451,7 @@ class IndexConstraintView(PGChildNodeView):
         for k, v in data.items():
             try:
                 data[k] = json.loads(v, encoding='utf-8')
-            except (ValueError, TypeError):
+            except (ValueError, TypeError, KeyError):
                 data[k] = v
 
         for arg in required_args:
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/__init__.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/__init__.py
index fa67947..d79c946 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/__init__.py
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/__init__.py
@@ -528,7 +528,7 @@ class IndexesView(PGChildNodeView):
         for k, v in data.items():
             try:
                 data[k] = json.loads(v, encoding='utf-8')
-            except (ValueError, TypeError):
+            except (ValueError, TypeError, KeyError):
                 data[k] = v
 
         required_args = {
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/triggers/__init__.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/triggers/__init__.py
index a639df0..b3e4eec 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/triggers/__init__.py
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/triggers/__init__.py
@@ -543,7 +543,7 @@ class TriggerView(PGChildNodeView):
         for k, v in data.items():
             try:
                 data[k] = json.loads(v, encoding='utf-8')
-            except (ValueError, TypeError):
+            except (ValueError, TypeError, KeyError):
                 data[k] = v
 
         required_args = {


^ permalink  raw  reply  [nested|flat] 6+ messages in thread

* Re: Patch for RM1500 other issues [pgAdmin4]
@ 2016-08-03 13:00  Dave Page <[email protected]>
  parent: Harshal Dhumal <[email protected]>
  0 siblings, 1 reply; 6+ messages in thread

From: Dave Page @ 2016-08-03 13:00 UTC (permalink / raw)
  To: Harshal Dhumal <[email protected]>; +Cc: pgadmin-hackers

Hi

On Wed, Aug 3, 2016 at 12:43 PM, Harshal Dhumal
<[email protected]> wrote:
> Hi Dave,
>
> This because on python 2.X simplejson throws KeyError instead of TypeError
> if any error occurs while loading json data from given object. Now I have
> handled that exception as well in attached patch.
>
> I'm sending this as separate patch instead part of RM1500.

I still see the same error, with both patches applied. I've restarted
the app server and cleared the browser cache and reloaded etc.


-- 
Dave Page
Blog: http://pgsnake.blogspot.com
Twitter: @pgsnake

EnterpriseDB UK: http://www.enterprisedb.com
The Enterprise PostgreSQL Company


-- 
Sent via pgadmin-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgadmin-hackers



^ permalink  raw  reply  [nested|flat] 6+ messages in thread

* Re: Patch for RM1500 other issues [pgAdmin4]
@ 2016-08-03 13:39  Harshal Dhumal <[email protected]>
  parent: Dave Page <[email protected]>
  0 siblings, 1 reply; 6+ messages in thread

From: Harshal Dhumal @ 2016-08-03 13:39 UTC (permalink / raw)
  To: Dave Page <[email protected]>; +Cc: pgadmin-hackers

Hi Dave,

Please find attached updated patch. I missed to change table __init__.py
file that why you got the error sorry for that. Also patch has changes for
both RM1500 and simplejson issue as both require changes in same file.
Please discard old patch of RM1500 and simplejson.




-- 
*Harshal Dhumal*
*Software Engineer*

EnterpriseDB India: http://www.enterprisedb.com
The Enterprise PostgreSQL Company

On Wed, Aug 3, 2016 at 6:30 PM, Dave Page <[email protected]> wrote:

> Hi
>
> On Wed, Aug 3, 2016 at 12:43 PM, Harshal Dhumal
> <[email protected]> wrote:
> > Hi Dave,
> >
> > This because on python 2.X simplejson throws KeyError instead of
> TypeError
> > if any error occurs while loading json data from given object. Now I have
> > handled that exception as well in attached patch.
> >
> > I'm sending this as separate patch instead part of RM1500.
>
> I still see the same error, with both patches applied. I've restarted
> the app server and cleared the browser cache and reloaded etc.
>
>
> --
> Dave Page
> Blog: http://pgsnake.blogspot.com
> Twitter: @pgsnake
>
> EnterpriseDB UK: http://www.enterprisedb.com
> The Enterprise PostgreSQL Company
>


-- 
Sent via pgadmin-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgadmin-hackers


Attachments:

  [text/x-patch] RM1500_with_simplejson_exception_handle_python_2.X.patch (44.7K, 3-RM1500_with_simplejson_exception_handle_python_2.X.patch)
  download | inline diff:
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/__init__.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/__init__.py
index 02057bf..8bda490 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/__init__.py
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/__init__.py
@@ -187,9 +187,9 @@ class TableView(PGChildNodeView, DataTypeReader, VacuumSettings):
       - It will return formatted output of query result
         as per client model format for index constraint node
 
-    * _cltype_formatter(self, type):
+    * _cltype_formatter(type): (staticmethod)
       - We need to remove [] from type and append it
-        after length/precision so we will set flag for
+        after length/precision so we will send flag for
         sql template
 
     * _parse_format_columns(self, data, mode=None):
@@ -627,17 +627,16 @@ class TableView(PGChildNodeView, DataTypeReader, VacuumSettings):
                     column['isdup'], column['attndims'], column['atttypmod']
                 )
 
-                import re
                 # If we have length & precision both
                 matchObj = re.search(r'(\d+),(\d+)', fulltype)
                 if matchObj:
-                    column['attlen'] = matchObj.group(1)
-                    column['attprecision'] = matchObj.group(2)
+                    column['attlen'] = int(matchObj.group(1))
+                    column['attprecision'] = int(matchObj.group(2))
                 else:
                     # If we have length only
                     matchObj = re.search(r'(\d+)', fulltype)
                     if matchObj:
-                        column['attlen'] = matchObj.group(1)
+                        column['attlen'] = int(matchObj.group(1))
                         column['attprecision'] = None
                     else:
                         column['attlen'] = None
@@ -1045,7 +1044,6 @@ class TableView(PGChildNodeView, DataTypeReader, VacuumSettings):
         # Filter inherited columns from all columns
         if 'columns' in data and len(data['columns']) > 0 \
                 and len(all_columns) > 0:
-            columns = []
             for row in data['columns']:
                 for i, col in enumerate(all_columns):
                     # If both name are same then remove it
@@ -1271,24 +1269,22 @@ class TableView(PGChildNodeView, DataTypeReader, VacuumSettings):
         except Exception as e:
             return internal_server_error(errormsg=str(e))
 
-    def _cltype_formatter(self, type):
+    @staticmethod
+    def _cltype_formatter(data_type):
         """
 
         Args:
-            data: Type string
+            data_type: Type string
 
         Returns:
             We need to remove [] from type and append it
-            after length/precision so we will set flag for
+            after length/precision so we will send flag for
             sql template
         """
-        if '[]' in type:
-            type = type.replace('[]', '')
-            self.hasSqrBracket = True
+        if '[]' in data_type:
+            return data_type[:-2], True
         else:
-            self.hasSqrBracket = False
-
-        return type
+            return data_type, False
 
     def _parse_format_columns(self, data, mode=None):
         """
@@ -1313,9 +1309,9 @@ class TableView(PGChildNodeView, DataTypeReader, VacuumSettings):
                         if 'attacl' in c:
                             c['attacl'] = parse_priv_to_db(c['attacl'], self.column_acl)
 
-                        # check type for '[]' in it
-                        c['cltype'] = self._cltype_formatter(c['cltype'])
-                        c['hasSqrBracket'] = self.hasSqrBracket
+                        if 'cltype' in c:
+                            # check type for '[]' in it
+                            c['cltype'], c['hasSqrBracket'] = self._cltype_formatter(c['cltype'])
 
                     data['columns'][action] = final_columns
         else:
@@ -1333,9 +1329,9 @@ class TableView(PGChildNodeView, DataTypeReader, VacuumSettings):
                 if 'attacl' in c:
                     c['attacl'] = parse_priv_to_db(c['attacl'], self.column_acl)
 
-                # check type for '[]' in it
-                c['cltype'] = self._cltype_formatter(c['cltype'])
-                c['hasSqrBracket'] = self.hasSqrBracket
+                if 'cltype' in c:
+                    # check type for '[]' in it
+                    c['cltype'], c['hasSqrBracket'] = self._cltype_formatter(c['cltype'])
 
             data['columns'] = final_columns
 
@@ -1359,7 +1355,7 @@ class TableView(PGChildNodeView, DataTypeReader, VacuumSettings):
         for k, v in data.items():
             try:
                 data[k] = json.loads(v, encoding='utf-8')
-            except (ValueError, TypeError):
+            except (ValueError, TypeError, KeyError):
                 data[k] = v
 
         required_args = [
@@ -1448,7 +1444,7 @@ class TableView(PGChildNodeView, DataTypeReader, VacuumSettings):
         for k, v in data.items():
             try:
                 data[k] = json.loads(v, encoding='utf-8')
-            except (ValueError, TypeError):
+            except (ValueError, TypeError, KeyError):
                 data[k] = v
 
         try:
@@ -1688,7 +1684,7 @@ class TableView(PGChildNodeView, DataTypeReader, VacuumSettings):
         for k, v in request.args.items():
             try:
                 data[k] = json.loads(v, encoding='utf-8')
-            except (ValueError, TypeError):
+            except (ValueError, TypeError, KeyError):
                 data[k] = v
 
         try:
@@ -1843,19 +1839,20 @@ class TableView(PGChildNodeView, DataTypeReader, VacuumSettings):
                         )
                         return '\n\n'.join(sql)
 
-                    cols = []
-                    for col in c['columns']:
-                        cols.append(col['local_column'])
+                    if 'columns' in c:
+                        cols = []
+                        for col in c['columns']:
+                            cols.append(col['local_column'])
 
-                    coveringindex = self.search_coveringindex(tid, cols)
+                        coveringindex = self.search_coveringindex(tid, cols)
 
-                    if coveringindex is None and 'autoindex' in c and c['autoindex'] and \
-                            ('coveringindex' in c and
-                                     c['coveringindex'] != ''):
-                        sql.append(render_template(
-                            "/".join([self.foreign_key_template_path, 'create_index.sql']),
-                            data=c, conn=self.conn).strip('\n')
-                                   )
+                        if coveringindex is None and 'autoindex' in c and c['autoindex'] and \
+                                ('coveringindex' in c and
+                                         c['coveringindex'] != ''):
+                            sql.append(render_template(
+                                "/".join([self.foreign_key_template_path, 'create_index.sql']),
+                                data=c, conn=self.conn).strip('\n')
+                                       )
 
             if 'added' in constraint:
                 for c in constraint['added']:
@@ -2163,9 +2160,46 @@ class TableView(PGChildNodeView, DataTypeReader, VacuumSettings):
                             return internal_server_error(errormsg=res)
                         old_data = res['rows'][0]
 
-                        old_data['cltype'] = self._cltype_formatter(old_data['cltype'])
-                        old_data['hasSqrBracket'] = self.hasSqrBracket
+                        old_data['cltype'], old_data['hasSqrBracket'] = self._cltype_formatter(old_data['cltype'])
+
+                        fulltype = self.get_full_type(
+                            old_data['typnspname'], old_data['typname'],
+                            old_data['isdup'], old_data['attndims'], old_data['atttypmod']
+                        )
 
+                        # If we have length & precision both
+                        matchObj = re.search(r'(\d+),(\d+)', fulltype)
+                        if matchObj:
+                            old_data['attlen'] = int(matchObj.group(1))
+                            old_data['attprecision'] = int(matchObj.group(2))
+                        else:
+                            # If we have length only
+                            matchObj = re.search(r'(\d+)', fulltype)
+                            if matchObj:
+                                old_data['attlen'] = int(matchObj.group(1))
+                                old_data['attprecision'] = None
+                            else:
+                                old_data['attlen'] = None
+                                old_data['attprecision'] = None
+
+                        # Manual Data type formatting
+                        # If data type has () with them then we need to remove them
+                        # eg bit(1) because we need to match the name with combobox
+                        isArray = False
+                        if old_data['cltype'].endswith('[]'):
+                            isArray = True
+                            old_data['cltype'] = old_data['cltype'].rstrip('[]')
+
+                        idx = old_data['cltype'].find('(')
+                        if idx and old_data['cltype'].endswith(')'):
+                            old_data['cltype'] = old_data['cltype'][:idx]
+
+                        if isArray:
+                            old_data['cltype'] += "[]"
+
+                        if old_data['typnspname'] != 'pg_catalog':
+                            old_data['cltype'] = self.qtIdent(self.conn, old_data['typnspname']) \
+                                               + '.' + old_data['cltype']
                         # Sql for alter column
                         if 'inheritedfrom' not in c:
                             column_sql += render_template("/".join(
@@ -2259,7 +2293,8 @@ class TableView(PGChildNodeView, DataTypeReader, VacuumSettings):
 
         return SQL
 
-    def validate_constrains(self, key, data):
+    @staticmethod
+    def validate_constrains(key, data):
 
         if key == 'primary_key' or key == 'unique_constraint':
             if 'columns' in data and len(data['columns']) > 0:
@@ -2267,15 +2302,17 @@ class TableView(PGChildNodeView, DataTypeReader, VacuumSettings):
             else:
                 return False
         elif key == 'foreign_key':
-            for arg in ['columns']:
-                if arg not in data:
+            if 'oid' not in data:
+                for arg in ['columns']:
+                    if arg not in data:
+                        return False
+                    elif isinstance(data[arg], list) and len(data[arg]) < 1:
+                        return False
+
+                if 'autoindex' in data and data['autoindex'] and \
+                        ('coveringindex' not in data or
+                                                  data['coveringindex'] == ''):
                     return False
-                elif isinstance(data[arg], list) and len(data[arg]) < 1:
-                    return False
-
-            if data['autoindex'] and ('coveringindex' not in data or
-                                              data['coveringindex'] == ''):
-                return False
 
             return True
 
@@ -2406,8 +2443,8 @@ class TableView(PGChildNodeView, DataTypeReader, VacuumSettings):
                     c['attacl'] = parse_priv_to_db(c['attacl'], self.column_acl)
 
                 # check type for '[]' in it
-                c['cltype'] = self._cltype_formatter(c['cltype'])
-                c['hasSqrBracket'] = self.hasSqrBracket
+                if 'cltype' in c:
+                    c['cltype'], c['hasSqrBracket'] = self._cltype_formatter(c['cltype'])
 
         sql_header = u"-- Table: {0}\n\n-- ".format(self.qtIdent(self.conn,
                                                                 data['schema'],
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/column/__init__.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/column/__init__.py
index b67783c..ef5cbe4 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/column/__init__.py
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/column/__init__.py
@@ -515,7 +515,7 @@ class ColumnsView(PGChildNodeView, DataTypeReader):
         for k, v in data.items():
             try:
                 data[k] = json.loads(v, encoding='utf-8')
-            except (ValueError, TypeError):
+            except (ValueError, TypeError, KeyError):
                 data[k] = v
 
         required_args = {
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/column/templates/column/js/column.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/column/templates/column/js/column.js
index d7fe5a4..072adaf 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/column/templates/column/js/column.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/column/templates/column/js/column.js
@@ -57,17 +57,29 @@ function($, _, S, pgAdmin, pgBrowser, Backform, alertify) {
       },
       dependentChanged: function () {
         this.$el.empty();
-        var model = this.model;
-        var column = this.column;
-        editable = this.column.get("editable");
+        var model = this.model,
+            column = this.column,
+            editable = this.column.get("editable"),
+            is_editable = _.isFunction(editable) ? !!editable.apply(column, [model]) : !!editable;
 
-        is_editable = _.isFunction(editable) ? !!editable.apply(column, [model]) : !!editable;
         if (is_editable){ this.$el.addClass("editable"); }
         else { this.$el.removeClass("editable"); }
 
         this.delegateEvents();
         return this;
       },
+      render: function() {
+        Backgrid.NumberCell.prototype.render.apply(this, arguments);
+
+        var model = this.model,
+            column = this.column,
+            editable = this.column.get("editable"),
+            is_editable = _.isFunction(editable) ? !!editable.apply(column, [model]) : !!editable;
+
+        if (is_editable){ this.$el.addClass("editable"); }
+        else { this.$el.removeClass("editable"); }
+        return this;
+      },
       remove: Backgrid.Extension.DependentCell.prototype.remove
     });
 
@@ -140,6 +152,8 @@ function($, _, S, pgAdmin, pgBrowser, Backform, alertify) {
         ]);
       },
       model: pgBrowser.Node.Model.extend({
+        idAttribute: 'attnum',
+
         defaults: {
           name: undefined,
           attowner: undefined,
@@ -156,7 +170,9 @@ function($, _, S, pgAdmin, pgBrowser, Backform, alertify) {
           is_primary_key: false,
           inheritedfrom: undefined,
           attstattarget:undefined,
-          attnotnull: false
+          attnotnull: false,
+          attlen: null,
+          attprecision: null
         },
         schema: [{
           id: 'name', label: '{{ _('Name') }}', cell: 'string',
@@ -322,16 +338,21 @@ function($, _, S, pgAdmin, pgBrowser, Backform, alertify) {
              if(!_.isUndefined(m.get('inheritedfrom'))) {
                 return false;
              }
+
+             if (!m.datatypes) {
+              // datatypes not loaded, may be this call is from CallByNeed from backgrid cell initialize.
+              return true;
+             }
              var of_type = m.get('cltype'),
                flag = false;
-              _.each(m.datatypes, function(o) {
-                if ( of_type == o.value ) {
-                    if(o.length)
-                    {
-                      m.set('min_val', o.min_val, {silent: true});
-                      m.set('max_val', o.max_val, {silent: true});
-                      flag = true;
-                    }
+
+               _.each(m.datatypes, function(o) {
+               if ( of_type == o.value ) {
+                 if(o.length) {
+                   m.set('min_val', o.min_val, {silent: true});
+                   m.set('max_val', o.max_val, {silent: true});
+                   flag = true;
+                 }
                 }
               });
 
@@ -351,12 +372,11 @@ function($, _, S, pgAdmin, pgBrowser, Backform, alertify) {
                flag = true;
               _.each(m.datatypes, function(o) {
                 if ( of_type == o.value ) {
-                    if(o.precision)
-                    {
-                      m.set('min_val', o.min_val, {silent: true});
-                      m.set('max_val', o.max_val, {silent: true});
-                      flag = false;
-                    }
+                  if(o.precision) {
+                    m.set('min_val', o.min_val, {silent: true});
+                    m.set('max_val', o.max_val, {silent: true});
+                    flag = false;
+                  }
                 }
               });
 
@@ -373,16 +393,20 @@ function($, _, S, pgAdmin, pgBrowser, Backform, alertify) {
                 return false;
              }
 
+             if (!m.datatypes) {
+              // datatypes not loaded yet, may be this call is from CallByNeed from backgrid cell initialize.
+              return true;
+             }
+
              var of_type = m.get('cltype'),
                flag = false;
               _.each(m.datatypes, function(o) {
                 if ( of_type == o.value ) {
-                    if(o.precision)
-                    {
-                      m.set('min_val', o.min_val, {silent: true});
-                      m.set('max_val', o.max_val, {silent: true});
-                      flag = true;
-                    }
+                  if(o.precision) {
+                    m.set('min_val', o.min_val, {silent: true});
+                    m.set('max_val', o.max_val, {silent: true});
+                    flag = true;
+                  }
                 }
               });
 
@@ -401,22 +425,22 @@ function($, _, S, pgAdmin, pgBrowser, Backform, alertify) {
           deps: ['cltype'], disabled: function(m) {
              var of_type = m.get('cltype'),
                flag = true;
-              _.each(m.datatypes, function(o) {
+             _.each(m.datatypes, function(o) {
                 if ( of_type == o.value ) {
                     if(o.is_collatable)
                     {
                       flag = false;
                     }
                 }
-              });
-              if (flag) {
+             });
+             if (flag) {
                 setTimeout(function(){
                   if(m.get('collspcname') && m.get('collspcname') !== '') {
                     m.set('collspcname', "");
                   }
                 }, 10);
-              }
-              return flag;
+             }
+             return flag;
           }
         },{
           id: 'defval', label:'{{ _('Default Value') }}', cell: 'string',
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/check_constraint/__init__.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/check_constraint/__init__.py
index 8f0a815..3405ded 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/check_constraint/__init__.py
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/check_constraint/__init__.py
@@ -403,7 +403,7 @@ class CheckConstraintView(PGChildNodeView):
         for k, v in data.items():
             try:
                 data[k] = json.loads(v, encoding='utf-8')
-            except (ValueError, TypeError):
+            except (ValueError, TypeError, KeyError):
                 data[k] = v
 
         for arg in required_args:
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/check_constraint/templates/check_constraint/js/check_constraint.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/check_constraint/templates/check_constraint/js/check_constraint.js
index cb33a1a..9389bc9 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/check_constraint/templates/check_constraint/js/check_constraint.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/check_constraint/templates/check_constraint/js/check_constraint.js
@@ -90,6 +90,8 @@ function($, _, S, pgAdmin, pgBrowser, Alertify) {
       },
       canDrop: pgBrowser.Nodes['schema'].canChildDrop,
       model: pgAdmin.Browser.Node.Model.extend({
+        idAttribute: 'oid',
+
         defaults: {
           name: undefined,
           oid: undefined,
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/exclusion_constraint/__init__.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/exclusion_constraint/__init__.py
index 7a6396d..26115f7 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/exclusion_constraint/__init__.py
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/exclusion_constraint/__init__.py
@@ -448,7 +448,7 @@ class ExclusionConstraintView(PGChildNodeView):
         for k, v in data.items():
             try:
                 data[k] = json.loads(v, encoding='utf-8')
-            except (ValueError, TypeError):
+            except (ValueError, TypeError, KeyError):
                 data[k] = v
 
         for arg in required_args:
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/exclusion_constraint/templates/exclusion_constraint/js/exclusion_constraint.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/exclusion_constraint/templates/exclusion_constraint/js/exclusion_constraint.js
index 9232677..abdd623 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/exclusion_constraint/templates/exclusion_constraint/js/exclusion_constraint.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/exclusion_constraint/templates/exclusion_constraint/js/exclusion_constraint.js
@@ -639,6 +639,8 @@ function($, _, S, pgAdmin, pgBrowser, Alertify) {
       },
       // Define the model for exclusion constraint node
       model: pgAdmin.Browser.Node.Model.extend({
+        idAttribute: 'oid',
+
         defaults: {
           name: undefined,
           oid: undefined,
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/foreign_key/__init__.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/foreign_key/__init__.py
index b6d996b..9a2ee06 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/foreign_key/__init__.py
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/foreign_key/__init__.py
@@ -471,7 +471,7 @@ class ForeignKeyConstraintView(PGChildNodeView):
         for k, v in data.items():
             try:
                 data[k] = json.loads(v, encoding='utf-8')
-            except (ValueError, TypeError):
+            except (ValueError, TypeError, KeyError):
                 data[k] = v
 
         for arg in required_args:
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/foreign_key/templates/foreign_key/js/foreign_key.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/foreign_key/templates/foreign_key/js/foreign_key.js
index cae2efa..9da61f9 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/foreign_key/templates/foreign_key/js/foreign_key.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/foreign_key/templates/foreign_key/js/foreign_key.js
@@ -672,6 +672,8 @@ function($, _, S, pgAdmin, pgBrowser, Alertify) {
       },
       // Define the model for foreign key node
       model: pgAdmin.Browser.Node.Model.extend({
+        idAttribute: 'oid',
+
         defaults: {
           name: undefined,
           oid: undefined,
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/index_constraint/__init__.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/index_constraint/__init__.py
index 37fb8f2..ecdbd8b 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/index_constraint/__init__.py
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/index_constraint/__init__.py
@@ -451,7 +451,7 @@ class IndexConstraintView(PGChildNodeView):
         for k, v in data.items():
             try:
                 data[k] = json.loads(v, encoding='utf-8')
-            except (ValueError, TypeError):
+            except (ValueError, TypeError, KeyError):
                 data[k] = v
 
         for arg in required_args:
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/index_constraint/templates/index_constraint/js/index_constraint.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/index_constraint/templates/index_constraint/js/index_constraint.js
index 73a563b..7db68d5 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/index_constraint/templates/index_constraint/js/index_constraint.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/index_constraint/templates/index_constraint/js/index_constraint.js
@@ -79,6 +79,8 @@ function($, _, S, pgAdmin, pgBrowser, alertify) {
 
       // Define the model for index constraint node
       model: pgAdmin.Browser.Node.Model.extend({
+        idAttribute: 'oid',
+
         defaults: {
           name: undefined,
           oid: undefined,
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/__init__.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/__init__.py
index fa67947..d79c946 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/__init__.py
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/__init__.py
@@ -528,7 +528,7 @@ class IndexesView(PGChildNodeView):
         for k, v in data.items():
             try:
                 data[k] = json.loads(v, encoding='utf-8')
-            except (ValueError, TypeError):
+            except (ValueError, TypeError, KeyError):
                 data[k] = v
 
         required_args = {
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/templates/index/js/index.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/templates/index/js/index.js
index 3283582..8ff8359 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/templates/index/js/index.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/templates/index/js/index.js
@@ -238,8 +238,11 @@ function($, _, S, pgAdmin, pgBrowser, Backform, alertify) {
       canDrop: pgBrowser.Nodes['schema'].canChildDrop,
       canDropCascade: pgBrowser.Nodes['schema'].canChildDrop,
       model: pgAdmin.Browser.Node.Model.extend({
+        idAttribute: 'oid',
+
         defaults: {
           name: undefined,
+          oid: undefined,
           nspname: undefined,
           tabname: undefined,
           spcname: 'pg_default',
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/column/sql/9.1_plus/update.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/column/sql/9.1_plus/update.sql
index 2b1d5b9..454f964 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/column/sql/9.1_plus/update.sql
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/column/sql/9.1_plus/update.sql
@@ -2,7 +2,7 @@
 {% import 'column/macros/privilege.macros' as PRIVILEGE %}
 {% import 'macros/variable.macros' as VARIABLE %}
 {###  Rename column name ###}
-{% if data.name != o_data.name %}
+{% if data.name and data.name != o_data.name %}
 ALTER TABLE {{conn|qtIdent(data.schema, data.table)}}
     RENAME {{conn|qtIdent(o_data.name)}} TO {{conn|qtIdent(data.name)}};
 
@@ -10,8 +10,8 @@ ALTER TABLE {{conn|qtIdent(data.schema, data.table)}}
 {###  Alter column type and collation ###}
 {% if (data.cltype and data.cltype != o_data.cltype) or (data.attlen and data.attlen != o_data.attlen) or (data.attprecision and data.attprecision != o_data.attprecision) %}
 ALTER TABLE {{conn|qtIdent(data.schema, data.table)}}
-    ALTER COLUMN {{conn|qtIdent(data.name)}} TYPE {% if data.cltype %}{{conn|qtTypeIdent(data.cltype)}} {% else %}{{o_data.cltype}} {% endif %}{% if data.attlen %}
-({{data.attlen}}{% if data.attprecision%}, {{data.attprecision}}{% endif %}){% endif %}{% if data.hasSqrBracket %}
+    ALTER COLUMN {% if data.name %}{{conn|qtTypeIdent(data.name)}}{% else %}{{conn|qtTypeIdent(o_data.name)}}{% endif %} TYPE {% if data.cltype %}{{conn|qtTypeIdent(data.cltype)}} {% else %}{{conn|qtTypeIdent(o_data.cltype)}} {% endif %}
+{% if data.attlen %}({{data.attlen}}{% elif not data.cltype %}({{o_data.attlen}}{% endif %}{% if data.attprecision%}, {{data.attprecision}}){% elif not data.cltype %}, {{o_data.attprecision}}){% elif data.attlen %}){% endif %}{% if data.hasSqrBracket %}
 []{% endif %}{% if data.collspcname and data.collspcname != o_data.collspcname %}
  COLLATE {{data.collspcname}}{% endif %};
 
@@ -19,31 +19,35 @@ ALTER TABLE {{conn|qtIdent(data.schema, data.table)}}
 {###  Alter column default value ###}
 {% if data.defval and data.defval != o_data.defval %}
 ALTER TABLE {{conn|qtIdent(data.schema, data.table)}}
-    ALTER COLUMN {{conn|qtIdent(data.name)}} SET DEFAULT {{data.defval}};
+    ALTER COLUMN {% if data.name %}{{conn|qtTypeIdent(data.name)}}{% else %}{{conn|qtTypeIdent(o_data.name)}}{% endif %} SET DEFAULT {{data.defval}};
 
 {% endif %}
 {###  Alter column not null value ###}
 {% if 'attnotnull' in data and data.attnotnull != o_data.attnotnull %}
 ALTER TABLE {{conn|qtIdent(data.schema, data.table)}}
-    ALTER COLUMN {{conn|qtIdent(data.name)}} {% if data.attnotnull %}SET{% else %}DROP{% endif %} NOT NULL;
+    ALTER COLUMN {% if data.name %}{{conn|qtTypeIdent(data.name)}}{% else %}{{conn|qtTypeIdent(o_data.name)}}{% endif %} {% if data.attnotnull %}SET{% else %}DROP{% endif %} NOT NULL;
 
 {% endif %}
 {###  Alter column statistics value ###}
 {% if data.attstattarget and data.attstattarget != o_data.attstattarget %}
 ALTER TABLE {{conn|qtIdent(data.schema, data.table)}}
-    ALTER COLUMN {{conn|qtIdent(data.name)}} SET STATISTICS {{data.attstattarget}};
+    ALTER COLUMN {% if data.name %}{{conn|qtTypeIdent(data.name)}}{% else %}{{conn|qtTypeIdent(o_data.name)}}{% endif %} SET STATISTICS {{data.attstattarget}};
 
 {% endif %}
 {###  Alter column storage value ###}
 {% if data.attstorage and data.attstorage != o_data.attstorage %}
 ALTER TABLE {{conn|qtIdent(data.schema, data.table)}}
-    ALTER COLUMN {{conn|qtIdent(data.name)}} SET STORAGE {%if data.attstorage == 'p' %}
+    ALTER COLUMN {% if data.name %}{{conn|qtTypeIdent(data.name)}}{% else %}{{conn|qtTypeIdent(o_data.name)}}{% endif %} SET STORAGE {%if data.attstorage == 'p' %}
 PLAIN{% elif data.attstorage == 'm'%}MAIN{% elif data.attstorage == 'e'%}
 EXTERNAL{% elif data.attstorage == 'x'%}EXTENDED{% endif %};
 
 {% endif %}
 {% if data.description is defined %}
+{% if data.name %}
 COMMENT ON COLUMN {{conn|qtIdent(data.schema, data.table, data.name)}}
+{% else %}
+COMMENT ON COLUMN {{conn|qtIdent(data.schema, data.table, o_data.name)}}
+{% endif %}
     IS {{data.description|qtLiteral}};
 
 {% endif %}
@@ -52,15 +56,27 @@ COMMENT ON COLUMN {{conn|qtIdent(data.schema, data.table, data.name)}}
 {% set variables = data.attoptions %}
 {% if 'deleted' in variables and variables.deleted|length > 0 %}
 ALTER TABLE {{conn|qtIdent(data.schema, data.table)}}
+{% if data.name %}
     {{ VARIABLE.UNSET(conn, 'COLUMN', data.name, variables.deleted) }}
+{% else %}
+    {{ VARIABLE.UNSET(conn, 'COLUMN', o_data.name, variables.deleted) }}
+{% endif %}
 {% endif %}
 {% if 'added' in variables and variables.added|length > 0 %}
 ALTER TABLE {{conn|qtIdent(data.schema, data.table)}}
+{% if data.name %}
     {{ VARIABLE.SET(conn, 'COLUMN', data.name, variables.added) }}
+{% else %}
+    {{ VARIABLE.SET(conn, 'COLUMN', o_data.name, variables.added) }}
+{% endif %}
 {% endif %}
 {% if 'changed' in variables and variables.changed|length > 0 %}
 ALTER TABLE {{conn|qtIdent(data.schema, data.table)}}
+{% if data.name %}
     {{ VARIABLE.SET(conn, 'COLUMN', data.name, variables.changed) }}
+{% else %}
+    {{ VARIABLE.SET(conn, 'COLUMN', o_data.name, variables.changed) }}
+{% endif %}
 {% endif %}
 
 {% endif %}
@@ -69,18 +85,31 @@ ALTER TABLE {{conn|qtIdent(data.schema, data.table)}}
 {% if data.attacl %}
 {% if 'deleted' in data.attacl %}
 {% for priv in data.attacl.deleted %}
+{% if data.name %}
 {{ PRIVILEGE.RESETALL(conn, data.schema, data.table, data.name, priv.grantee) }}
+{% else %}
+{{ PRIVILEGE.RESETALL(conn, data.schema, data.table, o_data.name, priv.grantee) }}
+{% endif %}
 {% endfor %}
 {% endif %}
 {% if 'changed' in data.attacl %}
 {% for priv in data.attacl.changed %}
+{% if data.name %}
 {{ PRIVILEGE.RESETALL(conn, data.schema, data.table, data.name, priv.grantee) }}
 {{ PRIVILEGE.APPLY(conn, data.schema, data.table, data.name, priv.grantee, priv.without_grant, priv.with_grant) }}
+{% else %}
+{{ PRIVILEGE.RESETALL(conn, data.schema, data.table, o_data.name, priv.grantee) }}
+{{ PRIVILEGE.APPLY(conn, data.schema, data.table, o_data.name, priv.grantee, priv.without_grant, priv.with_grant) }}
+{% endif %}
 {% endfor %}
 {% endif %}
 {% if 'added' in data.attacl %}
 {% for priv in data.attacl.added %}
+{% if data.name %}
 {{ PRIVILEGE.APPLY(conn, data.schema, data.table, data.name, priv.grantee, priv.without_grant, priv.with_grant) }}
+{% else %}
+{{ PRIVILEGE.APPLY(conn, data.schema, data.table, o_data.name, priv.grantee, priv.without_grant, priv.with_grant) }}
+{% endif %}
 {% endfor %}
 {% endif %}
 {% endif %}
@@ -90,18 +119,30 @@ ALTER TABLE {{conn|qtIdent(data.schema, data.table)}}
 {% set seclabels = data.seclabels %}
 {% if 'deleted' in seclabels and seclabels.deleted|length > 0 %}
 {% for r in seclabels.deleted %}
+{% if data.name %}
 {{ SECLABEL.DROP(conn, 'COLUMN', data.schema, data.table, data.name, r.provider) }}
+{% else %}
+{{ SECLABEL.DROP(conn, 'COLUMN', data.schema, data.table, o_data.name, r.provider) }}
+{% endif %}
 {% endfor %}
 {% endif %}
 {% if 'added' in seclabels and seclabels.added|length > 0 %}
 {% for r in seclabels.added %}
+{% if data.name %}
 {{ SECLABEL.APPLY(conn, 'COLUMN',data.schema, data.table, data.name, r.provider, r.label) }}
+{% else %}
+{{ SECLABEL.APPLY(conn, 'COLUMN',data.schema, data.table, o_data.name, r.provider, r.label) }}
+{% endif %}
 {% endfor %}
 {% endif %}
 {% if 'changed' in seclabels and seclabels.changed|length > 0 %}
 {% for r in seclabels.changed %}
+{% if data.name %}
 {{ SECLABEL.APPLY(conn, 'COLUMN',data.schema, data.table, data.name, r.provider, r.label) }}
+{% else %}
+{{ SECLABEL.APPLY(conn, 'COLUMN',data.schema, data.table, o_data.name, r.provider, r.label) }}
+{% endif %}
 {% endfor %}
 {% endif %}
 
-{% endif %}
+{% endif %}
\ No newline at end of file
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 5445805..77ef8ea 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
@@ -2,7 +2,7 @@
 {% import 'column/macros/privilege.macros' as PRIVILEGE %}
 {% import 'macros/variable.macros' as VARIABLE %}
 {###  Rename column name ###}
-{% if data.name != o_data.name %}
+{% if data.name and data.name != o_data.name %}
 ALTER TABLE {{conn|qtIdent(data.schema, data.table)}}
     RENAME {{conn|qtIdent(o_data.name)}} TO {{conn|qtIdent(data.name)}};
 
@@ -10,40 +10,43 @@ ALTER TABLE {{conn|qtIdent(data.schema, data.table)}}
 {###  Alter column type and collation ###}
 {% if (data.cltype and data.cltype != o_data.cltype) or (data.attlen and data.attlen != o_data.attlen) or (data.attprecision and data.attprecision != o_data.attprecision) %}
 ALTER TABLE {{conn|qtIdent(data.schema, data.table)}}
-    ALTER COLUMN {{conn|qtIdent(data.name)}} TYPE {% if data.cltype %}{{conn|qtTypeIdent(data.cltype)}} {% else %}{{o_data.cltype}} {% endif %}{% if data.attlen %}
-({{data.attlen}}{% if data.attprecision%}, {{data.attprecision}}{% endif %}){% endif %}{% if data.hasSqrBracket %}
+    ALTER COLUMN {% if data.name %}{{conn|qtTypeIdent(data.name)}}{% else %}{{conn|qtTypeIdent(o_data.name)}}{% endif %} TYPE {% if data.cltype %}{{conn|qtTypeIdent(data.cltype)}} {% else %}{{conn|qtTypeIdent(o_data.cltype)}} {% endif %}
+{% if data.attlen %}({{data.attlen}}{% elif not data.cltype %}({{o_data.attlen}}{% endif %}{% if data.attprecision%}, {{data.attprecision}}){% elif not data.cltype %}, {{o_data.attprecision}}){% elif data.attlen %}){% endif %}{% if data.hasSqrBracket %}
 []{% endif %}{% if data.collspcname and data.collspcname != o_data.collspcname %}
  COLLATE {{data.collspcname}}{% endif %};
-
 {% endif %}
 {###  Alter column default value ###}
 {% if data.defval and data.defval != o_data.defval %}
 ALTER TABLE {{conn|qtIdent(data.schema, data.table)}}
-    ALTER COLUMN {{conn|qtIdent(data.name)}} SET DEFAULT {{data.defval}};
+    ALTER COLUMN {% if data.name %}{{conn|qtTypeIdent(data.name)}}{% else %}{{conn|qtTypeIdent(o_data.name)}}{% endif %} SET DEFAULT {{data.defval}};
 
 {% endif %}
 {###  Alter column not null value ###}
 {% if 'attnotnull' in data and data.attnotnull != o_data.attnotnull %}
 ALTER TABLE {{conn|qtIdent(data.schema, data.table)}}
-    ALTER COLUMN {{conn|qtIdent(data.name)}} {% if data.attnotnull %}SET{% else %}DROP{% endif %} NOT NULL;
+    ALTER COLUMN {% if data.name %}{{conn|qtTypeIdent(data.name)}}{% else %}{{conn|qtTypeIdent(o_data.name)}}{% endif %} {% if data.attnotnull %}SET{% else %}DROP{% endif %} NOT NULL;
 
 {% endif %}
 {###  Alter column statistics value ###}
 {% if data.attstattarget and data.attstattarget != o_data.attstattarget %}
 ALTER TABLE {{conn|qtIdent(data.schema, data.table)}}
-    ALTER COLUMN {{conn|qtIdent(data.name)}} SET STATISTICS {{data.attstattarget}};
+    ALTER COLUMN {% if data.name %}{{conn|qtTypeIdent(data.name)}}{% else %}{{conn|qtTypeIdent(o_data.name)}}{% endif %} SET STATISTICS {{data.attstattarget}};
 
 {% endif %}
 {###  Alter column storage value ###}
 {% if data.attstorage and data.attstorage != o_data.attstorage %}
 ALTER TABLE {{conn|qtIdent(data.schema, data.table)}}
-    ALTER COLUMN {{conn|qtIdent(data.name)}} SET STORAGE {%if data.attstorage == 'p' %}
+    ALTER COLUMN {% if data.name %}{{conn|qtTypeIdent(data.name)}}{% else %}{{conn|qtTypeIdent(o_data.name)}}{% endif %} SET STORAGE {%if data.attstorage == 'p' %}
 PLAIN{% elif data.attstorage == 'm'%}MAIN{% elif data.attstorage == 'e'%}
 EXTERNAL{% elif data.attstorage == 'x'%}EXTENDED{% endif %};
 
 {% endif %}
 {% if data.description is defined %}
+{% if data.name %}
 COMMENT ON COLUMN {{conn|qtIdent(data.schema, data.table, data.name)}}
+{% else %}
+COMMENT ON COLUMN {{conn|qtIdent(data.schema, data.table, o_data.name)}}
+{% endif %}
     IS {{data.description|qtLiteral}};
 
 {% endif %}
@@ -52,15 +55,27 @@ COMMENT ON COLUMN {{conn|qtIdent(data.schema, data.table, data.name)}}
 {% set variables = data.attoptions %}
 {% if 'deleted' in variables and variables.deleted|length > 0 %}
 ALTER TABLE {{conn|qtIdent(data.schema, data.table)}}
+{% if data.name %}
     {{ VARIABLE.UNSET(conn, 'COLUMN', data.name, variables.deleted) }}
+{% else %}
+    {{ VARIABLE.UNSET(conn, 'COLUMN', o_data.name, variables.deleted) }}
+{% endif %}
 {% endif %}
 {% if 'added' in variables and variables.added|length > 0 %}
 ALTER TABLE {{conn|qtIdent(data.schema, data.table)}}
+{% if data.name %}
     {{ VARIABLE.SET(conn, 'COLUMN', data.name, variables.added) }}
+{% else %}
+    {{ VARIABLE.SET(conn, 'COLUMN', o_data.name, variables.added) }}
+{% endif %}
 {% endif %}
 {% if 'changed' in variables and variables.changed|length > 0 %}
 ALTER TABLE {{conn|qtIdent(data.schema, data.table)}}
+{% if data.name %}
     {{ VARIABLE.SET(conn, 'COLUMN', data.name, variables.changed) }}
+{% else %}
+    {{ VARIABLE.SET(conn, 'COLUMN', o_data.name, variables.changed) }}
+{% endif %}
 {% endif %}
 {% endif %}
 {### Update column privileges ###}
@@ -68,18 +83,31 @@ ALTER TABLE {{conn|qtIdent(data.schema, data.table)}}
 {% if data.attacl %}
 {% if 'deleted' in data.attacl %}
 {% for priv in data.attacl.deleted %}
-{{ PRIVILEGE.RESETALL(conn, data.schema, data.table, data.name, priv.grantee) }}
+{% if data.name %}
+    {{ PRIVILEGE.RESETALL(conn, data.schema, data.table, data.name, priv.grantee) }}
+{% else %}
+    {{ PRIVILEGE.RESETALL(conn, data.schema, data.table, o_data.name, priv.grantee) }}
+{% endif %}
 {% endfor %}
 {% endif %}
 {% if 'changed' in data.attacl %}
 {% for priv in data.attacl.changed %}
-{{ PRIVILEGE.RESETALL(conn, data.schema, data.table, data.name, priv.grantee) }}
-{{ PRIVILEGE.APPLY(conn, data.schema, data.table, data.name, priv.grantee, priv.without_grant, priv.with_grant) }}
+{% if data.name %}
+    {{ PRIVILEGE.RESETALL(conn, data.schema, data.table, data.name, priv.grantee) }}
+    {{ PRIVILEGE.APPLY(conn, data.schema, data.table, data.name, priv.grantee, priv.without_grant, priv.with_grant) }}
+{% else %}
+    {{ PRIVILEGE.RESETALL(conn, data.schema, data.table, o_data.name, priv.grantee) }}
+    {{ PRIVILEGE.APPLY(conn, data.schema, data.table, o_data.name, priv.grantee, priv.without_grant, priv.with_grant) }}
+{% endif %}
 {% endfor %}
 {% endif %}
 {% if 'added' in data.attacl %}
 {% for priv in data.attacl.added %}
-{{ PRIVILEGE.APPLY(conn, data.schema, data.table, data.name, priv.grantee, priv.without_grant, priv.with_grant) }}
+{% if data.name %}
+    {{ PRIVILEGE.APPLY(conn, data.schema, data.table, data.name, priv.grantee, priv.without_grant, priv.with_grant) }}
+{% else %}
+    {{ PRIVILEGE.APPLY(conn, data.schema, data.table, o_data.name, priv.grantee, priv.without_grant, priv.with_grant) }}
+{% endif %}
 {% endfor %}
 {% endif %}
 {% endif %}
@@ -89,17 +117,29 @@ ALTER TABLE {{conn|qtIdent(data.schema, data.table)}}
 {% set seclabels = data.seclabels %}
 {% if 'deleted' in seclabels and seclabels.deleted|length > 0 %}
 {% for r in seclabels.deleted %}
+{% if data.name %}
 {{ SECLABEL.DROP(conn, 'COLUMN', data.schema, data.table, data.name, r.provider) }}
+{% else %}
+{{ SECLABEL.DROP(conn, 'COLUMN', data.schema, data.table, o_data.name, r.provider) }}
+{% endif %}
 {% endfor %}
 {% endif %}
 {% if 'added' in seclabels and seclabels.added|length > 0 %}
 {% for r in seclabels.added %}
+{% if data.name %}
 {{ SECLABEL.APPLY(conn, 'COLUMN',data.schema, data.table, data.name, r.provider, r.label) }}
+{% else %}
+{{ SECLABEL.APPLY(conn, 'COLUMN',data.schema, data.table, o_data.name, r.provider, r.label) }}
+{% endif %}
 {% endfor %}
 {% endif %}
 {% if 'changed' in seclabels and seclabels.changed|length > 0 %}
 {% for r in seclabels.changed %}
+{% if data.name %}
 {{ SECLABEL.APPLY(conn, 'COLUMN',data.schema, data.table, data.name, r.provider, r.label) }}
-{% endfor %}
+{% else %}
+{{ SECLABEL.APPLY(conn, 'COLUMN',data.schema, data.table, o_data.name, r.provider, r.label) }}
 {% endif %}
+{% endfor %}
 {% endif %}
+{% endif %}
\ No newline at end of file
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/triggers/__init__.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/triggers/__init__.py
index a639df0..b3e4eec 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/triggers/__init__.py
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/triggers/__init__.py
@@ -543,7 +543,7 @@ class TriggerView(PGChildNodeView):
         for k, v in data.items():
             try:
                 data[k] = json.loads(v, encoding='utf-8')
-            except (ValueError, TypeError):
+            except (ValueError, TypeError, KeyError):
                 data[k] = v
 
         required_args = {
diff --git a/web/pgadmin/browser/static/js/datamodel.js b/web/pgadmin/browser/static/js/datamodel.js
index 7b379ce..7d326f9 100644
--- a/web/pgadmin/browser/static/js/datamodel.js
+++ b/web/pgadmin/browser/static/js/datamodel.js
@@ -1065,8 +1065,10 @@ function(_, pgAdmin, $, Backbone) {
           return true;
         }
 
-        self.sessAttrs['changed'].push(obj);
-        (self.handler || self).trigger('pgadmin-session:changed', self, obj);
+        if (obj.sessChanged()) {
+          self.sessAttrs['changed'].push(obj);
+          (self.handler || self).trigger('pgadmin-session:changed', self, obj);
+        }
 
         return true;
       },


^ permalink  raw  reply  [nested|flat] 6+ messages in thread

* Re: Patch for RM1500 other issues [pgAdmin4]
@ 2016-08-03 14:39  Dave Page <[email protected]>
  parent: Harshal Dhumal <[email protected]>
  0 siblings, 0 replies; 6+ messages in thread

From: Dave Page @ 2016-08-03 14:39 UTC (permalink / raw)
  To: Harshal Dhumal <[email protected]>; +Cc: pgadmin-hackers

Thanks - applied.

On Wed, Aug 3, 2016 at 2:39 PM, Harshal Dhumal
<[email protected]> wrote:
> Hi Dave,
>
> Please find attached updated patch. I missed to change table __init__.py
> file that why you got the error sorry for that. Also patch has changes for
> both RM1500 and simplejson issue as both require changes in same file.
> Please discard old patch of RM1500 and simplejson.
>
>
>
>
> --
> Harshal Dhumal
> Software Engineer
>
> EnterpriseDB India: http://www.enterprisedb.com
> The Enterprise PostgreSQL Company
>
> On Wed, Aug 3, 2016 at 6:30 PM, Dave Page <[email protected]> wrote:
>>
>> Hi
>>
>> On Wed, Aug 3, 2016 at 12:43 PM, Harshal Dhumal
>> <[email protected]> wrote:
>> > Hi Dave,
>> >
>> > This because on python 2.X simplejson throws KeyError instead of
>> > TypeError
>> > if any error occurs while loading json data from given object. Now I
>> > have
>> > handled that exception as well in attached patch.
>> >
>> > I'm sending this as separate patch instead part of RM1500.
>>
>> I still see the same error, with both patches applied. I've restarted
>> the app server and cleared the browser cache and reloaded etc.
>>
>>
>> --
>> Dave Page
>> Blog: http://pgsnake.blogspot.com
>> Twitter: @pgsnake
>>
>> EnterpriseDB UK: http://www.enterprisedb.com
>> The Enterprise PostgreSQL Company
>
>



-- 
Dave Page
Blog: http://pgsnake.blogspot.com
Twitter: @pgsnake

EnterpriseDB UK: http://www.enterprisedb.com
The Enterprise PostgreSQL Company


-- 
Sent via pgadmin-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgadmin-hackers




^ permalink  raw  reply  [nested|flat] 6+ messages in thread


end of thread, other threads:[~2016-08-03 14:39 UTC | newest]

Thread overview: 6+ messages (download: mbox mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2016-08-03 06:36 Patch for RM1500 other issues [pgAdmin4] Harshal Dhumal <[email protected]>
2016-08-03 10:42 ` Dave Page <[email protected]>
2016-08-03 11:43   ` Harshal Dhumal <[email protected]>
2016-08-03 13:00     ` Dave Page <[email protected]>
2016-08-03 13:39       ` Harshal Dhumal <[email protected]>
2016-08-03 14:39         ` Dave Page <[email protected]>

This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox