github.com/influxdata/influxdb/v2@v2.7.6/influxql/query/explain.go (about)

     1  package query
     2  
     3  import (
     4  	"bytes"
     5  	"context"
     6  	"fmt"
     7  	"io"
     8  	"strings"
     9  
    10  	"github.com/influxdata/influxql"
    11  )
    12  
    13  func (p *preparedStatement) Explain(ctx context.Context) (string, error) {
    14  	// Determine the cost of all iterators created as part of this plan.
    15  	ic := &explainIteratorCreator{ic: p.ic}
    16  	p.ic = ic
    17  	cur, err := p.Select(ctx)
    18  	p.ic = ic.ic
    19  
    20  	if err != nil {
    21  		return "", err
    22  	}
    23  	cur.Close()
    24  
    25  	var buf bytes.Buffer
    26  	for i, node := range ic.nodes {
    27  		if i > 0 {
    28  			buf.WriteString("\n")
    29  		}
    30  
    31  		expr := "<nil>"
    32  		if node.Expr != nil {
    33  			expr = node.Expr.String()
    34  		}
    35  		fmt.Fprintf(&buf, "EXPRESSION: %s\n", expr)
    36  		if len(node.Aux) != 0 {
    37  			refs := make([]string, len(node.Aux))
    38  			for i, ref := range node.Aux {
    39  				refs[i] = ref.String()
    40  			}
    41  			fmt.Fprintf(&buf, "AUXILIARY FIELDS: %s\n", strings.Join(refs, ", "))
    42  		}
    43  		fmt.Fprintf(&buf, "NUMBER OF SHARDS: %d\n", node.Cost.NumShards)
    44  		fmt.Fprintf(&buf, "NUMBER OF SERIES: %d\n", node.Cost.NumSeries)
    45  		fmt.Fprintf(&buf, "CACHED VALUES: %d\n", node.Cost.CachedValues)
    46  		fmt.Fprintf(&buf, "NUMBER OF FILES: %d\n", node.Cost.NumFiles)
    47  		fmt.Fprintf(&buf, "NUMBER OF BLOCKS: %d\n", node.Cost.BlocksRead)
    48  		fmt.Fprintf(&buf, "SIZE OF BLOCKS: %d\n", node.Cost.BlockSize)
    49  	}
    50  	return buf.String(), nil
    51  }
    52  
    53  type planNode struct {
    54  	Expr influxql.Expr
    55  	Aux  []influxql.VarRef
    56  	Cost IteratorCost
    57  }
    58  
    59  type explainIteratorCreator struct {
    60  	ic interface {
    61  		IteratorCreator
    62  		io.Closer
    63  	}
    64  	nodes []planNode
    65  }
    66  
    67  func (e *explainIteratorCreator) CreateIterator(ctx context.Context, m *influxql.Measurement, opt IteratorOptions) (Iterator, error) {
    68  	cost, err := e.ic.IteratorCost(ctx, m, opt)
    69  	if err != nil {
    70  		return nil, err
    71  	}
    72  	e.nodes = append(e.nodes, planNode{
    73  		Expr: opt.Expr,
    74  		Aux:  opt.Aux,
    75  		Cost: cost,
    76  	})
    77  	return &nilFloatIterator{}, nil
    78  }
    79  
    80  func (e *explainIteratorCreator) IteratorCost(ctx context.Context, m *influxql.Measurement, opt IteratorOptions) (IteratorCost, error) {
    81  	return e.ic.IteratorCost(ctx, m, opt)
    82  }
    83  
    84  func (e *explainIteratorCreator) Close() error {
    85  	return e.ic.Close()
    86  }