Generate Bun-native PostgreSQL array fields with configurable nullable representation #13

Closed
opened 2026-07-20 20:33:57 +00:00 by warkanum · 1 comment
Owner

Problem

relspecgo currently generates PostgreSQL array columns such as text[] as wrapper structs:

Tags sqltypes.SqlStringArray `bun:"tags,type:text[]" json:"tags"`

Bun does not reliably scan these generated wrapper fields and returns:

bun: Scan(unsupported sqltypes.SqlStringArray)

Buns documented model representation for PostgreSQL arrays is a native Go slice with the array field option:

Tags []string `bun:"tags,array,type:text[]" json:"tags"`

## Requested change

Add Bun-specific, configurable PostgreSQL array generation.

When generating Bun models, map PostgreSQL arrays to native slice types and include array in the Bun tag:

 PostgreSQL           Go type
━━━━━━━━━━━━━━━━━━━  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 text[], varchar[]    []string
───────────────────  ────────────────────────────────────
 bigint[]             []int64
───────────────────  ────────────────────────────────────
 integer[]            []int / []int32
───────────────────  ────────────────────────────────────
 boolean[]            []bool
───────────────────  ────────────────────────────────────
 uuid[]               []uuid.UUID
───────────────────  ────────────────────────────────────
 jsonb[]              configurable / documented fallback

Example output:

Tags []string `bun:"tags,array,type:text[],default:'{}',notnull" json:"tags"`

## Nullability

Make nullable-array generation configurable:

- []T for NOT NULL columns.
- *[]T for nullable columns when callers must distinguish:
    - nil  SQL NULL
    - &[]T{}  {}

A configuration shape could be:

generators:
  bun:
    native_array_types: true
    nullable_arrays: pointer_slice

## Acceptance criteria

- Generated Bun models add ,array for PostgreSQL array columns.
- text[] generates as []string (or *[]string when configured/nullable).
- Existing non-Bun targets may continue using sqltypes.SqlStringArray.
- Add integration tests that insert and select NULL, {}, and populated arrays using Bun.
- Regeneration is deterministic and does not require hand-editing generated models.

## References

Bun PostgreSQL array docs:
https://bun.uptrace.dev/postgres/postgres-arrays.html
## Problem relspecgo currently generates PostgreSQL array columns such as `text[]` as wrapper structs: ```go Tags sqltypes.SqlStringArray `bun:"tags,type:text[]" json:"tags"` Bun does not reliably scan these generated wrapper fields and returns: bun: Scan(unsupported sqltypes.SqlStringArray) Bun’s documented model representation for PostgreSQL arrays is a native Go slice with the array field option: Tags []string `bun:"tags,array,type:text[]" json:"tags"` ## Requested change Add Bun-specific, configurable PostgreSQL array generation. When generating Bun models, map PostgreSQL arrays to native slice types and include array in the Bun tag: PostgreSQL Go type ━━━━━━━━━━━━━━━━━━━ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ text[], varchar[] []string ─────────────────── ──────────────────────────────────── bigint[] []int64 ─────────────────── ──────────────────────────────────── integer[] []int / []int32 ─────────────────── ──────────────────────────────────── boolean[] []bool ─────────────────── ──────────────────────────────────── uuid[] []uuid.UUID ─────────────────── ──────────────────────────────────── jsonb[] configurable / documented fallback Example output: Tags []string `bun:"tags,array,type:text[],default:'{}',notnull" json:"tags"` ## Nullability Make nullable-array generation configurable: - []T for NOT NULL columns. - *[]T for nullable columns when callers must distinguish: - nil → SQL NULL - &[]T{} → {} A configuration shape could be: generators: bun: native_array_types: true nullable_arrays: pointer_slice ## Acceptance criteria - Generated Bun models add ,array for PostgreSQL array columns. - text[] generates as []string (or *[]string when configured/nullable). - Existing non-Bun targets may continue using sqltypes.SqlStringArray. - Add integration tests that insert and select NULL, {}, and populated arrays using Bun. - Regeneration is deterministic and does not require hand-editing generated models. ## References Bun PostgreSQL array docs: https://bun.uptrace.dev/postgres/postgres-arrays.html
Author
Owner

Fixed in commit 5d9ff5d.

What changed (pkg/writers/bun):

  • Array columns (text[], integer[], uuid[], ...) always generate as native Go slices ([]string, []int32, ...) with an explicit array bun tag and plain type:text[], in every --types mode (sqltypes/stdlib/baselib). The SqlXxxArray wrapper types are no longer used for Bun array columns.
  • Nullable arrays: pass --array-nullable pointer_slice to generate *[]string instead of []string for nullable array columns, so callers can distinguish SQL NULL (nil pointer) from '{}' (pointer to an empty slice). NOT NULL array columns are unaffected. Default remains "slice" (plain []T always) for backwards compatibility.
  • Example output: Tags []string \bun:"tags,array,type:text[],default:'{}',notnull,` json:"tags"`, or Tags *[]string `bun:"tags,array,type:text[],nullzero,` json:"tags"`` with --array-nullable pointer_slice.

Verification: Ran live against a real PostgreSQL instance (not just unit tests) — inserted/selected NULL, {}, and populated arrays for both NOT NULL and nullable columns, and confirmed native slice fields scan correctly alongside sql_types.SqlString-style scalar fields in the same model. Added pkg/writers/bun/array_integration_test.go (gated on RELSPEC_TEST_PG_CONN, same convention as the existing pgsql reader tests) covering these cases, plus unit tests for the type-mapper changes.

Note: gorm output is unaffected — it still uses the SqlXxxArray wrapper types from pkg/sqltypes.

Docs updated in pkg/writers/bun/README.md and the root README.md.

Fixed in commit 5d9ff5d. **What changed (pkg/writers/bun):** - Array columns (text[], integer[], uuid[], ...) always generate as native Go slices ([]string, []int32, ...) with an explicit `array` bun tag and plain `type:text[]`, in every --types mode (sqltypes/stdlib/baselib). The SqlXxxArray wrapper types are no longer used for Bun array columns. - Nullable arrays: pass --array-nullable pointer_slice to generate *[]string instead of []string for nullable array columns, so callers can distinguish SQL NULL (nil pointer) from '{}' (pointer to an empty slice). NOT NULL array columns are unaffected. Default remains "slice" (plain []T always) for backwards compatibility. - Example output: `Tags []string \`bun:"tags,array,type:text[],default:'{}',notnull,\` json:"tags"\``, or `Tags *[]string \`bun:"tags,array,type:text[],nullzero,\` json:"tags"\`` with --array-nullable pointer_slice. **Verification:** Ran live against a real PostgreSQL instance (not just unit tests) — inserted/selected NULL, {}, and populated arrays for both NOT NULL and nullable columns, and confirmed native slice fields scan correctly alongside sql_types.SqlString-style scalar fields in the same model. Added pkg/writers/bun/array_integration_test.go (gated on RELSPEC_TEST_PG_CONN, same convention as the existing pgsql reader tests) covering these cases, plus unit tests for the type-mapper changes. **Note:** gorm output is unaffected — it still uses the SqlXxxArray wrapper types from pkg/sqltypes. Docs updated in pkg/writers/bun/README.md and the root README.md.
Sign in to join this conversation.
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: wdevs/relspecgo#13