handleExplain used to handle the EXPLAIN command.
(session *driver.Session, query string, node sqlparser.Statement)
| 20 | |
| 21 | // handleExplain used to handle the EXPLAIN command. |
| 22 | func (spanner *Spanner) handleExplain(session *driver.Session, query string, node sqlparser.Statement) (*sqltypes.Result, error) { |
| 23 | log := spanner.log |
| 24 | database := session.Schema() |
| 25 | router := spanner.router |
| 26 | qr := &sqltypes.Result{} |
| 27 | qr.Fields = []*querypb.Field{ |
| 28 | {Name: "EXPLAIN", Type: querypb.Type_VARCHAR}, |
| 29 | } |
| 30 | |
| 31 | explainableStmt := node.(*sqlparser.Explain).Statement |
| 32 | privilegePlug := spanner.plugins.PlugPrivilege() |
| 33 | if err := privilegePlug.Check(database, session.User(), explainableStmt); err != nil { |
| 34 | return nil, err |
| 35 | } |
| 36 | |
| 37 | // Explain only supports DML. |
| 38 | // see: https://dev.mysql.com/doc/refman/8.0/en/explain.html |
| 39 | switch explainableStmt.(type) { |
| 40 | case *sqlparser.Union: |
| 41 | case *sqlparser.Select: |
| 42 | case *sqlparser.Delete: |
| 43 | case *sqlparser.Insert: |
| 44 | autoincPlug := spanner.plugins.PlugAutoIncrement() |
| 45 | if err := autoincPlug.Process(database, explainableStmt.(*sqlparser.Insert)); err != nil { |
| 46 | return nil, err |
| 47 | } |
| 48 | case *sqlparser.Update: |
| 49 | default: |
| 50 | return nil, sqldb.NewSQLError(sqldb.ER_SYNTAX_ERROR, "explain only supports SELECT/DELETE/INSERT/UNION") |
| 51 | } |
| 52 | |
| 53 | simOptimizer := optimizer.NewSimpleOptimizer(log, database, query, explainableStmt, router) |
| 54 | planTree, err := simOptimizer.BuildPlanTree() |
| 55 | if err != nil { |
| 56 | log.Error("proxy.explain.error:%+v", err) |
| 57 | return nil, err |
| 58 | } |
| 59 | |
| 60 | if len(planTree.Plans()) > 0 { |
| 61 | msg := planTree.Plans()[0].JSON() |
| 62 | row := []sqltypes.Value{ |
| 63 | sqltypes.MakeTrusted(querypb.Type_VARCHAR, []byte(msg)), |
| 64 | } |
| 65 | qr.Rows = append(qr.Rows, row) |
| 66 | return qr, nil |
| 67 | } |
| 68 | return qr, nil |
| 69 | } |
no test coverage detected