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

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.
@@ -1,12 +1,13 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // src/bin/duckdb-introspect.ts
4
- import { DuckDBInstance } from "@duckdb/node-api";
4
+ import { DuckDBInstance as DuckDBInstance3 } from "@duckdb/node-api";
5
5
  import { mkdir, writeFile } from "node:fs/promises";
6
6
  import path from "node:path";
7
7
  import process from "node:process";
8
8
 
9
9
  // src/driver.ts
10
+ import { DuckDBInstance as DuckDBInstance2 } from "@duckdb/node-api";
10
11
  import { entityKind as entityKind3 } from "drizzle-orm/entity";
11
12
  import { DefaultLogger } from "drizzle-orm/logger";
12
13
  import { PgDatabase } from "drizzle-orm/pg-core/db";
@@ -23,10 +24,6 @@ import { PgPreparedQuery, PgSession } from "drizzle-orm/pg-core/session";
23
24
  import { fillPlaceholders, sql } from "drizzle-orm/sql/sql";
24
25
 
25
26
  // src/sql/query-rewriters.ts
26
- var tableIdPropSelectionRegex = new RegExp([
27
- `("(.+)"\\."(.+)")`,
28
- `(\\s+as\\s+'?(.+?)'?\\.'?(.+?)'?)?`
29
- ].join(""), "i");
30
27
  function adaptArrayOperators(query) {
31
28
  const operators = [
32
29
  { token: "@>", fn: "array_has_all" },
@@ -43,6 +40,8 @@ function adaptArrayOperators(query) {
43
40
  let inString = false;
44
41
  for (;idx >= 0; idx--) {
45
42
  const ch = source[idx];
43
+ if (ch === undefined)
44
+ break;
46
45
  if (ch === "'" && source[idx - 1] !== "\\") {
47
46
  inString = !inString;
48
47
  }
@@ -70,6 +69,8 @@ function adaptArrayOperators(query) {
70
69
  let inString = false;
71
70
  for (;idx < source.length; idx++) {
72
71
  const ch = source[idx];
72
+ if (ch === undefined)
73
+ break;
73
74
  if (ch === "'" && source[idx - 1] !== "\\") {
74
75
  inString = !inString;
75
76
  }
@@ -311,8 +312,85 @@ import { TransactionRollbackError } from "drizzle-orm/errors";
311
312
 
312
313
  // src/client.ts
313
314
  import {
314
- listValue
315
+ listValue as listValue2,
316
+ timestampValue as timestampValue2
317
+ } from "@duckdb/node-api";
318
+
319
+ // src/value-wrappers.ts
320
+ import {
321
+ listValue,
322
+ arrayValue,
323
+ structValue,
324
+ mapValue,
325
+ blobValue,
326
+ timestampValue,
327
+ timestampTZValue
315
328
  } from "@duckdb/node-api";
329
+
330
+ // src/value-wrappers-core.ts
331
+ var DUCKDB_VALUE_MARKER = Symbol.for("drizzle-duckdb:value");
332
+
333
+ // src/value-wrappers.ts
334
+ function dateToMicros(value) {
335
+ if (value instanceof Date) {
336
+ return BigInt(value.getTime()) * 1000n;
337
+ }
338
+ let normalized = value;
339
+ if (!value.includes("T") && value.includes(" ")) {
340
+ normalized = value.replace(" ", "T");
341
+ }
342
+ if (!normalized.endsWith("Z") && !/[+-]\d{2}:?\d{2}$/.test(normalized)) {
343
+ normalized += "Z";
344
+ }
345
+ const date = new Date(normalized);
346
+ if (isNaN(date.getTime())) {
347
+ throw new Error(`Invalid timestamp string: ${value}`);
348
+ }
349
+ return BigInt(date.getTime()) * 1000n;
350
+ }
351
+ function toUint8Array(data) {
352
+ return data instanceof Uint8Array && !(data instanceof Buffer) ? data : new Uint8Array(data);
353
+ }
354
+ function convertStructEntries(data, toValue) {
355
+ const entries = {};
356
+ for (const [key, val] of Object.entries(data)) {
357
+ entries[key] = toValue(val);
358
+ }
359
+ return entries;
360
+ }
361
+ function convertMapEntries(data, toValue) {
362
+ return Object.entries(data).map(([key, val]) => ({
363
+ key,
364
+ value: toValue(val)
365
+ }));
366
+ }
367
+ function wrapperToNodeApiValue(wrapper, toValue) {
368
+ switch (wrapper.kind) {
369
+ case "list":
370
+ return listValue(wrapper.data.map(toValue));
371
+ case "array":
372
+ return arrayValue(wrapper.data.map(toValue));
373
+ case "struct":
374
+ return structValue(convertStructEntries(wrapper.data, toValue));
375
+ case "map":
376
+ return mapValue(convertMapEntries(wrapper.data, toValue));
377
+ case "timestamp":
378
+ return wrapper.withTimezone ? timestampTZValue(dateToMicros(wrapper.data)) : timestampValue(dateToMicros(wrapper.data));
379
+ case "blob":
380
+ return blobValue(toUint8Array(wrapper.data));
381
+ case "json":
382
+ return JSON.stringify(wrapper.data);
383
+ default: {
384
+ const _exhaustive = wrapper;
385
+ throw new Error(`Unknown wrapper kind: ${_exhaustive.kind}`);
386
+ }
387
+ }
388
+ }
389
+
390
+ // src/client.ts
391
+ function isPool(client) {
392
+ return typeof client.acquire === "function";
393
+ }
316
394
  function isPgArrayLiteral(value) {
317
395
  return value.startsWith("{") && value.endsWith("}");
318
396
  }
@@ -324,15 +402,13 @@ function parsePgArrayLiteral(value) {
324
402
  return value;
325
403
  }
326
404
  }
327
- var warnedArrayLiteral = false;
328
405
  function prepareParams(params, options = {}) {
329
406
  return params.map((param) => {
330
407
  if (typeof param === "string" && isPgArrayLiteral(param)) {
331
408
  if (options.rejectStringArrayLiterals) {
332
409
  throw new Error("Stringified array literals are not supported. Use duckDbList()/duckDbArray() or pass native arrays.");
333
410
  }
334
- if (!warnedArrayLiteral && options.warnOnStringArrayLiteral) {
335
- warnedArrayLiteral = true;
411
+ if (options.warnOnStringArrayLiteral) {
336
412
  options.warnOnStringArrayLiteral();
337
413
  }
338
414
  return parsePgArrayLiteral(param);
@@ -341,30 +417,116 @@ function prepareParams(params, options = {}) {
341
417
  });
342
418
  }
343
419
  function toNodeApiValue(value) {
420
+ if (value == null)
421
+ return null;
422
+ const t = typeof value;
423
+ if (t === "string" || t === "number" || t === "bigint" || t === "boolean") {
424
+ return value;
425
+ }
426
+ if (t === "object" && DUCKDB_VALUE_MARKER in value) {
427
+ return wrapperToNodeApiValue(value, toNodeApiValue);
428
+ }
344
429
  if (Array.isArray(value)) {
345
- return listValue(value.map((inner) => toNodeApiValue(inner)));
430
+ return listValue2(value.map((inner) => toNodeApiValue(inner)));
431
+ }
432
+ if (value instanceof Date) {
433
+ return timestampValue2(BigInt(value.getTime()) * 1000n);
346
434
  }
347
435
  return value;
348
436
  }
349
- async function executeOnClient(client, query, params) {
350
- const values = params.length > 0 ? params.map((param) => toNodeApiValue(param)) : undefined;
351
- const result = await client.run(query, values);
352
- const rows = await result.getRowsJS();
353
- const columns = result.columnNames();
437
+ function deduplicateColumns(columns) {
354
438
  const seen = {};
355
- const uniqueColumns = columns.map((col) => {
439
+ return columns.map((col) => {
356
440
  const count = seen[col] ?? 0;
357
441
  seen[col] = count + 1;
358
442
  return count === 0 ? col : `${col}_${count}`;
359
443
  });
360
- return (rows ?? []).map((vals) => {
444
+ }
445
+ function mapRowsToObjects(columns, rows) {
446
+ return rows.map((vals) => {
361
447
  const obj = {};
362
- uniqueColumns.forEach((col, idx) => {
448
+ columns.forEach((col, idx) => {
363
449
  obj[col] = vals[idx];
364
450
  });
365
451
  return obj;
366
452
  });
367
453
  }
454
+ async function closeClientConnection(connection) {
455
+ if ("close" in connection && typeof connection.close === "function") {
456
+ await connection.close();
457
+ return;
458
+ }
459
+ if ("closeSync" in connection && typeof connection.closeSync === "function") {
460
+ connection.closeSync();
461
+ return;
462
+ }
463
+ if ("disconnectSync" in connection && typeof connection.disconnectSync === "function") {
464
+ connection.disconnectSync();
465
+ }
466
+ }
467
+ async function executeOnClient(client, query, params) {
468
+ if (isPool(client)) {
469
+ const connection = await client.acquire();
470
+ try {
471
+ return await executeOnClient(connection, query, params);
472
+ } finally {
473
+ await client.release(connection);
474
+ }
475
+ }
476
+ const values = params.length > 0 ? params.map((param) => toNodeApiValue(param)) : undefined;
477
+ const result = await client.run(query, values);
478
+ const rows = await result.getRowsJS();
479
+ const columns = result.deduplicatedColumnNames?.() ?? result.columnNames();
480
+ const uniqueColumns = deduplicateColumns(columns);
481
+ return rows ? mapRowsToObjects(uniqueColumns, rows) : [];
482
+ }
483
+ async function* executeInBatches(client, query, params, options = {}) {
484
+ if (isPool(client)) {
485
+ const connection = await client.acquire();
486
+ try {
487
+ yield* executeInBatches(connection, query, params, options);
488
+ return;
489
+ } finally {
490
+ await client.release(connection);
491
+ }
492
+ }
493
+ const rowsPerChunk = options.rowsPerChunk && options.rowsPerChunk > 0 ? options.rowsPerChunk : 1e5;
494
+ const values = params.length > 0 ? params.map((param) => toNodeApiValue(param)) : undefined;
495
+ const result = await client.stream(query, values);
496
+ const columns = result.deduplicatedColumnNames?.() ?? result.columnNames();
497
+ const uniqueColumns = deduplicateColumns(columns);
498
+ let buffer = [];
499
+ for await (const chunk of result.yieldRowsJs()) {
500
+ const objects = mapRowsToObjects(uniqueColumns, chunk);
501
+ for (const row of objects) {
502
+ buffer.push(row);
503
+ if (buffer.length >= rowsPerChunk) {
504
+ yield buffer;
505
+ buffer = [];
506
+ }
507
+ }
508
+ }
509
+ if (buffer.length > 0) {
510
+ yield buffer;
511
+ }
512
+ }
513
+ async function executeArrowOnClient(client, query, params) {
514
+ if (isPool(client)) {
515
+ const connection = await client.acquire();
516
+ try {
517
+ return await executeArrowOnClient(connection, query, params);
518
+ } finally {
519
+ await client.release(connection);
520
+ }
521
+ }
522
+ const values = params.length > 0 ? params.map((param) => toNodeApiValue(param)) : undefined;
523
+ const result = await client.run(query, values);
524
+ const maybeArrow = result.toArrow ?? result.getArrowTable;
525
+ if (typeof maybeArrow === "function") {
526
+ return await maybeArrow.call(result);
527
+ }
528
+ return result.getColumnsObjectJS();
529
+ }
368
530
 
369
531
  // src/session.ts
370
532
  class DuckDBPreparedQuery extends PgPreparedQuery {
@@ -405,11 +567,7 @@ class DuckDBPreparedQuery extends PgPreparedQuery {
405
567
  this.logger.logQuery(`[duckdb] original query before array rewrite: ${this.queryString}`, params);
406
568
  }
407
569
  this.logger.logQuery(rewrittenQuery, params);
408
- const {
409
- fields,
410
- joinsNotNullableMap,
411
- customResultMapper
412
- } = this;
570
+ const { fields, joinsNotNullableMap, customResultMapper } = this;
413
571
  const rows = await executeOnClient(this.client, rewrittenQuery, params);
414
572
  if (rows.length === 0 || !fields) {
415
573
  return rows;
@@ -449,16 +607,30 @@ class DuckDBSession extends PgSession {
449
607
  return new DuckDBPreparedQuery(this.client, this.dialect, query.sql, query.params, this.logger, fields, isResponseInArrayMode, customResultMapper, this.rewriteArrays, this.rejectStringArrayLiterals, this.rejectStringArrayLiterals ? undefined : this.warnOnStringArrayLiteral);
450
608
  }
451
609
  async transaction(transaction) {
452
- const session = new DuckDBSession(this.client, this.dialect, this.schema, this.options);
610
+ let pinnedConnection;
611
+ let pool;
612
+ let clientForTx = this.client;
613
+ if (isPool(this.client)) {
614
+ pool = this.client;
615
+ pinnedConnection = await pool.acquire();
616
+ clientForTx = pinnedConnection;
617
+ }
618
+ const session = new DuckDBSession(clientForTx, this.dialect, this.schema, this.options);
453
619
  const tx = new DuckDBTransaction(this.dialect, session, this.schema);
454
- await tx.execute(sql`BEGIN TRANSACTION;`);
455
620
  try {
456
- const result = await transaction(tx);
457
- await tx.execute(sql`commit`);
458
- return result;
459
- } catch (error) {
460
- await tx.execute(sql`rollback`);
461
- throw error;
621
+ await tx.execute(sql`BEGIN TRANSACTION;`);
622
+ try {
623
+ const result = await transaction(tx);
624
+ await tx.execute(sql`commit`);
625
+ return result;
626
+ } catch (error) {
627
+ await tx.execute(sql`rollback`);
628
+ throw error;
629
+ }
630
+ } finally {
631
+ if (pinnedConnection && pool) {
632
+ await pool.release(pinnedConnection);
633
+ }
462
634
  }
463
635
  }
464
636
  warnOnStringArrayLiteral = (query) => {
@@ -469,6 +641,32 @@ class DuckDBSession extends PgSession {
469
641
  this.logger.logQuery(`[duckdb] ${arrayLiteralWarning}
470
642
  query: ${query}`, []);
471
643
  };
644
+ executeBatches(query, options = {}) {
645
+ const builtQuery = this.dialect.sqlToQuery(query);
646
+ const params = prepareParams(builtQuery.params, {
647
+ rejectStringArrayLiterals: this.rejectStringArrayLiterals,
648
+ warnOnStringArrayLiteral: this.rejectStringArrayLiterals ? undefined : () => this.warnOnStringArrayLiteral(builtQuery.sql)
649
+ });
650
+ const rewrittenQuery = this.rewriteArrays ? adaptArrayOperators(builtQuery.sql) : builtQuery.sql;
651
+ if (this.rewriteArrays && rewrittenQuery !== builtQuery.sql) {
652
+ this.logger.logQuery(`[duckdb] original query before array rewrite: ${builtQuery.sql}`, params);
653
+ }
654
+ this.logger.logQuery(rewrittenQuery, params);
655
+ return executeInBatches(this.client, rewrittenQuery, params, options);
656
+ }
657
+ async executeArrow(query) {
658
+ const builtQuery = this.dialect.sqlToQuery(query);
659
+ const params = prepareParams(builtQuery.params, {
660
+ rejectStringArrayLiterals: this.rejectStringArrayLiterals,
661
+ warnOnStringArrayLiteral: this.rejectStringArrayLiterals ? undefined : () => this.warnOnStringArrayLiteral(builtQuery.sql)
662
+ });
663
+ const rewrittenQuery = this.rewriteArrays ? adaptArrayOperators(builtQuery.sql) : builtQuery.sql;
664
+ if (this.rewriteArrays && rewrittenQuery !== builtQuery.sql) {
665
+ this.logger.logQuery(`[duckdb] original query before array rewrite: ${builtQuery.sql}`, params);
666
+ }
667
+ this.logger.logQuery(rewrittenQuery, params);
668
+ return executeArrowOnClient(this.client, rewrittenQuery, params);
669
+ }
472
670
  }
473
671
 
474
672
  class DuckDBTransaction extends PgTransaction {
@@ -492,6 +690,12 @@ class DuckDBTransaction extends PgTransaction {
492
690
  setTransaction(config) {
493
691
  return this.session.execute(sql`set transaction ${this.getTransactionConfigSQL(config)}`);
494
692
  }
693
+ executeBatches(query, options = {}) {
694
+ return this.session.executeBatches(query, options);
695
+ }
696
+ executeArrow(query) {
697
+ return this.session.executeArrow(query);
698
+ }
495
699
  async transaction(transaction) {
496
700
  const nestedTx = new DuckDBTransaction(this.dialect, this.session, this.schema, this.nestedIndex + 1);
497
701
  return transaction(nestedTx);
@@ -590,13 +794,7 @@ import { PgViewBase } from "drizzle-orm/pg-core/view-base";
590
794
  import { SQL as SQL4 } from "drizzle-orm/sql/sql";
591
795
 
592
796
  // src/sql/selection.ts
593
- import {
594
- Column as Column2,
595
- SQL as SQL3,
596
- getTableName as getTableName2,
597
- is as is3,
598
- sql as sql3
599
- } from "drizzle-orm";
797
+ import { Column as Column2, SQL as SQL3, getTableName as getTableName2, is as is3, sql as sql3 } from "drizzle-orm";
600
798
  function mapEntries(obj, prefix, fullJoin = false) {
601
799
  return Object.fromEntries(Object.entries(obj).filter(([key]) => key !== "enableRLS").map(([key, value]) => {
602
800
  const qualified = prefix ? `${prefix}.${key}` : key;
@@ -680,6 +878,72 @@ class DuckDBSelectBuilder extends PgSelectBuilder {
680
878
  }
681
879
  }
682
880
 
881
+ // src/pool.ts
882
+ import { DuckDBConnection } from "@duckdb/node-api";
883
+ var POOL_PRESETS = {
884
+ pulse: 4,
885
+ standard: 6,
886
+ jumbo: 8,
887
+ mega: 12,
888
+ giga: 16,
889
+ local: 8,
890
+ memory: 4
891
+ };
892
+ function resolvePoolSize(pool) {
893
+ if (pool === false)
894
+ return false;
895
+ if (pool === undefined)
896
+ return 4;
897
+ if (typeof pool === "string")
898
+ return POOL_PRESETS[pool];
899
+ return pool.size ?? 4;
900
+ }
901
+ function createDuckDBConnectionPool(instance, options = {}) {
902
+ const size = options.size && options.size > 0 ? options.size : 4;
903
+ const idle = [];
904
+ const waiting = [];
905
+ let total = 0;
906
+ let closed = false;
907
+ const acquire = async () => {
908
+ if (closed) {
909
+ throw new Error("DuckDB connection pool is closed");
910
+ }
911
+ if (idle.length > 0) {
912
+ return idle.pop();
913
+ }
914
+ if (total < size) {
915
+ total += 1;
916
+ return await DuckDBConnection.create(instance);
917
+ }
918
+ return await new Promise((resolve) => {
919
+ waiting.push(resolve);
920
+ });
921
+ };
922
+ const release = async (connection) => {
923
+ if (closed) {
924
+ await closeClientConnection(connection);
925
+ return;
926
+ }
927
+ const waiter = waiting.shift();
928
+ if (waiter) {
929
+ waiter(connection);
930
+ return;
931
+ }
932
+ idle.push(connection);
933
+ };
934
+ const close = async () => {
935
+ closed = true;
936
+ const toClose = idle.splice(0, idle.length);
937
+ await Promise.all(toClose.map((conn) => closeClientConnection(conn)));
938
+ };
939
+ return {
940
+ acquire,
941
+ release,
942
+ close,
943
+ size
944
+ };
945
+ }
946
+
683
947
  // src/driver.ts
684
948
  class DuckDBDriver {
685
949
  client;
@@ -699,7 +963,14 @@ class DuckDBDriver {
699
963
  });
700
964
  }
701
965
  }
702
- function drizzle(client, config = {}) {
966
+ function isConfigObject(data) {
967
+ if (typeof data !== "object" || data === null)
968
+ return false;
969
+ if (data.constructor?.name !== "Object")
970
+ return false;
971
+ return "connection" in data || "client" in data || "pool" in data || "schema" in data || "logger" in data;
972
+ }
973
+ function createFromClient(client, config = {}, instance) {
703
974
  const dialect = new DuckDBDialect;
704
975
  const logger = config.logger === true ? new DefaultLogger : config.logger || undefined;
705
976
  let schema;
@@ -717,17 +988,60 @@ function drizzle(client, config = {}) {
717
988
  rejectStringArrayLiterals: config.rejectStringArrayLiterals
718
989
  });
719
990
  const session = driver.createSession(schema);
720
- return new DuckDBDatabase(dialect, session, schema);
991
+ const db = new DuckDBDatabase(dialect, session, schema, client, instance);
992
+ return db;
993
+ }
994
+ async function createFromConnectionString(path, instanceOptions, config = {}) {
995
+ const instance = await DuckDBInstance2.create(path, instanceOptions);
996
+ const poolSize = resolvePoolSize(config.pool);
997
+ if (poolSize === false) {
998
+ const connection = await instance.connect();
999
+ return createFromClient(connection, config, instance);
1000
+ }
1001
+ const pool = createDuckDBConnectionPool(instance, { size: poolSize });
1002
+ return createFromClient(pool, config, instance);
1003
+ }
1004
+ function drizzle(clientOrConfigOrPath, config) {
1005
+ if (typeof clientOrConfigOrPath === "string") {
1006
+ return createFromConnectionString(clientOrConfigOrPath, undefined, config);
1007
+ }
1008
+ if (isConfigObject(clientOrConfigOrPath)) {
1009
+ const configObj = clientOrConfigOrPath;
1010
+ if ("connection" in configObj) {
1011
+ const connConfig = configObj;
1012
+ const { connection, ...restConfig } = connConfig;
1013
+ if (typeof connection === "string") {
1014
+ return createFromConnectionString(connection, undefined, restConfig);
1015
+ }
1016
+ return createFromConnectionString(connection.path, connection.options, restConfig);
1017
+ }
1018
+ if ("client" in configObj) {
1019
+ const clientConfig = configObj;
1020
+ const { client: clientValue, ...restConfig } = clientConfig;
1021
+ return createFromClient(clientValue, restConfig);
1022
+ }
1023
+ throw new Error("Invalid drizzle config: either connection or client must be provided");
1024
+ }
1025
+ return createFromClient(clientOrConfigOrPath, config);
721
1026
  }
722
1027
 
723
1028
  class DuckDBDatabase extends PgDatabase {
724
1029
  dialect;
725
1030
  session;
726
1031
  static [entityKind3] = "DuckDBDatabase";
727
- constructor(dialect, session, schema) {
1032
+ $client;
1033
+ $instance;
1034
+ constructor(dialect, session, schema, client, instance) {
728
1035
  super(dialect, session, schema);
729
1036
  this.dialect = dialect;
730
1037
  this.session = session;
1038
+ this.$client = client;
1039
+ this.$instance = instance;
1040
+ }
1041
+ async close() {
1042
+ if (isPool(this.$client) && this.$client.close) {
1043
+ await this.$client.close();
1044
+ }
731
1045
  }
732
1046
  select(fields) {
733
1047
  const selectedFields = fields ? aliasFields(fields) : undefined;
@@ -737,6 +1051,12 @@ class DuckDBDatabase extends PgDatabase {
737
1051
  dialect: this.dialect
738
1052
  });
739
1053
  }
1054
+ executeBatches(query, options = {}) {
1055
+ return this.session.executeBatches(query, options);
1056
+ }
1057
+ executeArrow(query) {
1058
+ return this.session.executeArrow(query);
1059
+ }
740
1060
  async transaction(transaction) {
741
1061
  return await this.session.transaction(transaction);
742
1062
  }
@@ -745,7 +1065,7 @@ class DuckDBDatabase extends PgDatabase {
745
1065
  // src/introspect.ts
746
1066
  import { sql as sql4 } from "drizzle-orm";
747
1067
  var SYSTEM_SCHEMAS = new Set(["information_schema", "pg_catalog"]);
748
- var DEFAULT_IMPORT_BASE = "@leonardovida-md/drizzle-neo-duckdb";
1068
+ var DEFAULT_IMPORT_BASE = "@leonardovida-md/drizzle-neo-duckdb/helpers";
749
1069
  async function introspect(db, opts = {}) {
750
1070
  const database = await resolveDatabase(db, opts.database, opts.allDatabases);
751
1071
  const schemas = await resolveSchemas(db, database, opts.schemas);
@@ -1046,7 +1366,9 @@ function mapDuckDbType(column, imports, options) {
1046
1366
  }
1047
1367
  if (upper === "BIGINT" || upper === "INT8" || upper === "UBIGINT") {
1048
1368
  imports.pgCore.add("bigint");
1049
- return { builder: `bigint(${columnName(column.name)})` };
1369
+ return {
1370
+ builder: `bigint(${columnName(column.name)}, { mode: 'number' })`
1371
+ };
1050
1372
  }
1051
1373
  const decimalMatch = /^DECIMAL\((\d+),(\d+)\)/i.exec(upper);
1052
1374
  const numericMatch = /^NUMERIC\((\d+),(\d+)\)/i.exec(upper);
@@ -1079,6 +1401,22 @@ function mapDuckDbType(column, imports, options) {
1079
1401
  imports.pgCore.add("doublePrecision");
1080
1402
  return { builder: `doublePrecision(${columnName(column.name)})` };
1081
1403
  }
1404
+ const arrayMatch = /^(.*)\[(\d+)\]$/.exec(upper);
1405
+ if (arrayMatch) {
1406
+ imports.local.add("duckDbArray");
1407
+ const [, base, length] = arrayMatch;
1408
+ return {
1409
+ builder: `duckDbArray(${columnName(column.name)}, ${JSON.stringify(base)}, ${Number(length)})`
1410
+ };
1411
+ }
1412
+ const listMatch = /^(.*)\[\]$/.exec(upper);
1413
+ if (listMatch) {
1414
+ imports.local.add("duckDbList");
1415
+ const [, base] = listMatch;
1416
+ return {
1417
+ builder: `duckDbList(${columnName(column.name)}, ${JSON.stringify(base)})`
1418
+ };
1419
+ }
1082
1420
  if (upper.startsWith("CHAR(") || upper === "CHAR") {
1083
1421
  imports.pgCore.add("char");
1084
1422
  const length = column.characterLength;
@@ -1119,22 +1457,6 @@ function mapDuckDbType(column, imports, options) {
1119
1457
  imports.local.add("duckDbBlob");
1120
1458
  return { builder: `duckDbBlob(${columnName(column.name)})` };
1121
1459
  }
1122
- const arrayMatch = /^(.*)\[(\d+)\]$/.exec(upper);
1123
- if (arrayMatch) {
1124
- imports.local.add("duckDbArray");
1125
- const [, base, length] = arrayMatch;
1126
- return {
1127
- builder: `duckDbArray(${columnName(column.name)}, ${JSON.stringify(base)}, ${Number(length)})`
1128
- };
1129
- }
1130
- const listMatch = /^(.*)\[\]$/.exec(upper);
1131
- if (listMatch) {
1132
- imports.local.add("duckDbList");
1133
- const [, base] = listMatch;
1134
- return {
1135
- builder: `duckDbList(${columnName(column.name)}, ${JSON.stringify(base)})`
1136
- };
1137
- }
1138
1460
  if (upper.startsWith("STRUCT")) {
1139
1461
  imports.local.add("duckDbStruct");
1140
1462
  const inner = upper.replace(/^STRUCT\s*\(/i, "").replace(/\)$/, "");
@@ -1383,7 +1705,7 @@ async function main() {
1383
1705
  throw new Error("Missing required --url");
1384
1706
  }
1385
1707
  const instanceOptions = options.url.startsWith("md:") && process.env.MOTHERDUCK_TOKEN ? { motherduck_token: process.env.MOTHERDUCK_TOKEN } : undefined;
1386
- const instance = await DuckDBInstance.create(options.url, instanceOptions);
1708
+ const instance = await DuckDBInstance3.create(options.url, instanceOptions);
1387
1709
  const connection = await instance.connect();
1388
1710
  const db = drizzle(connection);
1389
1711
  try {
@@ -0,0 +1 @@
1
+ export { duckDbList, duckDbArray, duckDbMap, duckDbStruct, duckDbJson, duckDbBlob, duckDbInet, duckDbInterval, duckDbTimestamp, duckDbDate, duckDbTime, duckDbArrayContains, duckDbArrayContained, duckDbArrayOverlaps, } from './columns.ts';