Skip to content

Parser: Cannot parse COUNT(CASE WHEN x NOT NULL THEN 1 END) #1920

Open
@ryanschneider

Description

@ryanschneider

I'm not sure if this is generally accepted SQL syntax but duckdb supports it:

> duckdb
DuckDB v1.3.0 (Ossivalis) 71c5c07cdd
Enter ".help" for usage hints.
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database.
> WITH t AS (SELECT NULL as x) SELECT COUNT(CASE WHEN x NOT NULL THEN 1 END) AS x FROM t;
┌───────┐
│   x   │
│ int64 │
├───────┤
│   0   │
└───────┘
>

However the parser rejects it:

#[test]
fn test_duckdb_case() {
    let real_sql = r#"WITH t AS (SELECT NULL as x) SELECT COUNT(CASE WHEN x NOT NULL THEN 1 END) AS x FROM t"#;
    assert_eq!(duckdb().verified_stmt(real_sql).to_string(), real_sql);
}

This fails w/ WITH t AS (SELECT NULL as x) SELECT COUNT(CASE WHEN x NOT NULL THEN 1 END) AS x FROM t: ParserError("Expected: ), found: WHEN")

I've tried stepping through myself and got as far as looking at parse_case_expr and it's failing here:

        llet mut conditions = vec![];
        loop {
            let condition = self.parse_expr()?;
            self.expect_keyword_is(Keyword::THEN)?;   <-- fails here
            let result = self.parse_expr()?;
            conditions.push(CaseWhen { condition, result });
            if !self.parse_keyword(Keyword::WHEN) {
                break;
            }
        }

At that point, condition is just the Expr x and conditions is still empty, it still needs to parse NOT NULL before expecting the THEN keyword, but I'm not sure what the fix is.

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