diff --git a/docs/en_US/getting_started.rst b/docs/en_US/getting_started.rst
index 5b09c5b4c..2595505d2 100644
--- a/docs/en_US/getting_started.rst
+++ b/docs/en_US/getting_started.rst
@@ -64,6 +64,8 @@ display.  To open the *Preferences* dialog, select *Preferences* from the *File*
 for the dialog.  You can access additional Postgres help by navigating through
 the *Help* menu, and selecting the name of the resource that you wish to open.
 
+You can search for objects in the database using the :ref:`Search objects <search_objects>`
+
 .. toctree::
    :maxdepth: 2
 
@@ -74,6 +76,7 @@ the *Help* menu, and selecting the name of the resource that you wish to open.
    tree_control
    preferences
    keyboard_shortcuts
+   search_objects
 
 Before using pgAdmin to manage objects that reside on a server, you must define a
 connection to the server; for more information please see *Connecting to a Server*
diff --git a/docs/en_US/images/search_objects.png b/docs/en_US/images/search_objects.png
new file mode 100644
index 0000000000000000000000000000000000000000..1c5b4be267ab0240dc207c486057e236e18507a8
GIT binary patch
diff --git a/docs/en_US/images/toolbar.png b/docs/en_US/images/toolbar.png
index 19c4c574a905fb30ea1828b4825e85af7cdb0c0e..aac16b967b93b44576bf2a042b989aa296251648 100644
GIT binary patch
diff --git a/docs/en_US/search_objects.rst b/docs/en_US/search_objects.rst
new file mode 100644
index 000000000..7cf08c84f
--- /dev/null
+++ b/docs/en_US/search_objects.rst
@@ -0,0 +1,32 @@
+.. _search_objects:
+
+***********************
+`Search objects`:index:
+***********************
+
+.. image:: images/search_objects.png
+    :alt: Search objects dialog
+    :align: center
+
+With this dialog, you can search for almost any kind of objects in a
+database.
+
+You can access it by right clicking a database or any of its child nodes
+and select "Search objects". You can also access it by hitting the
+shortcut (default ALT+SHIFT+S).
+
+The minimum pattern length are 3 characters. The search performed is
+non-casesensitive and will find all objets whose name contains the pattern.
+You can only search for object names.
+
+The result is presented in the grid with object name, object type and
+the object tree path in the :ref:`browser <tree_control>`. You can double
+click on a result row to select the object in the
+:ref:`browser <tree_control>`. If the object is grey, this means that you
+have not enabled those object types in the :ref:`preferences <preferences>`,
+so you can't click on it.
+
+You can filter based on a particular object type by selecting one from the
+object type dropdown. An object type will not be visible in the dropdown
+if the database server does not support it or if it is not enabled from the
+:ref:`preferences <preferences>`.
\ No newline at end of file
diff --git a/docs/en_US/toolbar.rst b/docs/en_US/toolbar.rst
index 12dc8621a..f4c685f24 100644
--- a/docs/en_US/toolbar.rst
+++ b/docs/en_US/toolbar.rst
@@ -18,4 +18,6 @@ the selected browser node.
 * Use the :ref:`View Data <editgrid>` button to view/edit the data stored in a
   selected table.
 * Use the :ref:`Filtered Rows <viewdata_filter>` button to access the Data Filter popup
-  to apply a filter to a set of data for viewing/editing.
\ No newline at end of file
+  to apply a filter to a set of data for viewing/editing.
+* Use the :ref:`Search objects <search_objects>` button to access the search objects
+  dialog. It helps you search any database object.
\ No newline at end of file
diff --git a/web/pgadmin/browser/register_browser_preferences.py b/web/pgadmin/browser/register_browser_preferences.py
index 09f472795..5f57f9fa1 100644
--- a/web/pgadmin/browser/register_browser_preferences.py
+++ b/web/pgadmin/browser/register_browser_preferences.py
@@ -249,6 +249,21 @@ def register_browser_preferences(self):
         fields=fields
     )
 
