Skip to content

[MsSql] Exclude generated columns from INSERT column list#5882

Open
valerii-kuzivanov wants to merge 1 commit into
drizzle-team:betafrom
valerii-kuzivanov:fix-mssql-generated-columns-insert
Open

[MsSql] Exclude generated columns from INSERT column list#5882
valerii-kuzivanov wants to merge 1 commit into
drizzle-team:betafrom
valerii-kuzivanov:fix-mssql-generated-columns-insert

Conversation

@valerii-kuzivanov

Copy link
Copy Markdown

Fixes #5881

Problem

The MSSQL dialect's buildInsertQuery emits every table column in the INSERT column list, filling missing values with the default keyword. MsSqlColumn overrides shouldDisableInsert() with a hardcoded false, so generatedAlwaysAs() (computed) columns are included too — and SQL Server rejects any mention of a computed column in an INSERT column list, even with DEFAULT:

Msg 271: The column "value_upper" cannot be modified because it is either a computed column or is the result of a UNION operator.
const docs = mssqlTable('docs', {
	id: int().identity(),
	value: nvarchar({ length: 'max' }).notNull(),
	valueUpper: nvarchar('value_upper', { length: 450 }).generatedAlwaysAs(sql`upper([value])`),
});

db.insert(docs).values({ value: 'hello' }).toSQL().sql;
// before: insert into [docs] ([value], [value_upper]) values (@par0, default)  → Msg 271
// after:  insert into [docs] ([value]) values (@par0)

This blocks inserting into any table with a computed column — including schemas produced by drizzle-kit pull, which introspects SQL Server computed columns into generatedAlwaysAs().

Fix

  • Remove the MsSqlColumn.shouldDisableInsert() override so the base Column logic applies (the MSSQL generatedAlwaysAs() builder always sets generated.type: 'always', so computed columns are excluded). No other dialect overrides this method on its base column class.
  • MsSqlColumnWithIdentity.shouldDisableInsert() now combines its identity exclusion with the inherited check.

Tests

  • Added insert into table with generated column to integration-tests/tests/mssql/mssql.test.ts: creates a table with a computed column, inserts through the query builder, and reads the computed value back. Fails with Msg 271 before the fix, passes after.
  • Full MSSQL integration suite is green locally against mcr.microsoft.com/azure-sql-edge: mssql.test.ts 159 passed / 0 failed; mssql.custom.test.ts + mssql.prefixed.test.ts + mssql.rels.test.ts 186 passed / 0 failed.

MsSqlColumn overrode shouldDisableInsert() with a hardcoded false,
masking the base Column logic that excludes generatedAlwaysAs columns
from inserts. As a result buildInsertQuery listed computed columns
with the `default` keyword and SQL Server rejected the statement with
error 271 ("The column cannot be modified because it is either a
computed column or is the result of a UNION operator").

Remove the override so the base logic applies, and keep the identity
exclusion in MsSqlColumnWithIdentity combined with the inherited check.

Fixes drizzle-team#5881
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.

1 participant