Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Beta #4037

Merged
merged 18 commits into from
Jan 29, 2025
Merged

Beta #4037

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions changelogs/drizzle-kit/0.30.4.md
Original file line number Diff line number Diff line change
@@ -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
3 changes: 3 additions & 0 deletions changelogs/drizzle-orm/0.39.1.md
Original file line number Diff line number Diff line change
@@ -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
38 changes: 38 additions & 0 deletions changelogs/drizzle-seed/0.3.1.md
Original file line number Diff line number Diff line change
@@ -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.
```
2 changes: 1 addition & 1 deletion drizzle-kit/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "drizzle-kit",
"version": "0.30.3",
"version": "0.30.4",
"homepage": "https://orm.drizzle.team",
"keywords": [
"drizzle",
Expand Down
18 changes: 5 additions & 13 deletions drizzle-kit/src/introspect-mysql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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)})`
Expand All @@ -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)})`
Expand All @@ -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)})`
Expand All @@ -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)})`
Expand Down Expand Up @@ -923,7 +915,7 @@ const createTableIndexes = (

idxKey = casing(idxKey);

statement += `\t\t${idxKey}: `;
statement += `\n\t`;
statement += it.isUnique ? 'uniqueIndex(' : 'index(';
statement += `"${it.name}")`;
statement += `.on(${
Expand Down
17 changes: 4 additions & 13 deletions drizzle-kit/src/introspect-singlestore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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)})`
Expand All @@ -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)})`
Expand All @@ -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)})`
Expand All @@ -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)})`
Expand Down
2 changes: 1 addition & 1 deletion drizzle-orm/package.json
Original file line number Diff line number Diff line change
@@ -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": {
Expand Down
7 changes: 5 additions & 2 deletions drizzle-orm/src/alias.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,11 @@ 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>(
table: T,
tableAlias: string,
): T {
return new Proxy(table, new TableAliasProxyHandler(tableAlias, false)) as any;
}

export function aliasedRelation<T extends Relation>(relation: T, tableAlias: string): T {
Expand Down
2 changes: 1 addition & 1 deletion drizzle-orm/src/mysql-core/query-builders/select.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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']
>,
Expand Down
2 changes: 1 addition & 1 deletion drizzle-orm/src/pg-core/query-builders/select.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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']
>,
Expand Down
4 changes: 2 additions & 2 deletions drizzle-orm/src/sql/sql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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: [],
Expand All @@ -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: [],
Expand Down
2 changes: 1 addition & 1 deletion drizzle-orm/src/sqlite-core/db.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<
Expand Down
4 changes: 3 additions & 1 deletion drizzle-orm/src/sqlite-core/dialect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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}`;
Expand Down
15 changes: 11 additions & 4 deletions drizzle-orm/src/sqlite-core/query-builders/insert.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
}

Expand Down
Loading
Loading