antlr / grammars-v4

Grammars written for ANTLR v4; expectation that the grammars are free of actions.
MIT License
10.19k stars 3.71k forks source link

PL/SQL: support COUNT(*) in PIVOT elements #3823

Closed danlyons-home closed 7 months ago

danlyons-home commented 11 months ago

I ran into some parse failures with a query including a PIVOT using COUNT(*). I can reproduce it with the following simplistic query against v$session:

WITH SessionCTE AS
(
    SELECT
        terminal
    FROM v$session
)
SELECT
    *
FROM SessionCTE
PIVOT
(
    COUNT(*) FOR terminal IN ('VIRTUALORACLE11' AS oracle_local, 'DRUID' AS druid, 'THOR' AS thor)
)
which executes successfully on my ancient 11.2.0.1 Oracle test instance: ORACLE_LOCAL DRUID THOR
23 2 2

For reference: Oracle pivot_clause documentation

The current parser definition for pivot_element is as follows: https://github.com/antlr/grammars-v4/blob/d939aad7310b6a214d6ade30afc90eb28f9fe809/sql/plsql/PlSqlParser.g4#L5735-L5737

At a glance, it looks like it should work with COUNT(*), but it fails with the following: Exception:

Antlr4.Runtime.InputMismatchException: Exception of type 'Antlr4.Runtime.InputMismatchException' was thrown.
   at Antlr4.Runtime.DefaultErrorStrategy.Sync(Parser recognizer)
   at extracttables.Grammars.PlSqlParser.sql_script() in c:\repository\panther\src\database\code\build\extracttables\obj\Debug\PlSqlParser.cs:line 2311

Message: mismatched input '(' expecting {<EOF>, '/', ';'} Offending Symbol: mismatched input '(' expecting {<EOF>, '/', ';'} Line: 11 Character Position: 0

danlyons-home commented 11 months ago

For my immediate purposes, I switched pivot_element locally to the following:

pivot_element
---    : aggregate_function_name '(' expression ')' column_alias?
+++    : numeric_function column_alias?
    ;

referencing: https://github.com/antlr/grammars-v4/blob/d939aad7310b6a214d6ade30afc90eb28f9fe809/sql/plsql/PlSqlParser.g4#L6354-L6362

but I'm not sure that's quite correct.