@@ -9,26 +9,30 @@ import (
99 "sort"
1010)
1111
12- var formatFlag = flag .Bool ("format" , false , "Find tests with todo_format (required)" )
12+ var formatFlag = flag .Bool ("format" , false , "Find tests with todo_format: true" )
13+ var explainFlag = flag .Bool ("explain" , false , "Find tests with explain_todo entries (fewest first)" )
1314
1415type testMetadata struct {
15- TodoFormat bool `json:"todo_format,omitempty"`
16- Explain * bool `json:"explain,omitempty"`
17- Skip bool `json:"skip,omitempty"`
18- ParseError bool `json:"parse_error,omitempty"`
16+ TodoFormat bool `json:"todo_format,omitempty"`
17+ ExplainTodo map [string ]bool `json:"explain_todo,omitempty"`
18+ Explain * bool `json:"explain,omitempty"`
19+ Skip bool `json:"skip,omitempty"`
20+ ParseError bool `json:"parse_error,omitempty"`
1921}
2022
2123type todoTest struct {
22- name string
23- querySize int
24+ name string
25+ querySize int
26+ explainTodoLen int
2427}
2528
2629func main () {
2730 flag .Parse ()
2831
29- if ! * formatFlag {
30- fmt .Fprintf (os .Stderr , "Usage: go run ./cmd/next-test -format\n " )
31- fmt .Fprintf (os .Stderr , "Finds tests with todo_format: true in metadata.\n " )
32+ if ! * formatFlag && ! * explainFlag {
33+ fmt .Fprintf (os .Stderr , "Usage: go run ./cmd/next-test [-format | -explain]\n " )
34+ fmt .Fprintf (os .Stderr , " -format Find tests with todo_format: true\n " )
35+ fmt .Fprintf (os .Stderr , " -explain Find tests with explain_todo entries (fewest first)\n " )
3236 os .Exit (1 )
3337 }
3438
@@ -60,16 +64,22 @@ func main() {
6064 continue
6165 }
6266
63- // Check for todo_format
64- if ! metadata .TodoFormat {
65- continue
66- }
67-
6867 // Skip tests with skip or explain=false or parse_error
6968 if metadata .Skip || (metadata .Explain != nil && ! * metadata .Explain ) || metadata .ParseError {
7069 continue
7170 }
7271
72+ // Check based on flag
73+ if * formatFlag {
74+ if ! metadata .TodoFormat {
75+ continue
76+ }
77+ } else if * explainFlag {
78+ if len (metadata .ExplainTodo ) == 0 {
79+ continue
80+ }
81+ }
82+
7383 // Read query to get its size
7484 queryPath := filepath .Join (testDir , "query.sql" )
7585 queryBytes , err := os .ReadFile (queryPath )
@@ -78,26 +88,47 @@ func main() {
7888 }
7989
8090 todoTests = append (todoTests , todoTest {
81- name : entry .Name (),
82- querySize : len (queryBytes ),
91+ name : entry .Name (),
92+ querySize : len (queryBytes ),
93+ explainTodoLen : len (metadata .ExplainTodo ),
8394 })
8495 }
8596
97+ todoType := "todo_format"
98+ if * explainFlag {
99+ todoType = "explain_todo"
100+ }
101+
86102 if len (todoTests ) == 0 {
87- fmt .Printf ("No todo_format tests found!\n " )
103+ fmt .Printf ("No %s tests found!\n " , todoType )
88104 return
89105 }
90106
91- // Sort by query size (shortest first)
92- sort .Slice (todoTests , func (i , j int ) bool {
93- return todoTests [i ].querySize < todoTests [j ].querySize
94- })
107+ // Sort based on mode
108+ if * explainFlag {
109+ // Sort by explain_todo count (fewest first), then by query size
110+ sort .Slice (todoTests , func (i , j int ) bool {
111+ if todoTests [i ].explainTodoLen != todoTests [j ].explainTodoLen {
112+ return todoTests [i ].explainTodoLen < todoTests [j ].explainTodoLen
113+ }
114+ return todoTests [i ].querySize < todoTests [j ].querySize
115+ })
116+ } else {
117+ // Sort by query size (shortest first)
118+ sort .Slice (todoTests , func (i , j int ) bool {
119+ return todoTests [i ].querySize < todoTests [j ].querySize
120+ })
121+ }
95122
96- // Print the shortest one
123+ // Print the best candidate
97124 next := todoTests [0 ]
98125 testDir := filepath .Join (testdataDir , next .name )
99126
100- fmt .Printf ("Next todo_format test: %s\n \n " , next .name )
127+ if * explainFlag {
128+ fmt .Printf ("Next %s test: %s (%d pending statements)\n \n " , todoType , next .name , next .explainTodoLen )
129+ } else {
130+ fmt .Printf ("Next %s test: %s\n \n " , todoType , next .name )
131+ }
101132
102133 // Print query.sql contents
103134 queryPath := filepath .Join (testDir , "query.sql" )
@@ -110,5 +141,19 @@ func main() {
110141 fmt .Printf ("\n Expected EXPLAIN output:\n %s\n " , string (explainBytes ))
111142 }
112143
113- fmt .Printf ("\n Remaining todo_format tests: %d\n " , len (todoTests ))
144+ // Print explain_todo entries if in explain mode
145+ if * explainFlag {
146+ metadataPath := filepath .Join (testDir , "metadata.json" )
147+ if metadataBytes , err := os .ReadFile (metadataPath ); err == nil {
148+ var metadata testMetadata
149+ if json .Unmarshal (metadataBytes , & metadata ) == nil {
150+ fmt .Printf ("\n Pending statements (explain_todo):\n " )
151+ for stmt := range metadata .ExplainTodo {
152+ fmt .Printf (" - %s\n " , stmt )
153+ }
154+ }
155+ }
156+ }
157+
158+ fmt .Printf ("\n Remaining %s tests: %d\n " , todoType , len (todoTests ))
114159}
0 commit comments