def alter_search(self, search):
    overall_search = search
    self.overall_search_type = overall_search.get_search_type()
    search_type = self.overall_search_type
    search = Search(self.overall_search_type)
    value = self.values.get('value')
    if (not value):
        return
    name = self.get_name()
    if (not self.columns):
        self.columns = [name]
    partial = (self.values.get('partial') == 'on')
    try:
        value.encode('ascii')
    except UnicodeEncodeError:
        is_ascii = False
    else:
        is_ascii = True
    tmp_keywords = value.split(' ')
    keywords = []
    for keyword in tmp_keywords:
        if ((not keyword) or (len(keyword) == 1)):
            continue
        keywords.append(keyword)
    if (search_type == 'sthpw/sobject_list'):
        column = 'keywords'
        project_code = Project.get_project_code()
        overall_search.add_filter('project_code', project_code)
        if (self.has_index and is_ascii):
            if partial:
                overall_search.add_op('begin')
                overall_search.add_text_search_filter(column, keywords)
                overall_search.add_keyword_filter(column, keywords)
                overall_search.add_op('or')
            else:
                overall_search.add_text_search_filter(column, keywords)
        else:
            overall_search.add_keyword_filter(column, keywords)
    elif (self.mode == 'global'):
        column = 'keywords'
        search2 = Search('sthpw/sobject_list')
        project_code = Project.get_project_code()
        search2.add_filter('project_code', project_code)
        search2.add_filter('search_type', search_type)
        if (self.has_index and is_ascii):
            if partial:
                search2.add_op('begin')
                search2.add_text_search_filter(column, keywords)
                search2.add_keyword_filter(column, keywords)
                search2.add_op('or')
            else:
                search2.add_text_search_filter(column, keywords)
        else:
            search2.add_keyword_filter(column, keywords)
        refs = search2.get_sobjects()
        overall_search.add_filters('id', [x.get_value('search_id') for x in refs])
    elif (self.mode == 'keyword_tree'):
        if self.cross_db:
            sub_search_list = []
        else:
            overall_search.add_op('begin')
        partial_op = 'or'
        value = value.replace(',', ' ')
        project = Project.get()
        sql = project.get_sql()
        stmts = []
        value_idx = []
        impl = project.get_database_impl()
        op = self.values.get('cte_op')
        if (not op):
            op = 'keyword'
        if (op == 'child'):
            tbl = 'p1'
        elif (op == 'both'):
            tbl = 'p1'
            filter_expr1 = [['begin'], [('%s.name' % tbl), ('%s' % value)], [('%s.alias' % tbl), 'like', ('%%%s%%' % value)], ['or']]
            tbl = 'p2'
            filter_expr2 = [['begin'], [('%s.name' % tbl), ('%s' % value)], [('%s.alias' % tbl), 'like', ('%%%s%%' % value)], ['or']]
        else:
            tbl = 'p2'
        filter_expr = [['begin'], [('%s.name' % tbl), ('%s' % value)], [('%s.alias' % tbl), 'like', ('%%%s%%' % value)], ['or']]
        if (op == 'parent'):
            stmts.append(impl.get_parent_cte(filter_expr))
            value_idx.append(1)
        elif (op == 'child'):
            stmts.append(impl.get_child_cte(filter_expr))
            value_idx.append(3)
        elif (op == 'both'):
            stmts.append(impl.get_parent_cte(filter_expr2))
            value_idx.append(1)
            stmts.append(impl.get_child_cte(filter_expr1))
            value_idx.append(3)
        elif (op == 'keyword'):
            pass
        original_search = Search(self.keyword_search_type)
        original_search.add_op('begin')
        original_search.add_filter('name', value)
        original_search.add_regex_filter('alias', value, op='EQI')
        original_search.add_op('or')
        original = original_search.get_sobject()
        if original:
            value = original.get('name')
        keywords_list = [value]
        for (idx, stmt) in enumerate(stmts):
            results = sql.do_query(stmt)
            for res in results:
                if (res[value_idx[idx]] not in keywords_list):
                    keywords_list.append(res[value_idx[idx]])
        keywords = keywords_list
        for column in self.columns:
            if self.cross_db:
                search2 = None
                sub_search = None
            search_type_obj = overall_search.get_search_type_obj()
            table = search_type_obj.get_table()
            column_type = None
            search = Search(overall_search.get_search_type())
            local_table = True
            if (column.find('.') != (- 1)):
                parts = column.split('.')
                search_types = parts[:(- 1)]
                column = parts[(- 1)]
                local_table = False
                "\n                    if self.cross_db:\n                        search_types.reverse()\n                        top_search_type = search_types[0]\n                        search_type_str = '.'.join(search_types[1:])\n                        if search_type_str:\n                            expr = '''@SEARCH(%s)'''%(search_type_str)\n                            sub_search = Search.eval(expr)\n                        search2 = Search(top_search_type)\n                        table = SearchType.get(top_search_type).get_table()\n                        column_types = SearchType.get_column_types(top_search_type)\n                        column_type = column_types.get(column) \n                    else:\n                    "
                prev_stype = search_type
                for next_stype in search_types:
                    path = None
                    if (':' in next_stype):
                        (path, next_stype) = next_stype.split(':')
                    search.add_join(next_stype, prev_stype, path=path)
                    prev_stype = next_stype
                table = SearchType.get(next_stype).get_table()
                column_types = SearchType.get_column_types(next_stype)
                column_type = column_types.get(column)
            if self.cross_db:
                search2.add_keyword_filter(column, keywords_list, table=table, column_type=column_type, op=partial_op)
                if sub_search:
                    sub_search.add_relationship_search_filter(search2, op='in')
                else:
                    sub_search = search2
            elif local_table:
                overall_search.add_keyword_filter(column, keywords_list, table=table, column_type=column_type, op=partial_op)
            else:
                search.add_keyword_filter(column, keywords_list, table=table, column_type=column_type, op=partial_op)
                overall_search.add_relationship_search_filter(search, op='in')
        if self.cross_db:
            sub_search_list.append(sub_search)
        if self.cross_db:
            rtn_history = False
            overall_search.add_op('begin')
            for sub_search in sub_search_list:
                rtn = overall_search.add_relationship_search_filter(sub_search, op='in', delay_null=True)
                if (rtn_history == False):
                    rtn_history = rtn
            if (not rtn_history):
                overall_search.set_null_filter()
            overall_search.add_op('or')
        else:
            overall_search.add_op('or')
    elif (self.mode == 'keyword'):
        if self.cross_db:
            sub_search_list = []
        else:
            overall_search.add_op('begin')
        single_col = (len(self.columns) == 1)
        partial_op = 'and'
        value = value.replace(',', ' ')
        value = re.sub(' +', ' ', value)
        keywords = value.strip()
        if (not keywords):
            return
        keywords_list = keywords.split(' ')
        single_keyword = (len(keywords_list) == 1)
        if single_col:
            if single_keyword:
                multi_col_op = 'or'
                op = '|'
            else:
                multi_col_op = 'or'
                op = '&'
        elif single_keyword:
            multi_col_op = 'or'
            op = '|'
        else:
            multi_col_op = 'or'
            op = '&'
        for column in self.columns:
            if self.cross_db:
                search2 = None
                sub_search = None
            if single_col:
                keywords = keywords_list
            if (self.has_index and is_ascii):
                search_type_obj = SearchType.get(search_type)
                table = search_type_obj.get_table()
                search = Search(overall_search.get_search_type())
                local_table = True
                if (column.find('.') != (- 1)):
                    parts = column.split('.')
                    search_types = parts[:(- 1)]
                    column = parts[(- 1)]
                    local_table = False
                    if self.cross_db:
                        search_types.reverse()
                        top_search_type = search_types[0]
                        search_type_str = '.'.join(search_types[1:])
                        if search_type_str:
                            expr = ('@SEARCH(%s)' % search_type_str)
                            sub_search = Search.eval(expr)
                        search2 = Search(top_search_type)
                        table = SearchType.get(top_search_type).get_table()
                    else:
                        prev_stype = search_type
                        for next_stype in search_types:
                            path = None
                            if (':' in next_stype):
                                (path, next_stype) = next_stype.split(':')
                            search.add_join(next_stype, prev_stype, path=path)
                            prev_stype = next_stype
                        table = SearchType.get(next_stype).get_table()
                if partial:
                    if self.cross_db:
                        search2.add_op('begin')
                        search2.add_text_search_filter(column, keywords, table=table, op=op)
                        search2.add_keyword_filter(column, keywords_list, table=table, op=partial_op)
                        search2.add_op('or')
                        if sub_search:
                            sub_search.add_relationship_search_filter(search2, op='in')
                        else:
                            sub_search = search2
                    else:
                        search.add_op('begin')
                        search.add_text_search_filter(column, keywords, table=table, op=op)
                        search.add_keyword_filter(column, keywords_list, table=table, op=partial_op)
                        search.add_op('or')
                        overall_search.add_relationship_search_filter(search, op='in')
                elif self.cross_db:
                    if (not search2):
                        raise TacticException('If cross_db is set to true, all the columns should be formatted in expression-like format with one or more sTypes: sthpw/task.description')
                    search2.add_text_search_filter(column, keywords, table=table, op=op)
                    if sub_search:
                        sub_search.add_relationship_search_filter(search2, op='in')
                    else:
                        sub_search = search2
                elif local_table:
                    overall_search.add_text_search_filter(column, keywords, table=table, op=op)
                else:
                    search.add_text_search_filter(column, keywords, table=table, op=op)
                    overall_search.add_relationship_search_filter(search, op='in')
            else:
                search_type_obj = overall_search.get_search_type_obj()
                table = search_type_obj.get_table()
                column_type = None
                search = Search(overall_search.get_search_type())
                local_table = True
                if (column.find('.') != (- 1)):
                    parts = column.split('.')
                    search_types = parts[:(- 1)]
                    column = parts[(- 1)]
                    local_table = False
                    if self.cross_db:
                        search_types.reverse()
                        top_search_type = search_types[0]
                        search_type_str = '.'.join(search_types[1:])
                        if search_type_str:
                            expr = ('@SEARCH(%s)' % search_type_str)
                            sub_search = Search.eval(expr)
                        search2 = Search(top_search_type)
                        table = SearchType.get(top_search_type).get_table()
                        column_types = SearchType.get_column_types(top_search_type)
                        column_type = column_types.get(column)
                    else:
                        prev_stype = search_type
                        for next_stype in search_types:
                            path = None
                            if (':' in next_stype):
                                (path, next_stype) = next_stype.split(':')
                            search.add_join(next_stype, prev_stype, path=path)
                            prev_stype = next_stype
                        table = SearchType.get(next_stype).get_table()
                        column_types = SearchType.get_column_types(next_stype)
                        column_type = column_types.get(column)
                if self.cross_db:
                    search2.add_keyword_filter(column, keywords_list, table=table, column_type=column_type, op=partial_op)
                    if sub_search:
                        sub_search.add_relationship_search_filter(search2, op='in')
                    else:
                        sub_search = search2
                elif local_table:
                    overall_search.add_keyword_filter(column, keywords_list, table=table, column_type=column_type, op=partial_op)
                else:
                    search.add_keyword_filter(column, keywords_list, table=table, column_type=column_type, op=partial_op)
                    overall_search.add_relationship_search_filter(search, op='in')
            if self.cross_db:
                sub_search_list.append(sub_search)
        if self.cross_db:
            rtn_history = False
            overall_search.add_op('begin')
            for sub_search in sub_search_list:
                rtn = overall_search.add_relationship_search_filter(sub_search, op='in', delay_null=True)
                if (rtn_history == False):
                    rtn_history = rtn
            if (not rtn_history):
                overall_search.set_null_filter()
            overall_search.add_op(multi_col_op)
        else:
            overall_search.add_op(multi_col_op)
    else:
        raise TacticException(('Mode [%s] in keyword search not support' % self.mode))
def alter_search(self, search):
    overall_search = search
    self.overall_search_type = overall_search.get_search_type()
    search_type = self.overall_search_type
    search = Search(self.overall_search_type)
    value = self.values.get('value')
    if (not value):
        return
    name = self.get_name()
    if (not self.columns):
        self.columns = [name]
    partial = (self.values.get('partial') == 'on')
    try:
        value.encode('ascii')
    except UnicodeEncodeError:
        is_ascii = False
    else:
        is_ascii = True
    tmp_keywords = value.split(' ')
    keywords = []
    for keyword in tmp_keywords:
        if ((not keyword) or (len(keyword) == 1)):
            continue
        keywords.append(keyword)
    if (search_type == 'sthpw/sobject_list'):
        column = 'keywords'
        project_code = Project.get_project_code()
        overall_search.add_filter('project_code', project_code)
        if (self.has_index and is_ascii):
            if partial:
                overall_search.add_op('begin')
                overall_search.add_text_search_filter(column, keywords)
                overall_search.add_keyword_filter(column, keywords)
                overall_search.add_op('or')
            else:
                overall_search.add_text_search_filter(column, keywords)
        else:
            overall_search.add_keyword_filter(column, keywords)
    elif (self.mode == 'global'):
        column = 'keywords'
        search2 = Search('sthpw/sobject_list')
        project_code = Project.get_project_code()
        search2.add_filter('project_code', project_code)
        search2.add_filter('search_type', search_type)
        if (self.has_index and is_ascii):
            if partial:
                search2.add_op('begin')
                search2.add_text_search_filter(column, keywords)
                search2.add_keyword_filter(column, keywords)
                search2.add_op('or')
            else:
                search2.add_text_search_filter(column, keywords)
        else:
            search2.add_keyword_filter(column, keywords)
        refs = search2.get_sobjects()
        overall_search.add_filters('id', [x.get_value('search_id') for x in refs])
    elif (self.mode == 'keyword_tree'):
        if self.cross_db:
            sub_search_list = []
        else:
            overall_search.add_op('begin')
        partial_op = 'or'
        value = value.replace(',', ' ')
        project = Project.get()
        sql = project.get_sql()
        stmts = []
        value_idx = []
        impl = project.get_database_impl()
        op = self.values.get('cte_op')
        if (not op):
            op = 'keyword'
        if (op == 'child'):
            tbl = 'p1'
        elif (op == 'both'):
            tbl = 'p1'
            filter_expr1 = [['begin'], [('%s.name' % tbl), ('%s' % value)], [('%s.alias' % tbl), 'like', ('%%%s%%' % value)], ['or']]
            tbl = 'p2'
            filter_expr2 = [['begin'], [('%s.name' % tbl), ('%s' % value)], [('%s.alias' % tbl), 'like', ('%%%s%%' % value)], ['or']]
        else:
            tbl = 'p2'
        filter_expr = [['begin'], [('%s.name' % tbl), ('%s' % value)], [('%s.alias' % tbl), 'like', ('%%%s%%' % value)], ['or']]
        if (op == 'parent'):
            stmts.append(impl.get_parent_cte(filter_expr))
            value_idx.append(1)
        elif (op == 'child'):
            stmts.append(impl.get_child_cte(filter_expr))
            value_idx.append(3)
        elif (op == 'both'):
            stmts.append(impl.get_parent_cte(filter_expr2))
            value_idx.append(1)
            stmts.append(impl.get_child_cte(filter_expr1))
            value_idx.append(3)
        elif (op == 'keyword'):
            pass
        original_search = Search(self.keyword_search_type)
        original_search.add_op('begin')
        original_search.add_filter('name', value)
        original_search.add_regex_filter('alias', value, op='EQI')
        original_search.add_op('or')
        original = original_search.get_sobject()
        if original:
            value = original.get('name')
        keywords_list = [value]
        for (idx, stmt) in enumerate(stmts):
            results = sql.do_query(stmt)
            for res in results:
                if (res[value_idx[idx]] not in keywords_list):
                    keywords_list.append(res[value_idx[idx]])
        keywords = keywords_list
        for column in self.columns:
            if self.cross_db:
                search2 = None
                sub_search = None
            search_type_obj = overall_search.get_search_type_obj()
            table = search_type_obj.get_table()
            column_type = None
            search = Search(overall_search.get_search_type())
            local_table = True
            if (column.find('.') != (- 1)):
                parts = column.split('.')
                search_types = parts[:(- 1)]
                column = parts[(- 1)]
                local_table = False
                "\n                    if self.cross_db:\n                        search_types.reverse()\n                        top_search_type = search_types[0]\n                        search_type_str = '.'.join(search_types[1:])\n                        if search_type_str:\n                            expr = '@SEARCH(%s)'%(search_type_str)\n                            sub_search = Search.eval(expr)\n                        search2 = Search(top_search_type)\n                        table = SearchType.get(top_search_type).get_table()\n                        column_types = SearchType.get_column_types(top_search_type)\n                        column_type = column_types.get(column) \n                    else:\n                    "
                prev_stype = search_type
                for next_stype in search_types:
                    path = None
                    if (':' in next_stype):
                        (path, next_stype) = next_stype.split(':')
                    search.add_join(next_stype, prev_stype, path=path)
                    prev_stype = next_stype
                table = SearchType.get(next_stype).get_table()
                column_types = SearchType.get_column_types(next_stype)
                column_type = column_types.get(column)
            if self.cross_db:
                search2.add_keyword_filter(column, keywords_list, table=table, column_type=column_type, op=partial_op)
                if sub_search:
                    sub_search.add_relationship_search_filter(search2, op='in')
                else:
                    sub_search = search2
            elif local_table:
                overall_search.add_keyword_filter(column, keywords_list, table=table, column_type=column_type, op=partial_op)
            else:
                search.add_keyword_filter(column, keywords_list, table=table, column_type=column_type, op=partial_op)
                overall_search.add_relationship_search_filter(search, op='in')
        if self.cross_db:
            sub_search_list.append(sub_search)
        if self.cross_db:
            rtn_history = False
            overall_search.add_op('begin')
            for sub_search in sub_search_list:
                rtn = overall_search.add_relationship_search_filter(sub_search, op='in', delay_null=True)
                if (rtn_history == False):
                    rtn_history = rtn
            if (not rtn_history):
                overall_search.set_null_filter()
            overall_search.add_op('or')
        else:
            overall_search.add_op('or')
    elif (self.mode == 'keyword'):
        if self.cross_db:
            sub_search_list = []
        else:
            overall_search.add_op('begin')
        single_col = (len(self.columns) == 1)
        partial_op = 'and'
        value = value.replace(',', ' ')
        value = re.sub(' +', ' ', value)
        keywords = value.strip()
        if (not keywords):
            return
        keywords_list = keywords.split(' ')
        single_keyword = (len(keywords_list) == 1)
        if single_col:
            if single_keyword:
                multi_col_op = 'or'
                op = '|'
            else:
                multi_col_op = 'or'
                op = '&'
        elif single_keyword:
            multi_col_op = 'or'
            op = '|'
        else:
            multi_col_op = 'or'
            op = '&'
        for column in self.columns:
            if self.cross_db:
                search2 = None
                sub_search = None
            if single_col:
                keywords = keywords_list
            if (self.has_index and is_ascii):
                search_type_obj = SearchType.get(search_type)
                table = search_type_obj.get_table()
                search = Search(overall_search.get_search_type())
                local_table = True
                if (column.find('.') != (- 1)):
                    parts = column.split('.')
                    search_types = parts[:(- 1)]
                    column = parts[(- 1)]
                    local_table = False
                    if self.cross_db:
                        search_types.reverse()
                        top_search_type = search_types[0]
                        search_type_str = '.'.join(search_types[1:])
                        if search_type_str:
                            expr = ('@SEARCH(%s)' % search_type_str)
                            sub_search = Search.eval(expr)
                        search2 = Search(top_search_type)
                        table = SearchType.get(top_search_type).get_table()
                    else:
                        prev_stype = search_type
                        for next_stype in search_types:
                            path = None
                            if (':' in next_stype):
                                (path, next_stype) = next_stype.split(':')
                            search.add_join(next_stype, prev_stype, path=path)
                            prev_stype = next_stype
                        table = SearchType.get(next_stype).get_table()
                if partial:
                    if self.cross_db:
                        search2.add_op('begin')
                        search2.add_text_search_filter(column, keywords, table=table, op=op)
                        search2.add_keyword_filter(column, keywords_list, table=table, op=partial_op)
                        search2.add_op('or')
                        if sub_search:
                            sub_search.add_relationship_search_filter(search2, op='in')
                        else:
                            sub_search = search2
                    else:
                        search.add_op('begin')
                        search.add_text_search_filter(column, keywords, table=table, op=op)
                        search.add_keyword_filter(column, keywords_list, table=table, op=partial_op)
                        search.add_op('or')
                        overall_search.add_relationship_search_filter(search, op='in')
                elif self.cross_db:
                    if (not search2):
                        raise TacticException('If cross_db is set to true, all the columns should be formatted in expression-like format with one or more sTypes: sthpw/task.description')
                    search2.add_text_search_filter(column, keywords, table=table, op=op)
                    if sub_search:
                        sub_search.add_relationship_search_filter(search2, op='in')
                    else:
                        sub_search = search2
                elif local_table:
                    overall_search.add_text_search_filter(column, keywords, table=table, op=op)
                else:
                    search.add_text_search_filter(column, keywords, table=table, op=op)
                    overall_search.add_relationship_search_filter(search, op='in')
            else:
                search_type_obj = overall_search.get_search_type_obj()
                table = search_type_obj.get_table()
                column_type = None
                search = Search(overall_search.get_search_type())
                local_table = True
                if (column.find('.') != (- 1)):
                    parts = column.split('.')
                    search_types = parts[:(- 1)]
                    column = parts[(- 1)]
                    local_table = False
                    if self.cross_db:
                        search_types.reverse()
                        top_search_type = search_types[0]
                        search_type_str = '.'.join(search_types[1:])
                        if search_type_str:
                            expr = ('@SEARCH(%s)' % search_type_str)
                            sub_search = Search.eval(expr)
                        search2 = Search(top_search_type)
                        table = SearchType.get(top_search_type).get_table()
                        column_types = SearchType.get_column_types(top_search_type)
                        column_type = column_types.get(column)
                    else:
                        prev_stype = search_type
                        for next_stype in search_types:
                            path = None
                            if (':' in next_stype):
                                (path, next_stype) = next_stype.split(':')
                            search.add_join(next_stype, prev_stype, path=path)
                            prev_stype = next_stype
                        table = SearchType.get(next_stype).get_table()
                        column_types = SearchType.get_column_types(next_stype)
                        column_type = column_types.get(column)
                if self.cross_db:
                    search2.add_keyword_filter(column, keywords_list, table=table, column_type=column_type, op=partial_op)
                    if sub_search:
                        sub_search.add_relationship_search_filter(search2, op='in')
                    else:
                        sub_search = search2
                elif local_table:
                    overall_search.add_keyword_filter(column, keywords_list, table=table, column_type=column_type, op=partial_op)
                else:
                    search.add_keyword_filter(column, keywords_list, table=table, column_type=column_type, op=partial_op)
                    overall_search.add_relationship_search_filter(search, op='in')
            if self.cross_db:
                sub_search_list.append(sub_search)
        if self.cross_db:
            rtn_history = False
            overall_search.add_op('begin')
            for sub_search in sub_search_list:
                rtn = overall_search.add_relationship_search_filter(sub_search, op='in', delay_null=True)
                if (rtn_history == False):
                    rtn_history = rtn
            if (not rtn_history):
                overall_search.set_null_filter()
            overall_search.add_op(multi_col_op)
        else:
            overall_search.add_op(multi_col_op)
    else:
        raise TacticException(('Mode [%s] in keyword search not support' % self.mode))