func (inf *Inferrer) explainQuery(query *ast.SourceQuery) (Plan, error) {
	explainQuery := `EXPLAIN (VERBOSE, FORMAT JSON) ` + query.PreparedSQL
	ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout)
	defer cancel()
	row := inf.conn.QueryRow(ctx, explainQuery, createParamArgs(query)...)
	explain := make([]map[string]map[string]interface{}, 0, 1)
	if err := row.Scan(&explain); err != nil {
		return Plan{}, fmt.Errorf("explain prepared query: %w", err)
	}
	if len(explain) == 0 {
		return Plan{}, fmt.Errorf("no explain output")
	}
	plan, ok := explain[0]["Plan"]
	if !ok {
		return Plan{}, fmt.Errorf("explain output had no 'Plan' node")
	}
	node, ok := plan["Node Type"]
	if !ok {
		return Plan{}, fmt.Errorf("explain output had no 'Plan[Node Type]' node")
	}
	strNode, ok := node.(string)
	if !ok {
		return Plan{}, fmt.Errorf("explain output 'Plan[Node Type]' is not string; got type %T for value %v", node, node)
	}
	relation := plan["Relation Name"]
	relationStr, _ := relation.(string)
	rawOuts := plan["Output"]
	outs, _ := rawOuts.([]interface{})
	strOuts := make([]string, len(outs))
	for i, out := range outs {
		out, ok := out.(string)
		if !ok {
			return Plan{}, fmt.Errorf("explain output 'Plan.Output[%d]' was not a string; got type %T for value %v", i, out, out)
		}
		strOuts[i] = out
	}
	return Plan{
		Type:     PlanType(strNode),
		Relation: relationStr,
		Outputs:  strOuts,
	}, nil
}
explainQuery executes explain plan to get the node plan type and the format
of the output columns.
package pginfer
import (
	"context"
	"fmt"
	"github.com/jschaf/pggen/internal/ast"
)
type PlanType string
const (
	PlanResult      PlanType = "Result"       
	PlanModifyTable PlanType = "ModifyTable"  
)
type Plan struct {
	Type     PlanType
	Relation string    
	Outputs  []string  
}