// newExplainPlanNode instantiates a planNode that runs an EXPLAIN query.
func (p *planner) makeExplainPlanNode(explainer explainer, expanded bool, plan planNode) planNode {
	columns := ResultColumns{
		// Level is the depth of the node in the tree.
		{Name: "Level", Typ: parser.TypeInt},
		// Type is the node type.
		{Name: "Type", Typ: parser.TypeString},
		// Field is the part of the node that a row of output pertains to.
		// For example a select node may have separate "render" and
		// "filter" fields.
		{Name: "Field", Typ: parser.TypeString},
		// Description contains details about the field.
		{Name: "Description", Typ: parser.TypeString},
	}
	if explainer.showMetadata {
		// Columns is the type signature of the data source.
		columns = append(columns, ResultColumn{Name: "Columns", Typ: parser.TypeString})
		// Ordering indicates the known ordering of the data from this source.
		columns = append(columns, ResultColumn{Name: "Ordering", Typ: parser.TypeString})
	}

	explainer.fmtFlags = parser.FmtExpr(
		explainer.showTypes, explainer.symbolicVars, explainer.qualifyNames)

	node := &explainPlanNode{
		explainer: explainer,
		expanded:  expanded,
		plan:      plan,
		results:   p.newContainerValuesNode(columns, 0),
	}
	return node
}
Exemple #2
0
// planToString uses explain() to build a string representation of the planNode.
func planToString(plan planNode) string {
	var buf bytes.Buffer
	e := explainer{
		showMetadata:  true,
		showTypes:     true,
		showExprs:     true,
		showSelectTop: true,
		fmtFlags:      parser.FmtExpr(parser.FmtSimple, true, true, true),
		makeRow: func(level int, name, field, description string, plan planNode) {
			if field != "" {
				field = "." + field
			}
			if plan == nil {
				fmt.Fprintf(&buf, "%d %s%s %s\n", level, name, field, description)
			} else {
				fmt.Fprintf(&buf, "%d %s%s %s %s %s\n", level, name, field, description,
					formatColumns(plan.Columns(), true),
					plan.Ordering().AsString(plan.Columns()),
				)
			}
		},
	}
	_ = walkPlan(plan, &e)
	return buf.String()
}