UNPKG

@qrvey/formula-lang

Version:

QFormula support for qrvey projects

117 lines 4.17 kB
import { AST_PRIMITIVES, OPERATION_SCOPE } from '../constants'; import { isDateParam, isNumberParam, isStringParam, removeQuotes, } from '../utils'; import { greaterThanOrEqualToReference } from '../utils/greaterThanOrEqualToReference'; import { isAnAllowedValue } from '../utils/isAnAllowedValue'; import { isInteger } from '../utils/isInteger'; /** * `DATEADD` Adds a specific date part value to a given date. */ export const DATEADD = { identifier: 'DATEADD', operationScope: OPERATION_SCOPE.RAW, functionScope: [OPERATION_SCOPE.RAW], parameters: [ { identifier: 'DATE', optional: false, expectedPrimitive: AST_PRIMITIVES.DATE, validator: [isDateParam], }, { identifier: 'UNIT', optional: false, expectedPrimitive: AST_PRIMITIVES.STRING, validator: [ isStringParam, isAnAllowedValue(['Y', 'M', 'D', 'H', 'MI', 'S']), ], }, { identifier: 'INTERVAL', optional: false, expectedPrimitive: AST_PRIMITIVES.NUMBER, validator: [ isNumberParam, greaterThanOrEqualToReference(0), isInteger, ], }, ], transpiler: { elasticsearch, snowflake, redshift, postgresql, databricks, }, primitiveResult: AST_PRIMITIVES.DATE, }; function elasticsearch(date, unit, interval) { unit = removeQuotes(unit); switch (unit) { case 'Y': return `${date}.plusYears((long) Math.floor(${interval}))`; case 'M': return `${date}.plusMonths((long) Math.floor(${interval}))`; case 'D': return `${date}.plusDays((long) Math.floor(${interval}))`; case 'H': return `${date}.plusHours((long) Math.floor(${interval}))`; case 'MI': return `${date}.plusMinutes((long) Math.floor(${interval}))`; case 'S': return `${date}.plusSeconds((long) Math.floor(${interval}))`; default: return ''; } } function SQL(date, unit, interval) { unit = removeQuotes(unit); const sqlDateAdd = (_date, _unit, _interval) => `DATEADD(${_unit}, FLOOR(${_interval})::INTEGER, ${_date})`; switch (unit) { case 'Y': return sqlDateAdd(date, `month`, `${interval} * 12`); // Year to month conversion to get the same result for leap years. Redshift behavior is different for leap year example `2016-02-29` https://docs.aws.amazon.com/redshift/latest/dg/r_DATEADD_function.html case 'M': return sqlDateAdd(date, `month`, interval); case 'D': return sqlDateAdd(date, `day`, interval); case 'H': return sqlDateAdd(date, `hour`, interval); case 'MI': return sqlDateAdd(date, `minute`, interval); case 'S': return sqlDateAdd(date, `second`, interval); default: return ''; } } function snowflake(date, unit, interval) { return SQL(date, unit, interval); } function redshift(date, unit, interval) { return SQL(date, unit, interval); } function postgresql(date, unit, interval) { unit = removeQuotes(unit); const sqlDateAdd = (_date, _unit) => `${_date} + interval ${_unit}`; switch (unit) { case 'Y': return sqlDateAdd(date, `'1 year' * FLOOR(${interval})::INTEGER`); case 'M': return sqlDateAdd(date, `'1 month' * FLOOR(${interval})::INTEGER`); case 'D': return sqlDateAdd(date, `'1 day' * FLOOR(${interval})::INTEGER`); case 'H': return sqlDateAdd(date, `'1 hour' * FLOOR(${interval})::INTEGER`); case 'MI': return sqlDateAdd(date, `'1 minute' * FLOOR(${interval})::INTEGER`); case 'S': return sqlDateAdd(date, `'1 second' * FLOOR(${interval})::INTEGER`); default: return ''; } } function databricks(date, unit, interval) { return SQL(date, unit, interval); } //# sourceMappingURL=dateadd.js.map