Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 11 additions & 7 deletions packages/cubejs-schema-compiler/src/adapter/BaseQuery.js
Original file line number Diff line number Diff line change
Expand Up @@ -4475,27 +4475,31 @@ export class BaseQuery {
}

parseCronSyntax(every) {
// One of the years that start from monday (first day of week)
// Mon, 01 Jan 2018 00:00:00 GMT
const startDate = 1514764800000;
// Use the Unix epoch as the reference point for calculating dayOffset.
// The refresh key SQL formula is: FLOOR((unix_timestamp - dayOffset) / interval)
// Since Unix timestamps are measured from Thu, 01 Jan 1970 00:00:00 UTC,
// week boundaries naturally fall on Thursdays when dividing by 604800 (1 week).
// By calculating dayOffset from the epoch to the first cron fire time,
// we correctly shift the boundaries to align with the desired day of week.
const opt = {
utc: true,
currentDate: new Date(startDate)
currentDate: new Date(0) // Unix epoch
};

try {
const interval = cronParser.parseExpression(every, opt);
let dayOffset = interval.next().getTime();
const dayOffsetPrev = interval.prev().getTime();

if (dayOffsetPrev === startDate) {
dayOffset = startDate;
// If the cron fires exactly at the epoch, use 0 as dayOffset
if (dayOffsetPrev === 0) {
dayOffset = 0;
}

return {
start: interval.next(),
end: interval.next(),
dayOffset: (dayOffset - startDate) / 1000,
dayOffset: dayOffset / 1000, // Convert from ms to seconds
};
} catch (err) {
throw new UserError(`Invalid cron string '${every}' in refreshKey (${err})`);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1250,7 +1250,7 @@ describe('SQL Generation', () => {
.toEqual([`FLOOR((${utcOffset} + EXTRACT(EPOCH FROM NOW()) - 1800) / 3600)`, false, expect.any(BaseQuery)]);

expect(query.everyRefreshKeySql({ every: '30 5 * * 5', timezone }))
.toEqual([`FLOOR((${utcOffset} + EXTRACT(EPOCH FROM NOW()) - 365400) / 604800)`, false, expect.any(BaseQuery)]);
.toEqual([`FLOOR((${utcOffset} + EXTRACT(EPOCH FROM NOW()) - 106200) / 604800)`, false, expect.any(BaseQuery)]);

for (let i = 1; i < 59; i++) {
expect(query.everyRefreshKeySql({ every: `${i} * * * *`, timezone }))
Expand Down
Loading