+    self.preference.register(
+        'keyboard_shortcuts',
+        'sub_menu_search_objects',
+        gettext('Search objects'),
+        'keyboardshortcut',
+        {
+            'alt': True,
+            'shift': True,
+            'control': False,
+            'key': {'key_code': 83, 'char': 's'}
+        },
+        category_label=gettext('Keyboard shortcuts'),
+        fields=fields
+    )
+
     self.preference.register(
         'keyboard_shortcuts',
         'sub_menu_create',
diff --git a/web/pgadmin/browser/server_groups/servers/databases/extensions/static/js/extension.js b/web/pgadmin/browser/server_groups/servers/databases/extensions/static/js/extension.js
index 7724ef4c4..b2127c4b0 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/extensions/static/js/extension.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/extensions/static/js/extension.js
@@ -24,7 +24,7 @@ define('pgadmin.node.extension', [
     pgAdmin.Browser.Nodes['coll-extension'] =
       pgAdmin.Browser.Collection.extend({
         node: 'extension',
-        label: gettext('Extension'),
+        label: gettext('Extensions'),
         type: 'coll-extension',
         columns: ['name', 'owner', 'comment'],
       });
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/packages/templates/packages/ppas/12_plus/nodes.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/packages/templates/packages/ppas/12_plus/nodes.sql
new file mode 100644
index 000000000..8b11b594a
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/packages/templates/packages/ppas/12_plus/nodes.sql
@@ -0,0 +1,11 @@
+SELECT
+    nsp.oid, nspname AS name
+FROM
+    pg_namespace nsp
+WHERE nspparent = {{scid}}::oid
+{% if pkgid %}
+AND nsp.oid = {{pkgid}}::oid
+{% endif %}
+AND nspobjecttype = 0
+AND nspcompoundtrigger = false
+ORDER BY nspname;
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 2984a58e4..4b0a0918c 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
@@ -54,8 +54,8 @@ class IndexConstraintModule(ConstraintTypeModule):
         initialized.
     """
 
-    NODE_TYPE = 'Index constraint'
-    COLLECTION_LABEL = _('index_constraint')
+    NODE_TYPE = 'index_constraint'
+    COLLECTION_LABEL = _('Index constraint')
 
     def __init__(self, *args, **kwargs):
         """
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/partitions/__init__.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/partitions/__init__.py
index e455b8adf..9ffbe742c 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/partitions/__init__.py
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/partitions/__init__.py
@@ -29,8 +29,11 @@ from pgadmin.tools.schema_diff.compare import SchemaDiffObjectCompare
 
 
 def backend_supported(module, manager, **kwargs):
-    if 'tid' in kwargs and CollectionNodeModule.BackendSupported(
-            module, manager, **kwargs):
+
+    if CollectionNodeModule.BackendSupported(module, manager, **kwargs):
+        if 'tid' not in kwargs:
+            return True
+
         conn = manager.connection(did=kwargs['did'])
 
         template_path = 'partitions/sql/{0}/#{0}#{1}#'.format(
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/partitions/tests/test_backend_supported.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/partitions/tests/test_backend_supported.py
index bf92e5f01..1de4de825 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/partitions/tests/test_backend_supported.py
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/partitions/tests/test_backend_supported.py
@@ -21,19 +21,19 @@ else:
 
 class TestBackendSupport(BaseTestGenerator):
     scenarios = [
-        ('when tid is not present in arguments, should return None and no '
-         'query should be done',
+        ('when tid is not present in arguments, but server version'
+         'is supported then return True',
          dict(
              manager=dict(
-                 server_type="",
-                 version=""
+                 server_type="pg",
+                 version="100000"
              ),
              input_arguments=dict(did=432),
 
              collection_node_active=True,
              connection_execution_return_value=[],
 
-             expected_return_value=None,
+             expected_return_value=True,
              expect_error_response=False,
              expected_number_calls_on_render_template=0
          )),
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/catalog/pg/macros/catalogs.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/catalog/pg/macros/catalogs.sql
index 5f9bf9532..f1645d070 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/catalog/pg/macros/catalogs.sql
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/catalog/pg/macros/catalogs.sql
@@ -9,6 +9,9 @@
         (SELECT 1 FROM pg_class WHERE relname = 'tables' AND
             relnamespace = {{ tbl }}.oid LIMIT 1))
 {%- endmacro %}
+{% macro IS_CATALOG_SCHEMA(schema_col_name) -%}
+    {{ schema_col_name }} IN ('pg_catalog', 'pgagent', 'information_schema')
+{%- endmacro %}
 {% macro LABELS(tbl, _) -%}
     CASE {{ tbl }}.nspname
     WHEN 'pg_catalog' THEN '{{ _( 'PostgreSQL Catalog' ) }} (pg_catalog)'
@@ -17,9 +20,24 @@
     ELSE {{ tbl }}.nspname
     END AS name
 {%- endmacro %}
+{% macro LABELS_SCHEMACOL(schema_col_name, _) -%}
+    CASE {{ schema_col_name }}
+    WHEN 'pg_catalog' THEN '{{ _( 'PostgreSQL Catalog' ) }} (pg_catalog)'
+    WHEN 'pgagent' THEN '{{ _( 'pgAgent Job Scheduler' ) }} (pgagent)'
+    WHEN 'information_schema' THEN '{{ _( 'ANSI' ) }} (information_schema)'
+    ELSE {{ schema_col_name }}
+    END
+{%- endmacro %}
 {% macro DB_SUPPORT(tbl) -%}
     CASE
     WHEN {{ tbl }}.nspname = ANY('{information_schema}')
         THEN false
     ELSE true END
 {%- endmacro %}
+{% macro DB_SUPPORT_SCHEMACOL(schema_col_name) -%}
+    CASE
+    WHEN {{ schema_col_name }} = ANY('{information_schema}')
+        THEN false
+    ELSE true END
+{%- endmacro %}
+
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/catalog/ppas/macros/catalogs.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/catalog/ppas/macros/catalogs.sql
index 37fb594ed..b9fc276ef 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/catalog/ppas/macros/catalogs.sql
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/catalog/ppas/macros/catalogs.sql
@@ -13,6 +13,9 @@
        (SELECT 1 FROM pg_proc
         WHERE pronamespace = {{ tbl }}.oid and proname = 'run_job' LIMIT 1))
 {%- endmacro %}
+{% macro IS_CATALOG_SCHEMA(schema_col_name) -%}
+    {{ schema_col_name }} IN ('pg_catalog', 'pgagent', 'information_schema', 'dbo', 'sys', 'dbms_job_procedure')
+{%- endmacro %}
 {% macro LABELS(tbl, _) -%}
     CASE {{ tbl }}.nspname
     WHEN 'pg_catalog' THEN '{{ _( 'PostgreSQL Catalog' ) }} (pg_catalog)'
@@ -23,9 +26,25 @@
     ELSE {{ tbl }}.nspname
     END AS name
 {%- endmacro %}
-{% macro DB_SUPPORT(tbl) -%}
+{% macro LABELS_SCHEMACOL(schema_col_name, _) -%}
+    CASE {{ schema_col_name }}
+    WHEN 'pg_catalog' THEN '{{ _( 'PostgreSQL Catalog' ) }} (pg_catalog)'
+    WHEN 'pgagent' THEN '{{ _( 'pgAgent Job Scheduler' ) }} (pgagent)'
+    WHEN 'information_schema' THEN '{{ _( 'ANSI' ) }} (information_schema)'
+    WHEN 'dbo' THEN 'Redmond (dbo)'
+    WHEN 'sys' THEN 'Redwood (sys)'
+    ELSE {{ schema_col_name }}
+    END
+{%- endmacro %}
+{% macro DB_SUPPORT(tbl, schema_col_name) -%}
     CASE
     WHEN {{ tbl }}.nspname = ANY('{information_schema,sys,dbo}')
         THEN false
     ELSE true END
 {%- endmacro %}
+{% macro DB_SUPPORT_SCHEMACOL(schema_col_name) -%}
+    CASE
+    WHEN {{ schema_col_name }} = ANY('{information_schema,sys,dbo}')
+        THEN false
+    ELSE true END
+{%- endmacro %}
diff --git a/web/pgadmin/browser/server_groups/servers/roles/static/js/role.js b/web/pgadmin/browser/server_groups/servers/roles/static/js/role.js
index 47500caf7..c7bb247ec 100644
--- a/web/pgadmin/browser/server_groups/servers/roles/static/js/role.js
+++ b/web/pgadmin/browser/server_groups/servers/roles/static/js/role.js
@@ -18,6 +18,7 @@ define('pgadmin.node.role', [
     pgAdmin.Browser.Nodes['coll-role'] =
       pgAdmin.Browser.Collection.extend({
         node: 'role',
+        label: gettext('Login/Group Roles'),
         type: 'coll-role',
         columns: [
           'rolname', 'rolvaliduntil', 'rolconnlimit', 'rolcanlogin',
diff --git a/web/pgadmin/browser/static/js/collection.js b/web/pgadmin/browser/static/js/collection.js
index 2ec4fe1b5..a3c9ad96e 100644
--- a/web/pgadmin/browser/static/js/collection.js
+++ b/web/pgadmin/browser/static/js/collection.js
@@ -51,14 +51,23 @@ define([
         }]);
 
         // show query tool only in context menu of supported nodes.
-        if (pgAdmin.DataGrid && pgAdmin.unsupported_nodes) {
-          if (_.indexOf(pgAdmin.unsupported_nodes, this.type) == -1) {
+
+        if (pgAdmin.unsupported_nodes && _.indexOf(pgAdmin.unsupported_nodes, this.type) == -1) {
+          if ((this.type == 'database' && this.allowConn) || this.type != 'database') {
             pgAdmin.Browser.add_menus([{
-              name: 'show_query_tool', node: this.type, module: this,
+              name: 'show_query_tool', node: this.type, module: pgAdmin.DataGrid,
               applies: ['context'], callback: 'show_query_tool',
               priority: 998, label: gettext('Query Tool...'),
               icon: 'pg-font-icon icon-query-tool',
             }]);
+
+            // show search objects same as query tool
+            pgAdmin.Browser.add_menus([{
+              name: 'search_objects', node: this.type, module: pgAdmin.SearchObjects,
+              applies: ['context'], callback: 'show_search_objects',
+              priority: 997, label: gettext('Search Objects...'),
+              icon: 'fa fa-search',
+            }]);
           }
         }
       },
diff --git a/web/pgadmin/browser/static/js/keyboard.js b/web/pgadmin/browser/static/js/keyboard.js
index 5cd00e6a3..8705e14be 100644
--- a/web/pgadmin/browser/static/js/keyboard.js
+++ b/web/pgadmin/browser/static/js/keyboard.js
@@ -34,6 +34,7 @@ _.extend(pgBrowser.keyboardNavigation, {
         'tabbed_panel_forward': commonUtils.parseShortcutValue(pgBrowser.get_preference('browser', 'tabbed_panel_forward').value),
         'sub_menu_query_tool': commonUtils.parseShortcutValue(pgBrowser.get_preference('browser', 'sub_menu_query_tool').value),
         'sub_menu_view_data': commonUtils.parseShortcutValue(pgBrowser.get_preference('browser', 'sub_menu_view_data').value),
+        'sub_menu_search_objects': commonUtils.parseShortcutValue(pgBrowser.get_preference('browser', 'sub_menu_search_objects').value),
         'sub_menu_properties': commonUtils.parseShortcutValue(pgBrowser.get_preference('browser', 'sub_menu_properties').value),
         'sub_menu_create': commonUtils.parseShortcutValue(pgBrowser.get_preference('browser', 'sub_menu_create').value),
         'sub_menu_delete': commonUtils.parseShortcutValue(pgBrowser.get_preference('browser', 'sub_menu_delete').value),
@@ -55,6 +56,7 @@ _.extend(pgBrowser.keyboardNavigation, {
         'bindLeftTree': {'shortcuts': this.keyboardShortcut.left_tree_shortcut}, // Main menu,
         'bindSubMenuQueryTool': {'shortcuts': this.keyboardShortcut.sub_menu_query_tool}, // Sub menu - Open Query Tool,
         'bindSubMenuViewData': {'shortcuts': this.keyboardShortcut.sub_menu_view_data}, // Sub menu - Open View Data,
+        'bindSubMenuSearchObjects': {'shortcuts': this.keyboardShortcut.sub_menu_search_objects}, // Sub menu - Open search objects,
         'bindSubMenuProperties': {'shortcuts': this.keyboardShortcut.sub_menu_properties}, // Sub menu - Edit Properties,
         'bindSubMenuCreate': {'shortcuts': this.keyboardShortcut.sub_menu_create}, // Sub menu - Create Object,
         'bindSubMenuDelete': {'shortcuts': this.keyboardShortcut.sub_menu_delete}, // Sub menu - Delete object,
@@ -261,6 +263,15 @@ _.extend(pgBrowser.keyboardNavigation, {
     // Call data grid method to render view data
     pgAdmin.DataGrid.show_data_grid({'mnuid': 1}, tree.i);
   },
+  bindSubMenuSearchObjects: function() {
+    const tree = this.getTreeDetails();
+
+    if (!tree.d)
+      return;
+
+    // Call data grid method to render view data
+    pgAdmin.SearchObjects.show_search_objects('', tree.i);
+  },
   bindSubMenuProperties: function() {
     const tree = this.getTreeDetails();
 
diff --git a/web/pgadmin/browser/static/js/node.js b/web/pgadmin/browser/static/js/node.js
index 029a29817..9ee0b4bf5 100644
--- a/web/pgadmin/browser/static/js/node.js
+++ b/web/pgadmin/browser/static/js/node.js
@@ -177,6 +177,14 @@ define('pgadmin.browser.node', [
 
       // Show query tool only in context menu of supported nodes.
       if (_.indexOf(pgAdmin.unsupported_nodes, self.type) == -1) {
+        let enable = function(itemData) {
+          if (itemData._type == 'database' && itemData.allowConn)
+            return true;
+          else if (itemData._type != 'database')
+            return true;
+          else
+            return false;
+        };
         pgAdmin.Browser.add_menus([{
           name: 'show_query_tool',
           node: self.type,
@@ -186,14 +194,15 @@ define('pgadmin.browser.node', [
           priority: 998,
           label: gettext('Query Tool...'),
           icon: 'pg-font-icon icon-query-tool',
-          enable: function(itemData) {
-            if (itemData._type == 'database' && itemData.allowConn)
-              return true;
-            else if (itemData._type != 'database')
-              return true;
-            else
-              return false;
-          },
+          enable: enable,
+        }]);
+
+        // show search objects same as query tool
+        pgAdmin.Browser.add_menus([{
+          name: 'search_objects', node: self.type, module: pgAdmin.SearchObjects,
+          applies: ['context'], callback: 'show_search_objects',
+          priority: 997, label: gettext('Search Objects...'),
+          icon: 'fa fa-search', enable: enable,
         }]);
       }
 
diff --git a/web/pgadmin/browser/static/js/toolbar.js b/web/pgadmin/browser/static/js/toolbar.js
index 955fe6f32..6eb1f39f4 100644
--- a/web/pgadmin/browser/static/js/toolbar.js
+++ b/web/pgadmin/browser/static/js/toolbar.js
@@ -46,6 +46,16 @@ let _defaultToolBarButtons = [
     parentClass: 'pg-toolbar-btn btn-secondary',
     enabled: false,
   },
+  {
+    label: gettext('Search objects'),
+    ariaLabel: gettext('Search objects'),
+    btnClass: 'fa fa-search',
+    text: '',
+    toggled: false,
+    toggleClass: '',
+    parentClass: 'pg-toolbar-btn btn-secondary',
+    enabled: false,
+  },
 ];
 
 // Place holder for non default tool bar buttons.
@@ -92,6 +102,8 @@ export function initializeToolbar(panel, wcDocker) {
       pgAdmin.DataGrid.show_data_grid({mnuid: 3}, pgAdmin.Browser.tree.selected());
     else if ('name' in data && data.name === gettext('Filtered Rows'))
       pgAdmin.DataGrid.show_filtered_row({mnuid: 4}, pgAdmin.Browser.tree.selected());
+    else if ('name' in data && data.name === gettext('Search objects'))
+      pgAdmin.SearchObjects.show_search_objects('', pgAdmin.Browser.tree.selected());
   });
 }
 
diff --git a/web/pgadmin/browser/templates/browser/index.html b/web/pgadmin/browser/templates/browser/index.html
index 682c23d65..67a10ba89 100644
--- a/web/pgadmin/browser/templates/browser/index.html
+++ b/web/pgadmin/browser/templates/browser/index.html
@@ -11,7 +11,7 @@
 {% block init_script %}
 try {
 require(
-['sources/generated/app.bundle', 'sources/generated/codemirror', 'sources/generated/browser_nodes'],
+['sources/generated/app.bundle', 'sources/generated/codemirror', 'sources/generated/browser_nodes', 'sources/generated/slickgrid'],
 function() {
 },
 function() {
diff --git a/web/pgadmin/static/bundle/slickgrid.js b/web/pgadmin/static/bundle/slickgrid.js
index 4b0ab410b..96ad3c330 100644
--- a/web/pgadmin/static/bundle/slickgrid.js
+++ b/web/pgadmin/static/bundle/slickgrid.js
@@ -8,7 +8,6 @@
 //////////////////////////////////////////////////////////////
 
 import 'slickgrid/lib/jquery.event.drag-2.3.0';
-import 'slickgrid/lib/jquery-ui-1.11.3';
 import 'slickgrid/slick.core';
 import 'slickgrid/slick.grid';
 import 'slickgrid/slick.dataview';
@@ -21,5 +20,6 @@ import 'slickgrid/plugins/slick.cellrangeselector';
 import 'slickgrid/plugins/slick.checkboxselectcolumn';
 import 'slickgrid/plugins/slick.rowselectionmodel';
 import 'sources/slickgrid/custom_header_buttons';
+import 'sources/slickgrid/plugins/slick.autocolumnsize';
 
 export default window.Slick;
diff --git a/web/pgadmin/static/css/style.css b/web/pgadmin/static/css/style.css
index 6c0f84460..55e477ee1 100644
--- a/web/pgadmin/static/css/style.css
+++ b/web/pgadmin/static/css/style.css
@@ -5,19 +5,18 @@
 @import '~tempusdominus-bootstrap-4/build/css/tempusdominus-bootstrap-4.css';
 @import '~bootstrap4-toggle/css/bootstrap4-toggle.css';
 @import '~backgrid-filter/backgrid-filter.css';
-@import '~slickgrid/css/select2.css';
 @import '~jquery-contextmenu/dist/jquery.contextMenu.css';
 @import '~webcabin-docker/Build/wcDocker.css';
 @import '~acitree/css/aciTree.css';
 @import '~spectrum-colorpicker/spectrum.css';
 @import '~leaflet/dist/leaflet.css';
+@import '../../../node_modules/select2/dist/css/select2.css';
 
 @import '~codemirror/lib/codemirror.css';
 @import '~codemirror/addon/dialog/dialog.css';
 @import '~codemirror/addon/scroll/simplescrollbars.css';
 
 @import '~slickgrid/slick.grid.css';
-@import '~slickgrid/slick-default-theme.css';
 @import '~slickgrid/css/smoothness/jquery-ui-1.11.3.custom.css';
 
 @import '../vendor/backgrid/backgrid.css';
diff --git a/web/pgadmin/static/js/alertify.pgadmin.defaults.js b/web/pgadmin/static/js/alertify.pgadmin.defaults.js
index 84dfc12fe..daa60f696 100644
--- a/web/pgadmin/static/js/alertify.pgadmin.defaults.js
+++ b/web/pgadmin/static/js/alertify.pgadmin.defaults.js
@@ -271,7 +271,8 @@ define([
           let container = $(self.elements.footer);
           commonUtils.findAndSetFocus(container.find('button:not([disabled]):last'));
         }
-      });    });
+      });
+    });
     this.set('onresize', alertifyDialogStartResizing.bind(this, true));
     this.set('onresized', alertifyDialogResized.bind(this, true));
     this.set('onmaximized', alertifyDialogResized);
diff --git a/web/pgadmin/static/js/alertify/dialog.js b/web/pgadmin/static/js/alertify/dialog.js
index 6f4933720..8e5bdb738 100644
--- a/web/pgadmin/static/js/alertify/dialog.js
+++ b/web/pgadmin/static/js/alertify/dialog.js
@@ -80,6 +80,39 @@ export class Dialog {
     return serverInformation;
   }
 
+  retrieveAncestorOfTypeDatabase(item) {
+    let databaseInfo = null;
+    let aciTreeItem = item || this.pgBrowser.treeMenu.selected();
+    let treeNode = this.pgBrowser.treeMenu.findNodeByDomElement(aciTreeItem);
+
+    if (treeNode) {
+      if(treeNode.getData()._type === 'database') {
+        databaseInfo = treeNode.getData();
+      } else {
+        let nodeData = null;
+        treeNode.ancestorNode(
+          (node) => {
+            nodeData = node.getData();
+            if(nodeData._type === 'database') {
+              databaseInfo = nodeData;
+              return true;
+            }
+            return false;
+          }
+        );
+      }
+    }
+
+    if (databaseInfo === null) {
+      this.alertify.alert(
+        gettext(this.errorAlertTitle),
+        gettext('Please select a database or its child node from the browser.')
+      );
+    }
+
+    return databaseInfo;
+  }
+
   hasBinariesConfiguration(serverInformation) {
     const module = 'paths';
     let preference_name = 'pg_bin_dir';
diff --git a/web/pgadmin/static/js/alertify/dialog_factory.js b/web/pgadmin/static/js/alertify/dialog_factory.js
index cb0ae1552..760fde679 100644
--- a/web/pgadmin/static/js/alertify/dialog_factory.js
+++ b/web/pgadmin/static/js/alertify/dialog_factory.js
@@ -9,6 +9,7 @@
 
 import * as BackupDialog from '../../../tools/backup/static/js/backup_dialog_wrapper';
 import {RestoreDialogWrapper} from '../../../tools/restore/static/js/restore_dialog_wrapper';
+import SearchObjectsDialogWrapper from '../../../tools/search_objects/static/js/search_objects_dialog_wrapper';
 
 export class DialogFactory {
   constructor(pgBrowser, $,
@@ -25,6 +26,8 @@ export class DialogFactory {
   create(dialogTitle, typeOfDialog) {
     if (typeOfDialog === 'restore') {
       return this.createRestoreDialog(dialogTitle, typeOfDialog);
+    } else if (typeOfDialog === 'search_objects') {
+      return this.createSearchObjectsDialog(dialogTitle, typeOfDialog);
     } else {
       return this.createBackupDialog(dialogTitle, typeOfDialog);
     }
@@ -49,4 +52,14 @@ export class DialogFactory {
       this.dialogModel,
       this.backform);
   }
+
+  createSearchObjectsDialog(dialogTitle, typeOfDialog) {
+    return new SearchObjectsDialogWrapper(
+      this.dialogContainerSelector, dialogTitle, typeOfDialog,
+      this.jquery,
+      this.pgBrowser,
+      this.alertify,
+      this.dialogModel,
+      this.backform);
+  }
 }
diff --git a/web/pgadmin/static/js/alertify/dialog_wrapper.js b/web/pgadmin/static/js/alertify/dialog_wrapper.js
index e4c275f3a..32d9a7a0b 100644
--- a/web/pgadmin/static/js/alertify/dialog_wrapper.js
+++ b/web/pgadmin/static/js/alertify/dialog_wrapper.js
@@ -58,7 +58,11 @@ export class DialogWrapper {
     let backform_tab = $(alertifyDialog.elements.body).find('.backform-tab');
     backform_tab.attr('tabindex', -1);
     this.pgBrowser.keyboardNavigation.getDialogTabNavigator($(alertifyDialog.elements.dialog));
-    const container = backform_tab.find('.tab-content:first > .tab-pane.active:first');
+    let container = backform_tab.find('.tab-content:first > .tab-pane.active:first');
+
+    if(container.length === 0 && alertifyDialog.elements.content.innerHTML) {
+      container = $(alertifyDialog.elements.content);
+    }
     commonUtils.findAndSetFocus(container);
   }
 
diff --git a/web/pgadmin/static/js/backform.pgadmin.js b/web/pgadmin/static/js/backform.pgadmin.js
index a57f70ebc..3cdc13d4d 100644
--- a/web/pgadmin/static/js/backform.pgadmin.js
+++ b/web/pgadmin/static/js/backform.pgadmin.js
@@ -2132,6 +2132,7 @@ define([
     defaults: _.extend({}, Backform.SelectControl.prototype.defaults, {
       select2: {
         first_empty: true,
+
         multiple: false,
         emptyOptions: false,
         preserveSelectionOrder: false,
diff --git a/web/pgadmin/static/js/slickgrid/plugins/slick.autocolumnsize.js b/web/pgadmin/static/js/slickgrid/plugins/slick.autocolumnsize.js
index 40e537e1b..85b339139 100644
--- a/web/pgadmin/static/js/slickgrid/plugins/slick.autocolumnsize.js
+++ b/web/pgadmin/static/js/slickgrid/plugins/slick.autocolumnsize.js
@@ -98,7 +98,7 @@
     function getTemplateWidth(rowEl, template) {
       var cell = $(rowEl.find('.slick-cell'));
       cell.append(template);
-      $(cell).find('*').css('position', 'relative');
+      cell.find('*').css('position', 'relative');
       return cell.outerWidth() + 1;
     }
 
@@ -128,7 +128,7 @@
         'text-overflow': 'initial',
         'white-space': 'nowrap',
       });
-      var gridCanvas = $container.find('.grid-canvas');
+      var gridCanvas = $container.find('.grid-canvas').first();
       $(gridCanvas).append(rowEl);
       return rowEl;
     }
diff --git a/web/pgadmin/static/js/tree/tree.js b/web/pgadmin/static/js/tree/tree.js
index 57b6207c8..984d247d3 100644
--- a/web/pgadmin/static/js/tree/tree.js
+++ b/web/pgadmin/static/js/tree/tree.js
@@ -50,17 +50,50 @@ export class TreeNode {
   }
 
   reload(tree) {
-    this.unload(tree);
-    tree.aciTreeApi.setInode(this.domNode);
-    tree.aciTreeApi.deselect(this.domNode);
-    setTimeout(() => {
-      tree.selectNode(this.domNode);
-    }, 0);
+    return new Promise((resolve)=>{
+      this.unload(tree)
+        .then(()=>{
+          tree.aciTreeApi.setInode(this.domNode);
+          tree.aciTreeApi.deselect(this.domNode);
+          setTimeout(() => {
+            tree.selectNode(this.domNode);
+          }, 0);
+          resolve();
+        });
+    });
   }
 
   unload(tree) {
-    this.children = [];
-    tree.aciTreeApi.unload(this.domNode);
+    return new Promise((resolve, reject)=>{
+      this.children = [];
+      tree.aciTreeApi.unload(this.domNode, {
+        success: ()=>{
+          resolve(true);
+        },
+        fail: ()=>{
+          reject();
+        },
+      });
+    });
+  }
+
+  open(tree, suppressNoDom) {
+    return new Promise((resolve, reject)=>{
+      if(suppressNoDom && (this.domNode == null || typeof(this.domNode) === 'undefined')) {
+        resolve(true);
+      } else if(tree.aciTreeApi.isOpen(this.domNode)) {
+        resolve(true);
+      } else {
+        tree.aciTreeApi.open(this.domNode, {
+          success: ()=>{
+            resolve(true);
+          },
+          fail: ()=>{
+            reject(true);
+          },
+        });
+      }
+    });
   }
 
   /*
@@ -202,6 +235,47 @@ export class Tree {
     return findInTree(this.rootNode, path.join('.'));
   }
 
+  findNodeWithToggle(path) {
+    let tree = this;
+    path = path.join('.');
+
+    let onCorrectPath = function(matchPath) {
+      return (matchPath !== undefined && path !== undefined
+        && (path.startsWith(matchPath + '.') || path === matchPath));
+    };
+
+    return (function findInNode(currentNode) {
+      return new Promise((resolve, reject)=>{
+        if (path === null || path === undefined || path.length === 0) {
+          resolve(null);
+        }
+        /* No point in checking the children if
+         * the path for currentNode itself is not matching
+         */
+        if (currentNode.path !== undefined && !onCorrectPath(currentNode.path)) {
+          reject(null);
+        } else if (currentNode.path === path) {
+          resolve(currentNode);
+        } else {
+          currentNode.open(tree, true)
+            .then(()=>{
+              for (let i = 0, length = currentNode.children.length; i < length; i++) {
+                let childNode = currentNode.children[i];
+                if(onCorrectPath(childNode.path)) {
+                  resolve(findInNode(childNode));
+                  return;
+                }
+              }
+              reject(null);
+            })
+            .catch(()=>{
+              reject(null);
+            });
+        }
+      });
+    })(this.rootNode);
+  }
+
   findNodeByDomElement(domElement) {
     const path = this.translateTreeNodeIdFromACITree(domElement);
     if(!path || !path[0]) {
@@ -215,8 +289,19 @@ export class Tree {
     return this.aciTreeApi.selected();
   }
 
-  selectNode(aciTreeIdentifier) {
+  /* scrollIntoView will scroll only to top and bottom
+   * Logic can be added for scroll to middle
+   */
+  scrollTo(domElement) {
+    domElement.scrollIntoView();
+  }
+
+  selectNode(aciTreeIdentifier, scrollOnSelect) {
     this.aciTreeApi.select(aciTreeIdentifier);
+
+    if(scrollOnSelect) {
+      this.scrollTo(aciTreeIdentifier[0]);
+    }
   }
 
   createOrUpdateNode(id, data, parent, domNode) {
@@ -227,6 +312,7 @@ export class Tree {
     const oldNode = this.findNode(oldNodePath);
     if (oldNode !== null) {
       oldNode.data = data;
+      oldNode.domNode = domNode;
       return oldNode;
     }
 
@@ -238,6 +324,18 @@ export class Tree {
     return node;
   }
 
+  unloadNode(id, data, domNode, parentPath) {
+    let oldNodePath = [id];
+    const parent = this.findNode(parentPath);
+    if(parent !== null && parent !== undefined) {
+      oldNodePath = [parent.path, id];
+    }
+    const oldNode = this.findNode(oldNodePath);
+    if(oldNode) {
+      oldNode.children = [];
+    }
+  }
+
   /**
    * Given the JQuery object that contains the ACI Tree
    * this method is responsible for registering this tree class
@@ -252,16 +350,20 @@ export class Tree {
     $treeJQuery.on('acitree', function (event, api, item, eventName) {
       if (api.isItem(item)) {
         /* If the id of node is changed, the path should also be changed */
-        if (eventName === 'added' || eventName === 'idset') {
+        if (['added', 'idset', 'beforeunload'].indexOf(eventName) != -1) {
           const id = api.getId(item);
           const data = api.itemData(item);
+          const parentId = this.translateTreeNodeIdFromACITree(api.parent(item));
 
-          if(eventName === 'added') {
-            this.prepareDraggable(data, item);
-          }
+          if(eventName === 'beforeunload') {
+            this.unloadNode(id, data, item, parentId);
+          } else {
+            if(eventName === 'added') {
+              this.prepareDraggable(data, item);
+            }
 
-          const parentId = this.translateTreeNodeIdFromACITree(api.parent(item));
-          this.addNewNode(id, data, item, parentId);
+            this.addNewNode(id, data, item, parentId);
+          }
           if(data.errmsg) {
             Alertify.error(data.errmsg);
           }
diff --git a/web/pgadmin/static/js/utils.js b/web/pgadmin/static/js/utils.js
index 86dae698e..7bdddba85 100644
--- a/web/pgadmin/static/js/utils.js
+++ b/web/pgadmin/static/js/utils.js
@@ -32,11 +32,12 @@ export function findAndSetFocus(container) {
      * browser. For eg, in safari focus() works only when element has
      * tabindex="0", whereas in Chrome it works in any case
      */
+
     if (first_el.length == 0) {
       first_el = container
         .find(`
-          .pgadmin-controls:first input:enabled,
           .pgadmin-controls:first .btn:not(.toggle),
+          .pgadmin-controls:first,
           .ajs-commands:first,
           .CodeMirror-scroll`)
         .find('*[tabindex]:not([tabindex="-1"])');
diff --git a/web/pgadmin/static/scss/_alert.scss b/web/pgadmin/static/scss/_alert.scss
index 3f2e561e3..0e7e234d1 100644
--- a/web/pgadmin/static/scss/_alert.scss
+++ b/web/pgadmin/static/scss/_alert.scss
@@ -119,21 +119,18 @@
   }
 
   .success-in-footer {
-    border-radius: 5px;
-    border: 1px solid transparent;
-
-    .alert-text {
-      border-color: $color-success-light;
-    }
+    border-radius: $border-radius;
+    border: 1px solid $color-success-light;
+    background: $color-success-light;
   }
 
   .info-in-footer {
+    border-radius: $border-radius;
     border: 1px solid $color-primary;
-    border-radius: 4px;
-    height: 35px;
+    background: $color-primary-light;
 
-    .alert-text {
-      border: none;
+    .fa {
+        font-size: 1rem;
     }
   }
 }
diff --git a/web/pgadmin/static/scss/_webcabin.pgadmin.scss b/web/pgadmin/static/scss/_webcabin.pgadmin.scss
index 4846a8031..ca806785a 100644
--- a/web/pgadmin/static/scss/_webcabin.pgadmin.scss
+++ b/web/pgadmin/static/scss/_webcabin.pgadmin.scss
@@ -166,7 +166,7 @@
 
 .wcTabIcon {
   background-position: center;
-  padding: 0px 10px;
+  padding: 0rem 0.75rem;
 
   &.fa, &.pg-font-icon{
     padding: 0rem 0.25rem 0rem 0rem
diff --git a/web/pgadmin/tools/search_objects/__init__.py b/web/pgadmin/tools/search_objects/__init__.py
new file mode 100644
index 000000000..e8bd59141
--- /dev/null
+++ b/web/pgadmin/tools/search_objects/__init__.py
@@ -0,0 +1,87 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2020, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+"""Implements Search Object feature"""
+
+from flask import request
+from flask_babelex import gettext
+from flask_security import login_required
+
+from pgadmin.utils import PgAdminModule
+from pgadmin.utils.ajax import make_json_response, bad_request,\
+    internal_server_error
+from pgadmin.utils.preferences import Preferences
+from pgadmin.tools.search_objects.utils import SearchObjectsHelper
+
+MODULE_NAME = 'search_objects'
+
+
+class SearchObjectsModule(PgAdminModule):
+    LABEL = gettext('Search objects')
+
+    def get_exposed_url_endpoints(self):
+        """
+        Returns:
+            list: URL endpoints for search_object module
+        """
+        return ['search_objects.search', 'search_objects.types']
+
+    def show_system_objects(self):
+        """
+        return system preference objects
+        """
+        return self.pref_show_system_objects.get()
+
+    def register_preferences(self):
+        """
+        Get show_system_objects preference
+        """
+        browser_preference = Preferences.module('browser')
+        self.pref_show_system_objects =\
+            browser_preference.preference('show_system_objects')
+
+
+# Create blueprint for BackupModule class
+blueprint = SearchObjectsModule(
+    MODULE_NAME, __name__, static_url_path=''
+)
+
+
+@blueprint.route("/", endpoint='index')
+@login_required
+def index():
+    return bad_request(errormsg=_("This URL cannot be called directly."))
+
+
+@blueprint.route("types/<int:sid>/<int:did>", endpoint='types')
+@login_required
+def types(sid, did):
+    so_obj = SearchObjectsHelper(sid, did, blueprint.show_system_objects())
+    return make_json_response(data=so_obj.get_supported_types())
+
+
+@blueprint.route("search/<int:sid>/<int:did>", endpoint='search')
+@login_required
+def search(sid, did):
+    """
+    URL args:
+        text <required>: search text
+        type <optional>: type of object to be searched.
+    """
+    text = request.args.get('text', None)
+    obj_type = request.args.get('type', None)
+
+    so_obj = SearchObjectsHelper(sid, did, blueprint.show_system_objects())
+
+    status, res = so_obj.search(text, obj_type)
+
+    if not status:
+        return internal_server_error(errormsg=res)
+
+    return make_json_response(data=res)
diff --git a/web/pgadmin/tools/search_objects/static/js/search_objects.js b/web/pgadmin/tools/search_objects/static/js/search_objects.js
new file mode 100644
index 000000000..84e40afd1
--- /dev/null
+++ b/web/pgadmin/tools/search_objects/static/js/search_objects.js
@@ -0,0 +1,90 @@
+/////////////////////////////////////////////////////////////
+//
+// pgAdmin 4 - PostgreSQL Tools
+//
+// Copyright (C) 2013 - 2020, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+//////////////////////////////////////////////////////////////
+
+define([
+  'sources/gettext', 'sources/url_for', 'jquery', 'underscore', 'pgadmin.alertifyjs',
+  'sources/pgadmin', 'sources/csrf', 'pgadmin.browser.toolbar',
+  'pgadmin.search_objects/search_objects_dialog',
+], function(
+  gettext, url_for, $, _, alertify, pgAdmin, csrfToken, toolBar, SearchObjectsDialog
+) {
+
+  var pgBrowser = pgAdmin.Browser;
+  if (pgAdmin.SearchObjects)
+    return pgAdmin.SearchObjects;
+
+  pgAdmin.SearchObjects = {
+    init: function() {
+      if (this.initialized)
+        return;
+
+      this.initialized = true;
+      csrfToken.setPGCSRFToken(pgAdmin.csrf_token_header, pgAdmin.csrf_token);
+
+      // Define the nodes on which the menus to be appear
+      var menus = [{
+        name: 'search_objects',
+        module: this,
+        applies: ['tools'],
+        callback: 'show_search_objects',
+        enable: this.search_objects_enabled,
+        priority: 1,
+        label: gettext('Search objects'),
+      }, {
+        name: 'search_objects',
+        module: this,
+        applies: ['context'],
+        callback: 'show_search_objects',
+        enable: this.search_objects_enabled,
+        priority: 1,
+        label: gettext('Search objects'),
+      }];
+
+      pgBrowser.add_menus(menus);
+      return this;
+    },
+
+    search_objects_enabled: function(obj) {
+      /* Same as query tool */
+      var isEnabled = (() => {
+        if (!_.isUndefined(obj) && !_.isNull(obj)) {
+          if (_.indexOf(pgAdmin.unsupported_nodes, obj._type) == -1) {
+            if (obj._type == 'database' && obj.allowConn) {
+              return true;
+            } else if (obj._type != 'database') {
+              return true;
+            } else {
+              return false;
+            }
+          } else {
+            return false;
+          }
+        } else {
+          return false;
+        }
+      })();
+
+      toolBar.enable(gettext('Search objects'), isEnabled);
+      return isEnabled;
+    },
+
+    // Callback to show the dialog
+    show_search_objects: function(action, item) {
+      let dialog = new SearchObjectsDialog.default(
+        pgBrowser,
+        $,
+        alertify,
+        {},
+      );
+      dialog.draw(action, item, {}, pgBrowser.stdW.md, pgBrowser.stdH.md);
+    },
+  };
+
+  return pgAdmin.SearchObjects;
+});
diff --git a/web/pgadmin/tools/search_objects/static/js/search_objects_dialog.js b/web/pgadmin/tools/search_objects/static/js/search_objects_dialog.js
new file mode 100644
index 000000000..c2e24940d
--- /dev/null
+++ b/web/pgadmin/tools/search_objects/static/js/search_objects_dialog.js
@@ -0,0 +1,40 @@
+/////////////////////////////////////////////////////////////
+//
+// pgAdmin 4 - PostgreSQL Tools
+//
+// Copyright (C) 2013 - 2020, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+//////////////////////////////////////////////////////////////
+
+import gettext from 'sources/gettext';
+import {Dialog} from 'sources/alertify/dialog';
+import {getPanelTitle} from 'tools/datagrid/static/js/datagrid_panel_title';
+
+export default class SearchObjectsDialog extends Dialog {
+  constructor(pgBrowser, $, alertify, BackupModel, backform = null) {
+    super('Search Objects Error',
+      '<div class=\'search_objects_dialog\'></div>',
+      pgBrowser, $, alertify, BackupModel, backform
+    );
+  }
+
+  dialogName() {
+    return 'search_objects';
+  }
+
+  draw(action, aciTreeItem, params, width=0, height=0) {
+    let dbInfo = this.retrieveAncestorOfTypeDatabase(aciTreeItem);
+    if (!dbInfo) {
+      return;
+    }
+
+    let dialogTitle = getPanelTitle(this.pgBrowser, aciTreeItem);
+    dialogTitle = gettext('Search Objects - ')  + dialogTitle;
+    const dialog = this.createOrGetDialog(
+      gettext('Search Objects...'),
+      'search_objects'
+    );
+    dialog(dialogTitle).resizeTo(width, height);
+  }
+}
diff --git a/web/pgadmin/tools/search_objects/static/js/search_objects_dialog_wrapper.js b/web/pgadmin/tools/search_objects/static/js/search_objects_dialog_wrapper.js
new file mode 100644
index 000000000..926c5cf43
--- /dev/null
+++ b/web/pgadmin/tools/search_objects/static/js/search_objects_dialog_wrapper.js
@@ -0,0 +1,614 @@
+import {getTreeNodeHierarchyFromElement} from 'sources/tree/pgadmin_tree_node';
+import axios from 'axios/index';
+import gettext from 'sources/gettext';
+import url_for from 'sources/url_for';
+import 'select2';
+import {DialogWrapper} from 'sources/alertify/dialog_wrapper';
+import Slick from 'sources/../bundle/slickgrid';
+import pgAdmin from 'sources/pgadmin';
+
+
+export default class SearchObjectsDialogWrapper extends DialogWrapper {
+  constructor(dialogContainerSelector, dialogTitle, typeOfDialog,
+    jquery, pgBrowser, alertify, dialogModel, backform) {
+    super(dialogContainerSelector, dialogTitle, jquery,
+      pgBrowser, alertify, dialogModel, backform);
+
+    this.grid = null;
+    this.gridContainer = null;
+  }
+
+  showMessage(text, is_error, call_after_show=()=>{}) {
+    if(text == '' || text == null) {
+      this.statusBar.classList.add('d-none');
+    } else {
+      if(is_error) {
+        this.statusBar.innerHTML = `
+          <div class="error-in-footer">
+            <div class="d-flex px-2 py-1">
+              <div class="pr-2">
+                <i class="fa fa-exclamation-triangle text-danger" aria-hidden="true" role="img"></i>
+              </div>
+              <div role="alert" class="alert-text">${text}</div>
+              <div class="ml-auto close-error-bar">
+                <a class="close-error fa fa-times text-danger"></a>
+              </div>
+            </div>
+          </div>
+        `;
+
+        this.statusBar.querySelector('.close-error').addEventListener('click', ()=>{
+          this.showMessage(null);
+        });
+      } else {
+        this.statusBar.innerHTML = `
+          <div class="info-in-footer">
+            <div class="d-flex px-2 py-1">
+              <div class="pr-2">
+                <i class="fa fa-info-circle text-primary" aria-hidden="true"></i>
+              </div>
+              <div class="alert-text" role="alert">${text}</div>
+            </div>
+          </div>
+        `;
+      }
+      this.statusBar.classList.remove('d-none');
+      call_after_show(this.statusBar);
+    }
+  }
+
+  createDialogDOM(dialogContainer) {
+    dialogContainer.innerHTML = `
+      <div class="d-flex flex-column w-100 h-100">
+        <div class="p-2">
+          <div class="row">
+            <div class="col-8 d-flex">
+              <div class="input-group pgadmin-controls">
+                  <div class="input-group-prepend">
+                      <span class="input-group-text fa fa-search" id="labelSearch" aria-label="` + gettext('Search') + `"></span>
+                  </div>
+                  <input type="search" class="form-control" id="txtGridSearch" placeholder="` + gettext('Type at least 3 characters') + `"
+                    tabindex="0" aria-describedby="labelSearch" aria-labelledby="labelSearch" autocomplete="off">
+              </div>
+              <div class="ml-2">
+                <button class="btn btn-primary btn-search" disabled>${ gettext('Search') }</button>
+              </div>
+            </div>
+            <div class="col-4">
+              <select class="node-types"></select>
+            </div>
+          </div>
+        </div>
+        <div class="search-result-container flex-grow-1">
+          <div class="pg-sp-container d-none">
+            <div class="pg-sp-content">
+              <div class="row"><div class="col-12 pg-sp-icon"></div></div>
+              <div class="row"><div class="col-12 pg-sp-text"></div></div>
+            </div>
+          </div>
+          <div class="search-result"></div>
+        </div>
+        <div class=\'pg-prop-status-bar pg-el-xs-12\'>
+        </div>
+      </div>
+    `;
+
+    return dialogContainer;
+  }
+
+  updateDimOfSearchResult() {
+    let dim = this.searchResultContainer.getBoundingClientRect();
+    this.searchResult.style.height = dim.height + 'px';
+    this.searchResult.style.width = dim.width + 'px';
+  }
+
+  setLoading(text) {
+    if(text != null) {
+      this.loader.classList.remove('d-none');
+      this.loader.querySelector('.pg-sp-text').innerHTML = text;
+    } else {
+      this.loader.classList.add('d-none');
+    }
+  }
+
+  searchBtnEnabled(enabled) {
+    if(typeof(enabled) != 'undefined') {
+      this.searchBtn.disabled = !enabled;
+    } else {
+      return !this.searchBtn.disabled;
+    }
+  }
+
+  searchBoxVal(val) {
+    if(typeof(val) != 'undefined') {
+      this.searchBox.value = val;
+    } else {
+      return this.searchBox.value.trim();
+    }
+  }
+
+  typesVal(val) {
+    if(typeof(val) != 'undefined') {
+      this.typesSelect.value = val;
+    } else {
+      return this.typesSelect.value;
+    }
+  }
+
+  setTypes(data, enabled=true) {
+    this.jquery(this.typesSelect).empty().select2({
+      data: data,
+    });
+
+    this.typesSelect.disabled = !enabled;
+  }
+
+  showOtherInfo(rowno) {
+    let data = this.grid.getData();
+    let rowData = data[rowno];
+    rowData.name += ` (${rowData.other_info})`;
+    rowData.other_info = null;
+    data[rowno] = rowData;
+    this.setGridData(data);
+  }
+
+  setGridData(data) {
+    data.getItemMetadata = (row)=>{
+      if(data[row] && !data[row].show_node){
+        return {
+          cssClasses: 'object-muted',
+        };
+      }
+      return null;
+    };
+    this.grid.setData(data);
+    this.grid.resizeCanvas();
+  }
+
+  prepareGrid() {
+    this.grid = new Slick.Grid(
+      this.searchResult,
+      [],
+      [
+        { id: 'name', name: 'Object name', field: 'name', sortable: true,
+          formatter: (row, cell, value, columnDef, dataContext) => {
+            let ret_el = `<i class='wcTabIcon ${dataContext.icon}'></i>${value}`;
+
+            if(dataContext.other_info != null && dataContext.other_info != '') {
+              ret_el += '&nbsp;<span class="object-other-info">(...)</span>';
+            }
+
+            return ret_el;
+          },
+          width: 50,
+        },
+        { id: 'type', name: 'Type', field: 'type_label', sortable: true, width: 35 },
+        { id: 'path', name: 'Path', field: 'path', sortable: false },
+      ],
+      {
+        enableCellNavigation: true,
+        enableColumnReorder: false,
+        multiColumnSort: true,
+        explicitInitialization: true,
+      }
+    );
+
+    this.grid.registerPlugin(new Slick.AutoColumnSize());
+
+    this.grid.setSelectionModel(new Slick.RowSelectionModel({selectActiveRow: true}));
+
+    this.grid.onKeyDown.subscribe((event) => {
+      let activeRow = this.grid.getActiveCell();
+      if(activeRow && !event.ctrlKey && !event.altKey && !event.metaKey && event.keyCode == 9) {
+        event.preventDefault();
+        event.stopImmediatePropagation();
+
+        if(event.shiftKey) {
+          this.prevToGrid.focus();
+        } else {
+          this.nextToGrid.focus();
+        }
+      }
+    });
+
+    this.grid.onClick.subscribe((event, args) => {
+      if(event.target.classList.contains('object-other-info')) {
+        this.showOtherInfo(args.row);
+      }
+    });
+
+    this.grid.onDblClick.subscribe((event, args) => {
+      let rowData = this.grid.getDataItem(args.row);
+      let treeMenu = this.pgBrowser.treeMenu;
+
+      if(!rowData.show_node) {
+        this.showMessage(
+          gettext('%s objects are disabled in the browser.', rowData.type) + ' ' +
+          gettext('You can enable them in the') + ' <a class="pref-dialog-link">' + gettext('preferences dialog') + '</a>',
+          true,
+          (statusBar)=>{
+            statusBar.querySelector('.pref-dialog-link').addEventListener('click', ()=>{
+              if(pgAdmin.Preferences) {
+                pgAdmin.Preferences.show();
+              }
+            });
+          }
+        );
+        return false;
+      }
+      this.showMessage(gettext('Locating...'));
+      treeMenu.findNodeWithToggle(rowData.id_path)
+        .then((treeItem)=>{
+          treeMenu.selectNode(treeItem.domNode, true);
+          this.showMessage(null);
+        })
+        .catch((args)=>{
+          this.showMessage(gettext('Unable to locate this object in the browser.'), true);
+          console.warn(args);
+        });
+    });
+
+    this.grid.onSort.subscribe((event, args) => {
+      let cols = args.sortCols;
+      let data = this.grid.getData();
+
+      data.sort(function (dataRow1, dataRow2) {
+        for (var i = 0, l = cols.length; i < l; i++) {
+          var field = cols[i].sortCol.field;
+          var sign = cols[i].sortAsc ? 1 : -1;
+          var value1 = dataRow1[field], value2 = dataRow2[field];
+          var result = (value1 == value2 ? 0 : (value1 > value2 ? 1 : -1)) * sign;
+          if (result != 0) {
+            return result;
+          }
+        }
+        return false;
+      });
+      this.setGridData(data);
+    });
+  }
+
+  onDialogResize() {
+    this.updateDimOfSearchResult();
+
+    if(this.grid) {
+      this.grid.resizeCanvas();
+      this.grid.autosizeColumns();
+    }
+  }
+
+  onDialogShow() {
+    this.focusOnDialog(this);
+
+    setTimeout(()=>{
+      if(!this.grid) {
+        this.prepareGrid();
+      }
+      this.updateDimOfSearchResult();
+      this.grid.init();
+      this.setGridData([]);
+      this.onDialogResize();
+    }, 500);
+  }
+
+  getBaseUrl(endpoint) {
+    return url_for('search_objects.'+endpoint, {
+      sid: this.treeInfo.server._id,
+      did: this.treeInfo.database._id,
+    });
+  }
+
+  getCollNode(node_type) {
+    if('coll-'+node_type in this.pgBrowser.Nodes) {
+      return this.pgBrowser.Nodes['coll-'+node_type];
+    } else if(node_type in this.pgBrowser.Nodes &&
+              typeof(this.pgBrowser.Nodes[node_type].collection_type) === 'string') {
+      return this.pgBrowser.Nodes[this.pgBrowser.Nodes[node_type].collection_type];
+    }
+
+    return null;
+  }
+
+  getSelectedNode() {
+    const tree = this.pgBrowser.treeMenu;
+    const selectedNode = tree.selected();
+    if (selectedNode) {
+      return tree.findNodeByDomElement(selectedNode);
+    } else {
+      return undefined;
+    }
+  }
+
+  finaliseData(datum) {
+    datum.icon = 'icon-' + datum.type;
+    /* finalise path */
+    [datum.path, datum.id_path] = this.translateSearchObjectsPath(datum.path, datum.catalog_level);
+    return datum;
+  }
+
+  /* This function will translate the path given by search objects API into two parts
+   * 1. The display path on the UI
+   * 2. The tree search path to locate the object on the tree.
+   *
+   * Sample path returned by search objects API
+   * :schema.11:/pg_catalog/:table.2604:/pg_attrdef
+   *
+   * Sample path required by tree locator
+   * Normal object  - server_group/1.server/3.coll-database/3.database/13258.coll-schema/13258.schema/2200.coll-table/2200.table/41773
+   * pg_catalog schema - server_group/1.server/3.coll-database/3.database/13258.coll-catalog/13258.catalog/11.coll-table/11.table/2600
+   * Information Schema, dbo, sys    - server_group/1.server/3.coll-database/3.database/13258.coll-catalog/13258.catalog/12967.coll-catalog_object/12967.catalog_object/13204
+   *
+   * Column catalog_level has values as
+   * N - Not a catalog schema
+   * D - Catalog schema with DB support - pg_catalog
+   * O - Catalog schema with object support only - info schema, dbo, sys
+   */
+  translateSearchObjectsPath(path, catalog_level) {
+    if (path === null) {
+      return path;
+    }
+
+    catalog_level = catalog_level || 'N';
+
+    /* path required by tree locator */
+    /* the path received from the backend is after the DB node, initial path setup */
+    let id_path = [
+      this.treeInfo.server_group.id,
+      this.treeInfo.server.id,
+      this.getCollNode('database').type + '/' + this.treeInfo.server._id,
+      this.treeInfo.database.id,
+    ];
+
+    let prev_node_id = this.treeInfo.database._id;
+
+    /* add the slash to match regex, remove it from display path later */
+    path = '/' + path;
+    /* the below regex will match all /:server_group.1:/ */
+    let new_path = path.replace(/\/:[a-zA-Z_]+\.[0-9]+:\//g, (token)=>{
+      let orig_token = token;
+      /* remove the slash and colon */
+      token = token.slice(2, -2);
+      let [node_type, node_oid, others] = token.split('.');
+      if(typeof(others) !== 'undefined') {
+        return token;
+      }
+
+      /* schema type is "catalog" for catalog schemas */
+      node_type = (['D', 'O'].indexOf(catalog_level) != -1 && node_type == 'schema') ? 'catalog' : node_type;
+
+      /* catalog like info schema will only have views and tables AKA catalog_object except for pg_catalog */
+      node_type = (catalog_level === 'O' && ['view', 'table'].indexOf(node_type) != -1) ? 'catalog_object' : node_type;
+
+      /* If collection node present then add it */
+      let coll_node = this.getCollNode(node_type);
+      if(coll_node) {
+        /* Add coll node to the path */
+        if(prev_node_id != null) id_path.push(`${coll_node.type}/${prev_node_id}`);
+
+        /* Add the node to the path */
+        id_path.push(`${node_type}/${node_oid}`);
+
+        /* This will be needed for coll node */
+        prev_node_id = node_oid;
+
+        /* This will be displayed in the grid */
+        return  `/${coll_node.label}/`;
+      } else if(node_type in this.pgBrowser.Nodes) {
+        /* Add the node to the path */
+        id_path.push(`${node_type}/${node_oid}`);
+
+        /* This will be need for coll node id path */
+        prev_node_id = node_oid;
+
+        /* Remove the token and replace with slash. This will be displayed in the grid */
+        return '/';
+      }
+      prev_node_id = null;
+      return orig_token;
+    });
+
+    /* Remove the slash we had added */
+    new_path = new_path.substring(1);
+    return [new_path, id_path];
+  }
+
+  prepareDialog() {
+    this.showMessage(null);
+    if(this.grid) {
+      this.grid.destroy();
+      this.grid = null;
+    }
+
+    /* Load types */
+    this.setTypes([{
+      id: -1,
+      text: gettext('Loading...'),
+      value: null,
+    }], false);
+
+    axios.get(
+      this.getBaseUrl('types')
+    ).then((res)=>{
+      let types = [{
+        id: 'all',
+        text: 'All types',
+      }];
+
+      for (const key of Object.keys(res.data.data).sort()) {
+        types.push({
+          id: key,
+          text: res.data.data[key],
+        });
+      }
+      this.setTypes(types);
+    }).catch(()=>{
+      this.setTypes([{
+        id: -1,
+        text: gettext('Failed'),
+        value: null,
+      }], false);
+    });
+  }
+
+  main(title) {
+    this.set('title', title);
+  }
+
+  setup() {
+    return {
+      buttons: [{
+        text: '',
+        key: 112,
+        className: 'btn btn-secondary pull-left fa fa-question pg-alertify-icon-button',
+        attrs: {
+          name: 'dialog_help',
+          type: 'button',
+          label: gettext('Help'),
+          'aria-label': gettext('Help'),
+          url: url_for('help.static', {
+            'filename': 'search_objects.html',
+          }),
+        },
+      }, {
+        text: gettext('Close'),
+        key: 27,
+        className: 'btn btn-secondary fa fa-lg fa-times pg-alertify-button',
+        'data-btn-name': 'cancel',
+      }],
+      // Set options for dialog
+      options: {
+        title: this.dialogTitle,
+        //disable both padding and overflow control.
+        padding: !1,
+        overflow: !1,
+        model: 0,
+        resizable: true,
+        maximizable: true,
+        pinnable: false,
+        closableByDimmer: false,
+        modal: false,
+      },
+    };
+  }
+
+  build() {
+    let tmpEle = document.createElement('div');
+    tmpEle.innerHTML = this.dialogContainerSelector;
+    let dialogContainer = tmpEle.firstChild;
+
+    // Append the container
+    this.elements.content.innerHTML = '';
+    this.elements.content.appendChild(dialogContainer);
+
+    this.createDialogDOM(dialogContainer);
+    this.alertify.pgDialogBuild.apply(this);
+
+    this.loader = dialogContainer.getElementsByClassName('pg-sp-container')[0];
+
+    this.searchBox = dialogContainer.querySelector('#txtGridSearch');
+    this.searchBtn = dialogContainer.querySelector('.btn-search');
+    this.typesSelect = dialogContainer.querySelector('.node-types');
+    this.searchResultContainer = dialogContainer.querySelector('.search-result-container');
+    this.searchResult = dialogContainer.querySelector('.search-result');
+    this.statusBar = dialogContainer.querySelector('.pg-prop-status-bar');
+
+    /* These two values are required to come out of grid when tab is
+     * pressed in the grid. Slickgrid does not allow any way to come out
+     */
+    this.nextToGrid = this.elements.footer.querySelector('.ajs-button');
+    this.prevToGrid = this.typesSelect;
+
+    /* init select2 */
+    this.setTypes([{
+      id: -1,
+      text: gettext('Loading...'),
+      value: null,
+    }], false);
+
+    /* on search box change */
+    this.searchBox.addEventListener('input', ()=>{
+      if(this.searchBoxVal().length >= 3) {
+        this.searchBtnEnabled(true);
+      } else {
+        this.searchBtnEnabled(false);
+      }
+    });
+
+    /* on enter key press */
+    this.searchBox.addEventListener('keypress', (e)=>{
+      if(e.keyCode == 13) {
+        e.stopPropagation();
+        if(this.searchBtnEnabled()) {
+          this.searchBtn.dispatchEvent(new Event('click'));
+        }
+      }
+    });
+
+    /* on search button click */
+    this.searchBtn.addEventListener('click', ()=>{
+      this.searchBtnEnabled(false);
+      this.setGridData([]);
+      this.showMessage(null);
+
+      this.setLoading(gettext('Searching....'));
+      axios.get(this.getBaseUrl('search'), {
+        params: {
+          text: this.searchBoxVal(),
+          type: this.typesVal(),
+        },
+      }).then((res)=>{
+        let grid_data = res.data.data.map((row)=>{
+          return this.finaliseData(row);
+        });
+
+        this.setGridData(grid_data);
+      }).catch((error)=>{
+        let errmsg = '';
+
+        if (error.response) {
+          errmsg = error.response.statusText;
+        } else if (error.request) {
+          errmsg = gettext('No response received');
+        } else {
+          errmsg = error.message;
+        }
+        this.showMessage(gettext('An unexpected occurred: %s', errmsg), true);
+        console.warn(error);
+      }).finally(()=>{
+        this.setLoading(null);
+        this.searchBtnEnabled(true);
+      });
+    });
+
+    this.set({
+      'onresized': this.onDialogResize.bind(this),
+      'onmaximized': this.onDialogResize.bind(this),
+      'onrestored': this.onDialogResize.bind(this),
+      'onshow': this.onDialogShow.bind(this),
+    });
+  }
+
+  prepare() {
+    let selectedTreeNode = this.getSelectedNode();
+    if (!this.getSelectedNodeData(selectedTreeNode)) {
+      return;
+    }
+
+    this.treeInfo = getTreeNodeHierarchyFromElement(this.pgBrowser, selectedTreeNode);
+    this.prepareDialog();
+    this.focusOnDialog(this);
+  }
+
+  callback(event) {
+    if (this.wasHelpButtonPressed(event)) {
+      event.cancel = true;
+      this.pgBrowser.showHelp(
+        event.button.element.name,
+        event.button.element.getAttribute('url'),
+        null,
+        null,
+      );
+      return;
+    }
+  }
+}
diff --git a/web/pgadmin/tools/search_objects/static/scss/_search_objects.scss b/web/pgadmin/tools/search_objects/static/scss/_search_objects.scss
new file mode 100644
index 000000000..920c53832
--- /dev/null
+++ b/web/pgadmin/tools/search_objects/static/scss/_search_objects.scss
@@ -0,0 +1,118 @@
+.search_objects_dialog {
+    height: 100%;
+
+    .object-other-info {
+        &:hover {
+            font-weight: bold;
+        }
+    }
+
+    .pref-dialog-link {
+        color: $color-fg !important;
+        text-decoration: underline !important;
+        cursor: pointer;
+    }
+
+    .search-result-container {
+        width: 100%;
+        height: 100%;
+        min-height: 0;
+    }
+
+    .node-types ~ .select2-container {
+        min-width: 100%;
+    }
+
+    .ui-widget {
+        font-family: $font-family-primary;
+        font-size: $font-size-base;
+
+        .slick-header.ui-state-default {
+            border: $table-border-width solid $table-border-color;
+            .slick-header-columns {
+                background: $table-bg;
+                color: $color-fg;
+                border-bottom: $panel-border;
+
+                .slick-header-column-sorted {
+                    font-style: unset;
+                }
+
+                .ui-state-default {
+                    background: $table-bg !important;
+                    color: $color-fg !important;
+                    padding: $table-header-cell-padding $table-cell-padding;
+                    border-right: $table-border-width solid $table-border-color;
+
+                    .slick-column-name {
+                        font-weight: bold;
+                    }
+
+                    .slick-sort-indicator {
+                        float: unset;
+                    }
+                }
+
+                .slick-header-sortable {
+                    cursor: pointer !important;
+
+                    .slick-sort-indicator-asc {
+                        background: none;
+                        border-top: none;
+                        border-right: 0.25rem solid transparent;
+                        border-bottom: 0.25rem solid $color-fg;
+                        border-left: 0.25rem solid transparent;
+                    }
+
+                    .slick-sort-indicator-desc {
+                        background: none;
+                        border-top: 0.25rem solid $color-fg;
+                        border-right: 0.25rem solid transparent;
+                        border-bottom: none;
+                        border-left: 0.25rem solid transparent;
+                    }
+                }
+            }
+        }
+        .ui-widget-content {
+            color: $color-fg;
+            &.slick-row {
+                &.object-muted {
+                    &.active, &.active:hover, &:hover, & {
+                        .slick-cell {
+                            color: $text-muted !important;
+                            cursor: default !important;
+                        }
+                    }
+                }
+
+                &.active, &.active:hover {
+                    .slick-cell {
+                        border-top: $table-border-width solid transparent !important;
+                        background-color: $tree-bg-selected !important;
+                        color: $tree-fg-selected !important;
+                    }
+                }
+
+                &:hover {
+                    cursor: pointer;
+                    .slick-cell {
+                        border-top: $table-border-width solid transparent !important;
+                        border-bottom: $table-border-width solid transparent !important;
+                        background-color: $tree-bg-hover !important;
+                        color: $tree-fg-hover !important;
+                        cursor: pointer !important;
+                    }
+                }
+            }
+        }
+    }
+
+
+    .pg-prop-status-bar {
+        position: absolute;
+        bottom: 0;
+        right: 0;
+        left: 0;
+    }
+}
diff --git a/web/pgadmin/tools/search_objects/templates/search_objects/sql/pg/10_plus/search.sql b/web/pgadmin/tools/search_objects/templates/search_objects/sql/pg/10_plus/search.sql
new file mode 100644
index 000000000..d00ca0d11
--- /dev/null
+++ b/web/pgadmin/tools/search_objects/templates/search_objects/sql/pg/10_plus/search.sql
@@ -0,0 +1,434 @@
+{% import 'catalog/pg/macros/catalogs.sql' as CATALOGS %}
+{% set all_obj = false %}
+{% if obj_type == 'all' or obj_type is none %}
+{% set all_obj = true %}
+{% endif %}
+SELECT obj_type, obj_name,
+    REPLACE(obj_path, '/'||sn.schema_name||'/', '/'||{{ CATALOGS.LABELS_SCHEMACOL('sn.schema_name', _) }}||'/') AS obj_path,
+    schema_name, show_node, other_info,
+    CASE
+        WHEN {{ CATALOGS.IS_CATALOG_SCHEMA('sn.schema_name') }} THEN
+            CASE WHEN {{ CATALOGS.DB_SUPPORT_SCHEMACOL('sn.schema_name') }} THEN 'D' ELSE 'O' END
+        ELSE 'N'
+    END AS catalog_level
+FROM (
+{% if all_obj or obj_type in ['sequence', 'view', 'mview'] %}
+    SELECT
+    CASE
+        WHEN c.relkind = 'S' THEN 'sequence'
+        WHEN c.relkind = 'v' THEN 'view'
+        WHEN c.relkind = 'm' THEN 'mview'
+        ELSE 'should not happen'
+    END::text AS obj_type, c.relname AS obj_name,
+    ':schema.'|| n.oid || ':/' || n.nspname || '/' ||
+    CASE
+        WHEN c.relkind = 'S' THEN ':sequence.'
+        WHEN c.relkind = 'v' THEN ':view.'
+        WHEN c.relkind = 'm' THEN ':mview.'
+        ELSE 'should not happen'
+    END || c.oid ||':/' || c.relname AS obj_path, n.nspname AS schema_name,
+    CASE
+        WHEN c.relkind = 'S' THEN {{ show_node_prefs['sequence'] }}
+        WHEN c.relkind = 'v' THEN {{ show_node_prefs['view'] }}
+        WHEN c.relkind = 'm' THEN {{ show_node_prefs['mview'] }}
+        ELSE False
+    END AS show_node, NULL AS other_info
+    FROM pg_class c
+    LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
+    {% if all_obj %}
+    WHERE c.relkind in ('S','v','m')
+    {% elif obj_type == 'sequence' %}
+    WHERE c.relkind  = 'S'
+    {% elif obj_type == 'view' %}
+    WHERE c.relkind  = 'v'
+    {% elif obj_type == 'mview' %}
+    WHERE c.relkind  = 'm'
+    {% endif %}
+    AND {{ CATALOGS.DB_SUPPORT('n') }}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['table', 'partition'] %}
+    SELECT CASE WHEN c.relispartition THEN 'partition' ELSE 'table' END::text AS obj_type, c.relname AS obj_name,
+    ':schema.'|| n.oid || ':/' || n.nspname || '/' || (
+		WITH RECURSIVE table_path_data as (
+			select c.oid as oid, 0 as height,
+				CASE c.relispartition WHEN true THEN ':partition.' ELSE ':table.' END || c.oid || ':/' || c.relname as path
+			union
+			select rel.oid, pt.height+1 as height,
+				CASE rel.relispartition WHEN true THEN ':partition.' ELSE ':table.' END
+				|| rel.oid || ':/' || rel.relname || '/' || pt.path as path
+			from pg_class rel JOIN pg_namespace nsp ON rel.relnamespace = nsp.oid
+			join pg_inherits inh ON inh.inhparent = rel.oid
+			join table_path_data pt ON inh.inhrelid = pt.oid
+		)
+		select path from table_path_data order by height desc limit 1
+	) obj_path, n.nspname AS schema_name,
+	CASE WHEN c.relispartition THEN {{ show_node_prefs['partition'] }}
+	    ELSE {{ show_node_prefs['table'] }} END AS show_node,
+    NULL AS other_info
+    FROM pg_class c
+    LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
+    WHERE c.relkind in ('p','r')
+    {% if obj_type == 'table' %}
+    AND NOT c.relispartition
+    {% elif obj_type == 'partition' %}
+    AND c.relispartition
+    {% endif %}
+    AND {{ CATALOGS.DB_SUPPORT('n') }}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['index'] %}
+    SELECT 'index'::text AS obj_type, cls.relname AS obj_name,
+    ':schema.'|| n.oid || ':/' || n.nspname || '/:table.'|| tab.oid ||':/' || tab.relname || '/:index.'|| cls.oid ||':/' || cls.relname AS obj_path, n.nspname AS schema_name,
+    {{ show_node_prefs['index'] }} AS show_node, NULL AS other_info
+    FROM pg_index idx
+    JOIN pg_class cls ON cls.oid=indexrelid
+    JOIN pg_class tab ON tab.oid=indrelid
+    JOIN pg_namespace n ON n.oid=tab.relnamespace
+    LEFT JOIN pg_depend dep ON (dep.classid = cls.tableoid AND dep.objid = cls.oid AND dep.refobjsubid = '0' AND dep.refclassid=(SELECT oid FROM pg_class WHERE relname='pg_constraint') AND dep.deptype='i')
+    LEFT OUTER JOIN pg_constraint con ON (con.tableoid = dep.refclassid AND con.oid = dep.refobjid)
+    LEFT OUTER JOIN pg_description des ON des.objoid=cls.oid
+    LEFT OUTER JOIN pg_description desp ON (desp.objoid=con.oid AND desp.objsubid = 0)
+    WHERE contype IS NULL
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['trigger_function', 'function'] %}
+    SELECT
+        CASE
+        WHEN t.typname IN ('trigger', 'event_trigger') THEN 'trigger_function'
+        ELSE 'function' END::text AS obj_type, p.proname AS obj_name,
+    ':schema.'|| n.oid || ':/' || n.nspname || '/' || case when t.typname = 'trigger' then ':trigger_function.' else ':function.' end || p.oid ||':/' || p.proname AS obj_path, n.nspname AS schema_name,
+    CASE WHEN t.typname IN ('trigger', 'event_trigger') THEN {{ show_node_prefs['trigger_function'] }} ELSE {{ show_node_prefs['function'] }} END AS show_node,
+    pg_catalog.pg_get_function_identity_arguments(p.oid) AS other_info
+    from pg_proc p
+    left join pg_namespace n on p.pronamespace = n.oid
+    left join pg_type t on p.prorettype = t.oid
+    WHERE ({{ CATALOGS.DB_SUPPORT('n') }})
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['event_trigger'] %}
+    select 'event_trigger'::text AS obj_type, evtname AS obj_name, ':event_trigger.'||oid||':/' || evtname AS obj_path, ''::text AS schema_name,
+    {{ show_node_prefs['index'] }} AS show_node, NULL AS other_info from pg_event_trigger
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['schema'] %}
+    select 'schema'::text AS obj_type, n.nspname AS obj_name,
+    ':schema.'||n.oid||':/' || n.nspname as obj_path, n.nspname AS schema_name,
+    {{ show_node_prefs['schema'] }} AS show_node, NULL AS other_info from pg_namespace n
+    where {{ CATALOGS.DB_SUPPORT('n') }}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['column'] %}
+    select 'column'::text AS obj_type, a.attname AS obj_name,
+    ':schema.'||n.oid||':/' || n.nspname || '/' ||
+    case
+        WHEN t.relkind = 'r' THEN ':table.'
+        WHEN t.relkind = 'v' THEN ':view.'
+        WHEN t.relkind = 'm' THEN ':mview.'
+        else 'should not happen'
+    end || t.oid || ':/' || t.relname || '/:column.'|| a.attnum ||':/' || a.attname AS obj_path, n.nspname AS schema_name,
+    {{ show_node_prefs['column'] }} AS show_node, NULL AS other_info
+    from pg_attribute a
+    inner join pg_class t on a.attrelid = t.oid and t.relkind in ('r','v','m')
+    left join pg_namespace n on t.relnamespace = n.oid where a.attnum > 0
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['constraints', 'check_constraint', 'foreign_key', 'primary_key', 'unique_constraint', 'exclusion_constraint'] %}
+    SELECT
+    CASE
+        WHEN c.contype = 'c' THEN  'check_constraint'
+        WHEN c.contype = 'f' THEN  'foreign_key'
+        WHEN c.contype = 'p' THEN  'primary_key'
+        WHEN c.contype = 'u' THEN  'unique_constraint'
+        WHEN c.contype = 'x' THEN  'exclusion_constraint'
+    END::text AS obj_type,
+    case when tf.relname is null then c.conname else c.conname || ' -> ' || tf.relname end AS obj_name,
+    ':schema.'||n.oid||':/' || n.nspname||'/'||
+    (
+		WITH RECURSIVE table_path_data as (
+			select t.oid as oid, 0 as height,
+				CASE t.relispartition WHEN true THEN ':partition.' ELSE ':table.' END || t.oid || ':/' || t.relname as path
+			union
+			select rel.oid, pt.height+1 as height,
+				CASE rel.relispartition WHEN true THEN ':partition.' ELSE ':table.' END
+				|| rel.oid || ':/' || rel.relname || '/' || pt.path as path
+			from pg_class rel JOIN pg_namespace nsp ON rel.relnamespace = nsp.oid
+			join pg_inherits inh ON inh.inhparent = rel.oid
+			join table_path_data pt ON inh.inhrelid = pt.oid
+		)
+		select path from table_path_data order by height desc limit 1
+	) ||
+    CASE
+        WHEN c.contype = 'c' THEN  '/:check_constraint.' ||c.oid
+        WHEN c.contype = 'f' THEN  '/:foreign_key.' ||c.conindid
+        WHEN c.contype = 'p' THEN  '/:primary_key.' ||c.conindid
+        WHEN c.contype = 'u' THEN  '/:unique_constraint.' ||c.conindid
+        WHEN c.contype = 'x' THEN  '/:exclusion_constraint.' ||c.conindid
+    END ||':/'|| case when tf.relname is null then c.conname else c.conname || ' -> ' || tf.relname end AS obj_path, n.nspname AS schema_name,
+    {{ show_node_prefs['constraints'] }} AS show_node, NULL AS other_info
+    from pg_constraint c
+    left join pg_class t on c.conrelid = t.oid
+    left join pg_class tf on c.confrelid = tf.oid
+    left join pg_namespace n on t.relnamespace = n.oid
+    where c.contypid = 0
+    {% if obj_type == 'check_constraint' %}
+    AND c.contype = 'c'
+    {% elif obj_type == 'foreign_key' %}
+    AND c.contype = 'f'
+    {% elif obj_type == 'primary_key' %}
+    AND c.contype = 'p'
+    {% elif obj_type == 'unique_constraint' %}
+    AND c.contype = 'u'
+    {% elif obj_type == 'exclusion_constraint' %}
+    AND c.contype = 'x'
+    {% else %}
+    AND c.contype IN  ('c', 'f', 'p', 'u', 'x')
+    {% endif %}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['rule'] %}
+    select 'rule'::text AS obj_type, r.rulename AS obj_name, ':schema.'||n.oid||':/' || n.nspname|| '/' ||
+            case
+                when t.relkind = 'v' then ':view.'
+                when t.relkind = 'm' then ':mview.'
+                WHEN t.relkind in ('r', 'p') THEN
+                    (
+                        WITH RECURSIVE table_path_data as (
+                            select t.oid as oid, 0 as height,
+                                CASE t.relispartition WHEN true THEN ':partition.' ELSE ':table.' END || t.oid || ':/' || t.relname as path
+                            union
+                            select rel.oid, pt.height+1 as height,
+                                CASE rel.relispartition WHEN true THEN ':partition.' ELSE ':table.' END
+                                || rel.oid || ':/' || rel.relname || '/' || pt.path as path
+                            from pg_class rel JOIN pg_namespace nsp ON rel.relnamespace = nsp.oid
+                            join pg_inherits inh ON inh.inhparent = rel.oid
+                            join table_path_data pt ON inh.inhrelid = pt.oid
+                        )
+                        select path from table_path_data order by height desc limit 1
+                    )
+            end
+            ||'/:rule.'||r.oid||':/'|| r.rulename AS obj_path,
+            n.nspname AS schema_name,
+            {{ show_node_prefs['rule'] }} AS show_node, NULL AS other_info
+            from pg_rewrite r
+    left join pg_class t on r.ev_class = t.oid
+    left join pg_namespace n on t.relnamespace = n.oid
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['trigger'] %}
+    select 'trigger'::text AS obj_type, tr.tgname AS obj_name, ':schema.'||n.oid||':/' || n.nspname|| '/' ||
+        case
+            when t.relkind = 'v' then ':view.'
+            when t.relkind = 'm' then ':mview.'
+            WHEN t.relkind in ('r', 'p') THEN
+            (
+                WITH RECURSIVE table_path_data as (
+                    select t.oid as oid, 0 as height,
+                        CASE t.relispartition WHEN true THEN ':partition.' ELSE ':table.' END || t.oid || ':/' || t.relname as path
+                    union
+                    select rel.oid, pt.height+1 as height,
+                        CASE rel.relispartition WHEN true THEN ':partition.' ELSE ':table.' END
+                        || rel.oid || ':/' || rel.relname || '/' || pt.path as path
+                    from pg_class rel JOIN pg_namespace nsp ON rel.relnamespace = nsp.oid
+                    join pg_inherits inh ON inh.inhparent = rel.oid
+                    join table_path_data pt ON inh.inhrelid = pt.oid
+                )
+                select path from table_path_data order by height desc limit 1
+            )
+        end || '/:trigger.'|| tr.oid || ':/' || tr.tgname AS obj_path, n.nspname AS schema_name,
+        {{ show_node_prefs['trigger'] }} AS show_node, NULL AS other_info
+        from pg_trigger tr
+    left join pg_class t on tr.tgrelid = t.oid
+    left join pg_namespace n on t.relnamespace = n.oid
+    where tr.tgisinternal = false
+    and {{ CATALOGS.DB_SUPPORT('n') }}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['type'] %}
+    SELECT 'type'::text AS obj_type, t.typname AS obj_name, ':schema.'||n.oid||':/' || n.nspname ||
+        '/:type.'|| t.oid ||':/' || t.typname AS obj_path, n.nspname AS schema_name,
+        {{ show_node_prefs['type'] }} AS show_node, NULL AS other_info
+    FROM pg_type t
+    LEFT OUTER JOIN pg_type e ON e.oid=t.typelem
+    LEFT OUTER JOIN pg_class ct ON ct.oid=t.typrelid AND ct.relkind <> 'c'
+    LEFT OUTER JOIN pg_namespace n on t.typnamespace = n.oid
+    WHERE t.typtype != 'd' AND t.typname NOT LIKE E'\\_%'
+    {% if not show_system_objects %}
+        AND ct.oid is NULL
+    {% endif %}
+    AND {{ CATALOGS.DB_SUPPORT('n') }}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['cast'] %}
+    SELECT 'cast'::text AS obj_type, format_type(st.oid,NULL) ||'->'|| format_type(tt.oid,tt.typtypmod) AS obj_name,
+    ':cast.'||ca.oid||':/' || format_type(st.oid,NULL) ||'->'|| format_type(tt.oid,tt.typtypmod) AS obj_path, ''::text AS schema_name,
+    {{ show_node_prefs['cast'] }} AS show_node, NULL AS other_info
+    FROM pg_cast ca
+    JOIN pg_type st ON st.oid=castsource
+    JOIN pg_type tt ON tt.oid=casttarget
+    {% if not show_system_objects %}
+    WHERE ca.oid > {{last_system_oid}}::OID
+    {% endif %}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['language'] %}
+    SELECT 'language'::text AS obj_type, lanname AS obj_name, ':language.'||lan.oid||':/' || lanname AS obj_path, ''::text AS schema_name,
+    {{ show_node_prefs['language'] }} AS show_node, NULL AS other_info
+    FROM pg_language lan
+    WHERE lanispl IS TRUE
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['fts_configuration'] %}
+    SELECT 'fts_configuration'::text AS obj_type, cfg.cfgname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:fts_configuration.'||cfg.oid||':/' || cfg.cfgname AS obj_path, n.nspname AS schema_name,
+    {{ show_node_prefs['fts_configuration'] }} AS show_node, NULL AS other_info
+    FROM pg_ts_config cfg
+    left join pg_namespace n on cfg.cfgnamespace = n.oid
+    WHERE {{ CATALOGS.DB_SUPPORT('n') }}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['fts_dictionary'] %}
+    SELECT 'fts_dictionary' AS obj_type, dict.dictname AS obj_name, ':schema.'||ns.oid||':/' || ns.nspname || '/:fts_dictionary.'||dict.oid||':/' || dict.dictname AS obj_path, ns.nspname AS schema_name,
+    {{ show_node_prefs['fts_dictionary'] }} AS show_node, NULL AS other_info
+    FROM pg_ts_dict dict
+    left join pg_namespace ns on dict.dictnamespace = ns.oid
+    WHERE {{ CATALOGS.DB_SUPPORT('ns') }}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['fts_parser'] %}
+    SELECT 'fts_parser' AS obj_type, prs.prsname AS obj_name, ':schema.'||ns.oid||':/' || ns.nspname || '/:fts_parser.'||prs.oid||':/' || prs.prsname AS obj_path, ns.nspname AS schema_name,
+    {{ show_node_prefs['fts_parser'] }} AS show_node, NULL AS other_info
+    FROM pg_ts_parser prs
+    left join pg_namespace ns on prs.prsnamespace = ns.oid
+    WHERE {{ CATALOGS.DB_SUPPORT('ns') }}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['fts_template'] %}
+    SELECT 'fts_template' AS obj_type, tmpl.tmplname AS obj_name, ':schema.'||ns.oid||':/' || ns.nspname || '/:fts_template.'||tmpl.oid||':/' || tmpl.tmplname AS obj_path, ns.nspname AS schema_name,
+    {{ show_node_prefs['fts_template'] }} AS show_node, NULL AS other_info
+    FROM pg_ts_template tmpl
+    left join pg_namespace ns on tmpl.tmplnamespace = ns.oid
+    AND {{ CATALOGS.DB_SUPPORT('ns') }}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['domain'] %}
+    select 'domain' AS obj_type, t.typname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:domain.'||t.oid||':/' || t.typname AS obj_path, n.nspname AS schema_name,
+    {{ show_node_prefs['domain'] }} AS show_node, NULL AS other_info
+    from pg_type t
+    inner join pg_namespace n on t.typnamespace = n.oid
+    where t.typtype = 'd'
+    AND {{ CATALOGS.DB_SUPPORT('n') }}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['domain_constraints'] %}
+    SELECT 'domain_constraints' AS obj_type,
+        c.conname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:domain.'||t.oid||':/' || t.typname || '/:domain_constraints.'||c.oid||':/' || c.conname AS obj_path,
+        n.nspname AS schema_name,
+        {{ show_node_prefs['domain_constraints'] }} AS show_node, NULL AS other_info
+    FROM pg_constraint c JOIN pg_type t
+    ON t.oid=contypid JOIN pg_namespace n
+    ON n.oid=t.typnamespace
+    WHERE t.typtype = 'd'
+    AND {{ CATALOGS.DB_SUPPORT('n') }}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['foreign_data_wrapper'] %}
+    select 'foreign_data_wrapper' AS obj_type, fdwname AS obj_name, ':foreign_data_wrapper.'||oid||':/' || fdwname AS obj_path, ''::text AS schema_name,
+    {{ show_node_prefs['foreign_data_wrapper'] }} AS show_node, NULL AS other_info
+    from pg_foreign_data_wrapper
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['foreign_server'] %}
+    select 'foreign_server' AS obj_type, sr.srvname AS obj_name, ':foreign_data_wrapper.'||fdw.oid||':/' || fdw.fdwname || '/:foreign_server.'||sr.oid||':/' || sr.srvname AS obj_path, ''::text AS schema_name,
+    {{ show_node_prefs['foreign_server'] }} AS show_node, NULL AS other_info
+    from pg_foreign_server sr
+    inner join pg_foreign_data_wrapper fdw on sr.srvfdw = fdw.oid
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['user_mapping'] %}
+    select 'user_mapping' AS obj_type, ro.rolname AS obj_name, ':foreign_data_wrapper.'||fdw.oid||':/' || fdw.fdwname || '/:foreign_server.'||sr.oid||':/' || sr.srvname || '/:user_mapping.'||ro.oid||':/' || ro.rolname AS obj_path, ''::text AS schema_name,
+    {{ show_node_prefs['user_mapping'] }} AS show_node, NULL AS other_info
+    from pg_user_mapping um
+    inner join pg_roles ro on um.umuser = ro.oid
+    inner join pg_foreign_server sr on um.umserver = sr.oid
+    inner join pg_foreign_data_wrapper fdw on sr.srvfdw = fdw.oid
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['foreign_table'] %}
+    select 'foreign_table' AS obj_type, c.relname AS obj_name, ':schema.'||ns.oid||':/' || ns.nspname || '/:foreign_table.'||c.oid||':/' || c.relname AS obj_path, ns.nspname AS schema_name,
+    {{ show_node_prefs['foreign_table'] }} AS show_node, NULL AS other_info
+    from pg_foreign_table ft
+    inner join pg_class c on ft.ftrelid = c.oid
+    inner join pg_namespace ns on c.relnamespace = ns.oid
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['extension'] %}
+    select 'extension' AS obj_type, x.extname AS obj_name, ':extension.'||x.oid||':/' || x.extname AS obj_path, ''::text AS schema_name,
+    {{ show_node_prefs['extension'] }} AS show_node, NULL AS other_info
+    FROM pg_extension x
+    JOIN pg_namespace n on x.extnamespace=n.oid
+    join pg_available_extensions() e(name, default_version, comment) ON x.extname=e.name
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['collation'] %}
+    SELECT 'collation' AS obj_type, c.collname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:collation.'||c.oid||':/' || c.collname AS obj_path, n.nspname AS schema_name,
+    {{ show_node_prefs['collation'] }} AS show_node, NULL AS other_info
+    FROM pg_collation c
+    JOIN pg_namespace n ON n.oid=c.collnamespace
+    WHERE {{ CATALOGS.DB_SUPPORT('n') }}
+{% endif %}
+
+) sn
+where lower(sn.obj_name) like '%{{ search_text }}%'
+{% if not show_system_objects %}
+AND NOT ({{ CATALOGS.IS_CATALOG_SCHEMA('sn.schema_name') }})
+AND (sn.schema_name IS NOT NULL AND sn.schema_name NOT LIKE 'pg\_%')
+{% endif %}
+ORDER BY 1, 2, 3
diff --git a/web/pgadmin/tools/search_objects/templates/search_objects/sql/pg/11_plus/search.sql b/web/pgadmin/tools/search_objects/templates/search_objects/sql/pg/11_plus/search.sql
new file mode 100644
index 000000000..bd2f94d9c
--- /dev/null
+++ b/web/pgadmin/tools/search_objects/templates/search_objects/sql/pg/11_plus/search.sql
@@ -0,0 +1,451 @@
+{% import 'catalog/pg/macros/catalogs.sql' as CATALOGS %}
+{% set all_obj = false %}
+{% if obj_type == 'all' or obj_type is none %}
+{% set all_obj = true %}
+{% endif %}
+SELECT obj_type, obj_name,
+    REPLACE(obj_path, '/'||sn.schema_name||'/', '/'||{{ CATALOGS.LABELS_SCHEMACOL('sn.schema_name', _) }}||'/') AS obj_path,
+    schema_name, show_node, other_info,
+    CASE
+        WHEN {{ CATALOGS.IS_CATALOG_SCHEMA('sn.schema_name') }} THEN
+            CASE WHEN {{ CATALOGS.DB_SUPPORT_SCHEMACOL('sn.schema_name') }} THEN 'D' ELSE 'O' END
+        ELSE 'N'
+    END AS catalog_level
+FROM (
+{% if all_obj or obj_type in ['sequence', 'view', 'mview'] %}
+    SELECT
+    CASE
+        WHEN c.relkind = 'S' THEN 'sequence'
+        WHEN c.relkind = 'v' THEN 'view'
+        WHEN c.relkind = 'm' THEN 'mview'
+        ELSE 'should not happen'
+    END::text AS obj_type, c.relname AS obj_name,
+    ':schema.'|| n.oid || ':/' || n.nspname || '/' ||
+    CASE
+        WHEN c.relkind = 'S' THEN ':sequence.'
+        WHEN c.relkind = 'v' THEN ':view.'
+        WHEN c.relkind = 'm' THEN ':mview.'
+        ELSE 'should not happen'
+    END || c.oid ||':/' || c.relname AS obj_path, n.nspname AS schema_name,
+    CASE
+        WHEN c.relkind = 'S' THEN {{ show_node_prefs['sequence'] }}
+        WHEN c.relkind = 'v' THEN {{ show_node_prefs['view'] }}
+        WHEN c.relkind = 'm' THEN {{ show_node_prefs['mview'] }}
+        ELSE False
+    END AS show_node, NULL AS other_info
+    FROM pg_class c
+    LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
+    {% if all_obj %}
+    WHERE c.relkind in ('S','v','m')
+    {% elif obj_type == 'sequence' %}
+    WHERE c.relkind  = 'S'
+    {% elif obj_type == 'view' %}
+    WHERE c.relkind  = 'v'
+    {% elif obj_type == 'mview' %}
+    WHERE c.relkind  = 'm'
+    {% endif %}
+    AND {{ CATALOGS.DB_SUPPORT('n') }}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['table', 'partition'] %}
+    SELECT CASE WHEN c.relispartition THEN 'partition' ELSE 'table' END::text AS obj_type, c.relname AS obj_name,
+    ':schema.'|| n.oid || ':/' || n.nspname || '/' || (
+		WITH RECURSIVE table_path_data as (
+			select c.oid as oid, 0 as height,
+				CASE c.relispartition WHEN true THEN ':partition.' ELSE ':table.' END || c.oid || ':/' || c.relname as path
+			union
+			select rel.oid, pt.height+1 as height,
+				CASE rel.relispartition WHEN true THEN ':partition.' ELSE ':table.' END
+				|| rel.oid || ':/' || rel.relname || '/' || pt.path as path
+			from pg_class rel JOIN pg_namespace nsp ON rel.relnamespace = nsp.oid
+			join pg_inherits inh ON inh.inhparent = rel.oid
+			join table_path_data pt ON inh.inhrelid = pt.oid
+		)
+		select path from table_path_data order by height desc limit 1
+	) obj_path, n.nspname AS schema_name,
+	CASE WHEN c.relispartition THEN {{ show_node_prefs['partition'] }}
+	    ELSE {{ show_node_prefs['table'] }} END AS show_node,
+    NULL AS other_info
+    FROM pg_class c
+    LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
+    WHERE c.relkind in ('p','r')
+    {% if obj_type == 'table' %}
+    AND NOT c.relispartition
+    {% elif obj_type == 'partition' %}
+    AND c.relispartition
+    {% endif %}
+    AND {{ CATALOGS.DB_SUPPORT('n') }}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['index'] %}
+    SELECT 'index'::text AS obj_type, cls.relname AS obj_name,
+    ':schema.'|| n.oid || ':/' || n.nspname || '/:table.'|| tab.oid ||':/' || tab.relname || '/:index.'|| cls.oid ||':/' || cls.relname AS obj_path, n.nspname AS schema_name,
+    {{ show_node_prefs['index'] }} AS show_node, NULL AS other_info
+    FROM pg_index idx
+    JOIN pg_class cls ON cls.oid=indexrelid
+    JOIN pg_class tab ON tab.oid=indrelid
+    JOIN pg_namespace n ON n.oid=tab.relnamespace
+    LEFT JOIN pg_depend dep ON (dep.classid = cls.tableoid AND dep.objid = cls.oid AND dep.refobjsubid = '0' AND dep.refclassid=(SELECT oid FROM pg_class WHERE relname='pg_constraint') AND dep.deptype='i')
+    LEFT OUTER JOIN pg_constraint con ON (con.tableoid = dep.refclassid AND con.oid = dep.refobjid)
+    LEFT OUTER JOIN pg_description des ON des.objoid=cls.oid
+    LEFT OUTER JOIN pg_description desp ON (desp.objoid=con.oid AND desp.objsubid = 0)
+    WHERE contype IS NULL
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['trigger_function', 'function', 'procedure'] %}
+    SELECT
+        CASE
+            WHEN t.typname IN ('trigger', 'event_trigger') THEN 'trigger_function'
+            WHEN p.prokind = 'p' THEN 'procedure'
+            ELSE 'function'
+        END::text AS obj_type, p.proname AS obj_name,
+        ':schema.'|| n.oid || ':/' || n.nspname || '/' ||
+        CASE
+            WHEN t.typname IN ('trigger', 'event_trigger') THEN ':trigger_function.'
+            WHEN p.prokind = 'p' THEN ':procedure.'
+            ELSE ':function.'
+        END || p.oid ||':/' || p.proname AS obj_path, n.nspname AS schema_name,
+        CASE
+            WHEN t.typname IN ('trigger', 'event_trigger') THEN {{ show_node_prefs['trigger_function'] }}
+            WHEN p.prokind = 'p' THEN {{ show_node_prefs['procedure'] }}
+            ELSE {{ show_node_prefs['function'] }}
+        END AS show_node,
+        pg_catalog.pg_get_function_identity_arguments(p.oid) AS other_info
+    from pg_proc p join pg_namespace n
+    on p.pronamespace = n.oid join pg_type t
+    on p.prorettype = t.oid join pg_language lng
+    ON lng.oid=p.prolang
+    WHERE p.prokind IN ('f', 'w', 'p')
+    AND CASE
+        WHEN t.typname IN ('trigger', 'event_trigger') THEN lng.lanname NOT IN ('edbspl', 'sql', 'internal')
+        ELSE true
+        END
+    AND ({{ CATALOGS.DB_SUPPORT('n') }})
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['event_trigger'] %}
+    select 'event_trigger'::text AS obj_type, evtname AS obj_name, ':event_trigger.'||oid||':/' || evtname AS obj_path, ''::text AS schema_name,
+    {{ show_node_prefs['index'] }} AS show_node, NULL AS other_info from pg_event_trigger
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['schema'] %}
+    select 'schema'::text AS obj_type, n.nspname AS obj_name,
+    ':schema.'||n.oid||':/' || n.nspname as obj_path, n.nspname AS schema_name,
+    {{ show_node_prefs['schema'] }} AS show_node, NULL AS other_info from pg_namespace n
+    where {{ CATALOGS.DB_SUPPORT('n') }}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['column'] %}
+    select 'column'::text AS obj_type, a.attname AS obj_name,
+    ':schema.'||n.oid||':/' || n.nspname || '/' ||
+    case
+        WHEN t.relkind = 'r' THEN ':table.'
+        WHEN t.relkind = 'v' THEN ':view.'
+        WHEN t.relkind = 'm' THEN ':mview.'
+        else 'should not happen'
+    end || t.oid || ':/' || t.relname || '/:column.'|| a.attnum ||':/' || a.attname AS obj_path, n.nspname AS schema_name,
+    {{ show_node_prefs['column'] }} AS show_node, NULL AS other_info
+    from pg_attribute a
+    inner join pg_class t on a.attrelid = t.oid and t.relkind in ('r','v','m')
+    left join pg_namespace n on t.relnamespace = n.oid where a.attnum > 0
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['constraints', 'check_constraint', 'foreign_key', 'primary_key', 'unique_constraint', 'exclusion_constraint'] %}
+    SELECT
+    CASE
+        WHEN c.contype = 'c' THEN  'check_constraint'
+        WHEN c.contype = 'f' THEN  'foreign_key'
+        WHEN c.contype = 'p' THEN  'primary_key'
+        WHEN c.contype = 'u' THEN  'unique_constraint'
+        WHEN c.contype = 'x' THEN  'exclusion_constraint'
+    END::text AS obj_type,
+    case when tf.relname is null then c.conname else c.conname || ' -> ' || tf.relname end AS obj_name,
+    ':schema.'||n.oid||':/' || n.nspname||'/'||
+    (
+		WITH RECURSIVE table_path_data as (
+			select t.oid as oid, 0 as height,
+				CASE t.relispartition WHEN true THEN ':partition.' ELSE ':table.' END || t.oid || ':/' || t.relname as path
+			union
+			select rel.oid, pt.height+1 as height,
+				CASE rel.relispartition WHEN true THEN ':partition.' ELSE ':table.' END
+				|| rel.oid || ':/' || rel.relname || '/' || pt.path as path
+			from pg_class rel JOIN pg_namespace nsp ON rel.relnamespace = nsp.oid
+			join pg_inherits inh ON inh.inhparent = rel.oid
+			join table_path_data pt ON inh.inhrelid = pt.oid
+		)
+		select path from table_path_data order by height desc limit 1
+	) ||
+    CASE
+        WHEN c.contype = 'c' THEN  '/:check_constraint.' ||c.oid
+        WHEN c.contype = 'f' THEN  '/:foreign_key.' ||c.conindid
+        WHEN c.contype = 'p' THEN  '/:primary_key.' ||c.conindid
+        WHEN c.contype = 'u' THEN  '/:unique_constraint.' ||c.conindid
+        WHEN c.contype = 'x' THEN  '/:exclusion_constraint.' ||c.conindid
+    END ||':/'|| case when tf.relname is null then c.conname else c.conname || ' -> ' || tf.relname end AS obj_path, n.nspname AS schema_name,
+    {{ show_node_prefs['constraints'] }} AS show_node, NULL AS other_info
+    from pg_constraint c
+    left join pg_class t on c.conrelid = t.oid
+    left join pg_class tf on c.confrelid = tf.oid
+    left join pg_namespace n on t.relnamespace = n.oid
+    where c.contypid = 0
+    {% if obj_type == 'check_constraint' %}
+    AND c.contype = 'c'
+    {% elif obj_type == 'foreign_key' %}
+    AND c.contype = 'f'
+    {% elif obj_type == 'primary_key' %}
+    AND c.contype = 'p'
+    {% elif obj_type == 'unique_constraint' %}
+    AND c.contype = 'u'
+    {% elif obj_type == 'exclusion_constraint' %}
+    AND c.contype = 'x'
+    {% else %}
+    AND c.contype IN  ('c', 'f', 'p', 'u', 'x')
+    {% endif %}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['rule'] %}
+    select 'rule'::text AS obj_type, r.rulename AS obj_name, ':schema.'||n.oid||':/' || n.nspname|| '/' ||
+            case
+                when t.relkind = 'v' then ':view.'
+                when t.relkind = 'm' then ':mview.'
+                WHEN t.relkind in ('r', 'p') THEN
+                    (
+                        WITH RECURSIVE table_path_data as (
+                            select t.oid as oid, 0 as height,
+                                CASE t.relispartition WHEN true THEN ':partition.' ELSE ':table.' END || t.oid || ':/' || t.relname as path
+                            union
+                            select rel.oid, pt.height+1 as height,
+                                CASE rel.relispartition WHEN true THEN ':partition.' ELSE ':table.' END
+                                || rel.oid || ':/' || rel.relname || '/' || pt.path as path
+                            from pg_class rel JOIN pg_namespace nsp ON rel.relnamespace = nsp.oid
+                            join pg_inherits inh ON inh.inhparent = rel.oid
+                            join table_path_data pt ON inh.inhrelid = pt.oid
+                        )
+                        select path from table_path_data order by height desc limit 1
+                    )
+            end
+            ||'/:rule.'||r.oid||':/'|| r.rulename AS obj_path,
+            n.nspname AS schema_name,
+            {{ show_node_prefs['rule'] }} AS show_node, NULL AS other_info
+            from pg_rewrite r
+    left join pg_class t on r.ev_class = t.oid
+    left join pg_namespace n on t.relnamespace = n.oid
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['trigger'] %}
+    select 'trigger'::text AS obj_type, tr.tgname AS obj_name, ':schema.'||n.oid||':/' || n.nspname|| '/' ||
+        case
+            when t.relkind = 'v' then ':view.'
+            when t.relkind = 'm' then ':mview.'
+            WHEN t.relkind in ('r', 'p') THEN
+            (
+                WITH RECURSIVE table_path_data as (
+                    select t.oid as oid, 0 as height,
+                        CASE t.relispartition WHEN true THEN ':partition.' ELSE ':table.' END || t.oid || ':/' || t.relname as path
+                    union
+                    select rel.oid, pt.height+1 as height,
+                        CASE rel.relispartition WHEN true THEN ':partition.' ELSE ':table.' END
+                        || rel.oid || ':/' || rel.relname || '/' || pt.path as path
+                    from pg_class rel JOIN pg_namespace nsp ON rel.relnamespace = nsp.oid
+                    join pg_inherits inh ON inh.inhparent = rel.oid
+                    join table_path_data pt ON inh.inhrelid = pt.oid
+                )
+                select path from table_path_data order by height desc limit 1
+            )
+        end || '/:trigger.'|| tr.oid || ':/' || tr.tgname AS obj_path, n.nspname AS schema_name,
+        {{ show_node_prefs['trigger'] }} AS show_node, NULL AS other_info
+        from pg_trigger tr
+    left join pg_class t on tr.tgrelid = t.oid
+    left join pg_namespace n on t.relnamespace = n.oid
+    where tr.tgisinternal = false
+    and {{ CATALOGS.DB_SUPPORT('n') }}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['type'] %}
+    SELECT 'type'::text AS obj_type, t.typname AS obj_name, ':schema.'||n.oid||':/' || n.nspname ||
+        '/:type.'|| t.oid ||':/' || t.typname AS obj_path, n.nspname AS schema_name,
+        {{ show_node_prefs['type'] }} AS show_node, NULL AS other_info
+    FROM pg_type t
+    LEFT OUTER JOIN pg_type e ON e.oid=t.typelem
+    LEFT OUTER JOIN pg_class ct ON ct.oid=t.typrelid AND ct.relkind <> 'c'
+    LEFT OUTER JOIN pg_namespace n on t.typnamespace = n.oid
+    WHERE t.typtype != 'd' AND t.typname NOT LIKE E'\\_%'
+    {% if not show_system_objects %}
+        AND ct.oid is NULL
+    {% endif %}
+    AND {{ CATALOGS.DB_SUPPORT('n') }}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['cast'] %}
+    SELECT 'cast'::text AS obj_type, format_type(st.oid,NULL) ||'->'|| format_type(tt.oid,tt.typtypmod) AS obj_name,
+    ':cast.'||ca.oid||':/' || format_type(st.oid,NULL) ||'->'|| format_type(tt.oid,tt.typtypmod) AS obj_path, ''::text AS schema_name,
+    {{ show_node_prefs['cast'] }} AS show_node, NULL AS other_info
+    FROM pg_cast ca
+    JOIN pg_type st ON st.oid=castsource
+    JOIN pg_type tt ON tt.oid=casttarget
+    {% if not show_system_objects %}
+    WHERE ca.oid > {{last_system_oid}}::OID
+    {% endif %}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['language'] %}
+    SELECT 'language'::text AS obj_type, lanname AS obj_name, ':language.'||lan.oid||':/' || lanname AS obj_path, ''::text AS schema_name,
+    {{ show_node_prefs['language'] }} AS show_node, NULL AS other_info
+    FROM pg_language lan
+    WHERE lanispl IS TRUE
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['fts_configuration'] %}
+    SELECT 'fts_configuration'::text AS obj_type, cfg.cfgname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:fts_configuration.'||cfg.oid||':/' || cfg.cfgname AS obj_path, n.nspname AS schema_name,
+    {{ show_node_prefs['fts_configuration'] }} AS show_node, NULL AS other_info
+    FROM pg_ts_config cfg
+    left join pg_namespace n on cfg.cfgnamespace = n.oid
+    WHERE {{ CATALOGS.DB_SUPPORT('n') }}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['fts_dictionary'] %}
+    SELECT 'fts_dictionary' AS obj_type, dict.dictname AS obj_name, ':schema.'||ns.oid||':/' || ns.nspname || '/:fts_dictionary.'||dict.oid||':/' || dict.dictname AS obj_path, ns.nspname AS schema_name,
+    {{ show_node_prefs['fts_dictionary'] }} AS show_node, NULL AS other_info
+    FROM pg_ts_dict dict
+    left join pg_namespace ns on dict.dictnamespace = ns.oid
+    WHERE {{ CATALOGS.DB_SUPPORT('ns') }}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['fts_parser'] %}
+    SELECT 'fts_parser' AS obj_type, prs.prsname AS obj_name, ':schema.'||ns.oid||':/' || ns.nspname || '/:fts_parser.'||prs.oid||':/' || prs.prsname AS obj_path, ns.nspname AS schema_name,
+    {{ show_node_prefs['fts_parser'] }} AS show_node, NULL AS other_info
+    FROM pg_ts_parser prs
+    left join pg_namespace ns on prs.prsnamespace = ns.oid
+    WHERE {{ CATALOGS.DB_SUPPORT('ns') }}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['fts_template'] %}
+    SELECT 'fts_template' AS obj_type, tmpl.tmplname AS obj_name, ':schema.'||ns.oid||':/' || ns.nspname || '/:fts_template.'||tmpl.oid||':/' || tmpl.tmplname AS obj_path, ns.nspname AS schema_name,
+    {{ show_node_prefs['fts_template'] }} AS show_node, NULL AS other_info
+    FROM pg_ts_template tmpl
+    left join pg_namespace ns on tmpl.tmplnamespace = ns.oid
+    AND {{ CATALOGS.DB_SUPPORT('ns') }}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['domain'] %}
+    select 'domain' AS obj_type, t.typname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:domain.'||t.oid||':/' || t.typname AS obj_path, n.nspname AS schema_name,
+    {{ show_node_prefs['domain'] }} AS show_node, NULL AS other_info
+    from pg_type t
+    inner join pg_namespace n on t.typnamespace = n.oid
+    where t.typtype = 'd'
+    AND {{ CATALOGS.DB_SUPPORT('n') }}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['domain_constraints'] %}
+    SELECT 'domain_constraints' AS obj_type,
+    	c.conname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:domain.'||t.oid||':/' || t.typname || '/:domain_constraints.'||c.oid||':/' || c.conname AS obj_path,
+        n.nspname AS schema_name,
+        {{ show_node_prefs['domain_constraints'] }} AS show_node, NULL AS other_info
+    FROM pg_constraint c JOIN pg_type t
+    ON t.oid=contypid JOIN pg_namespace n
+    ON n.oid=t.typnamespace
+    WHERE t.typtype = 'd'
+    AND {{ CATALOGS.DB_SUPPORT('n') }}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['foreign_data_wrapper'] %}
+    select 'foreign_data_wrapper' AS obj_type, fdwname AS obj_name, ':foreign_data_wrapper.'||oid||':/' || fdwname AS obj_path, ''::text AS schema_name,
+    {{ show_node_prefs['foreign_data_wrapper'] }} AS show_node, NULL AS other_info
+    from pg_foreign_data_wrapper
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['foreign_server'] %}
+    select 'foreign_server' AS obj_type, sr.srvname AS obj_name, ':foreign_data_wrapper.'||fdw.oid||':/' || fdw.fdwname || '/:foreign_server.'||sr.oid||':/' || sr.srvname AS obj_path, ''::text AS schema_name,
+    {{ show_node_prefs['foreign_server'] }} AS show_node, NULL AS other_info
+    from pg_foreign_server sr
+    inner join pg_foreign_data_wrapper fdw on sr.srvfdw = fdw.oid
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['user_mapping'] %}
+    select 'user_mapping' AS obj_type, ro.rolname AS obj_name, ':foreign_data_wrapper.'||fdw.oid||':/' || fdw.fdwname || '/:foreign_server.'||sr.oid||':/' || sr.srvname || '/:user_mapping.'||ro.oid||':/' || ro.rolname AS obj_path, ''::text AS schema_name,
+    {{ show_node_prefs['user_mapping'] }} AS show_node, NULL AS other_info
+    from pg_user_mapping um
+    inner join pg_roles ro on um.umuser = ro.oid
+    inner join pg_foreign_server sr on um.umserver = sr.oid
+    inner join pg_foreign_data_wrapper fdw on sr.srvfdw = fdw.oid
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['foreign_table'] %}
+    select 'foreign_table' AS obj_type, c.relname AS obj_name, ':schema.'||ns.oid||':/' || ns.nspname || '/:foreign_table.'||c.oid||':/' || c.relname AS obj_path, ns.nspname AS schema_name,
+    {{ show_node_prefs['foreign_table'] }} AS show_node, NULL AS other_info
+    from pg_foreign_table ft
+    inner join pg_class c on ft.ftrelid = c.oid
+    inner join pg_namespace ns on c.relnamespace = ns.oid
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['extension'] %}
+    select 'extension' AS obj_type, x.extname AS obj_name, ':extension.'||x.oid||':/' || x.extname AS obj_path, ''::text AS schema_name,
+    {{ show_node_prefs['extension'] }} AS show_node, NULL AS other_info
+    FROM pg_extension x
+    JOIN pg_namespace n on x.extnamespace=n.oid
+    join pg_available_extensions() e(name, default_version, comment) ON x.extname=e.name
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['collation'] %}
+    SELECT 'collation' AS obj_type, c.collname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:collation.'||c.oid||':/' || c.collname AS obj_path, n.nspname AS schema_name,
+    {{ show_node_prefs['collation'] }} AS show_node, NULL AS other_info
+    FROM pg_collation c
+    JOIN pg_namespace n ON n.oid=c.collnamespace
+    WHERE {{ CATALOGS.DB_SUPPORT('n') }}
+{% endif %}
+
+) sn
+where lower(sn.obj_name) like '%{{ search_text }}%'
+{% if not show_system_objects %}
+AND NOT ({{ CATALOGS.IS_CATALOG_SCHEMA('sn.schema_name') }})
+AND (sn.schema_name IS NOT NULL AND sn.schema_name NOT LIKE 'pg\_%')
+{% endif %}
+ORDER BY 1, 2, 3
diff --git a/web/pgadmin/tools/search_objects/templates/search_objects/sql/pg/default/search.sql b/web/pgadmin/tools/search_objects/templates/search_objects/sql/pg/default/search.sql
new file mode 100644
index 000000000..b384b316d
--- /dev/null
+++ b/web/pgadmin/tools/search_objects/templates/search_objects/sql/pg/default/search.sql
@@ -0,0 +1,367 @@
+{% import 'catalog/pg/macros/catalogs.sql' as CATALOGS %}
+{% set all_obj = false %}
+{% if obj_type == 'all' or obj_type is none %}
+{% set all_obj = true %}
+{% endif %}
+SELECT obj_type, obj_name,
+    REPLACE(obj_path, '/'||sn.schema_name||'/', '/'||{{ CATALOGS.LABELS_SCHEMACOL('sn.schema_name', _) }}||'/') AS obj_path,
+    schema_name, show_node, other_info,
+    CASE
+        WHEN {{ CATALOGS.IS_CATALOG_SCHEMA('sn.schema_name') }} THEN
+            CASE WHEN {{ CATALOGS.DB_SUPPORT_SCHEMACOL('sn.schema_name') }} THEN 'D' ELSE 'O' END
+        ELSE 'N'
+    END AS catalog_level
+FROM (
+{% if all_obj or obj_type in ['table', 'sequence', 'view', 'mview'] %}
+    SELECT
+    CASE
+        WHEN c.relkind = 'r' THEN 'table'
+        WHEN c.relkind = 'S' THEN 'sequence'
+        WHEN c.relkind = 'v' THEN 'view'
+        WHEN c.relkind = 'm' THEN 'mview'
+        ELSE 'should not happen'
+    END::text AS obj_type, c.relname AS obj_name,
+    ':schema.'|| n.oid || ':/' || n.nspname || '/' ||
+    CASE
+        WHEN c.relkind = 'r' THEN ':table.'
+        WHEN c.relkind = 'S' THEN ':sequence.'
+        WHEN c.relkind = 'v' THEN ':view.'
+        WHEN c.relkind = 'm' THEN ':mview.'
+        ELSE 'should not happen'
+    END || c.oid ||':/' || c.relname AS obj_path, n.nspname AS schema_name,
+    CASE
+        WHEN c.relkind = 'r' THEN {{ show_node_prefs['table'] }}
+        WHEN c.relkind = 'S' THEN {{ show_node_prefs['sequence'] }}
+        WHEN c.relkind = 'v' THEN {{ show_node_prefs['view'] }}
+        WHEN c.relkind = 'm' THEN {{ show_node_prefs['mview'] }}
+        ELSE False
+    END AS show_node, NULL AS other_info
+    FROM pg_class c
+    LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
+    {% if all_obj %}
+    WHERE c.relkind in ('r','S','v','m')
+    {% elif obj_type == 'table' %}
+    WHERE c.relkind  = 'r'
+    {% elif obj_type == 'sequence' %}
+    WHERE c.relkind  = 'S'
+    AND {{ CATALOGS.DB_SUPPORT('n') }}
+    {% elif obj_type == 'view' %}
+    WHERE c.relkind  = 'v'
+    {% elif obj_type == 'mview' %}
+    WHERE c.relkind  = 'm'
+    AND {{ CATALOGS.DB_SUPPORT('n') }}
+    {% endif %}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['index'] %}
+    SELECT 'index'::text AS obj_type, cls.relname AS obj_name,
+    ':schema.'|| n.oid || ':/' || n.nspname || '/:table.'|| tab.oid ||':/' || tab.relname || '/:index.'|| cls.oid ||':/' || cls.relname AS obj_path, n.nspname AS schema_name,
+    {{ show_node_prefs['index'] }} AS show_node, NULL AS other_info
+    FROM pg_index idx
+    JOIN pg_class cls ON cls.oid=indexrelid
+    JOIN pg_class tab ON tab.oid=indrelid
+    JOIN pg_namespace n ON n.oid=tab.relnamespace
+    LEFT JOIN pg_depend dep ON (dep.classid = cls.tableoid AND dep.objid = cls.oid AND dep.refobjsubid = '0' AND dep.refclassid=(SELECT oid FROM pg_class WHERE relname='pg_constraint') AND dep.deptype='i')
+    LEFT OUTER JOIN pg_constraint con ON (con.tableoid = dep.refclassid AND con.oid = dep.refobjid)
+    LEFT OUTER JOIN pg_description des ON des.objoid=cls.oid
+    LEFT OUTER JOIN pg_description desp ON (desp.objoid=con.oid AND desp.objsubid = 0)
+    WHERE contype IS NULL
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['trigger_function', 'function'] %}
+    SELECT
+        CASE
+        WHEN t.typname IN ('trigger', 'event_trigger') THEN 'trigger_function'
+        ELSE 'function' END::text AS obj_type, p.proname AS obj_name,
+    ':schema.'|| n.oid || ':/' || n.nspname || '/' || case when t.typname = 'trigger' then ':trigger_function.' else ':function.' end || p.oid ||':/' || p.proname AS obj_path, n.nspname AS schema_name,
+    CASE WHEN t.typname IN ('trigger', 'event_trigger') THEN {{ show_node_prefs['trigger_function'] }} ELSE {{ show_node_prefs['function'] }} END AS show_node,
+    pg_catalog.pg_get_function_identity_arguments(p.oid) AS other_info
+    from pg_proc p
+    left join pg_namespace n on p.pronamespace = n.oid
+    left join pg_type t on p.prorettype = t.oid
+    WHERE ({{ CATALOGS.DB_SUPPORT('n') }})
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['event_trigger'] %}
+    select 'event_trigger'::text AS obj_type, evtname AS obj_name, ':event_trigger.'||oid||':/' || evtname AS obj_path, ''::text AS schema_name,
+    {{ show_node_prefs['index'] }} AS show_node, NULL AS other_info from pg_event_trigger
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['schema'] %}
+    select 'schema'::text AS obj_type, n.nspname AS obj_name,
+    ':schema.'||n.oid||':/' || n.nspname as obj_path, n.nspname AS schema_name,
+    {{ show_node_prefs['schema'] }} AS show_node, NULL AS other_info from pg_namespace n
+    where {{ CATALOGS.DB_SUPPORT('n') }}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['column'] %}
+    select 'column'::text AS obj_type, a.attname AS obj_name,
+    ':schema.'||n.oid||':/' || n.nspname || '/' ||
+    case
+        WHEN t.relkind = 'r' THEN ':table.'
+        WHEN t.relkind = 'v' THEN ':view.'
+        WHEN t.relkind = 'm' THEN ':mview.'
+        else 'should not happen'
+    end || t.oid || ':/' || t.relname || '/:column.'|| a.attnum ||':/' || a.attname AS obj_path, n.nspname AS schema_name,
+    {{ show_node_prefs['column'] }} AS show_node, NULL AS other_info
+    from pg_attribute a
+    inner join pg_class t on a.attrelid = t.oid and t.relkind in ('r','v','m')
+    left join pg_namespace n on t.relnamespace = n.oid where a.attnum > 0
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['constraints', 'check_constraint', 'foreign_key', 'primary_key', 'unique_constraint', 'exclusion_constraint'] %}
+    SELECT
+    CASE
+        WHEN c.contype = 'c' THEN  'check_constraint'
+        WHEN c.contype = 'f' THEN  'foreign_key'
+        WHEN c.contype = 'p' THEN  'primary_key'
+        WHEN c.contype = 'u' THEN  'unique_constraint'
+        WHEN c.contype = 'x' THEN  'exclusion_constraint'
+    END::text AS obj_type,
+    case when tf.relname is null then c.conname else c.conname || ' -> ' || tf.relname end AS obj_name,
+    ':schema.'||n.oid||':/' || n.nspname||'/:table.'|| t.oid || ':/'||t.relname||
+    CASE
+        WHEN c.contype = 'c' THEN  '/:check_constraint.' ||c.oid
+        WHEN c.contype = 'f' THEN  '/:foreign_key.' ||c.conindid
+        WHEN c.contype = 'p' THEN  '/:primary_key.' ||c.conindid
+        WHEN c.contype = 'u' THEN  '/:unique_constraint.' ||c.conindid
+        WHEN c.contype = 'x' THEN  '/:exclusion_constraint.' ||c.conindid
+    END ||':/'|| case when tf.relname is null then c.conname else c.conname || ' -> ' || tf.relname end AS obj_path, n.nspname AS schema_name,
+    {{ show_node_prefs['constraints'] }} AS show_node, NULL AS other_info
+    from pg_constraint c
+    left join pg_class t on c.conrelid = t.oid
+    left join pg_class tf on c.confrelid = tf.oid
+    left join pg_namespace n on t.relnamespace = n.oid
+    where c.contypid = 0
+    {% if obj_type == 'check_constraint' %}
+    AND c.contype = 'c'
+    {% elif obj_type == 'foreign_key' %}
+    AND c.contype = 'f'
+    {% elif obj_type == 'primary_key' %}
+    AND c.contype = 'p'
+    {% elif obj_type == 'unique_constraint' %}
+    AND c.contype = 'u'
+    {% elif obj_type == 'exclusion_constraint' %}
+    AND c.contype = 'x'
+    {% else %}
+    AND c.contype IN  ('c', 'f', 'p', 'u', 'x')
+    {% endif %}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['rule'] %}
+    select 'rule'::text AS obj_type, r.rulename AS obj_name, ':schema.'||n.oid||':/' || n.nspname||
+            case
+                WHEN t.relkind = 'r' THEN '/:table.'
+                when t.relkind = 'v' then '/:view.'
+                when t.relkind = 'm' then '/:mview.'
+                else 'should not happen'
+            end || t.oid || ':/' || t.relname ||'/:rule.'||r.oid||':/'|| r.rulename AS obj_path,
+            n.nspname AS schema_name,
+            {{ show_node_prefs['rule'] }} AS show_node, NULL AS other_info
+            from pg_rewrite r
+    left join pg_class t on r.ev_class = t.oid
+    left join pg_namespace n on t.relnamespace = n.oid
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['trigger'] %}
+    select 'trigger'::text AS obj_type, tr.tgname AS obj_name, ':schema.'||n.oid||':/' || n.nspname||
+            case
+                WHEN t.relkind = 'r' THEN '/:table.'
+                when t.relkind = 'v' then '/:view.'
+                when t.relkind = 'm' then '/:mview.'
+                else 'should not happen'
+            end || t.oid || ':/' || t.relname || '/:trigger.'|| tr.oid || ':/' || tr.tgname AS obj_path, n.nspname AS schema_name,
+            {{ show_node_prefs['trigger'] }} AS show_node, NULL AS other_info
+            from pg_trigger tr
+    left join pg_class t on tr.tgrelid = t.oid
+    left join pg_namespace n on t.relnamespace = n.oid
+    where tr.tgisinternal = false
+    and {{ CATALOGS.DB_SUPPORT('n') }}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['type'] %}
+    SELECT 'type'::text AS obj_type, t.typname AS obj_name, ':schema.'||n.oid||':/' || n.nspname ||
+        '/:type.'|| t.oid ||':/' || t.typname AS obj_path, n.nspname AS schema_name,
+        {{ show_node_prefs['type'] }} AS show_node, NULL AS other_info
+    FROM pg_type t
+    LEFT OUTER JOIN pg_type e ON e.oid=t.typelem
+    LEFT OUTER JOIN pg_class ct ON ct.oid=t.typrelid AND ct.relkind <> 'c'
+    LEFT OUTER JOIN pg_namespace n on t.typnamespace = n.oid
+    WHERE t.typtype != 'd' AND t.typname NOT LIKE E'\\_%'
+    {% if not show_system_objects %}
+        AND ct.oid is NULL
+    {% endif %}
+    AND {{ CATALOGS.DB_SUPPORT('n') }}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['cast'] %}
+    SELECT 'cast'::text AS obj_type, format_type(st.oid,NULL) ||'->'|| format_type(tt.oid,tt.typtypmod) AS obj_name,
+    ':cast.'||ca.oid||':/' || format_type(st.oid,NULL) ||'->'|| format_type(tt.oid,tt.typtypmod) AS obj_path, ''::text AS schema_name,
+    {{ show_node_prefs['cast'] }} AS show_node, NULL AS other_info
+    FROM pg_cast ca
+    JOIN pg_type st ON st.oid=castsource
+    JOIN pg_type tt ON tt.oid=casttarget
+    {% if not show_system_objects %}
+    WHERE ca.oid > {{last_system_oid}}::OID
+    {% endif %}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['language'] %}
+    SELECT 'language'::text AS obj_type, lanname AS obj_name, ':language.'||lan.oid||':/' || lanname AS obj_path, ''::text AS schema_name,
+    {{ show_node_prefs['language'] }} AS show_node, NULL AS other_info
+    FROM pg_language lan
+    WHERE lanispl IS TRUE
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['fts_configuration'] %}
+    SELECT 'fts_configuration'::text AS obj_type, cfg.cfgname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:fts_configuration.'||cfg.oid||':/' || cfg.cfgname AS obj_path, n.nspname AS schema_name,
+    {{ show_node_prefs['fts_configuration'] }} AS show_node, NULL AS other_info
+    FROM pg_ts_config cfg
+    left join pg_namespace n on cfg.cfgnamespace = n.oid
+    WHERE {{ CATALOGS.DB_SUPPORT('n') }}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['fts_dictionary'] %}
+    SELECT 'fts_dictionary'::text AS obj_type, dict.dictname AS obj_name, ':schema.'||ns.oid||':/' || ns.nspname || '/:fts_dictionary.'||dict.oid||':/' || dict.dictname AS obj_path, ns.nspname AS schema_name,
+    {{ show_node_prefs['fts_dictionary'] }} AS show_node, NULL AS other_info
+    FROM pg_ts_dict dict
+    left join pg_namespace ns on dict.dictnamespace = ns.oid
+    WHERE {{ CATALOGS.DB_SUPPORT('ns') }}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['fts_parser'] %}
+    SELECT 'fts_parser'::text AS obj_type, prs.prsname AS obj_name, ':schema.'||ns.oid||':/' || ns.nspname || '/:fts_parser.'||prs.oid||':/' || prs.prsname AS obj_path, ns.nspname AS schema_name,
+    {{ show_node_prefs['fts_parser'] }} AS show_node, NULL AS other_info
+    FROM pg_ts_parser prs
+    left join pg_namespace ns on prs.prsnamespace = ns.oid
+    WHERE {{ CATALOGS.DB_SUPPORT('ns') }}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['fts_template'] %}
+    SELECT 'fts_template'::text AS obj_type, tmpl.tmplname AS obj_name, ':schema.'||ns.oid||':/' || ns.nspname || '/:fts_template.'||tmpl.oid||':/' || tmpl.tmplname AS obj_path, ns.nspname AS schema_name,
+    {{ show_node_prefs['fts_template'] }} AS show_node, NULL AS other_info
+    FROM pg_ts_template tmpl
+    left join pg_namespace ns on tmpl.tmplnamespace = ns.oid
+    AND {{ CATALOGS.DB_SUPPORT('ns') }}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['domain'] %}
+    select 'domain'::text AS obj_type, t.typname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:domain.'||t.oid||':/' || t.typname AS obj_path, n.nspname AS schema_name,
+    {{ show_node_prefs['domain'] }} AS show_node, NULL AS other_info
+    from pg_type t
+    inner join pg_namespace n on t.typnamespace = n.oid
+    where t.typtype = 'd'
+    AND {{ CATALOGS.DB_SUPPORT('n') }}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['domain_constraints'] %}
+    SELECT 'domain_constraints'::text AS obj_type,
+        c.conname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:domain.'||t.oid||':/' || t.typname || '/:domain_constraints.'||c.oid||':/' || c.conname AS obj_path,
+        n.nspname AS schema_name,
+        {{ show_node_prefs['domain_constraints'] }} AS show_node, NULL AS other_info
+    FROM pg_constraint c JOIN pg_type t
+    ON t.oid=contypid JOIN pg_namespace n
+    ON n.oid=t.typnamespace
+    WHERE t.typtype = 'd'
+    AND {{ CATALOGS.DB_SUPPORT('n') }}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['foreign_data_wrapper'] %}
+    select 'foreign_data_wrapper'::text AS obj_type, fdwname AS obj_name, ':foreign_data_wrapper.'||oid||':/' || fdwname AS obj_path, ''::text AS schema_name,
+    {{ show_node_prefs['foreign_data_wrapper'] }} AS show_node, NULL AS other_info
+    from pg_foreign_data_wrapper
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['foreign_server'] %}
+    select 'foreign_server'::text AS obj_type, sr.srvname AS obj_name, ':foreign_data_wrapper.'||fdw.oid||':/' || fdw.fdwname || '/:foreign_server.'||sr.oid||':/' || sr.srvname AS obj_path, ''::text AS schema_name,
+    {{ show_node_prefs['foreign_server'] }} AS show_node, NULL AS other_info
+    from pg_foreign_server sr
+    inner join pg_foreign_data_wrapper fdw on sr.srvfdw = fdw.oid
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['user_mapping'] %}
+    select 'user_mapping'::text AS obj_type, ro.rolname AS obj_name, ':foreign_data_wrapper.'||fdw.oid||':/' || fdw.fdwname || '/:foreign_server.'||sr.oid||':/' || sr.srvname || '/:user_mapping.'||ro.oid||':/' || ro.rolname AS obj_path, ''::text AS schema_name,
+    {{ show_node_prefs['user_mapping'] }} AS show_node, NULL AS other_info
+    from pg_user_mapping um
+    inner join pg_roles ro on um.umuser = ro.oid
+    inner join pg_foreign_server sr on um.umserver = sr.oid
+    inner join pg_foreign_data_wrapper fdw on sr.srvfdw = fdw.oid
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['foreign_table'] %}
+    select 'foreign_table'::text AS obj_type, c.relname AS obj_name, ':schema.'||ns.oid||':/' || ns.nspname || '/:foreign_table.'||c.oid||':/' || c.relname AS obj_path, ns.nspname AS schema_name,
+    {{ show_node_prefs['foreign_table'] }} AS show_node, NULL AS other_info
+    from pg_foreign_table ft
+    inner join pg_class c on ft.ftrelid = c.oid
+    inner join pg_namespace ns on c.relnamespace = ns.oid
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['extension'] %}
+    select 'extension'::text AS obj_type, x.extname AS obj_name, ':extension.'||x.oid||':/' || x.extname AS obj_path, ''::text AS schema_name,
+    {{ show_node_prefs['extension'] }} AS show_node, NULL AS other_info
+    FROM pg_extension x
+    JOIN pg_namespace n on x.extnamespace=n.oid
+    join pg_available_extensions() e(name, default_version, comment) ON x.extname=e.name
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['collation'] %}
+    SELECT 'collation'::text AS obj_type, c.collname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:collation.'||c.oid||':/' || c.collname AS obj_path, n.nspname AS schema_name,
+    {{ show_node_prefs['collation'] }} AS show_node, NULL AS other_info
+    FROM pg_collation c
+    JOIN pg_namespace n ON n.oid=c.collnamespace
+    WHERE {{ CATALOGS.DB_SUPPORT('n') }}
+{% endif %}
+
+) sn
+where lower(sn.obj_name) like '%{{ search_text }}%'
+{% if not show_system_objects %}
+AND NOT ({{ CATALOGS.IS_CATALOG_SCHEMA('sn.schema_name') }})
+AND (sn.schema_name IS NOT NULL AND sn.schema_name NOT LIKE 'pg\_%')
+{% endif %}
+ORDER BY 1, 2, 3
diff --git a/web/pgadmin/tools/search_objects/templates/search_objects/sql/ppas/10_plus/search.sql b/web/pgadmin/tools/search_objects/templates/search_objects/sql/ppas/10_plus/search.sql
new file mode 100644
index 000000000..76d3f01ba
--- /dev/null
+++ b/web/pgadmin/tools/search_objects/templates/search_objects/sql/ppas/10_plus/search.sql
@@ -0,0 +1,494 @@
+{% import 'catalog/ppas/macros/catalogs.sql' as CATALOGS %}
+{% set all_obj = false %}
+{% if obj_type == 'all' or obj_type is none %}
+{% set all_obj = true %}
+{% endif %}
+SELECT obj_type, obj_name,
+    REPLACE(obj_path, '/'||sn.schema_name||'/', '/'||{{ CATALOGS.LABELS_SCHEMACOL('sn.schema_name', _) }}||'/') AS obj_path,
+    schema_name, show_node, other_info,
+    CASE
+        WHEN {{ CATALOGS.IS_CATALOG_SCHEMA('sn.schema_name') }} THEN
+            CASE WHEN {{ CATALOGS.DB_SUPPORT_SCHEMACOL('sn.schema_name') }} THEN 'D' ELSE 'O' END
+        ELSE 'N'
+    END AS catalog_level
+FROM (
+{% if all_obj or obj_type in ['sequence', 'view', 'mview'] %}
+    SELECT
+    CASE
+        WHEN c.relkind = 'S' THEN 'sequence'
+        WHEN c.relkind = 'v' THEN 'view'
+        WHEN c.relkind = 'm' THEN 'mview'
+        ELSE 'should not happen'
+    END::text AS obj_type, c.relname AS obj_name,
+    ':schema.'|| n.oid || ':/' || n.nspname || '/' ||
+    CASE
+        WHEN c.relkind = 'S' THEN ':sequence.'
+        WHEN c.relkind = 'v' THEN ':view.'
+        WHEN c.relkind = 'm' THEN ':mview.'
+        ELSE 'should not happen'
+    END || c.oid ||':/' || c.relname AS obj_path, n.nspname AS schema_name,
+    CASE
+        WHEN c.relkind = 'S' THEN {{ show_node_prefs['sequence'] }}
+        WHEN c.relkind = 'v' THEN {{ show_node_prefs['view'] }}
+        WHEN c.relkind = 'm' THEN {{ show_node_prefs['mview'] }}
+        ELSE False
+    END AS show_node, NULL AS other_info
+    FROM pg_class c
+    LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
+    {% if all_obj %}
+    WHERE c.relkind in ('S','v','m')
+    {% elif obj_type == 'sequence' %}
+    WHERE c.relkind  = 'S'
+    {% elif obj_type == 'view' %}
+    WHERE c.relkind  = 'v'
+    {% elif obj_type == 'mview' %}
+    WHERE c.relkind  = 'm'
+    {% endif %}
+    AND {{ CATALOGS.DB_SUPPORT('n') }}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['table', 'partition'] %}
+    SELECT CASE WHEN c.relispartition THEN 'partition' ELSE 'table' END::text AS obj_type, c.relname AS obj_name,
+    ':schema.'|| n.oid || ':/' || n.nspname || '/' || (
+		WITH RECURSIVE table_path_data as (
+			select c.oid as oid, 0 as height,
+				CASE c.relispartition WHEN true THEN ':partition.' ELSE ':table.' END || c.oid || ':/' || c.relname as path
+			union
+			select rel.oid, pt.height+1 as height,
+				CASE rel.relispartition WHEN true THEN ':partition.' ELSE ':table.' END
+				|| rel.oid || ':/' || rel.relname || '/' || pt.path as path
+			from pg_class rel JOIN pg_namespace nsp ON rel.relnamespace = nsp.oid
+			join pg_inherits inh ON inh.inhparent = rel.oid
+			join table_path_data pt ON inh.inhrelid = pt.oid
+		)
+		select path from table_path_data order by height desc limit 1
+	) obj_path, n.nspname AS schema_name,
+	CASE WHEN c.relispartition THEN {{ show_node_prefs['partition'] }}
+	    ELSE {{ show_node_prefs['table'] }} END AS show_node,
+    NULL AS other_info
+    FROM pg_class c
+    LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
+    WHERE c.relkind in ('p','r')
+    {% if obj_type == 'table' %}
+    AND NOT c.relispartition
+    {% elif obj_type == 'partition' %}
+    AND c.relispartition
+    {% endif %}
+    AND {{ CATALOGS.DB_SUPPORT('n') }}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['index'] %}
+    SELECT 'index'::text AS obj_type, cls.relname AS obj_name,
+    ':schema.'|| n.oid || ':/' || n.nspname || '/:table.'|| tab.oid ||':/' || tab.relname || '/:index.'|| cls.oid ||':/' || cls.relname AS obj_path, n.nspname AS schema_name,
+    {{ show_node_prefs['index'] }} AS show_node, NULL AS other_info
+    FROM pg_index idx
+    JOIN pg_class cls ON cls.oid=indexrelid
+    JOIN pg_class tab ON tab.oid=indrelid
+    JOIN pg_namespace n ON n.oid=tab.relnamespace
+    LEFT JOIN pg_depend dep ON (dep.classid = cls.tableoid AND dep.objid = cls.oid AND dep.refobjsubid = '0' AND dep.refclassid=(SELECT oid FROM pg_class WHERE relname='pg_constraint') AND dep.deptype='i')
+    LEFT OUTER JOIN pg_constraint con ON (con.tableoid = dep.refclassid AND con.oid = dep.refobjid)
+    LEFT OUTER JOIN pg_description des ON des.objoid=cls.oid
+    LEFT OUTER JOIN pg_description desp ON (desp.objoid=con.oid AND desp.objsubid = 0)
+    WHERE contype IS NULL
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['trigger_function', 'function', 'procedure', 'edbfunc', 'edbproc'] %}
+    SELECT fd.obj_type, fd.obj_name,
+        CASE
+            WHEN fd.obj_type = 'function' THEN
+                ':schema.'|| fd.schema_oid || ':/' || fd.schema_name || '/:function.' || fd.obj_oid ||':/' || fd.obj_name
+            WHEN fd.obj_type = 'procedure' THEN
+                ':schema.'|| fd.schema_oid || ':/' || fd.schema_name || '/:procedure.' || fd.obj_oid ||':/' || fd.obj_name
+            WHEN fd.obj_type = 'trigger_function' THEN
+                ':schema.'|| fd.schema_oid || ':/' || fd.schema_name || '/:trigger_function.' || fd.obj_oid ||':/' || fd.obj_name
+            WHEN fd.obj_type = 'edbfunc' THEN
+                ':schema.'|| fd.next_schema_oid || ':/' || fd.next_schema_name || '/:package.'|| fd.schema_oid || ':/' || fd.schema_name || '/:edbfunc.' || fd.obj_oid ||':/' || fd.obj_name
+            WHEN fd.obj_type = 'edbproc' THEN
+                ':schema.'|| fd.next_schema_oid || ':/' || fd.next_schema_name || '/:package.'|| fd.schema_oid || ':/' || fd.schema_name || '/:edbproc.' || fd.obj_oid ||':/' || fd.obj_name
+            ELSE NULL
+        END AS obj_path,
+        CASE
+            WHEN fd.obj_type IN ('function', 'procedure', 'trigger_function') THEN fd.schema_name
+            WHEN fd.obj_type IN ('edbfunc', 'edbproc') THEN fd.next_schema_name
+            ELSE NULL
+        END AS schema_name,
+        CASE
+            WHEN fd.obj_type = 'function' THEN {{ show_node_prefs['function'] }}
+            WHEN fd.obj_type = 'procedure' THEN {{ show_node_prefs['procedure'] }}
+            WHEN fd.obj_type = 'trigger_function' THEN {{ show_node_prefs['trigger_function'] }}
+            WHEN fd.obj_type = 'edbfunc' THEN {{ show_node_prefs['edbfunc'] }}
+            WHEN fd.obj_type = 'edbproc' THEN {{ show_node_prefs['edbproc'] }}
+            ELSE NULL
+        END AS show_node, other_info
+    FROM (
+        SELECT
+            CASE
+            WHEN t.typname IN ('trigger', 'event_trigger') THEN 'trigger_function'
+            WHEN pr.protype = '0'::char THEN
+                CASE WHEN np.oid IS NOT NULL THEN 'edbfunc' ELSE 'function' END
+            WHEN pr.protype = '1'::char THEN
+                CASE WHEN np.oid IS NOT NULL THEN 'edbproc' ELSE 'procedure' END
+            ELSE null
+            END::text AS obj_type, pr.proname AS obj_name, pr.oid AS obj_oid, n.oid AS schema_oid, n.nspname AS schema_name, np.oid next_schema_oid, np.nspname next_schema_name,
+            pg_catalog.pg_get_function_identity_arguments(pr.oid) AS other_info
+        FROM pg_proc pr left join pg_namespace n
+        ON pr.pronamespace = n.oid left JOIN pg_namespace np
+        ON np.oid=n.nspparent left JOIN pg_type t
+        ON t.oid = pr.prorettype left JOIN pg_language l
+        ON l.oid = pr.prolang
+        WHERE NOT (t.typname = 'trigger' AND l.lanname = 'edbspl')
+        AND ({{ CATALOGS.DB_SUPPORT('n') }} AND {{ CATALOGS.DB_SUPPORT('np') }})
+    ) fd
+    {% if not all_obj %}
+    WHERE fd.obj_type = '{{ obj_type }}'
+    {% endif %}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['event_trigger'] %}
+    select 'event_trigger'::text AS obj_type, evtname AS obj_name, ':event_trigger.'||oid||':/' || evtname AS obj_path, ''::text AS schema_name,
+    {{ show_node_prefs['index'] }} AS show_node, NULL AS other_info from pg_event_trigger
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['schema'] %}
+    select 'schema'::text AS obj_type, n.nspname AS obj_name,
+    ':schema.'||n.oid||':/' || n.nspname as obj_path, n.nspname AS schema_name,
+    {{ show_node_prefs['schema'] }} AS show_node, NULL AS other_info from pg_namespace n
+    where n.nspparent = 0
+    AND {{ CATALOGS.DB_SUPPORT('n') }}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['column'] %}
+    select 'column'::text AS obj_type, a.attname AS obj_name,
+    ':schema.'||n.oid||':/' || n.nspname || '/' ||
+    case
+        WHEN t.relkind = 'r' THEN ':table.'
+        WHEN t.relkind = 'v' THEN ':view.'
+        WHEN t.relkind = 'm' THEN ':mview.'
+        else 'should not happen'
+    end || t.oid || ':/' || t.relname || '/:column.'|| a.attnum ||':/' || a.attname AS obj_path, n.nspname AS schema_name,
+    {{ show_node_prefs['column'] }} AS show_node, NULL AS other_info
+    from pg_attribute a
+    inner join pg_class t on a.attrelid = t.oid and t.relkind in ('r','v','m')
+    left join pg_namespace n on t.relnamespace = n.oid where a.attnum > 0
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['constraints', 'check_constraint', 'foreign_key', 'primary_key', 'unique_constraint', 'exclusion_constraint'] %}
+    SELECT
+    CASE
+        WHEN c.contype = 'c' THEN  'check_constraint'
+        WHEN c.contype = 'f' THEN  'foreign_key'
+        WHEN c.contype = 'p' THEN  'primary_key'
+        WHEN c.contype = 'u' THEN  'unique_constraint'
+        WHEN c.contype = 'x' THEN  'exclusion_constraint'
+    END::text AS obj_type,
+    case when tf.relname is null then c.conname else c.conname || ' -> ' || tf.relname end AS obj_name,
+    ':schema.'||n.oid||':/' || n.nspname||'/'||
+    (
+		WITH RECURSIVE table_path_data as (
+			select t.oid as oid, 0 as height,
+				CASE t.relispartition WHEN true THEN ':partition.' ELSE ':table.' END || t.oid || ':/' || t.relname as path
+			union
+			select rel.oid, pt.height+1 as height,
+				CASE rel.relispartition WHEN true THEN ':partition.' ELSE ':table.' END
+				|| rel.oid || ':/' || rel.relname || '/' || pt.path as path
+			from pg_class rel JOIN pg_namespace nsp ON rel.relnamespace = nsp.oid
+			join pg_inherits inh ON inh.inhparent = rel.oid
+			join table_path_data pt ON inh.inhrelid = pt.oid
+		)
+		select path from table_path_data order by height desc limit 1
+	) ||
+    CASE
+        WHEN c.contype = 'c' THEN  '/:check_constraint.' ||c.oid
+        WHEN c.contype = 'f' THEN  '/:foreign_key.' ||c.conindid
+        WHEN c.contype = 'p' THEN  '/:primary_key.' ||c.conindid
+        WHEN c.contype = 'u' THEN  '/:unique_constraint.' ||c.conindid
+        WHEN c.contype = 'x' THEN  '/:exclusion_constraint.' ||c.conindid
+    END ||':/'|| case when tf.relname is null then c.conname else c.conname || ' -> ' || tf.relname end AS obj_path, n.nspname AS schema_name,
+    {{ show_node_prefs['constraints'] }} AS show_node, NULL AS other_info
+    from pg_constraint c
+    left join pg_class t on c.conrelid = t.oid
+    left join pg_class tf on c.confrelid = tf.oid
+    left join pg_namespace n on t.relnamespace = n.oid
+    where c.contypid = 0
+    {% if obj_type == 'check_constraint' %}
+    AND c.contype = 'c'
+    {% elif obj_type == 'foreign_key' %}
+    AND c.contype = 'f'
+    {% elif obj_type == 'primary_key' %}
+    AND c.contype = 'p'
+    {% elif obj_type == 'unique_constraint' %}
+    AND c.contype = 'u'
+    {% elif obj_type == 'exclusion_constraint' %}
+    AND c.contype = 'x'
+    {% else %}
+    AND c.contype IN  ('c', 'f', 'p', 'u', 'x')
+    {% endif %}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['rule'] %}
+    select 'rule'::text AS obj_type, r.rulename AS obj_name, ':schema.'||n.oid||':/' || n.nspname|| '/' ||
+            case
+                when t.relkind = 'v' then ':view.'
+                when t.relkind = 'm' then ':mview.'
+                WHEN t.relkind in ('r', 'p') THEN
+                    (
+                        WITH RECURSIVE table_path_data as (
+                            select t.oid as oid, 0 as height,
+                                CASE t.relispartition WHEN true THEN ':partition.' ELSE ':table.' END || t.oid || ':/' || t.relname as path
+                            union
+                            select rel.oid, pt.height+1 as height,
+                                CASE rel.relispartition WHEN true THEN ':partition.' ELSE ':table.' END
+                                || rel.oid || ':/' || rel.relname || '/' || pt.path as path
+                            from pg_class rel JOIN pg_namespace nsp ON rel.relnamespace = nsp.oid
+                            join pg_inherits inh ON inh.inhparent = rel.oid
+                            join table_path_data pt ON inh.inhrelid = pt.oid
+                        )
+                        select path from table_path_data order by height desc limit 1
+                    )
+            end
+            ||'/:rule.'||r.oid||':/'|| r.rulename AS obj_path,
+            n.nspname AS schema_name,
+            {{ show_node_prefs['rule'] }} AS show_node, NULL AS other_info
+            from pg_rewrite r
+    left join pg_class t on r.ev_class = t.oid
+    left join pg_namespace n on t.relnamespace = n.oid
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['trigger'] %}
+    select 'trigger'::text AS obj_type, tr.tgname AS obj_name, ':schema.'||n.oid||':/' || n.nspname||
+            case
+                WHEN t.relkind = 'r' THEN '/:table.'
+                when t.relkind = 'v' then '/:view.'
+                when t.relkind = 'm' then '/:mview.'
+                else 'should not happen'
+            end || t.oid || ':/' || t.relname || '/:trigger.'|| tr.oid || ':/' || tr.tgname AS obj_path, n.nspname AS schema_name,
+            {{ show_node_prefs['trigger'] }} AS show_node, NULL AS other_info
+            from pg_trigger tr
+    left join pg_class t on tr.tgrelid = t.oid
+    left join pg_namespace n on t.relnamespace = n.oid
+    where tr.tgisinternal = false
+    and {{ CATALOGS.DB_SUPPORT('n') }}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['type'] %}
+    SELECT 'type'::text AS obj_type, t.typname AS obj_name, ':schema.'||n.oid||':/' || n.nspname ||
+        '/:type.'|| t.oid ||':/' || t.typname AS obj_path, n.nspname AS schema_name,
+        {{ show_node_prefs['type'] }} AS show_node, NULL AS other_info
+    FROM pg_type t
+    LEFT OUTER JOIN pg_type e ON e.oid=t.typelem
+    LEFT OUTER JOIN pg_class ct ON ct.oid=t.typrelid AND ct.relkind <> 'c'
+    LEFT OUTER JOIN pg_namespace n on t.typnamespace = n.oid
+    WHERE t.typtype != 'd' AND t.typname NOT LIKE E'\\_%'
+    {% if not show_system_objects %}
+        AND ct.oid is NULL
+    {% endif %}
+    AND {{ CATALOGS.DB_SUPPORT('n') }}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['cast'] %}
+    SELECT 'cast'::text AS obj_type, format_type(st.oid,NULL) ||'->'|| format_type(tt.oid,tt.typtypmod) AS obj_name,
+    ':cast.'||ca.oid||':/' || format_type(st.oid,NULL) ||'->'|| format_type(tt.oid,tt.typtypmod) AS obj_path, ''::text AS schema_name,
+    {{ show_node_prefs['cast'] }} AS show_node, NULL AS other_info
+    FROM pg_cast ca
+    JOIN pg_type st ON st.oid=castsource
+    JOIN pg_type tt ON tt.oid=casttarget
+    {% if not show_system_objects %}
+    WHERE ca.oid > {{last_system_oid}}::OID
+    {% endif %}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['language'] %}
+    SELECT 'language'::text AS obj_type, lanname AS obj_name, ':language.'||lan.oid||':/' || lanname AS obj_path, ''::text AS schema_name,
+    {{ show_node_prefs['language'] }} AS show_node, NULL AS other_info
+    FROM pg_language lan
+    WHERE lanispl IS TRUE
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['fts_configuration'] %}
+    SELECT 'fts_configuration'::text AS obj_type, cfg.cfgname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:fts_configuration.'||cfg.oid||':/' || cfg.cfgname AS obj_path, n.nspname AS schema_name,
+    {{ show_node_prefs['fts_configuration'] }} AS show_node, NULL AS other_info
+    FROM pg_ts_config cfg
+    left join pg_namespace n on cfg.cfgnamespace = n.oid
+    WHERE {{ CATALOGS.DB_SUPPORT('n') }}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['fts_dictionary'] %}
+    SELECT 'fts_dictionary' AS obj_type, dict.dictname AS obj_name, ':schema.'||ns.oid||':/' || ns.nspname || '/:fts_dictionary.'||dict.oid||':/' || dict.dictname AS obj_path, ns.nspname AS schema_name,
+    {{ show_node_prefs['fts_dictionary'] }} AS show_node, NULL AS other_info
+    FROM pg_ts_dict dict
+    left join pg_namespace ns on dict.dictnamespace = ns.oid
+    WHERE {{ CATALOGS.DB_SUPPORT('ns') }}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['fts_parser'] %}
+    SELECT 'fts_parser' AS obj_type, prs.prsname AS obj_name, ':schema.'||ns.oid||':/' || ns.nspname || '/:fts_parser.'||prs.oid||':/' || prs.prsname AS obj_path, ns.nspname AS schema_name,
+    {{ show_node_prefs['fts_parser'] }} AS show_node, NULL AS other_info
+    FROM pg_ts_parser prs
+    left join pg_namespace ns on prs.prsnamespace = ns.oid
+    WHERE {{ CATALOGS.DB_SUPPORT('ns') }}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['fts_template'] %}
+    SELECT 'fts_template' AS obj_type, tmpl.tmplname AS obj_name, ':schema.'||ns.oid||':/' || ns.nspname || '/:fts_template.'||tmpl.oid||':/' || tmpl.tmplname AS obj_path, ns.nspname AS schema_name,
+    {{ show_node_prefs['fts_template'] }} AS show_node, NULL AS other_info
+    FROM pg_ts_template tmpl
+    left join pg_namespace ns on tmpl.tmplnamespace = ns.oid
+    AND {{ CATALOGS.DB_SUPPORT('ns') }}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['domain'] %}
+    select 'domain' AS obj_type, t.typname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:domain.'||t.oid||':/' || t.typname AS obj_path, n.nspname AS schema_name,
+    {{ show_node_prefs['domain'] }} AS show_node, NULL AS other_info
+    from pg_type t
+    inner join pg_namespace n on t.typnamespace = n.oid
+    where t.typtype = 'd'
+    AND {{ CATALOGS.DB_SUPPORT('n') }}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['domain_constraints'] %}
+    SELECT 'domain_constraints' AS obj_type,
+        c.conname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:domain.'||t.oid||':/' || t.typname || '/:domain_constraints.'||c.oid||':/' || c.conname AS obj_path,
+        n.nspname AS schema_name,
+        {{ show_node_prefs['domain_constraints'] }} AS show_node, NULL AS other_info
+    FROM pg_constraint c JOIN pg_type t
+    ON t.oid=contypid JOIN pg_namespace n
+    ON n.oid=t.typnamespace
+    WHERE t.typtype = 'd'
+    AND {{ CATALOGS.DB_SUPPORT('n') }}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['foreign_data_wrapper'] %}
+    select 'foreign_data_wrapper' AS obj_type, fdwname AS obj_name, ':foreign_data_wrapper.'||oid||':/' || fdwname AS obj_path, ''::text AS schema_name,
+    {{ show_node_prefs['foreign_data_wrapper'] }} AS show_node, NULL AS other_info
+    from pg_foreign_data_wrapper
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['foreign_server'] %}
+    select 'foreign_server' AS obj_type, sr.srvname AS obj_name, ':foreign_data_wrapper.'||fdw.oid||':/' || fdw.fdwname || '/:foreign_server.'||sr.oid||':/' || sr.srvname AS obj_path, ''::text AS schema_name,
+    {{ show_node_prefs['foreign_server'] }} AS show_node, NULL AS other_info
+    from pg_foreign_server sr
+    inner join pg_foreign_data_wrapper fdw on sr.srvfdw = fdw.oid
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['user_mapping'] %}
+    select 'user_mapping' AS obj_type, ro.rolname AS obj_name, ':foreign_data_wrapper.'||fdw.oid||':/' || fdw.fdwname || '/:foreign_server.'||sr.oid||':/' || sr.srvname || '/:user_mapping.'||ro.oid||':/' || ro.rolname AS obj_path, ''::text AS schema_name,
+    {{ show_node_prefs['user_mapping'] }} AS show_node, NULL AS other_info
+    from pg_user_mapping um
+    inner join pg_roles ro on um.umuser = ro.oid
+    inner join pg_foreign_server sr on um.umserver = sr.oid
+    inner join pg_foreign_data_wrapper fdw on sr.srvfdw = fdw.oid
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['foreign_table'] %}
+    select 'foreign_table' AS obj_type, c.relname AS obj_name, ':schema.'||ns.oid||':/' || ns.nspname || '/:foreign_table.'||c.oid||':/' || c.relname AS obj_path, ns.nspname AS schema_name,
+    {{ show_node_prefs['foreign_table'] }} AS show_node, NULL AS other_info
+    from pg_foreign_table ft
+    inner join pg_class c on ft.ftrelid = c.oid
+    inner join pg_namespace ns on c.relnamespace = ns.oid
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['extension'] %}
+    select 'extension' AS obj_type, x.extname AS obj_name, ':extension.'||x.oid||':/' || x.extname AS obj_path, ''::text AS schema_name,
+    {{ show_node_prefs['extension'] }} AS show_node, NULL AS other_info
+    FROM pg_extension x
+    JOIN pg_namespace n on x.extnamespace=n.oid
+    join pg_available_extensions() e(name, default_version, comment) ON x.extname=e.name
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['collation'] %}
+    SELECT 'collation' AS obj_type, c.collname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:collation.'||c.oid||':/' || c.collname AS obj_path, n.nspname AS schema_name,
+    {{ show_node_prefs['collation'] }} AS show_node, NULL AS other_info
+    FROM pg_collation c
+    JOIN pg_namespace n ON n.oid=c.collnamespace
+    WHERE {{ CATALOGS.DB_SUPPORT('n') }}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['synonym'] %}
+    SELECT 'synonym' AS obj_type, s.synname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:synonym.'||s.oid||':/' || s.synname AS obj_path, n.nspname AS schema_name,
+    {{ show_node_prefs['synonym'] }} AS show_node, NULL AS other_info
+    FROM pg_synonym s
+    JOIN pg_namespace n ON n.oid=s.synnamespace
+    WHERE {{ CATALOGS.DB_SUPPORT('n') }}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['package'] %}
+    SELECT 'package' AS obj_type, p.nspname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:package.'||p.oid||':/' || p.nspname AS obj_path, n.nspname AS schema_name,
+    {{ show_node_prefs['package'] }} AS show_node, NULL AS other_info
+    FROM pg_namespace p
+    JOIN pg_namespace n ON n.oid=p.nspparent
+    WHERE p.nspcompoundtrigger = false
+    AND {{ CATALOGS.DB_SUPPORT('n') }}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['edbvar'] %}
+    SELECT 'edbvar' AS obj_type, v.varname AS obj_name,
+    ':schema.'||n.oid||':/' || n.nspname || '/:package.'||p.oid||':/' || p.nspname || '/:edbvar.'||v.oid||':/' || v.varname AS obj_path, n.nspname AS schema_name,
+    {{ show_node_prefs['edbvar'] }} AS show_node, NULL AS other_info
+    FROM edb_variable v JOIN pg_namespace p
+    ON v.varpackage = p.oid JOIN pg_namespace n
+    ON p.nspparent = n.oid
+    WHERE p.nspcompoundtrigger = false
+    AND {{ CATALOGS.DB_SUPPORT('p') }}
+    AND {{ CATALOGS.DB_SUPPORT('n') }}
+{% endif %}
+) sn
+where lower(sn.obj_name) like '%{{ search_text }}%'
+{% if not show_system_objects %}
+AND NOT ({{ CATALOGS.IS_CATALOG_SCHEMA('sn.schema_name') }})
+AND (sn.schema_name IS NOT NULL AND sn.schema_name NOT LIKE 'pg\_%')
+{% endif %}
+ORDER BY 1, 2, 3
diff --git a/web/pgadmin/tools/search_objects/templates/search_objects/sql/ppas/12_plus/search.sql b/web/pgadmin/tools/search_objects/templates/search_objects/sql/ppas/12_plus/search.sql
new file mode 100644
index 000000000..82eb9cf6f
--- /dev/null
+++ b/web/pgadmin/tools/search_objects/templates/search_objects/sql/ppas/12_plus/search.sql
@@ -0,0 +1,515 @@
+{% import 'catalog/ppas/macros/catalogs.sql' as CATALOGS %}
+{% set all_obj = false %}
+{% if obj_type == 'all' or obj_type is none %}
+{% set all_obj = true %}
+{% endif %}
+SELECT obj_type, obj_name,
+    REPLACE(obj_path, '/'||sn.schema_name||'/', '/'||{{ CATALOGS.LABELS_SCHEMACOL('sn.schema_name', _) }}||'/') AS obj_path,
+    schema_name, show_node, other_info,
+    CASE
+        WHEN {{ CATALOGS.IS_CATALOG_SCHEMA('sn.schema_name') }} THEN
+            CASE WHEN {{ CATALOGS.DB_SUPPORT_SCHEMACOL('sn.schema_name') }} THEN 'D' ELSE 'O' END
+        ELSE 'N'
+    END AS catalog_level
+FROM (
+{% if all_obj or obj_type in ['sequence', 'view', 'mview'] %}
+    SELECT
+    CASE
+        WHEN c.relkind = 'S' THEN 'sequence'
+        WHEN c.relkind = 'v' THEN 'view'
+        WHEN c.relkind = 'm' THEN 'mview'
+        ELSE 'should not happen'
+    END::text AS obj_type, c.relname AS obj_name,
+    ':schema.'|| n.oid || ':/' || n.nspname || '/' ||
+    CASE
+        WHEN c.relkind = 'S' THEN ':sequence.'
+        WHEN c.relkind = 'v' THEN ':view.'
+        WHEN c.relkind = 'm' THEN ':mview.'
+        ELSE 'should not happen'
+    END || c.oid ||':/' || c.relname AS obj_path, n.nspname AS schema_name,
+    CASE
+        WHEN c.relkind = 'S' THEN {{ show_node_prefs['sequence'] }}
+        WHEN c.relkind = 'v' THEN {{ show_node_prefs['view'] }}
+        WHEN c.relkind = 'm' THEN {{ show_node_prefs['mview'] }}
+        ELSE False
+    END AS show_node, NULL AS other_info
+    FROM pg_class c
+    LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
+    {% if all_obj %}
+    WHERE c.relkind in ('S','v','m')
+    {% elif obj_type == 'sequence' %}
+    WHERE c.relkind  = 'S'
+    {% elif obj_type == 'view' %}
+    WHERE c.relkind  = 'v'
+    {% elif obj_type == 'mview' %}
+    WHERE c.relkind  = 'm'
+    {% endif %}
+    AND {{ CATALOGS.DB_SUPPORT('n') }}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['table', 'partition'] %}
+    SELECT CASE WHEN c.relispartition THEN 'partition' ELSE 'table' END::text AS obj_type, c.relname AS obj_name,
+    ':schema.'|| n.oid || ':/' || n.nspname || '/' || (
+		WITH RECURSIVE table_path_data as (
+			select c.oid as oid, 0 as height,
+				CASE c.relispartition WHEN true THEN ':partition.' ELSE ':table.' END || c.oid || ':/' || c.relname as path
+			union
+			select rel.oid, pt.height+1 as height,
+				CASE rel.relispartition WHEN true THEN ':partition.' ELSE ':table.' END
+				|| rel.oid || ':/' || rel.relname || '/' || pt.path as path
+			from pg_class rel JOIN pg_namespace nsp ON rel.relnamespace = nsp.oid
+			join pg_inherits inh ON inh.inhparent = rel.oid
+			join table_path_data pt ON inh.inhrelid = pt.oid
+		)
+		select path from table_path_data order by height desc limit 1
+	) obj_path, n.nspname AS schema_name,
+	CASE WHEN c.relispartition THEN {{ show_node_prefs['partition'] }}
+	    ELSE {{ show_node_prefs['table'] }} END AS show_node,
+    NULL AS other_info
+    FROM pg_class c
+    LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
+    WHERE c.relkind in ('p','r')
+    {% if obj_type == 'table' %}
+    AND NOT c.relispartition
+    {% elif obj_type == 'partition' %}
+    AND c.relispartition
+    {% endif %}
+    AND {{ CATALOGS.DB_SUPPORT('n') }}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['index'] %}
+    SELECT 'index'::text AS obj_type, cls.relname AS obj_name,
+    ':schema.'|| n.oid || ':/' || n.nspname || '/:table.'|| tab.oid ||':/' || tab.relname || '/:index.'|| cls.oid ||':/' || cls.relname AS obj_path, n.nspname AS schema_name,
+    {{ show_node_prefs['index'] }} AS show_node, NULL AS other_info
+    FROM pg_index idx
+    JOIN pg_class cls ON cls.oid=indexrelid
+    JOIN pg_class tab ON tab.oid=indrelid
+    JOIN pg_namespace n ON n.oid=tab.relnamespace
+    LEFT JOIN pg_depend dep ON (dep.classid = cls.tableoid AND dep.objid = cls.oid AND dep.refobjsubid = '0' AND dep.refclassid=(SELECT oid FROM pg_class WHERE relname='pg_constraint') AND dep.deptype='i')
+    LEFT OUTER JOIN pg_constraint con ON (con.tableoid = dep.refclassid AND con.oid = dep.refobjid)
+    LEFT OUTER JOIN pg_description des ON des.objoid=cls.oid
+    LEFT OUTER JOIN pg_description desp ON (desp.objoid=con.oid AND desp.objsubid = 0)
+    WHERE contype IS NULL
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['trigger_function', 'function', 'procedure', 'edbfunc', 'edbproc'] %}
+    SELECT fd.obj_type, fd.obj_name,
+        CASE
+            WHEN fd.obj_type = 'function' THEN
+                ':schema.'|| fd.schema_oid || ':/' || fd.schema_name || '/:function.' || fd.obj_oid ||':/' || fd.obj_name
+            WHEN fd.obj_type = 'procedure' THEN
+                ':schema.'|| fd.schema_oid || ':/' || fd.schema_name || '/:procedure.' || fd.obj_oid ||':/' || fd.obj_name
+            WHEN fd.obj_type = 'trigger_function' THEN
+                ':schema.'|| fd.schema_oid || ':/' || fd.schema_name || '/:trigger_function.' || fd.obj_oid ||':/' || fd.obj_name
+            WHEN fd.obj_type = 'edbfunc' THEN
+                ':schema.'|| fd.next_schema_oid || ':/' || fd.next_schema_name || '/:package.'|| fd.schema_oid || ':/' || fd.schema_name || '/:edbfunc.' || fd.obj_oid ||':/' || fd.obj_name
+            WHEN fd.obj_type = 'edbproc' THEN
+                ':schema.'|| fd.next_schema_oid || ':/' || fd.next_schema_name || '/:package.'|| fd.schema_oid || ':/' || fd.schema_name || '/:edbproc.' || fd.obj_oid ||':/' || fd.obj_name
+            ELSE NULL
+        END AS obj_path,
+        CASE
+            WHEN fd.obj_type IN ('function', 'procedure', 'trigger_function') THEN fd.schema_name
+            WHEN fd.obj_type IN ('edbfunc', 'edbproc') THEN fd.next_schema_name
+            ELSE NULL
+        END AS schema_name,
+        CASE
+            WHEN fd.obj_type = 'function' THEN {{ show_node_prefs['function'] }}
+            WHEN fd.obj_type = 'procedure' THEN {{ show_node_prefs['procedure'] }}
+            WHEN fd.obj_type = 'trigger_function' THEN {{ show_node_prefs['trigger_function'] }}
+            WHEN fd.obj_type = 'edbfunc' THEN {{ show_node_prefs['edbfunc'] }}
+            WHEN fd.obj_type = 'edbproc' THEN {{ show_node_prefs['edbproc'] }}
+            ELSE NULL
+        END AS show_node, other_info
+    FROM (
+        SELECT
+            CASE
+            WHEN t.typname IN ('trigger', 'event_trigger') THEN 'trigger_function'
+            WHEN pr.protype = '0'::char THEN
+                CASE WHEN np.oid IS NOT NULL THEN 'edbfunc' ELSE 'function' END
+            WHEN pr.protype = '1'::char THEN
+                CASE WHEN np.oid IS NOT NULL THEN 'edbproc' ELSE 'procedure' END
+            ELSE null
+            END::text AS obj_type, pr.proname AS obj_name, pr.oid AS obj_oid, n.oid AS schema_oid, n.nspname AS schema_name, np.oid next_schema_oid, np.nspname next_schema_name,
+            pg_catalog.pg_get_function_identity_arguments(pr.oid) AS other_info
+        FROM pg_proc pr left join pg_namespace n
+        ON pr.pronamespace = n.oid left JOIN pg_namespace np
+        ON np.oid=n.nspparent left JOIN pg_type t
+        ON t.oid = pr.prorettype left JOIN pg_language l
+        ON l.oid = pr.prolang
+        WHERE NOT (t.typname = 'trigger' AND l.lanname = 'edbspl')
+        AND ({{ CATALOGS.DB_SUPPORT('n') }} AND {{ CATALOGS.DB_SUPPORT('np') }})
+    ) fd
+    {% if not all_obj %}
+    WHERE fd.obj_type = '{{ obj_type }}'
+    {% endif %}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['event_trigger'] %}
+    select 'event_trigger'::text AS obj_type, evtname AS obj_name, ':event_trigger.'||oid||':/' || evtname AS obj_path, ''::text AS schema_name,
+    {{ show_node_prefs['index'] }} AS show_node, NULL AS other_info from pg_event_trigger
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['schema'] %}
+    select 'schema'::text AS obj_type, n.nspname AS obj_name,
+    ':schema.'||n.oid||':/' || n.nspname as obj_path, n.nspname AS schema_name,
+    {{ show_node_prefs['schema'] }} AS show_node, NULL AS other_info from pg_namespace n
+    where n.nspparent = 0
+    AND {{ CATALOGS.DB_SUPPORT('n') }}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['column'] %}
+    select 'column'::text AS obj_type, a.attname AS obj_name,
+    ':schema.'||n.oid||':/' || n.nspname || '/' ||
+    case
+        WHEN t.relkind = 'r' THEN ':table.'
+        WHEN t.relkind = 'v' THEN ':view.'
+        WHEN t.relkind = 'm' THEN ':mview.'
+        else 'should not happen'
+    end || t.oid || ':/' || t.relname || '/:column.'|| a.attnum ||':/' || a.attname AS obj_path, n.nspname AS schema_name,
+    {{ show_node_prefs['column'] }} AS show_node, NULL AS other_info
+    from pg_attribute a
+    inner join pg_class t on a.attrelid = t.oid and t.relkind in ('r','v','m')
+    left join pg_namespace n on t.relnamespace = n.oid where a.attnum > 0
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['constraints', 'check_constraint', 'foreign_key', 'primary_key', 'unique_constraint', 'exclusion_constraint'] %}
+    SELECT
+    CASE
+        WHEN c.contype = 'c' THEN  'check_constraint'
+        WHEN c.contype = 'f' THEN  'foreign_key'
+        WHEN c.contype = 'p' THEN  'primary_key'
+        WHEN c.contype = 'u' THEN  'unique_constraint'
+        WHEN c.contype = 'x' THEN  'exclusion_constraint'
+    END::text AS obj_type,
+    case when tf.relname is null then c.conname else c.conname || ' -> ' || tf.relname end AS obj_name,
+    ':schema.'||n.oid||':/' || n.nspname||'/'||
+    (
+		WITH RECURSIVE table_path_data as (
+			select t.oid as oid, 0 as height,
+				CASE t.relispartition WHEN true THEN ':partition.' ELSE ':table.' END || t.oid || ':/' || t.relname as path
+			union
+			select rel.oid, pt.height+1 as height,
+				CASE rel.relispartition WHEN true THEN ':partition.' ELSE ':table.' END
+				|| rel.oid || ':/' || rel.relname || '/' || pt.path as path
+			from pg_class rel JOIN pg_namespace nsp ON rel.relnamespace = nsp.oid
+			join pg_inherits inh ON inh.inhparent = rel.oid
+			join table_path_data pt ON inh.inhrelid = pt.oid
+		)
+		select path from table_path_data order by height desc limit 1
+	) ||
+    CASE
+        WHEN c.contype = 'c' THEN  '/:check_constraint.' ||c.oid
+        WHEN c.contype = 'f' THEN  '/:foreign_key.' ||c.conindid
+        WHEN c.contype = 'p' THEN  '/:primary_key.' ||c.conindid
+        WHEN c.contype = 'u' THEN  '/:unique_constraint.' ||c.conindid
+        WHEN c.contype = 'x' THEN  '/:exclusion_constraint.' ||c.conindid
+    END ||':/'|| case when tf.relname is null then c.conname else c.conname || ' -> ' || tf.relname end AS obj_path, n.nspname AS schema_name,
+    {{ show_node_prefs['constraints'] }} AS show_node, NULL AS other_info
+    from pg_constraint c
+    left join pg_class t on c.conrelid = t.oid
+    left join pg_class tf on c.confrelid = tf.oid
+    left join pg_namespace n on t.relnamespace = n.oid
+    where c.contypid = 0
+    {% if obj_type == 'check_constraint' %}
+    AND c.contype = 'c'
+    {% elif obj_type == 'foreign_key' %}
+    AND c.contype = 'f'
+    {% elif obj_type == 'primary_key' %}
+    AND c.contype = 'p'
+    {% elif obj_type == 'unique_constraint' %}
+    AND c.contype = 'u'
+    {% elif obj_type == 'exclusion_constraint' %}
+    AND c.contype = 'x'
+    {% else %}
+    AND c.contype IN  ('c', 'f', 'p', 'u', 'x')
+    {% endif %}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['rule'] %}
+    select 'rule'::text AS obj_type, r.rulename AS obj_name, ':schema.'||n.oid||':/' || n.nspname|| '/' ||
+            case
+                when t.relkind = 'v' then ':view.'
+                when t.relkind = 'm' then ':mview.'
+                WHEN t.relkind in ('r', 'p') THEN
+                    (
+                        WITH RECURSIVE table_path_data as (
+                            select t.oid as oid, 0 as height,
+                                CASE t.relispartition WHEN true THEN ':partition.' ELSE ':table.' END || t.oid || ':/' || t.relname as path
+                            union
+                            select rel.oid, pt.height+1 as height,
+                                CASE rel.relispartition WHEN true THEN ':partition.' ELSE ':table.' END
+                                || rel.oid || ':/' || rel.relname || '/' || pt.path as path
+                            from pg_class rel JOIN pg_namespace nsp ON rel.relnamespace = nsp.oid
+                            join pg_inherits inh ON inh.inhparent = rel.oid
+                            join table_path_data pt ON inh.inhrelid = pt.oid
+                        )
+                        select path from table_path_data order by height desc limit 1
+                    )
+            end
+            ||'/:rule.'||r.oid||':/'|| r.rulename AS obj_path,
+            n.nspname AS schema_name,
+            {{ show_node_prefs['rule'] }} AS show_node, NULL AS other_info
+            from pg_rewrite r
+    left join pg_class t on r.ev_class = t.oid
+    left join pg_namespace n on t.relnamespace = n.oid
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['trigger', 'compound_trigger'] %}
+    select
+        CASE WHEN tr.tgpackageoid != 0 THEN 'compound_trigger' ELSE 'trigger' END::text AS obj_type, tr.tgname AS obj_name,
+        ':schema.'||n.oid||':/' || n.nspname|| '/' ||
+        case
+            when t.relkind = 'v' then ':view.'
+            when t.relkind = 'm' then ':mview.'
+            WHEN t.relkind in ('r', 'p') THEN
+            (
+                WITH RECURSIVE table_path_data as (
+                    select t.oid as oid, 0 as height,
+                        CASE t.relispartition WHEN true THEN ':partition.' ELSE ':table.' END || t.oid || ':/' || t.relname as path
+                    union
+                    select rel.oid, pt.height+1 as height,
+                        CASE rel.relispartition WHEN true THEN ':partition.' ELSE ':table.' END
+                        || rel.oid || ':/' || rel.relname || '/' || pt.path as path
+                    from pg_class rel JOIN pg_namespace nsp ON rel.relnamespace = nsp.oid
+                    join pg_inherits inh ON inh.inhparent = rel.oid
+                    join table_path_data pt ON inh.inhrelid = pt.oid
+                )
+                select path from table_path_data order by height desc limit 1
+            )
+        end || CASE WHEN tr.tgpackageoid != 0 THEN '/:compound_trigger.' ELSE '/:trigger.' END || tr.oid || ':/' || tr.tgname AS obj_path, n.nspname AS schema_name,
+        CASE WHEN tr.tgpackageoid != 0 THEN {{ show_node_prefs['compound_trigger'] }} ELSE {{ show_node_prefs['trigger'] }} END AS show_node,
+        NULL AS other_info
+        from pg_trigger tr
+    left join pg_class t on tr.tgrelid = t.oid
+    left join pg_namespace n on t.relnamespace = n.oid
+    where tr.tgisinternal = false
+    and {{ CATALOGS.DB_SUPPORT('n') }}
+    {% if obj_type == 'compound_trigger' %}
+    AND tr.tgpackageoid != 0
+    {% elif obj_type == 'trigger' %}
+    AND tr.tgpackageoid = 0
+    {% endif %}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['type'] %}
+    SELECT 'type'::text AS obj_type, t.typname AS obj_name, ':schema.'||n.oid||':/' || n.nspname ||
+        '/:type.'|| t.oid ||':/' || t.typname AS obj_path, n.nspname AS schema_name,
+        {{ show_node_prefs['type'] }} AS show_node, NULL AS other_info
+    FROM pg_type t
+    LEFT OUTER JOIN pg_type e ON e.oid=t.typelem
+    LEFT OUTER JOIN pg_class ct ON ct.oid=t.typrelid AND ct.relkind <> 'c'
+    LEFT OUTER JOIN pg_namespace n on t.typnamespace = n.oid
+    WHERE t.typtype != 'd' AND t.typname NOT LIKE E'\\_%'
+    {% if not show_system_objects %}
+        AND ct.oid is NULL
+    {% endif %}
+    AND {{ CATALOGS.DB_SUPPORT('n') }}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['cast'] %}
+    SELECT 'cast'::text AS obj_type, format_type(st.oid,NULL) ||'->'|| format_type(tt.oid,tt.typtypmod) AS obj_name,
+    ':cast.'||ca.oid||':/' || format_type(st.oid,NULL) ||'->'|| format_type(tt.oid,tt.typtypmod) AS obj_path, ''::text AS schema_name,
+    {{ show_node_prefs['cast'] }} AS show_node, NULL AS other_info
+    FROM pg_cast ca
+    JOIN pg_type st ON st.oid=castsource
+    JOIN pg_type tt ON tt.oid=casttarget
+    {% if not show_system_objects %}
+    WHERE ca.oid > {{last_system_oid}}::OID
+    {% endif %}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['language'] %}
+    SELECT 'language'::text AS obj_type, lanname AS obj_name, ':language.'||lan.oid||':/' || lanname AS obj_path, ''::text AS schema_name,
+    {{ show_node_prefs['language'] }} AS show_node, NULL AS other_info
+    FROM pg_language lan
+    WHERE lanispl IS TRUE
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['fts_configuration'] %}
+    SELECT 'fts_configuration'::text AS obj_type, cfg.cfgname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:fts_configuration.'||cfg.oid||':/' || cfg.cfgname AS obj_path, n.nspname AS schema_name,
+    {{ show_node_prefs['fts_configuration'] }} AS show_node, NULL AS other_info
+    FROM pg_ts_config cfg
+    left join pg_namespace n on cfg.cfgnamespace = n.oid
+    WHERE {{ CATALOGS.DB_SUPPORT('n') }}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['fts_dictionary'] %}
+    SELECT 'fts_dictionary'::text AS obj_type, dict.dictname AS obj_name, ':schema.'||ns.oid||':/' || ns.nspname || '/:fts_dictionary.'||dict.oid||':/' || dict.dictname AS obj_path, ns.nspname AS schema_name,
+    {{ show_node_prefs['fts_dictionary'] }} AS show_node, NULL AS other_info
+    FROM pg_ts_dict dict
+    left join pg_namespace ns on dict.dictnamespace = ns.oid
+    WHERE {{ CATALOGS.DB_SUPPORT('ns') }}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['fts_parser'] %}
+    SELECT 'fts_parser'::text AS obj_type, prs.prsname AS obj_name, ':schema.'||ns.oid||':/' || ns.nspname || '/:fts_parser.'||prs.oid||':/' || prs.prsname AS obj_path, ns.nspname AS schema_name,
+    {{ show_node_prefs['fts_parser'] }} AS show_node, NULL AS other_info
+    FROM pg_ts_parser prs
+    left join pg_namespace ns on prs.prsnamespace = ns.oid
+    WHERE {{ CATALOGS.DB_SUPPORT('ns') }}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['fts_template'] %}
+    SELECT 'fts_template'::text AS obj_type, tmpl.tmplname AS obj_name, ':schema.'||ns.oid||':/' || ns.nspname || '/:fts_template.'||tmpl.oid||':/' || tmpl.tmplname AS obj_path, ns.nspname AS schema_name,
+    {{ show_node_prefs['fts_template'] }} AS show_node, NULL AS other_info
+    FROM pg_ts_template tmpl
+    left join pg_namespace ns on tmpl.tmplnamespace = ns.oid
+    AND {{ CATALOGS.DB_SUPPORT('ns') }}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['domain'] %}
+    select 'domain'::text AS obj_type, t.typname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:domain.'||t.oid||':/' || t.typname AS obj_path, n.nspname AS schema_name,
+    {{ show_node_prefs['domain'] }} AS show_node, NULL AS other_info
+    from pg_type t
+    inner join pg_namespace n on t.typnamespace = n.oid
+    where t.typtype = 'd'
+    AND {{ CATALOGS.DB_SUPPORT('n') }}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['domain_constraints'] %}
+    SELECT 'domain_constraints'::text AS obj_type,
+        c.conname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:domain.'||t.oid||':/' || t.typname || '/:domain_constraints.'||c.oid||':/' || c.conname AS obj_path,
+        n.nspname AS schema_name,
+        {{ show_node_prefs['domain_constraints'] }} AS show_node, NULL AS other_info
+    FROM pg_constraint c JOIN pg_type t
+    ON t.oid=contypid JOIN pg_namespace n
+    ON n.oid=t.typnamespace
+    WHERE t.typtype = 'd'
+    AND {{ CATALOGS.DB_SUPPORT('n') }}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['foreign_data_wrapper'] %}
+    select 'foreign_data_wrapper'::text AS obj_type, fdwname AS obj_name, ':foreign_data_wrapper.'||oid||':/' || fdwname AS obj_path, ''::text AS schema_name,
+    {{ show_node_prefs['foreign_data_wrapper'] }} AS show_node, NULL AS other_info
+    from pg_foreign_data_wrapper
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['foreign_server'] %}
+    select 'foreign_server' AS obj_type, sr.srvname AS obj_name, ':foreign_data_wrapper.'||fdw.oid||':/' || fdw.fdwname || '/:foreign_server.'||sr.oid||':/' || sr.srvname AS obj_path, ''::text AS schema_name,
+    {{ show_node_prefs['foreign_server'] }} AS show_node, NULL AS other_info
+    from pg_foreign_server sr
+    inner join pg_foreign_data_wrapper fdw on sr.srvfdw = fdw.oid
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['user_mapping'] %}
+    select 'user_mapping' AS obj_type, ro.rolname AS obj_name, ':foreign_data_wrapper.'||fdw.oid||':/' || fdw.fdwname || '/:foreign_server.'||sr.oid||':/' || sr.srvname || '/:user_mapping.'||ro.oid||':/' || ro.rolname AS obj_path, ''::text AS schema_name,
+    {{ show_node_prefs['user_mapping'] }} AS show_node, NULL AS other_info
+    from pg_user_mapping um
+    inner join pg_roles ro on um.umuser = ro.oid
+    inner join pg_foreign_server sr on um.umserver = sr.oid
+    inner join pg_foreign_data_wrapper fdw on sr.srvfdw = fdw.oid
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['foreign_table'] %}
+    select 'foreign_table' AS obj_type, c.relname AS obj_name, ':schema.'||ns.oid||':/' || ns.nspname || '/:foreign_table.'||c.oid||':/' || c.relname AS obj_path, ns.nspname AS schema_name,
+    {{ show_node_prefs['foreign_table'] }} AS show_node, NULL AS other_info
+    from pg_foreign_table ft
+    inner join pg_class c on ft.ftrelid = c.oid
+    inner join pg_namespace ns on c.relnamespace = ns.oid
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['extension'] %}
+    select 'extension' AS obj_type, x.extname AS obj_name, ':extension.'||x.oid||':/' || x.extname AS obj_path, ''::text AS schema_name,
+    {{ show_node_prefs['extension'] }} AS show_node, NULL AS other_info
+    FROM pg_extension x
+    JOIN pg_namespace n on x.extnamespace=n.oid
+    join pg_available_extensions() e(name, default_version, comment) ON x.extname=e.name
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['collation'] %}
+    SELECT 'collation' AS obj_type, c.collname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:collation.'||c.oid||':/' || c.collname AS obj_path, n.nspname AS schema_name,
+    {{ show_node_prefs['collation'] }} AS show_node, NULL AS other_info
+    FROM pg_collation c
+    JOIN pg_namespace n ON n.oid=c.collnamespace
+    WHERE {{ CATALOGS.DB_SUPPORT('n') }}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['synonym'] %}
+    SELECT 'synonym' AS obj_type, s.synname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:synonym.'||s.oid||':/' || s.synname AS obj_path, n.nspname AS schema_name,
+    {{ show_node_prefs['synonym'] }} AS show_node, NULL AS other_info
+    FROM pg_synonym s
+    JOIN pg_namespace n ON n.oid=s.synnamespace
+    WHERE {{ CATALOGS.DB_SUPPORT('n') }}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['package'] %}
+    SELECT 'package' AS obj_type, p.nspname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:package.'||p.oid||':/' || p.nspname AS obj_path, n.nspname AS schema_name,
+    {{ show_node_prefs['package'] }} AS show_node, NULL AS other_info
+    FROM pg_namespace p
+    JOIN pg_namespace n ON n.oid=p.nspparent
+    WHERE p.nspcompoundtrigger = false
+    AND {{ CATALOGS.DB_SUPPORT('n') }}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['edbvar'] %}
+    SELECT 'edbvar' AS obj_type, v.varname AS obj_name,
+    ':schema.'||n.oid||':/' || n.nspname || '/:package.'||p.oid||':/' || p.nspname || '/:edbvar.'||v.oid||':/' || v.varname AS obj_path, n.nspname AS schema_name,
+    {{ show_node_prefs['edbvar'] }} AS show_node, NULL AS other_info
+    FROM edb_variable v JOIN pg_namespace p
+    ON v.varpackage = p.oid JOIN pg_namespace n
+    ON p.nspparent = n.oid
+    WHERE p.nspcompoundtrigger = false
+    AND {{ CATALOGS.DB_SUPPORT('p') }}
+    AND {{ CATALOGS.DB_SUPPORT('n') }}
+{% endif %}
+) sn
+where lower(sn.obj_name) like '%{{ search_text }}%'
+{% if not show_system_objects %}
+AND NOT ({{ CATALOGS.IS_CATALOG_SCHEMA('sn.schema_name') }})
+AND (sn.schema_name IS NOT NULL AND sn.schema_name NOT LIKE 'pg\_%')
+{% endif %}
+ORDER BY 1, 2, 3
diff --git a/web/pgadmin/tools/search_objects/templates/search_objects/sql/ppas/default/search.sql b/web/pgadmin/tools/search_objects/templates/search_objects/sql/ppas/default/search.sql
new file mode 100644
index 000000000..7bb126e32
--- /dev/null
+++ b/web/pgadmin/tools/search_objects/templates/search_objects/sql/ppas/default/search.sql
@@ -0,0 +1,437 @@
+{% import 'catalog/ppas/macros/catalogs.sql' as CATALOGS %}
+{% set all_obj = false %}
+{% if obj_type == 'all' or obj_type is none %}
+{% set all_obj = true %}
+{% endif %}
+SELECT obj_type, obj_name,
+    REPLACE(obj_path, '/'||sn.schema_name||'/', '/'||{{ CATALOGS.LABELS_SCHEMACOL('sn.schema_name', _) }}||'/') AS obj_path,
+    schema_name, show_node, other_info,
+    CASE
+        WHEN {{ CATALOGS.IS_CATALOG_SCHEMA('sn.schema_name') }} THEN
+            CASE WHEN {{ CATALOGS.DB_SUPPORT_SCHEMACOL('sn.schema_name') }} THEN 'D' ELSE 'O' END
+        ELSE 'N'
+    END AS catalog_level
+FROM (
+{% if all_obj or obj_type in ['table', 'sequence', 'view', 'mview'] %}
+    SELECT
+    CASE
+        WHEN c.relkind = 'r' THEN 'table'
+        WHEN c.relkind = 'S' THEN 'sequence'
+        WHEN c.relkind = 'v' THEN 'view'
+        WHEN c.relkind = 'm' THEN 'mview'
+        ELSE 'should not happen'
+    END::text::text AS obj_type, c.relname AS obj_name,
+    ':schema.'|| n.oid || ':/' || n.nspname || '/' ||
+    CASE
+        WHEN c.relkind = 'r' THEN ':table.'
+        WHEN c.relkind = 'S' THEN ':sequence.'
+        WHEN c.relkind = 'v' THEN ':view.'
+        WHEN c.relkind = 'm' THEN ':mview.'
+        ELSE 'should not happen'
+    END || c.oid ||':/' || c.relname AS obj_path, n.nspname AS schema_name,
+    CASE
+        WHEN c.relkind = 'r' THEN {{ show_node_prefs['table'] }}
+        WHEN c.relkind = 'S' THEN {{ show_node_prefs['sequence'] }}
+        WHEN c.relkind = 'v' THEN {{ show_node_prefs['view'] }}
+        WHEN c.relkind = 'm' THEN {{ show_node_prefs['mview'] }}
+        ELSE False
+    END AS show_node, NULL AS other_info
+    FROM pg_class c
+    LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
+    {% if all_obj %}
+    WHERE c.relkind in ('r','S','v','m')
+    {% elif obj_type == 'table' %}
+    WHERE c.relkind  = 'r'
+    {% elif obj_type == 'sequence' %}
+    WHERE c.relkind  = 'S'
+    {% elif obj_type == 'view' %}
+    WHERE c.relkind  = 'v'
+    {% elif obj_type == 'mview' %}
+    WHERE c.relkind  = 'm'
+    {% endif %}
+    AND {{ CATALOGS.DB_SUPPORT('n') }}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['index'] %}
+    SELECT 'index'::text::text AS obj_type, cls.relname AS obj_name,
+    ':schema.'|| n.oid || ':/' || n.nspname || '/:table.'|| tab.oid ||':/' || tab.relname || '/:index.'|| cls.oid ||':/' || cls.relname AS obj_path, n.nspname AS schema_name,
+    {{ show_node_prefs['index'] }} AS show_node, NULL AS other_info
+    FROM pg_index idx
+    JOIN pg_class cls ON cls.oid=indexrelid
+    JOIN pg_class tab ON tab.oid=indrelid
+    JOIN pg_namespace n ON n.oid=tab.relnamespace
+    LEFT JOIN pg_depend dep ON (dep.classid = cls.tableoid AND dep.objid = cls.oid AND dep.refobjsubid = '0' AND dep.refclassid=(SELECT oid FROM pg_class WHERE relname='pg_constraint') AND dep.deptype='i')
+    LEFT OUTER JOIN pg_constraint con ON (con.tableoid = dep.refclassid AND con.oid = dep.refobjid)
+    LEFT OUTER JOIN pg_description des ON des.objoid=cls.oid
+    LEFT OUTER JOIN pg_description desp ON (desp.objoid=con.oid AND desp.objsubid = 0)
+    WHERE contype IS NULL
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['trigger_function', 'function', 'procedure', 'edbfunc', 'edbproc'] %}
+    SELECT fd.obj_type, fd.obj_name,
+        CASE
+            WHEN fd.obj_type = 'function' THEN
+                ':schema.'|| fd.schema_oid || ':/' || fd.schema_name || '/:function.' || fd.obj_oid ||':/' || fd.obj_name
+            WHEN fd.obj_type = 'procedure' THEN
+                ':schema.'|| fd.schema_oid || ':/' || fd.schema_name || '/:procedure.' || fd.obj_oid ||':/' || fd.obj_name
+            WHEN fd.obj_type = 'trigger_function' THEN
+                ':schema.'|| fd.schema_oid || ':/' || fd.schema_name || '/:trigger_function.' || fd.obj_oid ||':/' || fd.obj_name
+            WHEN fd.obj_type = 'edbfunc' THEN
+                ':schema.'|| fd.next_schema_oid || ':/' || fd.next_schema_name || '/:package.'|| fd.schema_oid || ':/' || fd.schema_name || '/:edbfunc.' || fd.obj_oid ||':/' || fd.obj_name
+            WHEN fd.obj_type = 'edbproc' THEN
+                ':schema.'|| fd.next_schema_oid || ':/' || fd.next_schema_name || '/:package.'|| fd.schema_oid || ':/' || fd.schema_name || '/:edbproc.' || fd.obj_oid ||':/' || fd.obj_name
+            ELSE NULL
+        END AS obj_path,
+        CASE
+            WHEN fd.obj_type IN ('function', 'procedure', 'trigger_function') THEN fd.schema_name
+            WHEN fd.obj_type IN ('edbfunc', 'edbproc') THEN fd.next_schema_name
+            ELSE NULL
+        END AS schema_name,
+        CASE
+            WHEN fd.obj_type = 'function' THEN {{ show_node_prefs['function'] }}
+            WHEN fd.obj_type = 'procedure' THEN {{ show_node_prefs['procedure'] }}
+            WHEN fd.obj_type = 'trigger_function' THEN {{ show_node_prefs['trigger_function'] }}
+            WHEN fd.obj_type = 'edbfunc' THEN {{ show_node_prefs['edbfunc'] }}
+            WHEN fd.obj_type = 'edbproc' THEN {{ show_node_prefs['edbproc'] }}
+            ELSE NULL
+        END AS show_node, other_info
+    FROM (
+        SELECT
+            CASE
+            WHEN t.typname IN ('trigger', 'event_trigger') THEN 'trigger_function'
+            WHEN pr.protype = '0'::char THEN
+                CASE WHEN np.oid IS NOT NULL THEN 'edbfunc' ELSE 'function' END
+            WHEN pr.protype = '1'::char THEN
+                CASE WHEN np.oid IS NOT NULL THEN 'edbproc' ELSE 'procedure' END
+            ELSE null
+            END::text::text AS obj_type, pr.proname AS obj_name, pr.oid AS obj_oid, n.oid AS schema_oid, n.nspname AS schema_name, np.oid next_schema_oid, np.nspname next_schema_name,
+            pg_catalog.pg_get_function_identity_arguments(pr.oid) AS other_info
+        FROM pg_proc pr left join pg_namespace n
+        ON pr.pronamespace = n.oid left JOIN pg_namespace np
+        ON np.oid=n.nspparent left JOIN pg_type t
+        ON t.oid = pr.prorettype left JOIN pg_language l
+        ON l.oid = pr.prolang
+        WHERE NOT (t.typname = 'trigger' AND l.lanname = 'edbspl')
+        AND ({{ CATALOGS.DB_SUPPORT('n') }} AND {{ CATALOGS.DB_SUPPORT('np') }})
+    ) fd
+    {% if not all_obj %}
+    WHERE fd.obj_type = '{{ obj_type }}'
+    {% endif %}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['event_trigger'] %}
+    select 'event_trigger'::text::text AS obj_type, evtname AS obj_name, ':event_trigger.'||oid||':/' || evtname AS obj_path, ''::text AS schema_name,
+    {{ show_node_prefs['index'] }} AS show_node, NULL AS other_info from pg_event_trigger
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['schema'] %}
+    select 'schema'::text::text AS obj_type, n.nspname AS obj_name,
+    ':schema.'||n.oid||':/' || n.nspname as obj_path, n.nspname AS schema_name,
+    {{ show_node_prefs['schema'] }} AS show_node, NULL AS other_info from pg_namespace n
+    where n.nspparent = 0
+    AND {{ CATALOGS.DB_SUPPORT('n') }}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['column'] %}
+    select 'column'::text::text AS obj_type, a.attname AS obj_name,
+    ':schema.'||n.oid||':/' || n.nspname || '/' ||
+    case
+        WHEN t.relkind = 'r' THEN ':table.'
+        WHEN t.relkind = 'v' THEN ':view.'
+        WHEN t.relkind = 'm' THEN ':mview.'
+        else 'should not happen'
+    end || t.oid || ':/' || t.relname || '/:column.'|| a.attnum ||':/' || a.attname AS obj_path, n.nspname AS schema_name,
+    {{ show_node_prefs['column'] }} AS show_node, NULL AS other_info
+    from pg_attribute a
+    inner join pg_class t on a.attrelid = t.oid and t.relkind in ('r','v','m')
+    left join pg_namespace n on t.relnamespace = n.oid where a.attnum > 0
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['constraints', 'check_constraint', 'foreign_key', 'primary_key', 'unique_constraint', 'exclusion_constraint'] %}
+    SELECT
+    CASE
+        WHEN c.contype = 'c' THEN  'check_constraint'
+        WHEN c.contype = 'f' THEN  'foreign_key'
+        WHEN c.contype = 'p' THEN  'primary_key'
+        WHEN c.contype = 'u' THEN  'unique_constraint'
+        WHEN c.contype = 'x' THEN  'exclusion_constraint'
+    END::text::text AS obj_type,
+    case when tf.relname is null then c.conname else c.conname || ' -> ' || tf.relname end AS obj_name,
+    ':schema.'||n.oid||':/' || n.nspname||'/:table.'|| t.oid || ':/'||t.relname||
+    CASE
+        WHEN c.contype = 'c' THEN  '/:check_constraint.' ||c.oid
+        WHEN c.contype = 'f' THEN  '/:foreign_key.' ||c.conindid
+        WHEN c.contype = 'p' THEN  '/:primary_key.' ||c.conindid
+        WHEN c.contype = 'u' THEN  '/:unique_constraint.' ||c.conindid
+        WHEN c.contype = 'x' THEN  '/:exclusion_constraint.' ||c.conindid
+    END ||':/'|| case when tf.relname is null then c.conname else c.conname || ' -> ' || tf.relname end AS obj_path, n.nspname AS schema_name,
+    {{ show_node_prefs['constraints'] }} AS show_node, NULL AS other_info
+    from pg_constraint c
+    left join pg_class t on c.conrelid = t.oid
+    left join pg_class tf on c.confrelid = tf.oid
+    left join pg_namespace n on t.relnamespace = n.oid
+    where c.contypid = 0
+    {% if obj_type == 'check_constraint' %}
+    AND c.contype = 'c'
+    {% elif obj_type == 'foreign_key' %}
+    AND c.contype = 'f'
+    {% elif obj_type == 'primary_key' %}
+    AND c.contype = 'p'
+    {% elif obj_type == 'unique_constraint' %}
+    AND c.contype = 'u'
+    {% elif obj_type == 'exclusion_constraint' %}
+    AND c.contype = 'x'
+    {% else %}
+    AND c.contype IN  ('c', 'f', 'p', 'u', 'x')
+    {% endif %}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['rule'] %}
+    select 'rule'::text::text AS obj_type, r.rulename AS obj_name, ':schema.'||n.oid||':/' || n.nspname||
+            case
+                WHEN t.relkind = 'r' THEN '/:table.'
+                when t.relkind = 'v' then '/:view.'
+                when t.relkind = 'm' then '/:mview.'
+                else 'should not happen'
+            end || t.oid || ':/' || t.relname ||'/:rule.'||r.oid||':/'|| r.rulename AS obj_path,
+            n.nspname AS schema_name,
+            {{ show_node_prefs['rule'] }} AS show_node, NULL AS other_info
+            from pg_rewrite r
+    left join pg_class t on r.ev_class = t.oid
+    left join pg_namespace n on t.relnamespace = n.oid
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['trigger'] %}
+    select 'trigger'::text::text AS obj_type, tr.tgname AS obj_name, ':schema.'||n.oid||':/' || n.nspname||
+            case
+                WHEN t.relkind = 'r' THEN '/:table.'
+                when t.relkind = 'v' then '/:view.'
+                when t.relkind = 'm' then '/:mview.'
+                else 'should not happen'
+            end || t.oid || ':/' || t.relname || '/:trigger.'|| tr.oid || ':/' || tr.tgname AS obj_path, n.nspname AS schema_name,
+            {{ show_node_prefs['trigger'] }} AS show_node, NULL AS other_info
+            from pg_trigger tr
+    left join pg_class t on tr.tgrelid = t.oid
+    left join pg_namespace n on t.relnamespace = n.oid
+    where tr.tgisinternal = false
+    and {{ CATALOGS.DB_SUPPORT('n') }}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['type'] %}
+    SELECT 'type'::text::text AS obj_type, t.typname AS obj_name, ':schema.'||n.oid||':/' || n.nspname ||
+        '/:type.'|| t.oid ||':/' || t.typname AS obj_path, n.nspname AS schema_name,
+        {{ show_node_prefs['type'] }} AS show_node, NULL AS other_info
+    FROM pg_type t
+    LEFT OUTER JOIN pg_type e ON e.oid=t.typelem
+    LEFT OUTER JOIN pg_class ct ON ct.oid=t.typrelid AND ct.relkind <> 'c'
+    LEFT OUTER JOIN pg_namespace n on t.typnamespace = n.oid
+    WHERE t.typtype != 'd' AND t.typname NOT LIKE E'\\_%'
+    {% if not show_system_objects %}
+        AND ct.oid is NULL
+    {% endif %}
+    AND {{ CATALOGS.DB_SUPPORT('n') }}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['cast'] %}
+    SELECT 'cast'::text::text AS obj_type, format_type(st.oid,NULL) ||'->'|| format_type(tt.oid,tt.typtypmod) AS obj_name,
+    ':cast.'||ca.oid||':/' || format_type(st.oid,NULL) ||'->'|| format_type(tt.oid,tt.typtypmod) AS obj_path, ''::text AS schema_name,
+    {{ show_node_prefs['cast'] }} AS show_node, NULL AS other_info
+    FROM pg_cast ca
+    JOIN pg_type st ON st.oid=castsource
+    JOIN pg_type tt ON tt.oid=casttarget
+    {% if not show_system_objects %}
+    WHERE ca.oid > {{last_system_oid}}::OID
+    {% endif %}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['language'] %}
+    SELECT 'language'::text::text AS obj_type, lanname AS obj_name, ':language.'||lan.oid||':/' || lanname AS obj_path, ''::text AS schema_name,
+    {{ show_node_prefs['language'] }} AS show_node, NULL AS other_info
+    FROM pg_language lan
+    WHERE lanispl IS TRUE
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['fts_configuration'] %}
+    SELECT 'fts_configuration'::text::text AS obj_type, cfg.cfgname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:fts_configuration.'||cfg.oid||':/' || cfg.cfgname AS obj_path, n.nspname AS schema_name,
+    {{ show_node_prefs['fts_configuration'] }} AS show_node, NULL AS other_info
+    FROM pg_ts_config cfg
+    left join pg_namespace n on cfg.cfgnamespace = n.oid
+    WHERE {{ CATALOGS.DB_SUPPORT('n') }}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['fts_dictionary'] %}
+    SELECT 'fts_dictionary'::text::text AS obj_type, dict.dictname AS obj_name, ':schema.'||ns.oid||':/' || ns.nspname || '/:fts_dictionary.'||dict.oid||':/' || dict.dictname AS obj_path, ns.nspname AS schema_name,
+    {{ show_node_prefs['fts_dictionary'] }} AS show_node, NULL AS other_info
+    FROM pg_ts_dict dict
+    left join pg_namespace ns on dict.dictnamespace = ns.oid
+    WHERE {{ CATALOGS.DB_SUPPORT('ns') }}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['fts_parser'] %}
+    SELECT 'fts_parser'::text::text AS obj_type, prs.prsname AS obj_name, ':schema.'||ns.oid||':/' || ns.nspname || '/:fts_parser.'||prs.oid||':/' || prs.prsname AS obj_path, ns.nspname AS schema_name,
+    {{ show_node_prefs['fts_parser'] }} AS show_node, NULL AS other_info
+    FROM pg_ts_parser prs
+    left join pg_namespace ns on prs.prsnamespace = ns.oid
+    WHERE {{ CATALOGS.DB_SUPPORT('ns') }}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['fts_template'] %}
+    SELECT 'fts_template'::text::text AS obj_type, tmpl.tmplname AS obj_name, ':schema.'||ns.oid||':/' || ns.nspname || '/:fts_template.'||tmpl.oid||':/' || tmpl.tmplname AS obj_path, ns.nspname AS schema_name,
+    {{ show_node_prefs['fts_template'] }} AS show_node, NULL AS other_info
+    FROM pg_ts_template tmpl
+    left join pg_namespace ns on tmpl.tmplnamespace = ns.oid
+    AND {{ CATALOGS.DB_SUPPORT('ns') }}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['domain'] %}
+    select 'domain'::text::text AS obj_type, t.typname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:domain.'||t.oid||':/' || t.typname AS obj_path, n.nspname AS schema_name,
+    {{ show_node_prefs['domain'] }} AS show_node, NULL AS other_info
+    from pg_type t
+    inner join pg_namespace n on t.typnamespace = n.oid
+    where t.typtype = 'd'
+    AND {{ CATALOGS.DB_SUPPORT('n') }}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['domain_constraints'] %}
+    SELECT 'domain_constraints'::text::text AS obj_type,
+        c.conname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:domain.'||t.oid||':/' || t.typname || '/:domain_constraints.'||c.oid||':/' || c.conname AS obj_path,
+        n.nspname AS schema_name,
+        {{ show_node_prefs['domain_constraints'] }} AS show_node, NULL AS other_info
+    FROM pg_constraint c JOIN pg_type t
+    ON t.oid=contypid JOIN pg_namespace n
+    ON n.oid=t.typnamespace
+    WHERE t.typtype = 'd'
+    AND {{ CATALOGS.DB_SUPPORT('n') }}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['foreign_data_wrapper'] %}
+    select 'foreign_data_wrapper'::text AS obj_type, fdwname AS obj_name, ':foreign_data_wrapper.'||oid||':/' || fdwname AS obj_path, ''::text AS schema_name,
+    {{ show_node_prefs['foreign_data_wrapper'] }} AS show_node, NULL AS other_info
+    from pg_foreign_data_wrapper
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['foreign_server'] %}
+    select 'foreign_server'::text AS obj_type, sr.srvname AS obj_name, ':foreign_data_wrapper.'||fdw.oid||':/' || fdw.fdwname || '/:foreign_server.'||sr.oid||':/' || sr.srvname AS obj_path, ''::text AS schema_name,
+    {{ show_node_prefs['foreign_server'] }} AS show_node, NULL AS other_info
+    from pg_foreign_server sr
+    inner join pg_foreign_data_wrapper fdw on sr.srvfdw = fdw.oid
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['user_mapping'] %}
+    select 'user_mapping'::text AS obj_type, ro.rolname AS obj_name, ':foreign_data_wrapper.'||fdw.oid||':/' || fdw.fdwname || '/:foreign_server.'||sr.oid||':/' || sr.srvname || '/:user_mapping.'||ro.oid||':/' || ro.rolname AS obj_path, ''::text AS schema_name,
+    {{ show_node_prefs['user_mapping'] }} AS show_node, NULL AS other_info
+    from pg_user_mapping um
+    inner join pg_roles ro on um.umuser = ro.oid
+    inner join pg_foreign_server sr on um.umserver = sr.oid
+    inner join pg_foreign_data_wrapper fdw on sr.srvfdw = fdw.oid
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['foreign_table'] %}
+    select 'foreign_table'::text AS obj_type, c.relname AS obj_name, ':schema.'||ns.oid||':/' || ns.nspname || '/:foreign_table.'||c.oid||':/' || c.relname AS obj_path, ns.nspname AS schema_name,
+    {{ show_node_prefs['foreign_table'] }} AS show_node, NULL AS other_info
+    from pg_foreign_table ft
+    inner join pg_class c on ft.ftrelid = c.oid
+    inner join pg_namespace ns on c.relnamespace = ns.oid
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['extension'] %}
+    select 'extension'::text AS obj_type, x.extname AS obj_name, ':extension.'||x.oid||':/' || x.extname AS obj_path, ''::text AS schema_name,
+    {{ show_node_prefs['extension'] }} AS show_node, NULL AS other_info
+    FROM pg_extension x
+    JOIN pg_namespace n on x.extnamespace=n.oid
+    join pg_available_extensions() e(name, default_version, comment) ON x.extname=e.name
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['collation'] %}
+    SELECT 'collation'::text AS obj_type, c.collname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:collation.'||c.oid||':/' || c.collname AS obj_path, n.nspname AS schema_name,
+    {{ show_node_prefs['collation'] }} AS show_node, NULL AS other_info
+    FROM pg_collation c
+    JOIN pg_namespace n ON n.oid=c.collnamespace
+    WHERE {{ CATALOGS.DB_SUPPORT('n') }}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['synonym'] %}
+    SELECT 'synonym'::text AS obj_type, s.synname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:synonym.'||s.oid||':/' || s.synname AS obj_path, n.nspname AS schema_name,
+    {{ show_node_prefs['synonym'] }} AS show_node, NULL AS other_info
+    FROM pg_synonym s
+    JOIN pg_namespace n ON n.oid=s.synnamespace
+    WHERE {{ CATALOGS.DB_SUPPORT('n') }}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['package'] %}
+    SELECT 'package'::text AS obj_type, p.nspname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:package.'||p.oid||':/' || p.nspname AS obj_path, n.nspname AS schema_name,
+    {{ show_node_prefs['package'] }} AS show_node, NULL AS other_info
+    FROM pg_namespace p
+    JOIN pg_namespace n ON n.oid=p.nspparent
+    WHERE {{ CATALOGS.DB_SUPPORT('n') }}
+{% endif %}
+{% if all_obj %}
+    UNION
+{% endif %}
+{% if all_obj or obj_type in ['edbvar'] %}
+    SELECT 'edbvar'::text AS obj_type, v.varname AS obj_name,
+    ':schema.'||n.oid||':/' || n.nspname || '/:package.'||p.oid||':/' || p.nspname || '/:edbvar.'||v.oid||':/' || v.varname AS obj_path, n.nspname AS schema_name,
+    {{ show_node_prefs['edbvar'] }} AS show_node, NULL AS other_info
+    FROM edb_variable v JOIN pg_namespace p
+    ON v.varpackage = p.oid JOIN pg_namespace n
+    ON p.nspparent = n.oid
+    WHERE {{ CATALOGS.DB_SUPPORT('p') }}
+    AND {{ CATALOGS.DB_SUPPORT('n') }}
+{% endif %}
+) sn
+where lower(sn.obj_name) like '%{{ search_text }}%'
+{% if not show_system_objects %}
+AND NOT ({{ CATALOGS.IS_CATALOG_SCHEMA('sn.schema_name') }})
+AND (sn.schema_name IS NOT NULL AND sn.schema_name NOT LIKE 'pg\_%')
+{% endif %}
+ORDER BY 1, 2, 3
diff --git a/web/pgadmin/tools/search_objects/tests/__init__.py b/web/pgadmin/tools/search_objects/tests/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/web/pgadmin/tools/search_objects/tests/test_api_search.py b/web/pgadmin/tools/search_objects/tests/test_api_search.py
new file mode 100644
index 000000000..3952006d2
--- /dev/null
+++ b/web/pgadmin/tools/search_objects/tests/test_api_search.py
@@ -0,0 +1,75 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2020, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+from __future__ import print_function
+import sys
+import json
+
+from pgadmin.utils.route import BaseTestGenerator
+from regression import parent_node_dict
+from pgadmin.browser.server_groups.servers.databases.tests import utils as \
+    database_utils
+from regression.python_test_utils import test_utils as utils
+
+try:
+    from urllib import urlencode
+except Exception as e:
+    from urllib.parse import urlencode
+
+
+class SearchObjectsApiSearch(BaseTestGenerator):
+    """ This class will test search API of search objects. """
+    scenarios = [
+        ('Search with all types', dict(text='emp', type='all', singles=False)),
+        ('Search with None types', dict(text='emp', type=None, singles=False)),
+        ('Search for all single types',
+         dict(text='emp', type=None, singles=True)),
+    ]
+
+    def runFor(self, text=None, type=None):
+        url_params = dict(
+            text=text
+        )
+        if type is not None:
+            url_params['type'] = type
+
+        url_params = urlencode(url_params)
+        response = self.tester.get(self.base_url + '?' + url_params)
+
+        self.assertEquals(response.status_code, 200)
+
+    def runTest(self):
+        database_info = parent_node_dict["database"][-1]
+        server_id = database_info["server_id"]
+        db_id = database_info["db_id"]
+
+        db_con = database_utils.connect_database(self,
+                                                 utils.SERVER_GROUP,
+                                                 server_id,
+                                                 db_id)
+        if not db_con["info"] == "Database connected.":
+            raise Exception("Could not connect to database to add the schema.")
+
+        self.base_url = '/search_objects/search/' \
+                        + str(server_id) + '/' + str(db_id)
+
+        if not self.singles:
+            self.runFor(text=self.text, type=self.type)
+        else:
+            # test for all the node types individually
+            types_url = '/search_objects/types/' +\
+                        str(server_id) + '/' + str(db_id)
+            response = self.tester.get(types_url)
+            self.assertEquals(response.status_code, 200)
+            types_data = json.loads(response.data.decode('utf-8'))['data']
+
+            for a_type in types_data:
+                print('Running search for type {0}'.format(a_type),
+                      file=sys.stderr)
+                self.runFor(text=self.text, type=a_type)
diff --git a/web/pgadmin/tools/search_objects/tests/test_api_types.py b/web/pgadmin/tools/search_objects/tests/test_api_types.py
new file mode 100644
index 000000000..aed5571ad
--- /dev/null
+++ b/web/pgadmin/tools/search_objects/tests/test_api_types.py
@@ -0,0 +1,47 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2020, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+import json
+from pgadmin.utils.route import BaseTestGenerator
+from regression import parent_node_dict
+from pgadmin.browser.server_groups.servers.databases.tests import utils as \
+    database_utils
+from regression.python_test_utils import test_utils as utils
+
+
+class SearchObjectsApiTypes(BaseTestGenerator):
+    """ This class will test types API of search objects. """
+    scenarios = [
+        # Fetching default URL for schema node.
+        ('Types API URL', dict(url='/search_objects/types'))
+    ]
+
+    def runTest(self):
+        database_info = parent_node_dict["database"][-1]
+        server_id = database_info["server_id"]
+
+        db_id = database_info["db_id"]
+        db_con = database_utils.connect_database(self,
+                                                 utils.SERVER_GROUP,
+                                                 server_id,
+                                                 db_id)
+        if not db_con["info"] == "Database connected.":
+            raise Exception("Could not connect to database to add the schema.")
+
+        url = self.url + '/' + str(server_id) + '/' + str(db_id)
+        response = self.tester.get(url)
+        self.assertEquals(response.status_code, 200)
+
+        # repsonse data should be dict
+        response_data = json.loads(response.data.decode('utf-8'))['data']
+        self.assertEquals(type(response_data), dict)
+
+        # response data key values should not be None
+        for key, value in response_data.items():
+            self.assertIsNotNone(value, 'Key {0} has value None'.format(key))
diff --git a/web/pgadmin/tools/search_objects/tests/test_search_objects_helper.py b/web/pgadmin/tools/search_objects/tests/test_search_objects_helper.py
new file mode 100644
index 000000000..ec9c369b9
--- /dev/null
+++ b/web/pgadmin/tools/search_objects/tests/test_search_objects_helper.py
@@ -0,0 +1,117 @@
+import sys
+
+from pgadmin.tools.search_objects.utils import SearchObjectsHelper, current_app
+from pgadmin.utils.route import BaseTestGenerator
+
+if sys.version_info < (3, 3):
+    from mock import patch, MagicMock
+else:
+    from unittest.mock import patch, MagicMock
+
+
+class SearchObjectsHelperTest(BaseTestGenerator):
+    scenarios = [
+        ('scenario', dict(
+            node_blueprints=[
+                dict(node_type='table', coll_label='Tables',
+                     backend_supported=True),
+                dict(node_type='view', coll_label='Views',
+                     backend_supported=False),
+                dict(node_type='index', coll_label='Indexes',
+                     backend_supported=True),
+                dict(node_type='role', coll_label='Roles',
+                     backend_supported=True)
+            ],
+            all_node_types=['table', 'view', 'index'],
+            expected_show_node_prefs=dict(table=True, view=False, index=True),
+            expected_supported_types=dict(table='Tables', index='Indexes'),
+            expected_supported_types_skip=dict(table='Tables', view='Views',
+                                               index='Indexes'),
+            execute_dict_return_value=(
+                True, dict(rows=[
+                    dict(obj_name='name1', obj_type='table',
+                         obj_path='some/path', show_node=True,
+                         other_info=None, catalog_level='N'),
+                    dict(obj_name='name2', obj_type='view',
+                         obj_path='some1/path', show_node=True,
+                         other_info=None, catalog_level='D'),
+                    dict(obj_name='name3', obj_type='index',
+                         obj_path='some2/path1', show_node=True,
+                         other_info='oid', catalog_level='O'),
+                ])),
+            expected_search_op=(
+                True, [
+                    dict(name='name1', type='table', type_label='Tables',
+                         path='some/path',
+                         show_node=True, other_info=None, catalog_level='N'),
+                    dict(name='name2', type='view', type_label='Views',
+                         path='some1/path',
+                         show_node=True, other_info=None, catalog_level='D'),
+                    dict(name='name3', type='index', type_label='Indexes',
+                         path='some2/path1',
+                         show_node=True, other_info='oid', catalog_level='O'),
+                ]
+            )
+        ))
+    ]
+
+    def __create_manager(self):
+        connection = MagicMock(
+            execute_dict=MagicMock(),
+            db='somedb'
+        )
+        connection.execute_dict.return_value = self.execute_dict_return_value
+
+        def connection_function(did):
+            return connection
+
+        return MagicMock(
+            connection=connection_function
+        )
+
+    @patch('pgadmin.tools.search_objects.utils.get_node_blueprint')
+    @patch('pgadmin.tools.search_objects.utils.get_driver')
+    def runTest(self, get_driver_mock, get_node_blueprint_mock):
+        manager = self.__create_manager()
+
+        get_driver_mock.return_value = MagicMock(
+            connection_manager=lambda session_id: manager)
+
+        def __get_node_blueprint_mock(node_type):
+            blueprints = self.node_blueprints
+            blueprint = None
+            for data in blueprints:
+                if node_type == data['node_type']:
+                    blueprint = MagicMock(
+                        BackendSupported=MagicMock(
+                            return_value=data['backend_supported']),
+                        collection_label=data['coll_label'],
+                        show_node=data['backend_supported'],
+                    )
+            return blueprint
+
+        get_node_blueprint_mock.side_effect = __get_node_blueprint_mock
+
+        with self.app.app_context():
+
+            so_obj = SearchObjectsHelper(2, 18456,
+                                         node_types=self.all_node_types)
+            so_obj.get_sql = MagicMock(return_value='dummy query')
+
+            # test template path
+            manager.server_type = 'pg'
+            manager.version = 906000
+            self.assertEquals(so_obj.get_template_path(),
+                              'search_objects/sql/pg/#906000#')
+
+            self.assertEquals(so_obj.get_show_node_prefs(),
+                              self.expected_show_node_prefs)
+
+            self.assertEquals(so_obj.get_supported_types(),
+                              self.expected_supported_types)
+
+            self.assertEquals(so_obj.get_supported_types(skip_check=True),
+                              self.expected_supported_types_skip)
+
+            self.assertEquals(so_obj.search('searchtext', 'all'),
+                              self.expected_search_op)
diff --git a/web/pgadmin/tools/search_objects/utils.py b/web/pgadmin/tools/search_objects/utils.py
new file mode 100644
index 000000000..cf858d6e2
--- /dev/null
+++ b/web/pgadmin/tools/search_objects/utils.py
@@ -0,0 +1,131 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2020, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+from flask import current_app, render_template
+from flask_babelex import gettext
+
+from pgadmin.utils.driver import get_driver
+from config import PG_DEFAULT_DRIVER
+
+
+def get_node_blueprint(node_type):
+    blueprint = None
+    node_type = 'NODE-' + node_type
+    if node_type in current_app.blueprints:
+        blueprint = current_app.blueprints[node_type]
+
+    return blueprint
+
+
+class SearchObjectsHelper:
+    def __init__(self, sid, did, show_system_objects=False, node_types=None):
+        self.sid = sid
+        self.did = did
+        self.show_system_objects = show_system_objects
+        self.manager = get_driver(
+            PG_DEFAULT_DRIVER
+        ).connection_manager(sid)
+
+        self._all_node_types = [
+            'cast', 'fts_dictionary', 'check_constraint',
+            'exclusion_constraint', 'foreign_key',
+            'primary_key', 'unique_constraint', 'constraints', 'trigger',
+            'table', 'compound_trigger', 'rule', 'column', 'partition',
+            'index', 'type', 'domain', 'domain_constraints', 'schema',
+            'synonym', 'sequence', 'edbvar', 'edbfunc', 'edbproc', 'package',
+            'foreign_table', 'fts_parser', 'function', 'procedure',
+            'trigger_function', 'fts_template', 'collation', 'view', 'mview',
+            'fts_configuration', 'extension', 'language',
+            'event_trigger', 'foreign_server', 'user_mapping',
+            'foreign_data_wrapper'
+        ] if node_types is None else node_types
+
+    @property
+    def all_node_types(self):
+        return self._all_node_types
+
+    def get_template_path(self):
+        return 'search_objects/sql/{0}/#{1}#'.format(
+            self.manager.server_type, self.manager.version)
+
+    def get_show_node_prefs(self):
+        return_types = {}
+        for node_type in self.all_node_types:
+            blueprint = get_node_blueprint(node_type)
+            if blueprint is None:
+                continue
+
+            return_types[node_type] = blueprint.show_node
+        return return_types
+
+    def get_supported_types(self, skip_check=False):
+        return_types = {}
+        for node_type in self.all_node_types:
+            blueprint = get_node_blueprint(node_type)
+            if blueprint is None:
+                continue
+
+            if blueprint.BackendSupported(self.manager, is_catalog=False,
+                                          did=self.did) or skip_check:
+                if node_type in ['edbfunc', 'edbproc']:
+                    return_types[node_type] =\
+                        gettext('Package {0}').format(
+                            blueprint.collection_label)
+                else:
+                    return_types[node_type] = blueprint.collection_label
+
+        return return_types
+
+    def get_sql(self, sql_file, **kwargs):
+        return render_template(
+            "/".join([self.get_template_path(), sql_file]),
+            **kwargs
+        )
+
+    def finalize_id_path(self, path, base_path):
+        if base_path is not None:
+            path = '{0}/{1}'.format(base_path, path)
+
+        return path
+
+    def search(self, text, obj_type=None):
+        conn = self.manager.connection(did=self.did)
+        last_system_oid = (self.manager.db_info[self.did])['datlastsysoid'] \
+            if self.manager.db_info is not None and self.did in \
+            self.manager.db_info else 0
+
+        show_node_prefs = self.get_show_node_prefs()
+        node_labels = self.get_supported_types(skip_check=True)
+        # Column catalog_level has values as
+        # N - Not a catalog schema
+        # D - Catalog schema with DB support - pg_catalog
+        # O - Catalog schema with object support only - info schema, dbo, sys
+        status, res = conn.execute_dict(
+            self.get_sql('search.sql', search_text=text, obj_type=obj_type,
+                         show_system_objects=self.show_system_objects,
+                         show_node_prefs=show_node_prefs, _=gettext,
+                         last_system_oid=last_system_oid)
+        )
+
+        if not status:
+            return status, res
+
+        ret_val = [
+            {
+                'name': row['obj_name'],
+                'type': row['obj_type'],
+                'type_label': node_labels[row['obj_type']],
+                'path': row['obj_path'],
+                'show_node': row['show_node'],
+                'other_info': row['other_info'],
+                'catalog_level': row['catalog_level'],
+            }
+            for row in res['rows']
+        ]
+        return True, ret_val
diff --git a/web/pgadmin/tools/sqleditor/static/css/sqleditor.css b/web/pgadmin/tools/sqleditor/static/css/sqleditor.css
index 52b821d8b..f9d15b8da 100644
--- a/web/pgadmin/tools/sqleditor/static/css/sqleditor.css
+++ b/web/pgadmin/tools/sqleditor/static/css/sqleditor.css
@@ -112,7 +112,7 @@ li {
   font-size: 9pt;
 }
 
