func (tq TemplatedQuery) EmitRowScanArgs() (string, error) {
	switch tq.ResultKind {
	case ast.ResultKindExec:
		return "", fmt.Errorf("cannot EmitRowScanArgs for :exec query %s", tq.Name)
	case ast.ResultKindMany, ast.ResultKindOne:
		break  
	default:
		return "", fmt.Errorf("unhandled EmitRowScanArgs type: %s", tq.ResultKind)
	}
	hasOnlyOneNonVoid := len(removeVoidColumns(tq.Outputs)) == 1
	sb := strings.Builder{}
	sb.Grow(15 * len(tq.Outputs))
	for i, out := range tq.Outputs {
		switch typ := out.Type.(type) {
		case gotype.ArrayType:
			switch typ.Elem.(type) {
			case gotype.EnumType, gotype.CompositeType:
				sb.WriteString(out.LowerName)
				sb.WriteString("Array")
			default:
				if hasOnlyOneNonVoid {
					sb.WriteString("&item")
				} else {
					sb.WriteString("&item.")
					sb.WriteString(out.UpperName)
				}
			}
		case gotype.CompositeType:
			sb.WriteString(out.LowerName)
			sb.WriteString("Row")
		case gotype.VoidType:
			sb.WriteString("nil")
		case gotype.EnumType, gotype.OpaqueType:
			if hasOnlyOneNonVoid {
				sb.WriteString("&item")
			} else {
				sb.WriteString("&item.")
				sb.WriteString(out.UpperName)
			}
		default:
			return "", fmt.Errorf("unhandled type to emit row scan: %s %T", typ.BaseName(), typ)
		}
		if i < len(tq.Outputs)-1 {
			sb.WriteString(", ")
		}
	}
	return sb.String(), nil
}
EmitRowScanArgs emits the args to scan a single row from a pgx.Row or
pgx.Rows.
package golang
import (
	"fmt"
	"github.com/jschaf/pggen/internal/ast"
	"github.com/jschaf/pggen/internal/codegen/golang/gotype"
	"strconv"
	"strings"
)
type TemplatedPackage struct {
	Files []TemplatedFile  
}
type TemplatedFile struct {
	Pkg        TemplatedPackage  
	PkgPath    string            
	GoPkg      string            
	SourcePath string            
	Queries    []TemplatedQuery  
	Imports    []string          
	IsLeader bool
	Declarers []Declarer
}
type TemplatedQuery struct {
	Name        string             
	SQLVarName  string             
	ResultKind  ast.ResultKind     
	Doc         string             
	PreparedSQL string             
	Inputs      []TemplatedParam   
	Outputs     []TemplatedColumn  
}
type TemplatedParam struct {
	UpperName string  
	LowerName string  
	QualType  string  
	Type      gotype.Type
}
type TemplatedColumn struct {
	PgName    string  
	UpperName string  
	LowerName string  
	Type      gotype.Type
	QualType  string  
}
func (tf TemplatedFile) needsPgconnImport() bool {
	if tf.IsLeader {
		return true
	}
	for _, query := range tf.Queries {
		if query.ResultKind == ast.ResultKindExec {
			return true  
		}
	}
	return false
}
func (tq TemplatedQuery) EmitPreparedSQL() string {
	if strings.ContainsRune(tq.PreparedSQL, '`') {
		return strconv.Quote(tq.PreparedSQL)
	}
	return "`" + tq.PreparedSQL + "`"
}
func (tq TemplatedQuery) EmitParams() string {
	switch len(tq.Inputs) {
	case 0:
		return ""
	case 1, 2:
		sb := strings.Builder{}
		for _, input := range tq.Inputs {
			sb.WriteString(", ")
			sb.WriteString(input.LowerName)
			sb.WriteRune(' ')
			sb.WriteString(input.QualType)
		}
		return sb.String()
	default:
		return ", params " + tq.Name + "Params"
	}
}
func getLongestInput(inputs []TemplatedParam) int {
	max := 0
	for _, in := range inputs {
		if len(in.UpperName) > max {
			max = len(in.UpperName)
		}
	}
	return max
}
func (tq TemplatedQuery) EmitParamStruct() string {
	if len(tq.Inputs) < 3 {
		return ""
	}
	sb := &strings.Builder{}
	sb.WriteString("\n\ntype ")
	sb.WriteString(tq.Name)
	sb.WriteString("Params struct {\n")
	typeCol := getLongestInput(tq.Inputs) + 1  
	for _, out := range tq.Inputs {
		sb.WriteString("\t")
		sb.WriteString(out.UpperName)
		sb.WriteString(strings.Repeat(" ", typeCol-len(out.UpperName)))
		sb.WriteString(out.QualType)
		sb.WriteRune('\n')
	}
	sb.WriteString("}")
	return sb.String()
}
func (tq TemplatedQuery) EmitParamNames() string {
	appendParam := func(sb *strings.Builder, typ gotype.Type, name string) {
		switch typ := typ.(type) {
		case gotype.CompositeType:
			sb.WriteString("q.types.")
			sb.WriteString(NameCompositeInitFunc(typ))
			sb.WriteString("(")
			sb.WriteString(name)
			sb.WriteString(")")
		case gotype.ArrayType:
			sb.WriteString("q.types.")
			sb.WriteString(NameArrayInitFunc(typ))
			sb.WriteString("(")
			sb.WriteString(name)
			sb.WriteString(")")
		default:
			sb.WriteString(name)
		}
	}
	switch len(tq.Inputs) {
	case 0:
		return ""
	case 1, 2:
		sb := &strings.Builder{}
		for _, input := range tq.Inputs {
			sb.WriteString(", ")
			appendParam(sb, input.Type, input.LowerName)
		}
		return sb.String()
	default:
		sb := &strings.Builder{}
		for _, input := range tq.Inputs {
			sb.WriteString(", ")
			appendParam(sb, input.Type, "params."+input.UpperName)
		}
		return sb.String()
	}
}