Skip to content

ast/formatter: NOT EXISTS (subquery) renders as NOT (EXISTS (...) NOT ), which does not re-parse #601

Closed

Description

@ajitpratap0

Summary

The parser represents NOT EXISTS (subquery) as a BinaryExpression{Operator: "NOT", Not: true, Left: ExistsExpression, Right: nil}. BinaryExpression.writeSQL has no case for this unary-NOT shape. It falls into the generic Not branch and emits NOT (<left> NOT <nil>). ast.SQL(), pkg/formatter (compact and readable) and formatter.FormatString therefore all produce SQL that fails to parse.

Reproduction

tree, _ := gosqlx.Parse("SELECT * FROM t WHERE NOT EXISTS (SELECT 1 FROM u)")
fmt.Println(tree.SQL())
fmt.Println(formatter.FormatAST(tree, ast.CompactStyle()))

Actual (main 61ca6c8):

SELECT * FROM t WHERE NOT (EXISTS (SELECT 1 FROM u) NOT )

Re-parsing fails with Error E2002 at line 1, column 53: expected ), got NOT. formatter.FormatString gives SELECT *\nFROM t\nWHERE NOT (EXISTS (SELECT 1 FROM u) NOT );, which fails the same way. The same happens inside larger predicates (... NOT EXISTS (...) AND a = 1).

Expected: SELECT * FROM t WHERE NOT EXISTS (SELECT 1 FROM u).

Notes

Found during review of #591.

Metadata

Metadata

Assignees

No one assigned

    Labels

    astAST node changesbugSomething isn't workingformatter

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions