diff --git a/sqllineage/core.py b/sqllineage/core.py
index 11ee47e..6c6c494 100644
--- a/sqllineage/core.py
+++ b/sqllineage/core.py
@@ -113,18 +113,23 @@ class LineageAnalyzer:
                 if self.__token_negligible_before_tablename(sub_token):
                     continue
                 else:
-                    if not isinstance(sub_token, Identifier):
+                    if isinstance(sub_token, Identifier):
+                        if isinstance(sub_token.token_first(skip_cm=True), Parenthesis):
+                            # SELECT col1 FROM (SELECT col2 FROM tab1) dt, the subquery will be parsed as Identifier
+                            # and this Identifier's get_real_name method would return alias name dt
+                            # referring https://github.com/andialbrecht/sqlparse/issues/218 for further information
+                            pass
+                        else:
+                            self._lineage_result.read.add(Table.create(sub_token))
+                    elif isinstance(sub_token, Parenthesis):
+                        # SELECT col1 FROM (SELECT col2 FROM tab1), the subquery will be parsed as Parenthesis
+                        # This syntax without alias for subquery is invalid in MySQL, while valid for SparkSQL
+                        pass
+                    else:
                         raise SQLLineageException(
                             "An Identifier is expected, got %s[value: %s] instead"
                             % (type(sub_token).__name__, sub_token)
                         )
-                    if isinstance(sub_token.token_first(skip_cm=True), Parenthesis):
-                        # SELECT col1 FROM (SELECT col2 FROM tab1) dt, the subquery will be parsed as Identifier
-                        # and this Identifier's get_real_name method would return alias name dt
-                        # referring https://github.com/andialbrecht/sqlparse/issues/218 for further information
-                        pass
-                    else:
-                        self._lineage_result.read.add(Table.create(sub_token))
                     source_table_token_flag = False
             elif target_table_token_flag:
                 if self.__token_negligible_before_tablename(sub_token):

subquery without alias raises exception
```
SELECT col1 FROM (SELECT col1 FROM tab1)
```

Subquery without alias name is valid syntax in SparkSQL. And this parsing result says: "An Identifier is expected, got Parenthesis[value: (select col1 from tab1)] instead".

Since we're not assuming any specific SQL dialect, we should support this.
diff --git a/tests/test_select.py b/tests/test_select.py
index 30d8ee3..bfbf552 100644
--- a/tests/test_select.py
+++ b/tests/test_select.py
@@ -63,7 +63,12 @@ def test_select_count():
 
 
 def test_select_subquery():
-    helper("SELECT col1 FROM (SELECT col2 FROM tab1) dt", {"tab1"})
+    helper("SELECT col1 FROM (SELECT col1 FROM tab1) dt", {"tab1"})
+
+
+def test_select_subquery_without_alias():
+    """this syntax is valid in SparkSQL, not for MySQL"""
+    helper("SELECT col1 FROM (SELECT col1 FROM tab1)", {"tab1"})
 
 
 def test_select_inner_join():

pip install -e .
parse_log_pytest
pytest
pytest pytest-cov flake8 bandit mypy tox codecov
apt-get update apt-get install -y gcc
3.8
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
bandit==1.7.10
cachetools==5.5.2
certifi==2025.1.31
chardet==5.2.0
charset-normalizer==3.4.1
codecov==2.1.13
colorama==0.4.6
coverage==7.6.1
distlib==0.3.9
exceptiongroup @ file:///croot/exceptiongroup_1706031385326/work
filelock==3.16.1
flake8==7.1.2
idna==3.10
iniconfig @ file:///home/linux1/recipes/ci/iniconfig_1610983019677/work
markdown-it-py==3.0.0
mccabe==0.7.0
mdurl==0.1.2
mypy==1.14.1
mypy-extensions==1.0.0
packaging==24.2
pbr==6.1.1
platformdirs==4.3.6
pluggy==1.5.0
pycodestyle==2.12.1
pyflakes==3.2.0
Pygments==2.19.1
pyproject-api==1.8.0
pytest @ file:///croot/pytest_1717793244625/work
pytest-cov==5.0.0
PyYAML==6.0.2
requests==2.32.3
rich==14.0.0
-e git+https://github.com/reata/sqllineage.git@54ae4fe7ed6ebae497e45f7c6afde6feb68ca4d9#egg=sqllineage
sqlparse==0.3.1
stevedore==5.3.0
tomli==2.2.1
tox==4.25.0
typing_extensions==4.13.0
urllib3==2.2.3
virtualenv==20.29.3

name: sqllineage
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - exceptiongroup=1.2.0=py38h06a4308_0
  - iniconfig=1.1.1=pyhd3eb1b0_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=3.0.16=h5eee18b_0
  - pip=24.2=py38h06a4308_0
  - pytest=7.4.4=py38h06a4308_0
  - python=3.8.20=he870216_0
  - readline=8.2=h5eee18b_0
  - setuptools=75.1.0=py38h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - wheel=0.44.0=py38h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - bandit==1.7.10
      - cachetools==5.5.2
      - certifi==2025.1.31
      - chardet==5.2.0
      - charset-normalizer==3.4.1
      - codecov==2.1.13
      - colorama==0.4.6
      - coverage==7.6.1
      - distlib==0.3.9
      - filelock==3.16.1
      - flake8==7.1.2
      - idna==3.10
      - markdown-it-py==3.0.0
      - mccabe==0.7.0
      - mdurl==0.1.2
      - mypy==1.14.1
      - mypy-extensions==1.0.0
      - packaging==24.2
      - pbr==6.1.1
      - platformdirs==4.3.6
      - pluggy==1.5.0
      - pycodestyle==2.12.1
      - pyflakes==3.2.0
      - pygments==2.19.1
      - pyproject-api==1.8.0
      - pytest-cov==5.0.0
      - pyyaml==6.0.2
      - requests==2.32.3
      - rich==14.0.0
      - sqlparse==0.3.1
      - stevedore==5.3.0
      - tomli==2.2.1
      - tox==4.25.0
      - typing-extensions==4.13.0
      - urllib3==2.2.3
      - virtualenv==20.29.3
prefix: /opt/conda/envs/sqllineage

tests/test_select.py::test_select_subquery_without_alias
tests/test_select.py::test_select tests/test_select.py::test_select_with_schema tests/test_select.py::test_select_multi_line tests/test_select.py::test_select_asterisk tests/test_select.py::test_select_value tests/test_select.py::test_select_function tests/test_select.py::test_select_with_where tests/test_select.py::test_select_with_comment tests/test_select.py::test_select_with_comment_after_from tests/test_select.py::test_select_with_comment_after_join tests/test_select.py::test_select_keyword_as_column_alias tests/test_select.py::test_select_with_table_alias tests/test_select.py::test_select_count tests/test_select.py::test_select_subquery tests/test_select.py::test_select_inner_join tests/test_select.py::test_select_join tests/test_select.py::test_select_left_join tests/test_select.py::test_select_left_join_with_extra_space_in_middle tests/test_select.py::test_select_left_semi_join tests/test_select.py::test_select_left_semi_join_with_on tests/test_select.py::test_select_right_join tests/test_select.py::test_select_full_outer_join tests/test_select.py::test_select_full_outer_join_with_full_as_alias tests/test_select.py::test_select_cross_join tests/test_select.py::test_select_cross_join_with_on tests/test_select.py::test_select_join_with_subquery tests/test_select.py::test_with_select
sqllineage/core.py
sqllineage/core.py