func (tr *typeResolver) newProductImageTypeArrayRaw(vs []ProductImageType) []interface{} {
	elems := make([]interface{}, len(vs))
	for i, v := range vs {
		elems[i] = tr.newProductImageTypeRaw(v)
	}
	return elems
}
newProductImageTypeArrayRaw returns all elements for the Postgres array type '_product_image_type'
as a slice of interface{} for use with the pgtype.Value Set method.
package complex_params
import (
	"context"
	"fmt"
	"github.com/jackc/pgconn"
	"github.com/jackc/pgtype"
	"github.com/jackc/pgx/v4"
)
type Querier interface {
	ParamArrayInt(ctx context.Context, ints []int) ([]int, error)
	ParamArrayIntBatch(batch genericBatch, ints []int)
	ParamArrayIntScan(results pgx.BatchResults) ([]int, error)
	ParamNested1(ctx context.Context, dimensions Dimensions) (Dimensions, error)
	ParamNested1Batch(batch genericBatch, dimensions Dimensions)
	ParamNested1Scan(results pgx.BatchResults) (Dimensions, error)
	ParamNested2(ctx context.Context, image ProductImageType) (ProductImageType, error)
	ParamNested2Batch(batch genericBatch, image ProductImageType)
	ParamNested2Scan(results pgx.BatchResults) (ProductImageType, error)
	ParamNested2Array(ctx context.Context, images []ProductImageType) ([]ProductImageType, error)
	ParamNested2ArrayBatch(batch genericBatch, images []ProductImageType)
	ParamNested2ArrayScan(results pgx.BatchResults) ([]ProductImageType, error)
	ParamNested3(ctx context.Context, imageSet ProductImageSetType) (ProductImageSetType, error)
	ParamNested3Batch(batch genericBatch, imageSet ProductImageSetType)
	ParamNested3Scan(results pgx.BatchResults) (ProductImageSetType, error)
}
type DBQuerier struct {
	conn  genericConn    
	types *typeResolver  
}
var _ Querier = &DBQuerier{}
type genericConn interface {
	Query(ctx context.Context, sql string, args ...interface{}) (pgx.Rows, error)
	QueryRow(ctx context.Context, sql string, args ...interface{}) pgx.Row
	Exec(ctx context.Context, sql string, arguments ...interface{}) (pgconn.CommandTag, error)
}
type genericBatch interface {
	Queue(query string, arguments ...interface{})
}
func NewQuerier(conn genericConn) *DBQuerier {
	return NewQuerierConfig(conn, QuerierConfig{})
}
type QuerierConfig struct {
	DataTypes []pgtype.DataType
}
func NewQuerierConfig(conn genericConn, cfg QuerierConfig) *DBQuerier {
	return &DBQuerier{conn: conn, types: newTypeResolver(cfg.DataTypes)}
}
func (q *DBQuerier) WithTx(tx pgx.Tx) (*DBQuerier, error) {
	return &DBQuerier{conn: tx}, nil
}
type preparer interface {
	Prepare(ctx context.Context, name, sql string) (sd *pgconn.StatementDescription, err error)
}
func PrepareAllQueries(ctx context.Context, p preparer) error {
	if _, err := p.Prepare(ctx, paramArrayIntSQL, paramArrayIntSQL); err != nil {
		return fmt.Errorf("prepare query 'ParamArrayInt': %w", err)
	}
	if _, err := p.Prepare(ctx, paramNested1SQL, paramNested1SQL); err != nil {
		return fmt.Errorf("prepare query 'ParamNested1': %w", err)
	}
	if _, err := p.Prepare(ctx, paramNested2SQL, paramNested2SQL); err != nil {
		return fmt.Errorf("prepare query 'ParamNested2': %w", err)
	}
	if _, err := p.Prepare(ctx, paramNested2ArraySQL, paramNested2ArraySQL); err != nil {
		return fmt.Errorf("prepare query 'ParamNested2Array': %w", err)
	}
	if _, err := p.Prepare(ctx, paramNested3SQL, paramNested3SQL); err != nil {
		return fmt.Errorf("prepare query 'ParamNested3': %w", err)
	}
	return nil
}
type Dimensions struct {
	Width  int `json:"width"`
	Height int `json:"height"`
}
type ProductImageSetType struct {
	Name      string             `json:"name"`
	OrigImage ProductImageType   `json:"orig_image"`
	Images    []ProductImageType `json:"images"`
}
type ProductImageType struct {
	Source     string     `json:"source"`
	Dimensions Dimensions `json:"dimensions"`
}
type typeResolver struct {
	connInfo *pgtype.ConnInfo  
}
func newTypeResolver(types []pgtype.DataType) *typeResolver {
	ci := pgtype.NewConnInfo()
	for _, typ := range types {
		if txt, ok := typ.Value.(textPreferrer); ok && typ.OID != unknownOID {
			typ.Value = txt.ValueTranscoder
		}
		ci.RegisterDataType(typ)
	}
	return &typeResolver{connInfo: ci}
}
func (tr *typeResolver) findValue(name string) (uint32, pgtype.ValueTranscoder, bool) {
	typ, ok := tr.connInfo.DataTypeForName(name)
	if !ok {
		return 0, nil, false
	}
	v := pgtype.NewValue(typ.Value)
	return typ.OID, v.(pgtype.ValueTranscoder), true
}
func (tr *typeResolver) setValue(vt pgtype.ValueTranscoder, val interface{}) pgtype.ValueTranscoder {
	if err := vt.Set(val); err != nil {
		panic(fmt.Sprintf("set ValueTranscoder %T to %+v: %s", vt, val, err))
	}
	return vt
}
type compositeField struct {
	name       string                  
	typeName   string                  
	defaultVal pgtype.ValueTranscoder  
}
func (tr *typeResolver) newCompositeValue(name string, fields ...compositeField) pgtype.ValueTranscoder {
	if _, val, ok := tr.findValue(name); ok {
		return val
	}
	fs := make([]pgtype.CompositeTypeField, len(fields))
	vals := make([]pgtype.ValueTranscoder, len(fields))
	isBinaryOk := true
	for i, field := range fields {
		oid, val, ok := tr.findValue(field.typeName)
		if !ok {
			oid = unknownOID
			val = field.defaultVal
		}
		isBinaryOk = isBinaryOk && oid != unknownOID
		fs[i] = pgtype.CompositeTypeField{Name: field.name, OID: oid}
		vals[i] = val
	}
	typ, _ := pgtype.NewCompositeTypeValues(name, fs, vals)
	if !isBinaryOk {
		return textPreferrer{typ, name}
	}
	return typ
}
func (tr *typeResolver) newArrayValue(name, elemName string, defaultVal func() pgtype.ValueTranscoder) pgtype.ValueTranscoder {
	if _, val, ok := tr.findValue(name); ok {
		return val
	}
	elemOID, elemVal, ok := tr.findValue(elemName)
	elemValFunc := func() pgtype.ValueTranscoder {
		return pgtype.NewValue(elemVal).(pgtype.ValueTranscoder)
	}
	if !ok {
		elemOID = unknownOID
		elemValFunc = defaultVal
	}
	typ := pgtype.NewArrayType(name, elemOID, elemValFunc)
	if elemOID == unknownOID {
		return textPreferrer{typ, name}
	}
	return typ
}
func (tr *typeResolver) newDimensions() pgtype.ValueTranscoder {
	return tr.newCompositeValue(
		"dimensions",
		compositeField{"width", "int4", &pgtype.Int4{}},
		compositeField{"height", "int4", &pgtype.Int4{}},
	)
}
func (tr *typeResolver) newDimensionsInit(v Dimensions) pgtype.ValueTranscoder {
	return tr.setValue(tr.newDimensions(), tr.newDimensionsRaw(v))
}
func (tr *typeResolver) newDimensionsRaw(v Dimensions) []interface{} {
	return []interface{}{
		v.Width,
		v.Height,
	}
}
func (tr *typeResolver) newProductImageSetType() pgtype.ValueTranscoder {
	return tr.newCompositeValue(
		"product_image_set_type",
		compositeField{"name", "text", &pgtype.Text{}},
		compositeField{"orig_image", "product_image_type", tr.newProductImageType()},
		compositeField{"images", "_product_image_type", tr.newProductImageTypeArray()},
	)
}
func (tr *typeResolver) newProductImageSetTypeInit(v ProductImageSetType) pgtype.ValueTranscoder {
	return tr.setValue(tr.newProductImageSetType(), tr.newProductImageSetTypeRaw(v))
}
func (tr *typeResolver) newProductImageSetTypeRaw(v ProductImageSetType) []interface{} {
	return []interface{}{
		v.Name,
		tr.newProductImageTypeRaw(v.OrigImage),
		tr.newProductImageTypeArrayRaw(v.Images),
	}
}
func (tr *typeResolver) newProductImageType() pgtype.ValueTranscoder {
	return tr.newCompositeValue(
		"product_image_type",
		compositeField{"source", "text", &pgtype.Text{}},
		compositeField{"dimensions", "dimensions", tr.newDimensions()},
	)
}
func (tr *typeResolver) newProductImageTypeInit(v ProductImageType) pgtype.ValueTranscoder {
	return tr.setValue(tr.newProductImageType(), tr.newProductImageTypeRaw(v))
}
func (tr *typeResolver) newProductImageTypeRaw(v ProductImageType) []interface{} {
	return []interface{}{
		v.Source,
		tr.newDimensionsRaw(v.Dimensions),
	}
}
func (tr *typeResolver) newProductImageTypeArray() pgtype.ValueTranscoder {
	return tr.newArrayValue("_product_image_type", "product_image_type", tr.newProductImageType)
}
func (tr *typeResolver) newProductImageTypeArrayInit(ps []ProductImageType) pgtype.ValueTranscoder {
	dec := tr.newProductImageTypeArray()
	if err := dec.Set(tr.newProductImageTypeArrayRaw(ps)); err != nil {
		panic("encode []ProductImageType: " + err.Error())  
	}
	return textPreferrer{ValueTranscoder: dec, typeName: "_product_image_type"}
}