Skip to content

feat: support generated (computed) columns via the generated tag#178

Open
h2zi wants to merge 2 commits into
go-gorm:masterfrom
h2zi:feat/generated-columns
Open

feat: support generated (computed) columns via the generated tag#178
h2zi wants to merge 2 commits into
go-gorm:masterfrom
h2zi:feat/generated-columns

Conversation

@h2zi

@h2zi h2zi commented Jun 25, 2026

Copy link
Copy Markdown

What this adds

Support for SQL Server computed columns through the generated struct tag, keeping the generation expression separate from the column type. Part of rounding out generated-column support across the GORM drivers (see go-gorm/postgres#345, go-gorm/sqlite#230, go-gorm/mysql#189). Relates to go-gorm/gorm#7191.

type Product struct {
    ID       uint    `gorm:"primaryKey"`
    Price    float64 `gorm:"type:decimal(10,2)"`
    Quantity int
    Total    float64 `gorm:"->;generated:price * quantity"` // [total] AS (price * quantity) PERSISTED
}
  • The generated value is taken verbatim as the expression of a computed column. SQL Server infers the column type from the expression, so the type is omitted, and PERSISTED stores the value (matching the STORED semantics used by the other drivers). Commas inside the expression are preserved, so generated:concat(a, b) works.
  • Combine with -> so GORM treats the column as read-only (SQL Server forbids writing computed columns).
  • The identity keyword is reserved for identity columns and is left to the existing IDENTITY(1,1) handling rather than being mistaken for an expression.

Implementation

DataTypeOf returns AS (<expr>) PERSISTED when a computed expression is present; the base column type is computed exactly as before otherwise.

Tests

Unit test TestDataTypeOfGeneratedColumn covers the PERSISTED computed clause, comma-safe expressions, and the reserved identity keyword. The full suite (including integration against the real SQL Server service) passes in CI.

Also: CI fix (separate commit)

The workflow matrix still pinned Go 1.19–1.21 while go.mod requires go 1.24.0, so every run — including on master — failed before building (invalid go version '1.24.0': must match format 1.23). A second commit switches the matrix to oldstable/stable, matching the other GORM driver repos, which is what makes the suite above actually runnable again. Happy to split this into its own PR if preferred.

🤖 Generated with Claude Code

Copilot AI review requested due to automatic review settings June 25, 2026 12:11

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds SQL Server support for GORM’s generated (computed) columns by recognizing a generated tag and emitting SQL Server’s computed-column clause (AS (<expr>) PERSISTED) instead of a normal data type, aligning behavior with generated-column support in other GORM drivers.

Changes:

  • Update Dialector.DataTypeOf to return AS (<expr>) PERSISTED when the GENERATED tag is present and not reserved for identity.
  • Add parsing helpers to extract/validate the computed expression and avoid treating identity as a computed expression.
  • Add a unit test covering computed clause rendering, comma-safe expressions, and identity keyword handling.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
sqlserver.go Detects generated tag and emits SQL Server computed-column DDL (AS (...) PERSISTED), with helpers to avoid identity conflicts.
generated_test.go Adds unit coverage for computed column rendering and identity keyword handling.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

h2zi and others added 2 commits June 25, 2026 21:06
Render SQL Server computed columns from a `generated` tag, keeping the
generation expression separate from the column type. SQL Server infers a
computed column's type from its expression, so the type is omitted and the
value is PERSISTED (stored):

  Total float64 `gorm:"->;generated:price * quantity"`
  // -> [total] AS (price * quantity) PERSISTED

The expression is taken verbatim, so commas inside it (e.g. concat(a, b)) are
preserved; combine with the `->` read-only permission. The `identity` keyword
is reserved for identity columns and is rendered through SQL Server's native
IDENTITY, so it is not treated as a computed-column expression.

Relates to go-gorm/gorm#7191

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The module requires `go 1.24.0`, but the workflow matrix still pinned Go
1.19–1.21, which cannot parse the go.mod ("invalid go version '1.24.0': must
match format 1.23") and failed every run before building. Use oldstable/stable,
matching the other GORM driver repositories.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@h2zi h2zi force-pushed the feat/generated-columns branch from 8e4d774 to 9516e9e Compare June 25, 2026 13:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants