@avidian/duckdb-bun 0.0.0-stage → 1.0.1

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.
Files changed (231) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +286 -2
  3. package/package.json +96 -4
  4. package/src/bindings/api/appender.ts +288 -0
  5. package/src/bindings/api/data-chunk.ts +58 -0
  6. package/src/bindings/api/database.ts +232 -0
  7. package/src/bindings/api/datetime.ts +158 -0
  8. package/src/bindings/api/index.ts +13 -0
  9. package/src/bindings/api/logical-types.ts +227 -0
  10. package/src/bindings/api/query.ts +616 -0
  11. package/src/bindings/api/scalar-function.ts +274 -0
  12. package/src/bindings/api/table-function.ts +339 -0
  13. package/src/bindings/api/values.ts +546 -0
  14. package/src/bindings/api/vector.ts +266 -0
  15. package/src/bindings/generated/capi.ts +695 -0
  16. package/src/bindings/generated/contract.ts +162 -0
  17. package/src/bindings/index.ts +10 -0
  18. package/src/bindings/runtime/convert.ts +307 -0
  19. package/src/bindings/runtime/diagnostics.ts +45 -0
  20. package/src/bindings/runtime/dispatch.ts +213 -0
  21. package/src/bindings/runtime/exception.ts +103 -0
  22. package/src/bindings/runtime/flags.ts +19 -0
  23. package/src/bindings/runtime/handle.ts +217 -0
  24. package/src/bindings/runtime/kinds.ts +53 -0
  25. package/src/bindings/runtime/marshal.ts +190 -0
  26. package/src/bindings/runtime/native.ts +153 -0
  27. package/src/bindings/runtime/ring.ts +54 -0
  28. package/src/bindings/runtime/scope.ts +133 -0
  29. package/src/bindings/runtime/trace.ts +65 -0
  30. package/src/connection.ts +35 -0
  31. package/src/database.ts +27 -0
  32. package/src/errors.ts +30 -0
  33. package/src/file-assets.d.ts +10 -0
  34. package/src/index.ts +17 -0
  35. package/src/library.ts +83 -0
  36. package/src/neo.ts +16 -0
  37. package/src/reader.ts +47 -0
  38. package/src/statement.ts +61 -0
  39. package/src/types.ts +52 -0
  40. package/src/version.ts +6 -0
  41. package/vendor/node-api/LICENSE +7 -0
  42. package/vendor/node-api/PROVENANCE.md +54 -0
  43. package/vendor/node-api/node-bindings.d.ts +1669 -0
  44. package/vendor/node-api/src/DuckDBAppender.ts +237 -0
  45. package/vendor/node-api/src/DuckDBClientContext.ts +13 -0
  46. package/vendor/node-api/src/DuckDBConnection.ts +315 -0
  47. package/vendor/node-api/src/DuckDBDataChunk.ts +412 -0
  48. package/vendor/node-api/src/DuckDBDataChunkWriter.ts +144 -0
  49. package/vendor/node-api/src/DuckDBExtractedStatements.ts +37 -0
  50. package/vendor/node-api/src/DuckDBInstance.ts +35 -0
  51. package/vendor/node-api/src/DuckDBInstanceCache.ts +29 -0
  52. package/vendor/node-api/src/DuckDBLogicalType.ts +446 -0
  53. package/vendor/node-api/src/DuckDBMaterializedResult.ts +39 -0
  54. package/vendor/node-api/src/DuckDBPendingResult.ts +83 -0
  55. package/vendor/node-api/src/DuckDBPreparedStatement.ts +376 -0
  56. package/vendor/node-api/src/DuckDBPreparedStatementCollection.ts +5 -0
  57. package/vendor/node-api/src/DuckDBPreparedStatementWeakRefCollection.ts +31 -0
  58. package/vendor/node-api/src/DuckDBResult.ts +403 -0
  59. package/vendor/node-api/src/DuckDBResultReader.ts +283 -0
  60. package/vendor/node-api/src/DuckDBScalarFunction.ts +149 -0
  61. package/vendor/node-api/src/DuckDBScalarFunctionBindInfo.ts +34 -0
  62. package/vendor/node-api/src/DuckDBScalarFunctionInfo.ts +34 -0
  63. package/vendor/node-api/src/DuckDBScalarFunctionInitInfo.ts +35 -0
  64. package/vendor/node-api/src/DuckDBTableFunction.ts +149 -0
  65. package/vendor/node-api/src/DuckDBTableFunctionBindInfo.ts +56 -0
  66. package/vendor/node-api/src/DuckDBTableFunctionInfo.ts +36 -0
  67. package/vendor/node-api/src/DuckDBTableFunctionInitInfo.ts +52 -0
  68. package/vendor/node-api/src/DuckDBType.ts +1 -0
  69. package/vendor/node-api/src/DuckDBTypeId.ts +46 -0
  70. package/vendor/node-api/src/DuckDBValueConverter.ts +23 -0
  71. package/vendor/node-api/src/DuckDBValueConverters.ts +461 -0
  72. package/vendor/node-api/src/DuckDBVector.ts +1 -0
  73. package/vendor/node-api/src/JS.ts +11 -0
  74. package/vendor/node-api/src/JSDuckDBValueConverter.ts +85 -0
  75. package/vendor/node-api/src/JSInputTypeForTypeId.ts +101 -0
  76. package/vendor/node-api/src/JSToDuckDBValueConverter.ts +136 -0
  77. package/vendor/node-api/src/JSTypeForTypeId.ts +78 -0
  78. package/vendor/node-api/src/Json.ts +7 -0
  79. package/vendor/node-api/src/JsonDuckDBValueConverter.ts +72 -0
  80. package/vendor/node-api/src/JsonTypeForTypeId.ts +86 -0
  81. package/vendor/node-api/src/ToDuckDBValueConverter.ts +68 -0
  82. package/vendor/node-api/src/ToDuckDBValueConverters.ts +303 -0
  83. package/vendor/node-api/src/configurationOptionDescriptions.ts +13 -0
  84. package/vendor/node-api/src/conversion/bytesFromString.ts +5 -0
  85. package/vendor/node-api/src/conversion/dateTimeStringConversion.ts +343 -0
  86. package/vendor/node-api/src/conversion/displayStringForDuckDBValue.ts +12 -0
  87. package/vendor/node-api/src/conversion/stringFromBlob.ts +48 -0
  88. package/vendor/node-api/src/conversion/stringFromDecimal.ts +129 -0
  89. package/vendor/node-api/src/conversion/varintDecode.ts +42 -0
  90. package/vendor/node-api/src/convertColumnsFromChunks.ts +28 -0
  91. package/vendor/node-api/src/convertColumnsObjectFromChunks.ts +29 -0
  92. package/vendor/node-api/src/convertRowObjectsFromChunks.ts +21 -0
  93. package/vendor/node-api/src/convertRowsFromChunks.ts +16 -0
  94. package/vendor/node-api/src/createConfig.ts +14 -0
  95. package/vendor/node-api/src/createDuckDBValueConverter.ts +17 -0
  96. package/vendor/node-api/src/createResult.ts +15 -0
  97. package/vendor/node-api/src/createValue.ts +355 -0
  98. package/vendor/node-api/src/duckdb.ts +51 -0
  99. package/vendor/node-api/src/enums.ts +7 -0
  100. package/vendor/node-api/src/getColumnsFromChunks.ts +13 -0
  101. package/vendor/node-api/src/getColumnsObjectFromChunks.ts +16 -0
  102. package/vendor/node-api/src/getRowObjectsFromChunks.ts +13 -0
  103. package/vendor/node-api/src/getRowsFromChunks.ts +12 -0
  104. package/vendor/node-api/src/index.ts +3 -0
  105. package/vendor/node-api/src/readValue.ts +31 -0
  106. package/vendor/node-api/src/sleep.ts +5 -0
  107. package/vendor/node-api/src/sql.ts +7 -0
  108. package/vendor/node-api/src/tsconfig.json +7 -0
  109. package/vendor/node-api/src/typeForValue.ts +144 -0
  110. package/vendor/node-api/src/types/BaseDuckDBType.ts +31 -0
  111. package/vendor/node-api/src/types/DuckDBAnyType.ts +13 -0
  112. package/vendor/node-api/src/types/DuckDBArrayType.ts +43 -0
  113. package/vendor/node-api/src/types/DuckDBBigIntType.ts +21 -0
  114. package/vendor/node-api/src/types/DuckDBBigNumType.ts +21 -0
  115. package/vendor/node-api/src/types/DuckDBBitType.ts +13 -0
  116. package/vendor/node-api/src/types/DuckDBBlobType.ts +13 -0
  117. package/vendor/node-api/src/types/DuckDBBooleanType.ts +13 -0
  118. package/vendor/node-api/src/types/DuckDBDateType.ts +29 -0
  119. package/vendor/node-api/src/types/DuckDBDecimalType.ts +46 -0
  120. package/vendor/node-api/src/types/DuckDBDoubleType.ts +21 -0
  121. package/vendor/node-api/src/types/DuckDBEnumType.ts +111 -0
  122. package/vendor/node-api/src/types/DuckDBFloatType.ts +21 -0
  123. package/vendor/node-api/src/types/DuckDBGeometryType.ts +36 -0
  124. package/vendor/node-api/src/types/DuckDBHugeIntType.ts +21 -0
  125. package/vendor/node-api/src/types/DuckDBIntegerLiteralType.ts +13 -0
  126. package/vendor/node-api/src/types/DuckDBIntegerType.ts +21 -0
  127. package/vendor/node-api/src/types/DuckDBIntervalType.ts +13 -0
  128. package/vendor/node-api/src/types/DuckDBListType.ts +35 -0
  129. package/vendor/node-api/src/types/DuckDBMapType.ts +47 -0
  130. package/vendor/node-api/src/types/DuckDBSQLNullType.ts +17 -0
  131. package/vendor/node-api/src/types/DuckDBSmallIntType.ts +21 -0
  132. package/vendor/node-api/src/types/DuckDBStringLiteralType.ts +13 -0
  133. package/vendor/node-api/src/types/DuckDBStructType.ts +104 -0
  134. package/vendor/node-api/src/types/DuckDBTimeNSType.ts +20 -0
  135. package/vendor/node-api/src/types/DuckDBTimeTZType.ts +23 -0
  136. package/vendor/node-api/src/types/DuckDBTimeType.ts +20 -0
  137. package/vendor/node-api/src/types/DuckDBTimestampMillisecondsType.ts +29 -0
  138. package/vendor/node-api/src/types/DuckDBTimestampNanosecondsType.ts +29 -0
  139. package/vendor/node-api/src/types/DuckDBTimestampSecondsType.ts +29 -0
  140. package/vendor/node-api/src/types/DuckDBTimestampTZNanosecondsType.ts +32 -0
  141. package/vendor/node-api/src/types/DuckDBTimestampTZType.ts +32 -0
  142. package/vendor/node-api/src/types/DuckDBTimestampType.ts +32 -0
  143. package/vendor/node-api/src/types/DuckDBTinyIntType.ts +21 -0
  144. package/vendor/node-api/src/types/DuckDBType.ts +86 -0
  145. package/vendor/node-api/src/types/DuckDBUBigIntType.ts +21 -0
  146. package/vendor/node-api/src/types/DuckDBUHugeIntType.ts +21 -0
  147. package/vendor/node-api/src/types/DuckDBUIntegerType.ts +21 -0
  148. package/vendor/node-api/src/types/DuckDBUSmallIntType.ts +21 -0
  149. package/vendor/node-api/src/types/DuckDBUTinyIntType.ts +21 -0
  150. package/vendor/node-api/src/types/DuckDBUUIDType.ts +20 -0
  151. package/vendor/node-api/src/types/DuckDBUnionType.ts +74 -0
  152. package/vendor/node-api/src/types/DuckDBVarCharType.ts +13 -0
  153. package/vendor/node-api/src/types/DuckDBVariantType.ts +13 -0
  154. package/vendor/node-api/src/types/index.ts +44 -0
  155. package/vendor/node-api/src/values/DuckDBArrayValue.ts +18 -0
  156. package/vendor/node-api/src/values/DuckDBBitValue.ts +117 -0
  157. package/vendor/node-api/src/values/DuckDBBlobValue.ts +26 -0
  158. package/vendor/node-api/src/values/DuckDBDateValue.ts +43 -0
  159. package/vendor/node-api/src/values/DuckDBDecimalValue.ts +44 -0
  160. package/vendor/node-api/src/values/DuckDBGeometryValue.ts +30 -0
  161. package/vendor/node-api/src/values/DuckDBIntervalValue.ts +22 -0
  162. package/vendor/node-api/src/values/DuckDBListValue.ts +18 -0
  163. package/vendor/node-api/src/values/DuckDBMapValue.ts +25 -0
  164. package/vendor/node-api/src/values/DuckDBStructValue.ts +22 -0
  165. package/vendor/node-api/src/values/DuckDBTimeNSValue.ts +23 -0
  166. package/vendor/node-api/src/values/DuckDBTimeTZValue.ts +96 -0
  167. package/vendor/node-api/src/values/DuckDBTimeValue.ts +34 -0
  168. package/vendor/node-api/src/values/DuckDBTimestampMillisecondsValue.ts +29 -0
  169. package/vendor/node-api/src/values/DuckDBTimestampNanosecondsValue.ts +28 -0
  170. package/vendor/node-api/src/values/DuckDBTimestampSecondsValue.ts +28 -0
  171. package/vendor/node-api/src/values/DuckDBTimestampTZNanosecondsValue.ts +44 -0
  172. package/vendor/node-api/src/values/DuckDBTimestampTZValue.ts +54 -0
  173. package/vendor/node-api/src/values/DuckDBTimestampValue.ts +45 -0
  174. package/vendor/node-api/src/values/DuckDBTupleValue.ts +22 -0
  175. package/vendor/node-api/src/values/DuckDBUUIDValue.ts +48 -0
  176. package/vendor/node-api/src/values/DuckDBUnionValue.ts +22 -0
  177. package/vendor/node-api/src/values/DuckDBValue.ts +53 -0
  178. package/vendor/node-api/src/values/DuckDBVariantValue.ts +34 -0
  179. package/vendor/node-api/src/values/index.ts +24 -0
  180. package/vendor/node-api/src/vectors/DuckDBArrayVector.ts +107 -0
  181. package/vendor/node-api/src/vectors/DuckDBBigIntVector.ts +75 -0
  182. package/vendor/node-api/src/vectors/DuckDBBigNumVector.ts +98 -0
  183. package/vendor/node-api/src/vectors/DuckDBBitVector.ts +102 -0
  184. package/vendor/node-api/src/vectors/DuckDBBlobVector.ts +112 -0
  185. package/vendor/node-api/src/vectors/DuckDBBooleanVector.ts +84 -0
  186. package/vendor/node-api/src/vectors/DuckDBDateVector.ts +80 -0
  187. package/vendor/node-api/src/vectors/DuckDBDecimal128Vector.ts +107 -0
  188. package/vendor/node-api/src/vectors/DuckDBDecimal16Vector.ts +104 -0
  189. package/vendor/node-api/src/vectors/DuckDBDecimal32Vector.ts +104 -0
  190. package/vendor/node-api/src/vectors/DuckDBDecimal64Vector.ts +104 -0
  191. package/vendor/node-api/src/vectors/DuckDBDoubleVector.ts +68 -0
  192. package/vendor/node-api/src/vectors/DuckDBEnum16Vector.ts +75 -0
  193. package/vendor/node-api/src/vectors/DuckDBEnum32Vector.ts +75 -0
  194. package/vendor/node-api/src/vectors/DuckDBEnum8Vector.ts +75 -0
  195. package/vendor/node-api/src/vectors/DuckDBFloatVector.ts +68 -0
  196. package/vendor/node-api/src/vectors/DuckDBGeometryVector.ts +97 -0
  197. package/vendor/node-api/src/vectors/DuckDBHugeIntVector.ts +89 -0
  198. package/vendor/node-api/src/vectors/DuckDBIntegerVector.ts +75 -0
  199. package/vendor/node-api/src/vectors/DuckDBIntervalVector.ts +100 -0
  200. package/vendor/node-api/src/vectors/DuckDBListVector.ts +221 -0
  201. package/vendor/node-api/src/vectors/DuckDBMapVector.ts +88 -0
  202. package/vendor/node-api/src/vectors/DuckDBSQLNullVector.ts +53 -0
  203. package/vendor/node-api/src/vectors/DuckDBSmallIntVector.ts +75 -0
  204. package/vendor/node-api/src/vectors/DuckDBStructVector.ts +138 -0
  205. package/vendor/node-api/src/vectors/DuckDBTimeNSVector.ts +80 -0
  206. package/vendor/node-api/src/vectors/DuckDBTimeTZVector.ts +80 -0
  207. package/vendor/node-api/src/vectors/DuckDBTimeVector.ts +80 -0
  208. package/vendor/node-api/src/vectors/DuckDBTimestampMillisecondsVector.ts +88 -0
  209. package/vendor/node-api/src/vectors/DuckDBTimestampNanosecondsVector.ts +88 -0
  210. package/vendor/node-api/src/vectors/DuckDBTimestampSecondsVector.ts +88 -0
  211. package/vendor/node-api/src/vectors/DuckDBTimestampTZNanosecondsVector.ts +88 -0
  212. package/vendor/node-api/src/vectors/DuckDBTimestampTZVector.ts +86 -0
  213. package/vendor/node-api/src/vectors/DuckDBTimestampVector.ts +83 -0
  214. package/vendor/node-api/src/vectors/DuckDBTinyIntVector.ts +75 -0
  215. package/vendor/node-api/src/vectors/DuckDBTupleVector.ts +125 -0
  216. package/vendor/node-api/src/vectors/DuckDBUBigIntVector.ts +75 -0
  217. package/vendor/node-api/src/vectors/DuckDBUHugeIntVector.ts +89 -0
  218. package/vendor/node-api/src/vectors/DuckDBUIntegerVector.ts +75 -0
  219. package/vendor/node-api/src/vectors/DuckDBUSmallIntVector.ts +75 -0
  220. package/vendor/node-api/src/vectors/DuckDBUTinyIntVector.ts +75 -0
  221. package/vendor/node-api/src/vectors/DuckDBUUIDVector.ts +89 -0
  222. package/vendor/node-api/src/vectors/DuckDBUnionVector.ts +84 -0
  223. package/vendor/node-api/src/vectors/DuckDBValidity.ts +104 -0
  224. package/vendor/node-api/src/vectors/DuckDBVarCharVector.ts +100 -0
  225. package/vendor/node-api/src/vectors/DuckDBVariantVector.ts +609 -0
  226. package/vendor/node-api/src/vectors/DuckDBVector.ts +33 -0
  227. package/vendor/node-api/src/vectors/createVector.ts +269 -0
  228. package/vendor/node-api/src/vectors/dataAccessors.ts +387 -0
  229. package/vendor/node-api/src/vectors/index.ts +50 -0
  230. package/vendor/node-api/src/vectors/vectorRegistry.ts +24 -0
  231. package/vendor/node-api/src/version.ts +5 -0
