From a83792b775585d77fafdad6468b14d023aacb627 Mon Sep 17 00:00:00 2001 From: Matan Kushner Date: Thu, 6 Nov 2025 21:33:56 +0900 Subject: [PATCH 1/5] Pass db casing during json generation --- drizzle-kit/src/api.ts | 12 ++++++++---- drizzle-orm/src/casing.ts | 2 ++ drizzle-orm/src/gel-core/db.ts | 1 - drizzle-orm/src/gel-core/dialect.ts | 1 - drizzle-orm/src/mysql-core/db.ts | 1 - drizzle-orm/src/mysql-core/dialect.ts | 1 - drizzle-orm/src/pg-core/db.ts | 1 - drizzle-orm/src/pg-core/dialect.ts | 1 - drizzle-orm/src/singlestore-core/db.ts | 1 - drizzle-orm/src/singlestore-core/dialect.ts | 1 - drizzle-orm/src/sqlite-core/db.ts | 1 - drizzle-orm/src/sqlite-core/dialect.ts | 1 - 12 files changed, 10 insertions(+), 14 deletions(-) diff --git a/drizzle-kit/src/api.ts b/drizzle-kit/src/api.ts index 83e593dbd6..f48a6b4341 100644 --- a/drizzle-kit/src/api.ts +++ b/drizzle-kit/src/api.ts @@ -141,7 +141,8 @@ export const pushSchema = async ( }, }; - const cur = generateDrizzleJson(imports); + const casing = drizzleInstance.dialect.casing.casing; + const cur = generateDrizzleJson(imports, undefined, schemaFilters, casing); const { schema: prev } = await pgPushIntrospect( db, filters, @@ -285,7 +286,8 @@ export const pushSQLiteSchema = async ( }, }; - const cur = await generateSQLiteDrizzleJson(imports); + const casing = drizzleInstance.dialect.casing.casing; + const cur = await generateSQLiteDrizzleJson(imports, undefined, casing); const { schema: prev } = await sqlitePushIntrospect(db, []); const validatedPrev = sqliteSchema.parse(prev); @@ -422,7 +424,8 @@ export const pushMySQLSchema = async ( return res[0] as unknown as any[]; }, }; - const cur = await generateMySQLDrizzleJson(imports); + const casing = drizzleInstance.dialect.casing.casing; + const cur = await generateMySQLDrizzleJson(imports, undefined, casing); const { schema: prev } = await mysqlPushIntrospect(db, databaseName, []); const validatedPrev = mysqlSchema.parse(prev); @@ -558,7 +561,8 @@ export const pushSingleStoreSchema = async ( return res[0] as unknown as any[]; }, }; - const cur = await generateSingleStoreDrizzleJson(imports); + const casing = drizzleInstance.dialect.casing.casing; + const cur = await generateSingleStoreDrizzleJson(imports, undefined, casing); const { schema: prev } = await singlestorePushIntrospect(db, databaseName, []); const validatedPrev = singlestoreSchema.parse(prev); diff --git a/drizzle-orm/src/casing.ts b/drizzle-orm/src/casing.ts index 8372227b3c..85514f84c1 100644 --- a/drizzle-orm/src/casing.ts +++ b/drizzle-orm/src/casing.ts @@ -33,8 +33,10 @@ export class CasingCache { cache: Record = {}; private cachedTables: Record = {}; private convert: (input: string) => string; + readonly casing?: Casing; constructor(casing?: Casing) { + this.casing = casing; this.convert = casing === 'snake_case' ? toSnakeCase : casing === 'camelCase' diff --git a/drizzle-orm/src/gel-core/db.ts b/drizzle-orm/src/gel-core/db.ts index 6f73b80c4b..9baf88464d 100644 --- a/drizzle-orm/src/gel-core/db.ts +++ b/drizzle-orm/src/gel-core/db.ts @@ -45,7 +45,6 @@ export class GelDatabase< }; constructor( - /** @internal */ readonly dialect: GelDialect, /** @internal */ readonly session: GelSession, diff --git a/drizzle-orm/src/gel-core/dialect.ts b/drizzle-orm/src/gel-core/dialect.ts index 5b40dfdb01..37fae33d66 100644 --- a/drizzle-orm/src/gel-core/dialect.ts +++ b/drizzle-orm/src/gel-core/dialect.ts @@ -51,7 +51,6 @@ export interface GelDialectConfig { export class GelDialect { static readonly [entityKind]: string = 'GelDialect'; - /** @internal */ readonly casing: CasingCache; constructor(config?: GelDialectConfig) { diff --git a/drizzle-orm/src/mysql-core/db.ts b/drizzle-orm/src/mysql-core/db.ts index e857188595..79ee25de52 100644 --- a/drizzle-orm/src/mysql-core/db.ts +++ b/drizzle-orm/src/mysql-core/db.ts @@ -52,7 +52,6 @@ export class MySqlDatabase< }; constructor( - /** @internal */ readonly dialect: MySqlDialect, /** @internal */ readonly session: MySqlSession, diff --git a/drizzle-orm/src/mysql-core/dialect.ts b/drizzle-orm/src/mysql-core/dialect.ts index 0014dd303f..b1f0b5fd15 100644 --- a/drizzle-orm/src/mysql-core/dialect.ts +++ b/drizzle-orm/src/mysql-core/dialect.ts @@ -44,7 +44,6 @@ export interface MySqlDialectConfig { export class MySqlDialect { static readonly [entityKind]: string = 'MySqlDialect'; - /** @internal */ readonly casing: CasingCache; constructor(config?: MySqlDialectConfig) { diff --git a/drizzle-orm/src/pg-core/db.ts b/drizzle-orm/src/pg-core/db.ts index 235efc0737..2529bd32bf 100644 --- a/drizzle-orm/src/pg-core/db.ts +++ b/drizzle-orm/src/pg-core/db.ts @@ -54,7 +54,6 @@ export class PgDatabase< }; constructor( - /** @internal */ readonly dialect: PgDialect, /** @internal */ readonly session: PgSession, diff --git a/drizzle-orm/src/pg-core/dialect.ts b/drizzle-orm/src/pg-core/dialect.ts index 59ec42b169..b2089bb6be 100644 --- a/drizzle-orm/src/pg-core/dialect.ts +++ b/drizzle-orm/src/pg-core/dialect.ts @@ -63,7 +63,6 @@ export interface PgDialectConfig { export class PgDialect { static readonly [entityKind]: string = 'PgDialect'; - /** @internal */ readonly casing: CasingCache; constructor(config?: PgDialectConfig) { diff --git a/drizzle-orm/src/singlestore-core/db.ts b/drizzle-orm/src/singlestore-core/db.ts index 598a05a587..bfba45958e 100644 --- a/drizzle-orm/src/singlestore-core/db.ts +++ b/drizzle-orm/src/singlestore-core/db.ts @@ -47,7 +47,6 @@ export class SingleStoreDatabase< query: unknown; constructor( - /** @internal */ readonly dialect: SingleStoreDialect, /** @internal */ readonly session: SingleStoreSession, diff --git a/drizzle-orm/src/singlestore-core/dialect.ts b/drizzle-orm/src/singlestore-core/dialect.ts index 359809b0e9..579a7547db 100644 --- a/drizzle-orm/src/singlestore-core/dialect.ts +++ b/drizzle-orm/src/singlestore-core/dialect.ts @@ -43,7 +43,6 @@ export interface SingleStoreDialectConfig { export class SingleStoreDialect { static readonly [entityKind]: string = 'SingleStoreDialect'; - /** @internal */ readonly casing: CasingCache; constructor(config?: SingleStoreDialectConfig) { diff --git a/drizzle-orm/src/sqlite-core/db.ts b/drizzle-orm/src/sqlite-core/db.ts index 9cea9ecaae..cc1fa6201d 100644 --- a/drizzle-orm/src/sqlite-core/db.ts +++ b/drizzle-orm/src/sqlite-core/db.ts @@ -51,7 +51,6 @@ export class BaseSQLiteDatabase< constructor( private resultKind: TResultKind, - /** @internal */ readonly dialect: { sync: SQLiteSyncDialect; async: SQLiteAsyncDialect }[TResultKind], /** @internal */ readonly session: SQLiteSession, diff --git a/drizzle-orm/src/sqlite-core/dialect.ts b/drizzle-orm/src/sqlite-core/dialect.ts index 2f4a0c366d..81bf3f172c 100644 --- a/drizzle-orm/src/sqlite-core/dialect.ts +++ b/drizzle-orm/src/sqlite-core/dialect.ts @@ -47,7 +47,6 @@ export interface SQLiteDialectConfig { export abstract class SQLiteDialect { static readonly [entityKind]: string = 'SQLiteDialect'; - /** @internal */ readonly casing: CasingCache; constructor(config?: SQLiteDialectConfig) { From b2384e9c85a029326a65d225a37c4050eaeafb72 Mon Sep 17 00:00:00 2001 From: Matan Kushner Date: Fri, 7 Nov 2025 09:20:57 +0900 Subject: [PATCH 2/5] Simplify and re-add @internal --- drizzle-kit/src/api.ts | 12 ++++-------- drizzle-orm/src/gel-core/db.ts | 1 + drizzle-orm/src/gel-core/dialect.ts | 1 + drizzle-orm/src/mysql-core/db.ts | 6 +++++- drizzle-orm/src/mysql-core/dialect.ts | 1 + drizzle-orm/src/pg-core/db.ts | 6 +++++- drizzle-orm/src/pg-core/dialect.ts | 1 + drizzle-orm/src/singlestore-core/db.ts | 5 +++++ drizzle-orm/src/singlestore-core/dialect.ts | 1 + drizzle-orm/src/sqlite-core/db.ts | 6 +++++- drizzle-orm/src/sqlite-core/dialect.ts | 1 + 11 files changed, 30 insertions(+), 11 deletions(-) diff --git a/drizzle-kit/src/api.ts b/drizzle-kit/src/api.ts index f48a6b4341..7c269380c3 100644 --- a/drizzle-kit/src/api.ts +++ b/drizzle-kit/src/api.ts @@ -141,8 +141,7 @@ export const pushSchema = async ( }, }; - const casing = drizzleInstance.dialect.casing.casing; - const cur = generateDrizzleJson(imports, undefined, schemaFilters, casing); + const cur = generateDrizzleJson(imports, undefined, schemaFilters, drizzleInstance.casing); const { schema: prev } = await pgPushIntrospect( db, filters, @@ -286,8 +285,7 @@ export const pushSQLiteSchema = async ( }, }; - const casing = drizzleInstance.dialect.casing.casing; - const cur = await generateSQLiteDrizzleJson(imports, undefined, casing); + const cur = await generateSQLiteDrizzleJson(imports, undefined, drizzleInstance.casing); const { schema: prev } = await sqlitePushIntrospect(db, []); const validatedPrev = sqliteSchema.parse(prev); @@ -424,8 +422,7 @@ export const pushMySQLSchema = async ( return res[0] as unknown as any[]; }, }; - const casing = drizzleInstance.dialect.casing.casing; - const cur = await generateMySQLDrizzleJson(imports, undefined, casing); + const cur = await generateMySQLDrizzleJson(imports, undefined, drizzleInstance.casing); const { schema: prev } = await mysqlPushIntrospect(db, databaseName, []); const validatedPrev = mysqlSchema.parse(prev); @@ -561,8 +558,7 @@ export const pushSingleStoreSchema = async ( return res[0] as unknown as any[]; }, }; - const casing = drizzleInstance.dialect.casing.casing; - const cur = await generateSingleStoreDrizzleJson(imports, undefined, casing); + const cur = await generateSingleStoreDrizzleJson(imports, undefined, drizzleInstance.casing); const { schema: prev } = await singlestorePushIntrospect(db, databaseName, []); const validatedPrev = singlestoreSchema.parse(prev); diff --git a/drizzle-orm/src/gel-core/db.ts b/drizzle-orm/src/gel-core/db.ts index 9baf88464d..6f73b80c4b 100644 --- a/drizzle-orm/src/gel-core/db.ts +++ b/drizzle-orm/src/gel-core/db.ts @@ -45,6 +45,7 @@ export class GelDatabase< }; constructor( + /** @internal */ readonly dialect: GelDialect, /** @internal */ readonly session: GelSession, diff --git a/drizzle-orm/src/gel-core/dialect.ts b/drizzle-orm/src/gel-core/dialect.ts index 37fae33d66..5b40dfdb01 100644 --- a/drizzle-orm/src/gel-core/dialect.ts +++ b/drizzle-orm/src/gel-core/dialect.ts @@ -51,6 +51,7 @@ export interface GelDialectConfig { export class GelDialect { static readonly [entityKind]: string = 'GelDialect'; + /** @internal */ readonly casing: CasingCache; constructor(config?: GelDialectConfig) { diff --git a/drizzle-orm/src/mysql-core/db.ts b/drizzle-orm/src/mysql-core/db.ts index 79ee25de52..06dd45966f 100644 --- a/drizzle-orm/src/mysql-core/db.ts +++ b/drizzle-orm/src/mysql-core/db.ts @@ -6,7 +6,7 @@ import type { ExtractTablesWithRelations, RelationalSchemaConfig, TablesRelation import { SelectionProxyHandler } from '~/selection-proxy.ts'; import { type ColumnsSelection, type SQL, sql, type SQLWrapper } from '~/sql/sql.ts'; import { WithSubquery } from '~/subquery.ts'; -import type { DrizzleTypeError } from '~/utils.ts'; +import type { Casing, DrizzleTypeError } from '~/utils.ts'; import type { MySqlDialect } from './dialect.ts'; import { MySqlCountBuilder } from './query-builders/count.ts'; import { @@ -45,6 +45,8 @@ export class MySqlDatabase< readonly tableNamesMap: Record; }; + readonly casing: Casing | undefined; + query: TFullSchema extends Record ? DrizzleTypeError<'Seems like the schema generic is missing - did you forget to add it to your DB type?'> : { @@ -52,6 +54,7 @@ export class MySqlDatabase< }; constructor( + /** @internal */ readonly dialect: MySqlDialect, /** @internal */ readonly session: MySqlSession, @@ -86,6 +89,7 @@ export class MySqlDatabase< } } this.$cache = { invalidate: async (_params: any) => {} }; + this.casing = dialect.casing.casing; } /** diff --git a/drizzle-orm/src/mysql-core/dialect.ts b/drizzle-orm/src/mysql-core/dialect.ts index b1f0b5fd15..0014dd303f 100644 --- a/drizzle-orm/src/mysql-core/dialect.ts +++ b/drizzle-orm/src/mysql-core/dialect.ts @@ -44,6 +44,7 @@ export interface MySqlDialectConfig { export class MySqlDialect { static readonly [entityKind]: string = 'MySqlDialect'; + /** @internal */ readonly casing: CasingCache; constructor(config?: MySqlDialectConfig) { diff --git a/drizzle-orm/src/pg-core/db.ts b/drizzle-orm/src/pg-core/db.ts index 2529bd32bf..d6af806033 100644 --- a/drizzle-orm/src/pg-core/db.ts +++ b/drizzle-orm/src/pg-core/db.ts @@ -22,7 +22,7 @@ import type { ExtractTablesWithRelations, RelationalSchemaConfig, TablesRelation import { SelectionProxyHandler } from '~/selection-proxy.ts'; import { type ColumnsSelection, type SQL, sql, type SQLWrapper } from '~/sql/sql.ts'; import { WithSubquery } from '~/subquery.ts'; -import type { DrizzleTypeError, NeonAuthToken } from '~/utils.ts'; +import type { Casing, DrizzleTypeError, NeonAuthToken } from '~/utils.ts'; import type { PgColumn } from './columns/index.ts'; import { PgCountBuilder } from './query-builders/count.ts'; import { RelationalQueryBuilder } from './query-builders/query.ts'; @@ -47,6 +47,8 @@ export class PgDatabase< readonly session: PgSession; }; + readonly casing: Casing | undefined; + query: TFullSchema extends Record ? DrizzleTypeError<'Seems like the schema generic is missing - did you forget to add it to your DB type?'> : { @@ -54,6 +56,7 @@ export class PgDatabase< }; constructor( + /** @internal */ readonly dialect: PgDialect, /** @internal */ readonly session: PgSession, @@ -87,6 +90,7 @@ export class PgDatabase< } } this.$cache = { invalidate: async (_params: any) => {} }; + this.casing = dialect.casing.casing; } /** diff --git a/drizzle-orm/src/pg-core/dialect.ts b/drizzle-orm/src/pg-core/dialect.ts index b2089bb6be..59ec42b169 100644 --- a/drizzle-orm/src/pg-core/dialect.ts +++ b/drizzle-orm/src/pg-core/dialect.ts @@ -63,6 +63,7 @@ export interface PgDialectConfig { export class PgDialect { static readonly [entityKind]: string = 'PgDialect'; + /** @internal */ readonly casing: CasingCache; constructor(config?: PgDialectConfig) { diff --git a/drizzle-orm/src/singlestore-core/db.ts b/drizzle-orm/src/singlestore-core/db.ts index bfba45958e..85f795d077 100644 --- a/drizzle-orm/src/singlestore-core/db.ts +++ b/drizzle-orm/src/singlestore-core/db.ts @@ -27,6 +27,7 @@ import type { } from './session.ts'; import type { WithBuilder } from './subquery.ts'; import type { SingleStoreTable } from './table.ts'; +import type { Casing } from '~/utils.ts'; export class SingleStoreDatabase< TQueryResult extends SingleStoreQueryResultHKT, @@ -42,11 +43,14 @@ export class SingleStoreDatabase< readonly tableNamesMap: Record; }; + readonly casing: Casing | undefined; + // We are waiting for SingleStore support for `json_array` function /**@inrernal */ query: unknown; constructor( + /** @internal */ readonly dialect: SingleStoreDialect, /** @internal */ readonly session: SingleStoreSession, @@ -80,6 +84,7 @@ export class SingleStoreDatabase< // } // } this.$cache = { invalidate: async (_params: any) => {} }; + this.casing = dialect.casing.casing; } /** diff --git a/drizzle-orm/src/singlestore-core/dialect.ts b/drizzle-orm/src/singlestore-core/dialect.ts index 579a7547db..359809b0e9 100644 --- a/drizzle-orm/src/singlestore-core/dialect.ts +++ b/drizzle-orm/src/singlestore-core/dialect.ts @@ -43,6 +43,7 @@ export interface SingleStoreDialectConfig { export class SingleStoreDialect { static readonly [entityKind]: string = 'SingleStoreDialect'; + /** @internal */ readonly casing: CasingCache; constructor(config?: SingleStoreDialectConfig) { diff --git a/drizzle-orm/src/sqlite-core/db.ts b/drizzle-orm/src/sqlite-core/db.ts index cc1fa6201d..0cb0474031 100644 --- a/drizzle-orm/src/sqlite-core/db.ts +++ b/drizzle-orm/src/sqlite-core/db.ts @@ -21,7 +21,7 @@ import type { } from '~/sqlite-core/session.ts'; import type { SQLiteTable } from '~/sqlite-core/table.ts'; import { WithSubquery } from '~/subquery.ts'; -import type { DrizzleTypeError } from '~/utils.ts'; +import type { Casing, DrizzleTypeError } from '~/utils.ts'; import { SQLiteCountBuilder } from './query-builders/count.ts'; import { RelationalQueryBuilder } from './query-builders/query.ts'; import { SQLiteRaw } from './query-builders/raw.ts'; @@ -43,6 +43,8 @@ export class BaseSQLiteDatabase< readonly tableNamesMap: Record; }; + readonly casing: Casing | undefined; + query: TFullSchema extends Record ? DrizzleTypeError<'Seems like the schema generic is missing - did you forget to add it to your DB type?'> : { @@ -51,6 +53,7 @@ export class BaseSQLiteDatabase< constructor( private resultKind: TResultKind, + /** @internal */ readonly dialect: { sync: SQLiteSyncDialect; async: SQLiteAsyncDialect }[TResultKind], /** @internal */ readonly session: SQLiteSession, @@ -86,6 +89,7 @@ export class BaseSQLiteDatabase< } } this.$cache = { invalidate: async (_params: any) => {} }; + this.casing = dialect.casing.casing; } /** diff --git a/drizzle-orm/src/sqlite-core/dialect.ts b/drizzle-orm/src/sqlite-core/dialect.ts index 81bf3f172c..2f4a0c366d 100644 --- a/drizzle-orm/src/sqlite-core/dialect.ts +++ b/drizzle-orm/src/sqlite-core/dialect.ts @@ -47,6 +47,7 @@ export interface SQLiteDialectConfig { export abstract class SQLiteDialect { static readonly [entityKind]: string = 'SQLiteDialect'; + /** @internal */ readonly casing: CasingCache; constructor(config?: SQLiteDialectConfig) { From 9211a4a1a68692162d9c1df97ac9ac8b648f9ef4 Mon Sep 17 00:00:00 2001 From: Matan Kushner Date: Fri, 7 Nov 2025 10:15:45 +0900 Subject: [PATCH 3/5] Test enforcing casing configuration --- drizzle-kit/tests/push/pg.test.ts | 66 +++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/drizzle-kit/tests/push/pg.test.ts b/drizzle-kit/tests/push/pg.test.ts index a5c8b30287..01755d9725 100644 --- a/drizzle-kit/tests/push/pg.test.ts +++ b/drizzle-kit/tests/push/pg.test.ts @@ -4410,3 +4410,69 @@ test('alter inherit in role', async (t) => { await client.query(st); } }); + +test('push respects casing configuration', async () => { + const client = new PGlite(); + + const schema = { + users: pgTable('users', { + userId: serial('user_id').primaryKey(), + firstName: text('first_name').notNull(), + lastName: text('last_name'), + }), + }; + + const { statements, sqlStatements } = await diffTestSchemasPush( + client, + {}, + schema, + [], + false, + ['public'], + 'snake_case', + ); + + expect(statements).toStrictEqual([ + { + type: 'create_table', + tableName: 'users', + schema: '', + columns: [ + { + name: 'user_id', + type: 'serial', + primaryKey: true, + notNull: true, + }, + { + name: 'first_name', + type: 'text', + primaryKey: false, + notNull: true, + }, + { + name: 'last_name', + type: 'text', + primaryKey: false, + notNull: false, + }, + ], + compositePKs: [], + compositePkName: '', + uniqueConstraints: [], + checkConstraints: [], + isRLSEnabled: false, + policies: [], + }, + ]); + + expect(sqlStatements.length).toBe(1); + expect(sqlStatements[0]).toContain('CREATE TABLE'); + expect(sqlStatements[0]).toContain('"user_id"'); + expect(sqlStatements[0]).toContain('"first_name"'); + expect(sqlStatements[0]).toContain('"last_name"'); + + for (const st of sqlStatements) { + await client.query(st); + } +}); From fc7b3ca6b09940757a14bee85c69154dbebf8863 Mon Sep 17 00:00:00 2001 From: Matan Kushner Date: Fri, 7 Nov 2025 10:29:24 +0900 Subject: [PATCH 4/5] Add tests for other dbs --- drizzle-kit/tests/push/mysql.test.ts | 62 ++++++++++++++++++++++ drizzle-kit/tests/push/singlestore.test.ts | 62 ++++++++++++++++++++++ drizzle-kit/tests/push/sqlite.test.ts | 62 ++++++++++++++++++++++ 3 files changed, 186 insertions(+) diff --git a/drizzle-kit/tests/push/mysql.test.ts b/drizzle-kit/tests/push/mysql.test.ts index 6c7f5efc2c..2f8ce9d6ba 100644 --- a/drizzle-kit/tests/push/mysql.test.ts +++ b/drizzle-kit/tests/push/mysql.test.ts @@ -746,6 +746,68 @@ const mysqlSuite: DialectSuite = { await context.client.query(`DROP TABLE \`products_categories\``); }, + pushRespectsCasingConfiguration: async function(context?: any): Promise { + const schema = { + users: mysqlTable('users', { + userId: serial('user_id').primaryKey(), + firstName: text('first_name').notNull(), + lastName: text('last_name'), + }), + }; + + const { statements, sqlStatements } = await diffTestSchemasPushMysql( + context.client as Connection, + {}, + schema, + [], + 'drizzle', + false, + 'snake_case', + ); + + expect(statements).toStrictEqual([ + { + type: 'create_table', + tableName: 'users', + schema: '', + columns: [ + { + name: 'user_id', + type: 'serial', + primaryKey: true, + notNull: true, + autoincrement: true, + }, + { + name: 'first_name', + type: 'text', + primaryKey: false, + notNull: true, + autoincrement: false, + }, + { + name: 'last_name', + type: 'text', + primaryKey: false, + notNull: false, + autoincrement: false, + }, + ], + compositePKs: [], + compositePkName: '', + uniqueConstraints: [], + checkConstraints: [], + }, + ]); + + expect(sqlStatements.length).toBe(1); + expect(sqlStatements[0]).toContain('CREATE TABLE'); + expect(sqlStatements[0]).toContain('`user_id`'); + expect(sqlStatements[0]).toContain('`first_name`'); + expect(sqlStatements[0]).toContain('`last_name`'); + + await context.client.query(`DROP TABLE \`users\``); + }, }; run( diff --git a/drizzle-kit/tests/push/singlestore.test.ts b/drizzle-kit/tests/push/singlestore.test.ts index 6f58e8ddd7..aca2a32733 100644 --- a/drizzle-kit/tests/push/singlestore.test.ts +++ b/drizzle-kit/tests/push/singlestore.test.ts @@ -402,6 +402,68 @@ const singlestoreSuite: DialectSuite = { await context.client.query(`DROP TABLE \`products_categories\``); }, + pushRespectsCasingConfiguration: async function(context?: any): Promise { + const schema = { + users: singlestoreTable('users', { + userId: int('user_id').primaryKey(), + firstName: text('first_name').notNull(), + lastName: text('last_name'), + }), + }; + + const { statements, sqlStatements } = await diffTestSchemasPushSingleStore( + context.client as Connection, + {}, + schema, + [], + 'drizzle', + false, + 'snake_case', + ); + + expect(statements).toStrictEqual([ + { + type: 'create_table', + tableName: 'users', + schema: '', + columns: [ + { + name: 'user_id', + type: 'int', + primaryKey: true, + notNull: true, + autoincrement: false, + }, + { + name: 'first_name', + type: 'text', + primaryKey: false, + notNull: true, + autoincrement: false, + }, + { + name: 'last_name', + type: 'text', + primaryKey: false, + notNull: false, + autoincrement: false, + }, + ], + compositePKs: [], + compositePkName: '', + uniqueConstraints: [], + checkConstraints: [], + }, + ]); + + expect(sqlStatements.length).toBe(1); + expect(sqlStatements[0]).toContain('CREATE TABLE'); + expect(sqlStatements[0]).toContain('`user_id`'); + expect(sqlStatements[0]).toContain('`first_name`'); + expect(sqlStatements[0]).toContain('`last_name`'); + + await context.client.query(`DROP TABLE \`users\``); + }, }; run( diff --git a/drizzle-kit/tests/push/sqlite.test.ts b/drizzle-kit/tests/push/sqlite.test.ts index e2c85233a3..d47dd61c7f 100644 --- a/drizzle-kit/tests/push/sqlite.test.ts +++ b/drizzle-kit/tests/push/sqlite.test.ts @@ -1611,3 +1611,65 @@ test('rename table with composite primary key', async () => { 'ALTER TABLE `products_categories` RENAME TO `products_to_categories`;', ]); }); + +test('push respects casing configuration', async () => { + const client = new Database(':memory:'); + + const schema = { + users: sqliteTable('users', { + userId: integer('user_id').primaryKey(), + firstName: text('first_name').notNull(), + lastName: text('last_name'), + }), + }; + + const { statements, sqlStatements } = await diffTestSchemasPushSqlite( + client, + {}, + schema, + [], + false, + [], + 'snake_case', + ); + + expect(statements).toStrictEqual([ + { + type: 'sqlite_create_table', + tableName: 'users', + columns: [ + { + name: 'user_id', + type: 'integer', + primaryKey: true, + notNull: true, + autoincrement: false, + }, + { + name: 'first_name', + type: 'text', + primaryKey: false, + notNull: true, + autoincrement: false, + }, + { + name: 'last_name', + type: 'text', + primaryKey: false, + notNull: false, + autoincrement: false, + }, + ], + compositePKs: [], + referenceData: [], + uniqueConstraints: [], + checkConstraints: [], + }, + ]); + + expect(sqlStatements.length).toBe(1); + expect(sqlStatements[0]).toContain('CREATE TABLE'); + expect(sqlStatements[0]).toContain('`user_id`'); + expect(sqlStatements[0]).toContain('`first_name`'); + expect(sqlStatements[0]).toContain('`last_name`'); +}); From f162c4589aaa67e677b6344b1f565f0b8eeda5fe Mon Sep 17 00:00:00 2001 From: Matan Kushner Date: Fri, 7 Nov 2025 10:39:03 +0900 Subject: [PATCH 5/5] Add casing to gel db instance for consistency --- drizzle-orm/src/gel-core/db.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drizzle-orm/src/gel-core/db.ts b/drizzle-orm/src/gel-core/db.ts index 6f73b80c4b..2a4e9edfd5 100644 --- a/drizzle-orm/src/gel-core/db.ts +++ b/drizzle-orm/src/gel-core/db.ts @@ -15,7 +15,7 @@ import type { ExtractTablesWithRelations, RelationalSchemaConfig, TablesRelation import { SelectionProxyHandler } from '~/selection-proxy.ts'; import { type ColumnsSelection, type SQL, sql, type SQLWrapper } from '~/sql/sql.ts'; import { WithSubquery } from '~/subquery.ts'; -import type { DrizzleTypeError } from '~/utils.ts'; +import type { Casing, DrizzleTypeError } from '~/utils.ts'; import type { GelColumn } from './columns/index.ts'; import { GelCountBuilder } from './query-builders/count.ts'; import { RelationalQueryBuilder } from './query-builders/query.ts'; @@ -38,6 +38,8 @@ export class GelDatabase< readonly session: GelSession; }; + readonly casing: Casing | undefined; + query: TFullSchema extends Record ? DrizzleTypeError<'Seems like the schema generic is missing - did you forget to add it to your DB type?'> : { @@ -80,6 +82,7 @@ export class GelDatabase< } this.$cache = { invalidate: async (_params: any) => {} }; + this.casing = dialect.casing.casing; } /**