import re
import sys
import yaml
from collections import defaultdict

"""
@brief Wrapper function for ____run_sql_query
"""
def run_sql(sql, portid, con_args):
    from madpack import ____run_sql_query
    return ____run_sql_query(sql, True, portid, con_args)

"""
@brief Get the signature of a UDF/UDA for comparison
"""
def get_signature_for_compare(schema, proname, rettype, argument):
    signature = '%s %s.%s(%s)' % (
        rettype.strip(), schema.strip(), proname.strip(), argument.strip())
    signature = re.sub('\s+', ' ', signature)
    signature = re.sub('"', '', signature)
    return signature.lower()

"""
@brief Base class for handling the upgrade
"""
class UpgradeBase:
    def __init__(self, schema, portid, con_args):
        self._schema = schema.lower()
        self._portid = portid
        self._con_args = con_args
        self._schema_oid = None
        self._get_schema_oid()

    """
    @brief Wrapper function for run_sql
    """
    def _run_sql(self, sql):
        return run_sql(sql, self._portid, self._con_args)

    """
    @brief Get the oids of some objects from the catalog in the current version
    """
    def _get_schema_oid(self):
        self._schema_oid = self._run_sql("""
            SELECT oid FROM pg_namespace WHERE nspname = '{schema}'
            """.format(schema=self._schema))[0]['oid']


    """
    @brief Get the function name, return type, and arguments given an oid
    @note The function can only handle the case that proallargtypes is null,
    refer to pg_catalog.pg_get_function_identity_argument and
    pg_catalog.pg_get_function_result in PG for a complete implementation, which are
    not supported by GP
    """
    def _get_function_info(self, oid):
        row = self._run_sql("""
            SELECT
                max(proname) AS proname,
                max(rettype) AS rettype,
                array_to_string(
                    array_agg(argname || ' ' || argtype order by i), ',') AS argument
            FROM
            (
                SELECT
                    proname,
                    textin(regtypeout(prorettype::regtype)) AS rettype,
                    CASE array_upper(proargtypes,1) WHEN -1 THEN ''
                        ELSE textin(regtypeout(unnest(proargtypes)::regtype))
                    END AS argtype,
                    CASE WHEN proargnames IS NULL THEN ''
                        ELSE unnest(proargnames)
                    END AS argname,
                    CASE array_upper(proargtypes,1) WHEN -1 THEN 1
                        ELSE generate_series(0, array_upper(proargtypes, 1))
                    END AS i
                FROM
                    pg_proc AS p
                WHERE
                    oid = {oid}
            ) AS f
            """.format(oid=oid))
        return {"proname": row[0]['proname'], 'rettype': row[0]['rettype'],
            'argument': row[0]['argument']}

"""
@brief This class reads changes from the configuration file and handles
the dropping of objects
"""
class ChangeHandler(UpgradeBase):
    def __init__(self, schema, portid, con_args, maddir, mad_dbrev):
        UpgradeBase.__init__(self, schema, portid, con_args)
        self._opr_ind_svec = None
        self._get_opr_indepent_svec()
        self._maddir = maddir
        self._mad_dbrev = mad_dbrev
        self._newmodule = None
        self._udt = None
        self._udf = None
        self._uda = None
        self._udc = None
        self._load()


    """
    @brief Get the UDOps which are independent of svec in the current version
    """
    def _get_opr_indepent_svec(self):
        rows = self._run_sql("""
            SELECT
                oprname,
                tl.typname AS typ_left,
                nspl.nspname AS nsp_left,
                tr.typname AS typ_right,
                nspr.nspname AS nsp_right
            FROM
                pg_operator AS o,
                pg_type AS tl,
                pg_type AS tr,
                pg_namespace AS nspl,
                pg_namespace AS nspr
            WHERE
                oprnamespace = {schema_oid} AND
                (
                    oprleft <> '{schema_madlib}.svec'::regtype AND
                    oprright <> '{schema_madlib}.svec'::regtype AND
                    oprleft = tl.oid AND
                    oprright = tr.oid AND
                    tl.typnamespace = nspl.oid AND
                    tr.typnamespace = nspr.oid
                )
            """.format(schema_madlib=self._schema, schema_oid=self._schema_oid))
        self._opr_ind_svec = {}
        for row in rows:
            self._opr_ind_svec[row['oprname']] = row

    """
    @brief Load the configuration file
    """
    def _load(self):
        if float(self._mad_dbrev) < 0.6:
            filename = self._maddir + '/madpack/changelist_v0.5.yaml'
        else:
            filename = self._maddir + '/madpack/changelist.yaml'
        config = yaml.load(open(filename))

        self._newmodule = config['new module']
        if self._newmodule is None:
            self._newmodule = {}

        self._udt = config['udt']
        if self._udt is None:
            self._udt = {}

        self._udc = config['udc']
        if self._udc is None:
            self._udc = {}

        self._udf = defaultdict(list)
        items = config['udf']
        if items is not None:
            for item in items:
                for udf in item:
                    rettype = item[udf]['rettype'].lower().replace(
                        'schema_madlib', self._schema)
                    argument = ''
                    if item[udf]['argument'] is not None:
                        argument = item[udf]['argument'].lower().replace(
                            'schema_madlib', self._schema)
                    self._udf[udf].append(
                        {'rettype': rettype, 'argument': argument})

        self._uda = defaultdict(list)
        items = config['uda']
        if items is not None:
            for item in items:
                for uda in item:
                    rettype = item[uda]['rettype'].lower().replace(
                        'schema_madlib', self._schema)
                    argument = ''
                    if item[uda]['argument'] is not None:
                        argument = item[uda]['argument'].lower().replace(
                            'schema_madlib', self._schema)
                    self._uda[uda].append(
                        {'rettype': rettype, 'argument': argument})

    """
    @brief Get the list of new modules
    """
    def get_newmodule(self):
        return self._newmodule

    """
    @brief Get the list of changed UDTs
    """
    def get_udt(self):
        return self._udt

    """
    @brief Get the list of changed UDAs
    """
    def get_uda(self):
        return self._uda

    """
    @brief Get the list of changed UDCs
    @note This is a UDC in utilities module
    """
    def get_udc(self):
        return self._udc

    """
    @brief Get the list of UDF signatures for comparison
    """
    def get_udf_signature(self):
        res = defaultdict(bool)
        for udf in self._udf:
            for item in self._udf[udf]:
                signature = get_signature_for_compare(
                    self._schema, udf, item['rettype'], item['argument'])
                res[signature] = True
        return res

    """
    @brief Get the list of UDA signatures for comparison
    """
    def get_uda_signature(self):
        res = defaultdict(bool)
        for uda in self._uda:
            for item in self._uda[uda]:
                signature = get_signature_for_compare(
                    self._schema, uda, item['rettype'], item['argument'])
                res[signature] = True
        return res

    """
    @brief Drop all types that were updated/removed in the new version
    @note It is dangerous to drop a UDT becuase there might be many
    dependencies
    """
    def drop_changed_udt(self):
        # Note that we use CASCADE option here. This might be dangerous because
        # it may drop some undetected dependent objects (eg. UDCast, UDOp, etc)
        for udt in self._udt:
            # Newly added type
            if self._udt[udt] == 'i':
                continue
            self._run_sql("""
                DROP TYPE IF EXISTS {schema}.{udt} CASCADE
                """.format(schema=self._schema, udt=udt))
            if udt == 'svec':
                # Drop operators defined in the svec module which do not
                # depend on svec. We will run the whole svec.sql without
                # filtering once svec changed
                for opr in self._opr_ind_svec:
                    self._run_sql("""
                        DROP OPERATOR IF EXISTS {schema}.{oprname}
                        ({nsp_left}.{typ_left}, {nsp_left}.{typ_left})
                        """.format(
                            schema=self._schema, oprname=opr,
                            nsp_left=self._opr_ind_svec[opr]['nsp_left'],
                            typ_left=self._opr_ind_svec[opr]['typ_left'],
                            nsp_right=self._opr_ind_svec[opr]['nsp_right'],
                            typ_right=self._opr_ind_svec[opr]['typ_right']
                        ))
    """
    @brief Drop all functions (UDF) that were removed in new version
    """
    def drop_changed_udf(self):
        for udf in self._udf:
            for item in self._udf[udf]:
                self._run_sql("""
                    DROP FUNCTION IF EXISTS {schema}.{udf}({arg})
                    """.format(schema=self._schema,
                        udf=udf,
                        arg=item['argument']))

    """
    @brief Drop all aggregates (UDA) that were removed in new version
    """
    def drop_changed_uda(self):
        for uda in self._uda:
            for item in self._uda[uda]:
                self._run_sql("""
                    DROP AGGREGATE IF EXISTS {schema}.{uda}({arg})
                    """.format(schema=self._schema,
                        uda=uda,
                        arg=item['argument']))

    """
    @brief Drop all casts (UDC) that were updated/removed in new version
    @note We have special treatment for UDCs defined in the svec module
    """
    def drop_changed_udc(self):
        for udc in self._udc:
            self._run_sql("""
                DROP CAST IF EXISTS ({sourcetype} AS {targettype})
                """.format(
                    sourcetype=self._udc[udc]['sourcetype'],
                    targettype=self._udc[udc]['targettype']))

