gotypes

package
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 31, 2026 License: MIT Imports: 6 Imported by: 0

Documentation

Overview

Package gotypes maps PostgreSQL types to Go types for sqld code generators. It is the single source of truth shared by sqld-gen-go and sqld-gen-bob so both plugins emit identical Go types for the same catalog.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CollectUsedExtensionTypes

func CollectUsedExtensionTypes(catalog *irv1.Catalog, queries []*pluginv1.Query) []string

CollectUsedExtensionTypes scans the catalog (all schemas → tables → columns) and the query result columns + parameters for extension types (hstore, ltree, lquery) that are actually used, returning their names sorted for deterministic output. Only used extension types are registered in RegisterTypes.

func CompositeDepName

func CompositeDepName(reg *Registry, t *irv1.TypeRef) string

CompositeDepName returns the bare name of the composite type that t depends on, or "" if t does not (transitively) resolve to a composite. It follows array element types (a field of `address[]` depends on `address`) and domains (transparently, to their base type). The returned name is the registry key (bare PostgreSQL type name), suitable for building the composite dependency graph used to topologically order RegisterTypes.

func IsCompositeType

func IsCompositeType(reg *Registry, t *irv1.TypeRef) bool

IsCompositeType reports whether t resolves (through the registry) to a composite type. Domains are followed transparently to their base type.

func LowerCamel

func LowerCamel(s string) string

LowerCamel converts to lowerCamelCase.

func ParseOverrideValue

func ParseOverrideValue(v string) (goExpr string, imports []string)

ParseOverrideValue is the exported form of parseOverrideValue, used by callers (and tests) that need to resolve an override value directly.

func Pascal

func Pascal(s string) string

Pascal converts a snake_case name to PascalCase applying Go initialisms.

func UDTName

func UDTName(schema, name string) string

UDTName returns the Go identifier for a UDT given its schema and bare name. public (or empty) schema → no prefix; other schemas → Pascal(schema) prefix.

Types

type Mapper

type Mapper struct {
	// contains filtered or unexported fields
}

Mapper maps PostgreSQL TypeRefs to Go type expressions using a UDT registry, an override table, and a null-wrapping mode.

func NewMapper

func NewMapper(cat *irv1.Catalog, ov Overrides, null NullMode) *Mapper

NewMapper builds a registry from cat and returns a Mapper.

func NewMapper2

func NewMapper2(reg *Registry, ov Overrides, null NullMode) *Mapper

NewMapper2 returns a Mapper that uses an existing registry.

func (*Mapper) GoType

func (m *Mapper) GoType(columnID string, t *irv1.TypeRef, nullable bool) (goExpr string, imports []string)

GoType chooses the Go type for a value, applying overrides before falling back to the default mapping. Precedence:

  1. an override keyed by the (non-empty) columnID;
  2. an override keyed by the TypeRef's PostgreSQL name;
  3. the default mapping.

For override hits, a nullable value is wrapped via wrapNull unless the override Go type already has a nil-capable zero value.

func (*Mapper) IsNullWrapped

func (m *Mapper) IsNullWrapped(columnID string, t *irv1.TypeRef, nullable bool) bool

IsNullWrapped reports whether a nullable column maps to a WRAPPED Go field (a pointer *T in sqld-gen-go's default Pointer mode, or null.Val[T] in Opt mode) rather than to a nil-capable value type (slices, maps, json.RawMessage, the pgtype struct/range/multirange types) that already carries SQL NULL in its own zero value. A non-nullable column is never wrapped.

It is the single source of truth for the ToSqld bridge: a wrapped field needs a null-unwrapping conversion (".Ptr()" in pointer mode; a direct copy in opt mode, since both sides are null.Val), whereas a nil-capable value field is converted from bob's null.Val[T] via ".GetOrZero()".

Overrides are honoured exactly as GoType resolves them, so an override that yields a nil-capable Go type (e.g. "map[string]any") is reported unwrapped.

func (*Mapper) ParamType

func (m *Mapper) ParamType(columnID string, t *irv1.TypeRef, nullable bool) (goExpr string, imports []string)

ParamType maps a query parameter's TypeRef to a Go type. It matches GoType except that a composite parameter is always emitted as a value type (never a pointer): the generated composite codec reports IsNull()==false, so a NULL composite cannot be encoded and a pointer field would be meaningless. The caller passes the composite by value (e.g. SetAddressParams{Address: AppAddress{...}}).

An override (by column id or type name) wins, otherwise it falls back to the composite-aware default mapping.

func (*Mapper) Registry

func (m *Mapper) Registry() *Registry

Registry returns the Mapper's UDT registry.

func (*Mapper) SetUDTPackage

func (m *Mapper) SetUDTPackage(alias, importPath string) *Mapper

SetUDTPackage makes the Mapper qualify enum/composite Go type names with the given package alias and add importPath (a raw, unquoted import path — the same form scalarGoType returns) to their imports. With an empty alias the Mapper emits unqualified UDT names (the default). Returns the Mapper for chaining.

func (*Mapper) UDTName

func (m *Mapper) UDTName(schema, pgName string) string

UDTName returns the Go identifier for a UDT given its schema and bare name.

type NullMode

type NullMode int

NullMode selects how a nullable column's Go type is wrapped.

const (
	// Pointer wraps nullable scalars/enums/composites/overrides in a pointer
	// (*T), leaving nil-capable types (slices, maps, json.RawMessage, pgtype
	// struct/range types) unwrapped. This is the historical sqld-gen-go mode.
	Pointer NullMode = iota
	// Opt wraps nullable values in null.Val[T] (github.com/aarondl/opt/null),
	// leaving the same nil-capable types unwrapped. Used by sqld-gen-bob.
	Opt
)

type Overrides

type Overrides map[string]string

Overrides is a Go-type override table parsed from the plugin's options. Each key is EITHER a fully-qualified column id ("schema.table.column") OR a bare PostgreSQL type name (matched against TypeRef.PgName); each value is a Go type specification (see parseOverrideValue). Column-id overrides take precedence over type-name overrides, which take precedence over the default mapping.

type Registry

type Registry struct {
	// contains filtered or unexported fields
}

Registry is an index of all UDTs in the catalog, keyed by bare type name (the Name.Name field — not schema-qualified). When two schemas define a type with the same bare name the first one wins; that matches the PostgreSQL search_path behaviour that the host already applied.

func BuildRegistry

func BuildRegistry(catalog *irv1.Catalog) *Registry

BuildRegistry walks catalog schemas and builds a flat lookup table.

func (*Registry) CompositeSchema

func (r *Registry) CompositeSchema(pgName string) (string, bool)

CompositeSchema returns the schema a composite was declared in, and ok=false when pgName is not a registered composite.

func (*Registry) EnumSchema

func (r *Registry) EnumSchema(pgName string) (string, bool)

EnumSchema returns the schema an enum was declared in, and ok=false when pgName is not a registered enum.

func (*Registry) IsComposite

func (r *Registry) IsComposite(pgName string) bool

IsComposite reports whether pgName (bare PostgreSQL type name) is a registered composite type.

func (*Registry) IsEnum

func (r *Registry) IsEnum(pgName string) bool

IsEnum reports whether pgName (bare PostgreSQL type name) is a registered enum.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL