Skip to content

Commit 5392e89

Browse files
kyleconroyclaude
andcommitted
Fix INTERVAL parsing to handle both embedded and separate units
Use different precedence based on the first token of the interval value: - String literals like '1 day' have embedded units, so use ADD_PREC to stop before arithmetic operators - Other expressions need arithmetic included before the unit, so use LOWEST precedence This fixes `interval '1 day' - interval '1 hour'` (two separate intervals) while still handling `INTERVAL number - 15 MONTH` correctly (arithmetic expression with separate unit). Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent caaaad4 commit 5392e89

File tree

1 file changed

+10
-3
lines changed

1 file changed

+10
-3
lines changed

parser/expression.go

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1718,9 +1718,16 @@ func (p *Parser) parseInterval() ast.Expression {
17181718
}
17191719
p.nextToken() // skip INTERVAL
17201720

1721-
// Use AND_PREC to stop before AND/OR operators, but still allow arithmetic operations
1722-
// This ensures INTERVAL '5 MINUTES' AND ... doesn't consume the AND
1723-
expr.Value = p.parseExpression(AND_PREC)
1721+
// Choose precedence based on the first token of the interval value:
1722+
// - String literals like '1 day' have embedded units, so use ADD_PREC to stop before
1723+
// arithmetic operators. This handles `interval '1 day' - interval '1 hour'` correctly.
1724+
// - Other expressions (identifiers, numbers) need arithmetic included before the unit.
1725+
// Use LOWEST so `INTERVAL number - 15 MONTH` parses value as `number - 15`.
1726+
prec := ADD_PREC
1727+
if !p.currentIs(token.STRING) {
1728+
prec = LOWEST
1729+
}
1730+
expr.Value = p.parseExpression(prec)
17241731

17251732
// Handle INTERVAL '2' AS n minute - where AS n is alias on the value
17261733
// Only consume AS if it's followed by an identifier AND that identifier is followed by an interval unit

0 commit comments

Comments
 (0)