'search for a local synonym matching the given desired owner/name.
if desired_owner is None, attempts to locate a distinct owner.
returns the actual name, owner, dblink name, and synonym name if found.'

def _resolve_synonym(self, connection, desired_owner=None, desired_synonym=None, desired_table=None):

    q = 'SELECT    owner,    table_owner,    table_name,    db_link,    synonym_name    FROM    all_synonyms    WHERE    '
    clauses = []
    params = {}
    if desired_synonym:
        clauses.append('synonym_name    =    :synonym_name')
        params['synonym_name'] = desired_synonym
    if desired_owner:
        clauses.append('owner    =    :desired_owner')
        params['desired_owner'] = desired_owner
    if desired_table:
        clauses.append('table_name    =    :tname')
        params['tname'] = desired_table
    q += '    AND    '.join(clauses)
    result = connection.execute(sql.text(q), **params)
    if desired_owner:
        row = result.first()
        if row:
            return (row['table_name'], row['table_owner'], row['db_link'], row['synonym_name'])
        else:
            return (None, None, None, None)
    else:
        rows = result.fetchall()
        if (len(rows) > 1):
            raise AssertionError('There    are    multiple    tables    visible    to    the    schema,    you    must    specify    owner')
        elif (len(rows) == 1):
            row = rows[0]
            return (row['table_name'], row['table_owner'], row['db_link'], row['synonym_name'])
        else:
            return (None, None, None, None)
