From 32b71c080ca9b52b026ba5f85a48806a59f196a1 Mon Sep 17 00:00:00 2001
From: OleksiiKH0240 <homenko0240@gmail.com>
Date: Mon, 27 Jan 2025 16:56:45 +0200
Subject: [PATCH 01/11] bug fix

---
 drizzle-seed/src/index.ts | 286 ++++++++++++++++++++++----------------
 1 file changed, 167 insertions(+), 119 deletions(-)

diff --git a/drizzle-seed/src/index.ts b/drizzle-seed/src/index.ts
index cc416c84d..eb44e47f1 100644
--- a/drizzle-seed/src/index.ts
+++ b/drizzle-seed/src/index.ts
@@ -615,47 +615,63 @@ const getPostgresInfo = (
 		const schemaConfig = extractTablesRelationalConfig(schema, createTableRelationsHelpers);
 		const relations: RelationWithReferences[] = [];
 		for (const table of Object.values(schemaConfig.tables)) {
-			if (table.relations !== undefined) {
-				for (const drizzleRel of Object.values(table.relations)) {
-					if (is(drizzleRel, One)) {
-						const tableConfig = getPgTableConfig(drizzleRel.sourceTable as PgTable);
-						const tableDbSchema = tableConfig.schema ?? 'public';
-						const tableDbName = tableConfig.name;
-						const tableTsName = schemaConfig.tableNamesMap[`${tableDbSchema}.${tableDbName}`] ?? tableDbName;
-
-						const dbToTsColumnNamesMap = getDbToTsColumnNamesMap(drizzleRel.sourceTable);
-						const columns = drizzleRel.config?.fields.map((field) => dbToTsColumnNamesMap[field.name] as string)
-							?? [];
-
-						const refTableConfig = getPgTableConfig(drizzleRel.referencedTable as PgTable);
-						const refTableDbSchema = refTableConfig.schema ?? 'public';
-						const refTableDbName = refTableConfig.name;
-						const refTableTsName = schemaConfig.tableNamesMap[`${refTableDbSchema}.${refTableDbName}`]
-							?? refTableDbName;
-
-						const dbToTsColumnNamesMapForRefTable = getDbToTsColumnNamesMap(drizzleRel.referencedTable);
-						const refColumns = drizzleRel.config?.references.map((ref) =>
-							dbToTsColumnNamesMapForRefTable[ref.name] as string
-						)
-							?? [];
-
-						if (tableRelations[refTableTsName] === undefined) {
-							tableRelations[refTableTsName] = [];
-						}
-
-						const relation: RelationWithReferences = {
-							table: tableTsName,
-							columns,
-							refTable: refTableTsName,
-							refColumns,
-							refTableRels: tableRelations[refTableTsName],
-							type: 'one',
-						};
-
-						relations.push(relation);
-						tableRelations[tableTsName]!.push(relation);
-					}
+			if (table.relations === undefined) continue;
+
+			for (const drizzleRel of Object.values(table.relations)) {
+				if (!is(drizzleRel, One)) continue;
+
+				const tableConfig = getPgTableConfig(drizzleRel.sourceTable as PgTable);
+				const tableDbSchema = tableConfig.schema ?? 'public';
+				const tableDbName = tableConfig.name;
+				const tableTsName = schemaConfig.tableNamesMap[`${tableDbSchema}.${tableDbName}`] ?? tableDbName;
+
+				const dbToTsColumnNamesMap = getDbToTsColumnNamesMap(drizzleRel.sourceTable);
+				const columns = drizzleRel.config?.fields.map((field) => dbToTsColumnNamesMap[field.name] as string)
+					?? [];
+
+				const refTableConfig = getPgTableConfig(drizzleRel.referencedTable as PgTable);
+				const refTableDbSchema = refTableConfig.schema ?? 'public';
+				const refTableDbName = refTableConfig.name;
+				const refTableTsName = schemaConfig.tableNamesMap[`${refTableDbSchema}.${refTableDbName}`]
+					?? refTableDbName;
+
+				const dbToTsColumnNamesMapForRefTable = getDbToTsColumnNamesMap(drizzleRel.referencedTable);
+				const refColumns = drizzleRel.config?.references.map((ref) =>
+					dbToTsColumnNamesMapForRefTable[ref.name] as string
+				)
+					?? [];
+
+				if (tableRelations[refTableTsName] === undefined) {
+					tableRelations[refTableTsName] = [];
 				}
+
+				const relation: RelationWithReferences = {
+					table: tableTsName,
+					columns,
+					refTable: refTableTsName,
+					refColumns,
+					refTableRels: tableRelations[refTableTsName],
+					type: 'one',
+				};
+
+				// do not add duplicate relation
+				if (
+					tableRelations[tableTsName]?.some((rel) =>
+						rel.table === relation.table
+						&& rel.refTable === relation.refTable
+					) === true
+				) {
+					console.warn(
+						`You are providing a one-to-many relation from the '${relation.table}' table to the '${relation.refTable}' table,\n`
+							+ `while your '${relation.table}' table object already has foreign key constraint in the schema(from the '${relation.table}' table to the '${relation.refTable}' table).\n`
+							+ `You can specify either the foreign key constraint or the relation, but not both.\n`
+							+ `By default, one-to-many relation will be ignored to respect foreign key constraint.\n`,
+					);
+					continue;
+				}
+
+				relations.push(relation);
+				tableRelations[tableTsName]!.push(relation);
 			}
 		}
 		return relations;
@@ -993,47 +1009,63 @@ const getMySqlInfo = (
 		const schemaConfig = extractTablesRelationalConfig(schema, createTableRelationsHelpers);
 		const relations: RelationWithReferences[] = [];
 		for (const table of Object.values(schemaConfig.tables)) {
-			if (table.relations !== undefined) {
-				for (const drizzleRel of Object.values(table.relations)) {
-					if (is(drizzleRel, One)) {
-						const tableConfig = getMysqlTableConfig(drizzleRel.sourceTable as MySqlTable);
-						const tableDbSchema = tableConfig.schema ?? 'public';
-						const tableDbName = tableConfig.name;
-						const tableTsName = schemaConfig.tableNamesMap[`${tableDbSchema}.${tableDbName}`] ?? tableDbName;
-
-						const dbToTsColumnNamesMap = getDbToTsColumnNamesMap(drizzleRel.sourceTable as MySqlTable);
-						const columns = drizzleRel.config?.fields.map((field) => dbToTsColumnNamesMap[field.name] as string)
-							?? [];
-
-						const refTableConfig = getMysqlTableConfig(drizzleRel.referencedTable as MySqlTable);
-						const refTableDbSchema = refTableConfig.schema ?? 'public';
-						const refTableDbName = refTableConfig.name;
-						const refTableTsName = schemaConfig.tableNamesMap[`${refTableDbSchema}.${refTableDbName}`]
-							?? refTableDbName;
-
-						const dbToTsColumnNamesMapForRefTable = getDbToTsColumnNamesMap(drizzleRel.referencedTable as MySqlTable);
-						const refColumns = drizzleRel.config?.references.map((ref) =>
-							dbToTsColumnNamesMapForRefTable[ref.name] as string
-						)
-							?? [];
-
-						if (tableRelations[refTableTsName] === undefined) {
-							tableRelations[refTableTsName] = [];
-						}
-
-						const relation: RelationWithReferences = {
-							table: tableTsName,
-							columns,
-							refTable: refTableTsName,
-							refColumns,
-							refTableRels: tableRelations[refTableTsName],
-							type: 'one',
-						};
-
-						relations.push(relation);
-						tableRelations[tableTsName]!.push(relation);
-					}
+			if (table.relations === undefined) continue;
+
+			for (const drizzleRel of Object.values(table.relations)) {
+				if (!is(drizzleRel, One)) continue;
+
+				const tableConfig = getMysqlTableConfig(drizzleRel.sourceTable as MySqlTable);
+				const tableDbSchema = tableConfig.schema ?? 'public';
+				const tableDbName = tableConfig.name;
+				const tableTsName = schemaConfig.tableNamesMap[`${tableDbSchema}.${tableDbName}`] ?? tableDbName;
+
+				const dbToTsColumnNamesMap = getDbToTsColumnNamesMap(drizzleRel.sourceTable as MySqlTable);
+				const columns = drizzleRel.config?.fields.map((field) => dbToTsColumnNamesMap[field.name] as string)
+					?? [];
+
+				const refTableConfig = getMysqlTableConfig(drizzleRel.referencedTable as MySqlTable);
+				const refTableDbSchema = refTableConfig.schema ?? 'public';
+				const refTableDbName = refTableConfig.name;
+				const refTableTsName = schemaConfig.tableNamesMap[`${refTableDbSchema}.${refTableDbName}`]
+					?? refTableDbName;
+
+				const dbToTsColumnNamesMapForRefTable = getDbToTsColumnNamesMap(drizzleRel.referencedTable as MySqlTable);
+				const refColumns = drizzleRel.config?.references.map((ref) =>
+					dbToTsColumnNamesMapForRefTable[ref.name] as string
+				)
+					?? [];
+
+				if (tableRelations[refTableTsName] === undefined) {
+					tableRelations[refTableTsName] = [];
 				}
+
+				const relation: RelationWithReferences = {
+					table: tableTsName,
+					columns,
+					refTable: refTableTsName,
+					refColumns,
+					refTableRels: tableRelations[refTableTsName],
+					type: 'one',
+				};
+
+				// do not add duplicate relation
+				if (
+					tableRelations[tableTsName]?.some((rel) =>
+						rel.table === relation.table
+						&& rel.refTable === relation.refTable
+					) === true
+				) {
+					console.warn(
+						`You are providing a one-to-many relation from the '${relation.table}' table to the '${relation.refTable}' table,\n`
+							+ `while your '${relation.table}' table object already has foreign key constraint in the schema(from the '${relation.table}' table to the '${relation.refTable}' table).\n`
+							+ `You can specify either the foreign key constraint or the relation, but not both.\n`
+							+ `By default, one-to-many relation will be ignored to respect foreign key constraint.\n`,
+					);
+					continue;
+				}
+
+				relations.push(relation);
+				tableRelations[tableTsName]!.push(relation);
 			}
 		}
 		return relations;
@@ -1299,46 +1331,62 @@ const getSqliteInfo = (
 		const schemaConfig = extractTablesRelationalConfig(schema, createTableRelationsHelpers);
 		const relations: RelationWithReferences[] = [];
 		for (const table of Object.values(schemaConfig.tables)) {
-			if (table.relations !== undefined) {
-				for (const drizzleRel of Object.values(table.relations)) {
-					if (is(drizzleRel, One)) {
-						const tableConfig = getSqliteTableConfig(drizzleRel.sourceTable as SQLiteTable);
-						const tableDbName = tableConfig.name;
-						// TODO: tableNamesMap: have {public.customer: 'customer'} structure in sqlite
-						const tableTsName = schemaConfig.tableNamesMap[`public.${tableDbName}`] ?? tableDbName;
-
-						const dbToTsColumnNamesMap = getDbToTsColumnNamesMap(drizzleRel.sourceTable as SQLiteTable);
-						const columns = drizzleRel.config?.fields.map((field) => dbToTsColumnNamesMap[field.name] as string)
-							?? [];
-
-						const refTableConfig = getSqliteTableConfig(drizzleRel.referencedTable as SQLiteTable);
-						const refTableDbName = refTableConfig.name;
-						const refTableTsName = schemaConfig.tableNamesMap[`public.${refTableDbName}`]
-							?? refTableDbName;
-
-						const dbToTsColumnNamesMapForRefTable = getDbToTsColumnNamesMap(drizzleRel.referencedTable as SQLiteTable);
-						const refColumns = drizzleRel.config?.references.map((ref) =>
-							dbToTsColumnNamesMapForRefTable[ref.name] as string
-						)
-							?? [];
-
-						if (tableRelations[refTableTsName] === undefined) {
-							tableRelations[refTableTsName] = [];
-						}
-
-						const relation: RelationWithReferences = {
-							table: tableTsName,
-							columns,
-							refTable: refTableTsName,
-							refColumns,
-							refTableRels: tableRelations[refTableTsName],
-							type: 'one',
-						};
-
-						relations.push(relation);
-						tableRelations[tableTsName]!.push(relation);
-					}
+			if (table.relations === undefined) continue;
+
+			for (const drizzleRel of Object.values(table.relations)) {
+				if (!is(drizzleRel, One)) continue;
+
+				const tableConfig = getSqliteTableConfig(drizzleRel.sourceTable as SQLiteTable);
+				const tableDbName = tableConfig.name;
+				// TODO: tableNamesMap: have {public.customer: 'customer'} structure in sqlite
+				const tableTsName = schemaConfig.tableNamesMap[`public.${tableDbName}`] ?? tableDbName;
+
+				const dbToTsColumnNamesMap = getDbToTsColumnNamesMap(drizzleRel.sourceTable as SQLiteTable);
+				const columns = drizzleRel.config?.fields.map((field) => dbToTsColumnNamesMap[field.name] as string)
+					?? [];
+
+				const refTableConfig = getSqliteTableConfig(drizzleRel.referencedTable as SQLiteTable);
+				const refTableDbName = refTableConfig.name;
+				const refTableTsName = schemaConfig.tableNamesMap[`public.${refTableDbName}`]
+					?? refTableDbName;
+
+				const dbToTsColumnNamesMapForRefTable = getDbToTsColumnNamesMap(drizzleRel.referencedTable as SQLiteTable);
+				const refColumns = drizzleRel.config?.references.map((ref) =>
+					dbToTsColumnNamesMapForRefTable[ref.name] as string
+				)
+					?? [];
+
+				if (tableRelations[refTableTsName] === undefined) {
+					tableRelations[refTableTsName] = [];
 				}
+
+				const relation: RelationWithReferences = {
+					table: tableTsName,
+					columns,
+					refTable: refTableTsName,
+					refColumns,
+					refTableRels: tableRelations[refTableTsName],
+					type: 'one',
+				};
+
+				// do not add duplicate relation
+				if (
+					tableRelations[tableTsName]?.some((rel) =>
+						rel.table === relation.table
+						&& rel.refTable === relation.refTable
+					) === true
+				) {
+					console.warn(
+						`You are providing a one-to-many relation from the '${relation.table}' table to the '${relation.refTable}' table,\n`
+							+ `while your '${relation.table}' table object already has foreign key constraint in the schema(from the '${relation.table}' table to the '${relation.refTable}' table).\n`
+							+ `You can specify either the foreign key constraint or the relation, but not both.\n`
+							+ `By default, one-to-many relation will be ignored to respect foreign key constraint.\n`,
+					);
+					continue;
+				}
+
+				relations.push(relation);
+				tableRelations[tableTsName]!.push(relation);
 			}
 		}
 		return relations;

From e5713d6b7d6a26da08d93a13493f823b92ce6545 Mon Sep 17 00:00:00 2001
From: OleksiiKH0240 <homenko0240@gmail.com>
Date: Mon, 27 Jan 2025 19:32:25 +0200
Subject: [PATCH 02/11] fixes

---
 drizzle-seed/src/index.ts                     | 27 ++++----
 .../mysql/allDataTypesTest/drizzle.config.ts  |  7 --
 drizzle-seed/tests/mysql/drizzle.config.ts    |  7 --
 .../mysql/generatorsTest/drizzle.config.ts    |  7 --
 drizzle-seed/tests/mysql/mysql.test.ts        | 64 ++++++++++++++++++-
 drizzle-seed/tests/mysql/mysqlSchema.ts       | 19 ++++++
 .../tests/pg/allDataTypesTest/pgSchema.ts     | 46 ++++++-------
 drizzle-seed/tests/pg/pg.test.ts              | 54 ++++++++++++++--
 drizzle-seed/tests/pg/pgSchema.ts             | 16 ++++-
 drizzle-seed/tests/sqlite/sqlite.test.ts      | 52 ++++++++++++++-
 drizzle-seed/tests/sqlite/sqliteSchema.ts     | 25 ++++++++
 11 files changed, 251 insertions(+), 73 deletions(-)
 delete mode 100644 drizzle-seed/tests/mysql/allDataTypesTest/drizzle.config.ts
 delete mode 100644 drizzle-seed/tests/mysql/drizzle.config.ts
 delete mode 100644 drizzle-seed/tests/mysql/generatorsTest/drizzle.config.ts

diff --git a/drizzle-seed/src/index.ts b/drizzle-seed/src/index.ts
index eb44e47f1..a56134ac3 100644
--- a/drizzle-seed/src/index.ts
+++ b/drizzle-seed/src/index.ts
@@ -659,13 +659,12 @@ const getPostgresInfo = (
 					tableRelations[tableTsName]?.some((rel) =>
 						rel.table === relation.table
 						&& rel.refTable === relation.refTable
-					) === true
+					)
 				) {
 					console.warn(
-						`You are providing a one-to-many relation from the '${relation.table}' table to the '${relation.refTable}' table,\n`
-							+ `while your '${relation.table}' table object already has foreign key constraint in the schema(from the '${relation.table}' table to the '${relation.refTable}' table).\n`
-							+ `You can specify either the foreign key constraint or the relation, but not both.\n`
-							+ `By default, one-to-many relation will be ignored to respect foreign key constraint.\n`,
+						`You are providing a one-to-many relation between the '${relation.refTable}' and '${relation.table}' tables,\n`
+							+ `while the '${relation.table}' table object already has foreign key constraint in the schema referencing '${relation.refTable}' table.\n`
+							+ `In this case, the foreign key constraint will be used.\n`,
 					);
 					continue;
 				}
@@ -1053,13 +1052,12 @@ const getMySqlInfo = (
 					tableRelations[tableTsName]?.some((rel) =>
 						rel.table === relation.table
 						&& rel.refTable === relation.refTable
-					) === true
+					)
 				) {
 					console.warn(
-						`You are providing a one-to-many relation from the '${relation.table}' table to the '${relation.refTable}' table,\n`
-							+ `while your '${relation.table}' table object already has foreign key constraint in the schema(from the '${relation.table}' table to the '${relation.refTable}' table).\n`
-							+ `You can specify either the foreign key constraint or the relation, but not both.\n`
-							+ `By default, one-to-many relation will be ignored to respect foreign key constraint.\n`,
+						`You are providing a one-to-many relation between the '${relation.refTable}' and '${relation.table}' tables,\n`
+							+ `while the '${relation.table}' table object already has foreign key constraint in the schema referencing '${relation.refTable}' table.\n`
+							+ `In this case, the foreign key constraint will be used.\n`,
 					);
 					continue;
 				}
@@ -1374,13 +1372,12 @@ const getSqliteInfo = (
 					tableRelations[tableTsName]?.some((rel) =>
 						rel.table === relation.table
 						&& rel.refTable === relation.refTable
-					) === true
+					)
 				) {
 					console.warn(
-						`You are providing a one-to-many relation from the '${relation.table}' table to the '${relation.refTable}' table,\n`
-							+ `while your '${relation.table}' table object already has foreign key constraint in the schema(from the '${relation.table}' table to the '${relation.refTable}' table).\n`
-							+ `You can specify either the foreign key constraint or the relation, but not both.\n`
-							+ `By default, one-to-many relation will be ignored to respect foreign key constraint.\n`,
+						`You are providing a one-to-many relation between the '${relation.refTable}' and '${relation.table}' tables,\n`
+							+ `while the '${relation.table}' table object already has foreign key constraint in the schema referencing '${relation.refTable}' table.\n`
+							+ `In this case, the foreign key constraint will be used.\n`,
 					);
 					continue;
 				}
diff --git a/drizzle-seed/tests/mysql/allDataTypesTest/drizzle.config.ts b/drizzle-seed/tests/mysql/allDataTypesTest/drizzle.config.ts
deleted file mode 100644
index 78ff7a54b..000000000
--- a/drizzle-seed/tests/mysql/allDataTypesTest/drizzle.config.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-import { defineConfig } from 'drizzle-kit';
-
-export default defineConfig({
-	schema: './src/tests/mysql/allDataTypesTest/mysqlSchema.ts',
-	out: './src/tests/mysql/allDataTypesTest/mysqlMigrations',
-	dialect: 'mysql',
-});
diff --git a/drizzle-seed/tests/mysql/drizzle.config.ts b/drizzle-seed/tests/mysql/drizzle.config.ts
deleted file mode 100644
index 9a84354e3..000000000
--- a/drizzle-seed/tests/mysql/drizzle.config.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-import { defineConfig } from 'drizzle-kit';
-
-export default defineConfig({
-	schema: './src/tests/mysql/mysqlSchema.ts',
-	out: './src/tests/mysql/mysqlMigrations',
-	dialect: 'mysql',
-});
diff --git a/drizzle-seed/tests/mysql/generatorsTest/drizzle.config.ts b/drizzle-seed/tests/mysql/generatorsTest/drizzle.config.ts
deleted file mode 100644
index 621d8acc1..000000000
--- a/drizzle-seed/tests/mysql/generatorsTest/drizzle.config.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-import { defineConfig } from 'drizzle-kit';
-
-export default defineConfig({
-	schema: './src/tests/mysql/generatorsTest/mysqlSchema.ts',
-	out: './src/tests/mysql/generatorsTest/mysqlMigrations',
-	dialect: 'mysql',
-});
diff --git a/drizzle-seed/tests/mysql/mysql.test.ts b/drizzle-seed/tests/mysql/mysql.test.ts
index 7d6bfd48e..4d25171ea 100644
--- a/drizzle-seed/tests/mysql/mysql.test.ts
+++ b/drizzle-seed/tests/mysql/mysql.test.ts
@@ -1,12 +1,12 @@
 import Docker from 'dockerode';
-import { sql } from 'drizzle-orm';
+import { relations, sql } from 'drizzle-orm';
 import type { MySql2Database } from 'drizzle-orm/mysql2';
 import { drizzle } from 'drizzle-orm/mysql2';
 import getPort from 'get-port';
 import type { Connection } from 'mysql2/promise';
 import { createConnection } from 'mysql2/promise';
 import { v4 as uuid } from 'uuid';
-import { afterAll, afterEach, beforeAll, expect, test } from 'vitest';
+import { afterAll, afterEach, beforeAll, expect, test, vi } from 'vitest';
 import { reset, seed } from '../../src/index.ts';
 import * as schema from './mysqlSchema.ts';
 
@@ -180,6 +180,29 @@ beforeAll(async () => {
 		`,
 	);
 
+	await db.execute(
+		sql`
+			    CREATE TABLE \`users\` (
+				\`id\` int,
+				\`name\` text,
+				\`invitedBy\` int,
+				CONSTRAINT \`users_id\` PRIMARY KEY(\`id\`)
+			);
+		`,
+	);
+
+	await db.execute(
+		sql`
+			    CREATE TABLE \`posts\` (
+				\`id\` int,
+				\`name\` text,
+				\`content\` text,
+				\`userId\` int,
+				CONSTRAINT \`posts_id\` PRIMARY KEY(\`id\`)
+			);
+		`,
+	);
+
 	await db.execute(
 		sql`
 			ALTER TABLE \`order_detail\` ADD CONSTRAINT \`order_detail_order_id_order_id_fk\` FOREIGN KEY (\`order_id\`) REFERENCES \`order\`(\`id\`) ON DELETE cascade ON UPDATE no action;
@@ -215,6 +238,18 @@ beforeAll(async () => {
 			ALTER TABLE \`product\` ADD CONSTRAINT \`product_supplier_id_supplier_id_fk\` FOREIGN KEY (\`supplier_id\`) REFERENCES \`supplier\`(\`id\`) ON DELETE cascade ON UPDATE no action;
 		`,
 	);
+
+	await db.execute(
+		sql`
+			ALTER TABLE \`users\` ADD CONSTRAINT \`users_invitedBy_users_id_fk\` FOREIGN KEY (\`invitedBy\`) REFERENCES \`users\`(\`id\`) ON DELETE cascade ON UPDATE no action;
+		`,
+	);
+
+	await db.execute(
+		sql`
+			ALTER TABLE \`posts\` ADD CONSTRAINT \`posts_userId_users_id_fk\` FOREIGN KEY (\`userId\`) REFERENCES \`users\`(\`id\`) ON DELETE cascade ON UPDATE no action;
+		`,
+	);
 });
 
 afterAll(async () => {
@@ -379,3 +414,28 @@ test("sequential using of 'with'", async () => {
 	expect(products.length).toBe(11);
 	expect(suppliers.length).toBe(11);
 });
+
+test('overlapping a foreign key constraint with a one-to-many relation', async () => {
+	const postsRelation = relations(schema.posts, ({ one }) => ({
+		user: one(schema.users, { fields: [schema.posts.userId], references: [schema.users.id] }),
+	}));
+
+	const consoleMock = vi.spyOn(console, 'warn').mockImplementation(() => {});
+
+	await reset(db, { users: schema.users, posts: schema.posts, postsRelation });
+	await seed(db, { users: schema.users, posts: schema.posts, postsRelation });
+	// expecting to get a warning
+	expect(consoleMock).toBeCalled();
+	expect(consoleMock).toBeCalledWith(expect.stringMatching(/^You are providing a one-to-many relation.+/));
+
+	const users = await db.select().from(schema.users);
+	const posts = await db.select().from(schema.posts);
+
+	expect(users.length).toBe(10);
+	let predicate = users.every((row) => Object.values(row).every((val) => val !== undefined && val !== null));
+	expect(predicate).toBe(true);
+
+	expect(posts.length).toBe(10);
+	predicate = posts.every((row) => Object.values(row).every((val) => val !== undefined && val !== null));
+	expect(predicate).toBe(true);
+});
diff --git a/drizzle-seed/tests/mysql/mysqlSchema.ts b/drizzle-seed/tests/mysql/mysqlSchema.ts
index 624d45d3e..6e1bd5a75 100644
--- a/drizzle-seed/tests/mysql/mysqlSchema.ts
+++ b/drizzle-seed/tests/mysql/mysqlSchema.ts
@@ -100,3 +100,22 @@ export const details = mysqlTable('order_detail', {
 		.notNull()
 		.references(() => products.id, { onDelete: 'cascade' }),
 });
+
+export const users = mysqlTable(
+	'users',
+	{
+		id: int().primaryKey(),
+		name: text(),
+		invitedBy: int().references((): AnyMySqlColumn => users.id),
+	},
+);
+
+export const posts = mysqlTable(
+	'posts',
+	{
+		id: int().primaryKey(),
+		name: text(),
+		content: text(),
+		userId: int().references(() => users.id),
+	},
+);
diff --git a/drizzle-seed/tests/pg/allDataTypesTest/pgSchema.ts b/drizzle-seed/tests/pg/allDataTypesTest/pgSchema.ts
index d4f45de22..16a55baf4 100644
--- a/drizzle-seed/tests/pg/allDataTypesTest/pgSchema.ts
+++ b/drizzle-seed/tests/pg/allDataTypesTest/pgSchema.ts
@@ -64,31 +64,31 @@ export const allDataTypes = schema.table('all_data_types', {
 });
 
 export const allArrayDataTypes = schema.table('all_array_data_types', {
-	// integerArray: integer('integer_array').array(),
-	// smallintArray: smallint('smallint_array').array(),
-	// bigintegerArray: bigint('bigint_array', { mode: 'bigint' }).array(),
-	// bigintNumberArray: bigint('bigint_number_array', { mode: 'number' }).array(),
-	// booleanArray: boolean('boolean_array').array(),
-	// textArray: text('text_array').array(),
-	// varcharArray: varchar('varchar_array', { length: 256 }).array(),
-	// charArray: char('char_array', { length: 256 }).array(),
-	// numericArray: numeric('numeric_array').array(),
-	// decimalArray: decimal('decimal_array').array(),
-	// realArray: real('real_array').array(),
-	// doublePrecisionArray: doublePrecision('double_precision_array').array(),
-	// jsonArray: json('json_array').array(),
-	// jsonbArray: jsonb('jsonb_array').array(),
-	// timeArray: time('time_array').array(),
-	// timestampDateArray: timestamp('timestamp_date_array', { mode: 'date' }).array(),
-	// timestampStringArray: timestamp('timestamp_string_array', { mode: 'string' }).array(),
+	integerArray: integer('integer_array').array(),
+	smallintArray: smallint('smallint_array').array(),
+	bigintegerArray: bigint('bigint_array', { mode: 'bigint' }).array(),
+	bigintNumberArray: bigint('bigint_number_array', { mode: 'number' }).array(),
+	booleanArray: boolean('boolean_array').array(),
+	textArray: text('text_array').array(),
+	varcharArray: varchar('varchar_array', { length: 256 }).array(),
+	charArray: char('char_array', { length: 256 }).array(),
+	numericArray: numeric('numeric_array').array(),
+	decimalArray: decimal('decimal_array').array(),
+	realArray: real('real_array').array(),
+	doublePrecisionArray: doublePrecision('double_precision_array').array(),
+	jsonArray: json('json_array').array(),
+	jsonbArray: jsonb('jsonb_array').array(),
+	timeArray: time('time_array').array(),
+	timestampDateArray: timestamp('timestamp_date_array', { mode: 'date' }).array(),
+	timestampStringArray: timestamp('timestamp_string_array', { mode: 'string' }).array(),
 	dateStringArray: date('date_string_array', { mode: 'string' }).array(),
 	dateArray: date('date_array', { mode: 'date' }).array(),
-	// intervalArray: interval('interval_array').array(),
-	// pointArray: point('point_array', { mode: 'xy' }).array(),
-	// pointTupleArray: point('point_tuple_array', { mode: 'tuple' }).array(),
-	// lineArray: line('line_array', { mode: 'abc' }).array(),
-	// lineTupleArray: line('line_tuple_array', { mode: 'tuple' }).array(),
-	// moodEnumArray: moodEnum('mood_enum_array').array(),
+	intervalArray: interval('interval_array').array(),
+	pointArray: point('point_array', { mode: 'xy' }).array(),
+	pointTupleArray: point('point_tuple_array', { mode: 'tuple' }).array(),
+	lineArray: line('line_array', { mode: 'abc' }).array(),
+	lineTupleArray: line('line_tuple_array', { mode: 'tuple' }).array(),
+	moodEnumArray: moodEnum('mood_enum_array').array(),
 });
 
 export const ndArrays = schema.table('nd_arrays', {
diff --git a/drizzle-seed/tests/pg/pg.test.ts b/drizzle-seed/tests/pg/pg.test.ts
index 90d6b4fc2..08fa5133d 100644
--- a/drizzle-seed/tests/pg/pg.test.ts
+++ b/drizzle-seed/tests/pg/pg.test.ts
@@ -1,8 +1,8 @@
 import { PGlite } from '@electric-sql/pglite';
-import { sql } from 'drizzle-orm';
+import { relations, sql } from 'drizzle-orm';
 import type { PgliteDatabase } from 'drizzle-orm/pglite';
 import { drizzle } from 'drizzle-orm/pglite';
-import { afterAll, afterEach, beforeAll, expect, test } from 'vitest';
+import { afterAll, afterEach, beforeAll, expect, test, vi } from 'vitest';
 import { reset, seed } from '../../src/index.ts';
 import * as schema from './pgSchema.ts';
 
@@ -193,14 +193,29 @@ beforeAll(async () => {
 
 	await db.execute(
 		sql`
-			create table "seeder_lib_pg"."user"
+			create table "seeder_lib_pg"."users"
 			(
 			    id          serial
 			        primary key,
 			    name        text,
 			    "invitedBy" integer
-			        constraint "user_invitedBy_user_id_fk"
-			            references "seeder_lib_pg"."user"
+			        constraint "users_invitedBy_user_id_fk"
+			            references "seeder_lib_pg"."users"
+			);
+		`,
+	);
+
+	await db.execute(
+		sql`
+			create table "seeder_lib_pg"."posts"
+			(
+			    id          serial
+			        primary key,
+			    name        text,
+				content     text,
+			    "userId" integer
+			        constraint "users_userId_user_id_fk"
+			            references "seeder_lib_pg"."users"
 			);
 		`,
 	);
@@ -385,11 +400,36 @@ test('seeding with identity columns', async () => {
 });
 
 test('seeding with self relation', async () => {
-	await seed(db, { user: schema.user });
+	await seed(db, { users: schema.users });
 
-	const result = await db.select().from(schema.user);
+	const result = await db.select().from(schema.users);
 
 	expect(result.length).toBe(10);
 	const predicate = result.every((row) => Object.values(row).every((val) => val !== undefined && val !== null));
 	expect(predicate).toBe(true);
 });
+
+test('overlapping a foreign key constraint with a one-to-many relation', async () => {
+	const postsRelation = relations(schema.posts, ({ one }) => ({
+		user: one(schema.users, { fields: [schema.posts.userId], references: [schema.users.id] }),
+	}));
+
+	const consoleMock = vi.spyOn(console, 'warn').mockImplementation(() => {});
+
+	await reset(db, { users: schema.users, posts: schema.posts, postsRelation });
+	await seed(db, { users: schema.users, posts: schema.posts, postsRelation });
+	// expecting to get a warning
+	expect(consoleMock).toBeCalled();
+	expect(consoleMock).toBeCalledWith(expect.stringMatching(/^You are providing a one-to-many relation.+/));
+
+	const users = await db.select().from(schema.users);
+	const posts = await db.select().from(schema.posts);
+
+	expect(users.length).toBe(10);
+	let predicate = users.every((row) => Object.values(row).every((val) => val !== undefined && val !== null));
+	expect(predicate).toBe(true);
+
+	expect(posts.length).toBe(10);
+	predicate = posts.every((row) => Object.values(row).every((val) => val !== undefined && val !== null));
+	expect(predicate).toBe(true);
+});
diff --git a/drizzle-seed/tests/pg/pgSchema.ts b/drizzle-seed/tests/pg/pgSchema.ts
index 1a9af755e..05608ab14 100644
--- a/drizzle-seed/tests/pg/pgSchema.ts
+++ b/drizzle-seed/tests/pg/pgSchema.ts
@@ -109,11 +109,21 @@ export const identityColumnsTable = schema.table('identity_columns_table', {
 	name: text(),
 });
 
-export const user = schema.table(
-	'user',
+export const users = schema.table(
+	'users',
 	{
 		id: serial().primaryKey(),
 		name: text(),
-		invitedBy: integer().references((): AnyPgColumn => user.id),
+		invitedBy: integer().references((): AnyPgColumn => users.id),
+	},
+);
+
+export const posts = schema.table(
+	'posts',
+	{
+		id: serial().primaryKey(),
+		name: text(),
+		content: text(),
+		userId: integer().references(() => users.id),
 	},
 );
diff --git a/drizzle-seed/tests/sqlite/sqlite.test.ts b/drizzle-seed/tests/sqlite/sqlite.test.ts
index 550648d49..bf89284d5 100644
--- a/drizzle-seed/tests/sqlite/sqlite.test.ts
+++ b/drizzle-seed/tests/sqlite/sqlite.test.ts
@@ -1,8 +1,8 @@
 import BetterSqlite3 from 'better-sqlite3';
-import { sql } from 'drizzle-orm';
+import { relations, sql } from 'drizzle-orm';
 import type { BetterSQLite3Database } from 'drizzle-orm/better-sqlite3';
 import { drizzle } from 'drizzle-orm/better-sqlite3';
-import { afterAll, afterEach, beforeAll, expect, test } from 'vitest';
+import { afterAll, afterEach, beforeAll, expect, test, vi } from 'vitest';
 import { reset, seed } from '../../src/index.ts';
 import * as schema from './sqliteSchema.ts';
 
@@ -122,6 +122,29 @@ beforeAll(async () => {
 	\`postal_code\` text NOT NULL,
 	\`country\` text NOT NULL,
 	\`phone\` text NOT NULL
+);        
+    `),
+	);
+
+	db.run(
+		sql.raw(`
+    CREATE TABLE \`users\` (
+	\`id\` integer PRIMARY KEY,
+	\`name\` text,
+	\`invitedBy\` integer,
+	FOREIGN KEY (\`invitedBy\`) REFERENCES \`users\`(\`id\`) ON UPDATE no action ON DELETE cascade
+);        
+    `),
+	);
+
+	db.run(
+		sql.raw(`
+    CREATE TABLE \`posts\` (
+	\`id\` integer PRIMARY KEY,
+	\`name\` text,
+	\`content\` text,
+	\`userId\` integer,
+	FOREIGN KEY (\`userId\`) REFERENCES \`users\`(\`id\`) ON UPDATE no action ON DELETE cascade
 );        
     `),
 	);
@@ -288,3 +311,28 @@ test("sequential using of 'with'", async () => {
 	expect(products.length).toBe(11);
 	expect(suppliers.length).toBe(11);
 });
+
+test('overlapping a foreign key constraint with a one-to-many relation', async () => {
+	const postsRelation = relations(schema.posts, ({ one }) => ({
+		user: one(schema.users, { fields: [schema.posts.userId], references: [schema.users.id] }),
+	}));
+
+	const consoleMock = vi.spyOn(console, 'warn').mockImplementation(() => {});
+
+	await reset(db, { users: schema.users, posts: schema.posts, postsRelation });
+	await seed(db, { users: schema.users, posts: schema.posts, postsRelation });
+	// expecting to get a warning
+	expect(consoleMock).toBeCalled();
+	expect(consoleMock).toBeCalledWith(expect.stringMatching(/^You are providing a one-to-many relation.+/));
+
+	const users = await db.select().from(schema.users);
+	const posts = await db.select().from(schema.posts);
+
+	expect(users.length).toBe(10);
+	let predicate = users.every((row) => Object.values(row).every((val) => val !== undefined && val !== null));
+	expect(predicate).toBe(true);
+
+	expect(posts.length).toBe(10);
+	predicate = posts.every((row) => Object.values(row).every((val) => val !== undefined && val !== null));
+	expect(predicate).toBe(true);
+});
diff --git a/drizzle-seed/tests/sqlite/sqliteSchema.ts b/drizzle-seed/tests/sqlite/sqliteSchema.ts
index fa00dd365..fe508321b 100644
--- a/drizzle-seed/tests/sqlite/sqliteSchema.ts
+++ b/drizzle-seed/tests/sqlite/sqliteSchema.ts
@@ -105,3 +105,28 @@ export const details = sqliteTable('order_detail', {
 		.notNull()
 		.references(() => products.id, { onDelete: 'cascade' }),
 });
+
+export const users = sqliteTable(
+	'users',
+	{
+		id: integer().primaryKey(),
+		name: text(),
+		invitedBy: integer(),
+	},
+	(table) => ({
+		reportsToFk: foreignKey(() => ({
+			columns: [table.invitedBy],
+			foreignColumns: [table.id],
+		})),
+	}),
+);
+
+export const posts = sqliteTable(
+	'posts',
+	{
+		id: integer().primaryKey(),
+		name: text(),
+		content: text(),
+		userId: integer().references(() => users.id),
+	},
+);

From c5f4421edd497e25e453a68342f50699caf28cd9 Mon Sep 17 00:00:00 2001
From: Karibash <y.karibayashi@gmail.com>
Date: Tue, 28 Jan 2025 10:08:47 +0900
Subject: [PATCH 03/11] bugfix: Fix bug that generates incorrect syntax when
 introspect in mysql

---
 drizzle-kit/src/introspect-mysql.ts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drizzle-kit/src/introspect-mysql.ts b/drizzle-kit/src/introspect-mysql.ts
index 72d94a6ac..d493ca068 100644
--- a/drizzle-kit/src/introspect-mysql.ts
+++ b/drizzle-kit/src/introspect-mysql.ts
@@ -923,7 +923,7 @@ const createTableIndexes = (
 
 		idxKey = casing(idxKey);
 
-		statement += `\t\t${idxKey}: `;
+		statement += `\n\t`;
 		statement += it.isUnique ? 'uniqueIndex(' : 'index(';
 		statement += `"${it.name}")`;
 		statement += `.on(${

From 43cdb1ed3f8fa834658f95a9b8fd021aedb63f4d Mon Sep 17 00:00:00 2001
From: Karibash <y.karibayashi@gmail.com>
Date: Tue, 28 Jan 2025 12:05:41 +0900
Subject: [PATCH 04/11] bugfix: Fix a bug that caused incorrect syntax output
 when introspect in unsigned columns

---
 drizzle-kit/src/introspect-mysql.ts       | 16 ++++------------
 drizzle-kit/src/introspect-singlestore.ts | 17 ++++-------------
 2 files changed, 8 insertions(+), 25 deletions(-)

diff --git a/drizzle-kit/src/introspect-mysql.ts b/drizzle-kit/src/introspect-mysql.ts
index 72d94a6ac..e46f9f412 100644
--- a/drizzle-kit/src/introspect-mysql.ts
+++ b/drizzle-kit/src/introspect-mysql.ts
@@ -405,9 +405,7 @@ const column = (
 	if (lowered.startsWith('int')) {
 		const isUnsigned = lowered.startsWith('int unsigned');
 		const columnName = dbColumnName({ name, casing: rawCasing, withMode: isUnsigned });
-		let out = `${casing(name)}: int(${columnName}${
-			isUnsigned ? `${columnName.length > 0 ? ', ' : ''}{ unsigned: true }` : ''
-		})`;
+		let out = `${casing(name)}: int(${columnName}${isUnsigned ? '{ unsigned: true }' : ''})`;
 		out += autoincrement ? `.autoincrement()` : '';
 		out += typeof defaultValue !== 'undefined'
 			? `.default(${mapColumnDefault(defaultValue, isExpression)})`
@@ -419,9 +417,7 @@ const column = (
 		const isUnsigned = lowered.startsWith('tinyint unsigned');
 		const columnName = dbColumnName({ name, casing: rawCasing, withMode: isUnsigned });
 		// let out = `${name.camelCase()}: tinyint("${name}")`;
-		let out: string = `${casing(name)}: tinyint(${columnName}${
-			isUnsigned ? `${columnName.length > 0 ? ', ' : ''}{ unsigned: true }` : ''
-		})`;
+		let out: string = `${casing(name)}: tinyint(${columnName}${isUnsigned ? '{ unsigned: true }' : ''})`;
 		out += autoincrement ? `.autoincrement()` : '';
 		out += typeof defaultValue !== 'undefined'
 			? `.default(${mapColumnDefault(defaultValue, isExpression)})`
@@ -432,9 +428,7 @@ const column = (
 	if (lowered.startsWith('smallint')) {
 		const isUnsigned = lowered.startsWith('smallint unsigned');
 		const columnName = dbColumnName({ name, casing: rawCasing, withMode: isUnsigned });
-		let out = `${casing(name)}: smallint(${columnName}${
-			isUnsigned ? `${columnName.length > 0 ? ', ' : ''}{ unsigned: true }` : ''
-		})`;
+		let out = `${casing(name)}: smallint(${columnName}${isUnsigned ? '{ unsigned: true }' : ''})`;
 		out += autoincrement ? `.autoincrement()` : '';
 		out += defaultValue
 			? `.default(${mapColumnDefault(defaultValue, isExpression)})`
@@ -445,9 +439,7 @@ const column = (
 	if (lowered.startsWith('mediumint')) {
 		const isUnsigned = lowered.startsWith('mediumint unsigned');
 		const columnName = dbColumnName({ name, casing: rawCasing, withMode: isUnsigned });
-		let out = `${casing(name)}: mediumint(${columnName}${
-			isUnsigned ? `${columnName.length > 0 ? ', ' : ''}{ unsigned: true }` : ''
-		})`;
+		let out = `${casing(name)}: mediumint(${columnName}${isUnsigned ? '{ unsigned: true }' : ''})`;
 		out += autoincrement ? `.autoincrement()` : '';
 		out += defaultValue
 			? `.default(${mapColumnDefault(defaultValue, isExpression)})`
diff --git a/drizzle-kit/src/introspect-singlestore.ts b/drizzle-kit/src/introspect-singlestore.ts
index ee0ae5e0d..e39c0fe19 100644
--- a/drizzle-kit/src/introspect-singlestore.ts
+++ b/drizzle-kit/src/introspect-singlestore.ts
@@ -380,9 +380,7 @@ const column = (
 	if (lowered.startsWith('int')) {
 		const isUnsigned = lowered.includes('unsigned');
 		const columnName = dbColumnName({ name, casing: rawCasing, withMode: isUnsigned });
-		let out = `${casing(name)}: int(${columnName}${
-			isUnsigned ? `${columnName.length > 0 ? ', ' : ''}{ unsigned: true }` : ''
-		})`;
+		let out = `${casing(name)}: int(${columnName}${isUnsigned ? '{ unsigned: true }' : ''})`;
 		out += autoincrement ? `.autoincrement()` : '';
 		out += typeof defaultValue !== 'undefined'
 			? `.default(${mapColumnDefault(defaultValue, isExpression)})`
@@ -393,10 +391,7 @@ const column = (
 	if (lowered.startsWith('tinyint')) {
 		const isUnsigned = lowered.includes('unsigned');
 		const columnName = dbColumnName({ name, casing: rawCasing, withMode: isUnsigned });
-		// let out = `${name.camelCase()}: tinyint("${name}")`;
-		let out: string = `${casing(name)}: tinyint(${columnName}${
-			isUnsigned ? `${columnName.length > 0 ? ', ' : ''}{ unsigned: true }` : ''
-		})`;
+		let out: string = `${casing(name)}: tinyint(${columnName}${isUnsigned ? '{ unsigned: true }' : ''})`;
 		out += autoincrement ? `.autoincrement()` : '';
 		out += typeof defaultValue !== 'undefined'
 			? `.default(${mapColumnDefault(defaultValue, isExpression)})`
@@ -407,9 +402,7 @@ const column = (
 	if (lowered.startsWith('smallint')) {
 		const isUnsigned = lowered.includes('unsigned');
 		const columnName = dbColumnName({ name, casing: rawCasing, withMode: isUnsigned });
-		let out = `${casing(name)}: smallint(${columnName}${
-			isUnsigned ? `${columnName.length > 0 ? ', ' : ''}{ unsigned: true }` : ''
-		})`;
+		let out = `${casing(name)}: smallint(${columnName}${isUnsigned ? '{ unsigned: true }' : ''})`;
 		out += autoincrement ? `.autoincrement()` : '';
 		out += defaultValue
 			? `.default(${mapColumnDefault(defaultValue, isExpression)})`
@@ -420,9 +413,7 @@ const column = (
 	if (lowered.startsWith('mediumint')) {
 		const isUnsigned = lowered.includes('unsigned');
 		const columnName = dbColumnName({ name, casing: rawCasing, withMode: isUnsigned });
-		let out = `${casing(name)}: mediumint(${columnName}${
-			isUnsigned ? `${columnName.length > 0 ? ', ' : ''}{ unsigned: true }` : ''
-		})`;
+		let out = `${casing(name)}: mediumint(${columnName}${isUnsigned ? '{ unsigned: true }' : ''})`;
 		out += autoincrement ? `.autoincrement()` : '';
 		out += defaultValue
 			? `.default(${mapColumnDefault(defaultValue, isExpression)})`

From 0af1a1290f29608ff7c60dd5a71c13cda9d7e184 Mon Sep 17 00:00:00 2001
From: OleksiiKH0240 <homenko0240@gmail.com>
Date: Tue, 28 Jan 2025 12:45:37 +0200
Subject: [PATCH 05/11] fix

---
 drizzle-seed/src/services/SeedService.ts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drizzle-seed/src/services/SeedService.ts b/drizzle-seed/src/services/SeedService.ts
index e68a939e0..22d92655c 100644
--- a/drizzle-seed/src/services/SeedService.ts
+++ b/drizzle-seed/src/services/SeedService.ts
@@ -411,7 +411,7 @@ export class SeedService {
 			) {
 				orderedTablesNames.push(parent);
 			} else {
-				leafTablesNames.push(parent);
+				leafTablesNames.push(...tablesInOutRelations[parent]!.requiredTableNames, parent);
 				continue;
 			}
 

From 348e49632fc04fcd4e13de3ca99ba5443058bc1b Mon Sep 17 00:00:00 2001
From: Sukairo-02 <sreka9056@gmail.com>
Date: Tue, 28 Jan 2025 15:32:45 +0200
Subject: [PATCH 06/11] Fixed SQLite onConflict clauses being overwritten
 instead of stacked, added related tests, removed unused import

---
 drizzle-orm/src/sqlite-core/db.ts             |   2 +-
 drizzle-orm/src/sqlite-core/dialect.ts        |   4 +-
 .../src/sqlite-core/query-builders/insert.ts  |  15 +-
 .../tests/sqlite/better-sqlite.test.ts        |   2 +-
 .../tests/sqlite/sqlite-common.ts             | 176 ++++++++++++++++++
 5 files changed, 192 insertions(+), 7 deletions(-)

diff --git a/drizzle-orm/src/sqlite-core/db.ts b/drizzle-orm/src/sqlite-core/db.ts
index f8593c783..f5735155f 100644
--- a/drizzle-orm/src/sqlite-core/db.ts
+++ b/drizzle-orm/src/sqlite-core/db.ts
@@ -25,7 +25,7 @@ import { SQLiteCountBuilder } from './query-builders/count.ts';
 import { RelationalQueryBuilder } from './query-builders/query.ts';
 import { SQLiteRaw } from './query-builders/raw.ts';
 import type { SelectedFields } from './query-builders/select.types.ts';
-import type { WithBuilder, WithSubqueryWithSelection } from './subquery.ts';
+import type { WithBuilder } from './subquery.ts';
 import type { SQLiteViewBase } from './view-base.ts';
 
 export class BaseSQLiteDatabase<
diff --git a/drizzle-orm/src/sqlite-core/dialect.ts b/drizzle-orm/src/sqlite-core/dialect.ts
index 8db4ee56b..6eae0dd93 100644
--- a/drizzle-orm/src/sqlite-core/dialect.ts
+++ b/drizzle-orm/src/sqlite-core/dialect.ts
@@ -487,7 +487,9 @@ export abstract class SQLiteDialect {
 			? sql` returning ${this.buildSelection(returning, { isSingleTable: true })}`
 			: undefined;
 
-		const onConflictSql = onConflict ? sql` on conflict ${onConflict}` : undefined;
+		const onConflictSql = onConflict?.length
+			? sql.join(onConflict)
+			: undefined;
 
 		// if (isSingleValue && valuesSqlList.length === 0){
 		// 	return sql`insert into ${table} default values ${onConflictSql}${returningSql}`;
diff --git a/drizzle-orm/src/sqlite-core/query-builders/insert.ts b/drizzle-orm/src/sqlite-core/query-builders/insert.ts
index 2c26df8df..7609162c3 100644
--- a/drizzle-orm/src/sqlite-core/query-builders/insert.ts
+++ b/drizzle-orm/src/sqlite-core/query-builders/insert.ts
@@ -21,7 +21,7 @@ export interface SQLiteInsertConfig<TTable extends SQLiteTable = SQLiteTable> {
 	table: TTable;
 	values: Record<string, Param | SQL>[] | SQLiteInsertSelectQueryBuilder<TTable> | SQL;
 	withList?: Subquery[];
-	onConflict?: SQL;
+	onConflict?: SQL[];
 	returning?: SelectedFieldsOrdered;
 	select?: boolean;
 }
@@ -303,12 +303,14 @@ export class SQLiteInsertBase<
 	 * ```
 	 */
 	onConflictDoNothing(config: { target?: IndexColumn | IndexColumn[]; where?: SQL } = {}): this {
+		if (!this.config.onConflict) this.config.onConflict = [];
+
 		if (config.target === undefined) {
-			this.config.onConflict = sql`do nothing`;
+			this.config.onConflict.push(sql` on conflict do nothing`);
 		} else {
 			const targetSql = Array.isArray(config.target) ? sql`${config.target}` : sql`${[config.target]}`;
 			const whereSql = config.where ? sql` where ${config.where}` : sql``;
-			this.config.onConflict = sql`${targetSql} do nothing${whereSql}`;
+			this.config.onConflict.push(sql` on conflict ${targetSql} do nothing${whereSql}`);
 		}
 		return this;
 	}
@@ -348,12 +350,17 @@ export class SQLiteInsertBase<
 				'You cannot use both "where" and "targetWhere"/"setWhere" at the same time - "where" is deprecated, use "targetWhere" or "setWhere" instead.',
 			);
 		}
+
+		if (!this.config.onConflict) this.config.onConflict = [];
+
 		const whereSql = config.where ? sql` where ${config.where}` : undefined;
 		const targetWhereSql = config.targetWhere ? sql` where ${config.targetWhere}` : undefined;
 		const setWhereSql = config.setWhere ? sql` where ${config.setWhere}` : undefined;
 		const targetSql = Array.isArray(config.target) ? sql`${config.target}` : sql`${[config.target]}`;
 		const setSql = this.dialect.buildUpdateSet(this.config.table, mapUpdateSet(this.config.table, config.set));
-		this.config.onConflict = sql`${targetSql}${targetWhereSql} do update set ${setSql}${whereSql}${setWhereSql}`;
+		this.config.onConflict.push(
+			sql` on conflict ${targetSql}${targetWhereSql} do update set ${setSql}${whereSql}${setWhereSql}`,
+		);
 		return this;
 	}
 
diff --git a/integration-tests/tests/sqlite/better-sqlite.test.ts b/integration-tests/tests/sqlite/better-sqlite.test.ts
index 53feee15f..ed9a2f861 100644
--- a/integration-tests/tests/sqlite/better-sqlite.test.ts
+++ b/integration-tests/tests/sqlite/better-sqlite.test.ts
@@ -6,7 +6,7 @@ import { afterAll, beforeAll, beforeEach, expect, test } from 'vitest';
 import { skipTests } from '~/common';
 import { anotherUsersMigratorTable, tests, usersMigratorTable } from './sqlite-common';
 
-const ENABLE_LOGGING = false;
+const ENABLE_LOGGING = true;
 
 let db: BetterSQLite3Database;
 let client: Database.Database;
diff --git a/integration-tests/tests/sqlite/sqlite-common.ts b/integration-tests/tests/sqlite/sqlite-common.ts
index 2419b1cc2..1263e46ed 100644
--- a/integration-tests/tests/sqlite/sqlite-common.ts
+++ b/integration-tests/tests/sqlite/sqlite-common.ts
@@ -125,6 +125,14 @@ const pkExampleTable = sqliteTable('pk_example', {
 	compositePk: primaryKey({ columns: [table.id, table.name] }),
 }));
 
+const conflictChainExampleTable = sqliteTable('conflict_chain_example', {
+	id: integer('id').notNull().unique(),
+	name: text('name').notNull(),
+	email: text('email').notNull(),
+}, (table) => ({
+	compositePk: primaryKey({ columns: [table.id, table.name] }),
+}));
+
 const bigIntExample = sqliteTable('big_int_example', {
 	id: integer('id').primaryKey(),
 	name: text('name').notNull(),
@@ -154,6 +162,7 @@ export function tests() {
 			await db.run(sql`drop table if exists ${orders}`);
 			await db.run(sql`drop table if exists ${bigIntExample}`);
 			await db.run(sql`drop table if exists ${pkExampleTable}`);
+			await db.run(sql`drop table if exists ${conflictChainExampleTable}`);
 			await db.run(sql`drop table if exists user_notifications_insert_into`);
 			await db.run(sql`drop table if exists users_insert_into`);
 			await db.run(sql`drop table if exists notifications_insert_into`);
@@ -212,6 +221,14 @@ export function tests() {
 					primary key (id, name)
 				)
 			`);
+			await db.run(sql`
+				create table ${conflictChainExampleTable} (
+					id integer not null unique,
+					name text not null,
+					email text not null,
+					primary key (id, name)
+				)
+			`);
 			await db.run(sql`
 				create table ${bigIntExample} (
 				  id integer primary key,
@@ -2037,6 +2054,165 @@ export function tests() {
 			expect(res).toEqual([{ id: 1, name: 'John', email: 'john1@example.com' }]);
 		});
 
+		test('insert with onConflict chained (.update -> .nothing)', async (ctx) => {
+			const { db } = ctx.sqlite;
+
+			await db.insert(conflictChainExampleTable).values([{ id: 1, name: 'John', email: 'john@example.com' }, {
+				id: 2,
+				name: 'John Second',
+				email: '2john@example.com',
+			}]).run();
+
+			await db
+				.insert(conflictChainExampleTable)
+				.values([{ id: 1, name: 'John', email: 'john@example.com' }, {
+					id: 2,
+					name: 'Anthony',
+					email: 'idthief@example.com',
+				}])
+				.onConflictDoUpdate({
+					target: [conflictChainExampleTable.id, conflictChainExampleTable.name],
+					set: { email: 'john1@example.com' },
+				})
+				.onConflictDoNothing({ target: conflictChainExampleTable.id })
+				.run();
+
+			const res = await db
+				.select({
+					id: conflictChainExampleTable.id,
+					name: conflictChainExampleTable.name,
+					email: conflictChainExampleTable.email,
+				})
+				.from(conflictChainExampleTable)
+				.orderBy(conflictChainExampleTable.id)
+				.all();
+
+			expect(res).toEqual([{ id: 1, name: 'John', email: 'john1@example.com' }, {
+				id: 2,
+				name: 'John Second',
+				email: '2john@example.com',
+			}]);
+		});
+
+		test('insert with onConflict chained (.nothing -> .update)', async (ctx) => {
+			const { db } = ctx.sqlite;
+
+			await db.insert(conflictChainExampleTable).values([{ id: 1, name: 'John', email: 'john@example.com' }, {
+				id: 2,
+				name: 'John Second',
+				email: '2john@example.com',
+			}]).run();
+
+			await db
+				.insert(conflictChainExampleTable)
+				.values([{ id: 1, name: 'John', email: 'john@example.com' }, {
+					id: 2,
+					name: 'Anthony',
+					email: 'idthief@example.com',
+				}])
+				.onConflictDoUpdate({
+					target: [conflictChainExampleTable.id, conflictChainExampleTable.name],
+					set: { email: 'john1@example.com' },
+				})
+				.onConflictDoNothing({ target: conflictChainExampleTable.id })
+				.run();
+
+			const res = await db
+				.select({
+					id: conflictChainExampleTable.id,
+					name: conflictChainExampleTable.name,
+					email: conflictChainExampleTable.email,
+				})
+				.from(conflictChainExampleTable)
+				.orderBy(conflictChainExampleTable.id)
+				.all();
+
+			expect(res).toEqual([{ id: 1, name: 'John', email: 'john1@example.com' }, {
+				id: 2,
+				name: 'John Second',
+				email: '2john@example.com',
+			}]);
+		});
+
+		test('insert with onConflict chained (.update -> .update)', async (ctx) => {
+			const { db } = ctx.sqlite;
+
+			await db.insert(conflictChainExampleTable).values([{ id: 1, name: 'John', email: 'john@example.com' }, {
+				id: 2,
+				name: 'John Second',
+				email: '2john@example.com',
+			}]).run();
+
+			await db
+				.insert(conflictChainExampleTable)
+				.values([{ id: 1, name: 'John', email: 'john@example.com' }, {
+					id: 2,
+					name: 'Anthony',
+					email: 'idthief@example.com',
+				}])
+				.onConflictDoUpdate({
+					target: [conflictChainExampleTable.id, conflictChainExampleTable.name],
+					set: { email: 'john1@example.com' },
+				})
+				.onConflictDoUpdate({ target: conflictChainExampleTable.id, set: { email: 'john2@example.com' } })
+				.run();
+
+			const res = await db
+				.select({
+					id: conflictChainExampleTable.id,
+					name: conflictChainExampleTable.name,
+					email: conflictChainExampleTable.email,
+				})
+				.from(conflictChainExampleTable)
+				.orderBy(conflictChainExampleTable.id)
+				.all();
+
+			expect(res).toEqual([{ id: 1, name: 'John', email: 'john1@example.com' }, {
+				id: 2,
+				name: 'John Second',
+				email: 'john2@example.com',
+			}]);
+		});
+
+		test('insert with onConflict chained (.nothing -> .nothing)', async (ctx) => {
+			const { db } = ctx.sqlite;
+
+			await db.insert(conflictChainExampleTable).values([{ id: 1, name: 'John', email: 'john@example.com' }, {
+				id: 2,
+				name: 'John Second',
+				email: '2john@example.com',
+			}]).run();
+
+			await db
+				.insert(conflictChainExampleTable)
+				.values([{ id: 1, name: 'John', email: 'john@example.com' }, {
+					id: 2,
+					name: 'Anthony',
+					email: 'idthief@example.com',
+				}])
+				.onConflictDoNothing({
+					target: [conflictChainExampleTable.id, conflictChainExampleTable.name],
+				})
+				.onConflictDoNothing({ target: conflictChainExampleTable.id })
+				.run();
+
+			const res = await db
+				.select({
+					id: conflictChainExampleTable.id,
+					name: conflictChainExampleTable.name,
+					email: conflictChainExampleTable.email,
+				})
+				.from(conflictChainExampleTable)
+				.orderBy(conflictChainExampleTable.id)
+				.all();
+
+			expect(res).toEqual([{ id: 1, name: 'John', email: 'john@example.com' }, {
+				id: 2,
+				name: 'John Second',
+				email: '2john@example.com',
+			}]);
+		});
+
 		test('insert undefined', async (ctx) => {
 			const { db } = ctx.sqlite;
 

From 2c677837c4c5efa556100fee4c0f8b422f5f74fb Mon Sep 17 00:00:00 2001
From: Sukairo-02 <sreka9056@gmail.com>
Date: Tue, 28 Jan 2025 15:35:02 +0200
Subject: [PATCH 07/11] Reverted flag change

---
 integration-tests/tests/sqlite/better-sqlite.test.ts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/integration-tests/tests/sqlite/better-sqlite.test.ts b/integration-tests/tests/sqlite/better-sqlite.test.ts
index ed9a2f861..53feee15f 100644
--- a/integration-tests/tests/sqlite/better-sqlite.test.ts
+++ b/integration-tests/tests/sqlite/better-sqlite.test.ts
@@ -6,7 +6,7 @@ import { afterAll, beforeAll, beforeEach, expect, test } from 'vitest';
 import { skipTests } from '~/common';
 import { anotherUsersMigratorTable, tests, usersMigratorTable } from './sqlite-common';
 
-const ENABLE_LOGGING = true;
+const ENABLE_LOGGING = false;
 
 let db: BetterSQLite3Database;
 let client: Database.Database;

From 6b6aca742968291d50ac915a903656ff577917e6 Mon Sep 17 00:00:00 2001
From: Sukairo-02 <sreka9056@gmail.com>
Date: Tue, 28 Jan 2025 20:19:47 +0200
Subject: [PATCH 08/11] Fixed types of joined views, fixed `aliasedTable()` not
 aliasing tables on type level, added `View` support to `aliasedTable()`,
 fixed sql builder prefixing aliased views and tables with their schema names

---
 drizzle-orm/src/alias.ts                      |  16 +-
 .../mysql-core/query-builders/select.types.ts |   2 +-
 .../pg-core/query-builders/select.types.ts    |   2 +-
 drizzle-orm/src/sql/sql.ts                    |   4 +-
 .../type-tests/common/aliased-table.ts        | 229 ++++++++++++++++++
 5 files changed, 247 insertions(+), 6 deletions(-)
 create mode 100644 drizzle-orm/type-tests/common/aliased-table.ts

diff --git a/drizzle-orm/src/alias.ts b/drizzle-orm/src/alias.ts
index 0711dc53d..eb2270f8e 100644
--- a/drizzle-orm/src/alias.ts
+++ b/drizzle-orm/src/alias.ts
@@ -1,9 +1,14 @@
 import type { AnyColumn } from './column.ts';
 import { Column } from './column.ts';
 import { entityKind, is } from './entity.ts';
+import type { AnyMySqlTable, BuildAliasTable as BuildAliasMySqlTable, MySqlView } from './mysql-core/index.ts';
+import type { AnyPgTable, BuildAliasTable as BuildAliasPgTable, PgView } from './pg-core/index.ts';
 import type { Relation } from './relations.ts';
 import type { View } from './sql/sql.ts';
 import { SQL, sql } from './sql/sql.ts';
+import type { BuildAliasTable as BuildAliasSQLiteTable } from './sqlite-core/index.ts';
+import type { AnySQLiteTable } from './sqlite-core/table.ts';
+import type { SQLiteView } from './sqlite-core/view.ts';
 import { Table } from './table.ts';
 import { ViewBaseConfig } from './view-common.ts';
 
@@ -88,8 +93,15 @@ export class RelationTableAliasProxyHandler<T extends Relation> implements Proxy
 	}
 }
 
-export function aliasedTable<T extends Table>(table: T, tableAlias: string): T {
-	return new Proxy(table, new TableAliasProxyHandler(tableAlias, false));
+export function aliasedTable<T extends Table | View, TAlias extends string>(
+	table: T,
+	tableAlias: TAlias,
+): T extends AnyPgTable | PgView ? BuildAliasPgTable<T, TAlias>
+	: T extends AnySQLiteTable | SQLiteView ? BuildAliasSQLiteTable<T, TAlias>
+	: T extends AnyMySqlTable | MySqlView ? BuildAliasMySqlTable<T, TAlias>
+	: never
+{
+	return new Proxy(table, new TableAliasProxyHandler(tableAlias, false)) as any;
 }
 
 export function aliasedRelation<T extends Relation>(relation: T, tableAlias: string): T {
diff --git a/drizzle-orm/src/mysql-core/query-builders/select.types.ts b/drizzle-orm/src/mysql-core/query-builders/select.types.ts
index 78b6f91a6..4b0f97d3a 100644
--- a/drizzle-orm/src/mysql-core/query-builders/select.types.ts
+++ b/drizzle-orm/src/mysql-core/query-builders/select.types.ts
@@ -97,7 +97,7 @@ export type MySqlJoin<
 				T['_']['selection'],
 				TJoinedName,
 				TJoinedTable extends MySqlTable ? TJoinedTable['_']['columns']
-					: TJoinedTable extends Subquery ? Assume<TJoinedTable['_']['selectedFields'], SelectedFields>
+					: TJoinedTable extends Subquery | View ? Assume<TJoinedTable['_']['selectedFields'], SelectedFields>
 					: never,
 				T['_']['selectMode']
 			>,
diff --git a/drizzle-orm/src/pg-core/query-builders/select.types.ts b/drizzle-orm/src/pg-core/query-builders/select.types.ts
index 87f21e526..b887c1ebd 100644
--- a/drizzle-orm/src/pg-core/query-builders/select.types.ts
+++ b/drizzle-orm/src/pg-core/query-builders/select.types.ts
@@ -98,7 +98,7 @@ export type PgSelectJoin<
 				T['_']['selection'],
 				TJoinedName,
 				TJoinedTable extends Table ? TJoinedTable['_']['columns']
-					: TJoinedTable extends Subquery ? Assume<TJoinedTable['_']['selectedFields'], SelectedFields>
+					: TJoinedTable extends Subquery | View ? Assume<TJoinedTable['_']['selectedFields'], SelectedFields>
 					: never,
 				T['_']['selectMode']
 			>,
diff --git a/drizzle-orm/src/sql/sql.ts b/drizzle-orm/src/sql/sql.ts
index 50d4c1557..ec4feb20c 100644
--- a/drizzle-orm/src/sql/sql.ts
+++ b/drizzle-orm/src/sql/sql.ts
@@ -181,7 +181,7 @@ export class SQL<T = unknown> implements SQLWrapper {
 				const schemaName = chunk[Table.Symbol.Schema];
 				const tableName = chunk[Table.Symbol.Name];
 				return {
-					sql: schemaName === undefined
+					sql: schemaName === undefined || chunk[IsAlias]
 						? escapeName(tableName)
 						: escapeName(schemaName) + '.' + escapeName(tableName),
 					params: [],
@@ -208,7 +208,7 @@ export class SQL<T = unknown> implements SQLWrapper {
 				const schemaName = chunk[ViewBaseConfig].schema;
 				const viewName = chunk[ViewBaseConfig].name;
 				return {
-					sql: schemaName === undefined
+					sql: schemaName === undefined || chunk[ViewBaseConfig].isAlias
 						? escapeName(viewName)
 						: escapeName(schemaName) + '.' + escapeName(viewName),
 					params: [],
diff --git a/drizzle-orm/type-tests/common/aliased-table.ts b/drizzle-orm/type-tests/common/aliased-table.ts
new file mode 100644
index 000000000..59fc7516f
--- /dev/null
+++ b/drizzle-orm/type-tests/common/aliased-table.ts
@@ -0,0 +1,229 @@
+import { type Equal, Expect } from 'type-tests/utils.ts';
+import { aliasedTable, eq } from '~/index.ts';
+import { drizzle as sqlited } from '~/libsql/index.ts';
+import { mysqlView } from '~/mysql-core/view.ts';
+import { drizzle as mysqld } from '~/mysql2/index.ts';
+import { pgView } from '~/pg-core/view.ts';
+import { drizzle as pgd } from '~/postgres-js/index.ts';
+import { sqliteView } from '~/sqlite-core/view.ts';
+import { users as mysqlUsers } from '../mysql/tables.ts';
+import { users as pgUsers } from '../pg/tables.ts';
+import { users as sqliteUsers } from '../sqlite/tables.ts';
+
+const pg = pgd.mock();
+const sqlite = sqlited.mock();
+const mysql = mysqld.mock();
+
+const pgvUsers = pgView('users_view').as((qb) => qb.select().from(pgUsers));
+const sqlitevUsers = sqliteView('users_view').as((qb) => qb.select().from(sqliteUsers));
+const mysqlvUsers = mysqlView('users_view').as((qb) => qb.select().from(mysqlUsers));
+
+const pgAlias = aliasedTable(pgUsers, 'usersAlias');
+const sqliteAlias = aliasedTable(sqliteUsers, 'usersAlias');
+const mysqlAlias = aliasedTable(mysqlUsers, 'usersAlias');
+
+const pgvAlias = aliasedTable(pgvUsers, 'usersvAlias');
+const sqlitevAlias = aliasedTable(sqlitevUsers, 'usersvAlias');
+const mysqlvAlias = aliasedTable(mysqlvUsers, 'usersvAlias');
+
+const pgRes = await pg.select().from(pgUsers).leftJoin(pgAlias, eq(pgAlias.id, pgUsers.id));
+const sqliteRes = await sqlite.select().from(sqliteUsers).leftJoin(sqliteAlias, eq(sqliteAlias.id, sqliteUsers.id));
+const mysqlRes = await mysql.select().from(mysqlUsers).leftJoin(mysqlAlias, eq(mysqlAlias.id, mysqlUsers.id));
+
+const pgvRes = await pg.select().from(pgUsers).leftJoin(pgvAlias, eq(pgvAlias.id, pgUsers.id));
+const sqlitevRes = await sqlite.select().from(sqliteUsers).leftJoin(sqlitevAlias, eq(sqlitevAlias.id, sqliteUsers.id));
+const mysqlvRes = await mysql.select().from(mysqlUsers).leftJoin(mysqlvAlias, eq(mysqlvAlias.id, mysqlUsers.id));
+
+Expect<
+	Equal<typeof pgRes, {
+		users_table: {
+			id: number;
+			uuid: string;
+			homeCity: number;
+			currentCity: number | null;
+			serialNullable: number;
+			serialNotNull: number;
+			class: 'A' | 'C';
+			subClass: 'B' | 'D' | null;
+			text: string | null;
+			age1: number;
+			createdAt: Date;
+			enumCol: 'a' | 'b' | 'c';
+			arrayCol: string[];
+		};
+		usersAlias: {
+			id: number;
+			uuid: string;
+			homeCity: number;
+			currentCity: number | null;
+			serialNullable: number;
+			serialNotNull: number;
+			class: 'A' | 'C';
+			subClass: 'B' | 'D' | null;
+			text: string | null;
+			age1: number;
+			createdAt: Date;
+			enumCol: 'a' | 'b' | 'c';
+			arrayCol: string[];
+		} | null;
+	}[]>
+>;
+
+Expect<
+	Equal<typeof sqliteRes, {
+		users_table: {
+			id: number;
+			homeCity: number;
+			currentCity: number | null;
+			serialNullable: number | null;
+			serialNotNull: number;
+			class: 'A' | 'C';
+			subClass: 'B' | 'D' | null;
+			name: string | null;
+			age1: number;
+			createdAt: Date;
+			enumCol: 'a' | 'b' | 'c';
+		};
+		usersAlias: {
+			id: number;
+			homeCity: number;
+			currentCity: number | null;
+			serialNullable: number | null;
+			serialNotNull: number;
+			class: 'A' | 'C';
+			subClass: 'B' | 'D' | null;
+			name: string | null;
+			age1: number;
+			createdAt: Date;
+			enumCol: 'a' | 'b' | 'c';
+		} | null;
+	}[]>
+>;
+
+Expect<
+	Equal<typeof mysqlRes, {
+		users_table: {
+			id: number;
+			homeCity: number;
+			currentCity: number | null;
+			serialNullable: number;
+			serialNotNull: number;
+			class: 'A' | 'C';
+			subClass: 'B' | 'D' | null;
+			text: string | null;
+			age1: number;
+			createdAt: Date;
+			enumCol: 'a' | 'b' | 'c';
+		};
+		usersAlias: {
+			id: number;
+			homeCity: number;
+			currentCity: number | null;
+			serialNullable: number;
+			serialNotNull: number;
+			class: 'A' | 'C';
+			subClass: 'B' | 'D' | null;
+			text: string | null;
+			age1: number;
+			createdAt: Date;
+			enumCol: 'a' | 'b' | 'c';
+		} | null;
+	}[]>
+>;
+
+Expect<
+	Equal<typeof pgvRes, {
+		users_table: {
+			id: number;
+			uuid: string;
+			homeCity: number;
+			currentCity: number | null;
+			serialNullable: number;
+			serialNotNull: number;
+			class: 'A' | 'C';
+			subClass: 'B' | 'D' | null;
+			text: string | null;
+			age1: number;
+			createdAt: Date;
+			enumCol: 'a' | 'b' | 'c';
+			arrayCol: string[];
+		};
+		usersvAlias: {
+			id: number;
+			uuid: string;
+			homeCity: number;
+			currentCity: number | null;
+			serialNullable: number;
+			serialNotNull: number;
+			class: 'A' | 'C';
+			subClass: 'B' | 'D' | null;
+			text: string | null;
+			age1: number;
+			createdAt: Date;
+			enumCol: 'a' | 'b' | 'c';
+			arrayCol: string[];
+		} | null;
+	}[]>
+>;
+
+Expect<
+	Equal<typeof sqlitevRes, {
+		users_table: {
+			id: number;
+			homeCity: number;
+			currentCity: number | null;
+			serialNullable: number | null;
+			serialNotNull: number;
+			class: 'A' | 'C';
+			subClass: 'B' | 'D' | null;
+			name: string | null;
+			age1: number;
+			createdAt: Date;
+			enumCol: 'a' | 'b' | 'c';
+		};
+		usersvAlias: {
+			id: number;
+			homeCity: number;
+			currentCity: number | null;
+			serialNullable: number | null;
+			serialNotNull: number;
+			class: 'A' | 'C';
+			subClass: 'B' | 'D' | null;
+			name: string | null;
+			age1: number;
+			createdAt: Date;
+			enumCol: 'a' | 'b' | 'c';
+		} | null;
+	}[]>
+>;
+
+Expect<
+	Equal<typeof mysqlvRes, {
+		users_table: {
+			id: number;
+			homeCity: number;
+			currentCity: number | null;
+			serialNullable: number;
+			serialNotNull: number;
+			class: 'A' | 'C';
+			subClass: 'B' | 'D' | null;
+			text: string | null;
+			age1: number;
+			createdAt: Date;
+			enumCol: 'a' | 'b' | 'c';
+		};
+		usersvAlias: {
+			id: number;
+			homeCity: number;
+			currentCity: number | null;
+			serialNullable: number;
+			serialNotNull: number;
+			class: 'A' | 'C';
+			subClass: 'B' | 'D' | null;
+			text: string | null;
+			age1: number;
+			createdAt: Date;
+			enumCol: 'a' | 'b' | 'c';
+		} | null;
+	}[]>
+>;

From a42bb0391586875cb7e62d8e49bed70164a262d0 Mon Sep 17 00:00:00 2001
From: Sukairo-02 <sreka9056@gmail.com>
Date: Wed, 29 Jan 2025 11:42:22 +0200
Subject: [PATCH 09/11] Reverted `aliasedTable` type improvements in favor of
 dialect-specific `alias` functions

---
 drizzle-orm/src/alias.ts                       | 15 +++------------
 drizzle-orm/type-tests/common/aliased-table.ts | 17 ++++++++++-------
 2 files changed, 13 insertions(+), 19 deletions(-)

diff --git a/drizzle-orm/src/alias.ts b/drizzle-orm/src/alias.ts
index eb2270f8e..21e802a1c 100644
--- a/drizzle-orm/src/alias.ts
+++ b/drizzle-orm/src/alias.ts
@@ -1,14 +1,9 @@
 import type { AnyColumn } from './column.ts';
 import { Column } from './column.ts';
 import { entityKind, is } from './entity.ts';
-import type { AnyMySqlTable, BuildAliasTable as BuildAliasMySqlTable, MySqlView } from './mysql-core/index.ts';
-import type { AnyPgTable, BuildAliasTable as BuildAliasPgTable, PgView } from './pg-core/index.ts';
 import type { Relation } from './relations.ts';
 import type { View } from './sql/sql.ts';
 import { SQL, sql } from './sql/sql.ts';
-import type { BuildAliasTable as BuildAliasSQLiteTable } from './sqlite-core/index.ts';
-import type { AnySQLiteTable } from './sqlite-core/table.ts';
-import type { SQLiteView } from './sqlite-core/view.ts';
 import { Table } from './table.ts';
 import { ViewBaseConfig } from './view-common.ts';
 
@@ -93,14 +88,10 @@ export class RelationTableAliasProxyHandler<T extends Relation> implements Proxy
 	}
 }
 
-export function aliasedTable<T extends Table | View, TAlias extends string>(
+export function aliasedTable<T extends Table | View>(
 	table: T,
-	tableAlias: TAlias,
-): T extends AnyPgTable | PgView ? BuildAliasPgTable<T, TAlias>
-	: T extends AnySQLiteTable | SQLiteView ? BuildAliasSQLiteTable<T, TAlias>
-	: T extends AnyMySqlTable | MySqlView ? BuildAliasMySqlTable<T, TAlias>
-	: never
-{
+	tableAlias: string,
+): T {
 	return new Proxy(table, new TableAliasProxyHandler(tableAlias, false)) as any;
 }
 
diff --git a/drizzle-orm/type-tests/common/aliased-table.ts b/drizzle-orm/type-tests/common/aliased-table.ts
index 59fc7516f..9c2be8c5f 100644
--- a/drizzle-orm/type-tests/common/aliased-table.ts
+++ b/drizzle-orm/type-tests/common/aliased-table.ts
@@ -1,10 +1,13 @@
 import { type Equal, Expect } from 'type-tests/utils.ts';
-import { aliasedTable, eq } from '~/index.ts';
+import { eq } from '~/index.ts';
 import { drizzle as sqlited } from '~/libsql/index.ts';
+import { alias as mysqlAliasFn } from '~/mysql-core/alias.ts';
 import { mysqlView } from '~/mysql-core/view.ts';
 import { drizzle as mysqld } from '~/mysql2/index.ts';
+import { alias as pgAliasFn } from '~/pg-core/alias.ts';
 import { pgView } from '~/pg-core/view.ts';
 import { drizzle as pgd } from '~/postgres-js/index.ts';
+import { alias as sqliteAliasFn } from '~/sqlite-core/alias.ts';
 import { sqliteView } from '~/sqlite-core/view.ts';
 import { users as mysqlUsers } from '../mysql/tables.ts';
 import { users as pgUsers } from '../pg/tables.ts';
@@ -18,13 +21,13 @@ const pgvUsers = pgView('users_view').as((qb) => qb.select().from(pgUsers));
 const sqlitevUsers = sqliteView('users_view').as((qb) => qb.select().from(sqliteUsers));
 const mysqlvUsers = mysqlView('users_view').as((qb) => qb.select().from(mysqlUsers));
 
-const pgAlias = aliasedTable(pgUsers, 'usersAlias');
-const sqliteAlias = aliasedTable(sqliteUsers, 'usersAlias');
-const mysqlAlias = aliasedTable(mysqlUsers, 'usersAlias');
+const pgAlias = pgAliasFn(pgUsers, 'usersAlias');
+const sqliteAlias = sqliteAliasFn(sqliteUsers, 'usersAlias');
+const mysqlAlias = mysqlAliasFn(mysqlUsers, 'usersAlias');
 
-const pgvAlias = aliasedTable(pgvUsers, 'usersvAlias');
-const sqlitevAlias = aliasedTable(sqlitevUsers, 'usersvAlias');
-const mysqlvAlias = aliasedTable(mysqlvUsers, 'usersvAlias');
+const pgvAlias = pgAliasFn(pgvUsers, 'usersvAlias');
+const sqlitevAlias = sqliteAliasFn(sqlitevUsers, 'usersvAlias');
+const mysqlvAlias = mysqlAliasFn(mysqlvUsers, 'usersvAlias');
 
 const pgRes = await pg.select().from(pgUsers).leftJoin(pgAlias, eq(pgAlias.id, pgUsers.id));
 const sqliteRes = await sqlite.select().from(sqliteUsers).leftJoin(sqliteAlias, eq(sqliteAlias.id, sqliteUsers.id));

From 4074110f311e1b39ed4e67457f94e5be1f22a00c Mon Sep 17 00:00:00 2001
From: OleksiiKH0240 <homenko0240@gmail.com>
Date: Wed, 29 Jan 2025 12:22:01 +0200
Subject: [PATCH 10/11] 0.3.1

---
 changelogs/drizzle-seed/0.3.1.md | 38 ++++++++++++++++++++++++++++++++
 drizzle-seed/package.json        |  2 +-
 2 files changed, 39 insertions(+), 1 deletion(-)
 create mode 100644 changelogs/drizzle-seed/0.3.1.md

diff --git a/changelogs/drizzle-seed/0.3.1.md b/changelogs/drizzle-seed/0.3.1.md
new file mode 100644
index 000000000..5e814a468
--- /dev/null
+++ b/changelogs/drizzle-seed/0.3.1.md
@@ -0,0 +1,38 @@
+## Bug fixes
+
+- Combining a reference in a table schema (foreign key constraint) with a one-to-many relation for the same two tables defined in the constraint causes the seeder to duplicate these relations and enter an infinite loop.
+
+Example:
+
+```ts
+// schema.ts
+import { integer, pgTable, text } from "drizzle-orm/pg-core";
+import { relations } from "drizzle-orm/relations";
+
+export const users = pgTable("users", {
+  id: integer().primaryKey(),
+  name: text(),
+  email: text(),
+});
+
+export const posts = pgTable("posts", {
+  id: integer().primaryKey(),
+  content: text(),
+  userId: integer().references(() => users.id),
+});
+
+export const postsRelation = relations(posts, ({ one }) => ({
+  user: one(users, {
+    fields: [posts.userId],
+    references: [users.id],
+  }),
+}));
+```
+
+Now, seeding with the schema above will trigger a warning.
+
+```
+You are providing a one-to-many relation between the 'users' and 'posts' tables,
+while the 'posts' table object already has foreign key constraint in the schema referencing 'users' table.
+In this case, the foreign key constraint will be used.
+```
diff --git a/drizzle-seed/package.json b/drizzle-seed/package.json
index a9287eb28..7efa03353 100644
--- a/drizzle-seed/package.json
+++ b/drizzle-seed/package.json
@@ -1,6 +1,6 @@
 {
 	"name": "drizzle-seed",
-	"version": "0.3.0",
+	"version": "0.3.1",
 	"main": "index.js",
 	"type": "module",
 	"scripts": {

From 5ffd0bdfcf2f60eecbc85f0766c7bd23620d97a1 Mon Sep 17 00:00:00 2001
From: AndriiSherman <andreysherman11@gmail.com>
Date: Wed, 29 Jan 2025 17:17:04 +0200
Subject: [PATCH 11/11] Bump versions

---
 changelogs/drizzle-kit/0.30.4.md | 2 ++
 changelogs/drizzle-orm/0.39.1.md | 3 +++
 drizzle-kit/package.json         | 2 +-
 drizzle-orm/package.json         | 2 +-
 4 files changed, 7 insertions(+), 2 deletions(-)
 create mode 100644 changelogs/drizzle-kit/0.30.4.md
 create mode 100644 changelogs/drizzle-orm/0.39.1.md

diff --git a/changelogs/drizzle-kit/0.30.4.md b/changelogs/drizzle-kit/0.30.4.md
new file mode 100644
index 000000000..005c1a9a8
--- /dev/null
+++ b/changelogs/drizzle-kit/0.30.4.md
@@ -0,0 +1,2 @@
+- Fix bug that generates incorrect syntax when introspect in mysql
+- Fix a bug that caused incorrect syntax output when introspect in unsigned columns
\ No newline at end of file
diff --git a/changelogs/drizzle-orm/0.39.1.md b/changelogs/drizzle-orm/0.39.1.md
new file mode 100644
index 000000000..012e4480e
--- /dev/null
+++ b/changelogs/drizzle-orm/0.39.1.md
@@ -0,0 +1,3 @@
+- Fixed SQLite onConflict clauses being overwritten instead of stacked - [#2276](https://github.com/drizzle-team/drizzle-orm/issues/2276)
+- Added view support to `aliasedTable()`
+- Fixed sql builder prefixing aliased views and tables with their schema
\ No newline at end of file
diff --git a/drizzle-kit/package.json b/drizzle-kit/package.json
index 9d4dd3824..5fe46a455 100644
--- a/drizzle-kit/package.json
+++ b/drizzle-kit/package.json
@@ -1,6 +1,6 @@
 {
 	"name": "drizzle-kit",
-	"version": "0.30.3",
+	"version": "0.30.4",
 	"homepage": "https://orm.drizzle.team",
 	"keywords": [
 		"drizzle",
diff --git a/drizzle-orm/package.json b/drizzle-orm/package.json
index e376281f8..9209685a2 100644
--- a/drizzle-orm/package.json
+++ b/drizzle-orm/package.json
@@ -1,6 +1,6 @@
 {
 	"name": "drizzle-orm",
-	"version": "0.39.0",
+	"version": "0.39.1",
 	"description": "Drizzle ORM package for SQL databases",
 	"type": "module",
 	"scripts": {