@leonardovida-md/drizzle-neo-duckdb 1.0.2 → 1.0.3

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/src/introspect.ts CHANGED
@@ -466,17 +466,17 @@ function emitConstraints(
466
466
  .map((col) => `t.${toIdentifier(col)}`)
467
467
  .join(', ')}], name: ${JSON.stringify(constraint.name)} })`
468
468
  );
469
- } else if (
470
- constraint.type === 'UNIQUE' &&
471
- constraint.columns.length > 1
472
- ) {
469
+ } else if (constraint.type === 'UNIQUE' && constraint.columns.length > 1) {
473
470
  imports.pgCore.add('unique');
474
471
  entries.push(
475
472
  `${key}: unique(${JSON.stringify(constraint.name)}).on(${constraint.columns
476
473
  .map((col) => `t.${toIdentifier(col)}`)
477
474
  .join(', ')})`
478
475
  );
479
- } else if (constraint.type === 'FOREIGN KEY' && constraint.referencedTable) {
476
+ } else if (
477
+ constraint.type === 'FOREIGN KEY' &&
478
+ constraint.referencedTable
479
+ ) {
480
480
  imports.pgCore.add('foreignKey');
481
481
  const targetTable = toIdentifier(constraint.referencedTable.name);
482
482
  entries.push(
@@ -546,7 +546,10 @@ function buildDefault(defaultValue: string | null): string {
546
546
  if (/^nextval\(/i.test(trimmed)) {
547
547
  return `.default(sql\`${trimmed}\`)`;
548
548
  }
