Repository: reata/sqllineage

Issue:
Missing target table with tsql parsing into statements with union
**Describe the bug**
* There is an issue with tsql parsing into statements with union, unable to obtain target

**SQL**
```sql
select * into t3 from t1 union all select * from t2
```

- `if` CLI (Command Line Interface): provide the command you're calling and the output. 
For example:
```shell
sqllineage -e 'select * into t3 from t1 union all select * from t2' -d tsql
```
```
Statements(#): 1
Source Tables:
    <default>.t2
    <default>.t3
Target Tables:
```

**Python version (available via `python --version`)**
 - 3.12.1

**SQLLineage version (available via `sqllineage --version`):**
 - 1.5.0



Discussion:

Patch:
diff --git a/sqllineage/core/parser/sqlfluff/extractors/select.py b/sqllineage/core/parser/sqlfluff/extractors/select.py
index f19a3b0..beee03f 100644
--- a/sqllineage/core/parser/sqlfluff/extractors/select.py
+++ b/sqllineage/core/parser/sqlfluff/extractors/select.py
@@ -59,12 +59,7 @@ class SelectExtractor(BaseExtractor, SourceHandlerMixin):
         self.extract_subquery(subqueries, holder)
 
         for segment in segments:
-            self._handle_swap_partition(segment, holder)
-            self._handle_select_into(segment, holder)
-            self.tables.extend(
-                self._list_table_from_from_clause_or_join_clause(segment, holder)
-            )
-            self._handle_column(segment)
+            self._handle_select_statement_child_segments(segment, holder)
 
             if is_set_expression(segment):
                 for idx, sub_segment in enumerate(
@@ -75,12 +70,7 @@ class SelectExtractor(BaseExtractor, SourceHandlerMixin):
                             (len(self.columns), len(self.tables))
                         )
                     for seg in list_child_segments(sub_segment):
-                        self.tables.extend(
-                            self._list_table_from_from_clause_or_join_clause(
-                                seg, holder
-                            )
-                        )
-                        self._handle_column(seg)
+                        self._handle_select_statement_child_segments(seg, holder)
 
         self.end_of_query_cleanup(holder)
 
@@ -88,6 +78,16 @@ class SelectExtractor(BaseExtractor, SourceHandlerMixin):
 
         return holder
 
+    def _handle_select_statement_child_segments(
+        self, segment: BaseSegment, holder: SubQueryLineageHolder
+    ):
+        self._handle_swap_partition(segment, holder)
+        self._handle_select_into(segment, holder)
+        self.tables.extend(
+            self._list_table_from_from_clause_or_join_clause(segment, holder)
+        )
+        self._handle_column(segment)
+
     @staticmethod
     def _handle_swap_partition(segment: BaseSegment, holder: SubQueryLineageHolder):
         """


Test patch:
diff --git a/tests/sql/table/test_select_dialect_specific.py b/tests/sql/table/test_select_dialect_specific.py
index 8d2f282..14aefc6 100644
--- a/tests/sql/table/test_select_dialect_specific.py
+++ b/tests/sql/table/test_select_dialect_specific.py
@@ -60,6 +60,14 @@ def test_select_into(dialect: str):
     assert_table_lineage_equal(sql, {"films"}, {"films_recent"}, dialect=dialect)
 
 
+@pytest.mark.parametrize("dialect", ["postgres", "tsql"])
+def test_select_into_with_union(dialect: str):
+    sql = "SELECT * INTO films_all FROM films UNION ALL SELECT * FROM films_backup"
+    assert_table_lineage_equal(
+        sql, {"films", "films_backup"}, {"films_all"}, dialect=dialect
+    )
+
+
 @pytest.mark.parametrize("dialect", ["athena"])
 def test_select_from_unnest_with_ordinality(dialect: str):
     """