Repository: sqlfluff/sqlfluff

Issue:
Query on non-table expression throws exception in L031
This query:
```sql
select *
from table(
    generator(
        rowcount=>10000
    )
)
```

Does not select from a table but the generator function

In this case rule L031 throws an exception
```
L:   4 | P:   5 | L031 | Unexpected exception: 'NoneType' object has no attribute 'raw'; Could you open an issue at
                       | https://github.com/sqlfluff/sqlfluff/issues ? You can ignore this exception for now, by adding
                       | '--noqa: L031' at the end of line 4
```

This is not Snowflake specific as this simple query:
```sql
select *
from values (1, 2, 3)
```

Returns the same error

Discussion:

Patch:
diff --git a/src/sqlfluff/core/rules/base.py b/src/sqlfluff/core/rules/base.py
index 0685c1b9e..2e7f98e2c 100644
--- a/src/sqlfluff/core/rules/base.py
+++ b/src/sqlfluff/core/rules/base.py
@@ -277,7 +277,7 @@ class BaseCrawler:
         # cause the user to get no results
         except Exception as e:
             self.logger.critical(
-                f"Applying rule {self.code} threw and Exception: {e}", exc_info=True
+                f"Applying rule {self.code} threw an Exception: {e}", exc_info=True
             )
             vs.append(
                 SQLLintError(
diff --git a/src/sqlfluff/core/rules/std.py b/src/sqlfluff/core/rules/std.py
index c1f61b63a..af4b3476d 100644
--- a/src/sqlfluff/core/rules/std.py
+++ b/src/sqlfluff/core/rules/std.py
@@ -3061,7 +3061,11 @@ class Rule_L031(BaseCrawler):
             table_ref = table_exp.get_child("object_reference")
 
             # If this is self-join - skip it
-            if base_table.raw == table_ref.raw and base_table != table_ref:
+            if (
+                base_table
+                and base_table.raw == table_ref.raw
+                and base_table != table_ref
+            ):
                 continue
 
             whitespace_ref = table_exp.get_child("whitespace")
@@ -3079,7 +3083,7 @@ class Rule_L031(BaseCrawler):
             # Find all references to alias in select clause
             for alias_with_column in select_clause.recursive_crawl("object_reference"):
                 used_alias_ref = alias_with_column.get_child("identifier")
-                if used_alias_ref.raw == alias_identifier_ref.raw:
+                if used_alias_ref and used_alias_ref.raw == alias_identifier_ref.raw:
                     ids_refs.append(used_alias_ref)
 
             # Find all references to alias in column references


Test patch:
diff --git a/test/core/rules/test_cases/L031.yml b/test/core/rules/test_cases/L031.yml
index 03cff7625..2ae39b268 100644
--- a/test/core/rules/test_cases/L031.yml
+++ b/test/core/rules/test_cases/L031.yml
@@ -77,3 +77,29 @@ test_4:
     JOIN customers on users.id = customers.user_id
     JOIN orders on users.id = orders.user_id
     order by o desc
+
+alias_single_char_identifiers:
+  pass_str: "select b from tbl as a"
+  pass_str: "select b from tbl"
+
+alias_with_wildcard_identifier:
+  fail_str: "select * from tbl as a"
+  fix_str: "select * from tbl"
+
+select_from_values:
+  pass_str: |
+    select *
+    from values(1, 2, 3)
+
+select_from_table_generator:
+  pass_str: |
+    select *
+    from table(
+        generator(
+            rowcount=>10000
+        )
+    )
+
+  configs:
+    core:
+      dialect: bigquery