diff --git a/web/pgadmin/static/js/slickgrid/slick.pgadmin.editors.js b/web/pgadmin/static/js/slickgrid/slick.pgadmin.editors.js
index faad731..a3f4469 100644
--- a/web/pgadmin/static/js/slickgrid/slick.pgadmin.editors.js
+++ b/web/pgadmin/static/js/slickgrid/slick.pgadmin.editors.js
@@ -11,17 +11,61 @@
       "Editors": {
         "pgText": pgTextEditor,
         "JsonText": JsonTextEditor,
+        "CustomNumber": CustomNumberEditor,
         // Below editor will read only editors, Just to display data
         "ReadOnlyText": ReadOnlyTextEditor,
         "ReadOnlyCheckbox": ReadOnlyCheckboxEditor,
         "Checkbox": CheckboxEditor, // Override editor to implement checkbox with three states
         "ReadOnlypgText": ReadOnlypgTextEditor,
-        "ReadOnlyJsonText": ReadOnlyJsonTextEditor,
-        "CustomNumber": CustomNumberEditor
+        "ReadOnlyJsonText": ReadOnlyJsonTextEditor
       }
     }
   });
 
+  /*
+   * This function handles the [default] and [null] values for cells
+   * if row is copied, otherwise returns the editor value.
+   * @param {args} editor object
+   * @param {item} row cell values
+   * @param {state} entered value
+   * @param {column_type} type of column
+   */
+  function setValue(args, item, state, column_type) {
+    // declare a 2-d array which tracks the status of each updated cell
+    // If a cell is edited for the 1st time and state is null,
+    // set cell value to [default] and update its status [row][cell] to 1.
+    // If same cell is edited again, and kept blank, set cell value to [null]
+
+    // If a row is copied
+    var grid = args.grid;
+    if (item.is_row_copied) {
+      if (!grid.copied_rows) {
+        grid.copied_rows = [[]];
+      }
+
+      var active_cell = grid.getActiveCell(),
+          row = active_cell['row'],
+          cell = active_cell['cell'],
+          last_value = item[args.column.pos],
+          last_value = (column_type === 'number') ?
+                        (_.isEmpty(last_value) || last_value) : last_value;
+
+      item[args.column.pos] = state;
+      if (last_value && _.isNull(state) &&
+          (_.isUndefined(grid.copied_rows[row]) ||
+          _.isUndefined(grid.copied_rows[row][cell]))
+      ) {
+        item[args.column.pos] = undefined;
+        if (grid.copied_rows[row] == undefined) grid.copied_rows[row] = [];
+        grid.copied_rows[row][cell] = 1;
+      }
+    }
+    else {
+      item[args.column.pos] = state;
+    }
+  }
+
+
   // Text data type editor
   function pgTextEditor(args) {
     var $input, $wrapper;
@@ -113,10 +157,10 @@
       var col = args.column;
 
       if (_.isUndefined(item[args.column.pos]) && col.has_default_val) {
-        $input.val("");
+        $input.val(defaultValue = "");
       }
       else if (item[args.column.pos] === "") {
-        $input.val("''");
+        $input.val(defaultValue = "''");
       }
       else {
         $input.val(defaultValue = item[args.column.pos]);
@@ -146,7 +190,7 @@
     };
 
     this.applyValue = function (item, state) {
-      item[args.column.pos] = state;
+      setValue(args, item, state, 'text');
     };
 
     this.isValueChanged = function () {
@@ -290,7 +334,7 @@
     };
 
     this.applyValue = function (item, state) {
-      item[args.column.pos] = state;
+      setValue(args, item, state, 'text');
     };
 
     this.isValueChanged = function () {
@@ -855,7 +899,7 @@
     };
 
     this.applyValue = function (item, state) {
-      item[args.column.pos] = state;
+      setValue(args, item, state, 'number');
     };
 
     this.isValueChanged = function () {
diff --git a/web/pgadmin/tools/sqleditor/command.py b/web/pgadmin/tools/sqleditor/command.py
index 2bb90c2..4f65c34 100644
--- a/web/pgadmin/tools/sqleditor/command.py
+++ b/web/pgadmin/tools/sqleditor/command.py
@@ -460,11 +460,16 @@ class TableCommand(GridCommand):
                             column_data[each_col] = None
                             column_type[each_col] =\
                                 self.columns_info[each_col]['type_name']
+                        else:
+                            column_type[each_col] = \
+                                self.columns_info[each_col]['type_name']
+
 
                     for each_row in changed_data[of_type]:
                         data = changed_data[of_type][each_row]['data']
                         # Remove our unique tracking key
                         data.pop('__temp_PK', None)
+                        data.pop('is_row_copied', None)
                         data = set_column_names(data)
                         data_type = set_column_names(changed_data[of_type][each_row]['data_type'])
                         list_of_rowid.append(data.get('__temp_PK'))
diff --git a/web/pgadmin/tools/sqleditor/templates/sqleditor/js/sqleditor.js b/web/pgadmin/tools/sqleditor/templates/sqleditor/js/sqleditor.js
index d8ae73e..11e5acb 100644
--- a/web/pgadmin/tools/sqleditor/templates/sqleditor/js/sqleditor.js
+++ b/web/pgadmin/tools/sqleditor/templates/sqleditor/js/sqleditor.js
@@ -39,10 +39,27 @@ define(
         pgBrowser = pgAdmin.Browser,
         Slick = window.Slick;
 
-    /* Get the function definition from
-     * http://stackoverflow.com/questions/1349404/generate-a-string-of-5-random-characters-in-javascript/35302975#35302975
+    /* Reference link
+     * http://stackoverflow.com/questions/105034/create-guid-uuid-in-javascript
+     * Modified as per requirement.
      */
-    function epicRandomString(b){for(var a=(Math.random()*eval("1e"+~~(50*Math.random()+50))).toString(36).split(""),c=3;c<a.length;c++)c==~~(Math.random()*c)+1&&a[c].match(/[a-z]/)&&(a[c]=a[c].toUpperCase());a=a.join("");a=a.substr(~~(Math.random()*~~(a.length/3)),~~(Math.random()*(a.length-~~(a.length/3*2)+1))+~~(a.length/3*2));if(24>b)return b?a.substr(a,b):a;a=a.substr(a,b);if(a.length==b)return a;for(;a.length<b;)a+=epicRandomString();return a.substr(0,b)};
+    function epicRandomString(b) {
+      var s = [];
+      var hexDigits = "0123456789abcdef";
+      for (var i = 0; i < 36; i++) {
+          s[i] = hexDigits.substr(
+                  Math.floor(Math.random() * 0x10), 1
+                );
+      }
+      // bits 12-15 of the time_hi_and_version field to 0010
+      s[14] = "4";
+      // bits 6-7 of the clock_seq_hi_and_reserved to 01
+      s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1);
+      s[8] = s[13] = s[18] = s[23] = "-";
+
+      var uuid = s.join("");
+      return uuid.replace(/-/g, '').substr(0, b);
+    };
 
     // Define key codes for shortcut keys
     var F5_KEY = 116,
@@ -526,6 +543,21 @@ define(
       render_grid: function(collection, columns, is_editable) {
         var self = this;
 
+        // returns primary keys
+        self.handler.get_row_primary_key = function() {
+          var self = this,
+            tmp_keys = [];
+          _.each(self.primary_keys, function(p, idx) {
+            // For each columns search primary key position
+            _.each(self.columns, function(c) {
+               if(c.name == idx) {
+                 tmp_keys.push(c.pos);
+               }
+            });
+          });
+          return tmp_keys;
+        };
+
         // This will work as data store and holds all the
         // inserted/updated/deleted data from grid
         self.handler.data_store = {
@@ -666,7 +698,8 @@ define(
                primary_key_list = _.keys(this.keys),
                _tmp_keys = [],
                _columns = this.columns,
-               rows_for_stage = {}, selected_rows_list = [];
+               rows_for_stage = {},
+               selected_rows_list = [];
 
                // Only if entire row(s) are selected via check box
                if(_.has(this.selection, 'getSelectedRows')) {
@@ -686,14 +719,19 @@ define(
 
                  // Check if selected is new row ?
                  // Allow to delete if yes
-                 var cell_el = this.grid.getCellNode(selected_rows_list[0], 0),
+                 var count = selected_rows_list.length-1,
+                  cell_el = this.grid.getCellNode(selected_rows_list[count],0),
                   parent_el = $(cell_el).parent(),
                   is_new_row = $(parent_el).hasClass('new_row');
 
                  // Clear selection model if row primary keys is set to default
-                 var row_data = collection[selected_rows_list[0]];
+                 var row_data = _.clone(collection[selected_rows_list[count]]),
+                   is_primary_key = _.has(row_data, primary_key_list) &&
+                                      row_data[0] != undefined ? true : false;
+
                  if (primary_key_list.length &&
-                     !_.has(row_data, primary_key_list) && !is_new_row) {
+                     !is_primary_key && !is_new_row
+                 ) {
                    this.selection.setSelectedRows([]);
                    selected_rows_list = [];
                  }
@@ -716,22 +754,20 @@ define(
                   // Collect primary key data from collection as needed for stage row
                   _.each(selected_rows_list, function(row_index) {
                     var row_data = collection[row_index],
-                      pkey_data = _.pick(row_data, primary_key_list);
+                      p_keys_list = _.pick(row_data, primary_key_list),
+                      is_primary_key = Object.keys(p_keys_list).length ?
+                                       p_keys_list[0] : undefined;
 
                     // Store Primary key data for selected rows
-                    if (!_.isUndefined(row_data) && !_.isUndefined(pkey_data)) {
+                    if (!_.isUndefined(row_data) && !_.isUndefined(p_keys_list)) {
                       // check for invalid row
-                      rows_for_stage[row_data.__temp_PK] = _.pick(row_data, primary_key_list);
+                      rows_for_stage[row_data.__temp_PK] = p_keys_list;
                     }
                   });
               } else {
                 //clear staged rows
                 clear_staged_rows();
               }
-              if (!Object.keys(rows_for_stage).length) {
-                clear_staged_rows();
-              }
-
              // Update main data store
              this.editor.handler.data_store.staged_rows = rows_for_stage;
            }.bind(editor_data));
@@ -806,7 +842,6 @@ define(
 
         });
 
-
         // Listener function which will be called when user updates existing rows
         grid.onCellChange.subscribe(function (e, args) {
           // self.handler.data_store.updated will holds all the updated data
@@ -816,7 +851,27 @@ define(
             column_data = {},
             _type;
 
-           column_data[changed_column] = updated_data;
+          // Access to row/cell value after a cell is changed.
+          // The purpose is to remove row_id from temp_new_row
+          // if new row has primary key instead of [default_value]
+          // so that cell edit is enabled for that row.
+          var grid = args.grid,
+            row_data = grid.getDataItem(args.row),
+            p_keys_list = _.pick(
+              row_data, self.handler.get_row_primary_key()
+            ),
+            is_primary_key = Object.keys(p_keys_list).length ?
+                             p_keys_list[0] : undefined;
+
+          // temp_new_rows is available only for view data.
+          if (is_primary_key && self.handler.temp_new_rows) {
+            var index = self.handler.temp_new_rows.indexOf(args.row);
+            if (index > -1) {
+              self.handler.temp_new_rows.splice(index, 1);
+            }
+          }
+
+          column_data[changed_column] = updated_data;
 
           if(_pk) {
             // Check if it is in newly added row by user?
@@ -854,53 +909,42 @@ define(
           $("#btn-save").prop('disabled', false);
         }.bind(editor_data));
 
-
-        // Listener function which will be called after cell is changed
-        grid.onActiveCellChanged.subscribe(function (e, args) {
-          // Access to row/cell value after a cell is changed.
-          // The purpose is to remove row_id from temp_new_row
-          // if new row has primary key instead of [default_value]
-          // so that cell edit is enabled for that row.
-          var grid = args.grid,
-            row_data = grid.getDataItem(args.row),
-            primary_key = row_data && row_data[0];
-
-          // temp_new_rows is available only for view data.
-          if (!_.isUndefined(primary_key) &&
-            self.handler.temp_new_rows
-          ) {
-            var index = self.handler.temp_new_rows.indexOf(args.row);
-            if (index > -1) {
-              self.handler.temp_new_rows.splice(index, 1);
-            }
-          }
-        });
-
         // Listener function which will be called when user adds new rows
         grid.onAddNewRow.subscribe(function (e, args) {
           // self.handler.data_store.added will holds all the newly added rows/data
           var _key = epicRandomString(10),
             column = args.column,
-            item = args.item, data_length = this.grid.getDataLength();
+            item = args.item,
+            data_length = this.grid.getDataLength(),
+            new_collection = args.grid.getData();
 
           // Add new row in list to keep track of it
           if (_.isUndefined(item[0])) {
             self.handler.temp_new_rows.push(data_length);
           }
 
+          // If copied item has already primary key, use it.
           if(item) {
             item.__temp_PK = _key;
           }
-          collection.push(item);
+          new_collection.push(item);
+
           self.handler.data_store.added[_key] = {'err': false, 'data': item};
           self.handler.data_store.added_index[data_length] = _key;
           // Fetch data type & add it for the column
           var temp = {};
           temp[column.pos] = _.where(this.columns, {pos: column.pos})[0]['type'];
           self.handler.data_store.added[_key]['data_type'] =  temp;
-          grid.invalidateRows([collection.length - 1]);
+          grid.invalidateRows([new_collection.length - 1]);
           grid.updateRowCount();
           grid.render();
+
+          // Add a blank row after add row
+          grid.setData(new_collection, true);
+          grid.updateRowCount();
+          grid.invalidateAllRows();
+          grid.render();
+
           // Enable save button
           $("#btn-save").prop('disabled', false);
         }.bind(editor_data));
@@ -2249,22 +2293,17 @@ define(
         },
 
         rows_to_delete: function(data) {
-          var self = this;
-          var tmp_keys = [];
-          _.each(self.primary_keys, function(p, idx) {
-            // For each columns search primary key position
-            _.each(self.columns, function(c) {
-               if(c.name == idx) {
-                 tmp_keys.push(c.pos);
-               }
-            });
-          });
+          var self = this,
+            tmp_keys = self.get_row_primary_key.call(self);
 
           // re-calculate rows with no primary keys
           self.temp_new_rows = [];
           data.forEach(function(d, idx) {
-            var p_keys_idx = _.pick(d, tmp_keys);
-            if (Object.keys(p_keys_idx).length == 0) {
+            var p_keys_list = _.pick(d, tmp_keys),
+              is_primary_key = Object.keys(p_keys_list).length ?
+                               p_keys_list[0] : undefined;
+
+            if (!is_primary_key) {
               self.temp_new_rows.push(idx);
             }
           });
@@ -2381,7 +2420,7 @@ define(
             is_primary_error = false;
 
           if( !is_added && !is_updated && !is_deleted ) {
-                return;  // Nothing to save here
+            return;  // Nothing to save here
           }
 
           if (save_data) {
@@ -2405,6 +2444,18 @@ define(
                 var grid = self.slickgrid,
                   data = grid.getData();
                 if (res.data.status) {
+                    // Remove flag is_row_copied from copied rows
+                    _.each(data, function(row, idx) {
+                      if (row.is_row_copied) {
+                        delete row.is_row_copied;
+                      }
+                    });
+
+                    // Remove 2d copied_rows array
+                    if (grid.copied_rows) {
+                      delete grid.copied_rows;
+                    }
+
                     // Remove deleted rows from client as well
                     if(is_deleted) {
                       var rows = grid.getSelectedRows();
@@ -3071,67 +3122,59 @@ define(
         _paste_row: function() {
           var self = this, col_info = {},
             grid = self.slickgrid,
-            data = grid.getData();
-            // Deep copy
-            var copied_rows = $.extend(true, [], self.copied_rows),
-            _tmp_copied_row = {};
+            data = grid.getData(),
+            count = Object.keys(data).length-1;
+
+          var rows = grid.getSelectedRows().sort(
+              function (a, b) { return a - b; }
+            ),
+            rows = rows.length == 0 ? self.last_copied_rows : rows,
+            copied_rows = rows.map(function (rowIndex) {
+              return data[rowIndex];
+            });
+            self.last_copied_rows = rows;
 
             // If there are rows to paste?
             if(copied_rows.length > 0) {
               // Enable save button so that user can
               // save newly pasted rows on server
               $("#btn-save").prop('disabled', false);
-              // Generate Unique key for each pasted row(s)
-              _.each(copied_rows, function(row) {
-                  var _pk = epicRandomString(8);
-                  row.__temp_PK = _pk;
-              });
-
-              var temp_func = self.data_view.getItemMetadata,
-                  count = Object.keys(data).length-1;
-
-              _.each(copied_rows, function(row, idx) {
-                data[count] = row;
-                count++;
-              });
 
-              //update data_view
-              data.getItemMetadata = temp_func;
-              grid.setData(data, true);
-              grid.updateRowCount();
-              grid.setSelectedRows([]);
-              grid.invalidateAllRows();
-              grid.render();
-
-              // Fetch column name & its data type
-              _.each(self.columns, function(c) {
-                col_info[String(c.pos)] = c.type;
-              });
-
-              // insert these data in data_store as well to save them on server
-              for (var j = 0; j < copied_rows.length; j += 1) {
-                self.data_store.added[copied_rows[j].__temp_PK] = {
-                  'data_type': {},
-                  'data': {}
-                };
-                self.data_store.added[copied_rows[j].__temp_PK]['data_type'] = col_info;
-                // We need to convert it from array to dict so that server can
-                // understand the data properly
-                _.each(copied_rows[j], function(val, key) {
-                  // If value is array then convert it to string
-                  if(_.isArray(val)) {
-                    _tmp_copied_row[String(key)] = val.toString();
-                  // If value is object then stringify it
-                  } else if(_.isObject(val)) {
-                    _tmp_copied_row[j][String(key)] = JSON.stringify(val);
-                  } else {
-                    _tmp_copied_row[String(key)] = val;
+              var arr_to_object = function (arr) {
+                var obj = {},
+                  count = typeof(arr) == 'object' ?
+                            Object.keys(arr).length: arr.length
+
+                _.each(arr, function(val, i){
+                  if (arr[i] !== undefined) {
+                    if(_.isObject(arr[i])) {
+                      obj[String(i)] = JSON.stringify(arr[i]);
+                    } else {
+                      obj[String(i)] = arr[i];
+                    }
                   }
                 });
-                self.data_store.added[copied_rows[j].__temp_PK]['data'] = _tmp_copied_row;
-                // reset the variable
-                _tmp_copied_row = {};
-              }
+                return obj;
+              };
+
+              // Generate Unique key for each pasted row(s)
+              // Convert array values to object to send to server
+              // Add flag is_row_copied to handle [default] and [null]
+              // for copied rows.
+              // Add index of copied row into temp_new_rows
+              // Trigger grid.onAddNewRow when a row is copied
+              // Reset selection
+              _.each(copied_rows, function(row) {
+                  var new_row = arr_to_object(row);
+                  new_row.is_row_copied = true;
+                  row = new_row;
+                  self.temp_new_rows.push(count);
+                  grid.onAddNewRow.notify(
+                    {item: new_row, column: self.columns[0] , grid:grid}
+                  )
+                  grid.setSelectedRows([]);
+                  count++;
+              });
             }
         },
 
