// buildExplainFor gets *last* (maybe running or finished) query plan from connection #connection id.
// See https://dev.mysql.com/doc/refman/8.0/en/explain-for-connection.html.
buildExplainFor gets *last* (maybe running or finished) query plan from connection #connection id.
// buildExplainFor gets * last * ( maybe running or finished ) query plan from connection #connection id . // See https : // dev . mysql . com / doc / refman / 8 . 0 / en / explain - for - connection . html .
func (b *PlanBuilder) buildExplainFor(explainFor *ast.ExplainForStmt) (Plan, error) {
	processInfo, ok := b.ctx.GetSessionManager().GetProcessInfo(explainFor.ConnectionID)
	if !ok {
		return nil, ErrNoSuchThread.GenWithStackByArgs(explainFor.ConnectionID)
	}
	if b.ctx.GetSessionVars() != nil && b.ctx.GetSessionVars().User != nil {
		if b.ctx.GetSessionVars().User.Username != processInfo.User {
			err := ErrAccessDenied.GenWithStackByArgs(b.ctx.GetSessionVars().User.Username, b.ctx.GetSessionVars().User.Hostname)
			b.visitInfo = appendVisitInfo(b.visitInfo, mysql.SuperPriv, "", "", "", err)
		}
	}
	targetPlan, ok := processInfo.Plan.(Plan)
	if !ok || targetPlan == nil {
		return &Explain{Format: explainFor.Format}, nil
	}
	var explainRows [][]string
	if explainFor.Format == ast.ExplainFormatROW {
		explainRows = processInfo.PlanExplainRows
	}
	return b.buildExplainPlan(targetPlan, explainFor.Format, explainRows, false, nil, processInfo.RuntimeStatsColl)
}
func ( b * PlanBuilder ) buildExplainFor ( explainFor * ast . ExplainForStmt ) ( Plan , error ) { processInfo , ok := b . ctx . GetSessionManager ( ) . GetProcessInfo ( explainFor . ConnectionID ) if ! ok { return nil , ErrNoSuchThread . GenWithStackByArgs ( explainFor . ConnectionID ) } if b . ctx . GetSessionVars ( ) != nil && b . ctx . GetSessionVars ( ) . User != nil { if b . ctx . GetSessionVars ( ) . User . Username != processInfo . User { err := ErrAccessDenied . GenWithStackByArgs ( b . ctx . GetSessionVars ( ) . User . Username , b . ctx . GetSessionVars ( ) . User . Hostname ) b . visitInfo = appendVisitInfo ( b . visitInfo , mysql . SuperPriv , " " , " " , " " , err ) } } targetPlan , ok := processInfo . Plan . ( Plan ) if ! ok || targetPlan == nil { return & Explain { Format : explainFor . Format } , nil } var explainRows [ ] [ ] string if explainFor . Format == ast . ExplainFormatROW { explainRows = processInfo . PlanExplainRows } return b . buildExplainPlan ( targetPlan , explainFor . Format , explainRows , false , nil , processInfo . RuntimeStatsColl ) }
buildExplainFor gets *last* (maybe running or finished) query plan from connection #connection id.
buildExplainFor gets * last * ( maybe running or finished ) query plan from connection #connection id .
// Different from MySQL's behavior and document.