Skip to content

Commit 32d42de

Browse files
Ajit Pratap SinghAjit Pratap Singh
authored andcommitted
bench(mariadb): add MariaDB-specific parsing benchmarks
17 benchmarks across 4 groups: - BenchmarkMariaDB_Sequence: CREATE/ALTER/DROP SEQUENCE (5 cases) - BenchmarkMariaDB_ForSystemTime: temporal table queries (5 cases) - BenchmarkMariaDB_ConnectBy: hierarchical queries with PRIOR (4 cases) - BenchmarkMariaDB_Mixed: combined features — CTE+temporal, CTE+CONNECT BY, CREATE TABLE WITH SYSTEM VERSIONING (3 cases) Baseline (M2): 398–3001 ns/op, 984–6763 B/op
1 parent 751e859 commit 32d42de

1 file changed

Lines changed: 260 additions & 0 deletions

File tree

Lines changed: 260 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,260 @@
1+
// Copyright 2026 GoSQLX Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package parser_test
16+
17+
import (
18+
"testing"
19+
20+
"github.com/ajitpratap0/GoSQLX/pkg/sql/ast"
21+
"github.com/ajitpratap0/GoSQLX/pkg/sql/keywords"
22+
"github.com/ajitpratap0/GoSQLX/pkg/sql/parser"
23+
"github.com/ajitpratap0/GoSQLX/pkg/sql/tokenizer"
24+
)
25+
26+
// BenchmarkMariaDB_Sequence benchmarks MariaDB SEQUENCE DDL parsing.
27+
func BenchmarkMariaDB_Sequence(b *testing.B) {
28+
benchmarks := []struct {
29+
name string
30+
sql string
31+
}{
32+
{
33+
name: "create_minimal",
34+
sql: "CREATE SEQUENCE seq_orders",
35+
},
36+
{
37+
name: "create_all_options",
38+
sql: "CREATE SEQUENCE s START WITH 1000 INCREMENT BY 5 MINVALUE 1 MAXVALUE 9999 CACHE 20 CYCLE",
39+
},
40+
{
41+
name: "create_or_replace_nocache",
42+
sql: "CREATE OR REPLACE SEQUENCE s NOCACHE NOCYCLE",
43+
},
44+
{
45+
name: "alter_restart_with",
46+
sql: "ALTER SEQUENCE s RESTART WITH 5000",
47+
},
48+
{
49+
name: "drop_if_exists",
50+
sql: "DROP SEQUENCE IF EXISTS seq_orders",
51+
},
52+
}
53+
54+
for _, bm := range benchmarks {
55+
bm := bm
56+
b.Run(bm.name, func(b *testing.B) {
57+
tkz := tokenizer.GetTokenizer()
58+
defer tokenizer.PutTokenizer(tkz)
59+
60+
tokens, err := tkz.Tokenize([]byte(bm.sql))
61+
if err != nil {
62+
b.Fatalf("Tokenize error: %v", err)
63+
}
64+
65+
b.ResetTimer()
66+
b.ReportAllocs()
67+
68+
for i := 0; i < b.N; i++ {
69+
p := parser.NewParser(parser.WithDialect(string(keywords.DialectMariaDB)))
70+
result, err := p.ParseFromModelTokens(tokens)
71+
if err != nil {
72+
b.Fatalf("Parse error: %v", err)
73+
}
74+
ast.ReleaseAST(result)
75+
p.Release()
76+
}
77+
})
78+
}
79+
}
80+
81+
// BenchmarkMariaDB_ForSystemTime benchmarks MariaDB temporal table query parsing.
82+
func BenchmarkMariaDB_ForSystemTime(b *testing.B) {
83+
benchmarks := []struct {
84+
name string
85+
sql string
86+
}{
87+
{
88+
name: "as_of_timestamp",
89+
sql: "SELECT * FROM t FOR SYSTEM_TIME AS OF TIMESTAMP '2024-01-01 00:00:00'",
90+
},
91+
{
92+
name: "all",
93+
sql: "SELECT id, name FROM orders FOR SYSTEM_TIME ALL",
94+
},
95+
{
96+
name: "between",
97+
sql: "SELECT * FROM t FOR SYSTEM_TIME BETWEEN TIMESTAMP '2023-01-01' AND TIMESTAMP '2023-12-31'",
98+
},
99+
{
100+
name: "from_to",
101+
sql: "SELECT * FROM t FOR SYSTEM_TIME FROM TIMESTAMP '2023-01-01' TO TIMESTAMP '2024-01-01'",
102+
},
103+
{
104+
name: "join_with_system_time",
105+
sql: `SELECT o.id, h.status
106+
FROM orders o
107+
JOIN order_history h FOR SYSTEM_TIME AS OF TIMESTAMP '2024-01-01'
108+
ON o.id = h.order_id`,
109+
},
110+
}
111+
112+
for _, bm := range benchmarks {
113+
bm := bm
114+
b.Run(bm.name, func(b *testing.B) {
115+
tkz := tokenizer.GetTokenizer()
116+
defer tokenizer.PutTokenizer(tkz)
117+
118+
tokens, err := tkz.Tokenize([]byte(bm.sql))
119+
if err != nil {
120+
b.Fatalf("Tokenize error: %v", err)
121+
}
122+
123+
b.ResetTimer()
124+
b.ReportAllocs()
125+
126+
for i := 0; i < b.N; i++ {
127+
p := parser.NewParser(parser.WithDialect(string(keywords.DialectMariaDB)))
128+
result, err := p.ParseFromModelTokens(tokens)
129+
if err != nil {
130+
b.Fatalf("Parse error: %v", err)
131+
}
132+
ast.ReleaseAST(result)
133+
p.Release()
134+
}
135+
})
136+
}
137+
}
138+
139+
// BenchmarkMariaDB_ConnectBy benchmarks MariaDB CONNECT BY hierarchical query parsing.
140+
func BenchmarkMariaDB_ConnectBy(b *testing.B) {
141+
benchmarks := []struct {
142+
name string
143+
sql string
144+
}{
145+
{
146+
name: "simple_prior_left",
147+
sql: `SELECT id, name FROM employees
148+
START WITH parent_id IS NULL
149+
CONNECT BY PRIOR id = parent_id`,
150+
},
151+
{
152+
name: "prior_right",
153+
sql: `SELECT id, name FROM employees
154+
START WITH id = 1
155+
CONNECT BY id = PRIOR parent_id`,
156+
},
157+
{
158+
name: "nocycle",
159+
sql: `SELECT id, name, level FROM employees
160+
START WITH parent_id IS NULL
161+
CONNECT BY NOCYCLE PRIOR id = parent_id`,
162+
},
163+
{
164+
name: "with_where_and_order",
165+
sql: `SELECT id, name FROM employees
166+
WHERE active = 1
167+
START WITH parent_id IS NULL
168+
CONNECT BY PRIOR id = parent_id
169+
ORDER BY id`,
170+
},
171+
}
172+
173+
for _, bm := range benchmarks {
174+
bm := bm
175+
b.Run(bm.name, func(b *testing.B) {
176+
tkz := tokenizer.GetTokenizer()
177+
defer tokenizer.PutTokenizer(tkz)
178+
179+
tokens, err := tkz.Tokenize([]byte(bm.sql))
180+
if err != nil {
181+
b.Fatalf("Tokenize error: %v", err)
182+
}
183+
184+
b.ResetTimer()
185+
b.ReportAllocs()
186+
187+
for i := 0; i < b.N; i++ {
188+
p := parser.NewParser(parser.WithDialect(string(keywords.DialectMariaDB)))
189+
result, err := p.ParseFromModelTokens(tokens)
190+
if err != nil {
191+
b.Fatalf("Parse error: %v", err)
192+
}
193+
ast.ReleaseAST(result)
194+
p.Release()
195+
}
196+
})
197+
}
198+
}
199+
200+
// BenchmarkMariaDB_Mixed benchmarks parsing of queries that combine multiple
201+
// MariaDB-specific features in a single statement.
202+
func BenchmarkMariaDB_Mixed(b *testing.B) {
203+
benchmarks := []struct {
204+
name string
205+
sql string
206+
}{
207+
{
208+
name: "temporal_with_cte",
209+
sql: `WITH history AS (
210+
SELECT * FROM orders FOR SYSTEM_TIME ALL
211+
)
212+
SELECT id, status FROM history WHERE status = 'cancelled'`,
213+
},
214+
{
215+
name: "hierarchical_with_cte",
216+
sql: `WITH RECURSIVE org AS (
217+
SELECT id, name, parent_id FROM employees
218+
START WITH parent_id IS NULL
219+
CONNECT BY PRIOR id = parent_id
220+
)
221+
SELECT * FROM org ORDER BY id`,
222+
},
223+
{
224+
name: "create_table_versioned",
225+
sql: `CREATE TABLE orders (
226+
id INT PRIMARY KEY,
227+
status VARCHAR(50),
228+
row_start DATETIME(6) GENERATED ALWAYS AS ROW START,
229+
row_end DATETIME(6) GENERATED ALWAYS AS ROW END,
230+
PERIOD FOR SYSTEM_TIME(row_start, row_end)
231+
) WITH SYSTEM VERSIONING`,
232+
},
233+
}
234+
235+
for _, bm := range benchmarks {
236+
bm := bm
237+
b.Run(bm.name, func(b *testing.B) {
238+
tkz := tokenizer.GetTokenizer()
239+
defer tokenizer.PutTokenizer(tkz)
240+
241+
tokens, err := tkz.Tokenize([]byte(bm.sql))
242+
if err != nil {
243+
b.Fatalf("Tokenize error: %v", err)
244+
}
245+
246+
b.ResetTimer()
247+
b.ReportAllocs()
248+
249+
for i := 0; i < b.N; i++ {
250+
p := parser.NewParser(parser.WithDialect(string(keywords.DialectMariaDB)))
251+
result, err := p.ParseFromModelTokens(tokens)
252+
if err != nil {
253+
b.Fatalf("Parse error: %v", err)
254+
}
255+
ast.ReleaseAST(result)
256+
p.Release()
257+
}
258+
})
259+
}
260+
}

0 commit comments

Comments
 (0)