@milaboratories/pl-middle-layer 1.43.49 → 1.43.51

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.
@@ -50,6 +50,8 @@ import {
50
50
  isAbortError,
51
51
  isPFrameDriverError,
52
52
  uniqueBy,
53
+ getAxisId,
54
+ canonicalizeJson,
53
55
  } from '@platforma-sdk/model';
54
56
  import { LRUCache } from 'lru-cache';
55
57
  import {
@@ -923,8 +925,9 @@ export class PFrameDriver implements InternalPFrameDriver {
923
925
  const def = migratePTableFilters(rawDef, this.logger);
924
926
  const pFrameHandle = this.createPFrame(extractAllColumns(def.src), ctx);
925
927
  const defIds = mapPTableDef(def, (c) => c.id);
928
+ const sortedDef = sortPTableDef(defIds);
926
929
 
927
- const { key, unref } = this.pTableDefs.acquire({ def: defIds, pFrameHandle });
930
+ const { key, unref } = this.pTableDefs.acquire({ def: sortedDef, pFrameHandle });
928
931
  if (getDebugFlags().logPFrameRequests) {
929
932
  this.logger('info', `Create PTable call (pFrameHandle = ${pFrameHandle}; pTableHandle = ${key})`);
930
933
  }
@@ -996,7 +999,7 @@ export class PFrameDriver implements InternalPFrameDriver {
996
999
 
997
1000
  const table = this.pTables.acquire({
998
1001
  pFrameHandle: handle,
999
- def: migratePTableFilters(request, this.logger),
1002
+ def: sortPTableDef(migratePTableFilters(request, this.logger)),
1000
1003
  });
1001
1004
  const { pTablePromise, disposeSignal } = table.resource;
1002
1005
  const pTable = await pTablePromise;
@@ -1180,10 +1183,116 @@ function joinEntryToInternal(entry: JoinEntry<PObjectId>): PFrameInternal.JoinEn
1180
1183
  secondary: entry.secondary.map((col) => joinEntryToInternal(col)),
1181
1184
  };
1182
1185
  default:
1183
- throw new PFrameDriverError(`unsupported PFrame join entry type: ${type}`);
1186
+ throw new PFrameDriverError(`unsupported PFrame join entry type: ${type satisfies never}`);
1184
1187
  }
1185
1188
  }
1186
1189
 