"""
@brief This class detects the direct/recursive view dependencies on MADLib
UDFs/UDAs defined in the current version
"""
class ViewDependency(UpgradeBase):
    def __init__(self, schema, portid, con_args):
        UpgradeBase.__init__(self, schema, portid, con_args)
        self._view2proc = None
        self._view2view = None
        self._view2def = None
        self._detect_direct_view_dependency()
        self._detect_recursive_view_dependency()
        self._filter_recursive_view_dependency()

    """
    @brief  Detect direct view dependencies on MADLib UDFs/UDAs
    """
    def _detect_direct_view_dependency(self):
        rows = self._run_sql("""
            SELECT
                view, nsp.nspname AS schema, procname, procoid, proisagg
            FROM
                pg_namespace nsp,
                (
                    SELECT
                        c.relname AS view,
                        c.relnamespace AS namespace,
                        p.proname As procname,
                        p.oid AS procoid,
                        p.proisagg AS proisagg
                    FROM
                        pg_class AS c,
                        pg_rewrite AS rw,
                        pg_depend AS d,
                        pg_proc AS p
                    WHERE
                        c.oid = rw.ev_class AND
                        rw.oid = d.objid AND
                        d.classid = 'pg_rewrite'::regclass AND
                        d.refclassid = 'pg_proc'::regclass AND
                        d.refobjid = p.oid AND
                        p.pronamespace = {schema_madlib_oid}
                ) t1
            WHERE
                t1.namespace = nsp.oid
        """.format(schema_madlib_oid=self._schema_oid))

        self._view2proc = defaultdict(list)
        for row in rows:
            key= (row['schema'], row['view'])
            self._view2proc[key].append(
                (row['procname'], row['procoid'],
                    True if row['proisagg'] == 't' else False))

    """
    @brief  Detect recursive view dependencies (view on view)
    """
    def _detect_recursive_view_dependency(self):
        rows = self._run_sql("""
            SELECT
                nsp1.nspname AS depender_schema,
                depender,
                nsp2.nspname AS dependee_schema,
                dependee
            FROM
                pg_namespace AS nsp1,
                pg_namespace AS nsp2,
                (
                    SELECT
                        c.relname depender,
                        c.relnamespace AS depender_nsp,
                        c1.relname AS dependee,
                        c1.relnamespace AS dependee_nsp
                    FROM
                        pg_rewrite AS rw,
                        pg_depend AS d,
                        pg_class AS c,
                        pg_class AS c1
                    WHERE
                        rw.ev_class = c.oid AND
                        rw.oid = d.objid AND
                        d.classid = 'pg_rewrite'::regclass AND
                        d.refclassid = 'pg_class'::regclass AND
                        d.refobjid = c1.oid AND
                        c1.relkind = 'v' AND
                        c.relname <> c1.relname
                    GROUP BY
                        depender, depender_nsp, dependee, dependee_nsp
                ) t1
            WHERE
                t1.depender_nsp = nsp1.oid AND
                t1.dependee_nsp = nsp2.oid
        """)

        self._view2view = defaultdict(list)
        for row in rows:
            key = (row['depender_schema'], row['depender'])
            val = (row['dependee_schema'], row['dependee'])
            self._view2view[key].append(val)

    """
    @brief  Filter out recursive view dependencies which are independent of
    MADLib UDFs/UDAs
    """
    def _filter_recursive_view_dependency(self):
        # Get recursive dependee list
        dependeelist = []
        checklist = self._view2proc
        while True:
            dependeelist.extend(checklist.keys())
            new_checklist = defaultdict(bool)
            for depender in self._view2view.keys():
                for dependee in self._view2view[depender]:
                    if dependee in checklist:
                        new_checklist[depender] = True
                        break
            if len(new_checklist) == 0:
                break
            else:
                checklist = new_checklist

        # Filter recursive dependencies not related with MADLib UDF/UDAs
        fil_view2view = defaultdict(list)
        for depender in self._view2view:
            dependee = self._view2view[depender]
            dependee = [r for r in dependee if r in dependeelist]
            if len(dependee) > 0:
                fil_view2view[depender] = dependee

        self._view2view = fil_view2view

    """
    @brief  Build the dependency graph (depender-to-dependee adjacency list)
    """
    def _build_dependency_graph(self, hasProcDependency = False):
        der2dee = self._view2view.copy()
        for view in self._view2proc:
            if view not in self._view2view:
                der2dee[view] = []
            if hasProcDependency:
                der2dee[view].extend(self._view2proc[view])

        graph = der2dee.copy()
        for der in der2dee:
            for dee in der2dee[der]:
                if dee not in graph:
                    graph[dee] = []
        return graph

    """
    @brief Check dependencies
    """
    def has_dependency(self):
        return len(self._view2proc) > 0

    """
    @brief Get the ordered views for creation
    """
    def get_create_order_views(self):
        graph = self._build_dependency_graph()
        ordered_views = []
        while True:
            remove_list = []
            for depender in graph:
                if len(graph[depender]) == 0:
                    ordered_views.append(depender)
                    remove_list.append(depender)
            for view in remove_list:
                del graph[view]
            for depender in graph:
                graph[depender] = [r for r in graph[depender]
                    if r not in remove_list]
            if len(remove_list) == 0:
                break
        return ordered_views

    """
    @brief Get the ordered views for dropping
    """
    def get_drop_order_views(self):
        ordered_views = self.get_create_order_views()
        ordered_views.reverse()
        return ordered_views

    """
    @brief Get the depended UDF/UDA signatures for comparison
    """
    def get_depended_func_signature(self, isagg = True):
        res = {}
        for procs in self._view2proc.values():
            for proc in procs:
                if proc[2] != isagg:
                    continue
                if (self._schema, proc) not in res:
                    funcinfo = self._get_function_info(proc[1])
                    signature = get_signature_for_compare(
                        self._schema, proc[0], funcinfo['rettype'], funcinfo['argument'])
                    res[signature] = True
        return res

    """
    @brief Get dependent UDAs
    """
    def get_depended_uda(self):
        res = []
        for procs in self._view2proc.values():
            for proc in procs:
                if proc[2] == False:
                    continue
                if (self._schema, proc) not in res:
                    res.append((self._schema, proc))
        res.sort()
        return res

    """
    @brief Get dependent UDFs
    """
    def get_depended_udf(self):
        res = []
        for procs in self._view2proc.values():
            for proc in procs:
                if proc[2] == True:
                    continue
                if (self._schema, proc) not in res:
                    res.append((self._schema, proc))
        res.sort()
        return res

    """
    @brief Save and drop the dependent views
    """
    def save_and_drop(self):
        self._view2def = {}
        ordered_views = self.get_drop_order_views()
        # Save views
        for view in ordered_views:
            row = self._run_sql("""
                SELECT
                    schemaname, viewname, viewowner, definition
                FROM
                    pg_views
                WHERE
                    schemaname = '{schemaname}' AND
                    viewname = '{viewname}'
            """.format(schemaname=view[0], viewname=view[1]))
            self._view2def[view] = row[0]

        # Drop views
        for view in ordered_views:
            self._run_sql("""
                DROP VIEW IF EXISTS {schema}.{view}
                """.format(schema=view[0], view=view[1]))

    """
    @brief Restore the dependent views
    """
    def restore(self):
        ordered_views = self.get_create_order_views()
        for view in ordered_views:
            row = self._view2def[view]
            schema = row['schemaname']
            view = row['viewname']
            owner = row['viewowner']
            definition = row['definition']
            self._run_sql("""
                --Alter view not supported by GP, so use set/reset role as a
                --workaround
                --ALTER VIEW {schema}.{view} OWNER TO {owner}
                SET ROLE {owner};
                CREATE OR REPLACE VIEW {schema}.{view} AS {definition};
                RESET ROLE
                """.format(
                    schema=schema, view=view,
                    definition=definition, owner=owner))

    def _node_to_str(self, node):
        res = ''
        if len(node) == 2:
            res = '%s.%s' % (node[0], node[1])
        else:
            res = '%s.%s{oid=%s,isagg=%s}' % (
                self._schema, node[0], node[1], node[2])
        return res

    def _nodes_to_str(self, nodes):
        res = []
        for node in nodes:
            res.append(self._node_to_str(node))
        return res

    """
    @brief Get the dependency graph string for print
    """
    def get_dependency_graph_str(self):
        graph = self._build_dependency_graph(True)
        nodes = graph.keys()
        nodes.sort()
        res = '\t\tDependency Graph (Depender-Dependee Adjacency List):\n'
        for node in nodes:
            res += "\t\t%s -> %s\n" % (
                self._node_to_str(node), self._nodes_to_str(graph[node]))
        return res[:-1]