@@ -0,0 +1,609 @@
1
+ import duckdb from "../../../../src/bindings/index.ts";
2
+ import { varintDecode } from '../conversion/varintDecode';
3
+ import {
4
+ BIGINT,
5
+ BIGNUM,
6
+ BIT,
7
+ BLOB,
8
+ BOOLEAN,
9
+ DATE,
10
+ DECIMAL,
11
+ DOUBLE,
12
+ DuckDBType,
13
+ DuckDBVariantType,
14
+ FLOAT,
15
+ GEOMETRY,
16
+ HUGEINT,
17
+ INTEGER,
18
+ INTERVAL,
19
+ LIST,
20
+ SMALLINT,
21
+ SQLNULL,
22
+ STRUCT,
23
+ TIME,
24
+ TIMESTAMP,
25
+ TIMESTAMPTZ,
26
+ TIMESTAMPTZ_NS,
27
+ TIMESTAMP_MS,
28
+ TIMESTAMP_NS,
29
+ TIMESTAMP_S,
30
+ TIMETZ,
31
+ TIME_NS,
32
+ TINYINT,
33
+ UBIGINT,
34
+ UHUGEINT,
35
+ UINTEGER,
36
+ USMALLINT,
37
+ UTINYINT,
38
+ UUID,
39
+ VARCHAR,
40
+ VARIANT,
41
+ } from '../DuckDBType';
42
+ import { DuckDBTypeId } from '../DuckDBTypeId';
43
+ import {
44
+ DuckDBBitValue,
45
+ DuckDBBlobValue,
46
+ DuckDBDateValue,
47
+ DuckDBDecimalValue,
48
+ DuckDBGeometryValue,
49
+ DuckDBIntervalValue,
50
+ DuckDBListValue,
51
+ DuckDBStructValue,
52
+ DuckDBTimeNSValue,
53
+ DuckDBTimeTZValue,
54
+ DuckDBTimeValue,
55
+ DuckDBTimestampMillisecondsValue,
56
+ DuckDBTimestampNanosecondsValue,
57
+ DuckDBTimestampSecondsValue,
58
+ DuckDBTimestampTZValue,
59
+ DuckDBTimestampTZNanosecondsValue,
60
+ DuckDBTimestampValue,
61
+ DuckDBUUIDValue,
62
+ DuckDBValue,
63
+ DuckDBVariantValue,
64
+ } from '../values';
65
+ import { DuckDBVector } from './DuckDBVector';
66
+ import {
67
+ getBigNumFromBytes,
68
+ getInt128,
69
+ getInt16,
70
+ getInt32,
71
+ getInt64,
72
+ getUInt128,
73
+ getUInt16,
74
+ getUInt32,
75
+ getUInt64,
76
+ getUInt8,
77
+ littleEndian,
78
+ textDecoder,
79
+ } from './dataAccessors';
80
+ import { DuckDBBlobVector } from './DuckDBBlobVector';
81
+ import { DuckDBListVector } from './DuckDBListVector';
82
+ import { DuckDBStructVector } from './DuckDBStructVector';
83
+ import { DuckDBUIntegerVector } from './DuckDBUIntegerVector';
84
+ import { DuckDBUTinyIntVector } from './DuckDBUTinyIntVector';
85
+ import { DuckDBVarCharVector } from './DuckDBVarCharVector';
86
+
87
+ // ---------------------------------------------------------------------------
88
+ // VARIANT
89
+ // ---------------------------------------------------------------------------
90
+ //
91
+ // VARIANT is a self-describing tagged value type whose physical layout is a
92
+ // STRUCT of four children: `keys` (LIST(VARCHAR)), `children`
93
+ // (LIST(STRUCT(keys_index, values_index))), `values`
94
+ // (LIST(STRUCT(type_id, byte_offset))), and `data` (BLOB). Each row's root
95
+ // node sits at index 0 of its `values` slice; primitive payloads live at
96
+ // `byte_offsets[...]` inside the row's blob, and OBJECT/ARRAY nodes
97
+ // reference their children through the row's `children` slice.
98
+ //
99
+ // Reading reuses the existing DuckDBStructVector / DuckDBListVector /
100
+ // DuckDBBlobVector construction plus the byte-readers above for primitive
101
+ // payloads. Writing is not yet supported.
102
+
103
+ /**
104
+ * On-disk tag for a single VARIANT node. Mirrors DuckDB's
105
+ * `VariantLogicalType` enum.
106
+ */
107
+ enum VariantLogicalType {
108
+ VARIANT_NULL = 0,
109
+ BOOL_TRUE = 1,
110
+ BOOL_FALSE = 2,
111
+ INT8 = 3,
112
+ INT16 = 4,
113
+ INT32 = 5,
114
+ INT64 = 6,
115
+ INT128 = 7,
116
+ UINT8 = 8,
117
+ UINT16 = 9,
118
+ UINT32 = 10,
119
+ UINT64 = 11,
120
+ UINT128 = 12,
121
+ FLOAT = 13,
122
+ DOUBLE = 14,
123
+ DECIMAL = 15,
124
+ VARCHAR = 16,
125
+ BLOB = 17,
126
+ UUID = 18,
127
+ DATE = 19,
128
+ TIME_MICROS = 20,
129
+ TIME_NANOS = 21,
130
+ TIMESTAMP_SEC = 22,
131
+ TIMESTAMP_MILIS = 23,
132
+ TIMESTAMP_MICROS = 24,
133
+ TIMESTAMP_NANOS = 25,
134
+ TIME_MICROS_TZ = 26,
135
+ TIMESTAMP_MICROS_TZ = 27,
136
+ INTERVAL = 28,
137
+ OBJECT = 29,
138
+ ARRAY = 30,
139
+ BIGNUM = 31,
140
+ BITSTRING = 32,
141
+ GEOMETRY = 33,
142
+ TIMESTAMP_NANOS_TZ = 34,
143
+ }
144
+
145
+ /** Physical STRUCT layout of a VARIANT column. Mirrors `LogicalType::VARIANT()`. */
146
+ const VARIANT_PHYSICAL_TYPE = STRUCT({
147
+ keys: LIST(VARCHAR),
148
+ children: LIST(STRUCT({ keys_index: UINTEGER, values_index: UINTEGER })),
149
+ values: LIST(STRUCT({ type_id: UTINYINT, byte_offset: UINTEGER })),
150
+ data: BLOB,
151
+ });
152
+
153
+ export class DuckDBVariantVector extends DuckDBVector<DuckDBVariantValue> {
154
+ private readonly structVec: DuckDBStructVector;
155
+ private readonly keysList: DuckDBListVector;
156
+ private readonly childrenList: DuckDBListVector;
157
+ private readonly valuesList: DuckDBListVector;
158
+ private readonly dataBlob: DuckDBBlobVector;
159
+ private readonly keysEntry: DuckDBVarCharVector;
160
+ private readonly keysIdxVec: DuckDBUIntegerVector;
161
+ private readonly valuesIdxVec: DuckDBUIntegerVector;
162
+ private readonly typeIdVec: DuckDBUTinyIntVector;
163
+ private readonly byteOffsetVec: DuckDBUIntegerVector;
164
+
165
+ constructor(structVec: DuckDBStructVector) {
166
+ super();
167
+ this.structVec = structVec;
168
+ this.keysList = structVec.entryVectorAt(0) as DuckDBListVector;
169
+ this.childrenList = structVec.entryVectorAt(1) as DuckDBListVector;
170
+ this.valuesList = structVec.entryVectorAt(2) as DuckDBListVector;
171
+ this.dataBlob = structVec.entryVectorAt(3) as DuckDBBlobVector;
172
+ this.keysEntry = this.keysList.childVector as DuckDBVarCharVector;
173
+ const childrenInner = this.childrenList.childVector as DuckDBStructVector;
174
+ const valuesInner = this.valuesList.childVector as DuckDBStructVector;
175
+ this.keysIdxVec = childrenInner.entryVectorAt(0) as DuckDBUIntegerVector;
176
+ this.valuesIdxVec = childrenInner.entryVectorAt(1) as DuckDBUIntegerVector;
177
+ this.typeIdVec = valuesInner.entryVectorAt(0) as DuckDBUTinyIntVector;
178
+ this.byteOffsetVec = valuesInner.entryVectorAt(1) as DuckDBUIntegerVector;
179
+ }
180
+
181
+ static fromRawVector(
182
+ vector: duckdb.Vector,
183
+ itemCount: number
184
+ ): DuckDBVariantVector {
185
+ const structVec = DuckDBStructVector.fromRawVector(
186
+ VARIANT_PHYSICAL_TYPE,
187
+ vector,
188
+ itemCount
189
+ );
190
+ return new DuckDBVariantVector(structVec);
191
+ }
192
+
193
+ public override get type(): DuckDBVariantType {
194
+ return DuckDBVariantType.instance;
195
+ }
196
+
197
+ public override get itemCount(): number {
198
+ return this.structVec.itemCount;
199
+ }
200
+
201
+ public override getItem(itemIndex: number): DuckDBVariantValue | null {
202
+ // Top-level validity is the canonical SQL-NULL indicator. Child rows
203
+ // may still carry data when the row is SQL-NULL; the inverse — that a
204
+ // non-NULL row has non-NULL children — is the only direction
205
+ // guaranteed by the format.
206
+ if (!this.structVec.isItemValid(itemIndex)) {
207
+ return null;
208
+ }
209
+ const blob = this.dataBlob.getItemBytes(itemIndex);
210
+ if (blob === null) {
211
+ // Defensive: a valid row's data BLOB is expected to be present.
212
+ return null;
213
+ }
214
+ const row: VariantRow = {
215
+ blob,
216
+ view: new DataView(blob.buffer, blob.byteOffset, blob.byteLength),
217
+ valuesOffset: this.valuesList.getEntryOffset(itemIndex),
218
+ valuesLength: this.valuesList.getEntryLength(itemIndex),
219
+ childrenOffset: this.childrenList.getEntryOffset(itemIndex),
220
+ childrenLength: this.childrenList.getEntryLength(itemIndex),
221
+ keysOffset: this.keysList.getEntryOffset(itemIndex),
222
+ keysLength: this.keysList.getEntryLength(itemIndex),
223
+ };
224
+ const root = this.decodeNode(0, row);
225
+ return new DuckDBVariantValue(root.value, root.type);
226
+ }
227
+
228
+ public override setItem(
229
+ _itemIndex: number,
230
+ value: DuckDBVariantValue | null
231
+ ): void {
232
+ // Writing a VARIANT value isn't supported yet. setItem(null) is
233
+ // tolerated as a no-op so a parent struct/list/array can iterate
234
+ // every child and call setItem(null) on this column without failing
235
+ // — the read path remains usable inside arbitrary container types.
236
+ if (value !== null) {
237
+ throw new Error('Setting VARIANT values is not yet supported.');
238
+ }
239
+ }
240
+
241
+ public override flush(): void {
242
+ // No-op: VARIANT is read-only, but a parent vector's flush() will
243
+ // still call this on every child. Nothing to write back.
244
+ }
245
+
246
+ public override slice(offset: number, length: number): DuckDBVariantVector {
247
+ return new DuckDBVariantVector(this.structVec.slice(offset, length));
248
+ }
249
+
250
+ /**
251
+ * Decode one variant node identified by its row-local `valueIndex`
252
+ * (an index into the row's `values` list). Per-row state is bundled in
253
+ * `row`: the data blob plus the row-local list slice extents and the
254
+ * absolute backing-array offsets they begin at. All recursive calls
255
+ * share the same `row`; only `valueIndex` changes.
256
+ *
257
+ * Returns both the decoded value and the `DuckDBType` corresponding to
258
+ * the node's on-disk tag, so the top-level caller can attach the type
259
+ * to the resulting `DuckDBVariantValue` for round-trip fidelity.
260
+ *
261
+ * Throws if any index decoded from the blob falls outside its row-local
262
+ * list slice — guards against malformed or hostile VARIANT payloads.
263
+ */
264
+ private decodeNode(
265
+ valueIndex: number,
266
+ row: VariantRow
267
+ ): { value: DuckDBValue; type: DuckDBType } {
268
+ if (valueIndex >= row.valuesLength) {
269
+ throw new Error(
270
+ `Malformed VARIANT: value_index ${valueIndex} out of bounds (row values length ${row.valuesLength})`
271
+ );
272
+ }
273
+ const nodeAbs = row.valuesOffset + valueIndex;
274
+ const tag = this.typeIdVec.getItem(nodeAbs) as number;
275
+ const byteOffset = this.byteOffsetVec.getItem(nodeAbs) as number;
276
+ const { blob, view } = row;
277
+ switch (tag as VariantLogicalType) {
278
+ case VariantLogicalType.VARIANT_NULL:
279
+ return { value: null, type: SQLNULL };
280
+ case VariantLogicalType.BOOL_TRUE:
281
+ return { value: true, type: BOOLEAN };
282
+ case VariantLogicalType.BOOL_FALSE:
283
+ return { value: false, type: BOOLEAN };
284
+ case VariantLogicalType.INT8:
285
+ return { value: view.getInt8(byteOffset), type: TINYINT };
286
+ case VariantLogicalType.INT16:
287
+ return { value: getInt16(view, byteOffset), type: SMALLINT };
288
+ case VariantLogicalType.INT32:
289
+ return { value: getInt32(view, byteOffset), type: INTEGER };
290
+ case VariantLogicalType.INT64:
291
+ return { value: getInt64(view, byteOffset), type: BIGINT };
292
+ case VariantLogicalType.INT128:
293
+ return { value: getInt128(view, byteOffset), type: HUGEINT };
294
+ case VariantLogicalType.UINT8:
295
+ return { value: getUInt8(view, byteOffset), type: UTINYINT };
296
+ case VariantLogicalType.UINT16:
297
+ return { value: getUInt16(view, byteOffset), type: USMALLINT };
298
+ case VariantLogicalType.UINT32:
299
+ return { value: getUInt32(view, byteOffset), type: UINTEGER };
300
+ case VariantLogicalType.UINT64:
301
+ return { value: getUInt64(view, byteOffset), type: UBIGINT };
302
+ case VariantLogicalType.UINT128:
303
+ return { value: getUInt128(view, byteOffset), type: UHUGEINT };
304
+ case VariantLogicalType.FLOAT:
305
+ return {
306
+ value: view.getFloat32(byteOffset, littleEndian),
307
+ type: FLOAT,
308
+ };
309
+ case VariantLogicalType.DOUBLE:
310
+ return {
311
+ value: view.getFloat64(byteOffset, littleEndian),
312
+ type: DOUBLE,
313
+ };
314
+ case VariantLogicalType.UUID:
315
+ return {
316
+ value: DuckDBUUIDValue.fromStoredHugeInt(getInt128(view, byteOffset)),
317
+ type: UUID,
318
+ };
319
+ case VariantLogicalType.DATE:
320
+ return {
321
+ value: new DuckDBDateValue(getInt32(view, byteOffset)),
322
+ type: DATE,
323
+ };
324
+ case VariantLogicalType.TIME_MICROS:
325
+ return {
326
+ value: new DuckDBTimeValue(getInt64(view, byteOffset)),
327
+ type: TIME,
328
+ };
329
+ case VariantLogicalType.TIME_NANOS:
330
+ return {
331
+ value: new DuckDBTimeNSValue(getInt64(view, byteOffset)),
332
+ type: TIME_NS,
333
+ };
334
+ case VariantLogicalType.TIME_MICROS_TZ:
335
+ return {
336
+ value: DuckDBTimeTZValue.fromBits(getUInt64(view, byteOffset)),
337
+ type: TIMETZ,
338
+ };
339
+ case VariantLogicalType.TIMESTAMP_SEC:
340
+ return {
341
+ value: new DuckDBTimestampSecondsValue(getInt64(view, byteOffset)),
342
+ type: TIMESTAMP_S,
343
+ };
344
+ case VariantLogicalType.TIMESTAMP_MILIS:
345
+ return {
346
+ value: new DuckDBTimestampMillisecondsValue(
347
+ getInt64(view, byteOffset)
348
+ ),
349
+ type: TIMESTAMP_MS,
350
+ };
351
+ case VariantLogicalType.TIMESTAMP_MICROS:
352
+ return {
353
+ value: new DuckDBTimestampValue(getInt64(view, byteOffset)),
354
+ type: TIMESTAMP,
355
+ };
356
+ case VariantLogicalType.TIMESTAMP_NANOS:
357
+ return {
358
+ value: new DuckDBTimestampNanosecondsValue(
359
+ getInt64(view, byteOffset)
360
+ ),
361
+ type: TIMESTAMP_NS,
362
+ };
363
+ case VariantLogicalType.TIMESTAMP_MICROS_TZ:
364
+ return {
365
+ value: new DuckDBTimestampTZValue(getInt64(view, byteOffset)),
366
+ type: TIMESTAMPTZ,
367
+ };
368
+ case VariantLogicalType.TIMESTAMP_NANOS_TZ:
369
+ return {
370
+ value: new DuckDBTimestampTZNanosecondsValue(
371
+ getInt64(view, byteOffset)
372
+ ),
373
+ type: TIMESTAMPTZ_NS,
374
+ };
375
+ case VariantLogicalType.INTERVAL:
376
+ return {
377
+ value: new DuckDBIntervalValue(
378
+ getInt32(view, byteOffset),
379
+ getInt32(view, byteOffset + 4),
380
+ getInt64(view, byteOffset + 8)
381
+ ),
382
+ type: INTERVAL,
383
+ };
384
+ case VariantLogicalType.VARCHAR: {
385
+ const bytes = readVarintBytes(view, byteOffset, blob);
386
+ return { value: textDecoder.decode(bytes), type: VARCHAR };
387
+ }
388
+ case VariantLogicalType.BLOB: {
389
+ // Copy out — the bytes alias the underlying vector storage, which
390
+ // we don't want to share through to user code.
391
+ const bytes = readVarintBytes(view, byteOffset, blob);
392
+ return {
393
+ value: new DuckDBBlobValue(new Uint8Array(bytes)),
394
+ type: BLOB,
395
+ };
396
+ }
397
+ case VariantLogicalType.BITSTRING: {
398
+ const bytes = readVarintBytes(view, byteOffset, blob);
399
+ return {
400
+ value: new DuckDBBitValue(new Uint8Array(bytes)),
401
+ type: BIT,
402
+ };
403
+ }
404
+ case VariantLogicalType.BIGNUM: {
405
+ const bytes = readVarintBytes(view, byteOffset, blob);
406
+ return { value: getBigNumFromBytes(bytes), type: BIGNUM };
407
+ }
408
+ case VariantLogicalType.GEOMETRY: {
409
+ const bytes = readVarintBytes(view, byteOffset, blob);
410
+ return {
411
+ value: new DuckDBGeometryValue(new Uint8Array(bytes)),
412
+ type: GEOMETRY,
413
+ };
414
+ }
415
+ case VariantLogicalType.DECIMAL: {
416
+ const wParse = varintDecode(view, byteOffset);
417
+ const sParse = varintDecode(view, wParse.nextOffset);
418
+ const width = wParse.value;
419
+ const scale = sParse.value;
420
+ const valueOffset = sParse.nextOffset;
421
+ let intValue: bigint;
422
+ if (width <= 4) {
423
+ intValue = BigInt(getInt16(view, valueOffset));
424
+ } else if (width <= 9) {
425
+ intValue = BigInt(getInt32(view, valueOffset));
426
+ } else if (width <= 18) {
427
+ intValue = getInt64(view, valueOffset);
428
+ } else if (width <= 38) {
429
+ intValue = getInt128(view, valueOffset);
430
+ } else {
431
+ throw new Error(`VARIANT DECIMAL width too large: ${width}`);
432
+ }
433
+ return {
434
+ value: new DuckDBDecimalValue(intValue, width, scale),
435
+ type: DECIMAL(width, scale),
436
+ };
437
+ }
438
+ case VariantLogicalType.OBJECT: {
439
+ const { childCount, childrenIdx } = readNestedHeader(view, byteOffset);
440
+ this.checkChildrenSlice(childrenIdx, childCount, row);
441
+ const entries: { [name: string]: DuckDBValue } = {};
442
+ const fields: { [name: string]: DuckDBType } = {};
443
+ for (let k = 0; k < childCount; k++) {
444
+ const entryAbs = row.childrenOffset + childrenIdx + k;
445
+ const keyIdx = this.keysIdxVec.getItem(entryAbs) as number;
446
+ if (keyIdx >= row.keysLength) {
447
+ throw new Error(
448
+ `Malformed VARIANT: keys_index ${keyIdx} out of bounds (row keys length ${row.keysLength})`
449
+ );
450
+ }
451
+ const keyStr = this.keysEntry.getItem(
452
+ row.keysOffset + keyIdx
453
+ ) as string;
454
+ const valIdx = this.valuesIdxVec.getItem(entryAbs) as number;
455
+ const child = this.decodeNode(valIdx, row);
456
+ entries[keyStr] = child.value;
457
+ fields[keyStr] = child.type;
458
+ }
459
+ return {
460
+ value: new DuckDBStructValue(entries),
461
+ type: STRUCT(fields),
462
+ };
463
+ }
464
+ case VariantLogicalType.ARRAY: {
465
+ const { childCount, childrenIdx } = readNestedHeader(view, byteOffset);
466
+ this.checkChildrenSlice(childrenIdx, childCount, row);
467
+ // Decode all children first so we can decide whether their types
468
+ // are uniform. If they are (treating SQLNULL as compatible with
469
+ // any sibling, so e.g. [1, 2, null] reads as LIST(UBIGINT)), use
470
+ // `LIST(commonType)` with bare items — that's a Value the C API's
471
+ // create_list_value will accept, and it round-trips through
472
+ // bind/append cleanly. Otherwise fall back to `LIST(VARIANT)`
473
+ // with non-null items wrapped to preserve their type; null items
474
+ // remain bare to match how column-level LIST(VARIANT) decodes a
475
+ // null element.
476
+ const children: { value: DuckDBValue; type: DuckDBType }[] = [];
477
+ for (let k = 0; k < childCount; k++) {
478
+ const entryAbs = row.childrenOffset + childrenIdx + k;
479
+ const valIdx = this.valuesIdxVec.getItem(entryAbs) as number;
480
+ children.push(this.decodeNode(valIdx, row));
481
+ }
482
+ const commonType = uniformVariantChildType(children);
483
+ if (commonType !== null) {
484
+ return {
485
+ value: new DuckDBListValue(children.map((c) => c.value)),
486
+ type: LIST(commonType),
487
+ };
488
+ }
489
+ return {
490
+ value: new DuckDBListValue(
491
+ children.map((c) =>
492
+ c.value === null
493
+ ? null
494
+ : new DuckDBVariantValue(c.value, c.type),
495
+ ),
496
+ ),
497
+ type: LIST(VARIANT),
498
+ };
499
+ }
500
+ default:
501
+ throw new Error(`Unknown VARIANT type id: ${tag}`);
502
+ }
503
+ }
504
+
505
+ /** Bounds-check an OBJECT / ARRAY's `[childrenIdx, childrenIdx+childCount)` range. */
506
+ private checkChildrenSlice(
507
+ childrenIdx: number,
508
+ childCount: number,
509
+ row: VariantRow
510
+ ): void {
511
+ if (childrenIdx + childCount > row.childrenLength) {
512
+ throw new Error(
513
+ `Malformed VARIANT: children slice [${childrenIdx}, ${childrenIdx + childCount}) out of bounds (row children length ${row.childrenLength})`
514
+ );
515
+ }
516
+ }
517
+ }
518
+
519
+ /**
520
+ * Returns the shared DuckDBType if every non-null child has the same type,
521
+ * or `null` if non-null children differ. Used to pick between
522
+ * `LIST(commonType)` and `LIST(VARIANT)` for a decoded ARRAY.
523
+ *
524
+ * SQLNULL children are treated as compatible with any sibling — that way a
525
+ * very common JSON shape like `[1, 2, null]` decodes as `LIST(UBIGINT)`
526
+ * with a bare null element rather than `LIST(VARIANT)`. An array whose
527
+ * children are all SQLNULL (including the empty array) collapses to
528
+ * SQLNULL itself — DuckDB casts `LIST(SQLNULL)` to VARIANT for round-trip,
529
+ * but a `LIST(VARIANT)` of nulls or an empty `LIST(VARIANT)` doesn't
530
+ * survive `create_list_value`.
531
+ */
532
+ function uniformVariantChildType(
533
+ children: { value: DuckDBValue; type: DuckDBType }[]
534
+ ): DuckDBType | null {
535
+ let common: DuckDBType | null = null;
536
+ let commonKey: string | null = null;
537
+ for (const child of children) {
538
+ if (child.type.typeId === DuckDBTypeId.SQLNULL) {
539
+ continue;
540
+ }
541
+ const key = typeKey(child.type);
542
+ if (common === null) {
543
+ common = child.type;
544
+ commonKey = key;
545
+ } else if (key !== commonKey) {
546
+ return null;
547
+ }
548
+ }
549
+ // All children (if any) are SQLNULL: collapse to SQLNULL.
550
+ return common ?? SQLNULL;
551
+ }
552
+
553
+ /**
554
+ * Returns a canonical string for a DuckDBType, suitable for equality
555
+ * comparison between types produced by the same decode pass. Uses the
556
+ * structured `toJson()` representation rather than the SQL-syntactic
557
+ * `toString()` so nested types compare structurally.
558
+ */
559
+ function typeKey(type: DuckDBType): string {
560
+ return JSON.stringify(type.toJson());
561
+ }
562
+
563
+ /** Per-row state shared across recursive VARIANT decode calls. */
564
+ interface VariantRow {
565
+ blob: Uint8Array;
566
+ view: DataView;
567
+ valuesOffset: number;
568
+ valuesLength: number;
569
+ childrenOffset: number;
570
+ childrenLength: number;
571
+ keysOffset: number;
572
+ keysLength: number;
573
+ }
574
+
575
+ /**
576
+ * Reads a length-prefixed payload (`<varint length><length bytes>`) from a
577
+ * variant data blob. Returns a (possibly aliased) Uint8Array view over the
578
+ * payload bytes — callers that need to retain the data should copy.
579
+ * Throws if the prefix length would read past the row's blob.
580
+ */
581
+ function readVarintBytes(
582
+ view: DataView,
583
+ offset: number,
584
+ blob: Uint8Array
585
+ ): Uint8Array {
586
+ const { value: length, nextOffset } = varintDecode(view, offset);
587
+ if (nextOffset + length > blob.byteLength) {
588
+ throw new Error(
589
+ `Malformed VARIANT payload: length-prefixed read of ${length} bytes at offset ${nextOffset} exceeds row blob size ${blob.byteLength}`
590
+ );
591
+ }
592
+ return new Uint8Array(blob.buffer, blob.byteOffset + nextOffset, length);
593
+ }
594
+
595
+ /**
596
+ * Reads an OBJECT / ARRAY header: `<varint child_count>` followed by
597
+ * `<varint children_idx>` iff `child_count > 0`.
598
+ */
599
+ function readNestedHeader(
600
+ view: DataView,
601
+ offset: number
602
+ ): { childCount: number; childrenIdx: number } {
603
+ const cParse = varintDecode(view, offset);
604
+ if (cParse.value === 0) {
605
+ return { childCount: 0, childrenIdx: 0 };
606
+ }
607
+ const iParse = varintDecode(view, cParse.nextOffset);
608
+ return { childCount: cParse.value, childrenIdx: iParse.value };
609
+ }
@@ -0,0 +1,33 @@
1
+ import duckdb from "../../../../src/bindings/index.ts";
2
+ import { DuckDBType } from '../DuckDBType';
3
+ import { DuckDBValue } from '../values';
4
+ import { vectorRegistry } from './vectorRegistry';
5
+
6
+ export abstract class DuckDBVector<TValue extends DuckDBValue = DuckDBValue> {
7
+ public static standardSize(): number {
8
+ return duckdb.vector_size();
9
+ }
10
+ public static create(
11
+ vector: duckdb.Vector,
12
+ itemCount: number,
13
+ knownType?: DuckDBType
14
+ ): DuckDBVector {
15
+ if (!vectorRegistry.create) {
16
+ throw new Error('DuckDBVector factory has not been registered');
17
+ }
18
+ return vectorRegistry.create(vector, itemCount, knownType);
19
+ }
20
+ public abstract get type(): DuckDBType;
21
+ public abstract get itemCount(): number;
22
+ public abstract getItem(itemIndex: number): TValue | null;
23
+ public abstract setItem(itemIndex: number, value: TValue | null): void;
24
+ public abstract flush(): void;
25
+ public abstract slice(offset: number, length: number): DuckDBVector<TValue>;
26
+ public toArray(): (TValue | null)[] {
27
+ const items: (TValue | null)[] = [];
28
+ for (let i = 0; i < this.itemCount; i++) {
29
+ items.push(this.getItem(i));
30
+ }
31
+ return items;
32
+ }
33
+ }