Skip to content

Support automatically appending ,string to JSON tags for numeric types (e.g. BIGINT → int64 with json:",string") #4124

@LuoShenKui

Description

@LuoShenKui

💡 Summary

Currently, sqlc does not provide a way to globally append ,string to JSON tags for numeric types like BIGINT while preserving the Go type as int64. This feature is important for frontend applications (e.g. JavaScript / TypeScript), which cannot safely handle 64-bit integers as numbers due to precision limitations.


🧠 Background / Problem

In modern frontend–backend setups, it's common to use JavaScript or TypeScript on the frontend. Since JavaScript numbers are IEEE 754 doubles, integers larger than 2^53 - 1 lose precision.

For example:

CREATE TABLE users (
  id BIGINT PRIMARY KEY,
  name TEXT
);

sqlc currently generates:

type User struct {
  ID   int64  `json:"id"`
  Name string `json:"name"`
}

If the id is 9007199254740993, the frontend will receive:

{ "id": 9007199254740992 }   // ❌ precision lost

The ideal JSON tag would be:

type User struct {
  ID   int64  `json:"id,string"`
  Name string `json:"name"`
}

This allows Go to keep using int64 internally (safe for arithmetic) while ensuring the frontend receives the value as a string, avoiding precision loss.


📌 Current Workarounds

  1. Per-column go_struct_tag overrides

    overrides:
      - column: "public.users.id"
        go_struct_tag: 'json:"id,string" db:"id"'

    ➡ Works, but is tedious when you have many bigint columns across many tables.

  2. Custom wrapper types (e.g. Int64String)
    Replace all BIGINT types with a custom Go type that implements MarshalJSON and UnmarshalJSON.
    ➡ Works globally, but requires additional type definitions and breaks the simplicity of using int64 directly.

There is currently no way to tell sqlc:

“For all BIGINT columns, keep the Go type as int64 but append ,string to the generated JSON tag.”


🚀 Proposed Solution

Add a new configuration option to globally append JSON tag suffixes (e.g. ,string) for specific DB types.

Example 1: New global option

gen:
  go:
    json_tag_suffix_for_types:
      - db_type: "pg_catalog.int8"
        suffix: ",string"

Example 2: Extend overrides to support JSON suffix

overrides:
  - db_type: "pg_catalog.int8"
    json_tag_suffix: ",string"

Expected generated code:

type User struct {
  ID   int64  `json:"id,string"`
  Name string `json:"name"`
}

Benefits

  • No need to define custom types just to get correct JSON output.
  • No need to write dozens or hundreds of per-column overrides.
  • Preserves int64 for arithmetic while fixing frontend precision issues.
  • Makes sqlc more ergonomic for modern web projects.

🧪 Environment

  • sqlc version: v2.x
  • Database: PostgreSQL
  • Language: Go
  • Use case: Backend API for JS/TS frontend

🙏 Thank you

This feature would make sqlc much more convenient for teams building modern web applications with PostgreSQL and Go.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions