@cubejs-backend/query-orchestrator 0.30.43 → 0.30.47

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.
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.PreAggregations = exports.PreAggregationPartitionRangeLoader = exports.PreAggregationLoader = exports.getLastUpdatedAtTimestamp = void 0;
6
+ exports.PreAggregations = exports.PreAggregationPartitionRangeLoader = exports.PreAggregationLoader = exports.getLastUpdatedAtTimestamp = exports.LAMBDA_TABLE_PREFIX = void 0;
7
7
  const crypto_1 = __importDefault(require("crypto"));
8
8
  const ramda_1 = __importDefault(require("ramda"));
9
9
  const shared_1 = require("@cubejs-backend/shared");
@@ -13,6 +13,8 @@ const LocalCacheDriver_1 = require("./LocalCacheDriver");
13
13
  const QueryCache_1 = require("./QueryCache");
14
14
  const ContinueWaitError_1 = require("./ContinueWaitError");
15
15
  const StreamObjectsCounter_1 = require("./StreamObjectsCounter");
16
+ /// Name of the inline table containing the lambda rows.
17
+ exports.LAMBDA_TABLE_PREFIX = 'lambda';
16
18
  function encodeTimeStamp(time) {
17
19
  return Math.floor(time / 1000).toString(32);
18
20
  }