"""
@brief This class detects the table dependencies on MADLib UDTs defined in the
current version
"""
class TableDependency(UpgradeBase):
    def __init__(self, schema, portid, con_args):
        UpgradeBase.__init__(self, schema, portid, con_args)
        self._table2type = None
        self._detect_table_dependency()

    """
    @brief Detect the table dependencies on MADLib UDTs
    """
    def _detect_table_dependency(self):
        rows = self._run_sql("""
            SELECT
                nsp.nspname AS schema,
                relname AS relation,
                attname AS column,
                typname AS type
            FROM
                pg_attribute a,
                pg_class c,
                pg_type t,
                pg_namespace nsp
            WHERE
                t.typnamespace = {schema_madlib_oid}
                AND a.atttypid = t.oid
                AND c.oid = a.attrelid
                AND c.relnamespace = nsp.oid
                AND c.relkind = 'r'
            ORDER BY
                nsp.nspname, relname, attname, typname
            """.format(schema_madlib_oid=self._schema_oid))

        self._table2type = defaultdict(list)
        for row in rows:
            key= (row['schema'], row['relation'])
            self._table2type[key].append(
                (row['column'], row['type']))

    """
    @brief Check dependencies
    """
    def has_dependency(self):
        return len(self._table2type) > 0

    """
    @brief Get the list of depended UDTs
    """
    def get_depended_udt(self):
        res = defaultdict(bool)
        for table in self._table2type:
            for (col, typ) in self._table2type[table]:
                if typ not in res:
                    res[typ] = True
        return res

    """
    @brief Get the dependencies in string for print
    """
    def get_dependency_str(self):
        res = '\t\tTable Dependency (schema.table.column -> type):\n'
        for table in self._table2type:
            for (col, udt) in self._table2type[table]:
                res += "\t\t%s.%s.%s -> %s\n" % (table[0], table[1], col, udt)
        return res[:-1]

