classifyForEditor maps a statement's base.QueryType (plus its node, to single out SET) onto the SQL-editor read-only decision, mirroring the legacy queryValidateListener.EnterSql_command. Returns (readOnly, isSet): - readOnly: the statement may run in the read-only SQL editor; - isSet: the state
(qt base.QueryType, node ast.Node)
| 81 | // base.Select while the legacy editor listener REJECTED USE (use_command was |
| 82 | // not in its accepted dml/other/describe/show set), so USE is excluded here. |
| 83 | func classifyForEditor(qt base.QueryType, node ast.Node) (bool, bool) { |
| 84 | if sh, ok := node.(*ast.ShowStmt); ok && sh.Pipe != nil { |
| 85 | // SHOW ... ->> <stmt>: SHOW itself is read-only metadata; the verdict is |
| 86 | // the piped statement's (a non-read-only pipe must not classify as a query). |
| 87 | return classifyForEditor(getQueryType(sh.Pipe), sh.Pipe) |
| 88 | } |
| 89 | if rs, ok := node.(*ast.ResultScanStmt); ok { |
| 90 | // stmt ->> query is read-only only if BOTH the source statement and the |
| 91 | // trailing query are; it returns the trailing query's data. |
| 92 | srcOK, _ := classifyForEditor(getQueryType(rs.Source), rs.Source) |
| 93 | queryOK, querySet := classifyForEditor(getQueryType(rs.Query), rs.Query) |
| 94 | return srcOK && queryOK, querySet |
| 95 | } |
| 96 | if _, ok := node.(*ast.UseStmt); ok { |
| 97 | // Legacy validateQuery rejected USE even though getQueryType classifies it |
| 98 | // read-only; preserve the stricter editor behavior. |
| 99 | return false, false |
| 100 | } |
| 101 | if _, ok := node.(*ast.SetStmt); ok { |
| 102 | // SET is read-only but does not return data. |
| 103 | return true, true |
| 104 | } |
| 105 | switch qt { |
| 106 | case base.Select, base.SelectInfoSchema, base.Explain: |
| 107 | return true, false |
| 108 | default: |
| 109 | return false, false |
| 110 | } |
| 111 | } |
no test coverage detected