@@ -71,7 +73,8 @@ const tablesToVersionEntries = (schema, tables) => ramda_1.default.sortBy(table
71
73
  const entity = {
72
74
  table_name: `${schema}.${match[1]}`,
73
75
  content_version: match[2],
74
- structure_version: match[3]
76
+ structure_version: match[3],
77
+ build_range_end: table.build_range_end,
75
78
  };
76
79
  if (match[4].length < 13) {
77
80
  entity.last_updated_at = decodeTimeStamp(match[4]);
@@ -129,9 +132,13 @@ class PreAggregationLoadCache {
129
132
  async getTablesQuery(preAggregation) {
130
133
  const redisKey = this.tablesRedisKey(preAggregation);
131
134
  if (!this.tables[redisKey]) {
132
- this.tables[redisKey] = this.preAggregations.options.skipExternalCacheAndQueue && preAggregation.external ?
135
+ const tables = this.preAggregations.options.skipExternalCacheAndQueue && preAggregation.external ?
133
136
  await this.fetchTablesNoCache(preAggregation) :
134
137
  await this.tablesFromCache(preAggregation);
138
+ if (tables === undefined) {
139
+ throw new Error('Pre-aggregation tables are undefined.');
140
+ }
141
+ this.tables[redisKey] = tables;
135
142
  }
136
143
  return this.tables[redisKey];
137
144
  }
@@ -300,7 +307,8 @@ class PreAggregationLoader {
300
307
  return {
301
308
  targetTableName: this.targetTableName(versionEntryByStructureVersion),
302
309
  refreshKeyValues: [],
303
- lastUpdatedAt: versionEntryByStructureVersion.last_updated_at
310
+ lastUpdatedAt: versionEntryByStructureVersion.last_updated_at,
311
+ buildRangeEnd: versionEntryByStructureVersion.build_range_end,
304
312
  };
305
313
  }
306
314
  else {
@@ -329,7 +337,8 @@ class PreAggregationLoader {
329
337
  return {
330
338
  targetTableName: this.targetTableName(versionEntryByContentVersion),
331
339
  refreshKeyValues: [],
332
- lastUpdatedAt: versionEntryByContentVersion.last_updated_at
340
+ lastUpdatedAt: versionEntryByContentVersion.last_updated_at,
341
+ buildRangeEnd: versionEntryByContentVersion.build_range_end,
333
342
  };
334
343
  }
335
344
  // TODO this check can be redundant due to structure version is already checked in loadPreAggregation()
@@ -341,7 +350,8 @@ class PreAggregationLoader {
341
350
  return {
342
351
  targetTableName: this.targetTableName(versionEntryByStructureVersion),
343
352
  refreshKeyValues: [],
344
- lastUpdatedAt: versionEntryByStructureVersion.last_updated_at
353
+ lastUpdatedAt: versionEntryByStructureVersion.last_updated_at,
354
+ buildRangeEnd: versionEntryByStructureVersion.build_range_end,
345
355
  };
346
356
  }
347
357
  }
@@ -370,7 +380,8 @@ class PreAggregationLoader {
370
380
  return {
371
381
  targetTableName: this.targetTableName(lastVersion),
372
382
  refreshKeyValues: [],
373
- lastUpdatedAt: lastVersion.last_updated_at
383
+ lastUpdatedAt: lastVersion.last_updated_at,
384
+ buildRangeEnd: lastVersion.build_range_end,
374
385
  };
375
386
  };
376
387
  if (this.forceBuild) {
@@ -424,7 +435,8 @@ class PreAggregationLoader {
424
435
  return {
425
436
  targetTableName: this.targetTableName(versionEntry),
426
437
  refreshKeyValues: [],
427
- lastUpdatedAt: versionEntry.last_updated_at
438
+ lastUpdatedAt: versionEntry.last_updated_at,
439
+ buildRangeEnd: versionEntry.build_range_end,
428
440
  };
429
441
  }
430
442
  contentVersion(invalidationKeys) {
@@ -464,7 +476,7 @@ class PreAggregationLoader {
464
476
  invalidationKeys,
465
477
  forceBuild: this.forceBuild,
466
478
  metadata: this.metadata,
467
- orphanedTimeout: this.orphanedTimeout
479
+ orphanedTimeout: this.orphanedTimeout,
468
480
  }, priority,
469
481
  // eslint-disable-next-line no-use-before-define
470
482
  { stageQueryKey: PreAggregations.preAggregationQueryCacheKey(this.preAggregation), requestId: this.requestId });
@@ -478,18 +490,16 @@ class PreAggregationLoader {
478
490
  // eslint-disable-next-line no-use-before-define
479
491
  return PreAggregations.targetTableName(versionEntry);
480
492
  }
481
- refresh(preAggregation, newVersionEntry, invalidationKeys) {
482
- return (client) => {
483
- let refreshStrategy = this.refreshImplStoreInSourceStrategy;
484
- if (this.preAggregation.external) {
485
- const readOnly = this.preAggregation.readOnly ||
486
- client.config && client.config.readOnly ||
487
- client.readOnly && (typeof client.readOnly === 'boolean' ? client.readOnly : client.readOnly());
488
- refreshStrategy = readOnly ?
489
- this.refreshImplStreamExternalStrategy : this.refreshImplTempTableExternalStrategy;
490
- }
491
- return utils_1.cancelCombinator(saveCancelFn => refreshStrategy.bind(this)(client, newVersionEntry, saveCancelFn, preAggregation, invalidationKeys));
492
- };
493
+ refresh(newVersionEntry, invalidationKeys, client) {
494
+ let refreshStrategy = this.refreshImplStoreInSourceStrategy;
495
+ if (this.preAggregation.external) {
496
+ const readOnly = this.preAggregation.readOnly ||
497
+ client.config && client.config.readOnly ||
498
+ client.readOnly && (typeof client.readOnly === 'boolean' ? client.readOnly : client.readOnly());
499
+ refreshStrategy = readOnly ?
500
+ this.refreshImplStreamExternalStrategy : this.refreshImplTempTableExternalStrategy;
501
+ }
502
+ return utils_1.cancelCombinator(saveCancelFn => refreshStrategy.bind(this)(client, newVersionEntry, saveCancelFn, invalidationKeys));
493
503
  }
494
504
  logExecutingSql(payload) {
495
505
  this.logger('Executing Load Pre Aggregation SQL', payload);
@@ -502,9 +512,10 @@ class PreAggregationLoader {
502
512
  targetTableName,
503
513
  requestId: this.requestId,
504
514
  newVersionEntry,
515
+ buildRangeEnd: this.preAggregation.buildRangeEnd,
505
516
  };
506
517
  }
507
- async refreshImplStoreInSourceStrategy(client, newVersionEntry, saveCancelFn, preAggregation, invalidationKeys) {
518
+ async refreshImplStoreInSourceStrategy(client, newVersionEntry, saveCancelFn, invalidationKeys) {
508
519
  const [loadSql, params] = Array.isArray(this.preAggregation.loadSql) ? this.preAggregation.loadSql : [this.preAggregation.loadSql, []];
509
520
  const targetTableName = this.targetTableName(newVersionEntry);
510
521
  const query = QueryCache_1.QueryCache.replacePreAggregationTableNames(loadSql, this.preAggregationsTablesToTempTables)
@@ -526,7 +537,7 @@ class PreAggregationLoader {
526
537
  /**
527
538
  * Strategy to copy pre-aggregation from source db (with write permissions) to external data
528
539
  */
529
- async refreshImplTempTableExternalStrategy(client, newVersionEntry, saveCancelFn, preAggregation, invalidationKeys) {
540
+ async refreshImplTempTableExternalStrategy(client, newVersionEntry, saveCancelFn, invalidationKeys) {
530
541
  const [loadSql, params] = Array.isArray(this.preAggregation.loadSql) ? this.preAggregation.loadSql : [this.preAggregation.loadSql, []];
531
542
  await client.createSchemaIfNotExists(this.preAggregation.preAggregationsSchema);
532
543
  const targetTableName = this.targetTableName(newVersionEntry);
@@ -536,7 +547,7 @@ class PreAggregationLoader {
536
547
  this.logExecutingSql(queryOptions);
537
548
  await saveCancelFn(client.loadPreAggregationIntoTable(targetTableName, query, params, queryOptions));
538
549
  try {
539
- const tableData = await this.downloadTempExternalPreAggregation(client, newVersionEntry, preAggregation, saveCancelFn, queryOptions);
550
+ const tableData = await this.downloadTempExternalPreAggregation(client, newVersionEntry, saveCancelFn, queryOptions);
540
551
  try {
541
552
  await this.uploadExternalPreAggregation(tableData, newVersionEntry, saveCancelFn, queryOptions);
542
553
  }
@@ -555,7 +566,7 @@ class PreAggregationLoader {
555
566
  /**
556
567
  * Strategy to copy pre-aggregation from source db (for read-only permissions) to external data
557
568
  */
558
- async refreshImplStreamExternalStrategy(client, newVersionEntry, saveCancelFn, preAggregation, invalidationKeys) {
569
+ async refreshImplStreamExternalStrategy(client, newVersionEntry, saveCancelFn, invalidationKeys) {
559
570
  const [sql, params] = Array.isArray(this.preAggregation.sql) ? this.preAggregation.sql : [this.preAggregation.sql, []];
560
571
  // @todo Deprecated, BaseDriver already implements it, before remove we need to add check for factoryDriver
561
572
  if (!client.downloadQueryResults) {
@@ -600,7 +611,7 @@ class PreAggregationLoader {
600
611
  /**
601
612
  * Create table (for db with write permissions) and extract data via memory/stream/unload
602
613
  */
603
- async downloadTempExternalPreAggregation(client, newVersionEntry, preAggregation, saveCancelFn, queryOptions) {
614
+ async downloadTempExternalPreAggregation(client, newVersionEntry, saveCancelFn, queryOptions) {
604
615
  // @todo Deprecated, BaseDriver already implements it, before remove we need to add check for factoryDriver
605
616
  if (!client.downloadTable) {
606
617
  throw new Error('Can\'t load external pre-aggregation: source driver doesn\'t support downloadTable()');
@@ -617,7 +628,7 @@ class PreAggregationLoader {
617
628
  else if (capabilities.streamImport && client.stream) {
618
629
  tableData = await saveCancelFn(client.stream(`SELECT * FROM ${table}`, [], this.getStreamingOptions()));
619
630
  if (client.unload) {
620
- const stream = new StreamObjectsCounter_1.LargeStreamWarning(preAggregation.preAggregationId, (msg) => {
631
+ const stream = new StreamObjectsCounter_1.LargeStreamWarning(this.preAggregation.preAggregationId, (msg) => {
621
632
  this.logger('Downloading external pre-aggregation warning', {
622
633
  ...queryOptions,
623
634
  error: msg
@@ -711,7 +722,10 @@ exports.PreAggregationLoader = PreAggregationLoader;
711
722
  class PreAggregationPartitionRangeLoader {
712
723
  constructor(redisPrefix, driverFactory, logger, queryCache,
713
724
  // eslint-disable-next-line no-use-before-define
714
- preAggregations, preAggregation, preAggregationsTablesToTempTables, loadCache, options = {}) {
725
+ preAggregations, preAggregation, preAggregationsTablesToTempTables, loadCache, options = {
726
+ maxPartitions: 10000,
727
+ maxSourceRowLimit: 10000,
728
+ }) {
715
729
  this.redisPrefix = redisPrefix;
716
730
  this.driverFactory = driverFactory;
717
731
  this.logger = logger;
@@ -723,11 +737,16 @@ class PreAggregationPartitionRangeLoader {
723
737
  this.options = options;
724
738
  this.waitForRenew = options.waitForRenew;
725
739
  this.requestId = options.requestId;
740
+ this.lambdaQuery = options.lambdaQuery;
726
741
  this.dataSource = preAggregation.dataSource;
727
742
  }
728
743
  async loadRangeQuery(rangeQuery, partitionRange) {
729
744
  const [query, values, queryOptions] = rangeQuery;
730
- return this.queryCache.cacheQueryResult(query, values, QueryCache_1.QueryCache.queryCacheKey({ query, values }), 24 * 60 * 60, {
745
+ const invalidate = this.preAggregation.invalidateKeyQueries &&
746
+ this.preAggregation.invalidateKeyQueries[0]
747
+ ? this.preAggregation.invalidateKeyQueries[0].slice(0, 2)
748
+ : false;
749
+ return this.queryCache.cacheQueryResult(query, values, QueryCache_1.QueryCache.queryCacheKey({ query, values, invalidate }), 24 * 60 * 60, {
731
750
  renewalThreshold: this.queryCache.options.refreshKeyRenewalThreshold
732
751
  || (queryOptions === null || queryOptions === void 0 ? void 0 : queryOptions.renewalThreshold) || 24 * 60 * 60,
733
752
  waitForRenew: this.waitForRenew,
@@ -736,7 +755,7 @@ class PreAggregationPartitionRangeLoader {
736
755
  dataSource: this.dataSource,
737
756
  useInMemory: true,
738
757
  external: queryOptions === null || queryOptions === void 0 ? void 0 : queryOptions.external,
739
- renewalKey: partitionRange ? await this.getInvalidationKeyValues(partitionRange) : null
758
+ renewalKey: partitionRange ? await this.getInvalidationKeyValues(partitionRange) : null,
740
759
  });
741
760
  }
742
761
  getInvalidationKeyValues(range) {
@@ -779,32 +798,38 @@ class PreAggregationPartitionRangeLoader {
779
798
  }), {
780
799
  ...options,
781
800
  renewalThreshold: (options === null || options === void 0 ? void 0 : options.incremental) && updateWindowToBoundary < new Date() ?
782
- // if updateWindowToBoundary passed just moments ago we want to renew it earlier in case of server
783
- // and db clock don't match
801
+ // if updateWindowToBoundary passed just moments ago we want to renew it earlier in case
802
+ // of server and db clock don't match
784
803
  Math.min(Math.round((new Date().getTime() - updateWindowToBoundary.getTime()) / 1000), options === null || options === void 0 ? void 0 : options.renewalThresholdOutsideUpdateWindow) : options === null || options === void 0 ? void 0 : options.renewalThreshold
785
804
  }];
786
805
  }
787
- partitionPreAggregationDescription(range) {
806
+ partitionPreAggregationDescription(range, buildRange) {
788
807
  const partitionTableName = PreAggregationPartitionRangeLoader.partitionTableName(this.preAggregation.tableName, this.preAggregation.partitionGranularity, range);
808
+ const [_, buildRangeEnd] = buildRange;
809
+ const loadRange = [...range];
810
+ if (this.preAggregation.unionWithSourceData && buildRangeEnd < range[1]) {
811
+ loadRange[1] = buildRangeEnd;
812
+ }
789
813
  return {
790
814
  ...this.preAggregation,
791
815
  tableName: partitionTableName,
792
816
  loadSql: this.preAggregation.loadSql &&
793
- this.replacePartitionSqlAndParams(this.preAggregation.loadSql, range, partitionTableName),
817
+ this.replacePartitionSqlAndParams(this.preAggregation.loadSql, loadRange, partitionTableName),
794
818
  sql: this.preAggregation.sql &&
795
- this.replacePartitionSqlAndParams(this.preAggregation.sql, range, partitionTableName),
819
+ this.replacePartitionSqlAndParams(this.preAggregation.sql, loadRange, partitionTableName),
796
820
  invalidateKeyQueries: (this.preAggregation.invalidateKeyQueries || [])
797
821
  .map(q => this.replacePartitionSqlAndParams(q, range, partitionTableName)),
798
822
  indexesSql: (this.preAggregation.indexesSql || [])
799
823
  .map(q => ({ ...q, sql: this.replacePartitionSqlAndParams(q.sql, range, partitionTableName) })),
800
824
  previewSql: this.preAggregation.previewSql &&
801
- this.replacePartitionSqlAndParams(this.preAggregation.previewSql, range, partitionTableName)
825
+ this.replacePartitionSqlAndParams(this.preAggregation.previewSql, range, partitionTableName),
826
+ buildRangeEnd,
802
827
  };
803
828
  }
804
829
  async loadPreAggregations() {
805
830
  if (this.preAggregation.partitionGranularity && !this.preAggregation.expandedPartition) {
806
- const partitionRanges = await this.partitionRanges();
807
- const partitionLoaders = partitionRanges.map(range => new PreAggregationLoader(this.redisPrefix, this.driverFactory, this.logger, this.queryCache, this.preAggregations, this.partitionPreAggregationDescription(range), this.preAggregationsTablesToTempTables, this.loadCache, this.options));
831
+ const { buildRange, partitionRanges } = await this.partitionRanges();
832
+ const partitionLoaders = partitionRanges.map(range => new PreAggregationLoader(this.redisPrefix, this.driverFactory, this.logger, this.queryCache, this.preAggregations, this.partitionPreAggregationDescription(range, buildRange), this.preAggregationsTablesToTempTables, this.loadCache, this.options));
808
833
  const resolveResults = await Promise.all(partitionLoaders.map(l => l.loadPreAggregation(false)));
809
834
  const loadResults = resolveResults.filter(res => res !== null);
810
835
  if (this.options.externalRefresh && loadResults.length === 0) {
@@ -813,25 +838,65 @@ class PreAggregationPartitionRangeLoader {
813
838
  'built yet. Please make sure your refresh worker is configured ' +
814
839
  'correctly and running.');
815
840
  }
816
- const allTableTargetNames = loadResults
817
- .map(targetTableName => targetTableName.targetTableName);
841
+ const allTableTargetNames = loadResults.map(targetTableName => targetTableName.targetTableName);
842
+ let lastUpdatedAt = getLastUpdatedAtTimestamp(loadResults.map(r => r.lastUpdatedAt));
843
+ let lambdaTable;
844
+ if (this.lambdaQuery && loadResults.length > 0) {
845
+ const { buildRangeEnd } = loadResults[loadResults.length - 1];
846
+ lambdaTable = await this.downloadLambdaTable(buildRangeEnd);
847
+ allTableTargetNames.push(lambdaTable.name);
848
+ lastUpdatedAt = Date.now();
849
+ }
818
850
  const unionTargetTableName = allTableTargetNames
819
851
  .map(targetTableName => `SELECT * FROM ${targetTableName}`)
820
852
  .join(' UNION ALL ');
821
853
  return {
822
854
  targetTableName: allTableTargetNames.length === 1 ? allTableTargetNames[0] : `(${unionTargetTableName})`,
823
855
  refreshKeyValues: loadResults.map(t => t.refreshKeyValues),
824
- lastUpdatedAt: getLastUpdatedAtTimestamp(loadResults.map(r => r.lastUpdatedAt)),
856
+ lastUpdatedAt,
857
+ buildRangeEnd: undefined,
858
+ lambdaTable,
825
859
  };
826
860
  }
827
861
  else {
828
862
  return new PreAggregationLoader(this.redisPrefix, this.driverFactory, this.logger, this.queryCache, this.preAggregations, this.preAggregation, this.preAggregationsTablesToTempTables, this.loadCache, this.options).loadPreAggregation(true);
829
863
  }
830
864
  }
865
+ /**
866
+ * Downloads the lambda table from the source DB.
867
+ */
868
+ async downloadLambdaTable(fromDate) {
869
+ const { sqlAndParams, cacheKeyQueries } = this.lambdaQuery;
870
+ const [query, params] = sqlAndParams;
871
+ const values = params.map((p) => {
872
+ if (p === shared_1.FROM_PARTITION_RANGE) {
873
+ return fromDate;
874
+ }
875
+ if (p === shared_1.MAX_SOURCE_ROW_LIMIT) {
876
+ return this.options.maxSourceRowLimit;
877
+ }
878
+ return p;
879
+ });
880
+ const { data } = await this.queryCache.renewQuery(query, values, cacheKeyQueries, 60 * 60, [query, values], undefined, {
881
+ requestId: this.requestId,
882
+ skipRefreshKeyWaitForRenew: false,
883
+ dataSource: this.dataSource,
884
+ external: false,
885
+ useCsvQuery: true,
886
+ });
887
+ if (data.rowCount === this.options.maxSourceRowLimit) {
888
+ throw new Error(`The maximum number of source rows ${this.options.maxSourceRowLimit} was reached for ${this.preAggregation.preAggregationId}`);
889
+ }
890
+ return {
891
+ name: `${exports.LAMBDA_TABLE_PREFIX}_${this.preAggregation.tableName.replace('.', '_')}`,
892
+ columns: data.types,
893
+ csvRows: data.csvRows,
894
+ };
895
+ }
831
896
  async partitionPreAggregations() {
832
897
  if (this.preAggregation.partitionGranularity && !this.preAggregation.expandedPartition) {
833
- const partitionRanges = await this.partitionRanges();
834
- return partitionRanges.map(range => this.partitionPreAggregationDescription(range));
898
+ const { buildRange, partitionRanges } = await this.partitionRanges();
899
+ return partitionRanges.map(range => this.partitionPreAggregationDescription(range, buildRange));
835
900
  }
836
901
  else {
837
902
  return [this.preAggregation];
@@ -840,7 +905,7 @@ class PreAggregationPartitionRangeLoader {
840
905
  async partitionRanges() {
841
906
  const buildRange = await this.loadBuildRange();
842
907
  if (!buildRange[0] || !buildRange[1]) {
843
- return [];
908
+ return { buildRange, partitionRanges: [] };
844
909
  }
845
910
  let dateRange = PreAggregationPartitionRangeLoader.intersectDateRanges(buildRange, this.preAggregation.matchedTimeDimensionDateRange);
846
911
  if (!dateRange) {
@@ -848,7 +913,11 @@ class PreAggregationPartitionRangeLoader {
848
913
  // use last partition so outer query can receive expected table structure.
849
914
  dateRange = [buildRange[1], buildRange[1]];
850
915
  }
851
- return PreAggregationPartitionRangeLoader.timeSeries(this.preAggregation.partitionGranularity, dateRange);
916
+ const partitionRanges = PreAggregationPartitionRangeLoader.timeSeries(this.preAggregation.partitionGranularity, dateRange);
917
+ if (partitionRanges.length > this.options.maxPartitions) {
918
+ throw new Error(`The maximum number of partitions (${this.options.maxPartitions}) was reached for the pre-aggregation`);
919
+ }
920
+ return { buildRange: dateRange, partitionRanges };
852
921
  }
853
922
  async loadBuildRange() {
854
923
  const { preAggregationStartEndQueries } = this.preAggregation;
@@ -860,9 +929,12 @@ class PreAggregationPartitionRangeLoader {
860
929
  const [rangeStart, rangeEnd] = await Promise.all(preAggregationStartEndQueries.map(async (rangeQuery, i) => PreAggregationPartitionRangeLoader.extractDate(await this.loadRangeQuery(rangeQuery, i === 0 ? wholeSeriesRanges[0] : wholeSeriesRanges[wholeSeriesRanges.length - 1]))));
861
930
  return this.orNowIfEmpty([rangeStart, rangeEnd]);
862
931
  }
932
+ now() {
933
+ return shared_1.utcToLocalTimeZone(this.preAggregation.timezone, 'YYYY-MM-DDTHH:mm:ss.SSS', new Date().toJSON().substring(0, 23));
934
+ }
863
935
  orNowIfEmpty(dateRange) {
864
936
  if (!dateRange[0] && !dateRange[1]) {
865
- const now = shared_1.utcToLocalTimeZone(this.preAggregation.timezone, 'YYYY-MM-DDTHH:mm:ss.SSS', new Date().toJSON().substring(0, 23));
937
+ const now = this.now();
866
938
  return [now, now];
867
939
  }
868
940
  if (!dateRange[0]) {
@@ -973,16 +1045,21 @@ class PreAggregations {
973
1045
  };
974
1046
  let queryParamsReplacement = null;
975
1047
  const preAggregationsTablesToTempTablesPromise = preAggregations.map((p, i) => (preAggregationsTablesToTempTables) => {
1048
+ var _a;
976
1049
  const loader = new PreAggregationPartitionRangeLoader(this.redisPrefix, () => this.driverFactory(p.dataSource || 'default'), this.logger, this.queryCache, this, p, preAggregationsTablesToTempTables, getLoadCacheByDataSource(p.dataSource, p.preAggregationsSchema), {
1050
+ maxPartitions: this.options.maxPartitions,
1051
+ maxSourceRowLimit: this.options.maxSourceRowLimit,
977
1052
  waitForRenew: queryBody.renewQuery,
978
1053
  // TODO workaround to avoid continuous waiting on building pre-aggregation dependencies
979
1054
  forceBuild: i === preAggregations.length - 1 ? queryBody.forceBuildPreAggregations : false,
980
1055
  requestId: queryBody.requestId,
981
1056
  metadata: queryBody.metadata,
982
1057
  orphanedTimeout: queryBody.orphanedTimeout,
1058
+ lambdaQuery: ((_a = queryBody.lambdaQueries) !== null && _a !== void 0 ? _a : {})[p.preAggregationId],
983
1059
  externalRefresh: this.externalRefresh
984
1060
  });
985
- const preAggregationPromise = () => loader.loadPreAggregations().then(async (loadResult) => {
1061
+ const preAggregationPromise = async () => {
1062
+ const loadResult = await loader.loadPreAggregations();
986
1063
  const usedPreAggregation = {
987
1064
  ...loadResult,
988
1065
  type: p.type,
@@ -992,7 +1069,7 @@ class PreAggregations {
992
1069
  queryParamsReplacement = await loader.replaceQueryBuildRangeParams(queryBody.values);
993
1070
  }
994
1071
  return [p.tableName, usedPreAggregation];
995
- });
1072
+ };
996
1073
  return preAggregationPromise().then(res => preAggregationsTablesToTempTables.concat([res]));
997
1074
  }).reduce((promise, fn) => promise.then(fn), Promise.resolve([]));
998
1075
  return preAggregationsTablesToTempTablesPromise.then(preAggregationsTablesToTempTables => ({
@@ -1027,9 +1104,11 @@ class PreAggregations {
1027
1104
  };
1028
1105
  const expandedPreAggregations = await Promise.all(preAggregations.map(p => {
1029
1106
  const loader = new PreAggregationPartitionRangeLoader(this.redisPrefix, () => this.driverFactory(p.dataSource || 'default'), this.logger, this.queryCache, this, p, [], getLoadCacheByDataSource(p.dataSource, p.preAggregationsSchema), {
1107
+ maxPartitions: this.options.maxPartitions,
1108
+ maxSourceRowLimit: this.options.maxSourceRowLimit,
1030
1109
  waitForRenew: queryBody.renewQuery,
1031
1110
  requestId: queryBody.requestId,
1032
- externalRefresh: this.externalRefresh
1111
+ externalRefresh: this.externalRefresh,
1033
1112
  });
1034
1113
  return loader.partitionPreAggregations();
1035
1114
  }));
@@ -1045,9 +1124,9 @@ class PreAggregations {
1045
1124
  async getQueue(dataSource = 'default') {
1046
1125
  if (!this.queue[dataSource]) {
1047
1126
  this.queue[dataSource] = QueryCache_1.QueryCache.createQueue(`SQL_PRE_AGGREGATIONS_${this.redisPrefix}_${dataSource}`, () => this.driverFactory(dataSource), (client, q) => {
1048
- const { preAggregation, preAggregationsTablesToTempTables, newVersionEntry, requestId, invalidationKeys } = q;
1049
- const loader = new PreAggregationLoader(this.redisPrefix, () => this.driverFactory(dataSource), this.logger, this.queryCache, this, preAggregation, preAggregationsTablesToTempTables, new PreAggregationLoadCache(this.redisPrefix, () => this.driverFactory(dataSource), this.queryCache, this, { requestId, dataSource }), { requestId, externalRefresh: this.externalRefresh });
1050
- return loader.refresh(preAggregation, newVersionEntry, invalidationKeys)(client);
1127
+ const { preAggregation, preAggregationsTablesToTempTables, newVersionEntry, requestId, invalidationKeys, buildRangeEnd } = q;
1128
+ const loader = new PreAggregationLoader(this.redisPrefix, () => this.driverFactory(dataSource), this.logger, this.queryCache, this, preAggregation, preAggregationsTablesToTempTables, new PreAggregationLoadCache(this.redisPrefix, () => this.driverFactory(dataSource), this.queryCache, this, { requestId, dataSource }), { requestId, externalRefresh: this.externalRefresh, buildRangeEnd });
1129
+ return loader.refresh(newVersionEntry, invalidationKeys, client);
1051
1130
  }, {
1052
1131
  concurrency: 1,
1053
1132
  logger: this.logger,