-.slick-header-column.ui-state-default {
+#datagrid .slick-header-column.ui-state-default {
     height: 32px !important;
 }
 
diff --git a/web/regression/javascript/fake_endpoints.js b/web/regression/javascript/fake_endpoints.js
index fa01b3f89..157a34863 100644
--- a/web/regression/javascript/fake_endpoints.js
+++ b/web/regression/javascript/fake_endpoints.js
@@ -19,5 +19,7 @@ define(function () {
     'datagrid.initialize_query_tool_with_did': '/initialize/query_tool/<int:sgid>/<int:sid>/<int:did>',
     'restore.create_job': '/restore/job/<int:sid>',
     'datagrid.panel': '/panel/<int:trans_id>',
+    'search_objects.types': '/search_objects/types/<int:sid>/<int:did>',
+    'search_objects.search': '/search_objects/search/<int:sid>/<int:did>',
   };
 });
diff --git a/web/regression/javascript/search_objects/search_objects_dialog_spec.js b/web/regression/javascript/search_objects/search_objects_dialog_spec.js
new file mode 100644
index 000000000..039db1970
--- /dev/null
+++ b/web/regression/javascript/search_objects/search_objects_dialog_spec.js
@@ -0,0 +1,155 @@
+/////////////////////////////////////////////////////////////
+//
+// pgAdmin 4 - PostgreSQL Tools
+//
+// Copyright (C) 2013 - 2020, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+//////////////////////////////////////////////////////////////
+import SearchObjectsDialog from 'tools/search_objects/static/js/search_objects_dialog';
+import {TreeFake} from '../tree/tree_fake';
+import MockAdapter from 'axios-mock-adapter';
+import axios from 'axios/index';
+
+const context = describe;
+
+describe('SearchObjectsDialog', () => {
+  let soDialog;
+  let pgBrowser;
+  let jquerySpy;
+  let alertifySpy;
+
+  beforeEach(() => {
+    pgBrowser = {
+      treeMenu: new TreeFake(),
+      Nodes: {
+        server: {
+          hasId: true,
+          label: 'server',
+          getTreeNodeHierarchy: jasmine.createSpy('server.getTreeNodeHierarchy'),
+        },
+        database: {
+          hasId: true,
+          label: 'database',
+          getTreeNodeHierarchy: jasmine.createSpy('db.getTreeNodeHierarchy'),
+        },
+        schema: {
+          hasId: true,
+          label: 'schema',
+          getTreeNodeHierarchy: jasmine.createSpy('db.getTreeNodeHierarchy'),
+        },
+      },
+      stdW: {
+        sm: 500,
+        md: 700,
+        lg: 900,
+        default: 500,
+      },
+      stdH: {
+        sm: 200,
+        md: 400,
+        lg: 550,
+        default: 550,
+      },
+    };
+    pgBrowser.Nodes.server.hasId = true;
+    pgBrowser.Nodes.database.hasId = true;
+    jquerySpy = jasmine.createSpy('jquerySpy');
+
+    const hierarchy = {
+      children: [
+        {
+          id: 'root',
+          children: [
+            {
+              id: 'serverTreeNode',
+              data: {
+                _id: 10,
+                _type: 'server',
+                user: {name: 'username'},
+                label: 'theserver',
+              },
+              children: [
+                {
+                  id: 'some_database',
+                  data: {
+                    _type: 'database',
+                    _id: 11,
+                    label: 'thedatabase',
+                  },
+                },
+              ],
+            },
+            {
+              id: 'ppasServer',
+              data: {
+                _type: 'server',
+                server_type: 'ppas',
+                children: [
+                  {id: 'someNodeUnderneathPPASServer'},
+                ],
+              },
+            },
+          ],
+        },
+      ],
+    };
+
+    pgBrowser.treeMenu = TreeFake.build(hierarchy);
+  });
+
+  describe('#draw', () => {
+    let networkMock;
+    beforeEach(() => {
+      networkMock = new MockAdapter(axios);
+      alertifySpy = jasmine.createSpyObj('alertify', ['alert', 'dialog']);
+      alertifySpy['search_objects'] = jasmine.createSpy('search_objects');
+      soDialog = new SearchObjectsDialog(
+        pgBrowser,
+        jquerySpy,
+        alertifySpy,
+        null
+      );
+
+      pgBrowser.get_preference = jasmine.createSpy('get_preferences');
+    });
+
+    afterEach(() => {
+      networkMock.restore();
+    });
+
+    context('there are no ancestors of the type database', () => {
+      it('does not create a dialog', () => {
+        pgBrowser.treeMenu.selectNode([{id: 'serverTreeNode'}]);
+        soDialog.draw(null, null, null);
+        expect(alertifySpy['search_objects']).not.toHaveBeenCalled();
+      });
+
+      it('display an alert with a Backup Error', () => {
+        soDialog.draw(null, [{id: 'serverTreeNode'}], null);
+        expect(alertifySpy.alert).toHaveBeenCalledWith(
+          'Search Objects Error',
+          'Please select a database or its child node from the browser.'
+        );
+      });
+    });
+
+    context('there is an ancestor of the type database', () => {
+      let soDialogResizeToSpy;
+      beforeEach(() => {
+        soDialogResizeToSpy = jasmine.createSpyObj('soDialogResizeToSpy', ['resizeTo']);
+        alertifySpy['search_objects'].and
+          .returnValue(soDialogResizeToSpy);
+      });
+
+      it('displays the dialog when database node selected', (done) => {
+        soDialog.draw(null, [{id: 'some_database'}], null, pgBrowser.stdW.md, pgBrowser.stdH.md);
+        setTimeout(() => {
+          expect(alertifySpy['search_objects']).toHaveBeenCalledWith('Search Objects - thedatabase/username@theserver');
+          expect(soDialogResizeToSpy.resizeTo).toHaveBeenCalledWith(pgBrowser.stdW.md, pgBrowser.stdH.md);
+          done();
+        }, 0);
+      });
+    });
+  });
+});
diff --git a/web/regression/javascript/search_objects/search_objects_dialog_wrapper_spec.js b/web/regression/javascript/search_objects/search_objects_dialog_wrapper_spec.js
new file mode 100644
index 000000000..4131e2d3a
--- /dev/null
+++ b/web/regression/javascript/search_objects/search_objects_dialog_wrapper_spec.js
@@ -0,0 +1,526 @@
+/////////////////////////////////////////////////////////////
+//
+// pgAdmin 4 - PostgreSQL Tools
+//
+// Copyright (C) 2013 - 2020, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+//////////////////////////////////////////////////////////////
+
+import {TreeFake} from '../tree/tree_fake';
+import SearchObjectsDialogWrapper from 'tools/search_objects/static/js/search_objects_dialog_wrapper';
+import axios from 'axios/index';
+import MockAdapter from 'axios-mock-adapter';
+import {TreeNode} from '../../../pgadmin/static/js/tree/tree';
+
+let context = describe;
+
+describe('SearchObjectsDialogWrapper', () => {
+  let jquerySpy;
+  let pgBrowser;
+  let alertifySpy;
+  let dialogModelKlassSpy = null;
+  let backform;
+  let soDialogWrapper;
+  let noDataNode;
+  let serverTreeNode;
+  let databaseTreeNode;
+  let viewSchema;
+  let soJQueryContainerSpy;
+  let soNodeChildNodeSpy;
+  let soNode;
+
+  beforeEach(() => {
+    pgBrowser = {
+      treeMenu: new TreeFake(),
+      Nodes: {
+        server: {
+          hasId: true,
+          getTreeNodeHierarchy: jasmine.createSpy('getTreeNodeHierarchy'),
+        },
+        database: {
+          hasId: true,
+          getTreeNodeHierarchy: jasmine.createSpy('getTreeNodeHierarchy'),
+        },
+        'coll-sometype': {
+          type: 'coll-sometype',
+          hasId: false,
+          label: 'Some types coll',
+        },
+        sometype: {
+          type: 'sometype',
+          hasId: true,
+        },
+        someothertype: {
+          type: 'someothertype',
+          hasId: true,
+          collection_type: 'coll-sometype',
+        },
+        'coll-edbfunc': {
+          type: 'coll-edbfunc',
+          hasId: true,
+          label: 'Functions',
+        },
+        'coll-edbproc': {
+          type: 'coll-edbfunc',
+          hasId: true,
+          label: 'Procedures',
+        },
+        'coll-edbvar': {
+          type: 'coll-edbfunc',
+          hasId: true,
+          label: 'Variables',
+        },
+      },
+      keyboardNavigation: jasmine.createSpyObj('keyboardNavigation', ['getDialogTabNavigator']),
+    };
+    noDataNode = pgBrowser.treeMenu.addNewNode('level1.1', undefined, [{id: 'level1'}]);
+    serverTreeNode = pgBrowser.treeMenu.addNewNode('level2.1', {
+      _type: 'server',
+      _id: 10,
+      label: 'some-tree-label',
+    }, [{id: 'level2.1'}]);
+    databaseTreeNode = new TreeNode('database-tree-node', {
+      _type: 'database',
+      _id: 123,
+      _label: 'some-database-label',
+    }, [{id: 'database-tree-node'}]);
+    pgBrowser.treeMenu.addChild(serverTreeNode, databaseTreeNode);
+
+    jquerySpy = jasmine.createSpy('jquerySpy');
+    soNode = {
+      __internal: {
+        buttons: [{}, {}, {}, {
+          element: {
+            disabled: false,
+          },
+        }],
+      },
+      elements: {
+        body: {
+          childNodes: [
+            {},
+          ],
+        },
+        content: jasmine.createSpyObj('content', ['appendChild', 'attr']),
+      },
+    };
+
+    soJQueryContainerSpy = jasmine.createSpyObj('soJQueryContainer', ['get', 'attr']);
+    soJQueryContainerSpy.get.and.returnValue(soJQueryContainerSpy);
+
+    viewSchema = {};
+    backform = jasmine.createSpyObj('backform', ['generateViewSchema', 'Dialog']);
+    backform.generateViewSchema.and.returnValue(viewSchema);
+
+    soNodeChildNodeSpy = jasmine.createSpyObj('something', ['addClass']);
+    jquerySpy.and.callFake((selector) => {
+      if (selector === '<div class=\'search_objects_dialog\'></div>') {
+        return soJQueryContainerSpy;
+      } else if (selector === soNode.elements.body.childNodes[0]) {
+        return soNodeChildNodeSpy;
+      }
+    });
+    alertifySpy = jasmine.createSpyObj('alertify', ['alert', 'dialog']);
+
+  });
+
+  describe('#prepare', () => {
+    beforeEach(() => {
+      soDialogWrapper = new SearchObjectsDialogWrapper(
+        '<div class=\'search_objects_dialog\'></div>',
+        'soDialogTitle',
+        'search_objects',
+        jquerySpy,
+        pgBrowser,
+        alertifySpy,
+        dialogModelKlassSpy,
+        backform
+      );
+      soDialogWrapper = Object.assign(soDialogWrapper, soNode);
+      spyOn(soDialogWrapper, 'prepareDialog').and.callThrough();
+      spyOn(soDialogWrapper, 'setTypes');
+    });
+
+    context('no tree element is selected', () => {
+      it('does not prepare dialog', () => {
+        spyOn(soDialogWrapper, 'prepareDialog');
+        soDialogWrapper.prepare();
+        expect(soDialogWrapper.prepareDialog).not.toHaveBeenCalled();
+      });
+    });
+
+    context('selected tree node has no data', () => {
+      beforeEach(() => {
+        pgBrowser.treeMenu.selectNode(noDataNode.domNode);
+      });
+
+      it('does not prepare the dialog', () => {
+        spyOn(soDialogWrapper, 'prepareDialog');
+        soDialogWrapper.prepare();
+        expect(soDialogWrapper.prepareDialog).not.toHaveBeenCalled();
+      });
+    });
+
+    context('tree element is selected', () => {
+      let gridDestroySpy;
+      let networkMock;
+
+      beforeEach(() => {
+        pgBrowser.treeMenu.selectNode(databaseTreeNode.domNode);
+        soDialogWrapper.grid = jasmine.createSpyObj('grid', ['destroy']);
+        spyOn(soDialogWrapper, 'showMessage');
+        gridDestroySpy = spyOn(soDialogWrapper.grid, 'destroy');
+
+        networkMock = new MockAdapter(axios);
+
+      });
+
+      afterEach(() => {
+        networkMock.restore();
+      });
+
+      it('creates dialog and displays it', () => {
+        soDialogWrapper.prepare();
+        expect(soDialogWrapper.prepareDialog).toHaveBeenCalled();
+        expect(soDialogWrapper.showMessage).toHaveBeenCalledWith(null);
+      });
+
+
+      it('if grid set then destroy it', () => {
+        soDialogWrapper.prepare();
+        expect(gridDestroySpy).toHaveBeenCalled();
+        expect(soDialogWrapper.grid).toBe(null);
+      });
+
+      it('setTypes called after the ajax success', (done) => {
+        networkMock.onGet('/search_objects/types/10/123').reply(200, {
+          'data': {
+            'type1': 'Type Label 1',
+            'type2': 'Type Label 2',
+          },
+        });
+
+        soDialogWrapper.prepare();
+
+        expect(soDialogWrapper.setTypes.calls.argsFor(0)).toEqual([
+          [{ id: -1, text: 'Loading...', value: null }], false,
+        ]);
+
+        setTimeout(()=>{
+          expect(soDialogWrapper.setTypes.calls.argsFor(1)).toEqual([
+            [{id: 'all', text: 'All types'},
+              {id: 'type1', text: 'Type Label 1'},
+              {id: 'type2', text: 'Type Label 2'}],
+          ]);
+          done();
+        }, 0);
+      });
+
+      it('setTypes called after the ajax fail', (done) => {
+        networkMock.onGet('/search_objects/types/10/123').reply(500);
+
+        soDialogWrapper.prepare();
+
+        expect(soDialogWrapper.setTypes.calls.argsFor(0)).toEqual([
+          [{ id: -1, text: 'Loading...', value: null }], false,
+        ]);
+
+        setTimeout(()=>{
+          expect(soDialogWrapper.setTypes.calls.argsFor(1)).toEqual([
+            [{id: -1, text: 'Failed', value: null }], false,
+          ]);
+          done();
+        }, 0);
+      });
+    });
+  });
+
+  describe('showMessage', () => {
+    beforeEach(() => {
+      soDialogWrapper = new SearchObjectsDialogWrapper(
+        '<div class=\'search_objects_dialog\'></div>',
+        'soDialogTitle',
+        'search_objects',
+        jquerySpy,
+        pgBrowser,
+        alertifySpy,
+        dialogModelKlassSpy,
+        backform
+      );
+      soDialogWrapper.statusBar = document.createElement('div');
+      soDialogWrapper.statusBar.classList.add('d-none');
+      document.body.appendChild(soDialogWrapper.statusBar);
+    });
+
+    afterEach(() => {
+      document.body.removeChild(soDialogWrapper.statusBar);
+    });
+    it('when info message', ()=>{
+      soDialogWrapper.showMessage('locating', false);
+      expect(soDialogWrapper.statusBar.classList.contains('d-none')).toBe(false);
+      expect(soDialogWrapper.statusBar.querySelector('.error-in-footer')).toBe(null);
+      expect(soDialogWrapper.statusBar.querySelector('.info-in-footer')).not.toBe(null);
+      expect(soDialogWrapper.statusBar.querySelector('.alert-text').innerHTML).toEqual('locating');
+    });
+
+    it('when error message', ()=>{
+      soDialogWrapper.showMessage('some error', true);
+      expect(soDialogWrapper.statusBar.classList.contains('d-none')).toBe(false);
+      expect(soDialogWrapper.statusBar.querySelector('.error-in-footer')).not.toBe(null);
+      expect(soDialogWrapper.statusBar.querySelector('.info-in-footer')).toBe(null);
+      expect(soDialogWrapper.statusBar.querySelector('.alert-text').innerHTML).toEqual('some error');
+    });
+
+    it('when no message', ()=>{
+      soDialogWrapper.showMessage(null);
+      expect(soDialogWrapper.statusBar.classList.contains('d-none')).toBe(true);
+    });
+  });
+
+  describe('function', () => {
+    beforeEach(() => {
+      soDialogWrapper = new SearchObjectsDialogWrapper(
+        '<div class=\'search_objects_dialog\'></div>',
+        'soDialogTitle',
+        'search_objects',
+        jquerySpy,
+        pgBrowser,
+        alertifySpy,
+        dialogModelKlassSpy,
+        backform
+      );
+    });
+
+    it('updateDimOfSearchResult', ()=>{
+      soDialogWrapper.searchResultContainer = document.createElement('div');
+      soDialogWrapper.searchResult = document.createElement('div');
+      spyOn(soDialogWrapper.searchResultContainer, 'getBoundingClientRect').and.returnValue({height:100, width: 50});
+
+      soDialogWrapper.updateDimOfSearchResult();
+      expect(soDialogWrapper.searchResult.style.height).toEqual('100px');
+      expect(soDialogWrapper.searchResult.style.width).toEqual('50px');
+    });
+
+    it('setLoading', ()=>{
+      soDialogWrapper.loader = document.createElement('div');
+      soDialogWrapper.loader.innerHTML = `
+        <div class="pg-sp-text"></div>
+      `;
+
+      soDialogWrapper.setLoading('loading');
+      expect(soDialogWrapper.loader.classList.contains('d-none')).toBe(false);
+      expect(soDialogWrapper.loader.querySelector('.pg-sp-text').innerHTML).toEqual('loading');
+
+      soDialogWrapper.setLoading(null);
+      expect(soDialogWrapper.loader.classList.contains('d-none')).toBe(true);
+    });
+
+    it('searchBtnEnabled', ()=>{
+      soDialogWrapper.searchBtn = document.createElement('button');
+
+      soDialogWrapper.searchBtnEnabled(true);
+      expect(soDialogWrapper.searchBtn.disabled).toEqual(false);
+      expect(soDialogWrapper.searchBtnEnabled()).toEqual(true);
+
+      soDialogWrapper.searchBtnEnabled(false);
+      expect(soDialogWrapper.searchBtn.disabled).toEqual(true);
+      expect(soDialogWrapper.searchBtnEnabled()).toEqual(false);
+    });
+
+    it('searchBoxVal', ()=>{
+      soDialogWrapper.searchBox = document.createElement('input');
+      soDialogWrapper.searchBoxVal('abc');
+      expect(soDialogWrapper.searchBox.value).toEqual('abc');
+      expect(soDialogWrapper.searchBoxVal()).toEqual('abc');
+    });
+
+    it('typesVal', ()=>{
+      soDialogWrapper.typesSelect = document.createElement('select');
+      let opt = document.createElement('option');
+      opt.appendChild( document.createTextNode('Some type') );
+      opt.value = 'sometype';
+      soDialogWrapper.typesSelect.appendChild(opt);
+
+      soDialogWrapper.typesVal('sometype');
+      expect(soDialogWrapper.typesSelect.value).toEqual('sometype');
+      expect(soDialogWrapper.typesVal()).toEqual('sometype');
+    });
+
+    it('setGridData', ()=>{
+      soDialogWrapper.grid = jasmine.createSpyObj('grid', ['setData', 'resizeCanvas']);
+      soDialogWrapper.setGridData([{id:'somedata'}]);
+      expect(soDialogWrapper.grid.setData).toHaveBeenCalled();
+      expect(soDialogWrapper.grid.resizeCanvas).toHaveBeenCalled();
+    });
+
+    it('onDialogResize', ()=>{
+      soDialogWrapper.grid = jasmine.createSpyObj('grid', ['autosizeColumns', 'resizeCanvas']);
+      spyOn(soDialogWrapper, 'updateDimOfSearchResult');
+
+      soDialogWrapper.onDialogResize();
+      expect(soDialogWrapper.updateDimOfSearchResult).toHaveBeenCalled();
+      expect(soDialogWrapper.grid.resizeCanvas).toHaveBeenCalled();
+      expect(soDialogWrapper.grid.autosizeColumns).toHaveBeenCalled();
+    });
+
+    it('onDialogShow', (done)=>{
+      spyOn(soDialogWrapper, 'prepareGrid').and.callFake(function() {
+        this.grid = jasmine.createSpyObj('grid', ['init']);
+      });
+
+      spyOn(soDialogWrapper, 'focusOnDialog');
+      spyOn(soDialogWrapper, 'updateDimOfSearchResult');
+      spyOn(soDialogWrapper, 'setGridData');
+      spyOn(soDialogWrapper, 'onDialogResize');
+
+
+      soDialogWrapper.onDialogShow();
+      setTimeout(()=>{
+        expect(soDialogWrapper.prepareGrid).toHaveBeenCalled();
+        expect(soDialogWrapper.focusOnDialog).toHaveBeenCalled();
+        expect(soDialogWrapper.setGridData).toHaveBeenCalledWith([]);
+        expect(soDialogWrapper.onDialogResize).toHaveBeenCalled();
+        done();
+      }, 750);
+    });
+
+    context('getCollNode', ()=>{
+      it('type have same coll node', ()=>{
+        let collNode = soDialogWrapper.getCollNode('sometype');
+        expect(collNode.type).toEqual('coll-sometype');
+      });
+
+      it('type does not same coll node', ()=>{
+        let collNode = soDialogWrapper.getCollNode('someothertype');
+        expect(collNode.type).toEqual('coll-sometype');
+      });
+
+      it('type does not have coll node at all', ()=>{
+        let collNode = soDialogWrapper.getCollNode('database');
+        expect(collNode).toBe(null);
+      });
+    });
+
+    it('finaliseData', ()=>{
+      spyOn(soDialogWrapper, 'translateSearchObjectsPath').and.returnValue(['disp/path', 'id/path']);
+      let data = soDialogWrapper.finaliseData({
+        name: 'objname',
+        type: 'sometype',
+        type_label: 'Some types coll',
+        path: ':some.123:/path',
+        show_node: true,
+      });
+      expect(data).toEqual({
+        icon: 'icon-sometype',
+        name: 'objname',
+        type: 'sometype',
+        type_label: 'Some types coll',
+        path: 'disp/path',
+        id_path: 'id/path',
+        show_node: true,
+      });
+    });
+
+    context('translateSearchObjectsPath', ()=>{
+      let path = null, catalog_level = null;
+      beforeEach(()=>{
+        pgBrowser.Nodes = {
+          'server_group': {
+            type:'server_group',
+            label: 'Server group',
+          },
+          'server': {
+            type:'server',
+            label: 'Server',
+          },
+          'coll-database': {
+            type:'coll-database',
+            label: 'Databases',
+          },
+          'database': {
+            type:'database',
+            label: 'Database',
+          },
+          'coll-schema': {
+            type:'coll-schema',
+            label: 'Schemas',
+          },
+          'schema': {
+            type:'schema',
+            label: 'Schema',
+          },
+          'coll-table': {
+            type:'coll-table',
+            label: 'Tables',
+          },
+          'table': {
+            type:'table',
+            label: 'Table',
+          },
+          'sometype': {
+            type:'sometype',
+            label: 'Some type',
+            collection_type: 'coll-table',
+          },
+          'coll-catalog': {
+            type:'coll-catalog',
+            label: 'Catalogs',
+          },
+          'catalog': {
+            type:'catalog',
+            label: 'Catalog',
+          },
+          'coll-catalog_object': {
+            type:'coll-catalog_object',
+            label: 'Catalog Objects',
+          },
+          'catalog_object': {
+            type:'catalog_object',
+            label: 'catalog object',
+          },
+        };
+
+        soDialogWrapper.treeInfo = {
+          'server_group': {'id': 'server_group/1', '_id': 1},
+          'server': {'id': 'server/3', '_id': 3},
+          'database': {'id': 'database/18456', '_id': 18456},
+        };
+      });
+      it('regular schema', ()=>{
+        path = ':schema.2200:/test_db/:table.2604:/sampletab';
+        catalog_level = 'N';
+
+        let retVal = soDialogWrapper.translateSearchObjectsPath(path, catalog_level);
+        expect(retVal).toEqual([
+          'Schemas/test_db/Tables/sampletab',
+          ['server_group/1','server/3','coll-database/3','database/18456','coll-schema/18456','schema/2200','coll-table/2200','table/2604'],
+        ]);
+      });
+
+      context('catalog schema', ()=>{
+        it('with db support', ()=>{
+          path = ':schema.11:/PostgreSQL Catalog (pg_catalog)/:table.2604:/pg_class';
+          catalog_level = 'D';
+
+          let retVal = soDialogWrapper.translateSearchObjectsPath(path, catalog_level);
+          expect(retVal).toEqual([
+            'Catalogs/PostgreSQL Catalog (pg_catalog)/Tables/pg_class',
+            ['server_group/1','server/3','coll-database/3','database/18456','coll-catalog/18456','catalog/11','coll-table/11','table/2604'],
+          ]);
+        });
+
+        it('with object support only', ()=>{
+          path = ':schema.11:/ANSI (information_schema)/:table.2604:/attributes';
+          catalog_level = 'O';
+
+          let retVal = soDialogWrapper.translateSearchObjectsPath(path, catalog_level);
+          expect(retVal).toEqual([
+            'Catalogs/ANSI (information_schema)/Catalog Objects/attributes',
+            ['server_group/1','server/3','coll-database/3','database/18456','coll-catalog/18456','catalog/11','coll-catalog_object/11','catalog_object/2604'],
+          ]);
+        });
+      });
+    });
+  });
+});
diff --git a/web/regression/javascript/tree/tree_fake.js b/web/regression/javascript/tree/tree_fake.js
index c0c17796a..f476bb272 100644
--- a/web/regression/javascript/tree/tree_fake.js
+++ b/web/regression/javascript/tree/tree_fake.js
@@ -41,6 +41,9 @@ export class TreeFake extends Tree {
     this.aciTreeToOurTreeTranslator = {};
     this.aciTreeApi = jasmine.createSpyObj(
       'ACITreeApi', ['setInode', 'unload', 'deselect', 'select']);
+    this.aciTreeApi.unload.and.callFake(function(domNode, config) {
+      config.success();
+    });
   }
 
   addNewNode(id, data, domNode, path) {
diff --git a/web/regression/javascript/tree/tree_spec.js b/web/regression/javascript/tree/tree_spec.js
index bb607796c..038fcc24c 100644
--- a/web/regression/javascript/tree/tree_spec.js
+++ b/web/regression/javascript/tree/tree_spec.js
@@ -246,39 +246,70 @@ describe('tree tests', () => {
 
         tree.aciTreeApi = jasmine.createSpyObj(
           'ACITreeApi', ['setInode', 'unload', 'deselect', 'select']);
+        tree.aciTreeApi.unload.and.callFake((domNode, config) => {
+          config.success();
+        });
       });
 
-      it('reloads the node and its children', () => {
-        level2.reload(tree);
-        expect(tree.findNodeByDomElement([{id: 'level2'}])).toEqual(level2);
+      it('reloads the node and its children', (done) => {
+        level2.reload(tree)
+          .then(()=>{
+            expect(tree.findNodeByDomElement([{id: 'level2'}])).toEqual(level2);
+            done();
+          })
+          .catch((error)=>{
+            fail(error);
+          });
       });
 
-      it('does not reload the children of node', () => {
-        level2.reload(tree);
-        expect(tree.findNodeByDomElement([{id: 'level3'}])).toBeNull();
+      it('does not reload the children of node', (done) => {
+        level2.reload(tree)
+          .then(()=>{
+            expect(tree.findNodeByDomElement([{id: 'level3'}])).toBeNull();
+            done();
+          })
+          .catch((error)=>{
+            fail(error);
+          });
       });
 
       it('select the node', (done) => {
-        level2.reload(tree);
-        setTimeout(() => {
-          expect(tree.selected()).toEqual([{id: 'level2'}]);
-          done();
-        }, 20);
+        level2.reload(tree)
+          .then(()=>{
+            setTimeout(() => {
+              expect(tree.selected()).toEqual([{id: 'level2'}]);
+              done();
+            }, 20);
+          })
+          .catch((error)=>{
+            fail(error);
+          });
       });
 
       describe('ACITree specific', () => {
-        it('sets the current node as a Inode, changing the Icon back to +', () => {
-          level2.reload(tree);
-          expect(tree.aciTreeApi.setInode).toHaveBeenCalledWith([{id: 'level2'}]);
+        it('sets the current node as a Inode, changing the Icon back to +', (done) => {
+          level2.reload(tree)
+            .then(()=>{
+              expect(tree.aciTreeApi.setInode).toHaveBeenCalledWith([{id: 'level2'}]);
+              done();
+            })
+            .catch((error)=>{
+              fail(error);
+            });
         });
 
         it('deselect the node and selects it again to trigger ACI tree' +
           ' events', (done) => {
-          level2.reload(tree);
-          setTimeout(() => {
-            expect(tree.aciTreeApi.deselect).toHaveBeenCalledWith([{id: 'level2'}]);
-            done();
-          }, 20);
+          level2.reload(tree)
+            .then(()=>{
+              setTimeout(() => {
+                expect(tree.aciTreeApi.deselect).toHaveBeenCalledWith([{id: 'level2'}]);
+                done();
+              }, 20);
+            })
+            .catch((error)=>{
+              fail(error);
+            });
         });
       });
     });
@@ -292,17 +323,32 @@ describe('tree tests', () => {
         level2 = tree.addNewNode('level2', {data: 'data'}, ['<li>level2</li>'], ['level1']);
         tree.addNewNode('level3', {data: 'more data'}, ['<li>level3</li>'], ['level1', 'level2']);
         tree.aciTreeApi = jasmine.createSpyObj('ACITreeApi', ['unload']);
+        tree.aciTreeApi.unload.and.callFake((domNode, config) => {
+          config.success();
+        });
       });
 
-      it('unloads the children of the current node', () => {
-        level2.unload(tree);
-        expect(tree.findNodeByDomElement([{id: 'level2'}])).toEqual(level2);
-        expect(tree.findNodeByDomElement([{id: 'level3'}])).toBeNull();
+      it('unloads the children of the current node', (done) => {
+        level2.unload(tree)
+          .then(()=>{
+            expect(tree.findNodeByDomElement([{id: 'level2'}])).toEqual(level2);
+            expect(tree.findNodeByDomElement([{id: 'level3'}])).toBeNull();
+            done();
+          })
+          .catch((error)=>{
+            fail(error);
+          });
       });
 
-      it('calls unload on the ACI Tree', () => {
-        level2.unload(tree);
-        expect(tree.aciTreeApi.unload).toHaveBeenCalledWith(['<li>level2</li>']);
+      it('calls unload on the ACI Tree', (done) => {
+        level2.unload(tree)
+          .then(()=>{
+            expect(tree.aciTreeApi.unload).toHaveBeenCalledWith(['<li>level2</li>'], jasmine.any(Object));
+            done();
+          })
+          .catch((error)=>{
+            fail(error);
+          });
       });
     });
   });
diff --git a/web/webpack.config.js b/web/webpack.config.js
index 9fd0a32e9..29811388a 100644
--- a/web/webpack.config.js
+++ b/web/webpack.config.js
@@ -494,7 +494,8 @@ module.exports = [{
         ',pgadmin.tools.debugger.controller' +
         ',pgadmin.tools.debugger.direct' +
         ',pgadmin.node.pga_job' +
-        ',pgadmin.tools.schema_diff',
+        ',pgadmin.tools.schema_diff' +
+        ',pgadmin.tools.search_objects',
       },
     }, {
       test: require.resolve('snapsvg'),
diff --git a/web/webpack.shim.js b/web/webpack.shim.js
index a5c73805a..0587d0498 100644
--- a/web/webpack.shim.js
+++ b/web/webpack.shim.js
@@ -281,6 +281,8 @@ var webpackShimConfig = {
     'pgadmin.tools.restore': path.join(__dirname, './pgadmin/tools/restore/static/js/restore'),
     'pgadmin.tools.schema_diff': path.join(__dirname, './pgadmin/tools/schema_diff/static/js/schema_diff'),
     'pgadmin.tools.schema_diff_ui': path.join(__dirname, './pgadmin/tools/schema_diff/static/js/schema_diff_ui'),
+    'pgadmin.tools.search_objects': path.join(__dirname, './pgadmin/tools/search_objects/static/js/search_objects'),
+    'pgadmin.search_objects': path.join(__dirname, './pgadmin/tools/search_objects/static/js'),
     'pgadmin.tools.user_management': path.join(__dirname, './pgadmin/tools/user_management/static/js/user_management'),
     'pgadmin.user_management.current_user': '/user_management/current_user',
     'slick.pgadmin.editors': path.join(__dirname, './pgadmin/tools/../static/js/slickgrid/editors'),
diff --git a/web/webpack.test.config.js b/web/webpack.test.config.js
index 70db29125..cfa8dda02 100644
--- a/web/webpack.test.config.js
+++ b/web/webpack.test.config.js
@@ -105,6 +105,7 @@ module.exports = {
       'pgadmin.browser.preferences': path.join(__dirname, './pgadmin/browser/static/js/preferences'),
       'pgadmin.browser.activity': path.join(__dirname, './pgadmin/browser/static/js/activity'),
       'bundled_codemirror': path.join(__dirname, './pgadmin/static/bundle/codemirror'),
+      'tools': path.join(__dirname, './pgadmin/tools/'),
     },
   },
 };
