1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
|
package engine
import (
"context"
"testing"
)
// TestSQLEngine_ArithmeticOnlyQueryExecution tests the specific fix for queries
// that contain ONLY arithmetic expressions (no base columns) in the SELECT clause.
// This was the root issue reported where such queries returned empty values.
func TestSQLEngine_ArithmeticOnlyQueryExecution(t *testing.T) {
engine := NewTestSQLEngine()
// Test the core functionality: arithmetic-only queries should return data
tests := []struct {
name string
query string
expectedCols []string
mustNotBeEmpty bool
}{
{
name: "Basic arithmetic only query",
query: "SELECT id+user_id, id*2 FROM user_events LIMIT 3",
expectedCols: []string{"id+user_id", "id*2"},
mustNotBeEmpty: true,
},
{
name: "With LIMIT and OFFSET - original user issue",
query: "SELECT id+user_id, id*2 FROM user_events LIMIT 2 OFFSET 1",
expectedCols: []string{"id+user_id", "id*2"},
mustNotBeEmpty: true,
},
{
name: "Multiple arithmetic expressions",
query: "SELECT user_id+100, id-1000 FROM user_events LIMIT 1",
expectedCols: []string{"user_id+100", "id-1000"},
mustNotBeEmpty: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result, err := engine.ExecuteSQL(context.Background(), tt.query)
if err != nil {
t.Fatalf("Query failed: %v", err)
}
if result.Error != nil {
t.Fatalf("Query returned error: %v", result.Error)
}
// CRITICAL: Verify we got results (the original bug would return empty)
if tt.mustNotBeEmpty && len(result.Rows) == 0 {
t.Fatal("CRITICAL BUG: Query returned no rows - arithmetic-only query fix failed!")
}
// Verify column count and names
if len(result.Columns) != len(tt.expectedCols) {
t.Errorf("Expected %d columns, got %d", len(tt.expectedCols), len(result.Columns))
}
// CRITICAL: Verify no empty/null values (the original bug symptom)
if len(result.Rows) > 0 {
firstRow := result.Rows[0]
for i, val := range firstRow {
if val.IsNull() {
t.Errorf("CRITICAL BUG: Column %d (%s) returned NULL", i, result.Columns[i])
}
if val.ToString() == "" {
t.Errorf("CRITICAL BUG: Column %d (%s) returned empty string", i, result.Columns[i])
}
}
}
// Log success
t.Logf("SUCCESS: %s returned %d rows with calculated values", tt.query, len(result.Rows))
})
}
}
// TestSQLEngine_ArithmeticOnlyQueryBugReproduction tests that the original bug
// (returning empty values) would have failed before our fix
func TestSQLEngine_ArithmeticOnlyQueryBugReproduction(t *testing.T) {
engine := NewTestSQLEngine()
// This is the EXACT query from the user's bug report
query := "SELECT id+user_id, id*amount, id*2 FROM user_events LIMIT 10 OFFSET 5"
result, err := engine.ExecuteSQL(context.Background(), query)
if err != nil {
t.Fatalf("Query failed: %v", err)
}
if result.Error != nil {
t.Fatalf("Query returned error: %v", result.Error)
}
// Key assertions that would fail with the original bug:
// 1. Must return rows (bug would return 0 rows or empty results)
if len(result.Rows) == 0 {
t.Fatal("CRITICAL: Query returned no rows - the original bug is NOT fixed!")
}
// 2. Must have expected columns
expectedColumns := []string{"id+user_id", "id*amount", "id*2"}
if len(result.Columns) != len(expectedColumns) {
t.Errorf("Expected %d columns, got %d", len(expectedColumns), len(result.Columns))
}
// 3. Must have calculated values, not empty/null
for i, row := range result.Rows {
for j, val := range row {
if val.IsNull() {
t.Errorf("Row %d, Column %d (%s) is NULL - original bug not fixed!",
i, j, result.Columns[j])
}
if val.ToString() == "" {
t.Errorf("Row %d, Column %d (%s) is empty - original bug not fixed!",
i, j, result.Columns[j])
}
}
}
// 4. Verify specific calculations for the OFFSET 5 data
if len(result.Rows) > 0 {
firstRow := result.Rows[0]
// With OFFSET 5, first returned row should be 6th row: id=417224, user_id=7810
expectedSum := "425034" // 417224 + 7810
if firstRow[0].ToString() != expectedSum {
t.Errorf("OFFSET 5 calculation wrong: expected id+user_id=%s, got %s",
expectedSum, firstRow[0].ToString())
}
expectedDouble := "834448" // 417224 * 2
if firstRow[2].ToString() != expectedDouble {
t.Errorf("OFFSET 5 calculation wrong: expected id*2=%s, got %s",
expectedDouble, firstRow[2].ToString())
}
}
t.Logf("SUCCESS: Arithmetic-only query with OFFSET works correctly!")
t.Logf("Query: %s", query)
t.Logf("Returned %d rows with correct calculations", len(result.Rows))
}
|