Repository: sqlfluff/sqlfluff

Issue:
NoQaDirective line number affected by rendered Jinja2 trailing whitespace 
Jinja2 trailing whitespace causes `NoQaDirective`s to be instantiated with different line numbers compared to where they are defined in a SQL file. This can cause `--noqa` comments to be ignored and errors to be incorrectly reported when running `sqlfluff lint`.

I tried to dig around the code, but I'm still not too familiar with the internals of `sqlfluff`. It appears to me that `--noqa` comments are being extracted from a templated version of the SQL file (as they respect Jinja2 removing trailing whitespace), where as the lining is running on a non-templated version of the SQL file (or at least a version that does not respect Jinja2 removing trailing whitespace).

## Minimal SQL
```
{%- set a_var = ["1", "2"] -%}

SELECT
  this_is_just_a_very_long_line_for_demostration_purposes AS wow_thats_big, --noqa: L016
  this_is_not_so_big
FROM
  a_table
```

## Expected Behaviour
Running `sqlfluff lint` should ignore line 4 being too long, and not report a Rule L016 violation, because we have specified a `--noqa`.

## Observed Behaviour
Running `sqlfluff lint` reports a Rule L016 error in line 4, despite having a `--noqa` comment.

```
=== [ path: test.sql ] ===

== [test.sql] TEMPLATING
== [test.sql] PARSING
== [test.sql] LINTING
== [test.sql] FAIL
L:   4 | P:  89 | L016 | Line is too long
==== summary ====
files:             1 violations:        1
clean files:       0 unclean files:     1
avg per file:   1.00 unclean rate:   100%
status:         FAIL
```

Running in more verbose mode reveals that `NoQaDirective` is being instantiated with an incorrect `line_no`:
```
INFO       Parsed noqa directives from file: [NoQaDirective(line_no=2, rules=('L016',), action=None)]
```
`line_no` is set to 2 despite it being in line number 4 in the original file.

Re-adding the trailing whitespace to the Jinja2 block (e.g. using `{%- set a_var = ["1", "2"] %}` apparently fixes the issue:
```
INFO       Parsed noqa directives from file: [NoQaDirective(line_no=4, rules=('L016',), action=None)]
...
== [test.sql] PASS
==== summary ====
files:             1 violations:        0
clean files:       1 unclean files:     0
avg per file:   0.00 unclean rate:     0%
status:         PASS
```

But splitting the Jinja2 block into multiple lines causes the error to come back:
```
❯ cat test.sql
{%-
set a_var = ["1", "2"]
%}

SELECT
  this_is_just_a_very_long_line_for_demostration_purposes AS wow_thats_big, --noqa: L016
  this_is_not_so_big
FROM
  a_table
```
```
INFO       Parsed noqa directives from file: [NoQaDirective(line_no=4, rules=('L016',), action=None)]
...
== [test.sql] FAIL
L:   6 | P:  89 | L016 | Line is too long
==== summary ====
files:             1 violations:        1
clean files:       0 unclean files:     1
avg per file:   1.00 unclean rate:   100%
status:         FAIL
```

## Steps to Reproduce

1. Write some basic SQL with a Jinja2 variable definition at the top and making sure that one of your lines contains an error to be ignored
2. Add `-` to the Jinja2 block to remove trailing whitespace
3. Add a `--noqa` to the line that contains an error
4. Run `sqlfluff lint`

## Version
Include the output of `sqlfluff --version` along with your Python version
```
sqlfluff --version && python --version
sqlfluff, version 0.5.2
Python 3.8.7
```

## Configuration
```
❯ cat .sqlfluff
[sqlfluff]
templater = jinja

[sqlfluff:rules]
tab_space_size = 2
max_line_length = 85
```


Discussion:

Patch:
diff --git a/src/sqlfluff/core/linter.py b/src/sqlfluff/core/linter.py
index 6e82d2a49..7869c6cee 100644
--- a/src/sqlfluff/core/linter.py
+++ b/src/sqlfluff/core/linter.py
@@ -1043,7 +1043,9 @@ class Linter:
         """Extract ignore mask entries from a comment segment."""
         # Also trim any whitespace afterward
         comment_content = comment.raw_trimmed().strip()
-        result = cls.parse_noqa(comment_content, comment.pos_marker.line_no)
+        result = cls.parse_noqa(
+            comment_content, comment.pos_marker.source_pos_marker.line_no
+        )
         if isinstance(result, SQLParseError):
             result.segment = comment
         return result


Test patch:
diff --git a/test/core/linter_test.py b/test/core/linter_test.py
index c1b59dd58..3073dda45 100644
--- a/test/core/linter_test.py
+++ b/test/core/linter_test.py
@@ -501,6 +501,28 @@ def test_linter_noqa():
     assert {3, 6, 7, 8, 10, 12, 13, 14, 15, 18} == {v.line_no() for v in violations}
 
 
+def test_linter_noqa_with_templating():
+    """Similar to test_linter_noqa, but uses templating (Jinja)."""
+    lntr = Linter(
+        config=FluffConfig(
+            overrides={
+                "templater": "jinja",
+                "rules": "L016",
+            }
+        )
+    )
+    sql = """
+    {%- set a_var = ["1", "2"] -%}
+    SELECT
+      this_is_just_a_very_long_line_for_demonstration_purposes_of_a_bug_involving_templated_sql_files, --noqa: L016
+      this_is_not_so_big
+    FROM
+      a_table
+        """
+    result = lntr.lint_string(sql)
+    assert not result.get_violations()
+
+
 @pytest.mark.dbt
 def test__linter__skip_dbt_model_disabled(in_dbt_project_dir):  # noqa
     """Test that the linter skips disabled dbt models."""