Repository: sqlfluff/sqlfluff

Issue:
Linting `CREATE TABLE` statement failed due to `KeyError: None` exception
*tl;dr* Running `lint` on a basic `CREATE TABLE` statement fails due to `KeyError: None` exception. Disabling L044 and L045 can mitigate the issue.

## Sample SQL
```
CREATE TABLE my_table (
  id INTEGER
);
```

## Expected Behaviour
Linting should pass, as it's a simple `CREATE TABLE` statement.

## Observed Behaviour
L044 and L045 failed due to `KeyError: None` exception.

## Steps to Reproduce
1. Checkout & run `sqlfluff` based on `origin/master`
2. Create a file with the `CREATE TABLE` statement below.
3. Run `python src/sqlfluff lint <path_to_file.sql`

### Note
* Public release 0.4.1 works. It only fails on the `master` branch.

## Console Output
### `parse`
```
(.venv) ~/code/sqlfluff (master) $ python src/sqlfluff parse sample.sql
[0](1, 1, 1)        |file:
[0](1, 1, 1)        |    statement:
[0](1, 1, 1)        |        create_table_statement:
[0](1, 1, 1)        |            keyword:                                          'CREATE'
[6](1, 1, 7)        |            whitespace:                                       ' '
[7](1, 1, 8)        |            keyword:                                          'TABLE'
[12](1, 1, 13)      |            whitespace:                                       ' '
[13](1, 1, 14)      |            table_reference:
[13](1, 1, 14)      |                identifier:                                   'my_table'
[21](1, 1, 22)      |            whitespace:                                       ' '
[22](1, 1, 23)      |            start_bracket:                                    '('
[23](1, 1, 24)      |            [META] indent:
[23](1, 1, 24)      |            newline:                                          '\n'
[24](1, 2, 1)       |            whitespace:                                       '  '
[26](1, 2, 3)       |            column_definition:
[26](1, 2, 3)       |                identifier:                                   'id'
[28](1, 2, 5)       |                whitespace:                                   ' '
[29](1, 2, 6)       |                data_type:
[29](1, 2, 6)       |                    data_type_identifier:                     'INTEGER'
[36](1, 2, 13)      |            newline:                                          '\n'
[37](1, 3, 1)       |            [META] dedent:
[37](1, 3, 1)       |            end_bracket:                                      ')'
[38](1, 3, 2)       |    statement_terminator:                                     ';'
[39](1, 3, 3)       |    newline:                                                  '\n'
```

### `lint`
```
(.venv) ~/code/sqlfluff (master) $ python src/sqlfluff lint sample.sql
CRITICAL   [L044] Applying rule L044 threw an Exception: None
Traceback (most recent call last):
  File "/Users/kennywong/code/sqlfluff/src/sqlfluff/core/rules/base.py", line 284, in crawl
    res = self._eval(
  File "/Users/kennywong/code/sqlfluff/src/sqlfluff/core/rules/std/L044.py", line 135, in _eval
    select_info = queries[None]
KeyError: None
CRITICAL   [L045] Applying rule L045 threw an Exception: None
Traceback (most recent call last):
  File "/Users/kennywong/code/sqlfluff/src/sqlfluff/core/rules/base.py", line 284, in crawl
    res = self._eval(
  File "/Users/kennywong/code/sqlfluff/src/sqlfluff/core/rules/std/L045.py", line 70, in _eval
    self._visit_sources(queries.pop(None), dialect, queries)
KeyError: None
== [sample.sql] FAIL
L:   1 | P:   1 | L044 | Unexpected exception: None; Could you open an issue at
                       | https://github.com/sqlfluff/sqlfluff/issues ? You can
                       | ignore this exception for now, by adding '--noqa: L044'
                       | at the end of line 1
L:   1 | P:   1 | L045 | Unexpected exception: None; Could you open an issue at
                       | https://github.com/sqlfluff/sqlfluff/issues ? You can
                       | ignore this exception for now, by adding '--noqa: L045'
                       | at the end of line 1
L:   2 | P:   3 | L003 | Indentation not hanging or a multiple of 4 spaces
```

## Version
Please note that this works with `0.4.1` public release - It fails on `master` branch only.

FWIW, this is the output of `python src/sqlfluff --version`
```
(.venv) ~/code/sqlfluff (master) $ python src/sqlfluff --version
sqlfluff, version 0.4.1
```

## Configuration

Default - No customization.

Discussion:

Patch:
diff --git a/src/sqlfluff/core/rules/std/L044.py b/src/sqlfluff/core/rules/std/L044.py
index b504b5811..a136cb136 100644
--- a/src/sqlfluff/core/rules/std/L044.py
+++ b/src/sqlfluff/core/rules/std/L044.py
@@ -132,9 +132,12 @@ class Rule_L044(BaseRule):
             queries = SelectCrawler.gather(segment, dialect)
 
             # Begin analysis at the final, outer query (key=None).
-            select_info = queries[None]
-            try:
-                return self._analyze_result_columns(select_info, dialect, queries)
-            except RuleFailure:
-                return LintResult(anchor=queries[None][0].select_info.select_statement)
+            if None in queries:
+                select_info = queries[None]
+                try:
+                    return self._analyze_result_columns(select_info, dialect, queries)
+                except RuleFailure:
+                    return LintResult(
+                        anchor=queries[None][0].select_info.select_statement
+                    )
         return None
diff --git a/src/sqlfluff/core/rules/std/L045.py b/src/sqlfluff/core/rules/std/L045.py
index c7a3a7477..8c5700efc 100644
--- a/src/sqlfluff/core/rules/std/L045.py
+++ b/src/sqlfluff/core/rules/std/L045.py
@@ -65,9 +65,9 @@ class Rule_L045(BaseRule):
     def _eval(self, segment, dialect, **kwargs):
         if segment.is_type("statement"):
             queries = SelectCrawler.gather(segment, dialect)
-
-            # Begin analysis at the final, outer query (key=None).
-            self._visit_sources(queries.pop(None), dialect, queries)
-            if queries:
-                return LintResult(anchor=segment)
+            if None in queries:
+                # Begin analysis at the final, outer query (key=None).
+                self._visit_sources(queries.pop(None), dialect, queries)
+                if queries:
+                    return LintResult(anchor=segment)
         return None


Test patch:
diff --git a/test/fixtures/rules/std_rule_cases/L044.yml b/test/fixtures/rules/std_rule_cases/L044.yml
index 3ca762d9d..604e22634 100644
--- a/test/fixtures/rules/std_rule_cases/L044.yml
+++ b/test/fixtures/rules/std_rule_cases/L044.yml
@@ -285,3 +285,7 @@ test_30:
   configs:
     core:
       dialect: bigquery
+
+test_31:
+  # Issue 915: Crash on statements that don't have a SELECT
+  pass_str: CREATE TABLE my_table (id INTEGER)
diff --git a/test/fixtures/rules/std_rule_cases/L045.yml b/test/fixtures/rules/std_rule_cases/L045.yml
index 5ad8fa642..19a4af701 100644
--- a/test/fixtures/rules/std_rule_cases/L045.yml
+++ b/test/fixtures/rules/std_rule_cases/L045.yml
@@ -75,4 +75,8 @@ test_7:
       FROM cte1
     )
     SELECT *
-    FROM cte1
\ No newline at end of file
+    FROM cte1
+
+test_8:
+  # Issue 915: Crash on statements that don't have a SELECT
+  pass_str: CREATE TABLE my_table (id INTEGER)