tranfi 0.1.2 → 0.2.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/LICENSE +177 -0
- package/NOTICE +8 -0
- package/README.md +272 -40
- package/app/assets/{index-pDFMluyz.js → index-BIAIKnrp.js} +1 -1
- package/app/index.html +1 -1
- package/binding.gyp +55 -3
- package/csrc/arena.c +7 -5
- package/csrc/batch.c +818 -71
- package/csrc/buffer.c +84 -8
- package/csrc/cJSON.c +262 -19
- package/csrc/cJSON.h +17 -1
- package/csrc/codec_csv.c +1074 -181
- package/csrc/codec_jsonl.c +830 -118
- package/csrc/codec_table.c +108 -78
- package/csrc/codec_text.c +286 -68
- package/csrc/compiler.c +31 -3
- package/csrc/config.h +21 -0
- package/csrc/dsl.c +4722 -485
- package/csrc/expr.c +363 -55
- package/csrc/expr.h +2 -0
- package/csrc/internal.h +316 -27
- package/csrc/ir.c +65 -18
- package/csrc/ir.h +41 -0
- package/csrc/ir_schema.c +20 -5
- package/csrc/ir_serialize.c +68 -6
- package/csrc/ir_sql.c +796 -185
- package/csrc/ir_validate.c +462 -6
- package/csrc/json_path.c +210 -0
- package/csrc/main.c +879 -30
- package/csrc/memory_estimate.c +477 -0
- package/csrc/op_acf.c +171 -21
- package/csrc/op_across.c +477 -0
- package/csrc/op_anomaly.c +167 -32
- package/csrc/op_assert.c +761 -0
- package/csrc/op_bin.c +168 -29
- package/csrc/op_cast.c +383 -55
- package/csrc/op_clip.c +30 -19
- package/csrc/op_date_trunc.c +208 -34
- package/csrc/op_datetime.c +259 -77
- package/csrc/op_derive.c +65 -97
- package/csrc/op_diff.c +146 -30
- package/csrc/op_ewma.c +149 -30
- package/csrc/op_explode.c +124 -26
- package/csrc/op_fill_down.c +125 -53
- package/csrc/op_fill_null.c +176 -31
- package/csrc/op_filter.c +89 -40
- package/csrc/op_frequency.c +571 -43
- package/csrc/op_grep.c +36 -18
- package/csrc/op_group_agg.c +1790 -119
- package/csrc/op_hash.c +48 -15
- package/csrc/op_head.c +21 -86
- package/csrc/op_interpolate.c +268 -62
- package/csrc/op_join.c +2700 -182
- package/csrc/op_json_extract.c +227 -0
- package/csrc/op_json_filter.c +384 -0
- package/csrc/op_json_flatten.c +293 -0
- package/csrc/op_json_schema.c +503 -0
- package/csrc/op_label_encode.c +328 -53
- package/csrc/op_lag.c +181 -0
- package/csrc/op_lead.c +141 -89
- package/csrc/op_normalize.c +363 -79
- package/csrc/op_onehot.c +345 -73
- package/csrc/op_pivot.c +1546 -162
- package/csrc/op_quarantine.c +189 -0
- package/csrc/op_registry.c +2062 -166
- package/csrc/op_rename.c +41 -50
- package/csrc/op_replace.c +270 -118
- package/csrc/op_rleid.c +297 -0
- package/csrc/op_rowid.c +559 -0
- package/csrc/op_sample.c +80 -23
- package/csrc/op_schema.c +1341 -0
- package/csrc/op_schema_infer.c +252 -0
- package/csrc/op_select.c +265 -65
- package/csrc/op_set.c +3449 -0
- package/csrc/op_skip.c +30 -87
- package/csrc/op_sort.c +670 -124
- package/csrc/op_source_name.c +120 -0
- package/csrc/op_split.c +65 -28
- package/csrc/op_split_data.c +41 -9
- package/csrc/op_stack.c +178 -222
- package/csrc/op_stats.c +206 -110
- package/csrc/op_step.c +217 -55
- package/csrc/op_tail.c +21 -12
- package/csrc/op_tee.c +338 -0
- package/csrc/op_top.c +260 -53
- package/csrc/op_trim.c +48 -19
- package/csrc/op_unique.c +1193 -150
- package/csrc/op_unpivot.c +100 -66
- package/csrc/op_validate.c +601 -24
- package/csrc/op_window.c +492 -51
- package/csrc/path_policy.c +85 -0
- package/csrc/pipeline.c +872 -99
- package/csrc/recipes.c +3 -1
- package/csrc/report.c +73 -30
- package/csrc/selector.c +1097 -0
- package/csrc/size_utils.c +348 -0
- package/csrc/spill.c +317 -0
- package/csrc/spill.h +21 -0
- package/csrc/tranfi.h +169 -1
- package/csrc/transform.h +209 -0
- package/csrc/transform_api.c +2237 -0
- package/csrc/transform_categorical.c +923 -0
- package/csrc/transform_internal.h +472 -0
- package/csrc/transform_json.c +3812 -0
- package/csrc/transform_numeric.c +1966 -0
- package/csrc/transform_sha256.c +154 -0
- package/csrc/transform_wasm.h +162 -0
- package/csrc/transform_wasm_api.c +1373 -0
- package/csrc/wasm_api.c +70 -9
- package/napi_api.c +219 -11
- package/napi_transform.c +1648 -0
- package/napi_transform.h +8 -0
- package/package.json +27 -11
- package/scripts/install-native.js +76 -0
- package/scripts/prepack.js +64 -0
- package/scripts/sync-csrc.js +23 -0
- package/src/cli.js +8 -11
- package/src/engines/duckdb.js +45 -12
- package/src/index.js +661 -42
- package/src/memory_policy.js +411 -0
- package/src/native.js +1 -5
- package/src/pipeline.js +454 -31
- package/src/recipe_json.js +80 -0
- package/src/server.js +10 -8
- package/src/transform.js +403 -0
- package/src/transform_error.js +10 -0
- package/src/wasm.js +6 -4
- package/wasm/index.js +498 -10
- package/wasm/tranfi_core.js +0 -0
- package/wasm/transform.js +1156 -0
- package/wasm/worker.js +786 -0
- package/csrc/plan.c +0 -206
package/csrc/recipes.c
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* recipes.c — Built-in named recipes
|
|
2
|
+
* recipes.c — Built-in named recipes for common ETL pipelines.
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
#include "recipes.h"
|
|
@@ -20,6 +20,8 @@ static const recipe_entry recipes[] = {
|
|
|
20
20
|
"Quick preview of first 10 rows"},
|
|
21
21
|
{"schema", "csv | head 0 | csv",
|
|
22
22
|
"Show column names only"},
|
|
23
|
+
{"sniff", "csv | schema infer rows=1000 | csv",
|
|
24
|
+
"Bounded-memory schema/type/nullability sniff (sample 1000 rows)"},
|
|
23
25
|
{"summary", "csv | stats count,min,max,avg,stddev | csv",
|
|
24
26
|
"Summary statistics"},
|
|
25
27
|
{"count", "csv | stats count | csv",
|
package/csrc/report.c
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
#include "report.h"
|
|
9
|
+
#include "internal.h"
|
|
9
10
|
#include <stdlib.h>
|
|
10
11
|
#include <string.h>
|
|
11
12
|
#include <stdio.h>
|
|
@@ -27,41 +28,68 @@ typedef struct {
|
|
|
27
28
|
char *data;
|
|
28
29
|
size_t len;
|
|
29
30
|
size_t cap;
|
|
31
|
+
int failed;
|
|
30
32
|
} strbuf;
|
|
31
33
|
|
|
32
34
|
static void sb_init(strbuf *sb) {
|
|
33
35
|
sb->cap = 4096;
|
|
34
|
-
sb->data = malloc(sb->cap);
|
|
35
36
|
sb->len = 0;
|
|
36
|
-
|
|
37
|
+
sb->failed = 0;
|
|
38
|
+
sb->data = tf_mallocarray_checked(sb->cap, sizeof(char));
|
|
39
|
+
if (sb->data) {
|
|
40
|
+
sb->data[0] = '\0';
|
|
41
|
+
} else {
|
|
42
|
+
sb->cap = 0;
|
|
43
|
+
sb->failed = 1;
|
|
44
|
+
}
|
|
37
45
|
}
|
|
38
46
|
|
|
39
|
-
static
|
|
40
|
-
if (sb
|
|
41
|
-
|
|
42
|
-
|
|
47
|
+
static int sb_ensure(strbuf *sb, size_t extra) {
|
|
48
|
+
if (!sb || sb->failed) return -1;
|
|
49
|
+
size_t need;
|
|
50
|
+
if (tf_size_add(sb->len, extra, &need) != TF_OK ||
|
|
51
|
+
tf_size_add(need, 1, &need) != TF_OK) {
|
|
52
|
+
sb->failed = 1;
|
|
53
|
+
return -1;
|
|
54
|
+
}
|
|
55
|
+
if (need <= sb->cap) return 0;
|
|
56
|
+
size_t new_cap;
|
|
57
|
+
if (tf_size_grow_pow2(sb->cap, need, 4096, &new_cap) != TF_OK) {
|
|
58
|
+
sb->failed = 1;
|
|
59
|
+
return -1;
|
|
60
|
+
}
|
|
61
|
+
char *tmp = tf_reallocarray_checked(sb->data, new_cap, sizeof(char));
|
|
62
|
+
if (!tmp) {
|
|
63
|
+
sb->failed = 1;
|
|
64
|
+
return -1;
|
|
43
65
|
}
|
|
66
|
+
sb->data = tmp;
|
|
67
|
+
sb->cap = new_cap;
|
|
68
|
+
return 0;
|
|
44
69
|
}
|
|
45
70
|
|
|
46
71
|
static void sb_append(strbuf *sb, const char *s) {
|
|
72
|
+
if (!sb || sb->failed || !s) return;
|
|
47
73
|
size_t n = strlen(s);
|
|
48
|
-
sb_ensure(sb, n);
|
|
74
|
+
if (sb_ensure(sb, n) != 0) return;
|
|
49
75
|
memcpy(sb->data + sb->len, s, n);
|
|
50
76
|
sb->len += n;
|
|
51
77
|
sb->data[sb->len] = '\0';
|
|
52
78
|
}
|
|
53
79
|
|
|
54
80
|
static void sb_printf(strbuf *sb, const char *fmt, ...) {
|
|
81
|
+
if (!sb || sb->failed || !fmt) return;
|
|
55
82
|
va_list ap;
|
|
56
83
|
va_start(ap, fmt);
|
|
57
84
|
int needed = vsnprintf(NULL, 0, fmt, ap);
|
|
58
85
|
va_end(ap);
|
|
59
|
-
if (needed < 0) return;
|
|
60
|
-
sb_ensure(sb, (size_t)needed);
|
|
86
|
+
if (needed < 0) { sb->failed = 1; return; }
|
|
87
|
+
if (sb_ensure(sb, (size_t)needed) != 0) return;
|
|
61
88
|
va_start(ap, fmt);
|
|
62
|
-
vsnprintf(sb->data + sb->len, (size_t)needed + 1, fmt, ap);
|
|
89
|
+
int written = vsnprintf(sb->data + sb->len, (size_t)needed + 1, fmt, ap);
|
|
63
90
|
va_end(ap);
|
|
64
|
-
sb->
|
|
91
|
+
if (written < 0 || written > needed) { sb->failed = 1; return; }
|
|
92
|
+
sb->len += (size_t)written;
|
|
65
93
|
}
|
|
66
94
|
|
|
67
95
|
/* ---- Sparkline ---- */
|
|
@@ -90,6 +118,17 @@ typedef struct {
|
|
|
90
118
|
size_t n_rows;
|
|
91
119
|
} csv_table;
|
|
92
120
|
|
|
121
|
+
static void csv_free(csv_table *t);
|
|
122
|
+
|
|
123
|
+
static char *csv_field_copy(const char *start, size_t len) {
|
|
124
|
+
if (len > MAX_FIELD - 1) len = MAX_FIELD - 1;
|
|
125
|
+
char *field = tf_mallocarray_checked(len + 1, sizeof(char));
|
|
126
|
+
if (!field) return NULL;
|
|
127
|
+
if (len > 0) memcpy(field, start, len);
|
|
128
|
+
field[len] = '\0';
|
|
129
|
+
return field;
|
|
130
|
+
}
|
|
131
|
+
|
|
93
132
|
/* Find column index by name, -1 if not found */
|
|
94
133
|
static int csv_col(const csv_table *t, const char *name) {
|
|
95
134
|
for (size_t i = 0; i < t->n_cols; i++) {
|
|
@@ -99,9 +138,9 @@ static int csv_col(const csv_table *t, const char *name) {
|
|
|
99
138
|
return -1;
|
|
100
139
|
}
|
|
101
140
|
|
|
102
|
-
/* Parse
|
|
141
|
+
/* Parse the bounded stats CSV format, including quoted comma-containing fields. */
|
|
103
142
|
static csv_table *csv_parse(const char *csv, size_t len) {
|
|
104
|
-
csv_table *t =
|
|
143
|
+
csv_table *t = tf_callocarray_checked(1, sizeof(csv_table));
|
|
105
144
|
if (!t) return NULL;
|
|
106
145
|
|
|
107
146
|
const char *p = csv;
|
|
@@ -112,13 +151,13 @@ static csv_table *csv_parse(const char *csv, size_t len) {
|
|
|
112
151
|
const char *start = p;
|
|
113
152
|
while (p < end && *p != ',' && *p != '\n' && *p != '\r') p++;
|
|
114
153
|
size_t flen = (size_t)(p - start);
|
|
115
|
-
if (flen > MAX_FIELD - 1) flen = MAX_FIELD - 1;
|
|
116
154
|
if (t->n_cols < MAX_COLS) {
|
|
117
|
-
|
|
118
|
-
if (
|
|
119
|
-
|
|
120
|
-
|
|
155
|
+
char *field = csv_field_copy(start, flen);
|
|
156
|
+
if (!field) {
|
|
157
|
+
csv_free(t);
|
|
158
|
+
return NULL;
|
|
121
159
|
}
|
|
160
|
+
t->headers[t->n_cols] = field;
|
|
122
161
|
t->n_cols++;
|
|
123
162
|
}
|
|
124
163
|
if (p < end && *p == ',') p++;
|
|
@@ -139,13 +178,13 @@ static csv_table *csv_parse(const char *csv, size_t len) {
|
|
|
139
178
|
start = p;
|
|
140
179
|
while (p < end && *p != '"') p++;
|
|
141
180
|
size_t flen = (size_t)(p - start);
|
|
142
|
-
if (flen > MAX_FIELD - 1) flen = MAX_FIELD - 1;
|
|
143
181
|
if (ci < MAX_COLS) {
|
|
144
|
-
|
|
145
|
-
if (
|
|
146
|
-
|
|
147
|
-
|
|
182
|
+
char *field = csv_field_copy(start, flen);
|
|
183
|
+
if (!field) {
|
|
184
|
+
csv_free(t);
|
|
185
|
+
return NULL;
|
|
148
186
|
}
|
|
187
|
+
t->cells[t->n_rows][ci] = field;
|
|
149
188
|
}
|
|
150
189
|
if (p < end && *p == '"') p++; /* skip closing quote */
|
|
151
190
|
if (p < end && *p == ',') p++;
|
|
@@ -154,13 +193,13 @@ static csv_table *csv_parse(const char *csv, size_t len) {
|
|
|
154
193
|
}
|
|
155
194
|
while (p < end && *p != ',' && *p != '\n' && *p != '\r') p++;
|
|
156
195
|
size_t flen = (size_t)(p - start);
|
|
157
|
-
if (flen > MAX_FIELD - 1) flen = MAX_FIELD - 1;
|
|
158
196
|
if (ci < MAX_COLS) {
|
|
159
|
-
|
|
160
|
-
if (
|
|
161
|
-
|
|
162
|
-
|
|
197
|
+
char *field = csv_field_copy(start, flen);
|
|
198
|
+
if (!field) {
|
|
199
|
+
csv_free(t);
|
|
200
|
+
return NULL;
|
|
163
201
|
}
|
|
202
|
+
t->cells[t->n_rows][ci] = field;
|
|
164
203
|
}
|
|
165
204
|
if (p < end && *p == ',') p++;
|
|
166
205
|
ci++;
|
|
@@ -176,7 +215,7 @@ static csv_table *csv_parse(const char *csv, size_t len) {
|
|
|
176
215
|
static void csv_free(csv_table *t) {
|
|
177
216
|
if (!t) return;
|
|
178
217
|
for (size_t i = 0; i < t->n_cols; i++) free(t->headers[i]);
|
|
179
|
-
for (size_t r = 0; r <
|
|
218
|
+
for (size_t r = 0; r < MAX_ROWS; r++)
|
|
180
219
|
for (size_t c = 0; c < t->n_cols; c++)
|
|
181
220
|
free(t->cells[r][c]);
|
|
182
221
|
free(t);
|
|
@@ -293,7 +332,7 @@ char *tf_report_format(const char *stats_csv, size_t stats_len, int use_color) {
|
|
|
293
332
|
|
|
294
333
|
strbuf sb;
|
|
295
334
|
sb_init(&sb);
|
|
296
|
-
if (
|
|
335
|
+
if (sb.failed) { csv_free(t); return NULL; }
|
|
297
336
|
|
|
298
337
|
/* Header */
|
|
299
338
|
long long total_count = 0;
|
|
@@ -459,5 +498,9 @@ char *tf_report_format(const char *stats_csv, size_t stats_len, int use_color) {
|
|
|
459
498
|
|
|
460
499
|
csv_free(t);
|
|
461
500
|
|
|
501
|
+
if (sb.failed) {
|
|
502
|
+
free(sb.data);
|
|
503
|
+
return NULL;
|
|
504
|
+
}
|
|
462
505
|
return sb.data;
|
|
463
506
|
}
|