1190
+ function sortPTableDef(def: PTableDef<PObjectId>): PTableDef<PObjectId> {
1191
+ function cmpJoinEntries(lhs: JoinEntry<PObjectId>, rhs: JoinEntry<PObjectId>): number {
1192
+ if (lhs.type !== rhs.type) {
1193
+ return lhs.type < rhs.type ? -1 : 1;
1194
+ }
1195
+ const type = lhs.type;
1196
+ switch (type) {
1197
+ case 'column':
1198
+ return lhs.column < (rhs as typeof lhs).column ? -1 : 1;
1199
+ case 'slicedColumn':
1200
+ case 'artificialColumn':
1201
+ return lhs.newId < (rhs as typeof lhs).newId ? -1 : 1;
1202
+ case 'inlineColumn': {
1203
+ return lhs.column.id < (rhs as typeof lhs).column.id ? -1 : 1;
1204
+ }
1205
+ case 'inner':
1206
+ case 'full': {
1207
+ const rhsInner = rhs as typeof lhs;
1208
+ if (lhs.entries.length !== rhsInner.entries.length) {
1209
+ return lhs.entries.length - rhsInner.entries.length;
1210
+ }
1211
+ for (let i = 0; i < lhs.entries.length; i++) {
1212
+ const cmp = cmpJoinEntries(lhs.entries[i], rhsInner.entries[i]);
1213
+ if (cmp !== 0) {
1214
+ return cmp;
1215
+ }
1216
+ }
1217
+ return 0;
1218
+ }
1219
+ case 'outer': {
1220
+ const rhsOuter = rhs as typeof lhs;
1221
+ const cmp = cmpJoinEntries(lhs.primary, rhsOuter.primary);
1222
+ if (cmp !== 0) {
1223
+ return cmp;
1224
+ }
1225
+ if (lhs.secondary.length !== rhsOuter.secondary.length) {
1226
+ return lhs.secondary.length - rhsOuter.secondary.length;
1227
+ }
1228
+ for (let i = 0; i < lhs.secondary.length; i++) {
1229
+ const cmp = cmpJoinEntries(lhs.secondary[i], rhsOuter.secondary[i]);
1230
+ if (cmp !== 0) {
1231
+ return cmp;
1232
+ }
1233
+ }
1234
+ return 0;
1235
+ }
1236
+ default:
1237
+ assertNever(type);
1238
+ }
1239
+ }
1240
+ function sortJoinEntry(entry: JoinEntry<PObjectId>): JoinEntry<PObjectId> {
1241
+ switch (entry.type) {
1242
+ case 'column':
1243
+ case 'slicedColumn':
1244
+ case 'inlineColumn':
1245
+ return entry;
1246
+ case 'artificialColumn': {
1247
+ const sortedAxesIndices = entry.axesIndices.toSorted((lhs, rhs) => lhs - rhs);
1248
+ return {
1249
+ ...entry,
1250
+ axesIndices: sortedAxesIndices,
1251
+ };
1252
+ }
1253
+ case 'inner':
1254
+ case 'full': {
1255
+ const sortedEntries = entry.entries.map(sortJoinEntry);
1256
+ sortedEntries.sort(cmpJoinEntries);
1257
+ return {
1258
+ ...entry,
1259
+ entries: sortedEntries,
1260
+ };
1261
+ }
1262
+ case 'outer': {
1263
+ const sortedSecondary = entry.secondary.map(sortJoinEntry);
1264
+ sortedSecondary.sort(cmpJoinEntries);
1265
+ return {
1266
+ ...entry,
1267
+ primary: sortJoinEntry(entry.primary),
1268
+ secondary: sortedSecondary,
1269
+ };
1270
+ }
1271
+ default:
1272
+ assertNever(entry);
1273
+ }
1274
+ }
1275
+ function sortFilters(filters: PTableRecordFilter[]): PTableRecordFilter[] {
1276
+ return filters.toSorted((lhs, rhs) => {
1277
+ if (lhs.column.type === 'axis' && rhs.column.type === 'axis') {
1278
+ const lhsId = canonicalizeJson(getAxisId(lhs.column.id));
1279
+ const rhsId = canonicalizeJson(getAxisId(rhs.column.id));
1280
+ return lhsId < rhsId ? -1 : 1;
1281
+ } else if (lhs.column.type === 'column' && rhs.column.type === 'column') {
1282
+ return lhs.column.id < rhs.column.id ? -1 : 1;
1283
+ } else {
1284
+ return lhs.column.type === 'axis' ? -1 : 1;
1285
+ }
1286
+ });
1287
+ }
1288
+ return {
1289
+ src: sortJoinEntry(def.src),
1290
+ partitionFilters: sortFilters(def.partitionFilters),
1291
+ filters: sortFilters(def.filters),
1292
+ sorting: def.sorting,
1293
+ };
1294
+ }
1295
+
1187
1296
  function stableKeyFromFullPTableDef(data: FullPTableDef): string {
1188
1297
  try {
1189
1298
  const hash = createHash('sha256');
@@ -1257,11 +1366,11 @@ function stableKeyFromPFrameData(data: PColumn<PFrameInternal.DataInfo<PlTreeEnt
1257
1366
  default:
1258
1367
  throw new PFrameDriverError(`unsupported resource type: ${JSON.stringify(type satisfies never)}`);
1259
1368
  }
1260
- result.payload.sort((lhs, rhs) => lhs.key.localeCompare(rhs.key));
1369
+ result.payload.sort((lhs, rhs) => lhs.key < rhs.key ? -1 : 1);
1261
1370
  return result;
1262
1371
  }),
1263
1372
  );
1264
- orderedData.sort((lhs, rhs) => lhs.id.localeCompare(rhs.id));
1373
+ orderedData.sort((lhs, rhs) => lhs.id < rhs.id ? -1 : 1);
1265
1374
 
1266
1375
  const hash = createHash('sha256');
1267
1376
  hash.update(canonicalize(orderedData)!);