The grammar structurally parses function_call (and cast_expression, window_function) inside the SQL portion. This works for most function arguments but breaks when the argument contains CASE...END, because END has no structural meaning to the parser — it gets consumed as a bare identifier, leaving the function call's ) unmatched.
import ggsql
v = ggsql.validate("""
SELECT COUNT(CASE WHEN status = 'Charged Off' THEN 1 END) AS n
FROM loans
VISUALISE n AS y DRAW bar
""")
print(v.valid())
# False
print(v.errors())
# [{'message': 'Parse error: Parse tree contains errors', 'location': None}]
These parse fine (CASE not inside function parens, or no CASE at all):
import ggsql
# CASE in select list (not inside function) — works
print(ggsql.validate("""
SELECT CASE WHEN grade = 'A' THEN 1 ELSE 0 END AS flag
FROM loans
VISUALISE flag AS y DRAW bar
""").valid())
# True
# Aggregate without CASE — works
print(ggsql.validate("""
SELECT COUNT(DISTINCT grade) AS n FROM loans
VISUALISE n AS y DRAW bar
""").valid())
# True
This isn't a request to parse more SQL — it's that the existing function_call rule rejects CASE...END as a valid position_arg. The same architectural pattern used for cast_expression (bracket the construct so its interior tokens don't leak) would fix it.
Conditional aggregation (COUNT(CASE WHEN...), SUM(CASE WHEN...)) is standard SQL-92 and the primary pattern for computing rates and proportions.
The grammar structurally parses
function_call(andcast_expression,window_function) inside the SQL portion. This works for most function arguments but breaks when the argument containsCASE...END, becauseENDhas no structural meaning to the parser — it gets consumed as a bare identifier, leaving the function call's)unmatched.These parse fine (CASE not inside function parens, or no CASE at all):
This isn't a request to parse more SQL — it's that the existing
function_callrule rejectsCASE...ENDas a validposition_arg. The same architectural pattern used forcast_expression(bracket the construct so its interior tokens don't leak) would fix it.Conditional aggregation (
COUNT(CASE WHEN...),SUM(CASE WHEN...)) is standard SQL-92 and the primary pattern for computing rates and proportions.