Skip to content

Commit 21bc015

Browse files
committed
Fix 23 todo tests: BETWEEN transformation and float literal parsing
- Transform NOT BETWEEN into or(less, greater) to match ClickHouse EXPLAIN output - Transform BETWEEN into and(greaterOrEquals, lessOrEquals) - Fix float literal parsing for trailing dot syntax (e.g., 1. is now Float64) - Update ast.json golden file for float literal change - Remove todo flag from 23 now-passing tests Fixed tests include polygon operations, geohash constants, decimal/float handling, and BETWEEN expression tests.
1 parent 40df19b commit 21bc015

26 files changed

Lines changed: 76 additions & 46 deletions

File tree

internal/explain/functions.go

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -229,17 +229,37 @@ func explainLikeExpr(sb *strings.Builder, n *ast.LikeExpr, indent string, depth
229229
}
230230

231231
func explainBetweenExpr(sb *strings.Builder, n *ast.BetweenExpr, indent string, depth int) {
232-
// BETWEEN is represented as Function and with two comparisons
233-
// But for explain, we can use a simpler form
234-
fnName := "between"
235232
if n.Not {
236-
fnName = "notBetween"
233+
// NOT BETWEEN is transformed to: expr < low OR expr > high
234+
// Represented as: Function or with two comparisons: less and greater
235+
fmt.Fprintf(sb, "%sFunction or (children %d)\n", indent, 1)
236+
fmt.Fprintf(sb, "%s ExpressionList (children %d)\n", indent, 2)
237+
// less(expr, low)
238+
fmt.Fprintf(sb, "%s Function less (children %d)\n", indent, 1)
239+
fmt.Fprintf(sb, "%s ExpressionList (children %d)\n", indent, 2)
240+
Node(sb, n.Expr, depth+4)
241+
Node(sb, n.Low, depth+4)
242+
// greater(expr, high)
243+
fmt.Fprintf(sb, "%s Function greater (children %d)\n", indent, 1)
244+
fmt.Fprintf(sb, "%s ExpressionList (children %d)\n", indent, 2)
245+
Node(sb, n.Expr, depth+4)
246+
Node(sb, n.High, depth+4)
247+
} else {
248+
// BETWEEN is represented as Function and with two comparisons
249+
// expr >= low AND expr <= high
250+
fmt.Fprintf(sb, "%sFunction and (children %d)\n", indent, 1)
251+
fmt.Fprintf(sb, "%s ExpressionList (children %d)\n", indent, 2)
252+
// greaterOrEquals(expr, low)
253+
fmt.Fprintf(sb, "%s Function greaterOrEquals (children %d)\n", indent, 1)
254+
fmt.Fprintf(sb, "%s ExpressionList (children %d)\n", indent, 2)
255+
Node(sb, n.Expr, depth+4)
256+
Node(sb, n.Low, depth+4)
257+
// lessOrEquals(expr, high)
258+
fmt.Fprintf(sb, "%s Function lessOrEquals (children %d)\n", indent, 1)
259+
fmt.Fprintf(sb, "%s ExpressionList (children %d)\n", indent, 2)
260+
Node(sb, n.Expr, depth+4)
261+
Node(sb, n.High, depth+4)
237262
}
238-
fmt.Fprintf(sb, "%sFunction %s (children %d)\n", indent, fnName, 1)
239-
fmt.Fprintf(sb, "%s ExpressionList (children %d)\n", indent, 3)
240-
Node(sb, n.Expr, depth+2)
241-
Node(sb, n.Low, depth+2)
242-
Node(sb, n.High, depth+2)
243263
}
244264

245265
func explainIsNullExpr(sb *strings.Builder, n *ast.IsNullExpr, indent string, depth int) {

lexer/lexer.go

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -594,16 +594,21 @@ func (l *Lexer) readNumber() Item {
594594
}
595595
}
596596

597-
// Check for decimal point
598-
if l.ch == '.' && unicode.IsDigit(l.peekChar()) {
599-
sb.WriteRune(l.ch)
600-
l.readChar()
601-
for unicode.IsDigit(l.ch) {
597+
// Check for decimal point (either followed by digit or end of number like 1.)
598+
if l.ch == '.' {
599+
nextCh := l.peekChar()
600+
// Allow 1. (trailing dot with no digits) and 1.5 (dot with digits)
601+
// But not 1.something (identifier-like)
602+
if unicode.IsDigit(nextCh) || (!isIdentStart(nextCh) && nextCh != '.') {
602603
sb.WriteRune(l.ch)
603604
l.readChar()
604-
// Handle underscore separators
605-
for l.ch == '_' && unicode.IsDigit(l.peekChar()) {
605+
for unicode.IsDigit(l.ch) {
606+
sb.WriteRune(l.ch)
606607
l.readChar()
608+
// Handle underscore separators
609+
for l.ch == '_' && unicode.IsDigit(l.peekChar()) {
610+
l.readChar()
611+
}
607612
}
608613
}
609614
}
@@ -675,15 +680,20 @@ func (l *Lexer) readNumberOrIdent() Item {
675680
}
676681
}
677682

678-
// Check for decimal point
679-
if l.ch == '.' && unicode.IsDigit(l.peekChar()) {
680-
sb.WriteRune(l.ch)
681-
l.readChar()
682-
for unicode.IsDigit(l.ch) {
683+
// Check for decimal point (either followed by digit or end of number like 1.)
684+
if l.ch == '.' {
685+
nextCh := l.peekChar()
686+
// Allow 1. (trailing dot with no digits) and 1.5 (dot with digits)
687+
// But not 1.something (identifier-like)
688+
if unicode.IsDigit(nextCh) || (!isIdentStart(nextCh) && nextCh != '.') {
683689
sb.WriteRune(l.ch)
684690
l.readChar()
685-
for l.ch == '_' && unicode.IsDigit(l.peekChar()) {
691+
for unicode.IsDigit(l.ch) {
692+
sb.WriteRune(l.ch)
686693
l.readChar()
694+
for l.ch == '_' && unicode.IsDigit(l.peekChar()) {
695+
l.readChar()
696+
}
687697
}
688698
}
689699
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"todo": true}
1+
{}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"todo": true}
1+
{}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"todo": true}
1+
{}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"todo": true}
1+
{}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"todo": true}
1+
{}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"todo": true}
1+
{}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"todo": true}
1+
{}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"todo": true}
1+
{}

0 commit comments

Comments
 (0)