@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/dist/index.mjs CHANGED
@@ -303,8 +303,137 @@ import { TransactionRollbackError } from "drizzle-orm/errors";
303
303
 
304
304
  // src/client.ts
305
305
  import {
306
- listValue
306
+ listValue as listValue2,
307
+ timestampValue as timestampValue2
307
308
  } from "@duckdb/node-api";
309
+
310
+ // src/value-wrappers.ts
311
+ import {
312
+ listValue,
313
+ arrayValue,
314
+ structValue,
315
+ mapValue,
316
+ blobValue,
317
+ timestampValue,
318
+ timestampTZValue
319
+ } from "@duckdb/node-api";
320
+ var DUCKDB_VALUE_MARKER = Symbol.for("drizzle-duckdb:value");
321
+ function isDuckDBWrapper(value) {
322
+ return value !== null && typeof value === "object" && DUCKDB_VALUE_MARKER in value && value[DUCKDB_VALUE_MARKER] === true;
323
+ }
324
+ function wrapList(data, elementType) {
325
+ return {
326
+ [DUCKDB_VALUE_MARKER]: true,
327
+ kind: "list",
328
+ data,
329
+ elementType
330
+ };
331
+ }
332
+ function wrapArray(data, elementType, fixedLength) {
333
+ return {
334
+ [DUCKDB_VALUE_MARKER]: true,
335
+ kind: "array",
336
+ data,
337
+ elementType,
338
+ fixedLength
339
+ };
340
+ }
341
+ function wrapStruct(data, schema) {
342
+ return {
343
+ [DUCKDB_VALUE_MARKER]: true,
344
+ kind: "struct",
345
+ data,
346
+ schema
347
+ };
348
+ }
349
+ function wrapMap(data, valueType) {
350
+ return {
351
+ [DUCKDB_VALUE_MARKER]: true,
352
+ kind: "map",
353
+ data,
354
+ valueType
355
+ };
356
+ }
357
+ function wrapTimestamp(data, withTimezone, precision) {
358
+ return {
359
+ [DUCKDB_VALUE_MARKER]: true,
360
+ kind: "timestamp",
361
+ data,
362
+ withTimezone,
363
+ precision
364
+ };
365
+ }
366
+ function wrapBlob(data) {
367
+ return {
368
+ [DUCKDB_VALUE_MARKER]: true,
369
+ kind: "blob",
370
+ data
371
+ };
372
+ }
373
+ function wrapJson(data) {
374
+ return {
375
+ [DUCKDB_VALUE_MARKER]: true,
376
+ kind: "json",
377
+ data
378
+ };
379
+ }
380
+ function dateToMicros(value) {
381
+ if (value instanceof Date) {
382
+ return BigInt(value.getTime()) * 1000n;
383
+ }
384
+ let normalized = value;
385
+ if (!value.includes("T") && value.includes(" ")) {
386
+ normalized = value.replace(" ", "T");
387
+ }
388
+ if (!normalized.endsWith("Z") && !/[+-]\d{2}:?\d{2}$/.test(normalized)) {
389
+ normalized += "Z";
390
+ }
391
+ const date = new Date(normalized);
392
+ if (isNaN(date.getTime())) {
393
+ throw new Error(`Invalid timestamp string: ${value}`);
394
+ }
395
+ return BigInt(date.getTime()) * 1000n;
396
+ }
397
+ function toUint8Array(data) {
398
+ return data instanceof Uint8Array && !(data instanceof Buffer) ? data : new Uint8Array(data);
399
+ }
400
+ function convertStructEntries(data, toValue) {
401
+ const entries = {};
402
+ for (const [key, val] of Object.entries(data)) {
403
+ entries[key] = toValue(val);
404
+ }
405
+ return entries;
406
+ }
407
+ function convertMapEntries(data, toValue) {
408
+ return Object.entries(data).map(([key, val]) => ({
409
+ key,
410
+ value: toValue(val)
411
+ }));
412
+ }
413
+ function wrapperToNodeApiValue(wrapper, toValue) {
414
+ switch (wrapper.kind) {
415
+ case "list":
416
+ return listValue(wrapper.data.map(toValue));
417
+ case "array":
418
+ return arrayValue(wrapper.data.map(toValue));
419
+ case "struct":
420
+ return structValue(convertStructEntries(wrapper.data, toValue));
421
+ case "map":
422
+ return mapValue(convertMapEntries(wrapper.data, toValue));
423
+ case "timestamp":
424
+ return wrapper.withTimezone ? timestampTZValue(dateToMicros(wrapper.data)) : timestampValue(dateToMicros(wrapper.data));
425
+ case "blob":
426
+ return blobValue(toUint8Array(wrapper.data));
427
+ case "json":
428
+ return JSON.stringify(wrapper.data);
429
+ default: {
430
+ const _exhaustive = wrapper;
431
+ throw new Error(`Unknown wrapper kind: ${_exhaustive.kind}`);
432
+ }
433
+ }
434
+ }
435
+
436
+ // src/client.ts
308
437
  function isPgArrayLiteral(value) {
309
438
  return value.startsWith("{") && value.endsWith("}");
310
439
  }
