Skip to content

Oracle dialect: KEEP (DENSE_RANK FIRST|LAST ORDER BY ...) on aggregate functions is unparsable and produces a spurious AL02 violation #8192

Description

@Ollec

Search before asking

  • I searched the issues and found no similar issues.

What Happened

Oracle's KEEP (DENSE_RANK FIRST|LAST ORDER BY ...) clause on aggregate functions (MIN, MAX, SUM, AVG, COUNT, VARIANCE, STDDEV) isn't recognized by the oracle dialect grammar. The parser falls back to treating the bare word KEEP as an implicit alias for the aggregate call, then treats everything from the following ( onward as an unparsable section; including any legitimate, already-explicit AS alias that appears later in that same clause. The knock-on effect: rule AL02 (require explicit column aliasing) fires on the phantom KEEP alias, even when the actual column alias is written correctly with AS.

oracle parser errors · Issue #7313 · sqlfluff/sqlfluff (unrelated/closed - confirms no existing umbrella issue covers this)

Expected Behaviour

The KEEP (DENSE_RANK FIRST|LAST ORDER BY ...) clause should parse as part of the aggregate function expression (see Oracle's docs below), and AL02 should not fire when an explicit AS is present.

FIRST/LAST Aggregate Functions — Oracle SQL Language Reference 19c

Observed Behaviour

$ sqlfluff parse --dialect oracle repro.sql

select_clause_element:
    function:
        function_name: MAX
        function_contents: (salary)
    alias_expression:
        naked_identifier: 'KEEP'          <-- phantom alias hallucinated from the KEEP keyword
unparsable:                                <-- everything else, including the real "AS best_salary", is dropped here
    (DENSE_RANK LAST ORDER BY commission_pct) AS best_salary

$ sqlfluff lint --dialect oracle --rules AL02 repro.sql
L: 2 | P: 20 | AL02 | Implicit/explicit aliasing of columns. [aliasing.column]

How to reproduce

SELECT department_id,
       MAX(salary) KEEP (DENSE_RANK LAST ORDER BY commission_pct) AS best_salary
  FROM employees
  GROUP BY department_id;

(This is Oracle's own canonical example for the clause, per their SQL Language Reference — see below.)

sqlfluff lint --dialect oracle --rules AL02 repro.sql

FIRST/LAST Aggregate Functions — Oracle SQL Language Reference 19c

Dialect

oracle

Version

sqlfluff, version 4.0.4 (Python 3.12.3)

Configuration

[sqlfluff]
dialect = oracle
rules = AL02

Are you willing to work on and submit a PR to address the issue?

  • Yes I am willing to submit a PR!

Code of Conduct

Activity

  1. adhavan18 commented on Jul 22, 2026

    @adhavan18
    Contributor

    This looks already fixed on main — #7950 ("Support Oracle KEEP (DENSE_RANK ... FIRST/LAST ...) syntax", merged 2026-06-14) landed after the 4.2.2 release (2026-06-04), so it isn't in any released version yet.

    Verified against current main with your exact repro:

    • sqlfluff parse --dialect oracle produces a proper keep_clause node attached to the aggregate (no phantom KEEP alias, no unparsable section, the AS best_salary alias parses correctly), and
    • sqlfluff lint --rules AL02 reports no violations.

    So this should resolve on its own with the next release; until then running from main works.

  2. Ollec commented on Jul 22, 2026

    @Ollec
    Author

    Fantastic! Sorry I missed the existing issue. Thank you for the response!

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

    bugSomething isn't workingoracle

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions