def get_sql_sources(sql_text, echo=False):
    'Obtain the source tables of a query\n  '
    import sqlparse
    sql_text = re.sub('as\\(', 'as (', sql_text, 0, (re.MULTILINE | re.IGNORECASE))
    statements = sqlparse.parse(sql_text)
    cte_aliases = set()
    sql_sources = {}

    def get_sources(statement):
        sources_dict = {}
        last_kw_from = False
        last_kw_join = False
        cte_mode = False
        last_tok = None
        done = False
        while (not done):
            for tok in statement.tokens:
                if tok.is_group:
                    if (cte_mode and isinstance(tok, sqlparse.sql.IdentifierList)):
                        for tok2 in tok.tokens:
                            if isinstance(tok2, sqlparse.sql.Identifier):
                                for tok3 in tok2.tokens:
                                    if isinstance(tok3, sqlparse.sql.Parenthesis):
                                        cte_aliases.add(tok3.parent.normalized.lower())
                                        sources_dict2 = get_sources(tok3)
                                        sources_dict = {**sources_dict, **sources_dict2}
                    elif isinstance(tok, sqlparse.sql.Parenthesis):
                        sources_dict2 = get_sources(tok)
                        sources_dict = {**sources_dict, **sources_dict2}
                    else:
                        for tok2 in tok.tokens:
                            if isinstance(tok2, sqlparse.sql.Parenthesis):
                                cte_aliases.add(tok2.parent.normalized.lower())
                                sources_dict2 = get_sources(tok2)
                                sources_dict = {**sources_dict, **sources_dict2}
                if ((last_kw_from or last_kw_join) and last_tok.is_whitespace):
                    if isinstance(tok, sqlparse.sql.IdentifierList):
                        for tok2 in tok.tokens:
                            if (isinstance(tok2, sqlparse.sql.Identifier) and ('(' in tok2.value)):
                                sources_dict2 = get_sources(tok2)
                                sources_dict = {**sources_dict, **sources_dict2}
                            elif (isinstance(tok2, sqlparse.sql.Identifier) and (tok2.normalized.lower() not in cte_aliases)):
                                if echo:
                                    log(('+Table = ' + tok2.normalized.lower()))
                                sources_dict[tok2.normalized.lower()] = tok.parent
                    elif (isinstance(tok, sqlparse.sql.Identifier) and (tok.normalized.lower() not in cte_aliases)):
                        if echo:
                            log(('+Table = ' + tok.normalized.lower()))
                        sources_dict[tok.normalized.lower()] = tok.parent
                    last_kw_join = False
                if (tok.is_keyword and (tok.normalized == 'WITH')):
                    cte_mode = True
                    last_kw_from = False
                elif (tok.is_keyword and (tok.normalized == 'GROUP')):
                    last_kw_join = False
                    last_kw_from = False
                elif (tok.is_keyword and (tok.normalized == 'WHERE')):
                    last_kw_join = False
                    last_kw_from = False
                elif (tok.is_keyword and (tok.normalized == 'ORDER')):
                    last_kw_join = False
                    last_kw_from = False
                elif (tok.is_keyword and (tok.normalized == 'CREATE')):
                    cte_mode = True
                    last_kw_from = False
                elif (tok.is_keyword and (tok.normalized == 'SELECT')):
                    cte_mode = False
                    last_kw_from = False
                elif (tok.is_keyword and (tok.normalized == 'FROM')):
                    last_kw_from = True
                elif (tok.is_keyword and ('JOIN' in tok.normalized)):
                    last_kw_join = True
                last_tok = tok
            done = True
        return sources_dict
    for (s, statement) in enumerate(statements):
        has_from = False
        last_kw_create = False
        last_kw_create_table = False
        create_table = None
        for tok in statement.tokens:
            if (isinstance(tok, sqlparse.sql.Identifier) and last_kw_create_table):
                create_table = tok.normalized
                last_kw_create_table = False
                last_kw_create = False
                if echo:
                    log(('-CREATE TABLE ' + create_table))
            if (tok.is_keyword and (tok.normalized == 'TABLE') and last_kw_create):
                last_kw_create_table = True
            if (tok.is_keyword and (tok.normalized == 'CREATE')):
                last_kw_create = True
            if (tok.is_keyword and (tok.normalized == 'FROM')):
                has_from = True
            last_tok = tok
        if has_from:
            sources_dict = get_sources(statement)
            if create_table:
                sql_sources[create_table] = sorted(sources_dict)
            else:
                sql_sources[s] = sorted(sources_dict)
    return sql_sources
