explainStatement returns the query plan for the given statement as JSON.
(ctx context.Context, statement string)
| 564 | |
| 565 | // explainStatement returns the query plan for the given statement as JSON. |
| 566 | func (d *Driver) explainStatement(ctx context.Context, statement string) ([]*v1pb.QueryResult, error) { |
| 567 | if d.client == nil { |
| 568 | return nil, errors.New("spanner client is not initialized, database name may be missing") |
| 569 | } |
| 570 | |
| 571 | stmts, err := util.SanitizeSQL(statement) |
| 572 | if err != nil { |
| 573 | return nil, err |
| 574 | } |
| 575 | |
| 576 | var results []*v1pb.QueryResult |
| 577 | for _, stmt := range stmts { |
| 578 | startTime := time.Now() |
| 579 | queryResult, err := func() (*v1pb.QueryResult, error) { |
| 580 | plan, err := d.client.Single().AnalyzeQuery(ctx, spanner.NewStatement(stmt)) |
| 581 | if err != nil { |
| 582 | return nil, err |
| 583 | } |
| 584 | |
| 585 | // Convert the query plan to JSON |
| 586 | planJSON, err := convertQueryPlanToJSON(plan) |
| 587 | if err != nil { |
| 588 | return nil, errors.Wrap(err, "failed to convert query plan to JSON") |
| 589 | } |
| 590 | |
| 591 | return &v1pb.QueryResult{ |
| 592 | ColumnNames: []string{"QUERY PLAN"}, |
| 593 | ColumnTypeNames: []string{"JSON"}, |
| 594 | Rows: []*v1pb.QueryRow{ |
| 595 | { |
| 596 | Values: []*v1pb.RowValue{ |
| 597 | {Kind: &v1pb.RowValue_StringValue{StringValue: planJSON}}, |
| 598 | }, |
| 599 | }, |
| 600 | }, |
| 601 | }, nil |
| 602 | }() |
| 603 | if err != nil { |
| 604 | queryResult = &v1pb.QueryResult{ |
| 605 | Error: err.Error(), |
| 606 | } |
| 607 | } |
| 608 | queryResult.Statement = stmt |
| 609 | queryResult.Latency = durationpb.New(time.Since(startTime)) |
| 610 | queryResult.RowsCount = int64(len(queryResult.Rows)) |
| 611 | results = append(results, queryResult) |
| 612 | } |
| 613 | |
| 614 | return results, nil |
| 615 | } |
| 616 | |
| 617 | // PlanNode represents a node in the Spanner query plan for JSON serialization. |
| 618 | type PlanNode struct { |
no test coverage detected