|
4 | 4 | "context"
|
5 | 5 | "testing"
|
6 | 6 |
|
| 7 | + "github.com/src-d/gitbase/internal/rule" |
| 8 | + |
7 | 9 | opentracing "github.com/opentracing/opentracing-go"
|
8 | 10 | "github.com/src-d/gitbase"
|
9 | 11 | "github.com/src-d/gitbase/internal/function"
|
@@ -133,18 +135,140 @@ func TestIntegration(t *testing.T) {
|
133 | 135 | },
|
134 | 136 | }
|
135 | 137 |
|
136 |
| - for _, tt := range testCases { |
137 |
| - t.Run(tt.query, func(t *testing.T) { |
138 |
| - require := require.New(t) |
| 138 | + runTests := func(t *testing.T) { |
| 139 | + for _, tt := range testCases { |
| 140 | + t.Run(tt.query, func(t *testing.T) { |
| 141 | + require := require.New(t) |
| 142 | + |
| 143 | + session := gitbase.NewSession(&pool) |
| 144 | + ctx := sql.NewContext(context.TODO(), session, opentracing.NoopTracer{}) |
139 | 145 |
|
140 |
| - session := gitbase.NewSession(&pool) |
141 |
| - ctx := sql.NewContext(context.TODO(), session, opentracing.NoopTracer{}) |
| 146 | + _, iter, err := engine.Query(ctx, tt.query) |
| 147 | + require.NoError(err) |
| 148 | + rows, err := sql.RowIterToRows(iter) |
| 149 | + require.NoError(err) |
| 150 | + require.ElementsMatch(tt.result, rows) |
| 151 | + }) |
| 152 | + } |
| 153 | + } |
142 | 154 |
|
143 |
| - _, iter, err := engine.Query(ctx, tt.query) |
144 |
| - require.NoError(err) |
145 |
| - rows, err := sql.RowIterToRows(iter) |
146 |
| - require.NoError(err) |
147 |
| - require.ElementsMatch(tt.result, rows) |
| 155 | + t.Run("without squash", runTests) |
| 156 | + |
| 157 | + engine.Analyzer.AddRule(rule.SquashJoinsRule, rule.SquashJoins) |
| 158 | + t.Run("with squash", runTests) |
| 159 | +} |
| 160 | + |
| 161 | +func BenchmarkQueries(b *testing.B) { |
| 162 | + queries := []struct { |
| 163 | + name string |
| 164 | + query string |
| 165 | + }{ |
| 166 | + { |
| 167 | + "simple query", |
| 168 | + `SELECT * FROM repositories r |
| 169 | + INNER JOIN refs rr |
| 170 | + ON r.id = rr.repository_id`, |
| 171 | + }, |
| 172 | + { |
| 173 | + "query with commit_has_blob", |
| 174 | + `SELECT COUNT(c.hash), c.hash |
| 175 | + FROM refs r |
| 176 | + INNER JOIN commits c |
| 177 | + ON r.name = 'HEAD' AND history_idx(r.hash, c.hash) >= 0 |
| 178 | + INNER JOIN blobs b |
| 179 | + ON commit_has_blob(c.hash, b.hash) |
| 180 | + GROUP BY c.hash`, |
| 181 | + }, |
| 182 | + { |
| 183 | + "query with history_idx and 3 joins", |
| 184 | + `SELECT COUNT(first_commit_year), first_commit_year |
| 185 | + FROM ( |
| 186 | + SELECT YEAR(c.author_when) AS first_commit_year |
| 187 | + FROM repositories r |
| 188 | + INNER JOIN refs |
| 189 | + ON r.id = refs.repository_id |
| 190 | + INNER JOIN commits c |
| 191 | + ON history_idx(refs.hash, c.hash) >= 0 |
| 192 | + ORDER BY c.author_when |
| 193 | + LIMIT 1 |
| 194 | + ) repo_years |
| 195 | + GROUP BY first_commit_year`, |
| 196 | + }, |
| 197 | + { |
| 198 | + "query with history_idx", |
| 199 | + `SELECT * FROM ( |
| 200 | + SELECT COUNT(c.hash) AS num, c.hash |
| 201 | + FROM refs r |
| 202 | + INNER JOIN commits c |
| 203 | + ON history_idx(r.hash, c.hash) >= 0 |
| 204 | + GROUP BY c.hash |
| 205 | + ) t WHERE num > 1`, |
| 206 | + }, |
| 207 | + { |
| 208 | + "join tree entries and blobs", |
| 209 | + `SELECT * FROM tree_entries te |
| 210 | + INNER JOIN blobs b |
| 211 | + ON te.entry_hash = b.hash`, |
| 212 | + }, |
| 213 | + { |
| 214 | + "join tree entries and blobs with filters", |
| 215 | + `SELECT * FROM tree_entries te |
| 216 | + INNER JOIN blobs b |
| 217 | + ON te.entry_hash = b.hash |
| 218 | + WHERE te.name = 'LICENSE'`, |
| 219 | + }, |
| 220 | + { |
| 221 | + "join refs and blobs", |
| 222 | + `SELECT * FROM refs r |
| 223 | + INNER JOIN blobs b |
| 224 | + ON commit_has_blob(r.hash, b.hash)`, |
| 225 | + }, |
| 226 | + { |
| 227 | + "join refs and blobs with filters", |
| 228 | + `SELECT * FROM refs r |
| 229 | + INNER JOIN blobs b |
| 230 | + ON commit_has_blob(r.hash, b.hash) |
| 231 | + WHERE r.name = 'refs/heads/master'`, |
| 232 | + }, |
| 233 | + } |
| 234 | + |
| 235 | + for _, qq := range queries { |
| 236 | + b.Run(qq.name, func(b *testing.B) { |
| 237 | + benchmarkQuery(b, qq.query) |
148 | 238 | })
|
149 | 239 | }
|
150 | 240 | }
|
| 241 | + |
| 242 | +func benchmarkQuery(b *testing.B, query string) { |
| 243 | + engine := sqle.New() |
| 244 | + require.NoError(b, fixtures.Init()) |
| 245 | + defer func() { |
| 246 | + require.NoError(b, fixtures.Clean()) |
| 247 | + }() |
| 248 | + |
| 249 | + path := fixtures.ByTag("worktree").One().Worktree().Root() |
| 250 | + |
| 251 | + engine.AddDatabase(gitbase.NewDatabase("foo")) |
| 252 | + engine.Catalog.RegisterFunctions(function.Functions) |
| 253 | + |
| 254 | + pool := gitbase.NewRepositoryPool() |
| 255 | + _, err := pool.AddGit(path) |
| 256 | + require.NoError(b, err) |
| 257 | + session := gitbase.NewSession(&pool) |
| 258 | + ctx := sql.NewContext(context.TODO(), session, opentracing.NoopTracer{}) |
| 259 | + |
| 260 | + run := func(b *testing.B) { |
| 261 | + for i := 0; i < b.N; i++ { |
| 262 | + _, rows, err := engine.Query(ctx, query) |
| 263 | + require.NoError(b, err) |
| 264 | + |
| 265 | + _, err = sql.RowIterToRows(rows) |
| 266 | + require.NoError(b, err) |
| 267 | + } |
| 268 | + } |
| 269 | + |
| 270 | + b.Run("no squash", run) |
| 271 | + |
| 272 | + engine.Analyzer.AddRule(rule.SquashJoinsRule, rule.SquashJoins) |
| 273 | + b.Run("squash", run) |
| 274 | +} |
0 commit comments