Obtain the source tables of a query
def get_sql_sources(sql_text, echo=False):
    '\n  '
    import sqlparse
    sql_text = re.sub('as\\(', 'as (', sql_text, 0, (re.MULTILINE | re.IGNORECASE))
    statements = sqlparse.parse(sql_text)
    cte_aliases = set()
    sql_sources = {}

    def get_sources(statement):
        sources_dict = {}
        last_kw_from = False
        last_kw_join = False
        cte_mode = False
        last_tok = None
        done = False
        while (not done):
            for tok in statement.tokens:
                if tok.is_group:
                    if (cte_mode and isinstance(tok, sqlparse.sql.IdentifierList)):
                        for tok2 in tok.tokens:
                            if isinstance(tok2, sqlparse.sql.Identifier):
                                for tok3 in tok2.tokens:
                                    if isinstance(tok3, sqlparse.sql.Parenthesis):
                                        cte_aliases.add(tok3.parent.normalized.lower())
                                        sources_dict2 = get_sources(tok3)
                                        sources_dict = {**sources_dict, **sources_dict2}
                    elif isinstance(tok, sqlparse.sql.Parenthesis):
                        sources_dict2 = get_sources(tok)
                        sources_dict = {**sources_dict, **sources_dict2}
                    else:
                        for tok2 in tok.tokens:
                            if isinstance(tok2, sqlparse.sql.Parenthesis):
                                cte_aliases.add(tok2.parent.normalized.lower())
                                sources_dict2 = get_sources(tok2)
                                sources_dict = {**sources_dict, **sources_dict2}
                if ((last_kw_from or last_kw_join) and last_tok.is_whitespace):
                    if isinstance(tok, sqlparse.sql.IdentifierList):
                        for tok2 in tok.tokens:
                            if (isinstance(tok2, sqlparse.sql.Identifier) and ('(' in tok2.value)):
                                sources_dict2 = get_sources(tok2)
                                sources_dict = {**sources_dict, **sources_dict2}
                            elif (isinstance(tok2, sqlparse.sql.Identifier) and (tok2.normalized.lower() not in cte_aliases)):
                                if echo:
                                    log(('+Table = ' + tok2.normalized.lower()))
                                sources_dict[tok2.normalized.lower()] = tok.parent
                    elif (isinstance(tok, sqlparse.sql.Identifier) and (tok.normalized.lower() not in cte_aliases)):
                        if echo:
                            log(('+Table = ' + tok.normalized.lower()))
                        sources_dict[tok.normalized.lower()] = tok.parent
                    last_kw_join = False
                if (tok.is_keyword and (tok.normalized == 'WITH')):
                    cte_mode = True
                    last_kw_from = False
                elif (tok.is_keyword and (tok.normalized == 'GROUP')):
                    last_kw_join = False
                    last_kw_from = False
                elif (tok.is_keyword and (tok.normalized == 'WHERE')):
                    last_kw_join = False
                    last_kw_from = False
                elif (tok.is_keyword and (tok.normalized == 'ORDER')):
                    last_kw_join = False
                    last_kw_from = False
                elif (tok.is_keyword and (tok.normalized == 'CREATE')):
                    cte_mode = True
                    last_kw_from = False
                elif (tok.is_keyword and (tok.normalized == 'SELECT')):
                    cte_mode = False
                    last_kw_from = False
                elif (tok.is_keyword and (tok.normalized == 'FROM')):
                    last_kw_from = True
                elif (tok.is_keyword and ('JOIN' in tok.normalized)):
                    last_kw_join = True
                last_tok = tok
            done = True
        return sources_dict
    for (s, statement) in enumerate(statements):
        has_from = False
        last_kw_create = False
        last_kw_create_table = False
        create_table = None
        for tok in statement.tokens:
            if (isinstance(tok, sqlparse.sql.Identifier) and last_kw_create_table):
                create_table = tok.normalized
                last_kw_create_table = False
                last_kw_create = False
                if echo:
                    log(('-CREATE TABLE ' + create_table))
            if (tok.is_keyword and (tok.normalized == 'TABLE') and last_kw_create):
                last_kw_create_table = True
            if (tok.is_keyword and (tok.normalized == 'CREATE')):
                last_kw_create = True
            if (tok.is_keyword and (tok.normalized == 'FROM')):
                has_from = True
            last_tok = tok
        if has_from:
            sources_dict = get_sources(statement)
            if create_table:
                sql_sources[create_table] = sorted(sources_dict)
            else:
                sql_sources[s] = sorted(sources_dict)
    return sql_sources