diff --git a/docs/en_US/query_tool.rst b/docs/en_US/query_tool.rst
index 973d3b47..00c0ebf8 100644
--- a/docs/en_US/query_tool.rst
+++ b/docs/en_US/query_tool.rst
@@ -131,7 +131,7 @@ You can:
 A result set is updatable if:
 
 * All the columns belong to the same table.
-* All the primary keys of the table are selected.
+* All the primary keys or OIDs of the table are explicitly selected.
 * No columns are duplicated.
 
 An updatable result set can be modified just like in
diff --git a/web/pgadmin/tools/sqleditor/__init__.py b/web/pgadmin/tools/sqleditor/__init__.py
index d7435702..c344f5d7 100644
--- a/web/pgadmin/tools/sqleditor/__init__.py
+++ b/web/pgadmin/tools/sqleditor/__init__.py
@@ -414,11 +414,6 @@ def poll(trans_id):
                 if 'primary_keys' in session_obj:
                     primary_keys = session_obj['primary_keys']
 
-                if 'has_oids' in session_obj:
-                    has_oids = session_obj['has_oids']
-                    if has_oids:
-                        oids = {'oid': 'oid'}
-
                 # Fetch column information
                 columns_info = conn.get_column_info()
                 client_primary_key = generate_client_primary_key_name(
@@ -429,13 +424,22 @@ def poll(trans_id):
                 # If trans_obj is a QueryToolCommand then check for updatable
                 # resultsets and primary keys
                 if isinstance(trans_obj, QueryToolCommand):
-                    trans_obj.check_updatable_results_pkeys()
+                    trans_obj.check_updatable_results_pkeys_oids()
                     pk_names, primary_keys = trans_obj.get_primary_keys()
+                    session_obj['has_oids'] = trans_obj.has_oids()
+                    # Update command_obj in session obj
+                    session_obj['command_obj'] = pickle.dumps(
+                        trans_obj, -1)
                     # If primary_keys exist, add them to the session_obj to
                     # allow for saving any changes to the data
                     if primary_keys is not None:
                         session_obj['primary_keys'] = primary_keys
 
+                if 'has_oids' in session_obj:
+                    has_oids = session_obj['has_oids']
+                    if has_oids:
+                        oids = {'oid': 'oid'}
+
                 if columns_info is not None:
                     # If it is a QueryToolCommand that has obj_id attribute
                     # then it should also be editable
diff --git a/web/pgadmin/tools/sqleditor/command.py b/web/pgadmin/tools/sqleditor/command.py
index 06d3615a..5725541f 100644
--- a/web/pgadmin/tools/sqleditor/command.py
+++ b/web/pgadmin/tools/sqleditor/command.py
@@ -863,6 +863,7 @@ class QueryToolCommand(BaseCommand, FetchedRowTracker):
         self.is_updatable_resultset = False
         self.primary_keys = None
         self.pk_names = None
+        self.table_has_oids = False
 
     def get_sql(self, default_conn=None):
         return None
@@ -873,13 +874,16 @@ class QueryToolCommand(BaseCommand, FetchedRowTracker):
     def get_primary_keys(self):
         return self.pk_names, self.primary_keys
 
+    def has_oids(self):
+        return self.table_has_oids
+
     def can_edit(self):
         return self.is_updatable_resultset
 
     def can_filter(self):
         return False
 
-    def check_updatable_results_pkeys(self):
+    def check_updatable_results_pkeys_oids(self):
         """
             This function is used to check whether the last successful query
             produced updatable results and sets the necessary flags and
@@ -895,8 +899,8 @@ class QueryToolCommand(BaseCommand, FetchedRowTracker):
         # Get the path to the sql templates
         sql_path = 'sqleditor/sql/#{0}#'.format(manager.version)
 
-        self.is_updatable_resultset, self.primary_keys, pk_names, table_oid = \
-            is_query_resultset_updatable(conn, sql_path)
+        self.is_updatable_resultset, self.table_has_oids, self.primary_keys, \
+            pk_names, table_oid = is_query_resultset_updatable(conn, sql_path)
 
         # Create pk_names attribute in the required format
         if pk_names is not None:
@@ -921,6 +925,7 @@ class QueryToolCommand(BaseCommand, FetchedRowTracker):
              client_primary_key='__temp_PK',
              default_conn=None):
         if not self.is_updatable_resultset:
+            print(self.is_updatable_resultset, 'hi')
             return False, gettext('Resultset is not updatable.'), None, None
         else:
             driver = get_driver(PG_DEFAULT_DRIVER)
diff --git a/web/pgadmin/tools/sqleditor/tests/test_is_query_resultset_updatable.py b/web/pgadmin/tools/sqleditor/tests/test_is_query_resultset_updatable.py
index 03fa0719..eec60c63 100644
--- a/web/pgadmin/tools/sqleditor/tests/test_is_query_resultset_updatable.py
+++ b/web/pgadmin/tools/sqleditor/tests/test_is_query_resultset_updatable.py
@@ -27,33 +27,65 @@ class TestQueryUpdatableResultset(BaseTestGenerator):
             primary_keys={
                 'pk_col1': 'int4',
                 'pk_col2': 'int4'
-            }
+            },
+            expected_has_oids=False,
+            table_has_oids=False
         )),
         ('When selecting all primary keys of the table', dict(
             sql='SELECT pk_col1, pk_col2 FROM %s;',
             primary_keys={
                 'pk_col1': 'int4',
                 'pk_col2': 'int4'
-            }
+            },
+            expected_has_oids=False,
+            table_has_oids=False
         )),
         ('When selecting some of the primary keys of the table', dict(
             sql='SELECT pk_col2 FROM %s;',
-            primary_keys=None
+            primary_keys=None,
+            expected_has_oids=False,
+            table_has_oids=False
         )),
         ('When selecting none of the primary keys of the table', dict(
             sql='SELECT normal_col1 FROM %s;',
-            primary_keys=None
+            primary_keys=None,
+            expected_has_oids=False,
+            table_has_oids=False
         )),
         ('When renaming a primary key', dict(
-            sql='SELECT pk_col1 as some_col, '
-                'pk_col2 FROM "%s";',
-            primary_keys=None
+            sql='SELECT pk_col1 as some_col, pk_col2 FROM "%s";',
+            primary_keys=None,
+            expected_has_oids=False,
+            table_has_oids=False
         )),
         ('When renaming a column to a primary key name', dict(
-            sql='SELECT pk_col1, pk_col2, normal_col1 as pk_col1 '
-                'FROM %s;',
-            primary_keys=None
-        ))
+            sql='SELECT pk_col1, pk_col2, normal_col1 as pk_col1 FROM %s;',
+            primary_keys=None,
+            expected_has_oids=False,
+            table_has_oids=False
+        )),
+        ('When selecting primary keys and oids (table with oids)', dict(
+            sql='SELECT *, oid FROM %s;',
+            primary_keys={
+                'pk_col1': 'int4',
+                'pk_col2': 'int4'
+            },
+            expected_has_oids=True,
+            table_has_oids=True
+        )),
+        ('When selecting oids without primary keys (table with oids)', dict(
+            sql='SELECT oid, normal_col1, normal_col2 FROM %s;',
+            primary_keys=None,
+            expected_has_oids=True,
+            table_has_oids=True
+        )),
+        ('When selecting none of the primary keys or oids (table with oids)',
+         dict(
+             sql='SELECT normal_col1, normal_col2 FROM %s;',
+             primary_keys=None,
+             expected_has_oids=False,
+             table_has_oids=True
+         ))
     ]
 
     def setUp(self):
@@ -63,9 +95,10 @@ class TestQueryUpdatableResultset(BaseTestGenerator):
 
     def runTest(self):
         # Create test table (unique for each scenario)
-        self._create_test_table()
+        test_table_name = self._create_test_table(
+            table_has_oids=self.table_has_oids)
         # Add test table name to the query
-        sql = self.sql % self.test_table_name
+        sql = self.sql % test_table_name
         is_success, response_data = \
             execute_query(tester=self.tester,
                           query=sql,
@@ -77,6 +110,10 @@ class TestQueryUpdatableResultset(BaseTestGenerator):
         primary_keys = response_data['data']['primary_keys']
         self.assertEquals(primary_keys, self.primary_keys)
 
+        # Check oids
+        has_oids = response_data['data']['has_oids']
+        self.assertEquals(has_oids, self.expected_has_oids)
+
     def tearDown(self):
         # Disconnect the database
         database_utils.disconnect_database(self, self.server_id, self.db_id)
@@ -85,11 +122,18 @@ class TestQueryUpdatableResultset(BaseTestGenerator):
         database_info = parent_node_dict["database"][-1]
         self.server_id = database_info["server_id"]
 
+        self.server_version = parent_node_dict["schema"][-1]["server_version"]
+
+        if self.server_version >= 120000 and self.table_has_oids:
+            self.skipTest('Tables with OIDs are not supported starting '
+                          'PostgreSQL 12')
+
         self.db_id = database_info["db_id"]
         db_con = database_utils.connect_database(self,
                                                  utils.SERVER_GROUP,
                                                  self.server_id,
                                                  self.db_id)
+
         if not db_con["info"] == "Database connected.":
             raise Exception("Could not connect to the database.")
 
@@ -108,8 +152,8 @@ class TestQueryUpdatableResultset(BaseTestGenerator):
 
         self.poll_url = '/sqleditor/poll/{0}'.format(self.trans_id)
 
-    def _create_test_table(self):
-        self.test_table_name = "test_for_updatable_resultset" + \
+    def _create_test_table(self, table_has_oids=False):
+        test_table_name = "test_for_updatable_resultset" + \
                                str(random.randint(1000, 9999))
         create_sql = """
                             DROP TABLE IF EXISTS "%s";
@@ -120,8 +164,13 @@ class TestQueryUpdatableResultset(BaseTestGenerator):
                                 normal_col1 VARCHAR,
                                 normal_col2 VARCHAR,
                                 PRIMARY KEY(pk_col1, pk_col2)
-                            );
-                      """ % (self.test_table_name, self.test_table_name)
+                            )
+                      """ % (test_table_name, test_table_name)
+
+        if table_has_oids:
+            create_sql += ' WITH OIDS;'
+        else:
+            create_sql += ';'
 
         is_success, _ = \
             execute_query(tester=self.tester,
@@ -129,3 +178,4 @@ class TestQueryUpdatableResultset(BaseTestGenerator):
                           start_query_tool_url=self.start_query_tool_url,
                           poll_url=self.poll_url)
         self.assertEquals(is_success, True)