"""
@brief This class removes sql statements from a sql script which should not be
executed during the upgrade
"""
class ScriptCleaner(UpgradeBase):
    def __init__(self, schema, portid, con_args, change_handler):
        UpgradeBase.__init__(self, schema, portid, con_args)
        self._sql = None
        self._existing_uda = None
        self._existing_udt = None
        self._get_existing_uda()
        self._get_existing_udt()
        self._ch = change_handler

    """
    @breif Get the existing UDAs in the current version
    """
    def _get_existing_uda(self):
        rows = self._run_sql("""
            SELECT
                max(proname) AS proname,
                max(rettype) AS rettype,
                array_to_string(array_agg(argtype order by i), ',') AS argument
            FROM
            (
                SELECT
                    p.oid AS procoid,
                    proname,
                    textin(regtypeout(prorettype::regtype)) AS rettype,

                    CASE array_upper(proargtypes,1) WHEN -1 THEN ''
                        ELSE textin(regtypeout(unnest(proargtypes)::regtype))
                    END AS argtype,

                    CASE array_upper(proargtypes,1) WHEN -1 THEN 1
                        ELSE generate_series(0, array_upper(proargtypes, 1))
                    END AS i
                FROM
                    pg_proc AS p,
                    pg_namespace AS nsp
                WHERE
                    p.pronamespace = nsp.oid AND
                    p.proisagg = true AND
                    nsp.nspname = '{schema}'
            ) AS f
            GROUP BY
                procoid
            """.format(schema=self._schema))
        self._existing_uda = {}
        for row in rows:
            # Consider about the overloaded aggregates
            if row['proname'] not in self._existing_uda:
                self._existing_uda[row['proname']] = []
            self._existing_uda[row['proname']].append({
                'rettype': ['rettype'],
                'argument': row['argument']})

    """
    @brief Get the existing UDTs in the current version
    """
    def _get_existing_udt(self):
        rows = self._run_sql("""
            SELECT
                typname
            FROM
                pg_type AS t,
                pg_namespace AS nsp
            WHERE
                t.typnamespace = nsp.oid AND
                nsp.nspname = '{schema}'
            """.format(schema=self._schema))
        self._existing_udt = []
        for row in rows:
            self._existing_udt.append(row['typname'])

    """
    @note The changer_handler is needed for deciding which sql statements to
    remove
    """
    def get_change_handler(self):
        return self._ch

    """
    @brief Remove comments in the sql script
    """
    def _clean_comment(self):
        pattern = re.compile(r"""(/\*(.|[\r\n])*?\*/)|(--(.*|[\r\n]))""")
        self._sql = re.sub(pattern, '', self._sql).strip()

    """
    @breif Remove "drop/create type" statements in the sql script
    """
    def _clean_type(self):
        # remove 'drop type'
        pattern = re.compile('DROP(\s+)TYPE(.*?);', re.DOTALL | re.IGNORECASE);
        self._sql = re.sub(pattern, '', self._sql)

        # remove 'create type'
        udt_str = ''
        for udt in self._existing_udt:
            if udt in self._ch.get_udt():
                continue
            if udt_str == '':
                udt_str += udt
            else:
                udt_str += '|' + udt
        p_str = 'CREATE(\s+)TYPE(\s+)%s\.(%s)(.*?);' % (self._schema.upper(), udt_str)
        pattern = re.compile(p_str, re.DOTALL | re.IGNORECASE);
        self._sql = re.sub(pattern, '', self._sql)

    """
    @brief Remove "drop/create cast" statements in the sql script
    """
    def _clean_cast(self):
        # remove 'drop cast'
        pattern = re.compile('DROP(\s+)CAST(.*?);', re.DOTALL | re.IGNORECASE);
        self._sql = re.sub(pattern, '', self._sql)

        # remove 'create cast'
        udc_str = ''
        for udc in self._ch.get_udc():
            if udc_str == '':
                udc_str += '%s\s+AS\s+%s' % (
                    self._ch.get_udc()[udc]['sourcetype'], self._ch.get_udc()[udc]['targettype'])
            else:
                udc_str += '|' + '%s\s+AS\s+%s' % (
                    self._ch.get_udc()[udc]['sourcetype'], self._ch.get_udc()[udc]['targettype'])

        pattern = re.compile('CREATE\s+CAST(.*?);', re.DOTALL | re.IGNORECASE)
        if udc_str != '':
            pattern = re.compile('CREATE\s+CAST\s*\(\s*(?!%s)(.*?);' % udc_str , re.DOTALL | re.IGNORECASE)
        self._sql = re.sub(pattern, '', self._sql)

    """
    @brief Remove "drop/create operator" statements in the sql script
    """
    def _clean_operator(self):
        # remove 'drop operator'
        pattern = re.compile('DROP(\s+)OPERATOR(.*?);', re.DOTALL | re.IGNORECASE);
        self._sql = re.sub(pattern, '', self._sql)

        # remove 'create operator'
        pattern = re.compile(r"""CREATE(\s+)OPERATOR(.*?);""", re.DOTALL | re.IGNORECASE);
        self._sql = re.sub(pattern, '', self._sql)

    """
    @brief Rewrite the type
    """
    def _rewrite_type_in(self, arg):
        type_mapper = {
            'smallint':'(int2|smallint)',
            'integer':'(int|int4|integer)',
            'bigint':'(int8|bigint)',
            'double precision':'(float8|double precision)',
            'real':'(float4|real)',
            'character varying':'(varchar|character varying)'
        }
        for typ in type_mapper:
            arg = arg.replace(typ, type_mapper[typ])
        return arg.replace('[', '\[').replace(']', '\]')

    """
    @brief Remove "drop/create aggregate" statements in the sql script
    """
    def _clean_aggregate(self):
        # remove 'drop aggregate'
        pattern = re.compile('DROP(\s+)AGGREGATE(.*?);', re.DOTALL | re.IGNORECASE);
        self._sql = re.sub(pattern, '', self._sql)

        # remove 'create aggregate'
        uda_str = ''
        for uda in self._existing_uda:
            for item in self._existing_uda[uda]:
                if uda in self._ch.get_uda():
                    items = self._ch.get_uda()[uda]
                    if item in items:
                        continue
                p_arg_str = ''
                argument = item['argument']
                args = argument.split(',')
                for arg in args:
                    arg = self._rewrite_type_in(arg.strip())
                    if p_arg_str == '':
                        p_arg_str += '%s\s*' % arg
                    else:
                        p_arg_str += ',\s*%s\s*' % arg
                p_str = 'CREATE\s+(ORDERED\s)*\s*AGGREGATE\s+%s\.(%s)\s*\(\s*%s\)(.*?);' % (
                    self._schema.upper(), uda, p_arg_str)
                pattern = re.compile(p_str, re.DOTALL | re.IGNORECASE);
                self._sql = re.sub(pattern, '', self._sql)

    """
    @brief Remove "drop function" statements and rewrite "create function"
    statements in the sql script
    @note We don't drop any function
    """
    def _clean_function(self):
        # remove 'drop function'
        pattern = re.compile(r"""DROP(\s+)FUNCTION(.*?);""", re.DOTALL | re.IGNORECASE);
        self._sql = re.sub(pattern, '', self._sql)
        # replace 'create function' with 'create or replace function'
        pattern = re.compile(r"""CREATE(\s+)FUNCTION""", re.DOTALL | re.IGNORECASE);
        self._sql = re.sub(pattern, 'CREATE OR REPLACE FUNCTION', self._sql)

    """
    @brief Entry function for cleaning the sql script
    """
    def cleanup(self, sql):
        self._sql = sql
        self._clean_comment()
        self._clean_type()
        self._clean_cast()
        self._clean_operator()
        self._clean_aggregate()
        self._clean_function()
        return self._sql