@@ -333,30 +462,91 @@ function prepareParams(params, options = {}) {
333
462
  });
334
463
  }
335
464
  function toNodeApiValue(value) {
465
+ if (value == null)
466
+ return null;
467
+ const t = typeof value;
468
+ if (t === "string" || t === "number" || t === "bigint" || t === "boolean") {
469
+ return value;
470
+ }
471
+ if (t === "object" && DUCKDB_VALUE_MARKER in value) {
472
+ return wrapperToNodeApiValue(value, toNodeApiValue);
473
+ }
336
474
  if (Array.isArray(value)) {
337
- return listValue(value.map((inner) => toNodeApiValue(inner)));
475
+ return listValue2(value.map((inner) => toNodeApiValue(inner)));
476
+ }
477
+ if (value instanceof Date) {
478
+ return timestampValue2(BigInt(value.getTime()) * 1000n);
338
479
  }
339
480
  return value;
340
481
  }
341
- async function executeOnClient(client, query, params) {
342
- const values = params.length > 0 ? params.map((param) => toNodeApiValue(param)) : undefined;
343
- const result = await client.run(query, values);
344
- const rows = await result.getRowsJS();
345
- const columns = result.columnNames();
482
+ function deduplicateColumns(columns) {
346
483
  const seen = {};
347
- const uniqueColumns = columns.map((col) => {
484
+ return columns.map((col) => {
348
485
  const count = seen[col] ?? 0;
349
486
  seen[col] = count + 1;
350
487
  return count === 0 ? col : `${col}_${count}`;
351
488
  });
352
- return (rows ?? []).map((vals) => {
489
+ }
490
+ function mapRowsToObjects(columns, rows) {
491
+ return rows.map((vals) => {
353
492
  const obj = {};
354
- uniqueColumns.forEach((col, idx) => {
493
+ columns.forEach((col, idx) => {
355
494
  obj[col] = vals[idx];
356
495
  });
357
496
  return obj;
358
497
  });
359
498
  }
499
+ async function closeClientConnection(connection) {
500
+ if ("close" in connection && typeof connection.close === "function") {
501
+ await connection.close();
502
+ return;
503
+ }
504
+ if ("closeSync" in connection && typeof connection.closeSync === "function") {
505
+ connection.closeSync();
506
+ return;
507
+ }
508
+ if ("disconnectSync" in connection && typeof connection.disconnectSync === "function") {
509
+ connection.disconnectSync();
510
+ }
511
+ }
512
+ async function executeOnClient(client, query, params) {
513
+ const values = params.length > 0 ? params.map((param) => toNodeApiValue(param)) : undefined;
514
+ const result = await client.run(query, values);
515
+ const rows = await result.getRowsJS();
516
+ const columns = result.deduplicatedColumnNames?.() ?? result.columnNames();
517
+ const uniqueColumns = deduplicateColumns(columns);
518
+ return rows ? mapRowsToObjects(uniqueColumns, rows) : [];
519
+ }
520
+ async function* executeInBatches(client, query, params, options = {}) {
521
+ const rowsPerChunk = options.rowsPerChunk && options.rowsPerChunk > 0 ? options.rowsPerChunk : 1e5;
522
+ const values = params.length > 0 ? params.map((param) => toNodeApiValue(param)) : undefined;
523
+ const result = await client.stream(query, values);
524
+ const columns = result.deduplicatedColumnNames?.() ?? result.columnNames();
525
+ const uniqueColumns = deduplicateColumns(columns);
526
+ let buffer = [];
527
+ for await (const chunk of result.yieldRowsJs()) {
528
+ const objects = mapRowsToObjects(uniqueColumns, chunk);
529
+ for (const row of objects) {
530
+ buffer.push(row);
531
+ if (buffer.length >= rowsPerChunk) {
532
+ yield buffer;
533
+ buffer = [];
534
+ }
535
+ }
536
+ }
537
+ if (buffer.length > 0) {
538
+ yield buffer;
539
+ }
540
+ }
541
+ async function executeArrowOnClient(client, query, params) {
542
+ const values = params.length > 0 ? params.map((param) => toNodeApiValue(param)) : undefined;
543
+ const result = await client.run(query, values);
544
+ const maybeArrow = result.toArrow ?? result.getArrowTable;
545
+ if (typeof maybeArrow === "function") {
546
+ return await maybeArrow.call(result);
547
+ }
548
+ return result.getColumnsObjectJS();
549
+ }
360
550
 
361
551
  // src/session.ts
362
552
  class DuckDBPreparedQuery extends PgPreparedQuery {
@@ -397,11 +587,7 @@ class DuckDBPreparedQuery extends PgPreparedQuery {
397
587
  this.logger.logQuery(`[duckdb] original query before array rewrite: ${this.queryString}`, params);
398
588
  }
399
589
  this.logger.logQuery(rewrittenQuery, params);
400
- const {
401
- fields,
402
- joinsNotNullableMap,
403
- customResultMapper
404
- } = this;
590
+ const { fields, joinsNotNullableMap, customResultMapper } = this;
405
591
  const rows = await executeOnClient(this.client, rewrittenQuery, params);
406
592
  if (rows.length === 0 || !fields) {
407
593
  return rows;
@@ -461,6 +647,32 @@ class DuckDBSession extends PgSession {
461
647
  this.logger.logQuery(`[duckdb] ${arrayLiteralWarning}
462
648
  query: ${query}`, []);
463
649
  };
650
+ executeBatches(query, options = {}) {
651
+ const builtQuery = this.dialect.sqlToQuery(query);
652
+ const params = prepareParams(builtQuery.params, {
653
+ rejectStringArrayLiterals: this.rejectStringArrayLiterals,
654
+ warnOnStringArrayLiteral: this.rejectStringArrayLiterals ? undefined : () => this.warnOnStringArrayLiteral(builtQuery.sql)
655
+ });
656
+ const rewrittenQuery = this.rewriteArrays ? adaptArrayOperators(builtQuery.sql) : builtQuery.sql;
657
+ if (this.rewriteArrays && rewrittenQuery !== builtQuery.sql) {
658
+ this.logger.logQuery(`[duckdb] original query before array rewrite: ${builtQuery.sql}`, params);
659
+ }
660
+ this.logger.logQuery(rewrittenQuery, params);
661
+ return executeInBatches(this.client, rewrittenQuery, params, options);
662
+ }
663
+ async executeArrow(query) {
664
+ const builtQuery = this.dialect.sqlToQuery(query);
665
+ const params = prepareParams(builtQuery.params, {
666
+ rejectStringArrayLiterals: this.rejectStringArrayLiterals,
667
+ warnOnStringArrayLiteral: this.rejectStringArrayLiterals ? undefined : () => this.warnOnStringArrayLiteral(builtQuery.sql)
668
+ });
669
+ const rewrittenQuery = this.rewriteArrays ? adaptArrayOperators(builtQuery.sql) : builtQuery.sql;
670
+ if (this.rewriteArrays && rewrittenQuery !== builtQuery.sql) {
671
+ this.logger.logQuery(`[duckdb] original query before array rewrite: ${builtQuery.sql}`, params);
672
+ }
673
+ this.logger.logQuery(rewrittenQuery, params);
674
+ return executeArrowOnClient(this.client, rewrittenQuery, params);
675
+ }
464
676
  }
465
677
 
466
678
  class DuckDBTransaction extends PgTransaction {
@@ -484,6 +696,12 @@ class DuckDBTransaction extends PgTransaction {
484
696
  setTransaction(config) {
485
697
  return this.session.execute(sql`set transaction ${this.getTransactionConfigSQL(config)}`);
486
698
  }
699
+ executeBatches(query, options = {}) {
700
+ return this.session.executeBatches(query, options);
701
+ }
702
+ executeArrow(query) {
703
+ return this.session.executeArrow(query);
704
+ }
487
705
  async transaction(transaction) {
488
706
  const nestedTx = new DuckDBTransaction(this.dialect, this.session, this.schema, this.nestedIndex + 1);
489
707
  return transaction(nestedTx);
@@ -582,13 +800,7 @@ import { PgViewBase } from "drizzle-orm/pg-core/view-base";
582
800
  import { SQL as SQL4 } from "drizzle-orm/sql/sql";
583
801
 
584
802
  // src/sql/selection.ts
585
- import {
586
- Column as Column2,
587
- SQL as SQL3,
588
- getTableName as getTableName2,
589
- is as is3,
590
- sql as sql3
591
- } from "drizzle-orm";
803
+ import { Column as Column2, SQL as SQL3, getTableName as getTableName2, is as is3, sql as sql3 } from "drizzle-orm";
592
804
  function mapEntries(obj, prefix, fullJoin = false) {
593
805
  return Object.fromEntries(Object.entries(obj).filter(([key]) => key !== "enableRLS").map(([key, value]) => {
594
806
  const qualified = prefix ? `${prefix}.${key}` : key;
@@ -729,6 +941,12 @@ class DuckDBDatabase extends PgDatabase {
729
941
  dialect: this.dialect
730
942
  });
731
943
  }
944
+ executeBatches(query, options = {}) {
945
+ return this.session.executeBatches(query, options);
946
+ }
947
+ executeArrow(query) {
948
+ return this.session.executeArrow(query);
949
+ }
732
950
  async transaction(transaction) {
733
951
  return await this.session.transaction(transaction);
734
952
  }
@@ -797,19 +1015,12 @@ function buildStructLiteral(value, schema) {
797
1015
  });
798
1016
  return sql4`struct_pack(${sql4.join(parts, sql4.raw(", "))})`;
799
1017
  }
800
- function buildMapLiteral(value, valueType) {
801
- const keys = Object.keys(value);
802
- const vals = Object.values(value);
803
- const keyList = buildListLiteral(keys, "TEXT");
804
- const valList = buildListLiteral(vals, valueType?.endsWith("[]") ? valueType.slice(0, -2) : valueType);
805
- return sql4`map(${keyList}, ${valList})`;
806
- }
807
1018
  var duckDbList = (name, elementType) => customType({
808
1019
  dataType() {
809
1020
  return `${elementType}[]`;
810
1021
  },
811
1022
  toDriver(value) {
812
- return buildListLiteral(value, elementType);
1023
+ return wrapList(value, elementType);
813
1024
  },
814
1025
  fromDriver(value) {
815
1026
  if (Array.isArray(value)) {
@@ -829,7 +1040,7 @@ var duckDbArray = (name, elementType, fixedLength) => customType({
829
1040
  return fixedLength ? `${elementType}[${fixedLength}]` : `${elementType}[]`;
830
1041
  },
831
1042
  toDriver(value) {
832
- return buildListLiteral(value, elementType);
1043
+ return wrapArray(value, elementType, fixedLength);
833
1044
  },
834
1045
  fromDriver(value) {
835
1046
  if (Array.isArray(value)) {
@@ -849,7 +1060,7 @@ var duckDbMap = (name, valueType) => customType({
849
1060
  return `MAP (STRING, ${valueType})`;
850
1061
  },
851
1062
  toDriver(value) {
852
- return buildMapLiteral(value, valueType);
1063
+ return wrapMap(value, valueType);
853
1064
  },
854
1065
  fromDriver(value) {
855
1066
  return value;
@@ -885,7 +1096,7 @@ var duckDbJson = (name) => customType({
885
1096
  if (value !== null && typeof value === "object" && "queryChunks" in value) {
886
1097
  return value;
887
1098
  }
888
- return JSON.stringify(value ?? null);
1099
+ return wrapJson(value);
889
1100
  },
890
1101
  fromDriver(value) {
891
1102
  if (typeof value !== "string") {
@@ -907,8 +1118,7 @@ var duckDbBlob = customType({
907
1118
  return "BLOB";
908
1119
  },
909
1120
  toDriver(value) {
910
- const hexString = value.toString("hex");
911
- return sql4`from_hex(${hexString})`;
1121
+ return wrapBlob(value);
912
1122
  }
913
1123
  });
914
1124
  var duckDbInet = (name) => customType({
@@ -1311,7 +1521,9 @@ function mapDuckDbType(column, imports, options) {
1311
1521
  }
1312
1522
  if (upper === "BIGINT" || upper === "INT8" || upper === "UBIGINT") {
1313
1523
  imports.pgCore.add("bigint");
1314
- return { builder: `bigint(${columnName(column.name)})` };
1524
+ return {
1525
+ builder: `bigint(${columnName(column.name)}, { mode: 'number' })`
1526
+ };
1315
1527
  }
1316
1528
  const decimalMatch = /^DECIMAL\((\d+),(\d+)\)/i.exec(upper);
1317
1529
  const numericMatch = /^NUMERIC\((\d+),(\d+)\)/i.exec(upper);
@@ -1558,9 +1770,140 @@ function renderImports(imports, importBasePath) {
1558
1770
  return lines.join(`
1559
1771
  `);
1560
1772
  }
1773
+ // src/olap.ts
1774
+ import { is as is5 } from "drizzle-orm/entity";
1775
+ import { sql as sql6 } from "drizzle-orm";
1776
+ import { SQL as SQL5 } from "drizzle-orm/sql/sql";
1777
+ import { Column as Column3, getTableName as getTableName3 } from "drizzle-orm";
1778
+ var countN = (expr = sql6`*`) => sql6`count(${expr})`.mapWith(Number);
1779
+ var sumN = (expr) => sql6`sum(${expr})`.mapWith(Number);
1780
+ var avgN = (expr) => sql6`avg(${expr})`.mapWith(Number);
1781
+ var sumDistinctN = (expr) => sql6`sum(distinct ${expr})`.mapWith(Number);
1782
+ var percentileCont = (p, expr) => sql6`percentile_cont(${p}) within group (order by ${expr})`.mapWith(Number);
1783
+ var median = (expr) => percentileCont(0.5, expr);
1784
+ var anyValue = (expr) => sql6`any_value(${expr})`;
1785
+ function normalizeArray(value) {
1786
+ if (!value)
1787
+ return [];
1788
+ return Array.isArray(value) ? value : [value];
1789
+ }
1790
+ function overClause(options) {
1791
+ const partitions = normalizeArray(options?.partitionBy);
1792
+ const orders = normalizeArray(options?.orderBy);
1793
+ const chunks = [];
1794
+ if (partitions.length > 0) {
1795
+ chunks.push(sql6`partition by ${sql6.join(partitions, sql6`, `)}`);
1796
+ }
1797
+ if (orders.length > 0) {
1798
+ chunks.push(sql6`order by ${sql6.join(orders, sql6`, `)}`);
1799
+ }
1800
+ if (chunks.length === 0) {
1801
+ return sql6``;
1802
+ }
1803
+ return sql6`over (${sql6.join(chunks, sql6` `)})`;
1804
+ }
1805
+ var rowNumber = (options) => sql6`row_number() ${overClause(options)}`.mapWith(Number);
1806
+ var rank = (options) => sql6`rank() ${overClause(options)}`.mapWith(Number);
1807
+ var denseRank = (options) => sql6`dense_rank() ${overClause(options)}`.mapWith(Number);
1808
+ var lag = (expr, offset = 1, defaultValue, options) => defaultValue ? sql6`lag(${expr}, ${offset}, ${defaultValue}) ${overClause(options)}` : sql6`lag(${expr}, ${offset}) ${overClause(options)}`;
1809
+ var lead = (expr, offset = 1, defaultValue, options) => defaultValue ? sql6`lead(${expr}, ${offset}, ${defaultValue}) ${overClause(options)}` : sql6`lead(${expr}, ${offset}) ${overClause(options)}`;
1810
+ function keyAlias(key, fallback) {
1811
+ if (is5(key, SQL5.Aliased)) {
1812
+ return key.fieldAlias ?? fallback;
1813
+ }
1814
+ if (is5(key, Column3)) {
1815
+ return `${getTableName3(key.table)}.${key.name}`;
1816
+ }
1817
+ return fallback;
1818
+ }
1819
+
1820
+ class OlapBuilder {
1821
+ db;
1822
+ source;
1823
+ keys = [];
1824
+ measureMap = {};
1825
+ nonAggregates = {};
1826
+ wrapNonAggWithAnyValue = false;
1827
+ orderByClauses = [];
1828
+ constructor(db) {
1829
+ this.db = db;
1830
+ }
1831
+ from(source) {
1832
+ this.source = source;
1833
+ return this;
1834
+ }
1835
+ groupBy(keys) {
1836
+ this.keys = keys;
1837
+ return this;
1838
+ }
1839
+ measures(measures) {
1840
+ this.measureMap = measures;
1841
+ return this;
1842
+ }
1843
+ selectNonAggregates(fields, options = {}) {
1844
+ this.nonAggregates = fields;
1845
+ this.wrapNonAggWithAnyValue = options.anyValue ?? false;
1846
+ return this;
1847
+ }
1848
+ orderBy(...clauses) {
1849
+ this.orderByClauses = clauses;
1850
+ return this;
1851
+ }
1852
+ build() {
1853
+ if (!this.source) {
1854
+ throw new Error("olap: .from() is required");
1855
+ }
1856
+ if (this.keys.length === 0) {
1857
+ throw new Error("olap: .groupBy() is required");
1858
+ }
1859
+ if (Object.keys(this.measureMap).length === 0) {
1860
+ throw new Error("olap: .measures() is required");
1861
+ }
1862
+ const selection = {};
1863
+ this.keys.forEach((key, idx) => {
1864
+ const alias = keyAlias(key, `key_${idx}`);
1865
+ selection[alias] = key;
1866
+ });
1867
+ Object.entries(this.nonAggregates).forEach(([alias, expr]) => {
1868
+ selection[alias] = this.wrapNonAggWithAnyValue ? anyValue(expr) : expr;
1869
+ });
1870
+ Object.assign(selection, this.measureMap);
1871
+ let query = this.db.select(selection).from(this.source).groupBy(...this.keys);
1872
+ if (this.orderByClauses.length > 0) {
1873
+ query = query.orderBy(...this.orderByClauses);
1874
+ }
1875
+ return query;
1876
+ }
1877
+ run() {
1878
+ return this.build();
1879
+ }
1880
+ }
1881
+ var olap = (db) => new OlapBuilder(db);
1561
1882
  export {
1883
+ wrapperToNodeApiValue,
1884
+ wrapTimestamp,
1885
+ wrapStruct,
1886
+ wrapMap,
1887
+ wrapList,
1888
+ wrapJson,
1889
+ wrapBlob,
1890
+ wrapArray,
1891
+ sumN,
1892
+ sumDistinctN,
1893
+ rowNumber,
1894
+ rank,
1895
+ prepareParams,
1896
+ percentileCont,
1897
+ olap,
1562
1898
  migrate,
1899
+ median,
1900
+ lead,
1901
+ lag,
1902
+ isDuckDBWrapper,
1563
1903
  introspect,
1904
+ executeOnClient,
1905
+ executeInBatches,
1906
+ executeArrowOnClient,
1564
1907
  duckDbTimestamp,
1565
1908
  duckDbTime,
1566
1909
  duckDbStruct,
@@ -1576,9 +1919,16 @@ export {
1576
1919
  duckDbArrayContained,
1577
1920
  duckDbArray,
1578
1921
  drizzle,
1922
+ denseRank,
1923
+ countN,
1924
+ closeClientConnection,
1925
+ avgN,
1926
+ anyValue,
1927
+ OlapBuilder,
1579
1928
  DuckDBTransaction,
1580
1929
  DuckDBSession,
1581
1930
  DuckDBPreparedQuery,
1582
1931
  DuckDBDriver,
1583
- DuckDBDatabase
1932
+ DuckDBDatabase,
1933
+ DUCKDB_VALUE_MARKER
1584
1934
  };
package/dist/olap.d.ts ADDED
@@ -0,0 +1,46 @@
1
+ import { Subquery, type SQLWrapper } from 'drizzle-orm';
2
+ import type { AnyPgColumn, PgTable } from 'drizzle-orm/pg-core';
3
+ import type { PgViewBase } from 'drizzle-orm/pg-core/view-base';
4
+ import { SQL } from 'drizzle-orm/sql/sql';
5
+ import type { DuckDBDatabase } from './driver.ts';
6
+ export declare const countN: (expr?: SQLWrapper) => SQL<number>;
7
+ export declare const sumN: (expr: SQLWrapper) => SQL<number>;
8
+ export declare const avgN: (expr: SQLWrapper) => SQL<number>;
9
+ export declare const sumDistinctN: (expr: SQLWrapper) => SQL<number>;
10
+ export declare const percentileCont: (p: number, expr: SQLWrapper) => SQL<number>;
11
+ export declare const median: (expr: SQLWrapper) => SQL<number>;
12
+ export declare const anyValue: <T = unknown>(expr: SQLWrapper) => SQL<T>;
13
+ type PartitionOrder = {
14
+ partitionBy?: SQLWrapper | SQLWrapper[];
15
+ orderBy?: SQLWrapper | SQLWrapper[];
16
+ } | undefined;
17
+ export declare const rowNumber: (options?: PartitionOrder) => SQL<number>;
18
+ export declare const rank: (options?: PartitionOrder) => SQL<number>;
19
+ export declare const denseRank: (options?: PartitionOrder) => SQL<number>;
20
+ export declare const lag: <T = unknown>(expr: SQLWrapper, offset?: number, defaultValue?: SQLWrapper, options?: PartitionOrder) => SQL<T>;
21
+ export declare const lead: <T = unknown>(expr: SQLWrapper, offset?: number, defaultValue?: SQLWrapper, options?: PartitionOrder) => SQL<T>;
22
+ type ValueExpr = SQL | SQL.Aliased | AnyPgColumn;
23
+ type GroupKey = ValueExpr;
24
+ type MeasureMap = Record<string, ValueExpr>;
25
+ type NonAggMap = Record<string, ValueExpr>;
26
+ export declare class OlapBuilder {
27
+ private db;
28
+ private source?;
29
+ private keys;
30
+ private measureMap;
31
+ private nonAggregates;
32
+ private wrapNonAggWithAnyValue;
33
+ private orderByClauses;
34
+ constructor(db: DuckDBDatabase);
35
+ from(source: PgTable | Subquery | PgViewBase | SQL): this;
36
+ groupBy(keys: GroupKey[]): this;
37
+ measures(measures: MeasureMap): this;
38
+ selectNonAggregates(fields: NonAggMap, options?: {
39
+ anyValue?: boolean;
40
+ }): this;
41
+ orderBy(...clauses: ValueExpr[]): this;
42
+ build(): any;
43
+ run(): any;
44
+ }
45
+ export declare const olap: (db: DuckDBDatabase) => OlapBuilder;
46
+ export {};
package/dist/session.d.ts CHANGED
@@ -9,6 +9,7 @@ import { type Query, SQL } from 'drizzle-orm/sql/sql';
9
9
  import type { Assume } from 'drizzle-orm/utils';
10
10
  import type { DuckDBDialect } from './dialect.ts';
11
11
  import type { DuckDBClientLike, RowData } from './client.ts';
12
+ import { type ExecuteInBatchesOptions } from './client.ts';
12
13
  export type { DuckDBClientLike, RowData } from './client.ts';
13
14
  export declare class DuckDBPreparedQuery<T extends PreparedQueryConfig> extends PgPreparedQuery<T> {
14
15
  private client;
@@ -47,12 +48,16 @@ export declare class DuckDBSession<TFullSchema extends Record<string, unknown> =
47
48
  prepareQuery<T extends PreparedQueryConfig = PreparedQueryConfig>(query: Query, fields: SelectedFieldsOrdered | undefined, name: string | undefined, isResponseInArrayMode: boolean, customResultMapper?: (rows: unknown[][]) => T['execute']): PgPreparedQuery<T>;
48
49
  transaction<T>(transaction: (tx: DuckDBTransaction<TFullSchema, TSchema>) => Promise<T>): Promise<T>;
49
50
  private warnOnStringArrayLiteral;
51
+ executeBatches<T extends RowData = RowData>(query: SQL, options?: ExecuteInBatchesOptions): AsyncGenerator<GenericRowData<T>[], void, void>;
52
+ executeArrow(query: SQL): Promise<unknown>;
50
53
  }
51
54
  export declare class DuckDBTransaction<TFullSchema extends Record<string, unknown>, TSchema extends TablesRelationalConfig> extends PgTransaction<DuckDBQueryResultHKT, TFullSchema, TSchema> {
52
55
  static readonly [entityKind]: string;
53
56
  rollback(): never;
54
57
  getTransactionConfigSQL(config: PgTransactionConfig): SQL;
55
58
  setTransaction(config: PgTransactionConfig): Promise<void>;
59
+ executeBatches<T extends RowData = RowData>(query: SQL, options?: ExecuteInBatchesOptions): AsyncGenerator<GenericRowData<T>[], void, void>;
60
+ executeArrow(query: SQL): Promise<unknown>;
56
61
  transaction<T>(transaction: (tx: DuckDBTransaction<TFullSchema, TSchema>) => Promise<T>): Promise<T>;
57
62
  }
58
63
  export type GenericRowData<T extends RowData = RowData> = T;