df-script 1.4.0 → 1.5.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.
- package/README.md +83 -34
- package/dist/api.d.ts +16 -8
- package/dist/api.js +11 -3
- package/dist/columnExpressions/ColumnExpr.d.ts +26 -364
- package/dist/columnExpressions/ColumnExpr.js +199 -3
- package/dist/columnExpressions/ExprBase.d.ts +8 -11
- package/dist/columnExpressions/ExprBase.js +20 -61
- package/dist/columnExpressions/constants.d.ts +2 -0
- package/dist/columnExpressions/constants.js +3 -1
- package/dist/columnExpressions/functions/coalesce.js +8 -4
- package/dist/columnExpressions/functions/element.d.ts +5 -0
- package/dist/columnExpressions/functions/element.js +11 -0
- package/dist/columnExpressions/functions/implode.d.ts +3 -0
- package/dist/columnExpressions/functions/implode.js +7 -0
- package/dist/columnExpressions/functions/lit.d.ts +3 -1
- package/dist/columnExpressions/functions/lit.js +8 -13
- package/dist/columnExpressions/functions/repeat.d.ts +47 -0
- package/dist/columnExpressions/functions/repeat.js +131 -0
- package/dist/columnExpressions/functions/seq_range.d.ts +31 -0
- package/dist/columnExpressions/functions/seq_range.js +91 -0
- package/dist/columnExpressions/functions/when.js +8 -4
- package/dist/columnExpressions/index.d.ts +5 -2
- package/dist/columnExpressions/index.js +5 -48
- package/dist/columnExpressions/mixins/AggregationExpr.d.ts +25 -50
- package/dist/columnExpressions/mixins/AggregationExpr.js +69 -165
- package/dist/columnExpressions/mixins/ArithmeticExpr.d.ts +41 -66
- package/dist/columnExpressions/mixins/ArithmeticExpr.js +126 -138
- package/dist/columnExpressions/mixins/BooleanExpr.d.ts +40 -0
- package/dist/columnExpressions/mixins/BooleanExpr.js +67 -0
- package/dist/columnExpressions/mixins/ComparisonExpr.d.ts +31 -60
- package/dist/columnExpressions/mixins/ComparisonExpr.js +231 -370
- package/dist/columnExpressions/mixins/ListExpr.d.ts +15 -39
- package/dist/columnExpressions/mixins/ListExpr.js +124 -148
- package/dist/columnExpressions/mixins/LogicalExpr.d.ts +7 -33
- package/dist/columnExpressions/mixins/LogicalExpr.js +48 -49
- package/dist/columnExpressions/mixins/ManipulationExpr.d.ts +6 -31
- package/dist/columnExpressions/mixins/ManipulationExpr.js +61 -25
- package/dist/columnExpressions/mixins/NumericExpr.d.ts +92 -0
- package/dist/columnExpressions/mixins/NumericExpr.js +259 -0
- package/dist/columnExpressions/mixins/StringExpr.d.ts +5 -30
- package/dist/columnExpressions/mixins/StringExpr.js +37 -49
- package/dist/columnExpressions/mixins/StructExpr.d.ts +16 -0
- package/dist/columnExpressions/mixins/StructExpr.js +139 -0
- package/dist/columnExpressions/mixins/TemporalExpr.d.ts +4 -30
- package/dist/columnExpressions/mixins/TemporalExpr.js +28 -29
- package/dist/columnExpressions/mixins/WindowExpr.d.ts +27 -49
- package/dist/columnExpressions/mixins/WindowExpr.js +144 -274
- package/dist/columnExpressions/utils.d.ts +4 -0
- package/dist/columnExpressions/utils.js +45 -0
- package/dist/dataframe/constants.d.ts +3 -0
- package/dist/dataframe/constants.js +4 -1
- package/dist/dataframe/dataframe.d.ts +27 -10
- package/dist/dataframe/dataframe.js +461 -220
- package/dist/dataframe/grouped/grouped.d.ts +2 -3
- package/dist/dataframe/grouped/grouped.js +17 -16
- package/dist/dataframe/types.d.ts +65 -1
- package/dist/dataframe/utils.d.ts +11 -3
- package/dist/dataframe/utils.js +101 -9
- package/dist/datatypes/DataType.d.ts +2 -1
- package/dist/datatypes/DataType.js +29 -0
- package/dist/datatypes/index.d.ts +2 -2
- package/dist/datatypes/types.d.ts +37 -36
- package/dist/datatypes/types.js +15 -11
- package/dist/exceptions/index.d.ts +2 -0
- package/dist/exceptions/index.js +4 -1
- package/dist/exceptions/utils.d.ts +1 -0
- package/dist/exceptions/utils.js +19 -0
- package/dist/functions/concat.d.ts +1 -2
- package/dist/functions/concat.js +24 -12
- package/dist/functions/index.d.ts +3 -1
- package/dist/functions/index.js +7 -15
- package/dist/functions/read_csv.d.ts +8 -0
- package/dist/functions/read_csv.js +53 -0
- package/dist/functions/read_json.d.ts +10 -0
- package/dist/functions/read_json.js +21 -0
- package/dist/functions/transpose.d.ts +7 -0
- package/dist/functions/transpose.js +84 -0
- package/dist/index.js +6 -1
- package/dist/types.d.ts +31 -5
- package/dist/utils/csv.d.ts +77 -0
- package/dist/utils/csv.js +313 -0
- package/dist/utils/date.js +5 -6
- package/dist/utils/guards.d.ts +0 -2
- package/dist/utils/guards.js +0 -31
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/index.js +2 -0
- package/dist/utils/json.d.ts +120 -2
- package/dist/utils/json.js +204 -20
- package/dist/utils/list.d.ts +173 -1
- package/dist/utils/list.js +255 -22
- package/dist/utils/number.d.ts +61 -28
- package/dist/utils/number.js +248 -70
- package/dist/utils/string.d.ts +5 -0
- package/dist/utils/string.js +89 -0
- package/package.json +5 -1
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { DataFrame } from "../dataframe";
|
|
2
2
|
import type { GroupMap } from "../types";
|
|
3
|
-
import {
|
|
4
|
-
import type { IExpr, ColumnDict, RowRecord } from "../../types";
|
|
3
|
+
import type { IExpr, ColumnDict, RowRecord, DataFrameSchema } from "../../types";
|
|
5
4
|
export declare class GroupedData<T, K extends keyof T> {
|
|
6
5
|
private groups;
|
|
7
6
|
private keys;
|
|
@@ -9,7 +8,7 @@ export declare class GroupedData<T, K extends keyof T> {
|
|
|
9
8
|
private parentColumns;
|
|
10
9
|
private parentHeight;
|
|
11
10
|
private parentSchema;
|
|
12
|
-
constructor(groups: GroupMap, keys: K[], allKeys: (keyof T)[], parentColumns: ColumnDict, parentHeight: number, parentSchema:
|
|
11
|
+
constructor(groups: GroupMap, keys: K[], allKeys: (keyof T)[], parentColumns: ColumnDict, parentHeight: number, parentSchema: DataFrameSchema);
|
|
13
12
|
to_dataframe<U extends RowRecord = any>(): DataFrame<U>;
|
|
14
13
|
agg<U extends RowRecord = any>(...exprs: (IExpr | any)[]): DataFrame<U>;
|
|
15
14
|
}
|
|
@@ -46,7 +46,7 @@ class GroupedData {
|
|
|
46
46
|
for (const k of keysStr) {
|
|
47
47
|
outSchema[k] = this.parentSchema[k];
|
|
48
48
|
}
|
|
49
|
-
return
|
|
49
|
+
return dataframe_1.DataFrame._createDirect(newColumns, outSchema, groupIdx);
|
|
50
50
|
}
|
|
51
51
|
agg(...exprs) {
|
|
52
52
|
const allKeysLen = this.allKeys.length;
|
|
@@ -59,7 +59,7 @@ class GroupedData {
|
|
|
59
59
|
for (let i = 0; i < keysLen; i++) {
|
|
60
60
|
keysStr[i] = String(this.keys[i]);
|
|
61
61
|
}
|
|
62
|
-
const expandedExprs = (0, columnExpressions_1.resolveColumnSelectors)(exprs.flat(), allKeysStr, keysStr);
|
|
62
|
+
const expandedExprs = (0, columnExpressions_1.resolveColumnSelectors)(exprs.flat(), allKeysStr, keysStr, this.parentSchema, this.parentColumns);
|
|
63
63
|
const numGroups = this.groups.size;
|
|
64
64
|
const newColumns = {};
|
|
65
65
|
for (let i = 0; i < keysStr.length; i++) {
|
|
@@ -82,22 +82,23 @@ class GroupedData {
|
|
|
82
82
|
const targetKey = e.outputName || e.colName || columnExpressions_1.ALL_COLUMNS_MARKER;
|
|
83
83
|
if (!e.aggFn) {
|
|
84
84
|
newColumns[targetKey] = e.evaluate(newColumns, numGroups);
|
|
85
|
-
continue;
|
|
86
85
|
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
86
|
+
else {
|
|
87
|
+
const preGroupedCol = e.evaluatePre(e.groupingOpsIndex, this.parentColumns, this.parentHeight);
|
|
88
|
+
const aggregatedGroupValues = new Array(numGroups);
|
|
89
|
+
let gIdx = 0;
|
|
90
|
+
for (const indices of this.groups.values()) {
|
|
91
|
+
if (indices.length === 0)
|
|
92
|
+
continue;
|
|
93
|
+
const groupValues = new Array(indices.length);
|
|
94
|
+
for (let k = 0; k < indices.length; k++) {
|
|
95
|
+
groupValues[k] = preGroupedCol[indices[k]];
|
|
96
|
+
}
|
|
97
|
+
aggregatedGroupValues[gIdx] = e.aggFn(groupValues);
|
|
98
|
+
gIdx++;
|
|
96
99
|
}
|
|
97
|
-
|
|
98
|
-
gIdx++;
|
|
100
|
+
newColumns[targetKey] = e.evaluatePost(e.groupingOpsIndex, aggregatedGroupValues, newColumns);
|
|
99
101
|
}
|
|
100
|
-
newColumns[targetKey] = e.evaluatePostGrouping(aggregatedGroupValues, newColumns);
|
|
101
102
|
}
|
|
102
103
|
const outSchema = {};
|
|
103
104
|
for (const k of keysStr) {
|
|
@@ -107,7 +108,7 @@ class GroupedData {
|
|
|
107
108
|
const targetKey = e.outputName || e.colName || columnExpressions_1.ALL_COLUMNS_MARKER;
|
|
108
109
|
outSchema[targetKey] = (0, utils_1.inferColumnType)(newColumns[targetKey]);
|
|
109
110
|
}
|
|
110
|
-
return
|
|
111
|
+
return dataframe_1.DataFrame._createDirect(newColumns, outSchema, groupIdx);
|
|
111
112
|
}
|
|
112
113
|
}
|
|
113
114
|
exports.GroupedData = GroupedData;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import type { IExpr, AggFn, RowRecord } from "../types";
|
|
1
|
+
import type { IExpr, AggFn, RowRecord, DataFrameSchema, JSONFormat } from "../types";
|
|
2
2
|
import type { DataFrame } from "./dataframe";
|
|
3
|
+
import type { JSONParseOptions, SafeJsonReplacerOptions, NDJSONParseOptions } from "../utils";
|
|
4
|
+
export type { JSONParseOptions, SafeJsonReplacerOptions, NDJSONParseOptions };
|
|
3
5
|
export type JoinType = "inner" | "left" | "outer" | "right";
|
|
4
6
|
export type LimitPosition = "start" | "end";
|
|
5
7
|
export type GroupMap = Map<string, number[]>;
|
|
@@ -31,3 +33,65 @@ export interface UnpivotOptions<T> {
|
|
|
31
33
|
varName?: string;
|
|
32
34
|
valueName?: string;
|
|
33
35
|
}
|
|
36
|
+
export interface TransposeOptions {
|
|
37
|
+
include_header?: boolean;
|
|
38
|
+
header_name?: string;
|
|
39
|
+
column_names?: string | Iterable<string>;
|
|
40
|
+
}
|
|
41
|
+
export interface ReadJSONOptions extends JSONParseOptions {
|
|
42
|
+
/**
|
|
43
|
+
* Optional explicit schema mapping column names to their registered data types.
|
|
44
|
+
*/
|
|
45
|
+
schema?: DataFrameSchema;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* The `replacer` argument type extracted directly from the overloads of the built-in `JSON.stringify`.
|
|
49
|
+
* Hover or Go-to-Definition on `JSON.stringify` below to inspect the standard library signatures.
|
|
50
|
+
*/
|
|
51
|
+
export type JSONStringifyReplacer = typeof JSON.stringify extends {
|
|
52
|
+
(value: any, replacer?: infer R1, space?: any): string;
|
|
53
|
+
(value: any, replacer?: infer R2, space?: any): string;
|
|
54
|
+
} ? R1 | R2 : never;
|
|
55
|
+
export interface WriteJSONOptions {
|
|
56
|
+
/**
|
|
57
|
+
* The format of the JSON output.
|
|
58
|
+
* @default "json"
|
|
59
|
+
*/
|
|
60
|
+
format?: JSONFormat;
|
|
61
|
+
/**
|
|
62
|
+
* Options for the safe JSON replacer.
|
|
63
|
+
*/
|
|
64
|
+
replacerOptions?: SafeJsonReplacerOptions;
|
|
65
|
+
}
|
|
66
|
+
export type { WriteCSVOptions } from "../utils";
|
|
67
|
+
export interface ReadCSVOptions {
|
|
68
|
+
/**
|
|
69
|
+
* Whether the CSV has a header row.
|
|
70
|
+
* @default true
|
|
71
|
+
*/
|
|
72
|
+
hasHeader?: boolean;
|
|
73
|
+
/**
|
|
74
|
+
* Character that separates fields.
|
|
75
|
+
* @default ","
|
|
76
|
+
*/
|
|
77
|
+
separator?: string;
|
|
78
|
+
/**
|
|
79
|
+
* The character used for quoting fields.
|
|
80
|
+
* @default '"'
|
|
81
|
+
*/
|
|
82
|
+
quoteChar?: string;
|
|
83
|
+
/**
|
|
84
|
+
* String representations of null values.
|
|
85
|
+
* @default ["", "NA", "null", "NaN"]
|
|
86
|
+
*/
|
|
87
|
+
nullValues?: string[];
|
|
88
|
+
/**
|
|
89
|
+
* Optional explicit schema mapping column names to their registered data types.
|
|
90
|
+
*/
|
|
91
|
+
schema?: DataFrameSchema;
|
|
92
|
+
/**
|
|
93
|
+
* Try to infer types from values if no schema is provided.
|
|
94
|
+
* @default true
|
|
95
|
+
*/
|
|
96
|
+
inferSchema?: boolean;
|
|
97
|
+
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import type { IExpr, ColumnData, ColumnDict } from "../types";
|
|
2
|
-
import { DataType } from "../datatypes";
|
|
1
|
+
import type { IExpr, ColumnData, ColumnDict, RegisteredDataType } from "../types";
|
|
3
2
|
export declare function resolveWindowExpr(expr: IExpr, columns: ColumnDict, height: number): ColumnData;
|
|
4
3
|
export declare function rowsToColumns(rows: any[]): {
|
|
5
4
|
columns: ColumnDict;
|
|
@@ -7,5 +6,14 @@ export declare function rowsToColumns(rows: any[]): {
|
|
|
7
6
|
};
|
|
8
7
|
export declare function columnsToRows(columns: ColumnDict, height: number): any[];
|
|
9
8
|
export declare function getRowFromColumns(columns: ColumnDict, idx: number, keys: string[]): any;
|
|
10
|
-
export declare function inferColumnType(col: ColumnData):
|
|
9
|
+
export declare function inferColumnType(col: ColumnData): RegisteredDataType;
|
|
11
10
|
export declare function gatherColumnsByIndices(columns: ColumnDict, indices: number[]): ColumnDict;
|
|
11
|
+
/**
|
|
12
|
+
* Computes a hash string for a row at the given index, using one or more column keys.
|
|
13
|
+
* Includes a single-key fast path to avoid array allocation and join overhead.
|
|
14
|
+
*/
|
|
15
|
+
export declare function computeRowHash(columns: ColumnDict, keys: string[], rowIndex: number): string;
|
|
16
|
+
export declare function coerceColumn(col: ColumnData, type: RegisteredDataType, height: number): ColumnData;
|
|
17
|
+
export declare function writeStringToFileOrStream(file: string | {
|
|
18
|
+
write: (str: string) => void;
|
|
19
|
+
} | undefined, content: string): void;
|
package/dist/dataframe/utils.js
CHANGED
|
@@ -6,6 +6,9 @@ exports.columnsToRows = columnsToRows;
|
|
|
6
6
|
exports.getRowFromColumns = getRowFromColumns;
|
|
7
7
|
exports.inferColumnType = inferColumnType;
|
|
8
8
|
exports.gatherColumnsByIndices = gatherColumnsByIndices;
|
|
9
|
+
exports.computeRowHash = computeRowHash;
|
|
10
|
+
exports.coerceColumn = coerceColumn;
|
|
11
|
+
exports.writeStringToFileOrStream = writeStringToFileOrStream;
|
|
9
12
|
const datatypes_1 = require("../datatypes");
|
|
10
13
|
const constants_1 = require("./constants");
|
|
11
14
|
const utils_1 = require("../utils");
|
|
@@ -24,11 +27,25 @@ function partition_by_columns(columns, height, partitionKeys) {
|
|
|
24
27
|
keyColumns[i] = pKey.evaluate(columns, height);
|
|
25
28
|
}
|
|
26
29
|
}
|
|
30
|
+
if (pKeysLen === 1) {
|
|
31
|
+
const keyCol = keyColumns[0];
|
|
32
|
+
for (let i = 0; i < height; i++) {
|
|
33
|
+
const val = keyCol[i];
|
|
34
|
+
const hash = val == null ? "" : (0, utils_1.toCanonicalString)(val);
|
|
35
|
+
let group = partitionMap.get(hash);
|
|
36
|
+
if (group === undefined) {
|
|
37
|
+
group = [];
|
|
38
|
+
partitionMap.set(hash, group);
|
|
39
|
+
}
|
|
40
|
+
group.push(i);
|
|
41
|
+
}
|
|
42
|
+
return partitionMap;
|
|
43
|
+
}
|
|
27
44
|
for (let i = 0; i < height; i++) {
|
|
28
|
-
const keyValues = new Array(
|
|
29
|
-
for (let j = 0; j <
|
|
45
|
+
const keyValues = new Array(pKeysLen);
|
|
46
|
+
for (let j = 0; j < pKeysLen; j++) {
|
|
30
47
|
const val = keyColumns[j][i];
|
|
31
|
-
keyValues[j] = val == null ? "" :
|
|
48
|
+
keyValues[j] = val == null ? "" : (0, utils_1.toCanonicalString)(val);
|
|
32
49
|
}
|
|
33
50
|
const hash = keyValues.join(constants_1.KEY_SEPARATOR);
|
|
34
51
|
let group = partitionMap.get(hash);
|
|
@@ -46,7 +63,7 @@ function resolveWindowExpr(expr, columns, height) {
|
|
|
46
63
|
return results;
|
|
47
64
|
const partitionKeys = expr.partitionBy || [];
|
|
48
65
|
const partitionGroups = partition_by_columns(columns, height, partitionKeys);
|
|
49
|
-
const prePartitionArray = expr.
|
|
66
|
+
const prePartitionArray = expr.evaluatePre(expr.partitionOpsIndex, columns, height);
|
|
50
67
|
for (const indices of partitionGroups.values()) {
|
|
51
68
|
const groupLen = indices.length;
|
|
52
69
|
const groupPreValues = new Array(groupLen);
|
|
@@ -70,7 +87,7 @@ function resolveWindowExpr(expr, columns, height) {
|
|
|
70
87
|
results[indices[k]] = prePartitionArray[indices[k]];
|
|
71
88
|
}
|
|
72
89
|
}
|
|
73
|
-
return expr.
|
|
90
|
+
return expr.evaluatePost(expr.partitionOpsIndex, results, columns);
|
|
74
91
|
}
|
|
75
92
|
function rowsToColumns(rows) {
|
|
76
93
|
if (!Array.isArray(rows) || rows.length === 0) {
|
|
@@ -134,6 +151,8 @@ function inferColumnType(col) {
|
|
|
134
151
|
let isBigInt = true;
|
|
135
152
|
let isDate = true;
|
|
136
153
|
let isList = true;
|
|
154
|
+
let isBinary = true;
|
|
155
|
+
let isObject = true;
|
|
137
156
|
let hasDateObj = false;
|
|
138
157
|
let hasNonNull = false;
|
|
139
158
|
const allListElements = [];
|
|
@@ -142,12 +161,17 @@ function inferColumnType(col) {
|
|
|
142
161
|
if (val == null)
|
|
143
162
|
continue;
|
|
144
163
|
hasNonNull = true;
|
|
145
|
-
if (!
|
|
164
|
+
if (!(val instanceof Uint8Array)) {
|
|
165
|
+
isBinary = false;
|
|
166
|
+
}
|
|
167
|
+
if (!(0, utils_1.isArrayOrTypedArray)(val) || val instanceof Uint8Array) {
|
|
146
168
|
isList = false;
|
|
147
169
|
}
|
|
148
170
|
else {
|
|
149
|
-
|
|
150
|
-
|
|
171
|
+
const valArr = val;
|
|
172
|
+
const subLen = valArr.length;
|
|
173
|
+
for (let j = 0; j < subLen; j++) {
|
|
174
|
+
allListElements.push(valArr[j]);
|
|
151
175
|
}
|
|
152
176
|
}
|
|
153
177
|
if (val instanceof Date)
|
|
@@ -167,9 +191,14 @@ function inferColumnType(col) {
|
|
|
167
191
|
if (!(val instanceof Date) && (typeof val !== "string" || isNaN(Date.parse(val)))) {
|
|
168
192
|
isDate = false;
|
|
169
193
|
}
|
|
194
|
+
if (!(0, utils_1.isObj)(val) || val instanceof Date || val instanceof Uint8Array || Array.isArray(val)) {
|
|
195
|
+
isObject = false;
|
|
196
|
+
}
|
|
170
197
|
}
|
|
171
198
|
if (!hasNonNull)
|
|
172
199
|
return datatypes_1.DataTypeRegistry.Utf8;
|
|
200
|
+
if (isBinary)
|
|
201
|
+
return datatypes_1.DataTypeRegistry.Binary;
|
|
173
202
|
if (isList) {
|
|
174
203
|
const innerType = inferColumnType(allListElements);
|
|
175
204
|
return datatypes_1.DataTypeRegistry.List(innerType);
|
|
@@ -195,6 +224,8 @@ function inferColumnType(col) {
|
|
|
195
224
|
}
|
|
196
225
|
if (isDate && hasDateObj)
|
|
197
226
|
return datatypes_1.DataTypeRegistry.Datetime;
|
|
227
|
+
if (isObject)
|
|
228
|
+
return datatypes_1.DataTypeRegistry.Object;
|
|
198
229
|
return datatypes_1.DataTypeRegistry.Utf8;
|
|
199
230
|
}
|
|
200
231
|
function gatherColumnsByIndices(columns, indices) {
|
|
@@ -205,7 +236,9 @@ function gatherColumnsByIndices(columns, indices) {
|
|
|
205
236
|
for (let j = 0; j < numKeys; j++) {
|
|
206
237
|
const k = keys[j];
|
|
207
238
|
const oldCol = columns[k];
|
|
208
|
-
const newCol =
|
|
239
|
+
const newCol = (0, utils_1.isTypedArray)(oldCol)
|
|
240
|
+
? new oldCol.constructor(newHeight)
|
|
241
|
+
: new Array(newHeight);
|
|
209
242
|
for (let idx = 0; idx < newHeight; idx++) {
|
|
210
243
|
newCol[idx] = oldCol[indices[idx]];
|
|
211
244
|
}
|
|
@@ -213,3 +246,62 @@ function gatherColumnsByIndices(columns, indices) {
|
|
|
213
246
|
}
|
|
214
247
|
return res;
|
|
215
248
|
}
|
|
249
|
+
/**
|
|
250
|
+
* Computes a hash string for a row at the given index, using one or more column keys.
|
|
251
|
+
* Includes a single-key fast path to avoid array allocation and join overhead.
|
|
252
|
+
*/
|
|
253
|
+
function computeRowHash(columns, keys, rowIndex) {
|
|
254
|
+
const len = keys.length;
|
|
255
|
+
if (len === 1) {
|
|
256
|
+
const val = columns[keys[0]][rowIndex];
|
|
257
|
+
return val == null ? "" : (0, utils_1.toCanonicalString)(val);
|
|
258
|
+
}
|
|
259
|
+
const vals = new Array(len);
|
|
260
|
+
for (let i = 0; i < len; i++) {
|
|
261
|
+
const val = columns[keys[i]][rowIndex];
|
|
262
|
+
vals[i] = val == null ? "" : (0, utils_1.toCanonicalString)(val);
|
|
263
|
+
}
|
|
264
|
+
return vals.join(constants_1.KEY_SEPARATOR);
|
|
265
|
+
}
|
|
266
|
+
function coerceColumn(col, type, height) {
|
|
267
|
+
let newCol = type.allocate ? type.allocate(height) : new Array(height);
|
|
268
|
+
const isTyped = (0, utils_1.isTypedArray)(newCol);
|
|
269
|
+
if (isTyped) {
|
|
270
|
+
const typedCol = newCol;
|
|
271
|
+
for (let i = 0; i < height; i++) {
|
|
272
|
+
const coerced = type.coerce(col[i]);
|
|
273
|
+
if (coerced == null) {
|
|
274
|
+
const fallback = new Array(height);
|
|
275
|
+
for (let j = 0; j < i; j++) {
|
|
276
|
+
fallback[j] = typedCol[j];
|
|
277
|
+
}
|
|
278
|
+
fallback[i] = null;
|
|
279
|
+
for (let j = i + 1; j < height; j++) {
|
|
280
|
+
fallback[j] = type.coerce(col[j]);
|
|
281
|
+
}
|
|
282
|
+
return fallback;
|
|
283
|
+
}
|
|
284
|
+
typedCol[i] = coerced;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
else {
|
|
288
|
+
for (let i = 0; i < height; i++) {
|
|
289
|
+
newCol[i] = type.coerce(col[i]);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
return newCol;
|
|
293
|
+
}
|
|
294
|
+
function writeStringToFileOrStream(file, content) {
|
|
295
|
+
if (!file)
|
|
296
|
+
return;
|
|
297
|
+
if (typeof file === "string") {
|
|
298
|
+
const fs = require("fs");
|
|
299
|
+
fs.writeFileSync(file, content, "utf8");
|
|
300
|
+
}
|
|
301
|
+
else if (typeof file === "object" && typeof file.write === "function") {
|
|
302
|
+
file.write(content);
|
|
303
|
+
}
|
|
304
|
+
else {
|
|
305
|
+
throw new TypeError("Invalid file argument. Expected a file path string or a writable stream/object with a write method.");
|
|
306
|
+
}
|
|
307
|
+
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
export declare abstract class DataType<T = any> {
|
|
2
2
|
abstract readonly name: string;
|
|
3
|
-
abstract coerce(val:
|
|
3
|
+
abstract coerce(val: unknown): T;
|
|
4
4
|
abstract equals(other: DataType): boolean;
|
|
5
5
|
abstract allocate(size: number): ArrayLike<T>;
|
|
6
|
+
matches(selector: any): boolean;
|
|
6
7
|
get isNumeric(): boolean;
|
|
7
8
|
get isInteger(): boolean;
|
|
8
9
|
get isFloat(): boolean;
|
|
@@ -2,6 +2,35 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.NestedDataType = exports.TemporalDataType = exports.FloatDataType = exports.UnsignedIntegerType = exports.SignedIntegerType = exports.IntegerDataType = exports.NumericDataType = exports.DataType = void 0;
|
|
4
4
|
class DataType {
|
|
5
|
+
matches(selector) {
|
|
6
|
+
if (selector == null)
|
|
7
|
+
return false;
|
|
8
|
+
if (selector instanceof DataType) {
|
|
9
|
+
if (this.equals(selector))
|
|
10
|
+
return true;
|
|
11
|
+
if (this.name.startsWith("Decimal") && selector.name.startsWith("Decimal")) {
|
|
12
|
+
if (selector.precision === undefined && selector.scale === undefined) {
|
|
13
|
+
return true;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
if (typeof selector === "function") {
|
|
19
|
+
if (selector.prototype instanceof DataType) {
|
|
20
|
+
return this instanceof selector;
|
|
21
|
+
}
|
|
22
|
+
try {
|
|
23
|
+
const dummy = selector();
|
|
24
|
+
if (dummy instanceof DataType) {
|
|
25
|
+
return this.constructor === dummy.constructor;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
// Ignore errors
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
5
34
|
get isNumeric() { return false; }
|
|
6
35
|
get isInteger() { return false; }
|
|
7
36
|
get isFloat() { return false; }
|
|
@@ -22,8 +22,8 @@ export declare const DataTypeRegistry: {
|
|
|
22
22
|
Duration: import("./types").DurationType;
|
|
23
23
|
Object: import("./types").ObjectType;
|
|
24
24
|
Null: import("./types").NullType;
|
|
25
|
-
List: <TInner>(inner: BaseDataType<TInner>) => import("./types").ListType<TInner>;
|
|
26
|
-
Struct: <TFields extends import("..").RowRecord>(fields: { [K in keyof TFields]: BaseDataType<TFields[K]>; }) => import("./types").StructType<TFields>;
|
|
25
|
+
List: <TInner>(inner: import("./types").RegisteredDataType & BaseDataType<TInner>) => import("./types").ListType<TInner>;
|
|
26
|
+
Struct: <TFields extends import("..").RowRecord>(fields: { [K in keyof TFields]: import("./types").RegisteredDataType & BaseDataType<TFields[K]>; }) => import("./types").StructType<TFields>;
|
|
27
27
|
};
|
|
28
28
|
export * from "./types";
|
|
29
29
|
export * from "./DataType";
|
|
@@ -2,70 +2,70 @@ import { DataType, SignedIntegerType, UnsignedIntegerType, FloatDataType, Tempor
|
|
|
2
2
|
import type { RowRecord } from "../types";
|
|
3
3
|
export declare class Int8Type extends SignedIntegerType {
|
|
4
4
|
readonly name = "Int8";
|
|
5
|
-
coerce(val:
|
|
5
|
+
coerce(val: unknown): number | null;
|
|
6
6
|
equals(other: DataType): boolean;
|
|
7
7
|
allocate(size: number): Int8Array;
|
|
8
8
|
}
|
|
9
9
|
export declare const Int8: Int8Type;
|
|
10
10
|
export declare class Int16Type extends SignedIntegerType {
|
|
11
11
|
readonly name = "Int16";
|
|
12
|
-
coerce(val:
|
|
12
|
+
coerce(val: unknown): number | null;
|
|
13
13
|
equals(other: DataType): boolean;
|
|
14
14
|
allocate(size: number): Int16Array;
|
|
15
15
|
}
|
|
16
16
|
export declare const Int16: Int16Type;
|
|
17
17
|
export declare class Int32Type extends SignedIntegerType {
|
|
18
18
|
readonly name = "Int32";
|
|
19
|
-
coerce(val:
|
|
19
|
+
coerce(val: unknown): number | null;
|
|
20
20
|
equals(other: DataType): boolean;
|
|
21
21
|
allocate(size: number): Int32Array;
|
|
22
22
|
}
|
|
23
23
|
export declare const Int32: Int32Type;
|
|
24
24
|
export declare class Int64Type extends SignedIntegerType<bigint | null> {
|
|
25
25
|
readonly name = "Int64";
|
|
26
|
-
coerce(val:
|
|
26
|
+
coerce(val: unknown): bigint | null;
|
|
27
27
|
equals(other: DataType): boolean;
|
|
28
28
|
allocate(size: number): BigInt64Array;
|
|
29
29
|
}
|
|
30
30
|
export declare const Int64: Int64Type;
|
|
31
31
|
export declare class UInt8Type extends UnsignedIntegerType {
|
|
32
32
|
readonly name = "UInt8";
|
|
33
|
-
coerce(val:
|
|
33
|
+
coerce(val: unknown): number | null;
|
|
34
34
|
equals(other: DataType): boolean;
|
|
35
35
|
allocate(size: number): Uint8Array;
|
|
36
36
|
}
|
|
37
37
|
export declare const UInt8: UInt8Type;
|
|
38
38
|
export declare class UInt16Type extends UnsignedIntegerType {
|
|
39
39
|
readonly name = "UInt16";
|
|
40
|
-
coerce(val:
|
|
40
|
+
coerce(val: unknown): number | null;
|
|
41
41
|
equals(other: DataType): boolean;
|
|
42
42
|
allocate(size: number): Uint16Array;
|
|
43
43
|
}
|
|
44
44
|
export declare const UInt16: UInt16Type;
|
|
45
45
|
export declare class UInt32Type extends UnsignedIntegerType {
|
|
46
46
|
readonly name = "UInt32";
|
|
47
|
-
coerce(val:
|
|
47
|
+
coerce(val: unknown): number | null;
|
|
48
48
|
equals(other: DataType): boolean;
|
|
49
49
|
allocate(size: number): Uint32Array;
|
|
50
50
|
}
|
|
51
51
|
export declare const UInt32: UInt32Type;
|
|
52
52
|
export declare class UInt64Type extends UnsignedIntegerType<bigint | null> {
|
|
53
53
|
readonly name = "UInt64";
|
|
54
|
-
coerce(val:
|
|
54
|
+
coerce(val: unknown): bigint | null;
|
|
55
55
|
equals(other: DataType): boolean;
|
|
56
56
|
allocate(size: number): BigUint64Array;
|
|
57
57
|
}
|
|
58
58
|
export declare const UInt64: UInt64Type;
|
|
59
59
|
export declare class Float32Type extends FloatDataType {
|
|
60
60
|
readonly name = "Float32";
|
|
61
|
-
coerce(val:
|
|
61
|
+
coerce(val: unknown): number | null;
|
|
62
62
|
equals(other: DataType): boolean;
|
|
63
63
|
allocate(size: number): Float32Array;
|
|
64
64
|
}
|
|
65
65
|
export declare const Float32: Float32Type;
|
|
66
66
|
export declare class Float64Type extends FloatDataType {
|
|
67
67
|
readonly name = "Float64";
|
|
68
|
-
coerce(val:
|
|
68
|
+
coerce(val: unknown): number | null;
|
|
69
69
|
equals(other: DataType): boolean;
|
|
70
70
|
allocate(size: number): Float64Array;
|
|
71
71
|
}
|
|
@@ -75,39 +75,39 @@ export declare class DecimalType extends NumericDataType {
|
|
|
75
75
|
readonly scale?: number | undefined;
|
|
76
76
|
readonly name: string;
|
|
77
77
|
constructor(precision?: number | undefined, scale?: number | undefined);
|
|
78
|
-
coerce(val:
|
|
78
|
+
coerce(val: unknown): number | null;
|
|
79
79
|
equals(other: DataType): boolean;
|
|
80
80
|
allocate(size: number): (number | null)[];
|
|
81
81
|
}
|
|
82
|
-
export declare class BooleanType extends DataType {
|
|
82
|
+
export declare class BooleanType extends DataType<boolean | null> {
|
|
83
83
|
readonly name = "Boolean";
|
|
84
84
|
get isBoolean(): boolean;
|
|
85
|
-
coerce(val:
|
|
85
|
+
coerce(val: unknown): boolean | null;
|
|
86
86
|
equals(other: DataType): boolean;
|
|
87
87
|
allocate(size: number): (boolean | null)[];
|
|
88
88
|
}
|
|
89
89
|
export declare const Boolean: BooleanType;
|
|
90
|
-
export declare class Utf8Type extends DataType {
|
|
90
|
+
export declare class Utf8Type extends DataType<string | null> {
|
|
91
91
|
readonly name = "Utf8";
|
|
92
92
|
get isString(): boolean;
|
|
93
93
|
get isUtf8(): boolean;
|
|
94
|
-
coerce(val:
|
|
94
|
+
coerce(val: unknown): string | null;
|
|
95
95
|
equals(other: DataType): boolean;
|
|
96
96
|
allocate(size: number): (string | null)[];
|
|
97
97
|
}
|
|
98
98
|
export declare const Utf8: Utf8Type;
|
|
99
|
-
export declare class BinaryType extends DataType {
|
|
99
|
+
export declare class BinaryType extends DataType<Uint8Array | null> {
|
|
100
100
|
readonly name = "Binary";
|
|
101
101
|
get isBinary(): boolean;
|
|
102
|
-
coerce(val:
|
|
102
|
+
coerce(val: unknown): Uint8Array | null;
|
|
103
103
|
equals(other: DataType): boolean;
|
|
104
104
|
allocate(size: number): (Uint8Array | null)[];
|
|
105
105
|
}
|
|
106
106
|
export declare const Binary: BinaryType;
|
|
107
|
-
export declare class NullType extends DataType {
|
|
107
|
+
export declare class NullType extends DataType<null> {
|
|
108
108
|
readonly name = "Null";
|
|
109
109
|
get isNull(): boolean;
|
|
110
|
-
coerce(_val:
|
|
110
|
+
coerce(_val: unknown): null;
|
|
111
111
|
equals(other: DataType): boolean;
|
|
112
112
|
allocate(size: number): null[];
|
|
113
113
|
}
|
|
@@ -115,58 +115,59 @@ export declare const Null: NullType;
|
|
|
115
115
|
export declare class ObjectType extends DataType {
|
|
116
116
|
readonly name = "Object";
|
|
117
117
|
get isObject(): boolean;
|
|
118
|
-
coerce(val:
|
|
118
|
+
coerce(val: unknown): any;
|
|
119
119
|
equals(other: DataType): boolean;
|
|
120
120
|
allocate(size: number): any[];
|
|
121
121
|
}
|
|
122
122
|
export declare const Object: ObjectType;
|
|
123
|
-
export declare class DateType extends TemporalDataType {
|
|
123
|
+
export declare class DateType extends TemporalDataType<Date | null> {
|
|
124
124
|
readonly name = "Date";
|
|
125
|
-
coerce(val:
|
|
125
|
+
coerce(val: unknown): Date | null;
|
|
126
126
|
equals(other: DataType): boolean;
|
|
127
127
|
allocate(size: number): (Date | null)[];
|
|
128
128
|
}
|
|
129
129
|
export declare const Date: DateType;
|
|
130
|
-
export declare class DatetimeType extends TemporalDataType {
|
|
130
|
+
export declare class DatetimeType extends TemporalDataType<Date | null> {
|
|
131
131
|
readonly name = "Datetime";
|
|
132
|
-
coerce(val:
|
|
132
|
+
coerce(val: unknown): Date | null;
|
|
133
133
|
equals(other: DataType): boolean;
|
|
134
134
|
allocate(size: number): (Date | null)[];
|
|
135
135
|
}
|
|
136
136
|
export declare const Datetime: DatetimeType;
|
|
137
|
-
export declare class TimeType extends TemporalDataType {
|
|
137
|
+
export declare class TimeType extends TemporalDataType<string | null> {
|
|
138
138
|
readonly name = "Time";
|
|
139
|
-
coerce(val:
|
|
139
|
+
coerce(val: unknown): string | null;
|
|
140
140
|
equals(other: DataType): boolean;
|
|
141
141
|
allocate(size: number): (string | null)[];
|
|
142
142
|
}
|
|
143
143
|
export declare const Time: TimeType;
|
|
144
|
-
export declare class DurationType extends TemporalDataType {
|
|
144
|
+
export declare class DurationType extends TemporalDataType<number | null> {
|
|
145
145
|
readonly name = "Duration";
|
|
146
|
-
coerce(val:
|
|
146
|
+
coerce(val: unknown): number | null;
|
|
147
147
|
equals(other: DataType): boolean;
|
|
148
148
|
allocate(size: number): (number | null)[];
|
|
149
149
|
}
|
|
150
150
|
export declare const Duration: DurationType;
|
|
151
151
|
export declare class ListType<TInner = any> extends NestedDataType<TInner[] | null> {
|
|
152
|
-
readonly innerType: DataType<TInner>;
|
|
152
|
+
readonly innerType: RegisteredDataType & DataType<TInner>;
|
|
153
153
|
readonly name = "List";
|
|
154
|
-
constructor(innerType: DataType<TInner>);
|
|
155
|
-
coerce(val:
|
|
154
|
+
constructor(innerType: RegisteredDataType & DataType<TInner>);
|
|
155
|
+
coerce(val: unknown): TInner[] | null;
|
|
156
156
|
equals(other: DataType): boolean;
|
|
157
157
|
allocate(size: number): (TInner[] | null)[];
|
|
158
158
|
}
|
|
159
|
-
export declare const List: <TInner>(inner: DataType<TInner>) => ListType<TInner>;
|
|
159
|
+
export declare const List: <TInner>(inner: RegisteredDataType & DataType<TInner>) => ListType<TInner>;
|
|
160
160
|
export declare class StructType<TFields extends RowRecord = any> extends NestedDataType<TFields | null> {
|
|
161
161
|
readonly fields: {
|
|
162
|
-
[K in keyof TFields]: DataType<TFields[K]>;
|
|
162
|
+
[K in keyof TFields]: RegisteredDataType & DataType<TFields[K]>;
|
|
163
163
|
};
|
|
164
164
|
readonly name = "Struct";
|
|
165
165
|
constructor(fields: {
|
|
166
|
-
[K in keyof TFields]: DataType<TFields[K]>;
|
|
166
|
+
[K in keyof TFields]: RegisteredDataType & DataType<TFields[K]>;
|
|
167
167
|
});
|
|
168
|
-
coerce(val:
|
|
168
|
+
coerce(val: unknown): TFields | null;
|
|
169
169
|
equals(other: DataType): boolean;
|
|
170
170
|
allocate(size: number): (TFields | null)[];
|
|
171
171
|
}
|
|
172
|
-
export declare const Struct: <TFields extends RowRecord>(fields: { [K in keyof TFields]: DataType<TFields[K]>; }) => StructType<TFields>;
|
|
172
|
+
export declare const Struct: <TFields extends RowRecord>(fields: { [K in keyof TFields]: RegisteredDataType & DataType<TFields[K]>; }) => StructType<TFields>;
|
|
173
|
+
export type RegisteredDataType = Int8Type | Int16Type | Int32Type | Int64Type | UInt8Type | UInt16Type | UInt32Type | UInt64Type | Float32Type | Float64Type | DecimalType | BooleanType | Utf8Type | BinaryType | NullType | ObjectType | DateType | DatetimeType | TimeType | DurationType | ListType<any> | StructType<any>;
|