+        return test_table_name
diff --git a/web/pgadmin/tools/sqleditor/utils/is_query_resultset_updatable.py b/web/pgadmin/tools/sqleditor/utils/is_query_resultset_updatable.py
index f6b453ee..9c2bd09a 100644
--- a/web/pgadmin/tools/sqleditor/utils/is_query_resultset_updatable.py
+++ b/web/pgadmin/tools/sqleditor/utils/is_query_resultset_updatable.py
@@ -15,6 +15,7 @@
         - No duplicate columns
 """
 from flask import render_template
+from flask_babelex import gettext
 try:
     from collections import OrderedDict
 except ImportError:
@@ -43,18 +44,25 @@ def is_query_resultset_updatable(conn, sql_path):
         return return_not_updatable()
 
     if conn.connected():
-        primary_keys, primary_keys_columns, pk_names = \
-            _get_primary_keys(conn=conn,
-                              table_oid=table_oid,
-                              sql_path=sql_path)
-
-        if not _check_primary_keys_uniquely_exist(primary_keys_columns,
-                                                  columns_info):
+        primary_keys, pk_names = _check_primary_keys(conn=conn,
+                                                     columns_info=columns_info,
+                                                     table_oid=table_oid,
+                                                     sql_path=sql_path)
+
+        has_oids = _check_oids(conn=conn,
+                               columns_info=columns_info,
+                               table_oid=table_oid,
+                               sql_path=sql_path)
+
+        if has_oids or primary_keys is not None:
+            return True, has_oids, primary_keys, pk_names, table_oid
+        else:
             return return_not_updatable()
-
-        return True, primary_keys, pk_names, table_oid
     else:
-        return return_not_updatable()
+        raise Exception(
+            gettext('Not connected to server or connection with the '
+                    'server has been closed.')
+        )
 
 
 def _check_single_table(columns_info):
@@ -74,6 +82,42 @@ def _check_duplicate_columns(columns_info):
     return True
 
 
+def _check_oids(conn, sql_path, table_oid, columns_info):
+    # Remove the special behavior of OID columns from
+    # PostgreSQL 12 onwards, so returning False.
+    if conn.manager.sversion >= 120000:
+        return False
+
+    # Check that the table has oids
+    query = render_template(
+        "/".join([sql_path, 'has_oids.sql']), obj_id=table_oid)
+
+    status, has_oids = conn.execute_scalar(query)
+    if not status:
+        raise Exception(has_oids)
+
+    # Check that the oid column is selected in results columns
+    oid_column_selected = False
+    for col in columns_info:
+        if col['table_column'] is None and col['display_name'] == 'oid':
+            oid_column_selected = True
+            break
+    return has_oids and oid_column_selected
+
+
+def _check_primary_keys(conn, columns_info, sql_path, table_oid):
+    primary_keys, primary_keys_columns, pk_names = \
+        _get_primary_keys(conn=conn,
+                          table_oid=table_oid,
+                          sql_path=sql_path)
+
+    if not _check_primary_keys_uniquely_exist(primary_keys_columns,
+                                              columns_info):
+        primary_keys = None
+        pk_names = None
+    return primary_keys, pk_names
+
+
 def _check_primary_keys_uniquely_exist(primary_keys_columns, columns_info):
     for pk in primary_keys_columns:
         pk_exists = False
@@ -99,7 +143,7 @@ def _get_primary_keys(sql_path, table_oid, conn):
     )
     status, result = conn.execute_dict(query)
     if not status:
-        return return_not_updatable()
+        raise Exception(result)
 
     primary_keys_columns = []
     primary_keys = OrderedDict()
@@ -117,4 +161,4 @@ def _get_primary_keys(sql_path, table_oid, conn):
 
 
 def return_not_updatable():
-    return False, None, None, None
+    return False, False, None, None, None
diff --git a/web/pgadmin/tools/sqleditor/utils/start_running_query.py b/web/pgadmin/tools/sqleditor/utils/start_running_query.py
index ece11f9c..927e91d0 100644
--- a/web/pgadmin/tools/sqleditor/utils/start_running_query.py
+++ b/web/pgadmin/tools/sqleditor/utils/start_running_query.py
@@ -45,8 +45,9 @@ class StartRunningQuery:
         if type(session_obj) is Response:
             return session_obj
 
-        # Remove any existing primary keys in session_obj
+        # Remove any existing primary keys or has_oids in session_obj
         session_obj.pop('primary_keys', None)
+        session_obj.pop('oids', None)
 
         transaction_object = pickle.loads(session_obj['command_obj'])
         can_edit = False
