drizzle-databend 0.1.12 → 0.1.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/databend-core/db.d.ts +1 -1
- package/dist/databend-core/query-builders/query-builder.d.ts +1 -1
- package/dist/databend-core/query-builders/select.d.ts +2 -1
- package/dist/index.mjs +39 -5
- package/package.json +3 -3
- package/src/databend-core/dialect.ts +4 -3
- package/src/databend-core/query-builders/select.ts +35 -0
- package/src/sql/result-mapper.ts +12 -2
|
@@ -11,7 +11,7 @@ export declare class DatabendDatabase {
|
|
|
11
11
|
query: any;
|
|
12
12
|
constructor(dialect: any, session: any, schema?: any);
|
|
13
13
|
$with(alias: string): {
|
|
14
|
-
as(qb: any): WithSubquery<string,
|
|
14
|
+
as(qb: any): WithSubquery<string, any>;
|
|
15
15
|
};
|
|
16
16
|
$count(source: any, filters?: any): DatabendCountBuilder;
|
|
17
17
|
with(...queries: any[]): {
|
|
@@ -7,7 +7,7 @@ export declare class QueryBuilder {
|
|
|
7
7
|
dialectConfig: any;
|
|
8
8
|
constructor(dialect?: any);
|
|
9
9
|
$with(alias: string): {
|
|
10
|
-
as(qb: any): WithSubquery<string,
|
|
10
|
+
as(qb: any): WithSubquery<string, any>;
|
|
11
11
|
};
|
|
12
12
|
with(...queries: any[]): {
|
|
13
13
|
select: (fields?: any) => DatabendSelectBuilder;
|
|
@@ -26,6 +26,7 @@ declare class DatabendSelectQueryBuilderBase extends TypedQueryBuilder<any, any>
|
|
|
26
26
|
rightJoin: (table: any, on: any) => this;
|
|
27
27
|
innerJoin: (table: any, on: any) => this;
|
|
28
28
|
fullJoin: (table: any, on: any) => this;
|
|
29
|
+
crossJoin: (table: any) => this;
|
|
29
30
|
private createSetOperator;
|
|
30
31
|
union: (rightSelection: any) => this;
|
|
31
32
|
unionAll: (rightSelection: any) => this;
|
|
@@ -44,7 +45,7 @@ declare class DatabendSelectQueryBuilderBase extends TypedQueryBuilder<any, any>
|
|
|
44
45
|
/** @internal */
|
|
45
46
|
getSQL(): any;
|
|
46
47
|
toSQL(): any;
|
|
47
|
-
as(alias: string): Subquery<string,
|
|
48
|
+
as(alias: string): Subquery<string, any>;
|
|
48
49
|
/** @internal */
|
|
49
50
|
getSelectedFields(): any;
|
|
50
51
|
$dynamic(): this;
|
package/dist/index.mjs
CHANGED
|
@@ -1065,6 +1065,7 @@ var DatabendDialect = class {
|
|
|
1065
1065
|
}
|
|
1066
1066
|
const table = joinMeta.table;
|
|
1067
1067
|
const lateralSql = joinMeta.lateral ? sql3` lateral` : void 0;
|
|
1068
|
+
const onClause = joinMeta.on ? sql3` on ${joinMeta.on}` : void 0;
|
|
1068
1069
|
if (is(table, DatabendTable)) {
|
|
1069
1070
|
const t = table;
|
|
1070
1071
|
const tableName = t[DatabendTable.Symbol.Name];
|
|
@@ -1072,7 +1073,7 @@ var DatabendDialect = class {
|
|
|
1072
1073
|
const origTableName = t[DatabendTable.Symbol.OriginalName];
|
|
1073
1074
|
const alias2 = tableName === origTableName ? void 0 : joinMeta.alias;
|
|
1074
1075
|
joinsArray.push(
|
|
1075
|
-
sql3`${sql3.raw(joinMeta.joinType)} join${lateralSql} ${tableSchema ? sql3`${sql3.identifier(tableSchema)}.` : void 0}${sql3.identifier(origTableName)}${alias2 && sql3` ${sql3.identifier(alias2)}`}
|
|
1076
|
+
sql3`${sql3.raw(joinMeta.joinType)} join${lateralSql} ${tableSchema ? sql3`${sql3.identifier(tableSchema)}.` : void 0}${sql3.identifier(origTableName)}${alias2 && sql3` ${sql3.identifier(alias2)}`}${onClause}`
|
|
1076
1077
|
);
|
|
1077
1078
|
} else if (is(table, View2)) {
|
|
1078
1079
|
const viewName = table[ViewBaseConfig].name;
|
|
@@ -1080,11 +1081,11 @@ var DatabendDialect = class {
|
|
|
1080
1081
|
const origViewName = table[ViewBaseConfig].originalName;
|
|
1081
1082
|
const alias2 = viewName === origViewName ? void 0 : joinMeta.alias;
|
|
1082
1083
|
joinsArray.push(
|
|
1083
|
-
sql3`${sql3.raw(joinMeta.joinType)} join${lateralSql} ${viewSchema ? sql3`${sql3.identifier(viewSchema)}.` : void 0}${sql3.identifier(origViewName)}${alias2 && sql3` ${sql3.identifier(alias2)}`}
|
|
1084
|
+
sql3`${sql3.raw(joinMeta.joinType)} join${lateralSql} ${viewSchema ? sql3`${sql3.identifier(viewSchema)}.` : void 0}${sql3.identifier(origViewName)}${alias2 && sql3` ${sql3.identifier(alias2)}`}${onClause}`
|
|
1084
1085
|
);
|
|
1085
1086
|
} else {
|
|
1086
1087
|
joinsArray.push(
|
|
1087
|
-
sql3`${sql3.raw(joinMeta.joinType)} join${lateralSql} ${table}
|
|
1088
|
+
sql3`${sql3.raw(joinMeta.joinType)} join${lateralSql} ${table}${onClause}`
|
|
1088
1089
|
);
|
|
1089
1090
|
}
|
|
1090
1091
|
if (index2 < joins.length - 1) {
|
|
@@ -1807,6 +1808,32 @@ var DatabendSelectQueryBuilderBase = class extends TypedQueryBuilder {
|
|
|
1807
1808
|
rightJoin = this.createJoin("right");
|
|
1808
1809
|
innerJoin = this.createJoin("inner");
|
|
1809
1810
|
fullJoin = this.createJoin("full");
|
|
1811
|
+
crossJoin = (table) => {
|
|
1812
|
+
const baseTableName = this.tableName;
|
|
1813
|
+
const tableName = getTableLikeName(table);
|
|
1814
|
+
if (typeof tableName === "string" && this.config.joins?.some((join) => join.alias === tableName)) {
|
|
1815
|
+
throw new Error(`Alias "${tableName}" is already used in this query`);
|
|
1816
|
+
}
|
|
1817
|
+
if (!this.isPartialSelect) {
|
|
1818
|
+
if (Object.keys(this.joinsNotNullableMap).length === 1 && typeof baseTableName === "string") {
|
|
1819
|
+
this.config.fields = {
|
|
1820
|
+
[baseTableName]: this.config.fields
|
|
1821
|
+
};
|
|
1822
|
+
}
|
|
1823
|
+
if (typeof tableName === "string" && !is5(table, SQL4)) {
|
|
1824
|
+
const selection = is5(table, Subquery2) ? table._.selectedFields : is5(table, View3) ? table[ViewBaseConfig2].selectedFields : table[Table4.Symbol.Columns];
|
|
1825
|
+
this.config.fields[tableName] = selection;
|
|
1826
|
+
}
|
|
1827
|
+
}
|
|
1828
|
+
if (!this.config.joins) {
|
|
1829
|
+
this.config.joins = [];
|
|
1830
|
+
}
|
|
1831
|
+
this.config.joins.push({ on: void 0, table, joinType: "cross", alias: tableName });
|
|
1832
|
+
if (typeof tableName === "string") {
|
|
1833
|
+
this.joinsNotNullableMap[tableName] = true;
|
|
1834
|
+
}
|
|
1835
|
+
return this;
|
|
1836
|
+
};
|
|
1810
1837
|
createSetOperator(type, isAll) {
|
|
1811
1838
|
return (rightSelection) => {
|
|
1812
1839
|
const rightSelect = typeof rightSelection === "function" ? rightSelection(getDatabendSetOperators()) : rightSelection;
|
|
@@ -2925,6 +2952,12 @@ import {
|
|
|
2925
2952
|
is as is10,
|
|
2926
2953
|
SQL as SQL8
|
|
2927
2954
|
} from "drizzle-orm";
|
|
2955
|
+
function getFieldSql(field) {
|
|
2956
|
+
const f = field;
|
|
2957
|
+
if (f.sql instanceof SQL8) return f.sql;
|
|
2958
|
+
if (f._?.sql instanceof SQL8) return f._.sql;
|
|
2959
|
+
throw new Error("Cannot extract SQL from field");
|
|
2960
|
+
}
|
|
2928
2961
|
function toDecoderInput(decoder, value) {
|
|
2929
2962
|
void decoder;
|
|
2930
2963
|
return value;
|
|
@@ -2975,11 +3008,12 @@ function mapResultRow(columns, row, joinsNotNullableMap) {
|
|
|
2975
3008
|
} else if (is10(field, SQL8)) {
|
|
2976
3009
|
decoder = field.decoder;
|
|
2977
3010
|
} else {
|
|
2978
|
-
const
|
|
3011
|
+
const fieldSql = getFieldSql(field);
|
|
3012
|
+
const col = fieldSql.queryChunks.find((chunk) => is10(chunk, Column3));
|
|
2979
3013
|
if (is10(col, DatabendCustomColumn)) {
|
|
2980
3014
|
decoder = col;
|
|
2981
3015
|
} else {
|
|
2982
|
-
decoder =
|
|
3016
|
+
decoder = fieldSql.decoder;
|
|
2983
3017
|
}
|
|
2984
3018
|
}
|
|
2985
3019
|
let node = acc;
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"module": "./dist/index.mjs",
|
|
4
4
|
"main": "./dist/index.mjs",
|
|
5
5
|
"types": "./dist/index.d.ts",
|
|
6
|
-
"version": "0.1.
|
|
6
|
+
"version": "0.1.14",
|
|
7
7
|
"description": "A drizzle ORM driver for use with Databend. Based on drizzle's Postgres driver surface.",
|
|
8
8
|
"type": "module",
|
|
9
9
|
"scripts": {
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
},
|
|
19
19
|
"peerDependencies": {
|
|
20
20
|
"databend-driver": ">=0.33.0",
|
|
21
|
-
"drizzle-orm": "
|
|
21
|
+
"drizzle-orm": ">=0.40.0"
|
|
22
22
|
},
|
|
23
23
|
"peerDependenciesMeta": {
|
|
24
24
|
"databend-driver": {
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"@biomejs/biome": "^2.4.7",
|
|
30
30
|
"@types/node": "^25.5.0",
|
|
31
31
|
"databend-driver": "^0.33.6",
|
|
32
|
-
"drizzle-orm": "0.
|
|
32
|
+
"drizzle-orm": "0.45.0",
|
|
33
33
|
"esbuild": "^0.25.0",
|
|
34
34
|
"typescript": "^5.8.2",
|
|
35
35
|
"vitest": "^1.6.0"
|
|
@@ -206,6 +206,7 @@ export class DatabendDialect {
|
|
|
206
206
|
}
|
|
207
207
|
const table = joinMeta.table;
|
|
208
208
|
const lateralSql = joinMeta.lateral ? sql` lateral` : undefined;
|
|
209
|
+
const onClause = joinMeta.on ? sql` on ${joinMeta.on}` : undefined;
|
|
209
210
|
if (is(table, DatabendTable)) {
|
|
210
211
|
const t = table as any;
|
|
211
212
|
const tableName = t[(DatabendTable as any).Symbol.Name];
|
|
@@ -213,7 +214,7 @@ export class DatabendDialect {
|
|
|
213
214
|
const origTableName = t[(DatabendTable as any).Symbol.OriginalName];
|
|
214
215
|
const alias = tableName === origTableName ? undefined : joinMeta.alias;
|
|
215
216
|
joinsArray.push(
|
|
216
|
-
sql`${sql.raw(joinMeta.joinType)} join${lateralSql} ${tableSchema ? sql`${sql.identifier(tableSchema)}.` : undefined}${sql.identifier(origTableName)}${alias && sql` ${sql.identifier(alias)}`}
|
|
217
|
+
sql`${sql.raw(joinMeta.joinType)} join${lateralSql} ${tableSchema ? sql`${sql.identifier(tableSchema)}.` : undefined}${sql.identifier(origTableName)}${alias && sql` ${sql.identifier(alias)}`}${onClause}`
|
|
217
218
|
);
|
|
218
219
|
} else if (is(table, View)) {
|
|
219
220
|
const viewName = (table as any)[ViewBaseConfig].name;
|
|
@@ -221,11 +222,11 @@ export class DatabendDialect {
|
|
|
221
222
|
const origViewName = (table as any)[ViewBaseConfig].originalName;
|
|
222
223
|
const alias = viewName === origViewName ? undefined : joinMeta.alias;
|
|
223
224
|
joinsArray.push(
|
|
224
|
-
sql`${sql.raw(joinMeta.joinType)} join${lateralSql} ${viewSchema ? sql`${sql.identifier(viewSchema)}.` : undefined}${sql.identifier(origViewName)}${alias && sql` ${sql.identifier(alias)}`}
|
|
225
|
+
sql`${sql.raw(joinMeta.joinType)} join${lateralSql} ${viewSchema ? sql`${sql.identifier(viewSchema)}.` : undefined}${sql.identifier(origViewName)}${alias && sql` ${sql.identifier(alias)}`}${onClause}`
|
|
225
226
|
);
|
|
226
227
|
} else {
|
|
227
228
|
joinsArray.push(
|
|
228
|
-
sql`${sql.raw(joinMeta.joinType)} join${lateralSql} ${table}
|
|
229
|
+
sql`${sql.raw(joinMeta.joinType)} join${lateralSql} ${table}${onClause}`
|
|
229
230
|
);
|
|
230
231
|
}
|
|
231
232
|
if (index < joins.length - 1) {
|
|
@@ -170,6 +170,41 @@ class DatabendSelectQueryBuilderBase extends TypedQueryBuilder<any, any> {
|
|
|
170
170
|
innerJoin = this.createJoin('inner');
|
|
171
171
|
fullJoin = this.createJoin('full');
|
|
172
172
|
|
|
173
|
+
crossJoin = (table: any) => {
|
|
174
|
+
const baseTableName = this.tableName;
|
|
175
|
+
const tableName = getTableLikeName(table);
|
|
176
|
+
|
|
177
|
+
if (typeof tableName === 'string' && this.config.joins?.some((join: any) => join.alias === tableName)) {
|
|
178
|
+
throw new Error(`Alias "${tableName}" is already used in this query`);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
if (!this.isPartialSelect) {
|
|
182
|
+
if (Object.keys(this.joinsNotNullableMap).length === 1 && typeof baseTableName === 'string') {
|
|
183
|
+
this.config.fields = {
|
|
184
|
+
[baseTableName]: this.config.fields,
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
if (typeof tableName === 'string' && !is(table, SQL)) {
|
|
188
|
+
const selection = is(table, Subquery)
|
|
189
|
+
? table._.selectedFields
|
|
190
|
+
: is(table, View)
|
|
191
|
+
? (table as any)[ViewBaseConfig].selectedFields
|
|
192
|
+
: table[(Table as any).Symbol.Columns];
|
|
193
|
+
this.config.fields[tableName] = selection;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
if (!this.config.joins) {
|
|
198
|
+
this.config.joins = [];
|
|
199
|
+
}
|
|
200
|
+
this.config.joins.push({ on: undefined, table, joinType: 'cross', alias: tableName });
|
|
201
|
+
|
|
202
|
+
if (typeof tableName === 'string') {
|
|
203
|
+
this.joinsNotNullableMap[tableName] = true;
|
|
204
|
+
}
|
|
205
|
+
return this;
|
|
206
|
+
};
|
|
207
|
+
|
|
173
208
|
private createSetOperator(type: string, isAll: boolean) {
|
|
174
209
|
return (rightSelection: any) => {
|
|
175
210
|
const rightSelect = typeof rightSelection === 'function'
|
package/src/sql/result-mapper.ts
CHANGED
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
is,
|
|
7
7
|
type SelectedFieldsOrdered,
|
|
8
8
|
SQL,
|
|
9
|
+
Subquery,
|
|
9
10
|
} from 'drizzle-orm';
|
|
10
11
|
import { DatabendCustomColumn } from '../databend-core/columns/custom.ts';
|
|
11
12
|
import { DatabendDate } from '../databend-core/columns/date.ts';
|
|
@@ -15,6 +16,14 @@ type SQLInternal<T = unknown> = SQL<T> & {
|
|
|
15
16
|
decoder: DriverValueDecoder<T, any>;
|
|
16
17
|
};
|
|
17
18
|
|
|
19
|
+
/** Extract SQL from Aliased (has .sql) or Subquery (has _.sql) */
|
|
20
|
+
function getFieldSql(field: unknown): SQL {
|
|
21
|
+
const f = field as any;
|
|
22
|
+
if (f.sql instanceof SQL) return f.sql;
|
|
23
|
+
if (f._?.sql instanceof SQL) return f._.sql;
|
|
24
|
+
throw new Error('Cannot extract SQL from field');
|
|
25
|
+
}
|
|
26
|
+
|
|
18
27
|
type DecoderInput<TDecoder extends DriverValueDecoder<unknown, unknown>> =
|
|
19
28
|
Parameters<TDecoder['mapFromDriverValue']>[0];
|
|
20
29
|
|
|
@@ -113,12 +122,13 @@ export function mapResultRow<TResult>(
|
|
|
113
122
|
} else if (is(field, SQL)) {
|
|
114
123
|
decoder = (field as SQLInternal).decoder;
|
|
115
124
|
} else {
|
|
116
|
-
const
|
|
125
|
+
const fieldSql = getFieldSql(field);
|
|
126
|
+
const col = fieldSql.queryChunks.find((chunk) => is(chunk, Column));
|
|
117
127
|
|
|
118
128
|
if (is(col, DatabendCustomColumn)) {
|
|
119
129
|
decoder = col;
|
|
120
130
|
} else {
|
|
121
|
-
decoder = (
|
|
131
|
+
decoder = (fieldSql as SQLInternal).decoder;
|
|
122
132
|
}
|
|
123
133
|
}
|
|
124
134
|
let node = acc;
|