From 782ac5288fdbab1fd1f7cdc3e8b93d4c0211a6d8 Mon Sep 17 00:00:00 2001
From: Warren Chan <wchan_syd@yahoo.com.au>
Date: Thu, 3 Sep 2020 11:16:14 +1000
Subject: [PATCH] changes to add new node (copy of sequence) under schema

---
 .../databases/schemas/foos/__init__.py        | 965 ++++++++++++++++++
 .../schemas/foos/static/img/coll-foo.svg      |   1 +
 .../databases/schemas/foos/static/img/foo.svg |   1 +
 .../databases/schemas/foos/static/js/foo.js   | 299 ++++++
 .../templates/foos/sql/10_plus/get_def.sql    |  11 +
 .../foos/templates/foos/sql/default/acl.sql   |  30 +
 .../foos/sql/default/backend_support.sql      |  15 +
 .../templates/foos/sql/default/coll_stats.sql |   9 +
 .../templates/foos/sql/default/create.sql     |  16 +
 .../templates/foos/sql/default/delete.sql     |   1 +
 .../templates/foos/sql/default/get_def.sql    |  10 +
 .../foos/sql/default/get_dependencies.sql     |  12 +
 .../templates/foos/sql/default/get_oid.sql    |   7 +
 .../foos/templates/foos/sql/default/grant.sql |  26 +
 .../foos/templates/foos/sql/default/nodes.sql |  11 +
 .../templates/foos/sql/default/properties.sql |  17 +
 .../foos/templates/foos/sql/default/stats.sql |   7 +
 .../templates/foos/sql/default/update.sql     |  97 ++
 .../templates/foos/sql/gpdb_5.0_plus/acl.sql  |   7 +
 .../databases/schemas/foos/tests/__init__.py  |  15 +
 .../tests/pg/default/alter_neg_seq_props.sql  |  13 +
 .../pg/default/alter_neg_seq_props_msql.sql   |   4 +
 .../tests/pg/default/alter_seq_comment.sql    |  16 +
 .../pg/default/alter_seq_comment_msql.sql     |   2 +
 .../tests/pg/default/alter_seq_privs_add.sql  |  21 +
 .../pg/default/alter_seq_privs_add_msql.sql   |   1 +
 .../pg/default/alter_seq_privs_remove.sql     |  19 +
 .../default/alter_seq_privs_remove_msql.sql   |   1 +
 .../pg/default/alter_seq_privs_update.sql     |  21 +
 .../default/alter_seq_privs_update_msql.sql   |   2 +
 .../foos/tests/pg/default/alter_seq_props.sql |  17 +
 .../tests/pg/default/alter_seq_props_msql.sql |   8 +
 .../pg/default/create_negative_sequence.sql   |  13 +
 .../default/create_negative_sequence_msql.sql |   9 +
 .../foos/tests/pg/default/create_sequence.sql |  13 +
 .../tests/pg/default/create_sequence_msql.sql |   9 +
 .../tests/pg/default/test_sequences_pg.json   | 173 ++++
 .../ppas/default/alter_neg_seq_props.sql      |  13 +
 .../ppas/default/alter_neg_seq_props_msql.sql |   4 +
 .../tests/ppas/default/alter_seq_comment.sql  |  16 +
 .../ppas/default/alter_seq_comment_msql.sql   |   2 +
 .../ppas/default/alter_seq_privs_add.sql      |  21 +
 .../ppas/default/alter_seq_privs_add_msql.sql |   1 +
 .../ppas/default/alter_seq_privs_remove.sql   |  19 +
 .../default/alter_seq_privs_remove_msql.sql   |   1 +
 .../ppas/default/alter_seq_privs_update.sql   |  21 +
 .../default/alter_seq_privs_update_msql.sql   |   2 +
 .../tests/ppas/default/alter_seq_props.sql    |  17 +
 .../ppas/default/alter_seq_props_msql.sql     |   8 +
 .../ppas/default/create_negative_sequence.sql |  13 +
 .../default/create_negative_sequence_msql.sql |   9 +
 .../tests/ppas/default/create_sequence.sql    |  13 +
 .../ppas/default/create_sequence_msql.sql     |   9 +
 .../ppas/default/test_sequences_ppas.json     | 173 ++++
 .../schemas/foos/tests/test_sequence_add.py   | 126 +++
 .../foos/tests/test_sequence_delete.py        |  69 ++
 .../tests/test_sequence_delete_multiple.py    |  93 ++
 .../schemas/foos/tests/test_sequence_get.py   |  64 ++
 .../schemas/foos/tests/test_sequence_put.py   |  98 ++
 .../databases/schemas/foos/tests/utils.py     |  89 ++
 web/webpack.config.js                         |   1 +
 web/webpack.shim.js                           |   1 +
 62 files changed, 2782 insertions(+)
 create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/__init__.py
 create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/static/img/coll-foo.svg
 create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/static/img/foo.svg
 create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/static/js/foo.js
 create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/10_plus/get_def.sql
 create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/acl.sql
 create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/backend_support.sql
 create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/coll_stats.sql
 create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/create.sql
 create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/delete.sql
 create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/get_def.sql
 create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/get_dependencies.sql
 create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/get_oid.sql
 create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/grant.sql
 create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/nodes.sql
 create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/properties.sql
 create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/stats.sql
 create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/update.sql
 create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/gpdb_5.0_plus/acl.sql
 create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/__init__.py
 create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_neg_seq_props.sql
 create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_neg_seq_props_msql.sql
 create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_comment.sql
 create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_comment_msql.sql
 create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_privs_add.sql
 create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_privs_add_msql.sql
 create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_privs_remove.sql
 create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_privs_remove_msql.sql
 create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_privs_update.sql
 create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_privs_update_msql.sql
 create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_props.sql
 create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_props_msql.sql
 create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/create_negative_sequence.sql
 create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/create_negative_sequence_msql.sql
 create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/create_sequence.sql
 create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/create_sequence_msql.sql
 create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/test_sequences_pg.json
 create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_neg_seq_props.sql
 create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_neg_seq_props_msql.sql
 create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_comment.sql
 create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_comment_msql.sql
 create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_privs_add.sql
 create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_privs_add_msql.sql
 create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_privs_remove.sql
 create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_privs_remove_msql.sql
 create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_privs_update.sql
 create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_privs_update_msql.sql
 create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_props.sql
 create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_props_msql.sql
 create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/create_negative_sequence.sql
 create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/create_negative_sequence_msql.sql
 create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/create_sequence.sql
 create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/create_sequence_msql.sql
 create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/test_sequences_ppas.json
 create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/test_sequence_add.py
 create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/test_sequence_delete.py
 create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/test_sequence_delete_multiple.py
 create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/test_sequence_get.py
 create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/test_sequence_put.py
 create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/utils.py

diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/__init__.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/__init__.py
new file mode 100644
index 000000000..3bc310d6f
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/__init__.py
@@ -0,0 +1,965 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2020, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+"""Implements Foo Node"""
+
+from functools import wraps
+
+import simplejson as json
+from flask import render_template, request, jsonify
+from flask_babelex import gettext as _
+
+import pgadmin.browser.server_groups.servers.databases as database
+from config import PG_DEFAULT_DRIVER
+from pgadmin.browser.server_groups.servers.databases.schemas.utils \
+    import SchemaChildModule
+from pgadmin.browser.server_groups.servers.utils import parse_priv_from_db, \
+    parse_priv_to_db
+from pgadmin.browser.utils import PGChildNodeView
+from pgadmin.tools.schema_diff.compare import SchemaDiffObjectCompare
+from pgadmin.tools.schema_diff.node_registry import SchemaDiffRegistry
+from pgadmin.utils.ajax import make_json_response, internal_server_error, \
+    make_response as ajax_response, gone
+from pgadmin.utils.driver import get_driver
+
+
+class FooModule(SchemaChildModule):
+    """
+    class SequenceModule(CollectionNodeModule)
+
+        A module class for Sequence node derived from CollectionNodeModule.
+
+    Methods:
+    -------
+    * __init__(*args, **kwargs)
+      - Method is used to initialize the SequenceModule and it's base module.
+
+    * get_nodes(gid, sid, did)
+      - Method is used to generate the browser collection node.
+
+    * script_load()
+      - Load the module script for sequence, when any of the database node is
+        initialized.
+
+    * node_inode()
+      - Method is overridden from its base class to make the node as leaf node.
+
+    """
+
+    _NODE_TYPE = 'foo'
+    _COLLECTION_LABEL = _("Foos Node")
+
+    def __init__(self, *args, **kwargs):
+        super(FooModule, self).__init__(*args, **kwargs)
+        self.min_ver = None
+        self.max_ver = None
+        self.min_gpdbver = 1000000000
+
+    def get_nodes(self, gid, sid, did, scid):
+        """
+        Generate the sequence node
+        """
+        yield self.generate_browser_collection_node(scid)
+
+    @property
+    def script_load(self):
+        """
+        Load the module script for database, when any of the database node is
+        initialized.
+        """
+        return database.DatabaseModule.node_type
+
+    @property
+    def node_inode(self):
+        """
+        Override this property to make the node a leaf node.
+
+        Returns: False as this is the leaf node
+        """
+        return False
+
+
+blueprint = FooModule(__name__)
+
+
+class FooView(PGChildNodeView, SchemaDiffObjectCompare):
+    node_type = blueprint.node_type
+
+    parent_ids = [
+        {'type': 'int', 'id': 'gid'},
+        {'type': 'int', 'id': 'sid'},
+        {'type': 'int', 'id': 'did'},
+        {'type': 'int', 'id': 'scid'}
+    ]
+    ids = [
+        {'type': 'int', 'id': 'fooid'}
+    ]
+
+    operations = dict({
+        'obj': [
+            {'get': 'properties', 'delete': 'delete', 'put': 'update'},
+            {'get': 'list', 'post': 'create', 'delete': 'delete'}
+        ],
+        'delete': [{'delete': 'delete'}, {'delete': 'delete'}],
+        'children': [{'get': 'children'}],
+        'nodes': [{'get': 'nodes'}, {'get': 'nodes'}],
+        'sql': [{'get': 'sql'}],
+        'msql': [{'get': 'msql'}, {'get': 'msql'}],
+        'stats': [{'get': 'statistics'}, {'get': 'statistics'}],
+        'dependency': [{'get': 'dependencies'}],
+        'dependent': [{'get': 'dependents'}]
+    })
+
+    def check_precondition(action=None):
+        """
+        This function will behave as a decorator which will checks
+        database connection before running view, it will also attaches
+        manager,conn & template_path properties to self
+        """
+
+        def wrap(f):
+            @wraps(f)
+            def wrapped(self, *args, **kwargs):
+
+                driver = get_driver(PG_DEFAULT_DRIVER)
+                self.manager = driver.connection_manager(kwargs['sid'])
+
+                if action and action in ["drop"]:
+                    self.conn = self.manager.connection()
+                elif 'did' in kwargs:
+                    self.conn = self.manager.connection(did=kwargs['did'])
+                else:
+                    self.conn = self.manager.connection()
+                self.datlastsysoid = \
+                    self.manager.db_info[kwargs['did']]['datlastsysoid'] \
+                    if self.manager.db_info is not None and \
+                    kwargs['did'] in self.manager.db_info else 0
+
+                self.template_path = 'sequences/sql/#{0}#'.format(
+                    self.manager.version
+                )
+                self.acl = ['r', 'w', 'U']
+                self.qtIdent = driver.qtIdent
+
+                return f(self, *args, **kwargs)
+            return wrapped
+        return wrap
+
+    @check_precondition(action='list')
+    def list(self, gid, sid, did, scid):
+        """
+        This function is used to list all the sequence nodes within the
+        collection.
+
+        Args:
+          gid: Server Group ID
+          sid: Server ID
+          did: Database ID
+          scid: Schema ID
+
+        Returns:
+
+        """
+        SQL = render_template(
+            "/".join([self.template_path, self._PROPERTIES_SQL]),
+            scid=scid
+        )
+        status, res = self.conn.execute_dict(SQL)
+
+        if not status:
+            return internal_server_error(errormsg=res)
+
+        sequence_nodes = self._get_sequence_nodes(res['rows'])
+        return ajax_response(
+            response=sequence_nodes,
+            status=200
+        )
+
+    @check_precondition(action='nodes')
+    def nodes(self, gid, sid, did, scid, fooid=None):
+        """
+        This function is used to create all the child nodes within the
+        collection, Here it will create all the sequence nodes.
+
+        Args:
+          gid: Server Group ID
+          sid: Server ID
+          did: Database ID
+          scid: Schema ID
+
+        Returns:
+
+        """
+        res = []
+        SQL = render_template(
+            "/".join([self.template_path, self._NODES_SQL]),
+            scid=scid,
+            fooid=fooid
+        )
+        status, rset = self.conn.execute_dict(SQL)
+        if not status:
+            return internal_server_error(errormsg=rset)
+
+        if fooid is not None:
+            if len(rset['rows']) == 0:
+                return gone(errormsg=_("Could not find the sequence."))
+            row = rset['rows'][0]
+            return make_json_response(
+                data=self.blueprint.generate_browser_node(
+                    row['oid'],
+                    scid,
+                    row['name'],
+                    icon="icon-%s" % self.node_type
+                ),
+                status=200
+            )
+
+        sequence_nodes = self._get_sequence_nodes(rset['rows'])
+        for row in sequence_nodes:
+            res.append(
+                self.blueprint.generate_browser_node(
+                    row['oid'],
+                    scid,
+                    row['name'],
+                    icon="icon-%s" % self.node_type
+                ))
+
+        return make_json_response(
+            data=res,
+            status=200
+        )
+
+    def _get_sequence_nodes(self, nodes):
+        """
+        This function is used to iterate through all the sequences node and
+        hiding sequences created as part of an IDENTITY column.
+        :param nodes:
+        :return:
+        """
+        # If show_system_objects is true then no need to hide any sequences.
+        if self.blueprint.show_system_objects:
+            return nodes
+
+        seq_nodes = []
+        for row in nodes:
+            system_seq = self._get_dependency(row['oid'],
+                                              show_system_objects=True)
+            seq = filter(lambda dep: dep['type'] == 'column' and
+                         dep['field'] == 'internal', system_seq)
+            if type(seq) is not list:
+                seq = list(seq)
+            if len(seq) > 0:
+                continue
+
+            # Append the node into the newly created list
+            seq_nodes.append(row)
+
+        return seq_nodes
+
+    @check_precondition(action='properties')
+    def properties(self, gid, sid, did, scid, fooid):
+        """
+        This function will show the properties of the selected sequence node.
+
+        Args:
+          gid: Server Group ID
+          sid: Server ID
+          did: Database ID
+          scid: Schema ID
+          fooid: Sequence ID
+
+        Returns:
+
+        """
+        status, res = self._fetch_properties(scid, fooid)
+        if not status:
+            return res
+
+        return ajax_response(
+            response=res,
+            status=200
+        )
+
+    def _fetch_properties(self, scid, fooid):
+        """
+        This function is used to fetch the properties of the specified object.
+        :param scid:
+        :param fooid:
+        :return:
+        """
+
+        sql = render_template(
+            "/".join([self.template_path, self._PROPERTIES_SQL]),
+            scid=scid, fooid=fooid
+        )
+        status, res = self.conn.execute_dict(sql)
+
+        if not status:
+            return False, internal_server_error(errormsg=res)
+        elif len(res['rows']) == 0:
+            return False, gone(
+                _("Could not find the sequence in the database."))
+
+        res['rows'][0]['is_sys_obj'] = (
+            res['rows'][0]['oid'] <= self.datlastsysoid)
+
+        for row in res['rows']:
+            sql = render_template(
+                "/".join([self.template_path, 'get_def.sql']),
+                data=row
+            )
+            status, rset1 = self.conn.execute_dict(sql)
+            if not status:
+                return False, internal_server_error(errormsg=rset1)
+
+            row['current_value'] = rset1['rows'][0]['last_value']
+            row['minimum'] = rset1['rows'][0]['min_value']
+            row['maximum'] = rset1['rows'][0]['max_value']
+            row['increment'] = rset1['rows'][0]['increment_by']
+            row['start'] = rset1['rows'][0]['start_value']
+            row['cache'] = rset1['rows'][0]['cache_value']
+            row['cycled'] = rset1['rows'][0]['is_cycled']
+
+            self._add_securities_to_row(row)
+
+        sql = render_template(
+            "/".join([self.template_path, self._ACL_SQL]),
+            scid=scid, fooid=fooid
+        )
+        status, dataclres = self.conn.execute_dict(sql)
+        if not status:
+            return False, internal_server_error(errormsg=res)
+
+        for row in dataclres['rows']:
+            priv = parse_priv_from_db(row)
+            if row['deftype'] in res['rows'][0]:
+                res['rows'][0][row['deftype']].append(priv)
+            else:
+                res['rows'][0][row['deftype']] = [priv]
+
+        return True, res['rows'][0]
+
+    def _add_securities_to_row(self, row):
+        sec_lbls = []
+        if 'securities' in row and row['securities'] is not None:
+            for sec in row['securities']:
+                import re
+                sec = re.search(r'([^=]+)=(.*$)', sec)
+                sec_lbls.append({
+                    'provider': sec.group(1),
+                    'label': sec.group(2)
+                })
+        row['securities'] = sec_lbls
+
+    @check_precondition(action="create")
+    def create(self, gid, sid, did, scid):
+        """
+        Create the sequence.
+
+        Args:
+          gid: Server Group ID
+          sid: Server ID
+          did: Database ID
+          scid: Schema ID
+
+        Returns:
+
+        """
+        required_args = [
+            u'name',
+            u'schema',
+            u'seqowner',
+        ]
+
+        data = request.form if request.form else json.loads(
+            request.data, encoding='utf-8'
+        )
+
+        for arg in required_args:
+            if arg not in data:
+                return make_json_response(
+                    status=400,
+                    success=0,
+                    errormsg=_(
+                        "Could not find the required parameter ({})."
+                    ).format(arg)
+                )
+
+        try:
+            # The SQL below will execute CREATE DDL only
+            sql = render_template(
+                "/".join([self.template_path, self._CREATE_SQL]),
+                data=data, conn=self.conn
+            )
+        except Exception as e:
+            return internal_server_error(errormsg=e)
+
+        status, msg = self.conn.execute_scalar(sql)
+        if not status:
+            return internal_server_error(errormsg=msg)
+
+        if 'relacl' in data:
+            data['relacl'] = parse_priv_to_db(data['relacl'], self.acl)
+
+        # The SQL below will execute rest DMLs because we cannot execute
+        # CREATE with any other
+        sql = render_template(
+            "/".join([self.template_path, self._GRANT_SQL]),
+            data=data, conn=self.conn
+        )
+        sql = sql.strip('\n').strip(' ')
+        if sql and sql != "":
+            status, msg = self.conn.execute_scalar(sql)
+            if not status:
+                return internal_server_error(errormsg=msg)
+
+        # We need oid of newly created sequence.
+        sql = render_template(
+            "/".join([self.template_path, self._OID_SQL]),
+            name=data['name'],
+            schema=data['schema']
+        )
+        sql = sql.strip('\n').strip(' ')
+
+        status, rset = self.conn.execute_2darray(sql)
+        if not status:
+            return internal_server_error(errormsg=rset)
+
+        row = rset['rows'][0]
+        return jsonify(
+            node=self.blueprint.generate_browser_node(
+                row['oid'],
+                row['relnamespace'],
+                data['name'],
+                icon="icon-%s" % self.node_type
+            )
+        )
+
+    @check_precondition(action='delete')
+    def delete(self, gid, sid, did, scid, fooid=None, only_sql=False):
+        """
+        This function will drop the object
+
+        Args:
+          gid: Server Group ID
+          sid: Server ID
+          did: Database ID
+          scid: Schema ID
+          fooid: Sequence ID
+          only_sql: Return SQL only if True
+
+        Returns:
+
+        """
+        if fooid is None:
+            data = request.form if request.form else json.loads(
+                request.data, encoding='utf-8'
+            )
+        else:
+            data = {'ids': [fooid]}
+
+        # Below will decide if it's simple drop or drop with cascade call
+        if self.cmd == 'delete':
+            # This is a cascade operation
+            cascade = True
+        else:
+            cascade = False
+
+        try:
+            for fooid in data['ids']:
+                sql = render_template(
+                    "/".join([self.template_path, self._PROPERTIES_SQL]),
+                    scid=scid, fooid=fooid
+                )
+                status, res = self.conn.execute_dict(sql)
+                if not status:
+                    return internal_server_error(errormsg=res)
+
+                elif not res['rows']:
+                    return make_json_response(
+                        success=0,
+                        errormsg=_(
+                            'Error: Object not found.'
+                        ),
+                        info=_(
+                            'The specified sequence could not be found.\n'
+                        )
+                    )
+
+                sql = render_template(
+                    "/".join([self.template_path, self._DELETE_SQL]),
+                    data=res['rows'][0], cascade=cascade
+                )
+
+                if only_sql:
+                    return sql
+
+                status, res = self.conn.execute_scalar(sql)
+                if not status:
+                    return internal_server_error(errormsg=res)
+
+            return make_json_response(
+                success=1,
+                info=_("Sequence dropped")
+            )
+
+        except Exception as e:
+            return internal_server_error(errormsg=str(e))
+
+    @check_precondition(action='update')
+    def update(self, gid, sid, did, scid, fooid):
+        """
+        This function will update the object
+
+        Args:
+          gid: Server Group ID
+          sid: Server ID
+          did: Database ID
+          scid: Schema ID
+          fooid: Sequence ID
+
+        Returns:
+
+        """
+        data = request.form if request.form else json.loads(
+            request.data, encoding='utf-8'
+        )
+        sql, name = self.get_SQL(gid, sid, did, data, scid, fooid)
+        # Most probably this is due to error
+        if not isinstance(sql, str):
+            return sql
+
+        sql = sql.strip('\n').strip(' ')
+
+        status, res = self.conn.execute_scalar(sql)
+        if not status:
+            return internal_server_error(errormsg=res)
+
+        sql = render_template(
+            "/".join([self.template_path, self._NODES_SQL]),
+            fooid=fooid
+        )
+        status, rset = self.conn.execute_2darray(sql)
+        if not status:
+            return internal_server_error(errormsg=rset)
+        row = rset['rows'][0]
+
+        return jsonify(
+            node=self.blueprint.generate_browser_node(
+                fooid,
+                row['schema'],
+                row['name'],
+                icon="icon-%s" % self.node_type
+            )
+        )
+
+    @check_precondition(action='msql')
+    def msql(self, gid, sid, did, scid, fooid=None):
+        """
+        This function to return modified SQL.
+
+        Args:
+            gid: Server Group ID
+            sid: Server ID
+            did: Database ID
+            scid: Schema ID
+            fooid: Sequence ID
+        """
+
+        data = {}
+        for k, v in request.args.items():
+            try:
+                # comments should be taken as is because if user enters a
+                # json comment it is parsed by loads which should not happen
+                if k in ('comment',):
+                    data[k] = v
+                else:
+                    data[k] = json.loads(v, encoding='utf-8')
+            except ValueError:
+                data[k] = v
+
+        if fooid is None:
+            required_args = [
+                'name',
+                'schema'
+            ]
+
+            for arg in required_args:
+                if arg not in data:
+                    return make_json_response(
+                        status=400,
+                        success=0,
+                        errormsg=_(
+                            "Could not find the required parameter ({})."
+                        ).format(arg)
+                    )
+        sql, name = self.get_SQL(gid, sid, did, data, scid, fooid)
+        # Most probably this is due to error
+        if not isinstance(sql, str):
+            return sql
+
+        sql = sql.strip('\n').strip(' ')
+        if sql == '':
+            sql = "--modified SQL"
+
+        return make_json_response(
+            data=sql,
+            status=200
+        )
+
+    def get_SQL(self, gid, sid, did, data, scid, fooid=None):
+        """
+        This function will generate sql from model data.
+
+        Args:
+            gid: Server Group ID
+            sid: Server ID
+            did: Database ID
+            scid: Schema ID
+            fooid: Sequence ID
+        """
+
+        required_args = [
+            u'name'
+        ]
+
+        if fooid is not None:
+            sql = render_template(
+                "/".join([self.template_path, self._PROPERTIES_SQL]),
+                scid=scid, fooid=fooid
+            )
+            status, res = self.conn.execute_dict(sql)
+            if not status:
+                return internal_server_error(errormsg=res)
+            elif len(res['rows']) == 0:
+                return gone(_("Could not find the sequence in the database."))
+
+            # Making copy of output for further processing
+            old_data = dict(res['rows'][0])
+            old_data = self._formatter(old_data, scid, fooid)
+
+            self._format_privilege_data(data)
+
+            # If name is not present with in update data then copy it
+            # from old data
+            for arg in required_args:
+                if arg not in data:
+                    data[arg] = old_data[arg]
+            sql = render_template(
+                "/".join([self.template_path, self._UPDATE_SQL]),
+                data=data, o_data=old_data, conn=self.conn
+            )
+            return sql, data['name'] if 'name' in data else old_data['name']
+        else:
+            # To format privileges coming from client
+            if 'relacl' in data:
+                data['relacl'] = parse_priv_to_db(data['relacl'], self.acl)
+
+            sql = render_template(
+                "/".join([self.template_path, self._CREATE_SQL]),
+                data=data, conn=self.conn
+            )
+            sql += render_template(
+                "/".join([self.template_path, self._GRANT_SQL]),
+                data=data, conn=self.conn
+            )
+            return sql, data['name']
+
+    def _format_privilege_data(self, data):
+        # To format privileges data coming from client
+        for key in ['relacl']:
+            if key in data and data[key] is not None:
+                if 'added' in data[key]:
+                    data[key]['added'] = parse_priv_to_db(
+                        data[key]['added'], self.acl
+                    )
+                if 'changed' in data[key]:
+                    data[key]['changed'] = parse_priv_to_db(
+                        data[key]['changed'], self.acl
+                    )
+                if 'deleted' in data[key]:
+                    data[key]['deleted'] = parse_priv_to_db(
+                        data[key]['deleted'], self.acl
+                    )
+
+    @check_precondition(action="sql")
+    def sql(self, gid, sid, did, scid, fooid, **kwargs):
+        """
+        This function will generate sql for sql panel
+
+        Args:
+            gid: Server Group ID
+            sid: Server ID
+            did: Database ID
+            scid: Schema ID
+            fooid: Sequence ID
+            json_resp: json response or plain text response
+        """
+        json_resp = kwargs.get('json_resp', True)
+
+        sql = render_template(
+            "/".join([self.template_path, self._PROPERTIES_SQL]),
+            scid=scid, fooid=fooid
+        )
+        status, res = self.conn.execute_dict(sql)
+        if not status:
+            return internal_server_error(errormsg=res)
+        if len(res['rows']) == 0:
+            return gone(_("Could not find the sequence in the database."))
+
+        for row in res['rows']:
+            sql = render_template(
+                "/".join([self.template_path, 'get_def.sql']),
+                data=row
+            )
+            status, rset1 = self.conn.execute_dict(sql)
+            if not status:
+                return internal_server_error(errormsg=rset1)
+
+            row['current_value'] = rset1['rows'][0]['last_value']
+            row['minimum'] = rset1['rows'][0]['min_value']
+            row['maximum'] = rset1['rows'][0]['max_value']
+            row['increment'] = rset1['rows'][0]['increment_by']
+            row['start'] = rset1['rows'][0]['start_value']
+            row['cache'] = rset1['rows'][0]['cache_value']
+            row['cycled'] = rset1['rows'][0]['is_cycled']
+
+        result = res['rows'][0]
+
+        result = self._formatter(result, scid, fooid)
+        sql, name = self.get_SQL(gid, sid, did, result, scid)
+        # Most probably this is due to error
+        if not isinstance(sql, str):
+            return sql
+        sql = sql.strip('\n').strip(' ')
+
+        # Return sql for schema diff
+        if not json_resp:
+            return sql
+
+        sql_header = u"""-- SEQUENCE: {0}.{1}\n\n""".format(
+            result['schema'], result['name'])
+
+        sql_header += """-- DROP SEQUENCE {0};
+
+""".format(self.qtIdent(self.conn, result['schema'], result['name']))
+
+        sql = sql_header + sql
+
+        return ajax_response(response=sql)
+
+    def _formatter(self, data, scid, fooid):
+        """
+        Args:
+            data: dict of query result
+            scid: Schema ID
+            fooid: Sequence ID
+
+        Returns:
+            It will return formatted output of sequence
+        """
+
+        # Need to format security labels according to client js collection
+        if 'securities' in data and data['securities'] is not None:
+            seclabels = []
+            for seclbls in data['securities']:
+                k, v = seclbls.split('=')
+                seclabels.append({'provider': k, 'label': v})
+
+            data['securities'] = seclabels
+
+        # We need to parse & convert ACL coming from database to json format
+        sql = render_template("/".join([self.template_path, self._ACL_SQL]),
+                              scid=scid, fooid=fooid)
+        status, acl = self.conn.execute_dict(sql)
+        if not status:
+            return internal_server_error(errormsg=acl)
+
+        # We will set get privileges from acl sql so we don't need
+        # it from properties sql
+        data['relacl'] = []
+
+        for row in acl['rows']:
+            priv = parse_priv_from_db(row)
+            data.setdefault(row['deftype'], []).append(priv)
+
+        return data
+
+    @check_precondition(action="dependents")
+    def dependents(self, gid, sid, did, scid, fooid):
+        """
+        This function gets the dependents and returns an ajax response
+        for the sequence node.
+
+        Args:
+            gid: Server Group ID
+            sid: Server ID
+            did: Database ID
+            scid: Schema ID
+            fooid: Sequence ID
+        """
+        dependents_result = self.get_dependents(self.conn, fooid)
+        return ajax_response(
+            response=dependents_result,
+            status=200
+        )
+
+    @check_precondition(action="dependencies")
+    def dependencies(self, gid, sid, did, scid, fooid):
+        """
+        This function gets the dependencies and returns an ajax response
+        for the sequence node.
+
+        Args:
+            gid: Server Group ID
+            sid: Server ID
+            did: Database ID
+            scid: Schema ID
+            fooid: Sequence ID
+        """
+
+        return ajax_response(
+            response=self._get_dependency(fooid),
+            status=200
+        )
+
+    def _get_dependency(self, fooid, show_system_objects=None):
+        dependencies_result = self.get_dependencies(self.conn, fooid, None,
+                                                    show_system_objects)
+
+        # Get missing dependencies.
+        # A Corner case, reported by Guillaume Lelarge, could be found at:
+        # http://archives.postgresql.org/pgadmin-hackers/2009-03/msg00026.php
+
+        sql = render_template("/".join([self.template_path,
+                                        'get_dependencies.sql']), fooid=fooid)
+
+        status, result = self.conn.execute_dict(sql)
+        if not status:
+            return internal_server_error(errormsg=result)
+
+        for row in result['rows']:
+            ref_name = row['refname']
+            if ref_name is None:
+                continue
+
+            dep_type = ''
+            dep_str = row['deptype']
+            if dep_str == 'a':
+                dep_type = 'auto'
+            elif dep_str == 'n':
+                dep_type = 'normal'
+            elif dep_str == 'i':
+                dep_type = 'internal'
+
+            dependencies_result.append({'type': 'column',
+                                        'name': ref_name,
+                                        'field': dep_type})
+        return dependencies_result
+
+    @check_precondition(action="stats")
+    def statistics(self, gid, sid, did, scid, fooid=None):
+        """
+        Statistics
+
+        Args:
+            gid: Server Group Id
+            sid: Server Id
+            did: Database Id
+            scid: Schema Id
+            fooid: Sequence Id
+
+        Returns the statistics for a particular object if fooid is specified
+        """
+        if fooid is not None:
+            sql = 'stats.sql'
+            schema_name = None
+        else:
+            sql = 'coll_stats.sql'
+            # Get schema name
+            status, schema_name = self.conn.execute_scalar(
+                render_template(
+                    'schemas/pg/#{0}#/sql/get_name.sql'.format(
+                        self.manager.version
+                    ),
+                    scid=scid
+                )
+            )
+            if not status:
+                return internal_server_error(errormsg=schema_name)
+
+        status, res = self.conn.execute_dict(
+            render_template(
+                "/".join([self.template_path, sql]),
+                conn=self.conn, fooid=fooid,
+                schema_name=schema_name
+            )
+        )
+
+        if not status:
+            return internal_server_error(errormsg=res)
+
+        return make_json_response(
+            data=res,
+            status=200
+        )
+
+    @check_precondition(action="fetch_objects_to_compare")
+    def fetch_objects_to_compare(self, sid, did, scid):
+        """
+        This function will fetch the list of all the sequences for
+        specified schema id.
+
+        :param sid: Server Id
+        :param did: Database Id
+        :param scid: Schema Id
+        :return:
+        """
+        res = dict()
+        sql = render_template("/".join([self.template_path,
+                                        self._NODES_SQL]), scid=scid)
+        status, rset = self.conn.execute_2darray(sql)
+        if not status:
+            return internal_server_error(errormsg=res)
+
+        for row in rset['rows']:
+            status, data = self._fetch_properties(scid, row['oid'])
+            if status:
+                res[row['name']] = data
+
+        return res
+
+    def get_sql_from_diff(self, **kwargs):
+        """
+        This function is used to get the DDL/DML statements.
+        :param kwargs
+        :return:
+        """
+        gid = kwargs.get('gid')
+        sid = kwargs.get('sid')
+        did = kwargs.get('did')
+        scid = kwargs.get('scid')
+        oid = kwargs.get('oid')
+        data = kwargs.get('data', None)
+        drop_sql = kwargs.get('drop_sql', False)
+
+        if data:
+            sql, name = self.get_SQL(gid, sid, did, data, scid, oid)
+        else:
+            if drop_sql:
+                sql = self.delete(gid=gid, sid=sid, did=did,
+                                  scid=scid, fooid=oid, only_sql=True)
+            else:
+                sql = self.sql(gid=gid, sid=sid, did=did, scid=scid, fooid=oid,
+                               json_resp=False)
+        return sql
+
+
+SchemaDiffRegistry(blueprint.node_type, FooView)
+FooView.register_node_view(blueprint)
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/static/img/coll-foo.svg b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/static/img/coll-foo.svg
new file mode 100644
index 000000000..9be12471d
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/static/img/coll-foo.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.cls-1{font-size:8px;fill:#7749bd;font-family:Helvetica-Bold, Helvetica;font-weight:700;}</style></defs><title>coll-sequence</title><g id="_2" data-name="2"><text class="cls-1" transform="translate(1.4 10.79)">1</text><text class="cls-1" transform="translate(9.87 10.79)">3</text><text class="cls-1" transform="translate(5.23 10.79)">..</text></g></svg>
\ No newline at end of file
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/static/img/foo.svg b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/static/img/foo.svg
new file mode 100644
index 000000000..5072a1ca8
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/static/img/foo.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.cls-1{font-size:8px;fill:#7749bd;font-family:Helvetica-Bold, Helvetica;font-weight:700;}</style></defs><title>sequence</title><g id="_2" data-name="2"><text class="cls-1" transform="translate(1.4 10.83)">1</text><text class="cls-1" transform="translate(9.87 10.83)">3</text><text class="cls-1" transform="translate(5.23 10.83)">..</text></g></svg>
\ No newline at end of file
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/static/js/foo.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/static/js/foo.js
new file mode 100644
index 000000000..162a34433
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/static/js/foo.js
@@ -0,0 +1,299 @@
+/////////////////////////////////////////////////////////////
+//
+// pgAdmin 4 - PostgreSQL Tools
+//
+// Copyright (C) 2013 - 2020, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+//////////////////////////////////////////////////////////////
+
+define('pgadmin.node.foo', [
+  'sources/gettext', 'sources/url_for', 'jquery', 'underscore',
+  'sources/pgadmin', 'pgadmin.browser', 'pgadmin.backform',
+  'pgadmin.node.schema.dir/child', 'pgadmin.node.schema.dir/schema_child_tree_node',
+  'pgadmin.browser.collection',
+], function(
+  gettext, url_for, $, _, pgAdmin, pgBrowser, Backform, schemaChild,
+  schemaChildTreeNode
+) {
+
+  // Extend the browser's collection class for foo collection
+  if (!pgBrowser.Nodes['coll-foo']) {
+    pgBrowser.Nodes['coll-foo'] =
+      pgBrowser.Collection.extend({
+        node: 'foo',
+        label: gettext('Foos'),
+        type: 'coll-foo',
+        columns: ['name', 'seqowner', 'comment'],
+        hasStatistics: true,
+        canDrop: schemaChildTreeNode.isTreeItemOfChildOfSchema,
+        canDropCascade: schemaChildTreeNode.isTreeItemOfChildOfSchema,
+      });
+  }
+
+  // Extend the browser's node class for foo node
+  if (!pgBrowser.Nodes['foo']) {
+    pgBrowser.Nodes['foo'] = schemaChild.SchemaChildNode.extend({
+      type: 'foo',
+      sqlAlterHelp: 'sql-alterfoo.html',
+      sqlCreateHelp: 'sql-createfoo.html',
+      dialogHelp: url_for('help.static', {'filename': 'foo_dialog.html'}),
+      label: gettext('Foo'),
+      collection_type: 'coll-foo',
+      hasSQL: true,
+      hasDepends: true,
+      hasStatistics: true,
+      Init: function() {
+        /* Avoid mulitple registration of menus */
+        if (this.initialized)
+          return;
+
+        this.initialized = true;
+
+        pgBrowser.add_menus([{
+          name: 'create_foo_on_coll', node: 'coll-foo', module: this,
+          applies: ['object', 'context'], callback: 'show_obj_properties',
+          category: 'create', priority: 4, label: gettext('Foo...'),
+          icon: 'wcTabIcon icon-foo', data: {action: 'create', check: true},
+          enable: 'canCreate',
+        },{
+          name: 'create_foo', node: 'foo', module: this,
+          applies: ['object', 'context'], callback: 'show_obj_properties',
+          category: 'create', priority: 4, label: gettext('Foo...'),
+          icon: 'wcTabIcon icon-foo', data: {action: 'create', check: true},
+          enable: 'canCreate',
+        },{
+          name: 'create_foo', node: 'schema', module: this,
+          applies: ['object', 'context'], callback: 'show_obj_properties',
+          category: 'create', priority: 4, label: gettext('Foo...'),
+          icon: 'wcTabIcon icon-foo', data: {action: 'create', check: false},
+          enable: 'canCreate',
+        },
+        ]);
+
+      },
+      // Define the model for foo node.
+      model: pgBrowser.Node.Model.extend({
+        idAttribute: 'oid',
+        defaults: {
+          name: undefined,
+          oid: undefined,
+          seqowner: undefined,
+          schema: undefined,
+          is_sys_obj: undefined,
+          comment: undefined,
+          increment: undefined,
+          start: undefined,
+          current_value: undefined,
+          minimum: undefined,
+          maximum: undefined,
+          cache: undefined,
+          cycled: undefined,
+          relacl: [],
+          securities: [],
+        },
+
+        // Default values!
+        initialize: function(attrs, args) {
+          var isNew = (_.size(attrs) === 0);
+
+          if (isNew) {
+            var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
+            var schemaInfo = args.node_info.schema;
+
+            this.set({'seqowner': userInfo.name}, {silent: true});
+            this.set({'schema': schemaInfo._label}, {silent: true});
+          }
+          pgBrowser.Node.Model.prototype.initialize.apply(this, arguments);
+        },
+
+        // Define the schema for foo node.
+        schema: [{
+          id: 'name', label: gettext('Name'), cell: 'string',
+          type: 'text', mode: ['properties', 'create', 'edit'],
+        },{
+          id: 'oid', label: gettext('OID'), cell: 'string',
+          type: 'text', mode: ['properties'],
+        },{
+          id: 'seqowner', label: gettext('Owner'), cell: 'string',
+          type: 'text', mode: ['properties', 'create', 'edit'], node: 'role',
+          control: Backform.NodeListByNameControl,
+        },{
+          id: 'schema', label: gettext('Schema'), cell: 'string',
+          control: 'node-list-by-name', node: 'schema',
+          type: 'text', mode: ['create', 'edit'], filter: function(d) {
+            // If schema name start with pg_* then we need to exclude them
+            if(d && d.label.match(/^pg_/))
+            {
+              return false;
+            }
+            return true;
+          }, cache_node: 'database', cache_level: 'database',
+        },{
+          id: 'is_sys_obj', label: gettext('System sequence?'),
+          cell:'boolean', type: 'switch', mode: ['properties'],
+        },{
+          id: 'comment', label: gettext('Comment'), type: 'multiline',
+          mode: ['properties', 'create', 'edit'],
+        },{
+          id: 'current_value', label: gettext('Current value'), type: 'int',
+          mode: ['properties', 'edit'], group: gettext('Definition'),
+        },{
+          id: 'increment', label: gettext('Increment'), type: 'int',
+          mode: ['properties', 'create', 'edit'], group: gettext('Definition'),
+        },{
+          id: 'start', label: gettext('Start'), type: 'int',
+          mode: ['properties', 'create'], group: gettext('Definition'),
+          readonly: function(m) {
+            return !m.isNew();
+          },
+        },{
+          id: 'minimum', label: gettext('Minimum'), type: 'int',
+          mode: ['properties', 'create', 'edit'], group: gettext('Definition'),
+        },{
+          id: 'maximum', label: gettext('Maximum'), type: 'int',
+          mode: ['properties', 'create', 'edit'], group: gettext('Definition'),
+        },{
+          id: 'cache', label: gettext('Cache'), type: 'int',
+          mode: ['properties', 'create', 'edit'], group: gettext('Definition'),
+          min: 1,
+        },{
+          id: 'cycled', label: gettext('Cycled'), type: 'switch',
+          mode: ['properties', 'create', 'edit'], group: gettext('Definition'),
+        }, pgBrowser.SecurityGroupSchema,{
+          id: 'acl', label: gettext('Privileges'), type: 'text',
+          group: gettext('Security'), mode: ['properties'],
+        },{
+          id: 'relacl', label: gettext('Privileges'), group: 'security',
+          model: pgBrowser.Node.PrivilegeRoleModel.extend({
+            privileges: ['r', 'w', 'U'],
+          }), uniqueCol : ['grantee', 'grantor'], mode: ['edit', 'create'],
+          editable: false, type: 'collection', canAdd: true, canDelete: true,
+          control: 'unique-col-collection',
+        },{
+          id: 'securities', label: gettext('Security labels'), canAdd: true,
+          model: pgBrowser.SecLabelModel, editable: false,
+          type: 'collection', canEdit: false, group: 'security',
+          mode: ['edit', 'create'], canDelete: true,
+          control: 'unique-col-collection',
+          min_version: 90200, uniqueCol : ['provider'],
+        }],
+        /* validate function is used to validate the input given by
+         * the user. In case of error, message will be displayed on
+         * the GUI for the respective control.
+         */
+        validate: function() {
+          var msg = undefined,
+            minimum = this.get('minimum'),
+            maximum = this.get('maximum'),
+            start = this.get('start');
+
+          if (_.isUndefined(this.get('name'))
+              || String(this.get('name')).replace(/^\s+|\s+$/g, '') == '') {
+            msg = gettext('Name cannot be empty.');
+            this.errorModel.set('name', msg);
+            return msg;
+          } else {
+            this.errorModel.unset('name');
+          }
+
+          if (_.isUndefined(this.get('seqowner'))
+              || String(this.get('seqowner')).replace(/^\s+|\s+$/g, '') == '') {
+            msg = gettext('Owner cannot be empty.');
+            this.errorModel.set('seqowner', msg);
+            return msg;
+          } else {
+            this.errorModel.unset('seqowner');
+          }
+
+          if (_.isUndefined(this.get('schema'))
+              || String(this.get('schema')).replace(/^\s+|\s+$/g, '') == '') {
+            msg = gettext('Schema cannot be empty.');
+            this.errorModel.set('schema', msg);
+            return msg;
+          } else {
+            this.errorModel.unset('schema');
+          }
+
+          if (!this.isNew()) {
+            if (_.isUndefined(this.get('current_value'))
+              || String(this.get('current_value')).replace(/^\s+|\s+$/g, '') == '') {
+              msg = gettext('Current value cannot be empty.');
+              this.errorModel.set('current_value', msg);
+              return msg;
+            } else {
+              this.errorModel.unset('current_value');
+            }
+
+            if (_.isUndefined(this.get('increment'))
+              || String(this.get('increment')).replace(/^\s+|\s+$/g, '') == '') {
+              msg = gettext('Increment value cannot be empty.');
+              this.errorModel.set('increment', msg);
+              return msg;
+            } else {
+              this.errorModel.unset('increment');
+            }
+
+            if (_.isUndefined(this.get('minimum'))
+              || String(this.get('minimum')).replace(/^\s+|\s+$/g, '') == '') {
+              msg = gettext('Minimum value cannot be empty.');
+              this.errorModel.set('minimum', msg);
+              return msg;
+            } else {
+              this.errorModel.unset('minimum');
+            }
+
+            if (_.isUndefined(this.get('maximum'))
+              || String(this.get('maximum')).replace(/^\s+|\s+$/g, '') == '') {
+              msg = gettext('Maximum value cannot be empty.');
+              this.errorModel.set('maximum', msg);
+              return msg;
+            } else {
+              this.errorModel.unset('maximum');
+            }
+
+            if (_.isUndefined(this.get('cache'))
+              || String(this.get('cache')).replace(/^\s+|\s+$/g, '') == '') {
+              msg = gettext('Cache value cannot be empty.');
+              this.errorModel.set('cache', msg);
+              return msg;
+            } else {
+              this.errorModel.unset('cache');
+            }
+          }
+          var min_lt = gettext('Minimum value must be less than maximum value.'),
+            start_lt = gettext('Start value cannot be less than minimum value.'),
+            start_gt = gettext('Start value cannot be greater than maximum value.');
+
+          if (_.isEmpty(minimum) || _.isEmpty(maximum))
+            return null;
+
+          if ((minimum == 0 && maximum == 0) ||
+              (parseInt(minimum, 10) >= parseInt(maximum, 10))) {
+            this.errorModel.set('minimum', min_lt);
+            return min_lt;
+          } else {
+            this.errorModel.unset('minimum');
+          }
+
+          if (start && minimum && parseInt(start) < parseInt(minimum)) {
+            this.errorModel.set('start', start_lt);
+            return start_lt;
+          } else {
+            this.errorModel.unset('start');
+          }
+
+          if (start && maximum && parseInt(start) > parseInt(maximum)) {
+            this.errorModel.set('start', start_gt);
+            return start_gt;
+          } else {
+            this.errorModel.unset('start');
+          }
+          return null;
+        },
+      }),
+    });
+  }
+
+  return pgBrowser.Nodes['foo'];
+});
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/10_plus/get_def.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/10_plus/get_def.sql
new file mode 100644
index 000000000..91ca135d1
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/10_plus/get_def.sql
@@ -0,0 +1,11 @@
+SELECT
+    last_value,
+    seqmin AS min_value,
+    seqmax AS max_value,
+    seqstart AS start_value,
+    seqcache AS cache_value,
+    seqcycle AS is_cycled,
+    seqincrement AS increment_by,
+    is_called
+FROM pg_sequence, {{ conn|qtIdent(data.schema) }}.{{ conn|qtIdent(data.name) }}
+WHERE seqrelid = {{data.oid}}
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/acl.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/acl.sql
new file mode 100644
index 000000000..e94f93b0e
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/acl.sql
@@ -0,0 +1,30 @@
+SELECT 'relacl' as deftype, COALESCE(gt.rolname, 'PUBLIC') grantee, g.rolname grantor, array_agg(privilege_type) as privileges, array_agg(is_grantable) as grantable
+FROM
+    (SELECT
+        d.grantee, d.grantor, d.is_grantable,
+        CASE d.privilege_type
+        WHEN 'CONNECT' THEN 'c'
+        WHEN 'CREATE' THEN 'C'
+        WHEN 'DELETE' THEN 'd'
+        WHEN 'EXECUTE' THEN 'X'
+        WHEN 'INSERT' THEN 'a'
+        WHEN 'REFERENCES' THEN 'x'
+        WHEN 'SELECT' THEN 'r'
+        WHEN 'TEMPORARY' THEN 'T'
+        WHEN 'TRIGGER' THEN 't'
+        WHEN 'TRUNCATE' THEN 'D'
+        WHEN 'UPDATE' THEN 'w'
+        WHEN 'USAGE' THEN 'U'
+        ELSE 'UNKNOWN'
+        END AS privilege_type
+    FROM
+        aclexplode((SELECT relacl
+            FROM pg_class cl
+            LEFT OUTER JOIN pg_description des ON (des.objoid=cl.oid AND des.classoid='pg_class'::regclass)
+            WHERE relkind = 'S' AND relnamespace  = {{scid}}::oid
+            AND cl.oid = {{fooid}}::oid )) d
+        ) d
+    LEFT JOIN pg_catalog.pg_roles g ON (d.grantor = g.oid)
+    LEFT JOIN pg_catalog.pg_roles gt ON (d.grantee = gt.oid)
+GROUP BY g.rolname, gt.rolname
+ORDER BY grantee
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/backend_support.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/backend_support.sql
new file mode 100644
index 000000000..1c8a83213
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/backend_support.sql
@@ -0,0 +1,15 @@
+SELECT
+    CASE WHEN nsp.nspname IN ('sys', 'dbo', 'information_schema') THEN true ELSE false END AS dbSupport
+FROM pg_namespace nsp
+WHERE nsp.oid={{scid}}::oid AND (
+    (nspname = 'pg_catalog' AND EXISTS
+        (SELECT 1 FROM pg_class WHERE relname = 'pg_class' AND relnamespace = nsp.oid LIMIT 1))
+    OR (nspname = 'pgagent' AND EXISTS
+	(SELECT 1 FROM pg_class WHERE relname = 'pga_job' AND relnamespace = nsp.oid LIMIT 1))
+    OR (nspname = 'information_schema' AND EXISTS
+	(SELECT 1 FROM pg_class WHERE relname = 'tables' AND relnamespace = nsp.oid LIMIT 1))
+    OR (nspname LIKE '_%' AND EXISTS
+	 (SELECT 1 FROM pg_proc WHERE proname='slonyversion' AND pronamespace = nsp.oid LIMIT 1))
+    ) AND
+    nspname NOT LIKE E'pg\\temp\\%' AND
+    nspname NOT LIKE E'pg\\toast_temp\\%'
\ No newline at end of file
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/coll_stats.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/coll_stats.sql
new file mode 100644
index 000000000..71d3c7059
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/coll_stats.sql
@@ -0,0 +1,9 @@
+SELECT
+    relname AS {{ conn|qtIdent(_('Name')) }},
+    blks_read AS {{ conn|qtIdent(_('Blocks read')) }},
+    blks_hit AS {{ conn|qtIdent(_('Blocks hit')) }}
+FROM
+    pg_statio_all_sequences
+WHERE
+    schemaname = {{ schema_name|qtLiteral }}
+ORDER BY relname;
\ No newline at end of file
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/create.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/create.sql
new file mode 100644
index 000000000..4a28806a4
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/create.sql
@@ -0,0 +1,16 @@
+CREATE SEQUENCE {{ conn|qtIdent(data.schema, data.name) }}{% if data.increment is defined and data.cycled %}
+
+    CYCLE{% endif %}{% if data.increment is defined %}
+
+    INCREMENT {{data.increment|int}}{% endif %}{% if data.start is defined %}
+
+    START {{data.start|int}}{% elif data.current_value is defined %}
+
+    START {{data.current_value|int}}{% endif %}{% if data.minimum is defined %}
+
+    MINVALUE {{data.minimum|int}}{% endif %}{% if data.maximum is defined %}
+
+    MAXVALUE {{data.maximum|int}}{% endif %}{% if data.cache is defined and data.cache|int(-1) > -1%}
+
+    CACHE {{data.cache|int}}{% endif %};
+
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/delete.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/delete.sql
new file mode 100644
index 000000000..efd218edf
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/delete.sql
@@ -0,0 +1 @@
+DROP SEQUENCE {{ conn|qtIdent(data.schema) }}.{{ conn|qtIdent(data.name) }}{% if cascade%} CASCADE{% endif %};
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/get_def.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/get_def.sql
new file mode 100644
index 000000000..e0e9efba1
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/get_def.sql
@@ -0,0 +1,10 @@
+SELECT 
+    last_value, 
+    min_value, 
+    max_value,
+    start_value,
+    cache_value,
+    is_cycled, 
+    increment_by,
+    is_called
+FROM {{ conn|qtIdent(data.schema) }}.{{ conn|qtIdent(data.name) }}
\ No newline at end of file
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/get_dependencies.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/get_dependencies.sql
new file mode 100644
index 000000000..325ee79ea
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/get_dependencies.sql
@@ -0,0 +1,12 @@
+SELECT
+    CASE WHEN att.attname IS NOT NULL AND ref.relname IS NOT NULL THEN ref.relname || '.' || att.attname
+       ELSE ref.relname
+    END AS refname,
+    d2.refclassid, d1.deptype AS deptype
+FROM pg_depend d1
+    LEFT JOIN pg_depend d2 ON d1.objid=d2.objid AND d1.refobjid != d2.refobjid
+    LEFT JOIN pg_class ref ON ref.oid = d2.refobjid
+    LEFT JOIN pg_attribute att ON d2.refobjid=att.attrelid AND d2.refobjsubid=att.attnum
+WHERE d1.classid=(SELECT oid FROM pg_class WHERE relname='pg_attrdef')
+    AND d2.refobjid NOT IN (SELECT d3.refobjid FROM pg_depend d3 WHERE d3.objid=d1.refobjid)
+    AND d1.refobjid={{fooid}}::oid
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/get_oid.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/get_oid.sql
new file mode 100644
index 000000000..340a66416
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/get_oid.sql
@@ -0,0 +1,7 @@
+SELECT cl.oid as oid, relnamespace
+FROM pg_class cl
+LEFT OUTER JOIN pg_description des ON (des.objoid=cl.oid AND des.classoid='pg_class'::regclass)
+LEFT OUTER JOIN pg_namespace nsp ON (nsp.oid = cl.relnamespace)
+WHERE relkind = 'S'
+AND relname = {{ name|qtLiteral }}
+AND nspname = {{ schema|qtLiteral }}
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/grant.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/grant.sql
new file mode 100644
index 000000000..d4a382c66
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/grant.sql
@@ -0,0 +1,26 @@
+{% import 'macros/schemas/security.macros' as SECLABEL %}
+{% import 'macros/schemas/privilege.macros' as PRIVILEGE %}
+{# Construct sequence name from name and schema #}
+{% set seqname=conn|qtIdent(data.schema, data.name) %}
+{% if data.seqowner %}
+
+ALTER SEQUENCE {{ seqname }}
+    OWNER TO {{ conn|qtIdent(data.seqowner) }};
+{% endif %}
+{% if data.comment %}
+
+COMMENT ON SEQUENCE {{ seqname }}
+    IS {{ data.comment|qtLiteral }};
+{% endif %}
+{% if data.securities %}
+
+{% for r in data.securities %}
+{{ SECLABEL.SET(conn, 'SEQUENCE', data.name, r.provider, r.label, data.schema) }}
+{% endfor %}
+{% endif %}
+{% if data.relacl %}
+
+{% for priv in data.relacl %}
+{{ PRIVILEGE.SET(conn, 'SEQUENCE', priv.grantee, data.name, priv.without_grant, priv.with_grant, data.schema) }}
+{% endfor %}
+{% endif %}
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/nodes.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/nodes.sql
new file mode 100644
index 000000000..f418ca133
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/nodes.sql
@@ -0,0 +1,11 @@
+SELECT cl.oid as oid, relname as name, relnamespace as schema
+FROM pg_class cl
+WHERE
+    relkind = 'S'
+{% if scid %}
+    AND relnamespace = {{scid|qtLiteral}}::oid
+{% endif %}
+{% if fooid %}
+    AND cl.oid = {{fooid|qtLiteral}}::oid
+{% endif %}
+ORDER BY relname
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/properties.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/properties.sql
new file mode 100644
index 000000000..ff186b71c
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/properties.sql
@@ -0,0 +1,17 @@
+{% if scid %}
+SELECT
+    cl.oid as oid,
+    relname as name,
+    nsp.nspname as schema,
+    pg_get_userbyid(relowner) AS seqowner,
+    description as comment,
+    array_to_string(relacl::text[], ', ') as acl,
+    (SELECT array_agg(provider || '=' || label) FROM pg_seclabels sl1 WHERE sl1.objoid=cl.oid) AS securities
+FROM pg_class cl
+    LEFT OUTER JOIN pg_namespace nsp ON cl.relnamespace = nsp.oid
+    LEFT OUTER JOIN pg_description des ON (des.objoid=cl.oid
+        AND des.classoid='pg_class'::regclass)
+WHERE relkind = 'S' AND relnamespace  = {{scid}}::oid
+{% if fooid %}AND cl.oid = {{fooid}}::oid {% endif %}
+ORDER BY relname
+{% endif %}
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/stats.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/stats.sql
new file mode 100644
index 000000000..cd9b0154a
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/stats.sql
@@ -0,0 +1,7 @@
+SELECT
+    blks_read AS {{ conn|qtIdent(_('Blocks read')) }},
+    blks_hit AS {{ conn|qtIdent(_('Blocks hit')) }}
+FROM
+    pg_statio_all_sequences
+WHERE
+    relid = {{ seid }}::OID
\ No newline at end of file
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/update.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/update.sql
new file mode 100644
index 000000000..2d42249b5
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/default/update.sql
@@ -0,0 +1,97 @@
+{% import 'macros/schemas/security.macros' as SECLABEL %}
+{% import 'macros/schemas/privilege.macros' as PRIVILEGE %}
+{% if data %}
+{% if data.name != o_data.name %}
+ALTER SEQUENCE {{ conn|qtIdent(o_data.schema, o_data.name) }}
+    RENAME TO {{ conn|qtIdent(data.name) }};
+
+{% endif %}
+{% if data.seqowner and data.seqowner != o_data.seqowner %}
+ALTER SEQUENCE {{ conn|qtIdent(o_data.schema, data.name) }}
+    OWNER TO {{ conn|qtIdent(data.seqowner) }};
+
+{% endif %}
+{% if data.current_value is defined %}
+{% set seqname = conn|qtIdent(o_data.schema, data.name) %}
+SELECT setval({{ seqname|qtLiteral }}, {{ data.current_value }}, true);
+
+{% endif %}
+{% set defquery = '' %}
+{% if data.increment is defined %}
+{% set defquery = defquery+'\n    INCREMENT '+data.increment|string %}
+{% endif %}
+{% if data.start is defined %}
+{% set defquery = defquery+'\n    START '+data.start|string %}
+{% endif %}
+{% if data.minimum is defined %}
+{% set defquery = defquery+'\n    MINVALUE '+data.minimum|string %}
+{% endif %}
+{% if data.maximum is defined %}
+{% set defquery = defquery+'\n    MAXVALUE '+data.maximum|string %}
+{% endif %}
+{% if data.cache is defined %}
+{% set defquery = defquery+'\n    CACHE '+data.cache|string %}
+{% endif %}
+{% if data.cycled == True %}
+{% set defquery = defquery+'\n    CYCLE' %}
+{% elif data.cycled == False %}
+{% set defquery = defquery+'\n    NO CYCLE' %}
+{% endif %}
+{% if defquery and defquery != '' %}
+ALTER SEQUENCE {{ conn|qtIdent(o_data.schema, data.name) }}{{ defquery }};
+
+{% endif %}
+{% if data.schema and data.schema != o_data.schema %}
+ALTER SEQUENCE {{ conn|qtIdent(o_data.schema, data.name) }}
+    SET SCHEMA {{ conn|qtIdent(data.schema) }};
+
+{% set seqname = conn|qtIdent(data.schema, data.name) %}
+{% set schema = data.schema %}
+{% else %}
+{% set seqname = conn|qtIdent(o_data.schema, data.name) %}
+{% set schema = o_data.schema %}
+{% endif %}
+{% if data.comment is defined and data.comment != o_data.comment %}
+COMMENT ON SEQUENCE {{ seqname }}
+    IS {{ data.comment|qtLiteral }};
+
+{% endif %}
+{% if data.securities and data.securities|length > 0 %}
+
+{% set seclabels = data.securities %}
+{% if 'deleted' in seclabels and seclabels.deleted|length > 0 %}
+{% for r in seclabels.deleted %}
+{{ SECLABEL.UNSET(conn, 'SEQUENCE', data.name, r.provider, schema) }}
+{% endfor %}
+{% endif %}
+{% if 'added' in seclabels and seclabels.added|length > 0 %}
+{% for r in seclabels.added %}
+{{ SECLABEL.SET(conn, 'SEQUENCE', data.name, r.provider, r.label, schema) }}
+{% endfor %}
+{% endif %}
+{% if 'changed' in seclabels and seclabels.changed|length > 0 %}
+{% for r in seclabels.changed %}
+{{ SECLABEL.SET(conn, 'SEQUENCE', data.name, r.provider, r.label, schema) }}
+{% endfor %}
+{% endif %}
+{% endif %}
+{% if data.relacl %}
+
+{% if 'deleted' in data.relacl %}
+{% for priv in data.relacl.deleted %}
+{{ PRIVILEGE.UNSETALL(conn, 'SEQUENCE', priv.grantee, data.name, schema) }}
+{% endfor %}
+{% endif %}
+{% if 'changed' in data.relacl %}
+{% for priv in data.relacl.changed %}
+{{ PRIVILEGE.UNSETALL(conn, 'SEQUENCE', priv.grantee, data.name, schema) }}
+{{ PRIVILEGE.SET(conn, 'SEQUENCE', priv.grantee, data.name, priv.without_grant, priv.with_grant, schema) }}
+{% endfor %}
+{% endif %}
+{% if 'added' in data.relacl %}
+{% for priv in data.relacl.added %}
+{{ PRIVILEGE.SET(conn, 'SEQUENCE', priv.grantee, data.name, priv.without_grant, priv.with_grant, schema) }}
+{% endfor %}
+{% endif %}
+{% endif %}
+{% endif %}
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/gpdb_5.0_plus/acl.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/gpdb_5.0_plus/acl.sql
new file mode 100644
index 000000000..167184011
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/templates/foos/sql/gpdb_5.0_plus/acl.sql
@@ -0,0 +1,7 @@
+SELECT
+  'relacl' AS deftype,
+  'PUBLIC' AS grantee,
+  NULL     AS grantor,
+  NULL     AS privileges,
+  NULL     AS grantable
+LIMIT 0;
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/__init__.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/__init__.py
new file mode 100644
index 000000000..512b71da3
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/__init__.py
@@ -0,0 +1,15 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2020, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+from pgadmin.utils.route import BaseTestGenerator
+
+
+class SequenceTestGenerator(BaseTestGenerator):
+    def runTest(self):
+        return []
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_neg_seq_props.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_neg_seq_props.sql
new file mode 100644
index 000000000..ce1a63de0
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_neg_seq_props.sql
@@ -0,0 +1,13 @@
+-- SEQUENCE: public.Seq1_$%{}[]()&*^!@"'`\/#
+
+-- DROP SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#";
+
+CREATE SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"
+    INCREMENT -7
+    START -30
+    MINVALUE -35
+    MAXVALUE -15
+    CACHE 1;
+
+ALTER SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"
+    OWNER TO postgres;
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_neg_seq_props_msql.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_neg_seq_props_msql.sql
new file mode 100644
index 000000000..f56eab153
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_neg_seq_props_msql.sql
@@ -0,0 +1,4 @@
+ALTER SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"
+    INCREMENT -7
+    MINVALUE -35
+    MAXVALUE -15;
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_comment.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_comment.sql
new file mode 100644
index 000000000..b98eb4871
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_comment.sql
@@ -0,0 +1,16 @@
+-- SEQUENCE: public.Seq1_$%{}[]()&*^!@"'`\/#
+
+-- DROP SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#";
+
+CREATE SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"
+    INCREMENT 5
+    START 5
+    MINVALUE 5
+    MAXVALUE 999
+    CACHE 1;
+
+ALTER SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"
+    OWNER TO postgres;
+
+COMMENT ON SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"
+    IS 'Some comment';
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_comment_msql.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_comment_msql.sql
new file mode 100644
index 000000000..7a5efbd92
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_comment_msql.sql
@@ -0,0 +1,2 @@
+COMMENT ON SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"
+    IS 'Some comment';
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_privs_add.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_privs_add.sql
new file mode 100644
index 000000000..16abe7497
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_privs_add.sql
@@ -0,0 +1,21 @@
+-- SEQUENCE: public.Seq1_$%{}[]()&*^!@"'`\/#
+
+-- DROP SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#";
+
+CREATE SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"
+    CYCLE
+    INCREMENT 12
+    START 5
+    MINVALUE 2
+    MAXVALUE 9992
+    CACHE 2;
+
+ALTER SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"
+    OWNER TO postgres;
+
+COMMENT ON SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"
+    IS 'Some comment';
+
+GRANT ALL ON SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" TO PUBLIC;
+
+GRANT ALL ON SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" TO postgres;
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_privs_add_msql.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_privs_add_msql.sql
new file mode 100644
index 000000000..66d9aa002
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_privs_add_msql.sql
@@ -0,0 +1 @@
+GRANT ALL ON SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" TO PUBLIC;
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_privs_remove.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_privs_remove.sql
new file mode 100644
index 000000000..b392b3e31
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_privs_remove.sql
@@ -0,0 +1,19 @@
+-- SEQUENCE: public.Seq1_$%{}[]()&*^!@"'`\/#
+
+-- DROP SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#";
+
+CREATE SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"
+    CYCLE
+    INCREMENT 12
+    START 5
+    MINVALUE 2
+    MAXVALUE 9992
+    CACHE 2;
+
+ALTER SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"
+    OWNER TO postgres;
+
+COMMENT ON SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"
+    IS 'Some comment';
+
+GRANT ALL ON SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" TO postgres;
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_privs_remove_msql.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_privs_remove_msql.sql
new file mode 100644
index 000000000..e8b94bad8
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_privs_remove_msql.sql
@@ -0,0 +1 @@
+REVOKE ALL ON SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" FROM PUBLIC;
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_privs_update.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_privs_update.sql
new file mode 100644
index 000000000..9b379e9ab
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_privs_update.sql
@@ -0,0 +1,21 @@
+-- SEQUENCE: public.Seq1_$%{}[]()&*^!@"'`\/#
+
+-- DROP SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#";
+
+CREATE SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"
+    CYCLE
+    INCREMENT 12
+    START 5
+    MINVALUE 2
+    MAXVALUE 9992
+    CACHE 2;
+
+ALTER SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"
+    OWNER TO postgres;
+
+COMMENT ON SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"
+    IS 'Some comment';
+
+GRANT SELECT ON SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" TO PUBLIC;
+
+GRANT ALL ON SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" TO postgres;
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_privs_update_msql.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_privs_update_msql.sql
new file mode 100644
index 000000000..c3c2a5b9a
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_privs_update_msql.sql
@@ -0,0 +1,2 @@
+REVOKE ALL ON SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" FROM PUBLIC;
+GRANT SELECT ON SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" TO PUBLIC;
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_props.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_props.sql
new file mode 100644
index 000000000..78122be35
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_props.sql
@@ -0,0 +1,17 @@
+-- SEQUENCE: public.Seq1_$%{}[]()&*^!@"'`\/#
+
+-- DROP SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#";
+
+CREATE SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"
+    CYCLE
+    INCREMENT 12
+    START 5
+    MINVALUE 2
+    MAXVALUE 9992
+    CACHE 2;
+
+ALTER SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"
+    OWNER TO postgres;
+
+COMMENT ON SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"
+    IS 'Some comment';
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_props_msql.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_props_msql.sql
new file mode 100644
index 000000000..3ed0c8c1d
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/alter_seq_props_msql.sql
@@ -0,0 +1,8 @@
+SELECT setval('public."Seq1_$%{}[]()&*^!@""''`\/#"', 7, true);
+
+ALTER SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"
+    INCREMENT 12
+    MINVALUE 2
+    MAXVALUE 9992
+    CACHE 2
+    CYCLE;
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/create_negative_sequence.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/create_negative_sequence.sql
new file mode 100644
index 000000000..7cd0881d7
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/create_negative_sequence.sql
@@ -0,0 +1,13 @@
+-- SEQUENCE: public.Seq1_$%{}[]()&*^!@"'`\/#
+
+-- DROP SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#";
+
+CREATE SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"
+    INCREMENT -5
+    START -30
+    MINVALUE -40
+    MAXVALUE -10
+    CACHE 1;
+
+ALTER SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"
+    OWNER TO postgres;
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/create_negative_sequence_msql.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/create_negative_sequence_msql.sql
new file mode 100644
index 000000000..f62613c8f
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/create_negative_sequence_msql.sql
@@ -0,0 +1,9 @@
+CREATE SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"
+    INCREMENT -5
+    START -30
+    MINVALUE -40
+    MAXVALUE -10
+    CACHE 1;
+
+ALTER SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"
+    OWNER TO postgres;
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/create_sequence.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/create_sequence.sql
new file mode 100644
index 000000000..b159ab9d3
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/create_sequence.sql
@@ -0,0 +1,13 @@
+-- SEQUENCE: public.Seq1_$%{}[]()&*^!@"'`\/#
+
+-- DROP SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#";
+
+CREATE SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"
+    INCREMENT 5
+    START 5
+    MINVALUE 5
+    MAXVALUE 999
+    CACHE 1;
+
+ALTER SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"
+    OWNER TO postgres;
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/create_sequence_msql.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/create_sequence_msql.sql
new file mode 100644
index 000000000..67e09cd68
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/create_sequence_msql.sql
@@ -0,0 +1,9 @@
+CREATE SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"
+    INCREMENT 5
+    START 5
+    MINVALUE 5
+    MAXVALUE 999
+    CACHE 1;
+
+ALTER SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"
+    OWNER TO postgres;
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/test_sequences_pg.json b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/test_sequences_pg.json
new file mode 100644
index 000000000..9687cf838
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/pg/default/test_sequences_pg.json
@@ -0,0 +1,173 @@
+{
+  "scenarios": [
+    {
+      "type": "create",
+      "name": "Create Sequence",
+      "endpoint": "NODE-sequence.obj",
+      "sql_endpoint": "NODE-sequence.sql_id",
+      "msql_endpoint": "NODE-sequence.msql",
+      "data": {
+        "name": "Seq1_$%{}[]()&*^!@\"'`\\/#",
+        "seqowner": "postgres",
+        "schema": "public",
+        "increment": "5",
+        "start": "5",
+        "maximum": "999",
+        "minimum": "5",
+        "cache": "1",
+        "cycled": false,
+        "relacl": [],
+        "securities": []
+      },
+      "expected_sql_file": "create_sequence.sql",
+      "expected_msql_file": "create_sequence_msql.sql"
+    },{
+      "type": "alter",
+      "name": "Alter Sequence comment",
+      "endpoint": "NODE-sequence.obj_id",
+      "sql_endpoint": "NODE-sequence.sql_id",
+      "msql_endpoint": "NODE-sequence.msql_id",
+      "data": {
+        "comment": "Some comment"
+      },
+      "expected_sql_file": "alter_seq_comment.sql",
+      "expected_msql_file": "alter_seq_comment_msql.sql"
+    },{
+      "type": "alter",
+      "name": "Alter Sequence properties",
+      "endpoint": "NODE-sequence.obj_id",
+      "sql_endpoint": "NODE-sequence.sql_id",
+      "msql_endpoint": "NODE-sequence.msql_id",
+      "data": {
+        "current_value": "7", "increment": "12", "minimum": "2", "maximum": "9992", "cache": "2", "cycled": true
+      },
+      "expected_sql_file": "alter_seq_props.sql",
+      "expected_msql_file": "alter_seq_props_msql.sql"
+    },{
+      "type": "alter",
+      "name": "Alter Sequence add privileges",
+      "endpoint": "NODE-sequence.obj_id",
+      "sql_endpoint": "NODE-sequence.sql_id",
+      "msql_endpoint": "NODE-sequence.msql_id",
+      "data": {
+        "relacl": {
+          "added":[{
+            "grantee": "PUBLIC",
+            "grantor": "postgres",
+            "privileges":[{
+              "privilege_type": "r",
+              "privilege": true,
+              "with_grant": false
+            },{
+              "privilege_type": "U",
+              "privilege": true,
+              "with_grant": false
+            },{
+              "privilege_type": "w",
+              "privilege": true,
+              "with_grant": false
+            }]
+          }]
+        }
+      },
+      "expected_sql_file": "alter_seq_privs_add.sql",
+      "expected_msql_file": "alter_seq_privs_add_msql.sql"
+    },{
+      "type": "alter",
+      "name": "Alter Sequence update privileges",
+      "endpoint": "NODE-sequence.obj_id",
+      "sql_endpoint": "NODE-sequence.sql_id",
+      "msql_endpoint": "NODE-sequence.msql_id",
+      "data": {
+        "relacl": {
+          "changed":[{
+            "grantee": "PUBLIC",
+            "grantor": "postgres",
+            "privileges":[{
+              "privilege_type": "r",
+              "privilege": true,
+              "with_grant": false
+            }]
+          }]
+        }
+      },
+      "expected_sql_file": "alter_seq_privs_update.sql",
+      "expected_msql_file": "alter_seq_privs_update_msql.sql"
+    },{
+      "type": "alter",
+      "name": "Alter Sequence remove privileges",
+      "endpoint": "NODE-sequence.obj_id",
+      "sql_endpoint": "NODE-sequence.sql_id",
+      "msql_endpoint": "NODE-sequence.msql_id",
+      "data": {
+        "relacl": {
+          "deleted":[{
+            "grantee": "PUBLIC",
+            "grantor": "postgres",
+            "privileges":[{
+              "privilege_type": "r",
+              "privilege": true,
+              "with_grant": false
+            },{
+              "privilege_type": "U",
+              "privilege": true,
+              "with_grant": false
+            },{
+              "privilege_type": "w",
+              "privilege": true,
+              "with_grant": false
+            }]
+          }]
+        }
+      },
+      "expected_sql_file": "alter_seq_privs_remove.sql",
+      "expected_msql_file": "alter_seq_privs_remove_msql.sql"
+    }, {
+      "type": "delete",
+      "name": "Drop sequence",
+      "endpoint": "NODE-sequence.delete_id",
+      "data": {
+        "name": "Seq1_$%{}[]()&*^!@\"'`\\/#"
+      }
+    }, {
+      "type": "create",
+      "name": "Create Sequence with Negative value",
+      "endpoint": "NODE-sequence.obj",
+      "sql_endpoint": "NODE-sequence.sql_id",
+      "msql_endpoint": "NODE-sequence.msql",
+      "data": {
+        "name": "Seq1_$%{}[]()&*^!@\"'`\\/#",
+        "seqowner": "postgres",
+        "schema": "public",
+        "increment": "-5",
+        "start": "-30",
+        "maximum": "-10",
+        "minimum": "-40",
+        "cache": "1",
+        "cycled": false,
+        "relacl": [],
+        "securities": []
+      },
+      "expected_sql_file": "create_negative_sequence.sql",
+      "expected_msql_file": "create_negative_sequence_msql.sql"
+    }, {
+      "type": "alter",
+      "name": "Alter Sequence properties with negative value",
+      "endpoint": "NODE-sequence.obj_id",
+      "sql_endpoint": "NODE-sequence.sql_id",
+      "msql_endpoint": "NODE-sequence.msql_id",
+      "data": {
+        "increment": "-7", "minimum": "-35", "maximum": "-15"
+      },
+      "expected_sql_file": "alter_neg_seq_props.sql",
+      "expected_msql_file": "alter_neg_seq_props_msql.sql"
+    }, {
+      "type": "delete",
+      "name": "Drop negative sequence",
+      "endpoint": "NODE-sequence.delete_id",
+      "data": {
+        "name": "Seq1_$%{}[]()&*^!@\"'`\\/#"
+      }
+    }
+  ]
+}
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_neg_seq_props.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_neg_seq_props.sql
new file mode 100644
index 000000000..01424cf9a
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_neg_seq_props.sql
@@ -0,0 +1,13 @@
+-- SEQUENCE: public.Seq1_$%{}[]()&*^!@"'`\/#
+
+-- DROP SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#";
+
+CREATE SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"
+    INCREMENT -7
+    START -30
+    MINVALUE -35
+    MAXVALUE -15
+    CACHE 1;
+
+ALTER SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"
+    OWNER TO enterprisedb;
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_neg_seq_props_msql.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_neg_seq_props_msql.sql
new file mode 100644
index 000000000..f56eab153
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_neg_seq_props_msql.sql
@@ -0,0 +1,4 @@
+ALTER SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"
+    INCREMENT -7
+    MINVALUE -35
+    MAXVALUE -15;
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_comment.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_comment.sql
new file mode 100644
index 000000000..cc47ed079
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_comment.sql
@@ -0,0 +1,16 @@
+-- SEQUENCE: public.Seq1_$%{}[]()&*^!@"'`\/#
+
+-- DROP SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#";
+
+CREATE SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"
+    INCREMENT 5
+    START 5
+    MINVALUE 5
+    MAXVALUE 999
+    CACHE 1;
+
+ALTER SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"
+    OWNER TO enterprisedb;
+
+COMMENT ON SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"
+    IS 'Some comment';
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_comment_msql.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_comment_msql.sql
new file mode 100644
index 000000000..7a5efbd92
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_comment_msql.sql
@@ -0,0 +1,2 @@
+COMMENT ON SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"
+    IS 'Some comment';
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_privs_add.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_privs_add.sql
new file mode 100644
index 000000000..457f48101
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_privs_add.sql
@@ -0,0 +1,21 @@
+-- SEQUENCE: public.Seq1_$%{}[]()&*^!@"'`\/#
+
+-- DROP SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#";
+
+CREATE SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"
+    CYCLE
+    INCREMENT 12
+    START 5
+    MINVALUE 2
+    MAXVALUE 9992
+    CACHE 2;
+
+ALTER SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"
+    OWNER TO enterprisedb;
+
+COMMENT ON SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"
+    IS 'Some comment';
+
+GRANT ALL ON SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" TO PUBLIC;
+
+GRANT ALL ON SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" TO enterprisedb;
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_privs_add_msql.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_privs_add_msql.sql
new file mode 100644
index 000000000..66d9aa002
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_privs_add_msql.sql
@@ -0,0 +1 @@
+GRANT ALL ON SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" TO PUBLIC;
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_privs_remove.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_privs_remove.sql
new file mode 100644
index 000000000..ac21e667f
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_privs_remove.sql
@@ -0,0 +1,19 @@
+-- SEQUENCE: public.Seq1_$%{}[]()&*^!@"'`\/#
+
+-- DROP SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#";
+
+CREATE SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"
+    CYCLE
+    INCREMENT 12
+    START 5
+    MINVALUE 2
+    MAXVALUE 9992
+    CACHE 2;
+
+ALTER SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"
+    OWNER TO enterprisedb;
+
+COMMENT ON SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"
+    IS 'Some comment';
+
+GRANT ALL ON SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" TO enterprisedb;
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_privs_remove_msql.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_privs_remove_msql.sql
new file mode 100644
index 000000000..e8b94bad8
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_privs_remove_msql.sql
@@ -0,0 +1 @@
+REVOKE ALL ON SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" FROM PUBLIC;
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_privs_update.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_privs_update.sql
new file mode 100644
index 000000000..fea961543
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_privs_update.sql
@@ -0,0 +1,21 @@
+-- SEQUENCE: public.Seq1_$%{}[]()&*^!@"'`\/#
+
+-- DROP SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#";
+
+CREATE SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"
+    CYCLE
+    INCREMENT 12
+    START 5
+    MINVALUE 2
+    MAXVALUE 9992
+    CACHE 2;
+
+ALTER SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"
+    OWNER TO enterprisedb;
+
+COMMENT ON SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"
+    IS 'Some comment';
+
+GRANT SELECT ON SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" TO PUBLIC;
+
+GRANT ALL ON SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" TO enterprisedb;
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_privs_update_msql.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_privs_update_msql.sql
new file mode 100644
index 000000000..c3c2a5b9a
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_privs_update_msql.sql
@@ -0,0 +1,2 @@
+REVOKE ALL ON SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" FROM PUBLIC;
+GRANT SELECT ON SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#" TO PUBLIC;
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_props.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_props.sql
new file mode 100644
index 000000000..bc59956a6
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_props.sql
@@ -0,0 +1,17 @@
+-- SEQUENCE: public.Seq1_$%{}[]()&*^!@"'`\/#
+
+-- DROP SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#";
+
+CREATE SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"
+    CYCLE
+    INCREMENT 12
+    START 5
+    MINVALUE 2
+    MAXVALUE 9992
+    CACHE 2;
+
+ALTER SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"
+    OWNER TO enterprisedb;
+
+COMMENT ON SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"
+    IS 'Some comment';
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_props_msql.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_props_msql.sql
new file mode 100644
index 000000000..3ed0c8c1d
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/alter_seq_props_msql.sql
@@ -0,0 +1,8 @@
+SELECT setval('public."Seq1_$%{}[]()&*^!@""''`\/#"', 7, true);
+
+ALTER SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"
+    INCREMENT 12
+    MINVALUE 2
+    MAXVALUE 9992
+    CACHE 2
+    CYCLE;
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/create_negative_sequence.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/create_negative_sequence.sql
new file mode 100644
index 000000000..6ad4989c5
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/create_negative_sequence.sql
@@ -0,0 +1,13 @@
+-- SEQUENCE: public.Seq1_$%{}[]()&*^!@"'`\/#
+
+-- DROP SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#";
+
+CREATE SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"
+    INCREMENT -5
+    START -30
+    MINVALUE -40
+    MAXVALUE -10
+    CACHE 1;
+
+ALTER SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"
+    OWNER TO enterprisedb;
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/create_negative_sequence_msql.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/create_negative_sequence_msql.sql
new file mode 100644
index 000000000..64e75266f
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/create_negative_sequence_msql.sql
@@ -0,0 +1,9 @@
+CREATE SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"
+    INCREMENT -5
+    START -30
+    MINVALUE -40
+    MAXVALUE -10
+    CACHE 1;
+
+ALTER SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"
+    OWNER TO enterprisedb;
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/create_sequence.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/create_sequence.sql
new file mode 100644
index 000000000..611226a14
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/create_sequence.sql
@@ -0,0 +1,13 @@
+-- SEQUENCE: public.Seq1_$%{}[]()&*^!@"'`\/#
+
+-- DROP SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#";
+
+CREATE SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"
+    INCREMENT 5
+    START 5
+    MINVALUE 5
+    MAXVALUE 999
+    CACHE 1;
+
+ALTER SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"
+    OWNER TO enterprisedb;
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/create_sequence_msql.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/create_sequence_msql.sql
new file mode 100644
index 000000000..f926dbec2
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/create_sequence_msql.sql
@@ -0,0 +1,9 @@
+CREATE SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"
+    INCREMENT 5
+    START 5
+    MINVALUE 5
+    MAXVALUE 999
+    CACHE 1;
+
+ALTER SEQUENCE public."Seq1_$%{}[]()&*^!@""'`\/#"
+    OWNER TO enterprisedb;
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/test_sequences_ppas.json b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/test_sequences_ppas.json
new file mode 100644
index 000000000..1639aac04
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/ppas/default/test_sequences_ppas.json
@@ -0,0 +1,173 @@
+{
+  "scenarios": [
+    {
+      "type": "create",
+      "name": "Create Sequence",
+      "endpoint": "NODE-sequence.obj",
+      "sql_endpoint": "NODE-sequence.sql_id",
+      "msql_endpoint": "NODE-sequence.msql",
+      "data": {
+        "name": "Seq1_$%{}[]()&*^!@\"'`\\/#",
+        "seqowner": "enterprisedb",
+        "schema": "public",
+        "increment": "5",
+        "start": "5",
+        "maximum": "999",
+        "minimum": "5",
+        "cache": "1",
+        "cycled": false,
+        "relacl": [],
+        "securities": []
+      },
+      "expected_sql_file": "create_sequence.sql",
+      "expected_msql_file": "create_sequence_msql.sql"
+    },{
+      "type": "alter",
+      "name": "Alter Sequence comment",
+      "endpoint": "NODE-sequence.obj_id",
+      "sql_endpoint": "NODE-sequence.sql_id",
+      "msql_endpoint": "NODE-sequence.msql_id",
+      "data": {
+        "comment": "Some comment"
+      },
+      "expected_sql_file": "alter_seq_comment.sql",
+      "expected_msql_file": "alter_seq_comment_msql.sql"
+    },{
+      "type": "alter",
+      "name": "Alter Sequence properties",
+      "endpoint": "NODE-sequence.obj_id",
+      "sql_endpoint": "NODE-sequence.sql_id",
+      "msql_endpoint": "NODE-sequence.msql_id",
+      "data": {
+        "current_value": "7", "increment": "12", "minimum": "2", "maximum": "9992", "cache": "2", "cycled": true
+      },
+      "expected_sql_file": "alter_seq_props.sql",
+      "expected_msql_file": "alter_seq_props_msql.sql"
+    },{
+      "type": "alter",
+      "name": "Alter Sequence add privileges",
+      "endpoint": "NODE-sequence.obj_id",
+      "sql_endpoint": "NODE-sequence.sql_id",
+      "msql_endpoint": "NODE-sequence.msql_id",
+      "data": {
+        "relacl": {
+          "added":[{
+            "grantee": "PUBLIC",
+            "grantor": "enterprisedb",
+            "privileges":[{
+              "privilege_type": "r",
+              "privilege": true,
+              "with_grant": false
+            },{
+              "privilege_type": "U",
+              "privilege": true,
+              "with_grant": false
+            },{
+              "privilege_type": "w",
+              "privilege": true,
+              "with_grant": false
+            }]
+          }]
+        }
+      },
+      "expected_sql_file": "alter_seq_privs_add.sql",
+      "expected_msql_file": "alter_seq_privs_add_msql.sql"
+    },{
+      "type": "alter",
+      "name": "Alter Sequence update privileges",
+      "endpoint": "NODE-sequence.obj_id",
+      "sql_endpoint": "NODE-sequence.sql_id",
+      "msql_endpoint": "NODE-sequence.msql_id",
+      "data": {
+        "relacl": {
+          "changed":[{
+            "grantee": "PUBLIC",
+            "grantor": "enterprisedb",
+            "privileges":[{
+              "privilege_type": "r",
+              "privilege": true,
+              "with_grant": false
+            }]
+          }]
+        }
+      },
+      "expected_sql_file": "alter_seq_privs_update.sql",
+      "expected_msql_file": "alter_seq_privs_update_msql.sql"
+    },{
+      "type": "alter",
+      "name": "Alter Sequence remove privileges",
+      "endpoint": "NODE-sequence.obj_id",
+      "sql_endpoint": "NODE-sequence.sql_id",
+      "msql_endpoint": "NODE-sequence.msql_id",
+      "data": {
+        "relacl": {
+          "deleted":[{
+            "grantee": "PUBLIC",
+            "grantor": "enterprisedb",
+            "privileges":[{
+              "privilege_type": "r",
+              "privilege": true,
+              "with_grant": false
+            },{
+              "privilege_type": "U",
+              "privilege": true,
+              "with_grant": false
+            },{
+              "privilege_type": "w",
+              "privilege": true,
+              "with_grant": false
+            }]
+          }]
+        }
+      },
+      "expected_sql_file": "alter_seq_privs_remove.sql",
+      "expected_msql_file": "alter_seq_privs_remove_msql.sql"
+    }, {
+      "type": "delete",
+      "name": "Drop sequence",
+      "endpoint": "NODE-sequence.delete_id",
+      "data": {
+        "name": "Seq1_$%{}[]()&*^!@\"'`\\/#"
+      }
+    }, {
+      "type": "create",
+      "name": "Create Sequence with Negative value",
+      "endpoint": "NODE-sequence.obj",
+      "sql_endpoint": "NODE-sequence.sql_id",
+      "msql_endpoint": "NODE-sequence.msql",
+      "data": {
+        "name": "Seq1_$%{}[]()&*^!@\"'`\\/#",
+        "seqowner": "enterprisedb",
+        "schema": "public",
+        "increment": "-5",
+        "start": "-30",
+        "maximum": "-10",
+        "minimum": "-40",
+        "cache": "1",
+        "cycled": false,
+        "relacl": [],
+        "securities": []
+      },
+      "expected_sql_file": "create_negative_sequence.sql",
+      "expected_msql_file": "create_negative_sequence_msql.sql"
+    }, {
+      "type": "alter",
+      "name": "Alter Sequence properties with negative value",
+      "endpoint": "NODE-sequence.obj_id",
+      "sql_endpoint": "NODE-sequence.sql_id",
+      "msql_endpoint": "NODE-sequence.msql_id",
+      "data": {
+        "increment": "-7", "minimum": "-35", "maximum": "-15"
+      },
+      "expected_sql_file": "alter_neg_seq_props.sql",
+      "expected_msql_file": "alter_neg_seq_props_msql.sql"
+    }, {
+      "type": "delete",
+      "name": "Drop negative sequence",
+      "endpoint": "NODE-sequence.delete_id",
+      "data": {
+        "name": "Seq1_$%{}[]()&*^!@\"'`\\/#"
+      }
+    }
+  ]
+}
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/test_sequence_add.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/test_sequence_add.py
new file mode 100644
index 000000000..7c1e8aaac
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/test_sequence_add.py
@@ -0,0 +1,126 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2020, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+import json
+import uuid
+
+from pgadmin.browser.server_groups.servers.databases.schemas.tests import \
+    utils as schema_utils
+from pgadmin.browser.server_groups.servers.databases.tests import utils as \
+    database_utils
+from pgadmin.utils.route import BaseTestGenerator
+from regression import parent_node_dict
+from regression.python_test_utils import test_utils as utils
+
+
+class SequenceAddTestCase(BaseTestGenerator):
+    """ This class will add new sequence(s) under schema node. """
+    skip_on_database = ['gpdb']
+    scenarios = [
+        # Fetching default URL for sequence node.
+        (
+            'Create sequence with positive values',
+            dict(
+                url='/browser/sequence/obj/',
+                # Valid optional data
+                data={
+                    "cache": "1",
+                    "cycled": True,
+                    "increment": "1",
+                    "maximum": "100000",
+                    "minimum": "1",
+                    "name": "test_sequence_add_%s" % (str(uuid.uuid4())[1:8]),
+                    "securities": [],
+                    "start": "100"
+                }
+            )
+        ),
+        (
+            'Create sequence with negative values',
+            dict(
+                url='/browser/sequence/obj/',
+                # Valid optional data
+                data={
+                    "cache": "1",
+                    "cycled": True,
+                    "increment": "-5",
+                    "maximum": "-10",
+                    "minimum": "-40",
+                    "name": "test_sequence_add_%s" % (str(uuid.uuid4())[1:8]),
+                    "securities": [],
+                    "start": "-30"
+                }
+            )
+        )
+    ]
+
+    def setUp(self):
+        super(SequenceAddTestCase, self).setUp()
+
+    def runTest(self):
+        """This function will add sequence(s) under schema node."""
+        db_name = parent_node_dict["database"][-1]["db_name"]
+        schema_info = parent_node_dict["schema"][-1]
+        self.server_id = schema_info["server_id"]
+        self.db_id = schema_info["db_id"]
+        db_con = database_utils.connect_database(self, utils.SERVER_GROUP,
+                                                 self.server_id, self.db_id)
+        if not db_con['data']["connected"]:
+            raise Exception("Could not connect to database to add sequence.")
+        schema_id = schema_info["schema_id"]
+        schema_name = schema_info["schema_name"]
+        schema_response = schema_utils.verify_schemas(self.server,
+                                                      db_name,
+                                                      schema_name)
+        if not schema_response:
+            raise Exception("Could not find the schema to add sequence.")
+        db_user = self.server["username"]
+
+        common_data = {
+            "relacl": [
+                {
+                    "grantee": db_user,
+                    "grantor": db_user,
+                    "privileges":
+                        [
+                            {
+                                "privilege_type": "r",
+                                "privilege": True,
+                                "with_grant": True
+                            },
+                            {
+                                "privilege_type": "w",
+                                "privilege": True,
+                                "with_grant": False
+                            },
+                            {
+                                "privilege_type": "U",
+                                "privilege": True,
+                                "with_grant": False
+                            }
+                        ]
+                }
+            ],
+            "schema": schema_name,
+            "seqowner": db_user,
+        }
+
+        self.data.update(common_data)
+
+        response = self.tester.post(
+            self.url + str(utils.SERVER_GROUP) + '/' +
+            str(self.server_id) + '/' + str(self.db_id) +
+            '/' + str(schema_id) + '/',
+            data=json.dumps(self.data),
+            content_type='html/json')
+        self.assertEquals(response.status_code, 200)
+
+    def tearDown(self):
+        # Disconnect the database
+        database_utils.disconnect_database(self, self.server_id, self.db_id)
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/test_sequence_delete.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/test_sequence_delete.py
new file mode 100644
index 000000000..294bc4d63
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/test_sequence_delete.py
@@ -0,0 +1,69 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2020, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+import uuid
+
+from pgadmin.browser.server_groups.servers.databases.schemas.tests import \
+    utils as schema_utils
+from pgadmin.browser.server_groups.servers.databases.tests import utils as \
+    database_utils
+from pgadmin.utils.route import BaseTestGenerator
+from regression import parent_node_dict
+from regression.python_test_utils import test_utils as utils
+from . import utils as sequence_utils
+
+
+class SequenceDeleteTestCase(BaseTestGenerator):
+    """This class will delete added sequence under schema node."""
+    skip_on_database = ['gpdb']
+    scenarios = [
+        # Fetching default URL for sequence node.
+        ('Fetch sequence Node URL', dict(url='/browser/sequence/obj/'))
+    ]
+
+    def setUp(self):
+        super(SequenceDeleteTestCase, self).setUp()
+        self.db_name = parent_node_dict["database"][-1]["db_name"]
+        schema_info = parent_node_dict["schema"][-1]
+        self.server_id = schema_info["server_id"]
+        self.db_id = schema_info["db_id"]
+        db_con = database_utils.connect_database(self, utils.SERVER_GROUP,
+                                                 self.server_id, self.db_id)
+        if not db_con['data']["connected"]:
+            raise Exception("Could not connect to database to add sequence.")
+        self.schema_id = schema_info["schema_id"]
+        self.schema_name = schema_info["schema_name"]
+        schema_response = schema_utils.verify_schemas(self.server,
+                                                      self.db_name,
+                                                      self.schema_name)
+        if not schema_response:
+            raise Exception("Could not find the schema to add sequence.")
+        self.sequence_name = "test_sequence_delete_%s" % str(uuid.uuid4())[1:8]
+        self.sequence_id = sequence_utils.create_sequences(
+            self.server, self.db_name, self.schema_name, self.sequence_name)
+
+    def runTest(self):
+        """ This function will delete added sequence under schema node. """
+        sequence_response = sequence_utils.verify_sequence(self.server,
+                                                           self.db_name,
+                                                           self.sequence_name)
+        if not sequence_response:
+            raise Exception("Could not find the sequence to delete.")
+        response = self.tester.delete(
+            self.url + str(utils.SERVER_GROUP) + '/' +
+            str(self.server_id) + '/' +
+            str(self.db_id) + '/' +
+            str(self.schema_id) + '/' +
+            str(self.sequence_id),
+            follow_redirects=True)
+        self.assertEquals(response.status_code, 200)
+
+    def tearDown(self):
+        # Disconnect the database
+        database_utils.disconnect_database(self, self.server_id, self.db_id)
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/test_sequence_delete_multiple.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/test_sequence_delete_multiple.py
new file mode 100644
index 000000000..f5cadd8d5
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/test_sequence_delete_multiple.py
@@ -0,0 +1,93 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2020, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+import uuid
+import json
+
+from pgadmin.browser.server_groups.servers.databases.schemas.tests import \
+    utils as schema_utils
+from pgadmin.browser.server_groups.servers.databases.tests import utils as \
+    database_utils
+from pgadmin.utils.route import BaseTestGenerator
+from regression import parent_node_dict
+from regression.python_test_utils import test_utils as utils
+from . import utils as sequence_utils
+
+
+class SequenceDeleteMultipleTestCase(BaseTestGenerator):
+    """This class will delete added sequence under schema node."""
+    skip_on_database = ['gpdb']
+    scenarios = [
+        # Fetching default URL for sequence node.
+        ('Fetch sequence Node URL', dict(url='/browser/sequence/obj/'))
+    ]
+
+    def setUp(self):
+        super(SequenceDeleteMultipleTestCase, self).setUp()
+        self.db_name = parent_node_dict["database"][-1]["db_name"]
+        schema_info = parent_node_dict["schema"][-1]
+        self.server_id = schema_info["server_id"]
+        self.db_id = schema_info["db_id"]
+        db_con = database_utils.connect_database(self, utils.SERVER_GROUP,
+                                                 self.server_id, self.db_id)
+        if not db_con['data']["connected"]:
+            raise Exception("Could not connect to database to add sequence.")
+        self.schema_id = schema_info["schema_id"]
+        self.schema_name = schema_info["schema_name"]
+        schema_response = schema_utils.verify_schemas(self.server,
+                                                      self.db_name,
+                                                      self.schema_name)
+        if not schema_response:
+            raise Exception("Could not find the schema to add sequence.")
+        self.sequence_name = "test_sequence_delete_%s" % str(uuid.uuid4())[1:8]
+        self.sequence_name_1 = "test_sequence_delete_%s" %\
+                               str(uuid.uuid4())[1:8]
+
+        self.sequence_ids = [sequence_utils.create_sequences(
+            self.server,
+            self.db_name,
+            self.schema_name,
+            self.sequence_name),
+            sequence_utils.create_sequences(
+                self.server,
+                self.db_name,
+                self.schema_name,
+                self.sequence_name_1)
+        ]
+
+    def runTest(self):
+        """ This function will delete added sequence under schema node. """
+        sequence_response = sequence_utils.verify_sequence(self.server,
+                                                           self.db_name,
+                                                           self.sequence_name)
+        if not sequence_response:
+            raise Exception("Could not find the sequence to delete.")
+
+        sequence_response = sequence_utils.verify_sequence(self.server,
+                                                           self.db_name,
+                                                           self.sequence_name_1
+                                                           )
+        if not sequence_response:
+            raise Exception("Could not find the sequence to delete.")
+
+        data = json.dumps({'ids': self.sequence_ids})
+        response = self.tester.delete(
+            self.url + str(utils.SERVER_GROUP) + '/' +
+            str(self.server_id) + '/' +
+            str(self.db_id) + '/' +
+            str(self.schema_id) + '/',
+            follow_redirects=True,
+            data=data,
+            content_type='html/json'
+        )
+        self.assertEquals(response.status_code, 200)
+
+    def tearDown(self):
+        # Disconnect the database
+        database_utils.disconnect_database(self, self.server_id, self.db_id)
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/test_sequence_get.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/test_sequence_get.py
new file mode 100644
index 000000000..9120a8900
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/test_sequence_get.py
@@ -0,0 +1,64 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2020, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+import uuid
+
+from pgadmin.browser.server_groups.servers.databases.schemas.tests import \
+    utils as schema_utils
+from pgadmin.browser.server_groups.servers.databases.tests import utils as \
+    database_utils
+from pgadmin.utils.route import BaseTestGenerator
+from regression import parent_node_dict
+from regression.python_test_utils import test_utils as utils
+from . import utils as sequence_utils
+
+
+class SequenceGetTestCase(BaseTestGenerator):
+    """This class will fetch added sequence under schema node."""
+    skip_on_database = ['gpdb']
+    scenarios = [
+        # Fetching default URL for sequence node.
+        ('Fetch sequence Node URL', dict(url='/browser/sequence/obj/'))
+    ]
+
+    def setUp(self):
+        super(SequenceGetTestCase, self).setUp()
+        self.db_name = parent_node_dict["database"][-1]["db_name"]
+        schema_info = parent_node_dict["schema"][-1]
+        self.server_id = schema_info["server_id"]
+        self.db_id = schema_info["db_id"]
+        db_con = database_utils.connect_database(self, utils.SERVER_GROUP,
+                                                 self.server_id, self.db_id)
+        if not db_con['data']["connected"]:
+            raise Exception("Could not connect to database to add sequence.")
+        self.schema_id = schema_info["schema_id"]
+        self.schema_name = schema_info["schema_name"]
+        schema_response = schema_utils.verify_schemas(self.server,
+                                                      self.db_name,
+                                                      self.schema_name)
+        if not schema_response:
+            raise Exception("Could not find the schema to add sequence.")
+        self.sequence_name = "test_sequence_delete_%s" % str(uuid.uuid4())[1:8]
+        self.sequence_id = sequence_utils.create_sequences(
+            self.server, self.db_name, self.schema_name, self.sequence_name)
+
+    def runTest(self):
+        """This function will fetch added sequence under schema node."""
+        response = self.tester.get(
+            self.url + str(utils.SERVER_GROUP) + '/' +
+            str(self.server_id) + '/' +
+            str(self.db_id) + '/' +
+            str(self.schema_id) + '/' +
+            str(self.sequence_id),
+            follow_redirects=True)
+        self.assertEquals(response.status_code, 200)
+
+    def tearDown(self):
+        # Disconnect the database
+        database_utils.disconnect_database(self, self.server_id, self.db_id)
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/test_sequence_put.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/test_sequence_put.py
new file mode 100644
index 000000000..1eeedd106
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/test_sequence_put.py
@@ -0,0 +1,98 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2020, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+import json
+import uuid
+
+from pgadmin.browser.server_groups.servers.databases.schemas.tests import \
+    utils as schema_utils
+from pgadmin.browser.server_groups.servers.databases.tests import utils as \
+    database_utils
+from pgadmin.utils.route import BaseTestGenerator
+from regression import parent_node_dict
+from regression.python_test_utils import test_utils as utils
+from . import utils as sequence_utils
+
+
+class SequencePutTestCase(BaseTestGenerator):
+    """This class will update added sequence under schema node."""
+    skip_on_database = ['gpdb']
+    scenarios = [
+        # Fetching default URL for sequence node.
+        ('Alter positive sequence comment, increment, max and min value',
+         dict(
+             url='/browser/sequence/obj/',
+             data={
+                 "comment": "This is sequence update comment",
+                 "increment": "5",
+                 "maximum": "1000",
+                 "minimum": "10",
+             },
+             positive_seq=True
+         )),
+        ('Alter negative sequence comment, increment, max and min value',
+         dict(
+             url='/browser/sequence/obj/',
+             data={
+                 "comment": "This is sequence update comment",
+                 "increment": "-7",
+                 "maximum": "-15",
+                 "minimum": "-35",
+             },
+             positive_seq=False
+         ))
+    ]
+
+    def setUp(self):
+        super(SequencePutTestCase, self).setUp()
+        self.db_name = parent_node_dict["database"][-1]["db_name"]
+        schema_info = parent_node_dict["schema"][-1]
+        self.server_id = schema_info["server_id"]
+        self.db_id = schema_info["db_id"]
+        db_con = database_utils.connect_database(self, utils.SERVER_GROUP,
+                                                 self.server_id, self.db_id)
+        if not db_con['data']["connected"]:
+            raise Exception("Could not connect to database to add sequence.")
+        self.schema_id = schema_info["schema_id"]
+        self.schema_name = schema_info["schema_name"]
+        schema_response = schema_utils.verify_schemas(self.server,
+                                                      self.db_name,
+                                                      self.schema_name)
+        if not schema_response:
+            raise Exception("Could not find the schema to add sequence.")
+        self.sequence_name = "test_sequence_delete_%s" % str(uuid.uuid4())[1:8]
+        self.sequence_id = sequence_utils.create_sequences(
+            self.server, self.db_name, self.schema_name, self.sequence_name,
+            self.positive_seq
+        )
+
+    def runTest(self):
+        """This function will update added sequence under schema node."""
+        sequence_response = sequence_utils.verify_sequence(self.server,
+                                                           self.db_name,
+                                                           self.sequence_name)
+        if not sequence_response:
+            raise Exception("Could not find the sequence to delete.")
+
+        # Add sequence id.
+        self.data["id"] = self.sequence_id
+
+        response = self.tester.put(
+            self.url + str(utils.SERVER_GROUP) + '/' +
+            str(self.server_id) + '/' +
+            str(self.db_id) + '/' +
+            str(self.schema_id) + '/' +
+            str(self.sequence_id),
+            data=json.dumps(self.data),
+            follow_redirects=True)
+        self.assertEquals(response.status_code, 200)
+
+    def tearDown(self):
+        # Disconnect the database
+        database_utils.disconnect_database(self, self.server_id, self.db_id)
diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/utils.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/utils.py
new file mode 100644
index 000000000..d47688026
--- /dev/null
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foos/tests/utils.py
@@ -0,0 +1,89 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2020, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+
+import sys
+import traceback
+
+from regression.python_test_utils import test_utils as utils
+
+
+def create_sequences(server, db_name, schema_name, sequence_name,
+                     positive_seq=True):
+    """
+    This function used to create sequence in schema provided.
+    :param server: server details
+    :type server: dict
+    :param db_name: database name
+    :type db_name: str
+    :param schema_name: schema name
+    :type schema_name: str
+    :param sequence_name: sequence name
+    :type sequence_name: str
+    :param positive_seq: True is sequence will be created using positive values
+    :type positive_seq: boolean
+    :return sequence_id: sequence id
+    :rtype: int
+    """
+    try:
+        connection = utils.get_db_connection(db_name,
+                                             server['username'],
+                                             server['db_password'],
+                                             server['host'],
+                                             server['port'],
+                                             server['sslmode'])
+        pg_cursor = connection.cursor()
+
+        query = "CREATE SEQUENCE %s.%s INCREMENT 5 START 30 " \
+                "MINVALUE 10 MAXVALUE 100" % (schema_name, sequence_name)
+        if not positive_seq:
+            query = "CREATE SEQUENCE %s.%s INCREMENT -5 START -30 " \
+                    "MINVALUE -40 MAXVALUE -10" % (schema_name, sequence_name)
+        pg_cursor.execute(query)
+        connection.commit()
+        # Get 'oid' from newly created sequence
+        pg_cursor.execute("select oid from pg_class where relname='%s'" %
+                          sequence_name)
+        sequence = pg_cursor.fetchone()
+        sequence_id = ''
+        if sequence:
+            sequence_id = sequence[0]
+        connection.close()
+        return sequence_id
+    except Exception:
+        traceback.print_exc(file=sys.stderr)
+
+
+def verify_sequence(server, db_name, sequence_name):
+    """
+    This function verifies the sequence in database
+    :param server: server details
+    :type server: dict
+    :param db_name: database name
+    :type db_name: str
+    :param sequence_name: sequence name
+    :type sequence_name: str
+    :return sequence: sequence record from database
+    :rtype: tuple
+    """
+    try:
+        connection = utils.get_db_connection(db_name,
+                                             server['username'],
+                                             server['db_password'],
+                                             server['host'],
+                                             server['port'],
+                                             server['sslmode'])
+        pg_cursor = connection.cursor()
+        pg_cursor.execute("select * from pg_class where relname='%s'" %
+                          sequence_name)
+        sequence = pg_cursor.fetchone()
+        connection.close()
+        return sequence
+    except Exception:
+        traceback.print_exc(file=sys.stderr)
diff --git a/web/webpack.config.js b/web/webpack.config.js
index 18ec4a65f..885fd64d3 100644
--- a/web/webpack.config.js
+++ b/web/webpack.config.js
@@ -449,6 +449,7 @@ module.exports = [{
         ',pgadmin.node.catalog_object' +
         ',pgadmin.node.collation' +
         ',pgadmin.node.domain' +
+        ',pgadmin.node.foo' +
         ',pgadmin.node.domain_constraints' +
         ',pgadmin.node.foreign_table' +
         ',pgadmin.node.fts_configuration' +
diff --git a/web/webpack.shim.js b/web/webpack.shim.js
index da19b6897..7b51de4cf 100644
--- a/web/webpack.shim.js
+++ b/web/webpack.shim.js
@@ -220,6 +220,7 @@ var webpackShimConfig = {
     'pgadmin.node.exclusion_constraint': path.join(__dirname, './pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/exclusion_constraint/static/js/exclusion_constraint'),
     'pgadmin.node.extension': path.join(__dirname, './pgadmin/browser/server_groups/servers/databases/extensions/static/js/extension'),
     'pgadmin.node.external_table': path.join(__dirname, './pgadmin/static/js/browser/server_groups/servers/databases/external_tables/index'),
+    'pgadmin.node.foo': path.join(__dirname, './pgadmin/browser/server_groups/servers/databases/schemas/foos/static/js/foo'),
     'pgadmin.node.foreign_data_wrapper': path.join(__dirname, './pgadmin/browser/server_groups/servers/databases/foreign_data_wrappers/static/js/foreign_data_wrapper'),
     'pgadmin.node.foreign_key': path.join(__dirname, './pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/foreign_key/static/js/foreign_key'),
     'pgadmin.node.foreign_server': path.join(__dirname, './pgadmin/browser/server_groups/servers/databases/foreign_data_wrappers/foreign_servers/static/js/foreign_server'),
-- 
2.22.0.windows.1

