Missing entity test is failing because of how table names in the spec are parsed

Describe the bug

In the initial spec tests run when executing permifrost run or permifrost spec-test, tables explicitly defined in the spec that have names that are longer than one character are fed into the test one character at a time, resulting in erroneous failures and output that looks like this:

Checking that all entities in the spec file are defined in Snowflake
Missing Entity Error: Table/View d was not found on Snowflake Server. Please create it before continuing.
Missing Entity Error: Table/View b was not found on Snowflake Server. Please create it before continuing.
Missing Entity Error: Table/View 1 was not found on Snowflake Server. Please create it before continuing.
Missing Entity Error: Table/View . was not found on Snowflake Server. Please create it before continuing.
Missing Entity Error: Table/View s was not found on Snowflake Server. Please create it before continuing.
Missing Entity Error: Table/View c was not found on Snowflake Server. Please create it before continuing.
Missing Entity Error: Table/View h was not found on Snowflake Server. Please create it before continuing.
Missing Entity Error: Table/View e was not found on Snowflake Server. Please create it before continuing.
Missing Entity Error: Table/View m was not found on Snowflake Server. Please create it before continuing.
Missing Entity Error: Table/View a was not found on Snowflake Server. Please create it before continuing.
Missing Entity Error: Table/View 1 was not found on Snowflake Server. Please create it before continuing.
Missing Entity Error: Table/View . was not found on Snowflake Server. Please create it before continuing.
Missing Entity Error: Table/View t was not found on Snowflake Server. Please create it before continuing.
Missing Entity Error: Table/View a was not found on Snowflake Server. Please create it before continuing.
Missing Entity Error: Table/View b was not found on Snowflake Server. Please create it before continuing.
Missing Entity Error: Table/View l was not found on Snowflake Server. Please create it before continuing.
Missing Entity Error: Table/View e was not found on Snowflake Server. Please create it before continuing.
Missing Entity Error: Table/View 1 was not found on Snowflake Server. Please create it before continuing.

Steps To Reproduce

Define a role with table-level permissions (containing an actual table name, no wildcards) on at least two tables from the same database, and then run permifrost run or permifrost spec-test.

Expected behavior

Expectation is that Permifrost will not output missing entity errors if the entity is not missing.

Screenshots and log output

If applicable, add screenshots or log output to help explain your problem.

The output of permifrost --version: This bug isn't in the current release of Permifrost. It only exists since commit 30cd41f6cd08bf56a6b62e1c349e049204c55348.

The operating system you're using: Mac OS

The output of python --version: Python 3.9.9

Additional context

The bug appears to have been introduced in !120 (merged), specifically here:

def group_table_by_database(self):
        tables_by_database = {}
        for table in self.entities["table_refs"]:
            db_name = table.split(".")[0]
            if db_name not in tables_by_database:
                tables_by_database[db_name] = [table]
            else:
                tables_by_database[db_name].extend(table)

Running [list].extend([string]) will result in Python considering the string to be an interable, and adding distinct items for each character in the string. See this example:

>>> tables_by_database={'db1':['table1']}
>>> db_name = 'db1'
>>> db_name not in tables_by_database
False
>>> table = 'table2'
>>> tables_by_database[db_name].extend(table)
>>> tables_by_database
{'db1': ['table1', 't', 'a', 'b', 'l', 'e', '2']}

Should be a fairly quick fix. In the fix we will also probably want to examine the test cases and see if there's anything to add there that would have helped catch this.

Edited by William Herrmann