func (q *DBQuerier) Nested3Scan(results pgx.BatchResults) ([]ProductImageSetType, error) {
	rows, err := results.Query()
	if err != nil {
		return nil, fmt.Errorf("query Nested3Batch: %w", err)
	}
	defer rows.Close()
	items := []ProductImageSetType{}
	rowRow := q.types.newProductImageSetType()
	for rows.Next() {
		var item ProductImageSetType
		if err := rows.Scan(rowRow); err != nil {
			return nil, fmt.Errorf("scan Nested3Batch row: %w", err)
		}
		if err := rowRow.AssignTo(&item); err != nil {
			return nil, fmt.Errorf("assign Nested3 row: %w", err)
		}
		items = append(items, item)
	}
	if err := rows.Err(); err != nil {
		return nil, fmt.Errorf("close Nested3Batch rows: %w", err)
	}
	return items, err
}
Nested3Scan implements Querier.Nested3Scan.
package nested
import (
	"context"
	"fmt"
	"github.com/jackc/pgconn"
	"github.com/jackc/pgtype"
	"github.com/jackc/pgx/v4"
)
type Querier interface {
	ArrayNested2(ctx context.Context) ([]ProductImageType, error)
	ArrayNested2Batch(batch genericBatch)
	ArrayNested2Scan(results pgx.BatchResults) ([]ProductImageType, error)
	Nested3(ctx context.Context) ([]ProductImageSetType, error)
	Nested3Batch(batch genericBatch)
	Nested3Scan(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, arrayNested2SQL, arrayNested2SQL); err != nil {
		return fmt.Errorf("prepare query 'ArrayNested2': %w", err)
	}
	if _, err := p.Prepare(ctx, nested3SQL, nested3SQL); err != nil {
		return fmt.Errorf("prepare query 'Nested3': %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) 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) newProductImageType() pgtype.ValueTranscoder {
	return tr.newCompositeValue(
		"product_image_type",
		compositeField{"source", "text", &pgtype.Text{}},
		compositeField{"dimensions", "dimensions", tr.newDimensions()},
	)
}
func (tr *typeResolver) newProductImageTypeArray() pgtype.ValueTranscoder {
	return tr.newArrayValue("_product_image_type", "product_image_type", tr.newProductImageType)
}
const arrayNested2SQL = `SELECT
  ARRAY [
    ROW ('img2', ROW (22, 22)::dimensions)::product_image_type,
    ROW ('img3', ROW (33, 33)::dimensions)::product_image_type
    ] AS images;`
func (q *DBQuerier) ArrayNested2(ctx context.Context) ([]ProductImageType, error) {
	ctx = context.WithValue(ctx, "pggen_query_name", "ArrayNested2")
	row := q.conn.QueryRow(ctx, arrayNested2SQL)
	item := []ProductImageType{}
	imagesArray := q.types.newProductImageTypeArray()
	if err := row.Scan(imagesArray); err != nil {
		return item, fmt.Errorf("query ArrayNested2: %w", err)
	}
	if err := imagesArray.AssignTo(&item); err != nil {
		return item, fmt.Errorf("assign ArrayNested2 row: %w", err)
	}
	return item, nil
}
func (q *DBQuerier) ArrayNested2Batch(batch genericBatch) {
	batch.Queue(arrayNested2SQL)
}
func (q *DBQuerier) ArrayNested2Scan(results pgx.BatchResults) ([]ProductImageType, error) {
	row := results.QueryRow()
	item := []ProductImageType{}
	imagesArray := q.types.newProductImageTypeArray()
	if err := row.Scan(imagesArray); err != nil {
		return item, fmt.Errorf("scan ArrayNested2Batch row: %w", err)
	}
	if err := imagesArray.AssignTo(&item); err != nil {
		return item, fmt.Errorf("assign ArrayNested2 row: %w", err)
	}
	return item, nil
}
const nested3SQL = `SELECT
  ROW (
    'name', -- name
    ROW ('img1', ROW (11, 11)::dimensions)::product_image_type, -- orig_image
    ARRAY [ --images
      ROW ('img2', ROW (22, 22)::dimensions)::product_image_type,
      ROW ('img3', ROW (33, 33)::dimensions)::product_image_type
      ]
    )::product_image_set_type;`
func (q *DBQuerier) Nested3(ctx context.Context) ([]ProductImageSetType, error) {
	ctx = context.WithValue(ctx, "pggen_query_name", "Nested3")
	rows, err := q.conn.Query(ctx, nested3SQL)
	if err != nil {
		return nil, fmt.Errorf("query Nested3: %w", err)
	}
	defer rows.Close()
	items := []ProductImageSetType{}
	rowRow := q.types.newProductImageSetType()
	for rows.Next() {
		var item ProductImageSetType
		if err := rows.Scan(rowRow); err != nil {
			return nil, fmt.Errorf("scan Nested3 row: %w", err)
		}
		if err := rowRow.AssignTo(&item); err != nil {
			return nil, fmt.Errorf("assign Nested3 row: %w", err)
		}
		items = append(items, item)
	}
	if err := rows.Err(); err != nil {
		return nil, fmt.Errorf("close Nested3 rows: %w", err)
	}
	return items, err
}
func (q *DBQuerier) Nested3Batch(batch genericBatch) {
	batch.Queue(nested3SQL)
}