549
- if (/^current_timestamp(?:\(\))?$/i.test(trimmed) || /^now\(\)$/i.test(trimmed)) {
549
+ if (
550
+ /^current_timestamp(?:\(\))?$/i.test(trimmed) ||
551
+ /^now\(\)$/i.test(trimmed)
552
+ ) {
550
553
  return `.defaultNow()`;
551
554
  }
552
555
  if (trimmed === 'true' || trimmed === 'false') {
@@ -604,7 +607,11 @@ function mapDuckDbType(
604
607
 
605
608
  if (upper === 'BIGINT' || upper === 'INT8' || upper === 'UBIGINT') {
606
609
  imports.pgCore.add('bigint');
607
- return { builder: `bigint(${columnName(column.name)})` };
610
+ // Drizzle's bigint helper requires an explicit mode. Default to 'number'
611
+ // to mirror DuckDB's typical 64-bit integer behavior in JS.
612
+ return {
613
+ builder: `bigint(${columnName(column.name)}, { mode: 'number' })`,
614
+ };
608
615
  }
609
616
 
610
617
  const decimalMatch = /^DECIMAL\((\d+),(\d+)\)/i.exec(upper);
@@ -894,9 +901,7 @@ function renderImports(imports: ImportBuckets, importBasePath: string): string {
894
901
  const pgCore = [...imports.pgCore];
895
902
  if (pgCore.length) {
896
903
  lines.push(
897
- `import { ${pgCore
898
- .sort()
899
- .join(', ')} } from 'drizzle-orm/pg-core';`
904
+ `import { ${pgCore.sort().join(', ')} } from 'drizzle-orm/pg-core';`
900
905
  );
901
906
  }
902
907
 
package/src/migrator.ts CHANGED
@@ -10,9 +10,7 @@ export async function migrate<TSchema extends Record<string, unknown>>(
10
10
  config: DuckDbMigrationConfig
11
11
  ) {
12
12
  const migrationConfig: MigrationConfig =
13
- typeof config === 'string'
14
- ? { migrationsFolder: config }
15
- : config;
13
+ typeof config === 'string' ? { migrationsFolder: config } : config;
16
14
 
17
15
  const migrations = readMigrationFiles(migrationConfig);
18
16
 
package/src/olap.ts ADDED
@@ -0,0 +1,189 @@
1
+ import { is } from 'drizzle-orm/entity';
2
+ import { sql, Subquery, type SQLWrapper } from 'drizzle-orm';
3
+ import type { AnyPgColumn, PgTable } from 'drizzle-orm/pg-core';
4
+ import type { PgViewBase } from 'drizzle-orm/pg-core/view-base';
5
+ import type { SelectedFields } from 'drizzle-orm/pg-core/query-builders';
6
+ import { SQL } from 'drizzle-orm/sql/sql';
7
+ import { Column, getTableName } from 'drizzle-orm';
8
+ import type { DuckDBDatabase } from './driver.ts';
9
+
10
+ export const countN = (expr: SQLWrapper = sql`*`) =>
11
+ sql<number>`count(${expr})`.mapWith(Number);
12
+
13
+ export const sumN = (expr: SQLWrapper) =>
14
+ sql<number>`sum(${expr})`.mapWith(Number);
15
+
16
+ export const avgN = (expr: SQLWrapper) =>
17
+ sql<number>`avg(${expr})`.mapWith(Number);
18
+
19
+ export const sumDistinctN = (expr: SQLWrapper) =>
20
+ sql<number>`sum(distinct ${expr})`.mapWith(Number);
21
+
22
+ export const percentileCont = (p: number, expr: SQLWrapper) =>
23
+ sql<number>`percentile_cont(${p}) within group (order by ${expr})`.mapWith(
24
+ Number
25
+ );
26
+
27
+ export const median = (expr: SQLWrapper) => percentileCont(0.5, expr);
28
+
29
+ export const anyValue = <T = unknown>(expr: SQLWrapper) =>
30
+ sql<T>`any_value(${expr})`;
31
+
32
+ type PartitionOrder =
33
+ | {
34
+ partitionBy?: SQLWrapper | SQLWrapper[];
35
+ orderBy?: SQLWrapper | SQLWrapper[];
36
+ }
37
+ | undefined;
38
+
39
+ function normalizeArray<T>(value?: T | T[]): T[] {
40
+ if (!value) return [];
41
+ return Array.isArray(value) ? value : [value];
42
+ }
43
+
44
+ function overClause(options?: PartitionOrder) {
45
+ const partitions = normalizeArray(options?.partitionBy);
46
+ const orders = normalizeArray(options?.orderBy);
47
+
48
+ const chunks: SQLWrapper[] = [];
49
+
50
+ if (partitions.length > 0) {
51
+ chunks.push(sql`partition by ${sql.join(partitions, sql`, `)}`);
52
+ }
53
+
54
+ if (orders.length > 0) {
55
+ chunks.push(sql`order by ${sql.join(orders, sql`, `)}`);
56
+ }
57
+
58
+ if (chunks.length === 0) {
59
+ return sql``;
60
+ }
61
+
62
+ return sql`over (${sql.join(chunks, sql` `)})`;
63
+ }
64
+
65
+ export const rowNumber = (options?: PartitionOrder) =>
66
+ sql<number>`row_number() ${overClause(options)}`.mapWith(Number);
67
+
68
+ export const rank = (options?: PartitionOrder) =>
69
+ sql<number>`rank() ${overClause(options)}`.mapWith(Number);
70
+
71
+ export const denseRank = (options?: PartitionOrder) =>
72
+ sql<number>`dense_rank() ${overClause(options)}`.mapWith(Number);
73
+
74
+ export const lag = <T = unknown>(
75
+ expr: SQLWrapper,
76
+ offset = 1,
77
+ defaultValue?: SQLWrapper,
78
+ options?: PartitionOrder
79
+ ) =>
80
+ defaultValue
81
+ ? sql<T>`lag(${expr}, ${offset}, ${defaultValue}) ${overClause(options)}`
82
+ : sql<T>`lag(${expr}, ${offset}) ${overClause(options)}`;
83
+
84
+ export const lead = <T = unknown>(
85
+ expr: SQLWrapper,
86
+ offset = 1,
87
+ defaultValue?: SQLWrapper,
88
+ options?: PartitionOrder
89
+ ) =>
90
+ defaultValue
91
+ ? sql<T>`lead(${expr}, ${offset}, ${defaultValue}) ${overClause(options)}`
92
+ : sql<T>`lead(${expr}, ${offset}) ${overClause(options)}`;
93
+
94
+ type ValueExpr = SQL | SQL.Aliased | AnyPgColumn;
95
+ type GroupKey = ValueExpr;
96
+ type MeasureMap = Record<string, ValueExpr>;
97
+ type NonAggMap = Record<string, ValueExpr>;
98
+
99
+ function keyAlias(key: SQLWrapper, fallback: string): string {
100
+ if (is(key, SQL.Aliased)) {
101
+ return key.fieldAlias ?? fallback;
102
+ }
103
+ if (is(key, Column)) {
104
+ return `${getTableName(key.table)}.${key.name}`;
105
+ }
106
+ return fallback;
107
+ }
108
+
109
+ export class OlapBuilder {
110
+ private source?: PgTable | Subquery | PgViewBase | SQL;
111
+ private keys: GroupKey[] = [];
112
+ private measureMap: MeasureMap = {};
113
+ private nonAggregates: NonAggMap = {};
114
+ private wrapNonAggWithAnyValue = false;
115
+ private orderByClauses: ValueExpr[] = [];
116
+
117
+ constructor(private db: DuckDBDatabase) {}
118
+
119
+ from(source: PgTable | Subquery | PgViewBase | SQL): this {
120
+ this.source = source;
121
+ return this;
122
+ }
123
+
124
+ groupBy(keys: GroupKey[]): this {
125
+ this.keys = keys;
126
+ return this;
127
+ }
128
+
129
+ measures(measures: MeasureMap): this {
130
+ this.measureMap = measures;
131
+ return this;
132
+ }
133
+
134
+ selectNonAggregates(
135
+ fields: NonAggMap,
136
+ options: { anyValue?: boolean } = {}
137
+ ): this {
138
+ this.nonAggregates = fields;
139
+ this.wrapNonAggWithAnyValue = options.anyValue ?? false;
140
+ return this;
141
+ }
142
+
143
+ orderBy(...clauses: ValueExpr[]): this {
144
+ this.orderByClauses = clauses;
145
+ return this;
146
+ }
147
+
148
+ build() {
149
+ if (!this.source) {
150
+ throw new Error('olap: .from() is required');
151
+ }
152
+ if (this.keys.length === 0) {
153
+ throw new Error('olap: .groupBy() is required');
154
+ }
155
+ if (Object.keys(this.measureMap).length === 0) {
156
+ throw new Error('olap: .measures() is required');
157
+ }
158
+
159
+ const selection: Record<string, ValueExpr> = {};
160
+
161
+ this.keys.forEach((key, idx) => {
162
+ const alias = keyAlias(key, `key_${idx}`);
163
+ selection[alias] = key;
164
+ });
165
+
166
+ Object.entries(this.nonAggregates).forEach(([alias, expr]) => {
167
+ selection[alias] = this.wrapNonAggWithAnyValue ? anyValue(expr) : expr;
168
+ });
169
+
170
+ Object.assign(selection, this.measureMap);
171
+
172
+ let query: any = this.db
173
+ .select(selection as SelectedFields)
174
+ .from(this.source!)
175
+ .groupBy(...this.keys);
176
+
177
+ if (this.orderByClauses.length > 0) {
178
+ query = query.orderBy(...this.orderByClauses);
179
+ }
180
+
181
+ return query;
182
+ }
183
+
184
+ run() {
185
+ return this.build();
186
+ }
187
+ }
188
+
189
+ export const olap = (db: DuckDBDatabase) => new OlapBuilder(db);
@@ -6,11 +6,7 @@ import {
6
6
  type SelectedFields,
7
7
  type TableLikeHasEmptySelection,
8
8
  } from 'drizzle-orm/pg-core/query-builders';
9
- import {
10
- PgColumn,
11
- PgTable,
12
- type PgSession,
13
- } from 'drizzle-orm/pg-core';
9
+ import { PgColumn, PgTable, type PgSession } from 'drizzle-orm/pg-core';
14
10
  import { Subquery, ViewBaseConfig, type SQLWrapper } from 'drizzle-orm';
15
11
  import { PgViewBase } from 'drizzle-orm/pg-core/view-base';
16
12
  import type {
@@ -25,7 +21,7 @@ import { getTableColumns, type DrizzleTypeError } from 'drizzle-orm/utils';
25
21
  interface PgViewBaseInternal<
26
22
  TName extends string = string,
27
23
  TExisting extends boolean = boolean,
28
- TSelectedFields extends ColumnsSelection = ColumnsSelection
24
+ TSelectedFields extends ColumnsSelection = ColumnsSelection,
29
25
  > extends PgViewBase<TName, TExisting, TSelectedFields> {
30
26
  [ViewBaseConfig]?: {
31
27
  selectedFields: SelectedFields;
@@ -34,7 +30,7 @@ interface PgViewBaseInternal<
34
30
 
35
31
  export class DuckDBSelectBuilder<
36
32
  TSelection extends SelectedFields | undefined,
37
- TBuilderMode extends 'db' | 'qb' = 'db'
33
+ TBuilderMode extends 'db' | 'qb' = 'db',
38
34
  > extends PgSelectBuilder<TSelection, TBuilderMode> {
39
35
  private _fields: TSelection;
40
36
  private _session: PgSession | undefined;
package/src/session.ts CHANGED
@@ -20,12 +20,18 @@ import { mapResultRow } from './sql/result-mapper.ts';
20
20
  import type { DuckDBDialect } from './dialect.ts';
21
21
  import { TransactionRollbackError } from 'drizzle-orm/errors';
22
22
  import type { DuckDBClientLike, RowData } from './client.ts';
23
- import { executeOnClient, prepareParams } from './client.ts';
23
+ import {
24
+ executeArrowOnClient,
25
+ executeInBatches,
26
+ executeOnClient,
27
+ prepareParams,
28
+ type ExecuteInBatchesOptions,
29
+ } from './client.ts';
24
30
 
25
31
  export type { DuckDBClientLike, RowData } from './client.ts';
26
32
 
27
33
  export class DuckDBPreparedQuery<
28
- T extends PreparedQueryConfig
34
+ T extends PreparedQueryConfig,
29
35
  > extends PgPreparedQuery<T> {
30
36
  static readonly [entityKind]: string = 'DuckDBPreparedQuery';
31
37
 
@@ -37,7 +43,9 @@ export class DuckDBPreparedQuery<
37
43
  private logger: Logger,
38
44
  private fields: SelectedFieldsOrdered | undefined,
39
45
  private _isResponseInArrayMode: boolean,
40
- private customResultMapper: ((rows: unknown[][]) => T['execute']) | undefined,
46
+ private customResultMapper:
47
+ | ((rows: unknown[][]) => T['execute'])
48
+ | undefined,
41
49
  private rewriteArrays: boolean,
42
50
  private rejectStringArrayLiterals: boolean,
43
51
  private warnOnStringArrayLiteral?: (sql: string) => void
@@ -71,17 +79,10 @@ export class DuckDBPreparedQuery<
71
79
 
72
80
  this.logger.logQuery(rewrittenQuery, params);
73
81
 
74
- const {
75
- fields,
76
- joinsNotNullableMap,
77
- customResultMapper,
78
- } = this as typeof this & { joinsNotNullableMap?: Record<string, boolean> };
82
+ const { fields, joinsNotNullableMap, customResultMapper } =
83
+ this as typeof this & { joinsNotNullableMap?: Record<string, boolean> };
79
84
 
80
- const rows = await executeOnClient(
81
- this.client,
82
- rewrittenQuery,
83
- params
84
- );
85
+ const rows = await executeOnClient(this.client, rewrittenQuery, params);
85
86
 
86
87
  if (rows.length === 0 || !fields) {
87
88
  return rows as T['execute'];
@@ -115,7 +116,7 @@ export interface DuckDBSessionOptions {
115
116
 
116
117
  export class DuckDBSession<
117
118
  TFullSchema extends Record<string, unknown> = Record<string, never>,
118
- TSchema extends TablesRelationalConfig = Record<string, never>
119
+ TSchema extends TablesRelationalConfig = Record<string, never>,
119
120
  > extends PgSession<DuckDBQueryResultHKT, TFullSchema, TSchema> {
120
121
  static readonly [entityKind]: string = 'DuckDBSession';
121
122
 
@@ -199,11 +200,67 @@ export class DuckDBSession<
199
200
  []
200
201
  );
201
202
  };
203
+
204
+ executeBatches<T extends RowData = RowData>(
205
+ query: SQL,
206
+ options: ExecuteInBatchesOptions = {}
207
+ ): AsyncGenerator<GenericRowData<T>[], void, void> {
208
+ const builtQuery = this.dialect.sqlToQuery(query);
209
+ const params = prepareParams(builtQuery.params, {
210
+ rejectStringArrayLiterals: this.rejectStringArrayLiterals,
211
+ warnOnStringArrayLiteral: this.rejectStringArrayLiterals
212
+ ? undefined
213
+ : () => this.warnOnStringArrayLiteral(builtQuery.sql),
214
+ });
215
+ const rewrittenQuery = this.rewriteArrays
216
+ ? adaptArrayOperators(builtQuery.sql)
217
+ : builtQuery.sql;
218
+
219
+ if (this.rewriteArrays && rewrittenQuery !== builtQuery.sql) {
220
+ this.logger.logQuery(
221
+ `[duckdb] original query before array rewrite: ${builtQuery.sql}`,
222
+ params
223
+ );
224
+ }
225
+
226
+ this.logger.logQuery(rewrittenQuery, params);
227
+
228
+ return executeInBatches(
229
+ this.client,
230
+ rewrittenQuery,
231
+ params,
232
+ options
233
+ ) as AsyncGenerator<GenericRowData<T>[], void, void>;
234
+ }
235
+
236
+ async executeArrow(query: SQL): Promise<unknown> {
237
+ const builtQuery = this.dialect.sqlToQuery(query);
238
+ const params = prepareParams(builtQuery.params, {
239
+ rejectStringArrayLiterals: this.rejectStringArrayLiterals,
240
+ warnOnStringArrayLiteral: this.rejectStringArrayLiterals
241
+ ? undefined
242
+ : () => this.warnOnStringArrayLiteral(builtQuery.sql),
243
+ });
244
+ const rewrittenQuery = this.rewriteArrays
245
+ ? adaptArrayOperators(builtQuery.sql)
246
+ : builtQuery.sql;
247
+
248
+ if (this.rewriteArrays && rewrittenQuery !== builtQuery.sql) {
249
+ this.logger.logQuery(
250
+ `[duckdb] original query before array rewrite: ${builtQuery.sql}`,
251
+ params
252
+ );
253
+ }
254
+
255
+ this.logger.logQuery(rewrittenQuery, params);
256
+
257
+ return executeArrowOnClient(this.client, rewrittenQuery, params);
258
+ }
202
259
  }
203
260
 
204
261
  type PgTransactionInternals<
205
262
  TFullSchema extends Record<string, unknown> = Record<string, never>,
206
- TSchema extends TablesRelationalConfig = Record<string, never>
263
+ TSchema extends TablesRelationalConfig = Record<string, never>,
207
264
  > = {
208
265
  dialect: DuckDBDialect;
209
266
  session: DuckDBSession<TFullSchema, TSchema>;
@@ -211,13 +268,13 @@ type PgTransactionInternals<
211
268
 
212
269
  type DuckDBTransactionWithInternals<
213
270
  TFullSchema extends Record<string, unknown> = Record<string, never>,
214
- TSchema extends TablesRelationalConfig = Record<string, never>
271
+ TSchema extends TablesRelationalConfig = Record<string, never>,
215
272
  > = PgTransactionInternals<TFullSchema, TSchema> &
216
273
  DuckDBTransaction<TFullSchema, TSchema>;
217
274
 
218
275
  export class DuckDBTransaction<
219
276
  TFullSchema extends Record<string, unknown>,
220
- TSchema extends TablesRelationalConfig
277
+ TSchema extends TablesRelationalConfig,
221
278
  > extends PgTransaction<DuckDBQueryResultHKT, TFullSchema, TSchema> {
222
279
  static readonly [entityKind]: string = 'DuckDBTransaction';
223
280
 
@@ -246,6 +303,19 @@ export class DuckDBTransaction<
246
303
  );
247
304
  }
248
305
 
306
+ executeBatches<T extends RowData = RowData>(
307
+ query: SQL,
308
+ options: ExecuteInBatchesOptions = {}
309
+ ): AsyncGenerator<GenericRowData<T>[], void, void> {
310
+ type Tx = DuckDBTransactionWithInternals<TFullSchema, TSchema>;
311
+ return (this as unknown as Tx).session.executeBatches<T>(query, options);
312
+ }
313
+
314
+ executeArrow(query: SQL): Promise<unknown> {
315
+ type Tx = DuckDBTransactionWithInternals<TFullSchema, TSchema>;
316
+ return (this as unknown as Tx).session.executeArrow(query);
317
+ }
318
+
249
319
  override async transaction<T>(
250
320
  transaction: (tx: DuckDBTransaction<TFullSchema, TSchema>) => Promise<T>
251
321
  ): Promise<T> {
@@ -268,7 +338,6 @@ export type GenericTableData<T = RowData> = T[];
268
338
  const arrayLiteralWarning =
269
339
  'Received a stringified Postgres-style array literal. Use duckDbList()/duckDbArray() or pass native arrays instead. You can also set rejectStringArrayLiterals=true to throw.';
270
340
 
271
-
272
341
  export interface DuckDBQueryResultHKT extends PgQueryResultHKT {
273
342
  type: GenericTableData<Assume<this['row'], RowData>>;
274
343
  }
@@ -85,10 +85,7 @@ export function adaptArrayOperators(query: string): string {
85
85
  let idx = rewritten.indexOf(token);
86
86
  while (idx !== -1) {
87
87
  const [leftStart, leftExpr] = walkLeft(rewritten, idx - 1);
88
- const [rightEnd, rightExpr] = walkRight(
89
- rewritten,
90
- idx + token.length
91
- );
88
+ const [rightEnd, rightExpr] = walkRight(rewritten, idx + token.length);
92
89
 
93
90
  const left = leftExpr.trim();
94
91
  const right = rightExpr.trim();
@@ -98,9 +95,7 @@ export function adaptArrayOperators(query: string): string {
98
95
  })`;
99
96
 
100
97
  rewritten =
101
- rewritten.slice(0, leftStart) +
102
- replacement +
103
- rewritten.slice(rightEnd);
98
+ rewritten.slice(0, leftStart) + replacement + rewritten.slice(rightEnd);
104
99
 
105
100
  idx = rewritten.indexOf(token, leftStart + replacement.length);
106
101
  }
@@ -136,7 +131,9 @@ export function queryAdapter(query: string): string {
136
131
  if (noTableProp) {
137
132
  const [, column, alias] = noTableProp;
138
133
  const asAlias = ` as '${column}'`;
139
- return alias ? trimmedField.replace(alias, asAlias) : `${trimmedField}${asAlias}`;
134
+ return alias
135
+ ? trimmedField.replace(alias, asAlias)
136
+ : `${trimmedField}${asAlias}`;
140
137
  }
141
138
 
142
139
  return trimmedField;
@@ -88,7 +88,10 @@ function normalizeTimestampString(
88
88
  return value;
89
89
  }
90
90
 
91
- function normalizeTimestamp(value: unknown, withTimezone: boolean): Date | unknown {
91
+ function normalizeTimestamp(
92
+ value: unknown,
93
+ withTimezone: boolean
94
+ ): Date | unknown {
92
95
  if (value instanceof Date) {
93
96
  return value;
94
97
  }
@@ -96,8 +99,7 @@ function normalizeTimestamp(value: unknown, withTimezone: boolean): Date | unkno
96
99
  const hasOffset =
97
100
  value.endsWith('Z') || /[+-]\d{2}:?\d{2}$/.test(value.trim());
98
101
  const spaced = value.replace(' ', 'T');
99
- const normalized =
100
- withTimezone || hasOffset ? spaced : `${spaced}+00`;
102
+ const normalized = withTimezone || hasOffset ? spaced : `${spaced}+00`;
101
103
  return new Date(normalized);
102
104
  }
103
105
  return value;
@@ -177,9 +179,7 @@ function mapDriverValue(
177
179
  if (normalized instanceof Date) {
178
180
  return normalized;
179
181
  }
180
- return decoder.mapFromDriverValue(
181
- toDecoderInput(decoder, normalized)
182
- );
182
+ return decoder.mapFromDriverValue(toDecoderInput(decoder, normalized));
183
183
  }
184
184
 
185
185
  if (is(decoder, PgDateString)) {
@@ -1,10 +1,4 @@
1
- import {
2
- Column,
3
- SQL,
4
- getTableName,
5
- is,
6
- sql,
7
- } from 'drizzle-orm';
1
+ import { Column, SQL, getTableName, is, sql } from 'drizzle-orm';
8
2
  import type { SelectedFields } from 'drizzle-orm/pg-core';
9
3
 
10
4
  function mapEntries(
@@ -38,8 +32,7 @@ function mapEntries(
38
32
  }
39
33
 
40
34
  if (is(value, SQL) || is(value, Column)) {
41
- const aliased =
42
- is(value, SQL) ? value : sql`${value}`.mapWith(value);
35
+ const aliased = is(value, SQL) ? value : sql`${value}`.mapWith(value);
43
36
  return [key, aliased.as(qualified)];
44
37
  }
45
38