@milaboratories/pf-driver 1.0.43 → 1.0.45
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/driver_decl.d.ts +2 -2
- package/dist/driver_decl.d.ts.map +1 -1
- package/dist/driver_impl.cjs +73 -147
- package/dist/driver_impl.cjs.map +1 -1
- package/dist/driver_impl.d.ts +2 -2
- package/dist/driver_impl.d.ts.map +1 -1
- package/dist/driver_impl.js +72 -146
- package/dist/driver_impl.js.map +1 -1
- package/dist/ptable_pool.cjs +1 -2
- package/dist/ptable_pool.cjs.map +1 -1
- package/dist/ptable_pool.js +1 -2
- package/dist/ptable_pool.js.map +1 -1
- package/dist/ptable_shared.cjs.map +1 -1
- package/dist/ptable_shared.d.ts +2 -2
- package/dist/ptable_shared.js.map +1 -1
- package/package.json +7 -7
- package/src/driver_decl.ts +2 -1
- package/src/driver_double.test.ts +144 -27
- package/src/driver_impl.ts +87 -150
- package/src/ptable_pool.ts +1 -2
- package/src/ptable_shared.ts +2 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@milaboratories/pf-driver",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.45",
|
|
4
4
|
"description": "PFrameDriver implementation abstracted from Middle Layer",
|
|
5
5
|
"keywords": [],
|
|
6
6
|
"license": "UNLICENSED",
|
|
@@ -20,22 +20,22 @@
|
|
|
20
20
|
}
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@milaboratories/pframes-rs-node": "1.1.
|
|
24
|
-
"@milaboratories/pframes-rs-wasm": "0.1.
|
|
23
|
+
"@milaboratories/pframes-rs-node": "1.1.3",
|
|
24
|
+
"@milaboratories/pframes-rs-wasm": "0.1.2",
|
|
25
25
|
"es-toolkit": "^1.39.10",
|
|
26
26
|
"lru-cache": "^11.2.2",
|
|
27
|
+
"@platforma-sdk/model": "1.54.7",
|
|
27
28
|
"@milaboratories/ts-helpers": "1.7.2",
|
|
28
|
-
"@
|
|
29
|
-
"@milaboratories/pl-model-middle-layer": "1.11.7"
|
|
29
|
+
"@milaboratories/pl-model-middle-layer": "1.11.9"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
32
|
"@types/node": "~24.5.2",
|
|
33
33
|
"@vitest/coverage-istanbul": "^4.0.16",
|
|
34
34
|
"typescript": "~5.6.3",
|
|
35
35
|
"vitest": "^4.0.16",
|
|
36
|
-
"@milaboratories/build-configs": "1.4.
|
|
36
|
+
"@milaboratories/build-configs": "1.4.4",
|
|
37
37
|
"@milaboratories/ts-configs": "1.2.1",
|
|
38
|
-
"@milaboratories/ts-builder": "1.2.
|
|
38
|
+
"@milaboratories/ts-builder": "1.2.10"
|
|
39
39
|
},
|
|
40
40
|
"engines": {
|
|
41
41
|
"node": ">=22.19.0"
|
package/src/driver_decl.ts
CHANGED
|
@@ -7,6 +7,7 @@ import type {
|
|
|
7
7
|
PFrameHandle,
|
|
8
8
|
PObjectId,
|
|
9
9
|
PTableDef,
|
|
10
|
+
PTableDefV2,
|
|
10
11
|
PTableHandle,
|
|
11
12
|
PTableShape,
|
|
12
13
|
PTableVector,
|
|
@@ -40,7 +41,7 @@ export interface AbstractInternalPFrameDriver<PColumnData> extends PFrameDriver,
|
|
|
40
41
|
createPTable(def: PTableDef<PColumn<PColumnData>>): PoolEntry<PTableHandle>;
|
|
41
42
|
|
|
42
43
|
/** Create a new PTable by new Pframe-rs api */
|
|
43
|
-
createPTableV2(def:
|
|
44
|
+
createPTableV2(def: PTableDefV2<PColumn<PColumnData>>): PoolEntry<PTableHandle>;
|
|
44
45
|
|
|
45
46
|
/** Calculates data for the table and returns complete data representation of it */
|
|
46
47
|
calculateTableData(
|
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
2
|
pTableValue,
|
|
3
|
+
canonicalizeJson,
|
|
4
|
+
filterSpecToSpecQueryExpr,
|
|
3
5
|
type CalculateTableDataResponse,
|
|
4
6
|
type PFrameDriver,
|
|
5
7
|
type PObjectId,
|
|
8
|
+
type PTableColumnId,
|
|
9
|
+
type SpecQuery,
|
|
10
|
+
type SpecQueryExpression,
|
|
11
|
+
SpecQueryBooleanExpression,
|
|
6
12
|
} from "@platforma-sdk/model";
|
|
7
13
|
import { readJson, PFrameInternal } from "@milaboratories/pl-model-middle-layer";
|
|
8
14
|
import { test } from "vitest";
|
|
@@ -143,7 +149,7 @@ test.for([{ testCase: "01_json" }, { testCase: "02_binary" }, { testCase: "03_pa
|
|
|
143
149
|
},
|
|
144
150
|
);
|
|
145
151
|
|
|
146
|
-
test
|
|
152
|
+
test("createTableV2 support", async ({ expect }) => {
|
|
147
153
|
await using driver = await createPFrameDriverDouble({});
|
|
148
154
|
|
|
149
155
|
const columnId = "column1" as PObjectId;
|
|
@@ -159,33 +165,144 @@ test.skip("createTableV2 support", async ({ expect }) => {
|
|
|
159
165
|
valueType: "Int" as const,
|
|
160
166
|
};
|
|
161
167
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
168
|
+
const axisColumnStr = canonicalizeJson<PTableColumnId>({
|
|
169
|
+
type: "axis",
|
|
170
|
+
id: { name: "axis1", type: "String" },
|
|
171
|
+
}) as string;
|
|
172
|
+
|
|
173
|
+
const valueColumnStr = canonicalizeJson<PTableColumnId>({
|
|
174
|
+
type: "column",
|
|
175
|
+
id: columnId,
|
|
176
|
+
}) as string;
|
|
177
|
+
|
|
178
|
+
const inlineData = [
|
|
179
|
+
{ key: ["a"], val: 10 },
|
|
180
|
+
{ key: ["b"], val: 20 },
|
|
181
|
+
{ key: ["c"], val: 30 },
|
|
182
|
+
{ key: ["d"], val: 5 },
|
|
183
|
+
];
|
|
184
|
+
|
|
185
|
+
const column = { id: columnId, spec: columnSpec, data: inlineData };
|
|
186
|
+
|
|
187
|
+
const columnRef: SpecQueryExpression = { type: "columnRef", value: columnId };
|
|
188
|
+
|
|
189
|
+
const baseQuery: SpecQuery<typeof column> = { type: "column", column };
|
|
190
|
+
|
|
191
|
+
const uiDriver: PFrameDriver = driver;
|
|
192
|
+
|
|
193
|
+
// --- No filters, no sorting ---
|
|
194
|
+
{
|
|
195
|
+
using pTable = driver.createPTableV2({
|
|
196
|
+
query: baseQuery,
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
const shape = await uiDriver.getShape(pTable.key);
|
|
200
|
+
expect(shape.rows).toBe(4);
|
|
201
|
+
expect(shape.columns).toBe(2); // 1 axis + 1 value column
|
|
202
|
+
|
|
203
|
+
const data = await uiDriver.getData(pTable.key, [0, 1]);
|
|
204
|
+
expect(data[0].type).toBe("String");
|
|
205
|
+
expect([...data[0].data]).toEqual(["a", "b", "c", "d"]);
|
|
206
|
+
expect(data[1].type).toBe("Int");
|
|
207
|
+
expect([...data[1].data]).toEqual([10, 20, 30, 5]);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// --- With patternEquals filter on axis ---
|
|
211
|
+
{
|
|
212
|
+
using pTable = driver.createPTableV2({
|
|
213
|
+
query: {
|
|
214
|
+
type: "filter",
|
|
215
|
+
input: baseQuery,
|
|
216
|
+
predicate: filterSpecToSpecQueryExpr({
|
|
217
|
+
type: "patternEquals",
|
|
218
|
+
column: axisColumnStr,
|
|
219
|
+
value: "b",
|
|
220
|
+
}) as SpecQueryBooleanExpression,
|
|
221
|
+
},
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
const shape = await uiDriver.getShape(pTable.key);
|
|
225
|
+
expect(shape.rows).toBe(1);
|
|
226
|
+
|
|
227
|
+
const data = await uiDriver.getData(pTable.key, [0, 1]);
|
|
228
|
+
expect([...data[0].data]).toEqual(["b"]);
|
|
229
|
+
expect([...data[1].data]).toEqual([20]);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// --- With greaterThan filter on value column ---
|
|
233
|
+
{
|
|
234
|
+
using pTable = driver.createPTableV2({
|
|
235
|
+
query: {
|
|
236
|
+
type: "filter",
|
|
237
|
+
input: baseQuery,
|
|
238
|
+
predicate: filterSpecToSpecQueryExpr({
|
|
239
|
+
type: "greaterThan",
|
|
240
|
+
column: valueColumnStr,
|
|
241
|
+
x: 15,
|
|
242
|
+
}) as SpecQueryBooleanExpression,
|
|
243
|
+
},
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
const shape = await uiDriver.getShape(pTable.key);
|
|
247
|
+
expect(shape.rows).toBe(2);
|
|
248
|
+
|
|
249
|
+
const data = await uiDriver.getData(pTable.key, [0, 1]);
|
|
250
|
+
expect([...data[0].data]).toEqual(["b", "c"]);
|
|
251
|
+
expect([...data[1].data]).toEqual([20, 30]);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// --- With sorting descending by value column ---
|
|
255
|
+
{
|
|
256
|
+
using pTable = driver.createPTableV2({
|
|
257
|
+
query: {
|
|
258
|
+
type: "sort",
|
|
259
|
+
input: baseQuery,
|
|
260
|
+
sortBy: [
|
|
261
|
+
{
|
|
262
|
+
expression: columnRef,
|
|
263
|
+
ascending: false,
|
|
264
|
+
nullsFirst: true,
|
|
265
|
+
},
|
|
171
266
|
],
|
|
172
267
|
},
|
|
173
|
-
}
|
|
174
|
-
partitionFilters: [],
|
|
175
|
-
filters: [],
|
|
176
|
-
sorting: [],
|
|
177
|
-
});
|
|
268
|
+
});
|
|
178
269
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
270
|
+
const data = await uiDriver.getData(pTable.key, [0, 1]);
|
|
271
|
+
expect([...data[0].data]).toEqual(["c", "b", "a", "d"]);
|
|
272
|
+
expect([...data[1].data]).toEqual([30, 20, 10, 5]);
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
// --- With combined filter + sorting ---
|
|
276
|
+
{
|
|
277
|
+
using pTable = driver.createPTableV2({
|
|
278
|
+
query: {
|
|
279
|
+
type: "sort",
|
|
280
|
+
input: {
|
|
281
|
+
type: "filter",
|
|
282
|
+
input: baseQuery,
|
|
283
|
+
predicate: filterSpecToSpecQueryExpr({
|
|
284
|
+
type: "and",
|
|
285
|
+
filters: [
|
|
286
|
+
{ type: "greaterThan", column: valueColumnStr, x: 5 },
|
|
287
|
+
{ type: "patternNotEquals", column: axisColumnStr, value: "c" },
|
|
288
|
+
],
|
|
289
|
+
}) as SpecQueryBooleanExpression,
|
|
290
|
+
},
|
|
291
|
+
sortBy: [
|
|
292
|
+
{
|
|
293
|
+
expression: columnRef,
|
|
294
|
+
ascending: false,
|
|
295
|
+
nullsFirst: true,
|
|
296
|
+
},
|
|
297
|
+
],
|
|
298
|
+
},
|
|
299
|
+
});
|
|
300
|
+
|
|
301
|
+
const shape = await uiDriver.getShape(pTable.key);
|
|
302
|
+
expect(shape.rows).toBe(2);
|
|
303
|
+
|
|
304
|
+
const data = await uiDriver.getData(pTable.key, [0, 1]);
|
|
305
|
+
expect([...data[0].data]).toEqual(["b", "a"]);
|
|
306
|
+
expect([...data[1].data]).toEqual([20, 10]);
|
|
307
|
+
}
|
|
191
308
|
});
|
package/src/driver_impl.ts
CHANGED
|
@@ -3,7 +3,6 @@ import {
|
|
|
3
3
|
mapPTableDef,
|
|
4
4
|
extractAllColumns,
|
|
5
5
|
uniqueBy,
|
|
6
|
-
getAxisId,
|
|
7
6
|
canonicalizeJson,
|
|
8
7
|
bigintReplacer,
|
|
9
8
|
ValueType,
|
|
@@ -24,11 +23,16 @@ import {
|
|
|
24
23
|
type UniqueValuesResponse,
|
|
25
24
|
type PColumn,
|
|
26
25
|
type PFrameDef,
|
|
27
|
-
type JoinEntry,
|
|
28
26
|
type PTableDef,
|
|
29
27
|
type PTableRecordSingleValueFilterV2,
|
|
30
28
|
type PTableRecordFilter,
|
|
31
29
|
type JsonSerializable,
|
|
30
|
+
type PTableDefV2,
|
|
31
|
+
type SpecQuery,
|
|
32
|
+
mapQuerySpec,
|
|
33
|
+
collectQueryColumns,
|
|
34
|
+
sortQuerySpec,
|
|
35
|
+
sortPTableDef,
|
|
32
36
|
} from "@platforma-sdk/model";
|
|
33
37
|
import type { PFrameInternal } from "@milaboratories/pl-model-middle-layer";
|
|
34
38
|
import {
|
|
@@ -57,9 +61,8 @@ import {
|
|
|
57
61
|
PTableCachePlainOpsDefaults,
|
|
58
62
|
type PTableCachePlainOps,
|
|
59
63
|
} from "./ptable_cache_plain";
|
|
60
|
-
|
|
64
|
+
import { createPFrame as createSpecFrame } from "@milaboratories/pframes-rs-wasm";
|
|
61
65
|
|
|
62
|
-
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
|
63
66
|
export interface LocalBlobProvider<
|
|
64
67
|
TreeEntry extends JsonSerializable,
|
|
65
68
|
> extends PoolLocalBlobProvider<TreeEntry> {}
|
|
@@ -206,50 +209,47 @@ export class AbstractPFrameDriver<
|
|
|
206
209
|
};
|
|
207
210
|
}
|
|
208
211
|
|
|
209
|
-
public createPTableV2(
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
// unref,
|
|
251
|
-
// [Symbol.dispose]: unref,
|
|
252
|
-
// };
|
|
212
|
+
public createPTableV2(def: PTableDefV2<PColumn<PColumnData>>): PoolEntry<PTableHandle> {
|
|
213
|
+
const columns = uniqueBy(collectQueryColumns(def.query), (c) => c.id);
|
|
214
|
+
const columnsMap = columns.reduce(
|
|
215
|
+
(acc, col) => ((acc[col.id] = col.spec), acc),
|
|
216
|
+
{} as Record<string, PColumnSpec>,
|
|
217
|
+
);
|
|
218
|
+
|
|
219
|
+
const pFrameEntry = this.createPFrame(columns);
|
|
220
|
+
const specFrame = createSpecFrame(columnsMap);
|
|
221
|
+
const sortedQuery = sortQuerySpec(mapQuerySpec(def.query, (c) => c.id));
|
|
222
|
+
const { tableSpec, dataQuery } = specFrame.evaluateQuery(
|
|
223
|
+
// WASM crate expects `columnId` field name, our types use `column`
|
|
224
|
+
// @todo: remove it after update wasm package
|
|
225
|
+
querySpecToWasm(sortedQuery) as SpecQuery,
|
|
226
|
+
);
|
|
227
|
+
|
|
228
|
+
const pTableEntry = this.pTableDefs.acquire({
|
|
229
|
+
type: "v2",
|
|
230
|
+
pFrameHandle: pFrameEntry.key,
|
|
231
|
+
def: {
|
|
232
|
+
tableSpec,
|
|
233
|
+
dataQuery,
|
|
234
|
+
},
|
|
235
|
+
});
|
|
236
|
+
if (logPFrames()) {
|
|
237
|
+
this.logger(
|
|
238
|
+
"info",
|
|
239
|
+
`Create PTable call (pFrameHandle = ${pFrameEntry.key}; pTableHandle = ${pTableEntry.key})`,
|
|
240
|
+
);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
const unref = () => {
|
|
244
|
+
pTableEntry.unref();
|
|
245
|
+
pFrameEntry.unref();
|
|
246
|
+
};
|
|
247
|
+
return {
|
|
248
|
+
key: pTableEntry.key,
|
|
249
|
+
resource: pTableEntry.resource,
|
|
250
|
+
unref,
|
|
251
|
+
[Symbol.dispose]: unref,
|
|
252
|
+
};
|
|
253
253
|
}
|
|
254
254
|
|
|
255
255
|
//
|
|
@@ -459,110 +459,47 @@ export class AbstractPFrameDriver<
|
|
|
459
459
|
}
|
|
460
460
|
}
|
|
461
461
|
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
return lhs.newId < (rhs as typeof lhs).newId ? -1 : 1;
|
|
474
|
-
case "inlineColumn": {
|
|
475
|
-
return lhs.column.id < (rhs as typeof lhs).column.id ? -1 : 1;
|
|
476
|
-
}
|
|
477
|
-
case "inner":
|
|
478
|
-
case "full": {
|
|
479
|
-
const rhsInner = rhs as typeof lhs;
|
|
480
|
-
if (lhs.entries.length !== rhsInner.entries.length) {
|
|
481
|
-
return lhs.entries.length - rhsInner.entries.length;
|
|
482
|
-
}
|
|
483
|
-
for (let i = 0; i < lhs.entries.length; i++) {
|
|
484
|
-
const cmp = cmpJoinEntries(lhs.entries[i], rhsInner.entries[i]);
|
|
485
|
-
if (cmp !== 0) {
|
|
486
|
-
return cmp;
|
|
487
|
-
}
|
|
488
|
-
}
|
|
489
|
-
return 0;
|
|
490
|
-
}
|
|
491
|
-
case "outer": {
|
|
492
|
-
const rhsOuter = rhs as typeof lhs;
|
|
493
|
-
const cmp = cmpJoinEntries(lhs.primary, rhsOuter.primary);
|
|
494
|
-
if (cmp !== 0) {
|
|
495
|
-
return cmp;
|
|
496
|
-
}
|
|
497
|
-
if (lhs.secondary.length !== rhsOuter.secondary.length) {
|
|
498
|
-
return lhs.secondary.length - rhsOuter.secondary.length;
|
|
499
|
-
}
|
|
500
|
-
for (let i = 0; i < lhs.secondary.length; i++) {
|
|
501
|
-
const cmp = cmpJoinEntries(lhs.secondary[i], rhsOuter.secondary[i]);
|
|
502
|
-
if (cmp !== 0) {
|
|
503
|
-
return cmp;
|
|
504
|
-
}
|
|
505
|
-
}
|
|
506
|
-
return 0;
|
|
507
|
-
}
|
|
508
|
-
default:
|
|
509
|
-
assertNever(type);
|
|
462
|
+
/**
|
|
463
|
+
* Converts a SpecQuery to the format expected by the WASM crate.
|
|
464
|
+
* Renames `column` → `columnId` in leaf nodes (QueryColumn, QuerySparseToDenseColumn).
|
|
465
|
+
*/
|
|
466
|
+
function querySpecToWasm(query: SpecQuery): unknown {
|
|
467
|
+
switch (query.type) {
|
|
468
|
+
case "column":
|
|
469
|
+
return { type: "column", columnId: query.column };
|
|
470
|
+
case "sparseToDenseColumn": {
|
|
471
|
+
const { column, ...rest } = query;
|
|
472
|
+
return { ...rest, columnId: column };
|
|
510
473
|
}
|
|
474
|
+
case "inlineColumn":
|
|
475
|
+
return query;
|
|
476
|
+
case "innerJoin":
|
|
477
|
+
case "fullJoin":
|
|
478
|
+
return {
|
|
479
|
+
...query,
|
|
480
|
+
entries: query.entries.map((e) => ({
|
|
481
|
+
...e,
|
|
482
|
+
entry: querySpecToWasm(e.entry),
|
|
483
|
+
})),
|
|
484
|
+
};
|
|
485
|
+
case "outerJoin":
|
|
486
|
+
return {
|
|
487
|
+
...query,
|
|
488
|
+
primary: { ...query.primary, entry: querySpecToWasm(query.primary.entry) },
|
|
489
|
+
secondary: query.secondary.map((e) => ({
|
|
490
|
+
...e,
|
|
491
|
+
entry: querySpecToWasm(e.entry),
|
|
492
|
+
})),
|
|
493
|
+
};
|
|
494
|
+
case "filter":
|
|
495
|
+
return { ...query, input: querySpecToWasm(query.input) };
|
|
496
|
+
case "sort":
|
|
497
|
+
return { ...query, input: querySpecToWasm(query.input) };
|
|
498
|
+
case "sliceAxes":
|
|
499
|
+
return { ...query, input: querySpecToWasm(query.input) };
|
|
500
|
+
default:
|
|
501
|
+
assertNever(query);
|
|
511
502
|
}
|
|
512
|
-
function sortJoinEntry(entry: JoinEntry<PObjectId>): JoinEntry<PObjectId> {
|
|
513
|
-
switch (entry.type) {
|
|
514
|
-
case "column":
|
|
515
|
-
case "slicedColumn":
|
|
516
|
-
case "inlineColumn":
|
|
517
|
-
return entry;
|
|
518
|
-
case "artificialColumn": {
|
|
519
|
-
const sortedAxesIndices = entry.axesIndices.toSorted((lhs, rhs) => lhs - rhs);
|
|
520
|
-
return {
|
|
521
|
-
...entry,
|
|
522
|
-
axesIndices: sortedAxesIndices,
|
|
523
|
-
};
|
|
524
|
-
}
|
|
525
|
-
case "inner":
|
|
526
|
-
case "full": {
|
|
527
|
-
const sortedEntries = entry.entries.map(sortJoinEntry);
|
|
528
|
-
sortedEntries.sort(cmpJoinEntries);
|
|
529
|
-
return {
|
|
530
|
-
...entry,
|
|
531
|
-
entries: sortedEntries,
|
|
532
|
-
};
|
|
533
|
-
}
|
|
534
|
-
case "outer": {
|
|
535
|
-
const sortedSecondary = entry.secondary.map(sortJoinEntry);
|
|
536
|
-
sortedSecondary.sort(cmpJoinEntries);
|
|
537
|
-
return {
|
|
538
|
-
...entry,
|
|
539
|
-
primary: sortJoinEntry(entry.primary),
|
|
540
|
-
secondary: sortedSecondary,
|
|
541
|
-
};
|
|
542
|
-
}
|
|
543
|
-
default:
|
|
544
|
-
assertNever(entry);
|
|
545
|
-
}
|
|
546
|
-
}
|
|
547
|
-
function sortFilters(filters: PTableRecordFilter[]): PTableRecordFilter[] {
|
|
548
|
-
return filters.toSorted((lhs, rhs) => {
|
|
549
|
-
if (lhs.column.type === "axis" && rhs.column.type === "axis") {
|
|
550
|
-
const lhsId = canonicalizeJson(getAxisId(lhs.column.id));
|
|
551
|
-
const rhsId = canonicalizeJson(getAxisId(rhs.column.id));
|
|
552
|
-
return lhsId < rhsId ? -1 : 1;
|
|
553
|
-
} else if (lhs.column.type === "column" && rhs.column.type === "column") {
|
|
554
|
-
return lhs.column.id < rhs.column.id ? -1 : 1;
|
|
555
|
-
} else {
|
|
556
|
-
return lhs.column.type === "axis" ? -1 : 1;
|
|
557
|
-
}
|
|
558
|
-
});
|
|
559
|
-
}
|
|
560
|
-
return {
|
|
561
|
-
src: sortJoinEntry(def.src),
|
|
562
|
-
partitionFilters: sortFilters(def.partitionFilters),
|
|
563
|
-
filters: sortFilters(def.filters),
|
|
564
|
-
sorting: def.sorting,
|
|
565
|
-
};
|
|
566
503
|
}
|
|
567
504
|
|
|
568
505
|
function migrateFilters(
|
package/src/ptable_pool.ts
CHANGED
|
@@ -152,7 +152,7 @@ export class PTablePool<TreeEntry extends JsonSerializable> extends RefCountPool
|
|
|
152
152
|
const defDisposeSignal = this.pTableDefs.tryGetByKey(key)?.disposeSignal;
|
|
153
153
|
const combinedSignal = AbortSignal.any([disposeSignal, defDisposeSignal].filter((s) => !!s));
|
|
154
154
|
|
|
155
|
-
const table = pFramePromise.then((pFrame) => pFrame.
|
|
155
|
+
const table = pFramePromise.then((pFrame) => pFrame.createTableV2(key, params.def));
|
|
156
156
|
return new PTableHolder(pFrameHandle, combinedSignal, table);
|
|
157
157
|
}
|
|
158
158
|
|
|
@@ -237,7 +237,6 @@ function joinEntryToInternal(entry: JoinEntry<PObjectId>): PFrameInternal.JoinEn
|
|
|
237
237
|
secondary: entry.secondary.map((col) => joinEntryToInternal(col)),
|
|
238
238
|
};
|
|
239
239
|
default:
|
|
240
|
-
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
|
241
240
|
throw new PFrameDriverError(`unsupported PFrame join entry type: ${type satisfies never}`);
|
|
242
241
|
}
|
|
243
242
|
}
|
package/src/ptable_shared.ts
CHANGED
|
@@ -3,7 +3,7 @@ import type {
|
|
|
3
3
|
PFrameHandle,
|
|
4
4
|
PTableDef,
|
|
5
5
|
PTableHandle,
|
|
6
|
-
|
|
6
|
+
DataQuery,
|
|
7
7
|
PTableColumnSpec,
|
|
8
8
|
} from "@platforma-sdk/model";
|
|
9
9
|
import { hashJson } from "@milaboratories/pl-model-middle-layer";
|
|
@@ -19,7 +19,7 @@ export type FullPTableDefV2 = {
|
|
|
19
19
|
pFrameHandle: PFrameHandle;
|
|
20
20
|
def: {
|
|
21
21
|
tableSpec: PTableColumnSpec[];
|
|
22
|
-
dataQuery:
|
|
22
|
+
dataQuery: DataQuery;
|
|
23
23
|
};
|
|
24
24
|
};
|
|
25
25
|
|