From 111b35cffcfe44b16fbdd27507f165bafd52a2a1 Mon Sep 17 00:00:00 2001 From: Osamaali313 Date: Wed, 22 Jul 2026 22:58:07 +0300 Subject: [PATCH] Fix function grouping skipped for lowercase 'as' in CREATE TABLE AS SELECT group_functions compared `tmp_token.value == 'AS'` case-sensitively, while the sibling CREATE and TABLE checks in the same loop use `.value.upper()`. SQL keywords are case-insensitive, so a lowercase `as` in a CREATE TABLE ... AS SELECT statement left `has_as` False, tripping the guard and skipping all function grouping for that statement (e.g. `count(x)` in the SELECT body was returned as a bare Identifier + Parenthesis instead of a Function). Compare case-insensitively, matching the sibling checks. --- CHANGELOG | 2 ++ sqlparse/engine/grouping.py | 2 +- tests/test_grouping.py | 8 ++++++++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index edfedb4f..453420fd 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -33,6 +33,8 @@ Bug Fixes * Fix statement splitting (issue845). * Fix a late-binding closure bug in `TokenList.token_not_matching`. +* Fix function grouping being skipped in ``CREATE TABLE ... AS SELECT`` + statements when the ``as`` keyword is lowercase. Release 0.5.5 (Dec 19, 2025) diff --git a/sqlparse/engine/grouping.py b/sqlparse/engine/grouping.py index e04c2a9e..a8300918 100644 --- a/sqlparse/engine/grouping.py +++ b/sqlparse/engine/grouping.py @@ -381,7 +381,7 @@ def group_functions(tlist): has_create = True if tmp_token.value.upper() == 'TABLE': has_table = True - if tmp_token.value == 'AS': + if tmp_token.value.upper() == 'AS': has_as = True if has_create and has_table and not has_as: return diff --git a/tests/test_grouping.py b/tests/test_grouping.py index bf278817..20fab9b7 100644 --- a/tests/test_grouping.py +++ b/tests/test_grouping.py @@ -344,6 +344,14 @@ def test_grouping_alias_ctas(): assert p.tokens[10].get_alias() == 'col1' assert isinstance(p.tokens[10].tokens[0], sql.Function) + +def test_grouping_alias_ctas_lowercase_as(): + # 'as' is case-insensitive; a lowercase keyword in CREATE TABLE ... AS + # SELECT must not disable function grouping in the SELECT body. + p = sqlparse.parse('create table tbl1 as select coalesce(t1.col1, 0) as col1 from t1')[0] + assert p.tokens[10].get_alias() == 'col1' + assert isinstance(p.tokens[10].tokens[0], sql.Function) + def test_grouping_subquery_no_parens(): # Not totally sure if this is the right approach... # When a THEN clause contains a subquery w/o parenthesis around it *and*