Repository: sqlfluff/sqlfluff

Issue:
L019 (trailing vs leading commas) fix doesn't flow around inline comments 
## Expected Behaviour

Inline comments should be taken into consideration when fixing leading to trailing

## Observed Behaviour

The fix incorrectly places a comma _after_ the inline comment, instead of after the field and _before_ the comment

## Steps to Reproduce

`test.sql`
```sql
select
    field_1,
    field_2 -- some comment,
    field_3
from my_table
```

```
$ sqlfluff fix test.sql
==== finding fixable violations ====
== [test_sql.sql] FAIL
L:   3 | P:   5 | L019 | Found leading comma. Expected only trailing.
L:   4 | P:   5 | L019 | Found leading comma. Expected only trailing.
==== fixing violations ====
2 fixable linting violations found
Are you sure you wish to attempt to fix these? [Y/n] ...
Attempting fixes...
Persisting Changes...
== [test_sql.sql] PASS
Done. Please check your files to confirm.
```

fixed `test.sql`
```sql
select
    field_1,
    field_2 -- some comment,
    field_3
from my_table
```


## Version
Include the output of `sqlfluff --version` along with your Python version
sqlfluff, version 0.4.0
Python 3.8.6
## Configuration

None


This one is on me 🤦🏻 I didn't consider this test case. I'll submit a PR with a failing test case soon

Discussion:

Patch:
diff --git a/src/sqlfluff/core/rules/std/L019.py b/src/sqlfluff/core/rules/std/L019.py
index e3cc8688c..5fff29cd9 100644
--- a/src/sqlfluff/core/rules/std/L019.py
+++ b/src/sqlfluff/core/rules/std/L019.py
@@ -52,6 +52,17 @@ class Rule_L019(BaseRule):
 
     config_keywords = ["comma_style"]
 
+    @staticmethod
+    def _last_comment_seg(raw_stack):
+        """Trace the raw stack back to the most recent comment segment.
+
+        A return value of `None` indicates no code segments preceding the current position.
+        """
+        for segment in raw_stack[::-1]:
+            if segment.is_comment:
+                return segment
+        return None
+
     @staticmethod
     def _last_code_seg(raw_stack):
         """Trace the raw stack back to the most recent code segment.
@@ -107,7 +118,18 @@ class Rule_L019(BaseRule):
                 if last_seg.is_type("newline"):
                     # Recorded where the fix should be applied
                     memory["last_leading_comma_seg"] = segment
-                    memory["anchor_for_new_trailing_comma_seg"] = last_seg
+                    last_comment_seg = self._last_comment_seg(raw_stack)
+                    inline_comment = (
+                        last_comment_seg.pos_marker.line_no
+                        == last_seg.pos_marker.line_no
+                        if last_comment_seg
+                        else False
+                    )
+                    # If we have a comment right before the newline, then anchor
+                    # the fix at the comment instead
+                    memory["anchor_for_new_trailing_comma_seg"] = (
+                        last_seg if not inline_comment else last_comment_seg
+                    )
                     # Trigger fix routine
                     memory["insert_trailing_comma"] = True
                     memory["whitespace_deletions"] = []


Test patch:
diff --git a/test/fixtures/rules/std_rule_cases/L019.yml b/test/fixtures/rules/std_rule_cases/L019.yml
index 44a934d4b..98e688fa3 100644
--- a/test/fixtures/rules/std_rule_cases/L019.yml
+++ b/test/fixtures/rules/std_rule_cases/L019.yml
@@ -12,6 +12,24 @@ leading_comma_violations:
       b
     FROM c
 
+leading_comma_violation_with_inline_comment:
+  fail_str: |
+    SELECT
+        a
+        , b -- inline comment
+        , c
+        /* non inline comment */
+        , d
+    FROM e
+  fix_str: |
+    SELECT
+        a,
+        b ,-- inline comment
+        c,
+        /* non inline comment */
+        d
+    FROM e
+
 leading_commas_allowed:
   pass_str: |
     SELECT