Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ This finds tests with `explain_todo` entries in their metadata.

## Running Tests

Always run parser tests with a 10 second timeout:
Always run parser tests with a 30 second timeout:

```bash
go test ./parser/... -timeout 10s
go test ./parser/... -timeout 30s
```

The tests are very fast. If a test is timing out, it indicates a bug (likely an infinite loop in the parser).
The tests are fast but some test files have many statements. If a test is timing out, it may indicate a bug (likely an infinite loop in the parser).

## Checking for Newly Passing Explain Tests

Expand Down
25 changes: 15 additions & 10 deletions internal/explain/expressions.go
Original file line number Diff line number Diff line change
Expand Up @@ -412,21 +412,26 @@ func explainAliasedExpr(sb *strings.Builder, n *ast.AliasedExpr, depth int) {
Node(sb, e.Right, depth+2)
}
case *ast.UnaryExpr:
// When inside a Subquery context, negated numeric literals should be output as Literal Int64_-N
// Otherwise, output as Function negate
if inSubqueryContext && e.Op == "-" {
// Handle negated numeric literals - output as Literal instead of Function negate
// For integers, only do this in subquery context (ClickHouse behavior)
// For floats (especially inf/nan), always do this
if e.Op == "-" {
if lit, ok := e.Operand.(*ast.Literal); ok {
switch lit.Type {
case ast.LiteralInteger:
switch val := lit.Value.(type) {
case int64:
fmt.Fprintf(sb, "%sLiteral Int64_%d (alias %s)\n", indent, -val, n.Alias)
return
case uint64:
fmt.Fprintf(sb, "%sLiteral Int64_-%d (alias %s)\n", indent, val, n.Alias)
return
// Only convert to literal in subquery context
if inSubqueryContext {
switch val := lit.Value.(type) {
case int64:
fmt.Fprintf(sb, "%sLiteral Int64_%d (alias %s)\n", indent, -val, n.Alias)
return
case uint64:
fmt.Fprintf(sb, "%sLiteral Int64_-%d (alias %s)\n", indent, val, n.Alias)
return
}
}
case ast.LiteralFloat:
// Always convert negated floats to literals (especially for -inf, -nan)
val := lit.Value.(float64)
s := FormatFloat(-val)
fmt.Fprintf(sb, "%sLiteral Float64_%s (alias %s)\n", indent, s, n.Alias)
Expand Down