Skip to content

ANTLR grammar fails to parse tabular subquery on the right of in #194

Open

Description

The KQL docs mention that this is a valid expression:

StormEvents 
| where State in (
    StormEvents
    | summarize count() by State
    | top 5 by count_
    ) 
| count

https://learn.microsoft.com/en-us/kusto/query/in-cs-operator?view=azure-data-explorer#tabular-expression

The KQL ANTLR grammar in the repo fails to parse it:

line 5:4 mismatched input '|' expecting {')', ','}
line 7:4 mismatched input ')' expecting {<EOF>, ';'}

This seems to be due to this line in Kql.g4:

listEqualityExpression:
    Left=relationalExpression OperatorToken=(IN | NOT_IN | IN_CI | NOT_IN_CI | HAS_ANY | HAS_ALL) '(' Expressions+=invocationExpression (',' Expressions+=invocationExpression)* ')';

which may need to be replaced with something like this (extra pipeExpression):

listEqualityExpression:
      Left=relationalExpression OperatorToken=(IN | NOT_IN | IN_CI | NOT_IN_CI | HAS_ANY | HAS_ALL) '(' Subquery=pipeExpression ')'
    | Left=relationalExpression OperatorToken=(IN | NOT_IN | IN_CI | NOT_IN_CI | HAS_ANY | HAS_ALL) '(' Expressions+=invocationExpression (',' Expressions+=invocationExpression)* ')'
    ;

Full repro:

Activity

  1. mattwar commented on Aug 21, 2026

    @mattwar
    Contributor

    the KQL grammar file was recovered from an older antlr3 grammer file that was not as current as the actual parser. The current parser solves this with a bit of magic look-ahead.. Solving it by adding the extra alternate with the pipe expression might work, but it might also cause an ambiguity with anltr due to having two branches that could possibly parse the same input in some cases.

  2. mmaitre314 commented on Aug 21, 2026

    @mmaitre314
    Author

    Would there be some better solution? I could try a different patch in my project so see what that gives.

  3. mattwar commented on Aug 21, 2026

    @mattwar
    Contributor

    The the approach you already tried successfully built with antlr4 then that’s the correct solution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions