Skip to content

Commit

Permalink
Merge pull request #4037 from drizzle-team/beta
Browse files Browse the repository at this point in the history
Beta
  • Loading branch information
AndriiSherman authored Jan 29, 2025
2 parents 1dd14ac + 5ffd0bd commit 4d72640
Show file tree
Hide file tree
Showing 29 changed files with 891 additions and 219 deletions.
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

0 comments on commit 4d72640

Please sign in to comment.