fix: keep RENAME TABLE clauses as separate identifiers (issue779)

RENAME TABLE a TO b, c TO d grouped the target of the first clause and
the source of the second into a single IdentifierList, because the comma
between the two clauses was treated as an identifier-list separator.

Detect the rename layout by the TO keywords flanking both sides of the
comma and leave such a comma ungrouped, so each renamed table stays a
separate Identifier. Genuine target lists such as GRANT ... TO a, b are
left untouched.
This commit is contained in:
dualfroz committed 2026-09-02 11:37:41 +02:00
1 parent 95c0c262cf
commit 241869a841
2 files changed
+46 -1

No files matched your search

+22 -1
View File
@@ -309,13 +309,34 @@ def group_operator(tlist):
def group_identifier_list(tlist):
m_role = T.Keyword, ('null', 'role')
m_to = T.Keyword, 'TO'
sqlcls = (sql.Function, sql.Case, sql.Identifier, sql.Comparison,
sql.IdentifierList, sql.Operation)
ttypes = (T_NUMERICAL + T_STRING + T_NAME
+ (T.Keyword, T.Comment, T.Wildcard))
def is_rename_separator(token):
# In ``RENAME TABLE a TO b, c TO d`` the comma separates independent
# rename clauses, so the target of one clause (``b``) and the source
# of the next (``c``) must not be merged into a single IdentifierList.
# Detect that layout by the ``TO`` keywords flanking both sides of the
# comma and leave such a comma ungrouped (issue779).
parent = token.parent
if parent is None:
return False
cidx = parent.token_index(token)
pidx, prev_ = parent.token_prev(cidx)
nidx, next_ = parent.token_next(cidx)
if prev_ is None or next_ is None:
return False
_, before_prev = parent.token_prev(pidx)
_, after_next = parent.token_next(nidx)
return (before_prev is not None and before_prev.match(*m_to)
and after_next is not None and after_next.match(*m_to))
def match(token):
return token.match(T.Punctuation, ',')
return token.match(T.Punctuation, ',') \
and not is_rename_separator(token)
def valid(token):
return imt(token, i=sqlcls, m=m_role, t=ttypes)