diff --git a/web/pgadmin/dashboard/templates/dashboard/sql/default/dashboard_stats.sql b/web/pgadmin/dashboard/templates/dashboard/sql/default/dashboard_stats.sql
index 8d35c87c..88b2868a 100644
--- a/web/pgadmin/dashboard/templates/dashboard/sql/default/dashboard_stats.sql
+++ b/web/pgadmin/dashboard/templates/dashboard/sql/default/dashboard_stats.sql
@@ -2,7 +2,7 @@
 {% set add_union = false %}
 {% if 'session_stats' in chart_names %}
 {% set add_union = true %}
-SELECT 'session_stats' AS chart_name, row_to_json(t) AS chart_data
+SELECT 'session_stats' AS chart_name, row_to_json(t)::jsonb AS chart_data
 FROM (SELECT
    (SELECT count(*) FROM pg_stat_activity{% if did %} WHERE datname = (SELECT datname FROM pg_database WHERE oid = {{ did }}){% endif %}) AS "{{ _('Total') }}",
    (SELECT count(*) FROM pg_stat_activity WHERE state = 'active'{% if did %} AND datname = (SELECT datname FROM pg_database WHERE oid = {{ did }}){% endif %})  AS "{{ _('Active') }}",
@@ -14,7 +14,7 @@ UNION ALL
 {% endif %}
 {% if 'tps_stats' in chart_names %}
 {% set add_union = true %}
-SELECT 'tps_stats' AS chart_name, row_to_json(t) AS chart_data
+SELECT 'tps_stats' AS chart_name, row_to_json(t)::jsonb AS chart_data
 FROM (SELECT
    (SELECT sum(xact_commit) + sum(xact_rollback) FROM pg_stat_database{% if did %} WHERE datname = (SELECT datname FROM pg_database WHERE oid = {{ did }}){% endif %}) AS "{{ _('Transactions') }}",
    (SELECT sum(xact_commit) FROM pg_stat_database{% if did %} WHERE datname = (SELECT datname FROM pg_database WHERE oid = {{ did }}){% endif %}) AS "{{ _('Commits') }}",
@@ -26,7 +26,7 @@ UNION ALL
 {% endif %}
 {% if 'ti_stats' in chart_names %}
 {% set add_union = true %}
-SELECT 'ti_stats' AS chart_name, row_to_json(t) AS chart_data
+SELECT 'ti_stats' AS chart_name, row_to_json(t)::jsonb AS chart_data
 FROM (SELECT
    (SELECT sum(tup_inserted) FROM pg_stat_database{% if did %} WHERE datname = (SELECT datname FROM pg_database WHERE oid = {{ did }}){% endif %}) AS "{{ _('Inserts') }}",
    (SELECT sum(tup_updated) FROM pg_stat_database{% if did %} WHERE datname = (SELECT datname FROM pg_database WHERE oid = {{ did }}){% endif %}) AS "{{ _('Updates') }}",
@@ -38,7 +38,7 @@ UNION ALL
 {% endif %}
 {% if 'to_stats' in chart_names %}
 {% set add_union = true %}
-SELECT 'to_stats' AS chart_name, row_to_json(t) AS chart_data
+SELECT 'to_stats' AS chart_name, row_to_json(t)::jsonb AS chart_data
 FROM (SELECT
    (SELECT sum(tup_fetched) FROM pg_stat_database{% if did %} WHERE datname = (SELECT datname FROM pg_database WHERE oid = {{ did }}){% endif %}) AS "{{ _('Fetched') }}",
    (SELECT sum(tup_returned) FROM pg_stat_database{% if did %} WHERE datname = (SELECT datname FROM pg_database WHERE oid = {{ did }}){% endif %}) AS "{{ _('Returned') }}"
@@ -49,7 +49,7 @@ UNION ALL
 {% endif %}
 {% if 'bio_stats' in chart_names %}
 {% set add_union = true %}
-SELECT 'bio_stats' AS chart_name, row_to_json(t) AS chart_data
+SELECT 'bio_stats' AS chart_name, row_to_json(t)::jsonb AS chart_data
 FROM (SELECT
    (SELECT sum(blks_read) FROM pg_stat_database{% if did %} WHERE datname = (SELECT datname FROM pg_database WHERE oid = {{ did }}){% endif %}) AS "{{ _('Reads') }}",
    (SELECT sum(blks_hit) FROM pg_stat_database{% if did %} WHERE datname = (SELECT datname FROM pg_database WHERE oid = {{ did }}){% endif %}) AS "{{ _('Hits') }}"
diff --git a/web/pgadmin/static/js/selection/active_cell_capture.js b/web/pgadmin/static/js/selection/active_cell_capture.js
index 03d7b40e..8592992e 100644
--- a/web/pgadmin/static/js/selection/active_cell_capture.js
+++ b/web/pgadmin/static/js/selection/active_cell_capture.js
@@ -62,6 +62,11 @@ define([
         return;
       }
 
+      /* Skip if clicked on resize handler */
+      if($(event.target).hasClass('slick-resizable-handle')) {
+        return;
+      }
+
       bypassDefaultActiveCellRangeChange = true;
 
       var clickedColumn = args.column.pos + 1;
diff --git a/web/pgadmin/static/js/slickgrid/editors.js b/web/pgadmin/static/js/slickgrid/editors.js
index 18bba9e9..d94fd66f 100644
--- a/web/pgadmin/static/js/slickgrid/editors.js
+++ b/web/pgadmin/static/js/slickgrid/editors.js
@@ -33,12 +33,12 @@
 
   // return wrapper element
   function getWrapper() {
-    return $('<div class=\'pg_text_editor\' />');
+    return $('<div class=\'pg-text-editor\' />');
   }
 
   // return textarea element
   function getTextArea() {
-    return $('<textarea class=\'pg_textarea text-12\' hidefocus rows=5\'>');
+    return $('<textarea class=\'pg-textarea text-12\' hidefocus rows=5\'>');
   }
 
   // Generate and return editor buttons
@@ -107,7 +107,11 @@
         grid.copied_rows[row][cell] = 1;
       }
     } else {
-      item[args.column.field] = state;
+      if(column_type === 'jsonb') {
+          item[args.column.field] = JSON.parse(state);
+      } else {
+        item[args.column.field] = state;
+      }
     }
   }
 
@@ -364,6 +368,7 @@
 
     this.loadValue = function(item) {
       var data = defaultValue = item[args.column.field];
+      /* If jsonb or array */
       if (data && typeof data === 'object' && !Array.isArray(data)) {
         data = JSON.stringify(data, null, 4);
       } else if (Array.isArray(data)) {
@@ -377,6 +382,7 @@
         });
         data = '[' + temp.join() + ']';
       }
+      /* if json take as is */
       $input.val(data);
       $input.trigger('select');
     };
@@ -388,8 +394,12 @@
       return $input.val();
     };
 
-    this.applyValue = function(item, state) {
-      setValue(args, item, state, 'text');
+    this.applyValue = function(item, state){
+      if(args.column.column_type_internal === 'jsonb') {
+        setValue(args, item, state, 'jsonb');
+      } else {
+        setValue(args, item, state, 'text');
+      }
     };
 
     this.isValueChanged = function() {
@@ -401,13 +411,17 @@
     };
 
     this.validate = function() {
-      if (args.column.validator) {
-        var validationResults = args.column.validator($input.val());
-        if (!validationResults.valid) {
-          return validationResults;
+      if(args.column.column_type_internal === 'jsonb') {
+        try {
+          JSON.parse($input.val());
+        } catch(e) {
+          $input.addClass('pg-text-invalid');
+          return {
+            valid: false,
+          };
         }
       }
-
+      $input.removeClass('pg-text-invalid');
       return {
         valid: true,
         msg: null,
diff --git a/web/pgadmin/static/js/slickgrid/plugins/slick.autocolumnsize.js b/web/pgadmin/static/js/slickgrid/plugins/slick.autocolumnsize.js
new file mode 100644
index 00000000..3274111e
--- /dev/null
+++ b/web/pgadmin/static/js/slickgrid/plugins/slick.autocolumnsize.js
@@ -0,0 +1,156 @@
+(function($) {
+
+    $.extend(true, window, {
+        "Slick": {
+            "AutoColumnSize": AutoColumnSize
+        }
+    });
+
+    function AutoColumnSize(maxWidth) {
+
+        var grid, $container, context,
+            keyCodes = {
+                'A': 65
+            };
+
+        function init(_grid) {
+            grid = _grid;
+            maxWidth = maxWidth || 200;
+
+            $container = $(grid.getContainerNode());
+            $container.on("dblclick.autosize", ".slick-resizable-handle", reSizeColumn);
+            $container.keydown(handleControlKeys);
+
+            context = document.createElement("canvas").getContext("2d");
+        }
+
+        function destroy() {
+            $container.off();
+        }
+
+        function handleControlKeys(event) {
+            if (event.ctrlKey && event.shiftKey && event.keyCode === keyCodes.A) {
+                resizeAllColumns();
+            }
+        }
+
+        function resizeAllColumns() {
+            var elHeaders = $container.find(".slick-header-column");
+            var allColumns = grid.getColumns();
+            elHeaders.each(function(index, el) {
+                var columnDef = $(el).data('column');
+                var headerWidth = getElementWidth(el);
+                var colIndex = grid.getColumnIndex(columnDef.id);
+                var column = allColumns[colIndex];
+                var autoSizeWidth = Math.max(headerWidth, getMaxColumnTextWidth(columnDef, colIndex)) + 1;
+                autoSizeWidth = Math.min(maxWidth, autoSizeWidth);
+                column.width = autoSizeWidth;
+            });
+            grid.setColumns(allColumns);
+            grid.onColumnsResized.notify();
+        }
+
+        function reSizeColumn(e) {
+            var headerEl = $(e.currentTarget).closest('.slick-header-column');
+            var columnDef = headerEl.data('column');
+
+            if (!columnDef || !columnDef.resizable) {
+                return;
+            }
+
+            e.preventDefault();
+            e.stopPropagation();
+
+            var headerWidth = getElementWidth(headerEl[0]);
+            var colIndex = grid.getColumnIndex(columnDef.id);
+            var allColumns = grid.getColumns();
+            var column = allColumns[colIndex];
+
+            var autoSizeWidth = Math.max(headerWidth, getMaxColumnTextWidth(columnDef, colIndex)) + 1;
+
+            if (autoSizeWidth !== column.width) {
+                column.width = autoSizeWidth;
+                grid.setColumns(allColumns);
+                grid.onColumnsResized.notify();
+            }
+        }
+
+        function getMaxColumnTextWidth(columnDef, colIndex) {
+            var texts = [];
+            var rowEl = createRow(columnDef);
+            var data = grid.getData();
+            if (Slick.Data && data instanceof Slick.Data.DataView) {
+                data = data.getItems();
+            }
+            for (var i = 0; i < data.length; i++) {
+                texts.push(data[i][columnDef.field]);
+            }
+            var template = getMaxTextTemplate(texts, columnDef, colIndex, data, rowEl);
+            var width = getTemplateWidth(rowEl, template);
+            deleteRow(rowEl);
+            return width;
+        }
+
+        function getTemplateWidth(rowEl, template) {
+            var cell = $(rowEl.find(".slick-cell"));
+            cell.append(template);
+            $(cell).find("*").css("position", "relative");
+            return cell.outerWidth() + 1;
+        }
+
+        function getMaxTextTemplate(texts, columnDef, colIndex, data, rowEl) {
+            var max = 0,
+                maxTemplate = null;
+            var formatFun = columnDef.formatter;
+            $(texts).each(function(index, text) {
+                var template;
+                if (formatFun) {
+                    template = $("<span>" + formatFun(index, colIndex, text, columnDef, data[index]) + "</span>");
+                    text = template.text() || text;
+                }
+                var length = text ? getElementWidthUsingCanvas(rowEl, text) : 0;
+                if (length > max) {
+                    max = length;
+                    maxTemplate = template || text;
+                }
+            });
+            return maxTemplate;
+        }
+
+        function createRow(columnDef) {
+            var rowEl = $('<div class="slick-row"><div class="slick-cell"></div></div>');
+            rowEl.find(".slick-cell").css({
+                "visibility": "hidden",
+                "text-overflow": "initial",
+                "white-space": "nowrap"
+            });
+            var gridCanvas = $container.find(".grid-canvas");
+            $(gridCanvas).append(rowEl);
+            return rowEl;
+        }
+
+        function deleteRow(rowEl) {
+            $(rowEl).remove();
+        }
+
+        function getElementWidth(element) {
+            var width, clone = element.cloneNode(true);
+            clone.style.cssText = 'position: absolute; visibility: hidden;right: auto;text-overflow: initial;white-space: nowrap;';
+            element.parentNode.insertBefore(clone, element);
+            width = clone.offsetWidth;
+            clone.parentNode.removeChild(clone);
+            return width;
+        }
+
+        function getElementWidthUsingCanvas(element, text) {
+            context.font = element.css("font-size") + " " + element.css("font-family");
+            var metrics = context.measureText(text);
+            return metrics.width;
+        }
+
+        return {
+            init: init,
+            destroy: destroy
+        };
+    }
+}(jQuery));
diff --git a/web/pgadmin/tools/sqleditor/static/css/sqleditor.css b/web/pgadmin/tools/sqleditor/static/css/sqleditor.css
index 81e63c33..92278c99 100644
--- a/web/pgadmin/tools/sqleditor/static/css/sqleditor.css
+++ b/web/pgadmin/tools/sqleditor/static/css/sqleditor.css
@@ -266,12 +266,6 @@ input.editor-checkbox:focus {
 }
 
 /* Style for text editor */
-.pg_textarea {
-  width:250px;
-  height:80px;
-  border:0;
-  outline:0;
-}
 .pg_buttons {
   text-align:right;
 }
diff --git a/web/pgadmin/tools/sqleditor/static/js/sqleditor.js b/web/pgadmin/tools/sqleditor/static/js/sqleditor.js
index edac4261..7e672672 100644
--- a/web/pgadmin/tools/sqleditor/static/js/sqleditor.js
+++ b/web/pgadmin/tools/sqleditor/static/js/sqleditor.js
@@ -41,6 +41,7 @@ define('tools.querytool', [
   'backgrid.sizeable.columns',
   'slick.pgadmin.formatters',
   'slick.pgadmin.editors',
+  'slick.pgadmin.plugins/slick.autocolumnsize',
   'pgadmin.browser',
   'pgadmin.tools.user_management',
 ], function(
@@ -861,6 +862,7 @@ define('tools.querytool', [
       grid.registerPlugin(new ActiveCellCapture());
       grid.setSelectionModel(new XCellSelectionModel());
       grid.registerPlugin(gridSelector);
+      grid.registerPlugin(new Slick.AutoColumnSize());
       var headerButtonsPlugin = new Slick.Plugins.HeaderButtons();
       headerButtonsPlugin.onCommand.subscribe(function (e, args) {
         let command = args.command;
@@ -924,7 +926,7 @@ define('tools.querytool', [
           var column_size = self.handler['col_size'];
           column_size[self.handler['table_name']][col['id']] = col['width'];
         });
-      });
+      }.bind(grid));
 
       gridSelector.onBeforeGridSelectAll.subscribe(function(e, args) {
         if (self.handler.has_more_rows) {
diff --git a/web/pgadmin/tools/sqleditor/static/scss/_sqleditor.scss b/web/pgadmin/tools/sqleditor/static/scss/_sqleditor.scss
index d017e667..d4a7163a 100644
--- a/web/pgadmin/tools/sqleditor/static/scss/_sqleditor.scss
+++ b/web/pgadmin/tools/sqleditor/static/scss/_sqleditor.scss
@@ -233,17 +233,26 @@ li.CodeMirror-hint-active {
   border-top: none;
 }
 
-.pg_text_editor {
+.pg-text-editor {
   z-index:10000;
   position:absolute;
   background: $color-bg-theme;
   padding: 0.25rem;
   border: $panel-border;
   box-shadow: $dropdown-box-shadow;
-}
 
-.pg_text_editor textarea {
-  resize: both;
+
+  & .pg-textarea {
+    width:250px;
+    height:80px;
+    border:0;
+    outline:0;
+    resize: both;
+  }
+
+  & .pg-text-invalid {
+    background: $color-danger-lighter;
+  }
 }
 
 .sql-editor-message {
diff --git a/web/pgadmin/utils/driver/psycopg2/__init__.py b/web/pgadmin/utils/driver/psycopg2/__init__.py
index 2b6ed6de..c63c35e4 100644
--- a/web/pgadmin/utils/driver/psycopg2/__init__.py
+++ b/web/pgadmin/utils/driver/psycopg2/__init__.py
@@ -18,7 +18,6 @@ from flask import session
 from flask_babelex import gettext
 import psycopg2
 from psycopg2.extensions import adapt
-from psycopg2.extras import Json as psycopg2_json
 
 import config
 from pgadmin.model import Server, User
@@ -226,14 +225,7 @@ class Driver(BaseDriver):
 
     @staticmethod
     def qtLiteral(value):
-        adapted = None
-
-        # adapt function cannot adapt dict data type
-        # Used http://initd.org/psycopg/docs/extras.html#json-adaptation
-        if type(value) == dict:
-            adapted = psycopg2_json(value)
-        else:
-            adapted = adapt(value)
+        adapted = adapt(value)
 
         # Not all adapted objects have encoding
         # e.g.
diff --git a/web/pgadmin/utils/driver/psycopg2/typecast.py b/web/pgadmin/utils/driver/psycopg2/typecast.py
index ea24ba57..1f462f08 100644
--- a/web/pgadmin/utils/driver/psycopg2/typecast.py
+++ b/web/pgadmin/utils/driver/psycopg2/typecast.py
@@ -17,6 +17,7 @@ import sys
 from psycopg2 import STRING as _STRING
 import psycopg2
 from psycopg2.extensions import encodings
+from psycopg2.extras import Json as psycopg2_json
 
 from .encoding import configureDriverEncodings
 
@@ -166,6 +167,14 @@ def register_global_typecasters():
     # array of string type
     psycopg2.extensions.register_type(pg_array_types_to_array_of_string_type)
 
+    # Treat JSON data as text because converting it to dict alters the data
+    # which should not happen as per postgres docs
+    psycopg2.extras.register_default_json(loads=lambda x: x)
+
+    # pysycopg2 adapt does not support dict by default. Need to register
+    # Used http://initd.org/psycopg/docs/extras.html#json-adaptation
+    psycopg2.extensions.register_adapter(dict, psycopg2_json)
+
 
 def register_string_typecasters(connection):
     # raw_unicode_escape used for SQL ASCII will escape the
diff --git a/web/webpack.shim.js b/web/webpack.shim.js
index b9645625..2244072f 100644
--- a/web/webpack.shim.js
+++ b/web/webpack.shim.js
@@ -283,6 +283,7 @@ var webpackShimConfig = {
     'pgadmin.user_management.current_user': '/user_management/current_user',
     'slick.pgadmin.editors': path.join(__dirname, './pgadmin/tools/../static/js/slickgrid/editors'),
     'slick.pgadmin.formatters': path.join(__dirname, './pgadmin/tools/../static/js/slickgrid/formatters'),
+    'slick.pgadmin.plugins': path.join(__dirname, './pgadmin/tools/../static/js/slickgrid/plugins'),
   },
   externals: [
     'pgadmin.user_management.current_user',
