@effectuate/cubejs-mongosql-driver 1.0.0
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/LICENSE +23 -0
- package/README.md +579 -0
- package/dist/MongoSqlDriver.d.ts +238 -0
- package/dist/MongoSqlDriver.d.ts.map +1 -0
- package/dist/MongoSqlDriver.js +745 -0
- package/dist/MongoSqlDriver.js.map +1 -0
- package/dist/MongoSqlQuery.d.ts +353 -0
- package/dist/MongoSqlQuery.d.ts.map +1 -0
- package/dist/MongoSqlQuery.js +551 -0
- package/dist/MongoSqlQuery.js.map +1 -0
- package/dist/config.d.ts +29 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +298 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/native.d.ts +104 -0
- package/dist/native.d.ts.map +1 -0
- package/dist/native.js +192 -0
- package/dist/native.js.map +1 -0
- package/dist/types.d.ts +49 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +24 -0
- package/dist/types.js.map +1 -0
- package/index.d.ts +160 -0
- package/index.js +316 -0
- package/package.json +108 -0
|
@@ -0,0 +1,551 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* MongoSqlQuery — Cube SQL dialect for MongoSQL.
|
|
4
|
+
*
|
|
5
|
+
* See SPEC.md FR-2 and ARCHITECTURE.md §4.1. Reference:
|
|
6
|
+
* https://www.mongodb.com/docs/sql-interface/language-reference/
|
|
7
|
+
*
|
|
8
|
+
* T12a scope: STATIC SYNTAX — identifier quoting, type names, timestamp
|
|
9
|
+
* casts, timezone passthrough, NULL/param tokens.
|
|
10
|
+
* T12b scope: DATE ARITHMETIC, INTERVALS, time-series generation,
|
|
11
|
+
* date-truncation, dateBin, unixTimestampSql.
|
|
12
|
+
*
|
|
13
|
+
* MongoSQL date-function audit (verified against mongosql v1.8.5 source —
|
|
14
|
+
* `mongosql/src/ast/definitions.rs` `FunctionName::try_from` and
|
|
15
|
+
* `algebrize_date_function`, plus `ast/rewrites/test.rs`):
|
|
16
|
+
*
|
|
17
|
+
* | Function | Signature | Notes |
|
|
18
|
+
* |----------------|--------------------------------------------------------|--------------------------------------------------------------------|
|
|
19
|
+
* | DATEADD | DATEADD(<date_part>, <numeric>, <date>) | TIMESTAMPADD is an alias. |
|
|
20
|
+
* | DATEDIFF | DATEDIFF(<date_part>, <start>, <end>[, <start_of_week>]) | Returns LONG. TIMESTAMPDIFF is an alias. |
|
|
21
|
+
* | DATETRUNC | DATETRUNC(<date_part>, <date>[, <start_of_week>]) | TIMESTAMPTRUNC is an alias. |
|
|
22
|
+
* | EXTRACT | EXTRACT(<date_part> FROM <date>) | Supports YEAR/MONTH/WEEK/DAY/HOUR/MINUTE/SECOND/MILLISECOND/... |
|
|
23
|
+
* | YEAR/MONTH/... | YEAR(d), MONTH(d), ... — rewritten to EXTRACT | All datepart helpers map to EXTRACT. |
|
|
24
|
+
* | CURRENT_TIMESTAMP | CURRENT_TIMESTAMP[(<precision>)] | SQL-92 keyword. Replaces NOW(). |
|
|
25
|
+
*
|
|
26
|
+
* <date_part> for DATEADD / DATEDIFF / DATETRUNC must be one of:
|
|
27
|
+
* YEAR | QUARTER | MONTH | WEEK | DAY | HOUR | MINUTE | SECOND | MILLISECOND
|
|
28
|
+
* (mongosql `DatePart` enum; `IsoWeek`/`DayOfYear` are EXTRACT-only and
|
|
29
|
+
* panic for date-functions per `algebrize_date_function`.)
|
|
30
|
+
*
|
|
31
|
+
* NOT available in MongoSQL (called out so future maintainers don't try):
|
|
32
|
+
* - `INTERVAL '1 day'` literals — REJECTED by parser.
|
|
33
|
+
* - `EXTRACT(EPOCH FROM ...)` — EPOCH is not a `DatePart`.
|
|
34
|
+
* - `AT TIME ZONE` / `CONVERT_TZ` — no SQL-level timezone function.
|
|
35
|
+
* - `VALUES (...)` table constructors — no parser support.
|
|
36
|
+
* - `WITH RECURSIVE` / `generate_series` — no recursive CTEs.
|
|
37
|
+
* For each gap, see the override below for the closest viable substitute.
|
|
38
|
+
*
|
|
39
|
+
* BaseQuery method-list audit (against
|
|
40
|
+
* `node_modules/@cubejs-backend/schema-compiler/dist/src/adapter/BaseQuery.js`,
|
|
41
|
+
* cross-checked against `MysqlQuery.js` and `PostgresQuery.js`):
|
|
42
|
+
*
|
|
43
|
+
* | BaseQuery method | T12a/b action | Why |
|
|
44
|
+
* |-------------------------------------------|-------------------|---------------------------------------------------------------------|
|
|
45
|
+
* | escapeColumnName(name) | OVERRIDE (T12a) | Default emits double-quoted ident; MongoSQL uses backticks. |
|
|
46
|
+
* | quoteIdentifier(name) | ADD (alias) (T12a)| Not on BaseQuery, but task spec + driver doc-comment expect it. |
|
|
47
|
+
* | autoPrefixWithCubeName(c, sql, isExpr) | OVERRIDE (T19a) | mongosql v1.8.5 rejects `<alias>.<col>` outside JOIN scope (3008). |
|
|
48
|
+
* | timeStampCast(value) | OVERRIDE (T12a) | Base emits `value::timestamptz` (Postgres). Mongosql has no `::`. |
|
|
49
|
+
* | dateTimeCast(value) | OVERRIDE (T12a) | Base emits `value::timestamp` (Postgres) — invalid in MongoSQL. |
|
|
50
|
+
* | timeStampParam(td) | INHERIT | Default delegates to timeStampCast — fine once we override that. |
|
|
51
|
+
* | timestampFormat() | INHERIT | ISO-8601 default matches mongosql's accepted CAST literal form. |
|
|
52
|
+
* | castToString(sql) | OVERRIDE (T12a) | Base emits `CAST(.. as TEXT)`; MongoSQL spells it `STRING`. |
|
|
53
|
+
* | convertTz(field) | OVERRIDE (T12a) | MongoSQL has no AT TIME ZONE / CONVERT_TZ. UTC-only passthrough. |
|
|
54
|
+
* | inDbTimeZone(date) | INHERIT | Pure JS — converts JS-side; no SQL emitted. |
|
|
55
|
+
* | nowTimestampSql() | OVERRIDE (T12a) | Base emits `NOW()`; MongoSQL spells it `CURRENT_TIMESTAMP`. |
|
|
56
|
+
* | unixTimestampSql() | OVERRIDE (T12b) | Base uses EXTRACT(EPOCH ...) — not in MongoSQL. Use DATEDIFF. |
|
|
57
|
+
* | concatStringsSql(strings) | INHERIT | Default uses `||` template; MongoSQL accepts `||` for concat. |
|
|
58
|
+
* | sqlTemplates() | OVERRIDE (T12a) | Patch quotes/identifiers + types.* to MongoSQL spellings. |
|
|
59
|
+
* | timeGroupedColumn(g, dim) | OVERRIDE (T12b) | Use DATETRUNC. Week pinned to 'sunday' for determinism. |
|
|
60
|
+
* | dateBin(interval, source, origin) | OVERRIDE (T12b) | DATEADD(unit, FLOOR(DATEDIFF/N)*N, origin) — no INTERVAL literals. |
|
|
61
|
+
* | subtractInterval / addInterval | OVERRIDE (T12b) | DATEADD with positive/negative numeric. Compound = chained calls. |
|
|
62
|
+
* | intervalString(interval) | OVERRIDE (T12b) | Quote-and-pass; no INTERVAL keyword. Used only in error/diag paths. |
|
|
63
|
+
* | seriesSql(td) | OVERRIDE (T12b) | UNION ALL of literal rows (MysqlQuery pattern, CAST not TIMESTAMP). |
|
|
64
|
+
* | newFilter(f) | OVERRIDE (Gap 4) | Return MongoSqlFilter — rewrites ILIKE (unsupported) to LOWER+LIKE. |
|
|
65
|
+
* | newParamAllocator(p) | INHERIT | Default `?` placeholder works for MongoSQL. |
|
|
66
|
+
* | escapeColumnName-driven preAggTableName | INHERIT | Inherited tableName logic produces backtick-safe identifiers. |
|
|
67
|
+
*
|
|
68
|
+
* Anything not in this table is BaseQuery default behaviour and is either
|
|
69
|
+
* (a) provably valid MongoSQL or (b) routed through the overrides above.
|
|
70
|
+
*/
|
|
71
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
72
|
+
exports.MongoSqlFilter = exports.MongoSqlQuery = void 0;
|
|
73
|
+
const schema_compiler_1 = require("@cubejs-backend/schema-compiler");
|
|
74
|
+
/**
|
|
75
|
+
* Inlined re-implementation of `@cubejs-backend/shared`'s `parseSqlInterval`.
|
|
76
|
+
* The shared package isn't a direct dep (only transitive via schema-compiler),
|
|
77
|
+
* and the function is a 10-line string-split — inlining avoids pulling in
|
|
78
|
+
* the entire shared package and keeps the dialect's resolver-friendly.
|
|
79
|
+
*
|
|
80
|
+
* Source pattern (matches shared@1.6.44 `dist/src/time.js::parseSqlInterval`):
|
|
81
|
+
* "1 year 6 months" -> { year: 1, month: 6 }
|
|
82
|
+
* Negative values are supported.
|
|
83
|
+
*/
|
|
84
|
+
function parseSqlInterval(intervalStr) {
|
|
85
|
+
const out = {};
|
|
86
|
+
const parts = intervalStr.trim().split(/\s+/);
|
|
87
|
+
for (let i = 0; i < parts.length; i += 2) {
|
|
88
|
+
const value = parseInt(parts[i], 10);
|
|
89
|
+
const unit = (parts[i + 1] ?? '').toLowerCase();
|
|
90
|
+
if (!unit || Number.isNaN(value)) {
|
|
91
|
+
throw new Error(`Cannot parse interval segment "${parts[i]} ${parts[i + 1] ?? ''}" in "${intervalStr}"`);
|
|
92
|
+
}
|
|
93
|
+
const singular = unit.endsWith('s') ? unit.slice(0, -1) : unit;
|
|
94
|
+
out[singular] = value;
|
|
95
|
+
}
|
|
96
|
+
return out;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Map from Cube's lowercase granularity names to MongoSQL's documented
|
|
100
|
+
* `DatePart` tokens (uppercase). Matches PostgresQuery's `GRANULARITY_TO_INTERVAL`
|
|
101
|
+
* spirit but uses MongoSQL's spellings.
|
|
102
|
+
*/
|
|
103
|
+
const GRANULARITY_TO_DATE_PART = Object.freeze({
|
|
104
|
+
second: 'SECOND',
|
|
105
|
+
minute: 'MINUTE',
|
|
106
|
+
hour: 'HOUR',
|
|
107
|
+
day: 'DAY',
|
|
108
|
+
week: 'WEEK',
|
|
109
|
+
month: 'MONTH',
|
|
110
|
+
quarter: 'QUARTER',
|
|
111
|
+
year: 'YEAR',
|
|
112
|
+
});
|
|
113
|
+
/**
|
|
114
|
+
* Map from `parseSqlInterval` keys (singular, lowercase) to MongoSQL DATEADD
|
|
115
|
+
* date-part tokens. Includes `millisecond` because mongosql DATEADD supports
|
|
116
|
+
* MILLISECOND (per `DatePart` enum).
|
|
117
|
+
*/
|
|
118
|
+
const INTERVAL_UNIT_TO_DATE_PART = Object.freeze({
|
|
119
|
+
millisecond: 'MILLISECOND',
|
|
120
|
+
second: 'SECOND',
|
|
121
|
+
minute: 'MINUTE',
|
|
122
|
+
hour: 'HOUR',
|
|
123
|
+
day: 'DAY',
|
|
124
|
+
week: 'WEEK',
|
|
125
|
+
month: 'MONTH',
|
|
126
|
+
quarter: 'QUARTER',
|
|
127
|
+
year: 'YEAR',
|
|
128
|
+
});
|
|
129
|
+
/**
|
|
130
|
+
* Cube SQL-dialect adapter that emits MongoSQL-compatible SQL.
|
|
131
|
+
*
|
|
132
|
+
* Instantiated by `MongoSqlDriver.dialectClass()`. Cube calls into this for
|
|
133
|
+
* every measure/dimension/timeDimension SQL fragment.
|
|
134
|
+
*/
|
|
135
|
+
class MongoSqlQuery extends schema_compiler_1.BaseQuery {
|
|
136
|
+
/**
|
|
137
|
+
* Identifier quoting — MongoSQL uses backticks.
|
|
138
|
+
* Reference: https://www.mongodb.com/docs/sql-interface/language-reference/identifiers/
|
|
139
|
+
*
|
|
140
|
+
* BaseQuery's actual identifier-quoting hook is `escapeColumnName`; we
|
|
141
|
+
* also expose `quoteIdentifier` as an alias because it's the conventional
|
|
142
|
+
* name and the driver's audit comment refers to it.
|
|
143
|
+
*/
|
|
144
|
+
escapeColumnName(name) {
|
|
145
|
+
return `\`${name.replace(/`/g, '``')}\``;
|
|
146
|
+
}
|
|
147
|
+
quoteIdentifier(identifier) {
|
|
148
|
+
return this.escapeColumnName(identifier);
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Suppress the cube-alias prefix on bare column references when the query
|
|
152
|
+
* has only one cube in scope.
|
|
153
|
+
*
|
|
154
|
+
* Background (T19 discovery): mongosql v1.8.5's algebrizer rejects qualified
|
|
155
|
+
* `<table_alias>.<col>` references in projections when only one collection
|
|
156
|
+
* is in scope — Error 3008 "Field `orders` in the `SELECT` clause at the 0
|
|
157
|
+
* scope level not found". Cube's BaseQuery emits `${cubeAlias}.${sql}` for
|
|
158
|
+
* every dimension that is a bare identifier (see BaseQuery.js:2508
|
|
159
|
+
* `autoPrefixWithCubeName`), which makes every realistic Cube query against
|
|
160
|
+
* a single cube fail translation.
|
|
161
|
+
*
|
|
162
|
+
* Strategy:
|
|
163
|
+
* - Single-cube query (`this.join.joins.length === 0`): drop the prefix
|
|
164
|
+
* — emit a bare column reference (`SELECT email FROM users`).
|
|
165
|
+
* - Multi-cube / JOIN: keep the prefix (`SELECT users.email`) — mongosql
|
|
166
|
+
* accepts qualified refs in JOIN scope (verified end-to-end in
|
|
167
|
+
* tests/integration/basic-queries.test.ts).
|
|
168
|
+
* - `this.join` may be `null` during pre-build / collect-cube-names paths
|
|
169
|
+
* before `prebuildJoin` runs; treat that as "not enough info, keep
|
|
170
|
+
* BaseQuery's behaviour" so we don't drop a prefix Cube actually needed.
|
|
171
|
+
* - `isMemberExpr` (member-expression SQL) bypasses the prefix entirely
|
|
172
|
+
* in BaseQuery; keep that semantics for forward compat.
|
|
173
|
+
*
|
|
174
|
+
* The conditional fall-through to `super` keeps every other code path
|
|
175
|
+
* (non-bare expressions like `LOWER(email)` already escape the regex match
|
|
176
|
+
* and are returned verbatim by the base implementation) unchanged.
|
|
177
|
+
*/
|
|
178
|
+
autoPrefixWithCubeName(cubeName, sql, isMemberExpr = false) {
|
|
179
|
+
// Single-cube projection: mongosql rejects `<alias>.<col>`. Strip the
|
|
180
|
+
// alias prefix only when (a) we'd otherwise emit it (bare identifier,
|
|
181
|
+
// not a member-expression) and (b) the query truly has no joins.
|
|
182
|
+
const join = this
|
|
183
|
+
.join;
|
|
184
|
+
if (join &&
|
|
185
|
+
Array.isArray(join.joins) &&
|
|
186
|
+
join.joins.length === 0 &&
|
|
187
|
+
!isMemberExpr &&
|
|
188
|
+
/^[_a-zA-Z][_a-zA-Z0-9]*$/.test(sql)) {
|
|
189
|
+
return sql;
|
|
190
|
+
}
|
|
191
|
+
return super.autoPrefixWithCubeName(cubeName, sql, isMemberExpr);
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* GROUP BY by column alias instead of positional `1, 2, ...`.
|
|
195
|
+
* mongosql v1.8.5's algebrizer rejects positional refs in GROUP BY
|
|
196
|
+
* (and the failure mode misreports as Error 3008 "Field <col> in the
|
|
197
|
+
* SELECT clause not found"). Mirrors the ClickHouseQuery pattern.
|
|
198
|
+
*/
|
|
199
|
+
groupByClause() {
|
|
200
|
+
if (this.ungrouped) {
|
|
201
|
+
return '';
|
|
202
|
+
}
|
|
203
|
+
const aliases = this.dimensionAliasNames();
|
|
204
|
+
return aliases.length ? ` GROUP BY ${aliases.join(', ')}` : '';
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* ORDER BY by column alias instead of positional `1, 2, ...`.
|
|
208
|
+
* Same constraint as `groupByClause` — mongosql requires named refs.
|
|
209
|
+
*/
|
|
210
|
+
orderHashToString(hash) {
|
|
211
|
+
if (!hash?.id) {
|
|
212
|
+
return null;
|
|
213
|
+
}
|
|
214
|
+
const fieldAlias = this.getFieldAlias(hash.id);
|
|
215
|
+
if (fieldAlias === null) {
|
|
216
|
+
return null;
|
|
217
|
+
}
|
|
218
|
+
const direction = hash.desc ? 'DESC' : 'ASC';
|
|
219
|
+
return `${fieldAlias} ${direction}`;
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Timestamp literal cast — CRITICAL DISCOVERY (T07): MongoSQL does NOT
|
|
223
|
+
* accept the SQL-92 `TIMESTAMP 'literal'` form. Use `CAST('...' AS TIMESTAMP)`.
|
|
224
|
+
* Reference: https://www.mongodb.com/docs/sql-interface/language-reference/data-types/
|
|
225
|
+
* (and crates/native/src/translate.rs::date_filter_emits_match_referencing_created_at)
|
|
226
|
+
*/
|
|
227
|
+
timeStampCast(value) {
|
|
228
|
+
return `CAST(${value} AS TIMESTAMP)`;
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* datetime cast — MongoSQL has only `TIMESTAMP` (no separate `DATETIME` /
|
|
232
|
+
* `DATE` types), so `dateTimeCast` and `timeStampCast` produce the same SQL.
|
|
233
|
+
* SPEC FR-2 explicitly substitutes `TIMESTAMP` for `DATE`.
|
|
234
|
+
*/
|
|
235
|
+
dateTimeCast(value) {
|
|
236
|
+
return `CAST(${value} AS TIMESTAMP)`;
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* String cast — MongoSQL's string type is spelt `STRING`, not the SQL-92
|
|
240
|
+
* `TEXT` (BaseQuery's default) or MySQL's `CHAR`.
|
|
241
|
+
* Reference: https://www.mongodb.com/docs/sql-interface/language-reference/data-types/
|
|
242
|
+
*/
|
|
243
|
+
castToString(sql) {
|
|
244
|
+
return `CAST(${sql} AS STRING)`;
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Generic typed cast helper. MongoSQL accepts the standard CAST grammar;
|
|
248
|
+
* the *type name* must be one of MongoSQL's documented type tokens
|
|
249
|
+
* (BOOL, INT, LONG, DOUBLE, DECIMAL, STRING, TIMESTAMP, ARRAY, DOCUMENT).
|
|
250
|
+
*/
|
|
251
|
+
castSqlType(value, type) {
|
|
252
|
+
return `CAST(${value} AS ${type})`;
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Timezone conversion — MongoSQL has no `AT TIME ZONE` or `CONVERT_TZ`
|
|
256
|
+
* function (verified against the v1.8.5 grammar). Data is stored in UTC
|
|
257
|
+
* (BSON DateTime), and `inDbTimeZone()` (inherited) shifts JS-side
|
|
258
|
+
* timestamp parameters. For SQL-emitted field references we passthrough —
|
|
259
|
+
* correct for UTC data and matching "no conversion" semantics.
|
|
260
|
+
*
|
|
261
|
+
* Revisit if MongoSQL adds a timezone-aware function form, or if T14
|
|
262
|
+
* integration shows non-UTC dimensions break.
|
|
263
|
+
*/
|
|
264
|
+
convertTz(field) {
|
|
265
|
+
return field;
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* NOW() equivalent. MongoSQL's documented form for the current time is
|
|
269
|
+
* `CURRENT_TIMESTAMP` (SQL-92 keyword), not MySQL/Postgres `NOW()`.
|
|
270
|
+
*/
|
|
271
|
+
nowTimestampSql() {
|
|
272
|
+
return 'CURRENT_TIMESTAMP';
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Seconds since the Unix epoch. BaseQuery default uses
|
|
276
|
+
* `EXTRACT(EPOCH FROM NOW())`, but MongoSQL's `EXTRACT` does NOT support
|
|
277
|
+
* the `EPOCH` date-part (only YEAR/MONTH/WEEK/DAY/HOUR/MINUTE/SECOND/
|
|
278
|
+
* MILLISECOND/DAYOFYEAR/DAYOFWEEK/ISOWEEK/ISOWEEKDAY — see
|
|
279
|
+
* `algebrize_extract` in mongosql/src/algebrizer/definitions.rs).
|
|
280
|
+
*
|
|
281
|
+
* Use `DATEDIFF(SECOND, '1970-01-01T00:00:00Z', CURRENT_TIMESTAMP)`
|
|
282
|
+
* instead. Returns LONG (mongosql `$dateDiff`).
|
|
283
|
+
*/
|
|
284
|
+
unixTimestampSql() {
|
|
285
|
+
return `DATEDIFF(SECOND, ${this.timeStampCast("'1970-01-01T00:00:00Z'")}, ${this.nowTimestampSql()})`;
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* Parse a Cube/Postgres-style interval string ("1 day", "2 weeks",
|
|
289
|
+
* "1 year 6 months") into an ordered list of MongoSQL DATEADD components.
|
|
290
|
+
*
|
|
291
|
+
* Cube emits compound intervals for partition ranges and granularity
|
|
292
|
+
* offsets. MongoSQL's DATEADD takes a single `<date_part>`, so we apply
|
|
293
|
+
* each component as a chained DATEADD call (see `addInterval` /
|
|
294
|
+
* `subtractInterval`). Order is preserved from `parseSqlInterval` so the
|
|
295
|
+
* outermost DATEADD is the *last* component (matches semantics: applying
|
|
296
|
+
* `(YEAR, 1)` then `(MONTH, 6)` is equivalent to "1 year 6 months").
|
|
297
|
+
*
|
|
298
|
+
* Public for unit-testing the bridge in isolation; not on BaseQuery.
|
|
299
|
+
*/
|
|
300
|
+
intervalUnitsForMongo(interval) {
|
|
301
|
+
const parsed = parseSqlInterval(interval);
|
|
302
|
+
const components = [];
|
|
303
|
+
for (const [unit, value] of Object.entries(parsed)) {
|
|
304
|
+
const datePart = INTERVAL_UNIT_TO_DATE_PART[unit];
|
|
305
|
+
if (!datePart) {
|
|
306
|
+
throw new Error(`MongoSQL DATEADD does not support interval unit "${unit}" (from "${interval}")`);
|
|
307
|
+
}
|
|
308
|
+
components.push({ value, unit: datePart });
|
|
309
|
+
}
|
|
310
|
+
if (components.length === 0) {
|
|
311
|
+
throw new Error(`Cannot parse interval "${interval}" — produced no components`);
|
|
312
|
+
}
|
|
313
|
+
return components;
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* Add a Cube interval to a date expression. Compound intervals
|
|
317
|
+
* ("1 year 6 months") are emitted as chained DATEADD calls.
|
|
318
|
+
*
|
|
319
|
+
* MongoSQL has no `INTERVAL '...'` literal. The base implementation emits
|
|
320
|
+
* `${date} + interval '...'` which the parser rejects.
|
|
321
|
+
*/
|
|
322
|
+
addInterval(date, interval) {
|
|
323
|
+
return this.applyIntervalChain(date, this.intervalUnitsForMongo(interval), 1);
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* Subtract a Cube interval from a date expression. Implemented as DATEADD
|
|
327
|
+
* with negated values (so `subtractInterval('d', '1 month')` becomes
|
|
328
|
+
* `DATEADD(MONTH, -1, d)`). Compound intervals chain the same way as
|
|
329
|
+
* `addInterval`.
|
|
330
|
+
*/
|
|
331
|
+
subtractInterval(date, interval) {
|
|
332
|
+
return this.applyIntervalChain(date, this.intervalUnitsForMongo(interval), -1);
|
|
333
|
+
}
|
|
334
|
+
applyIntervalChain(date, components, sign) {
|
|
335
|
+
return components.reduce((acc, { value, unit }) => `DATEADD(${unit}, ${sign * value}, ${acc})`, date);
|
|
336
|
+
}
|
|
337
|
+
/**
|
|
338
|
+
* Printable interval string. MongoSQL has no INTERVAL literal so this is
|
|
339
|
+
* not safe to splice into emitted SQL — kept for diagnostic / error
|
|
340
|
+
* messages and for any BaseQuery code path we haven't audited yet (a
|
|
341
|
+
* future grep for `'1 day'` in SQL output would surface a regression).
|
|
342
|
+
*/
|
|
343
|
+
intervalString(interval) {
|
|
344
|
+
return `'${interval}'`;
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* Truncate a timestamp to a granularity boundary. MongoSQL's documented
|
|
348
|
+
* form is `DATETRUNC(<unit>, <date>[, <start_of_week>])`. For week we pin
|
|
349
|
+
* `'sunday'` explicitly: mongosql's `ScalarFunctionsRewritePass` defaults
|
|
350
|
+
* a missing third arg to `'sunday'` (per ast/rewrites/test.rs::
|
|
351
|
+
* `timestamp_trunc`), but Cube's tests should not depend on that
|
|
352
|
+
* implicit default — a future mongosql release could change it.
|
|
353
|
+
*/
|
|
354
|
+
timeGroupedColumn(granularity, dimension) {
|
|
355
|
+
const datePart = GRANULARITY_TO_DATE_PART[granularity];
|
|
356
|
+
if (!datePart) {
|
|
357
|
+
throw new Error(`MongoSQL dialect does not support granularity "${granularity}"`);
|
|
358
|
+
}
|
|
359
|
+
if (granularity === 'week') {
|
|
360
|
+
return `DATETRUNC(${datePart}, ${dimension}, 'sunday')`;
|
|
361
|
+
}
|
|
362
|
+
return `DATETRUNC(${datePart}, ${dimension})`;
|
|
363
|
+
}
|
|
364
|
+
/**
|
|
365
|
+
* Bucket `source` into intervals starting from `origin`. Cube uses this
|
|
366
|
+
* for custom (non-natural) granularities like "5 minutes" or "10 days".
|
|
367
|
+
*
|
|
368
|
+
* MongoSQL has no INTERVAL literal, so PostgresQuery's
|
|
369
|
+
* `'origin'::ts + INTERVAL N * FLOOR(EXTRACT(EPOCH ...))` form doesn't
|
|
370
|
+
* port. Instead we use the DATEADD/DATEDIFF identity:
|
|
371
|
+
*
|
|
372
|
+
* floor((source - origin) / interval) * interval + origin
|
|
373
|
+
*
|
|
374
|
+
* which becomes:
|
|
375
|
+
*
|
|
376
|
+
* DATEADD(unit, FLOOR(DATEDIFF(unit, origin, source) / N) * N, origin)
|
|
377
|
+
*
|
|
378
|
+
* Year and quarter intervals are normalised to MONTH (1 year = 12 months,
|
|
379
|
+
* 1 quarter = 3 months) so arithmetic doesn't depend on leap-day-aware
|
|
380
|
+
* second math. Every other unit (week / day / hour / minute / second /
|
|
381
|
+
* millisecond) is used as-is — DATEDIFF/DATEADD operate in the unit's
|
|
382
|
+
* native granularity which is the most precise viable choice.
|
|
383
|
+
*
|
|
384
|
+
* NOTE: only single-component intervals are supported here (matches
|
|
385
|
+
* Cube's custom-granularity inputs which are always one unit). Compound
|
|
386
|
+
* dateBin intervals would need a different strategy.
|
|
387
|
+
*/
|
|
388
|
+
dateBin(interval, source, origin) {
|
|
389
|
+
const components = this.intervalUnitsForMongo(interval);
|
|
390
|
+
if (components.length !== 1) {
|
|
391
|
+
throw new Error(`MongoSQL dateBin requires a single-unit interval; got "${interval}"`);
|
|
392
|
+
}
|
|
393
|
+
const [{ value, unit }] = components;
|
|
394
|
+
// Normalise year/quarter to MONTH so the unit aligns with calendar
|
|
395
|
+
// boundaries; everything else uses its native unit for max precision.
|
|
396
|
+
const usedUnit = unit === 'YEAR' || unit === 'QUARTER' ? 'MONTH' : unit;
|
|
397
|
+
const stride = unit === 'YEAR' ? value * 12 : unit === 'QUARTER' ? value * 3 : value;
|
|
398
|
+
const originExpr = this.dateTimeCast(`'${origin}'`);
|
|
399
|
+
return `DATEADD(${usedUnit}, FLOOR(DATEDIFF(${usedUnit}, ${originExpr}, ${source}) / ${stride}) * ${stride}, ${originExpr})`;
|
|
400
|
+
}
|
|
401
|
+
/**
|
|
402
|
+
* Generate the date-series SQL Cube uses for time-bucketed pre-aggregations.
|
|
403
|
+
* MongoSQL has no `VALUES (...)`, no recursive CTE, and no `generate_series`,
|
|
404
|
+
* so we emit a UNION ALL of literal-row SELECTs (MysqlQuery's strategy)
|
|
405
|
+
* and CAST in the outer projection. Identical row count to MysqlQuery's
|
|
406
|
+
* version; the difference is `CAST(... AS TIMESTAMP)` instead of
|
|
407
|
+
* MySQL-specific `TIMESTAMP(...)`.
|
|
408
|
+
*
|
|
409
|
+
* NOTE: emits N rows for an N-row series. For very large partition ranges
|
|
410
|
+
* Cube can pre-compute the row set in JS — there's no in-DB way to grow
|
|
411
|
+
* the series without recursive CTEs, which v1.8.5 doesn't support.
|
|
412
|
+
*/
|
|
413
|
+
seriesSql(timeDimension) {
|
|
414
|
+
const rows = timeDimension.timeSeries();
|
|
415
|
+
const union = rows
|
|
416
|
+
.map((row) => {
|
|
417
|
+
const [from, to] = row;
|
|
418
|
+
return `SELECT '${from}' f, '${to}' t`;
|
|
419
|
+
})
|
|
420
|
+
.join(' UNION ALL ');
|
|
421
|
+
const dateFrom = this.escapeColumnName('date_from');
|
|
422
|
+
const dateTo = this.escapeColumnName('date_to');
|
|
423
|
+
return `SELECT CAST(dates.f AS TIMESTAMP) AS ${dateFrom}, CAST(dates.t AS TIMESTAMP) AS ${dateTo} FROM (${union}) ${this.asSyntaxTable} dates`;
|
|
424
|
+
}
|
|
425
|
+
/**
|
|
426
|
+
* Override Cube's filter class for every filter on a MongoSQL query.
|
|
427
|
+
*
|
|
428
|
+
* Background (Gap 4 discovery): Cube's default `BaseFilter.likeIgnoreCase`
|
|
429
|
+
* emits `<col> [NOT] ILIKE <pattern>` for `contains`, `notContains`,
|
|
430
|
+
* `startsWith`, `notStartsWith`, `endsWith`, `notEndsWith`. mongosql
|
|
431
|
+
* v1.8.5's grammar does NOT include the `ILIKE` keyword (verified
|
|
432
|
+
* empirically against atlas-local — the parser reports
|
|
433
|
+
* `Error 2001: Unrecognized token ILIKE, expected: BETWEEN` /
|
|
434
|
+
* `expected COMMA, RIGHT_PAREN`). mongosql DOES support the standard
|
|
435
|
+
* SQL-92 `LIKE` keyword.
|
|
436
|
+
*
|
|
437
|
+
* Strategy: subclass BaseFilter and override `likeIgnoreCase` to
|
|
438
|
+
* emit `LOWER(<col>) LIKE LOWER(<pattern>)` instead of
|
|
439
|
+
* `<col> ILIKE <pattern>`. Wrapping both sides in `LOWER(...)`
|
|
440
|
+
* preserves case-insensitive semantics; mongosql's `LOWER` is the
|
|
441
|
+
* standard SQL function and round-trips strings unchanged for ASCII
|
|
442
|
+
* content. We do NOT use `ESCAPE` clauses here because Cube's
|
|
443
|
+
* `escapeWildcardChars` pre-escapes `%` and `_` with `\` and SQL's
|
|
444
|
+
* default LIKE escape character IS `\` per the SQL standard (mongosql
|
|
445
|
+
* v1.8.5 follows this).
|
|
446
|
+
*
|
|
447
|
+
* **Non-ASCII / Unicode caveat.** This override is ASCII-aware case
|
|
448
|
+
* folding only. mongosql v1.8.5 does not expose `COLLATE` at the SQL
|
|
449
|
+
* surface, so case-folding non-ASCII characters (e.g. the German
|
|
450
|
+
* sharp-s `ß` → `ss`, Turkish dotless-i, etc.) is NOT performed. For
|
|
451
|
+
* pure-Latin inputs (the dominant Cube use case) this is correct.
|
|
452
|
+
* For locale-sensitive case-insensitive search, use MongoDB's
|
|
453
|
+
* collation feature outside the SQL surface or pre-normalise data.
|
|
454
|
+
*/
|
|
455
|
+
newFilter(filter) {
|
|
456
|
+
return new MongoSqlFilter(this, filter);
|
|
457
|
+
}
|
|
458
|
+
/**
|
|
459
|
+
* Patch the SQL templates that drive the rest of BaseQuery's builders.
|
|
460
|
+
* Mirrors MysqlQuery.sqlTemplates()'s pattern of `super` + targeted
|
|
461
|
+
* overrides.
|
|
462
|
+
*
|
|
463
|
+
* T12b additions: remove the `expressions.interval` template (BaseQuery's
|
|
464
|
+
* default emits `INTERVAL '<x>'` — invalid MongoSQL) so any caller that
|
|
465
|
+
* tries to render an interval literal surfaces an error rather than
|
|
466
|
+
* silently emitting unparseable SQL. The arithmetic-emitting paths
|
|
467
|
+
* (subtractInterval/addInterval/dateBin) don't go through this template.
|
|
468
|
+
* Also drop `statements.generated_time_series_*` for the same reason —
|
|
469
|
+
* those are recursive-CTE forms that mongosql doesn't accept.
|
|
470
|
+
*/
|
|
471
|
+
sqlTemplates() {
|
|
472
|
+
const templates = super.sqlTemplates();
|
|
473
|
+
// Identifier quoting at the template layer (used by Cube's SQL planner).
|
|
474
|
+
templates.quotes.identifiers = '`';
|
|
475
|
+
templates.quotes.escape = '``';
|
|
476
|
+
// Type names — MongoSQL's spellings per the Language Reference.
|
|
477
|
+
// https://www.mongodb.com/docs/sql-interface/language-reference/data-types/
|
|
478
|
+
templates.types.string = 'STRING';
|
|
479
|
+
templates.types.boolean = 'BOOL';
|
|
480
|
+
templates.types.tinyint = 'INT';
|
|
481
|
+
templates.types.smallint = 'INT';
|
|
482
|
+
templates.types.integer = 'INT';
|
|
483
|
+
templates.types.bigint = 'LONG';
|
|
484
|
+
templates.types.float = 'DOUBLE';
|
|
485
|
+
templates.types.double = 'DOUBLE';
|
|
486
|
+
templates.types.decimal = 'DECIMAL';
|
|
487
|
+
templates.types.timestamp = 'TIMESTAMP';
|
|
488
|
+
// MongoSQL has no `DATE` / `TIME` / `INTERVAL` / `BINARY`; map to closest
|
|
489
|
+
// representable type or delete to surface an error if Cube ever asks.
|
|
490
|
+
templates.types.date = 'TIMESTAMP';
|
|
491
|
+
templates.types.time = 'TIMESTAMP';
|
|
492
|
+
delete templates.types.interval;
|
|
493
|
+
delete templates.types.binary;
|
|
494
|
+
// Drop INTERVAL-literal and recursive-CTE forms — mongosql v1.8.5
|
|
495
|
+
// rejects both. Anything that would have used these now routes through
|
|
496
|
+
// our typed overrides (addInterval/subtractInterval/seriesSql) or
|
|
497
|
+
// surfaces a clear missing-template error.
|
|
498
|
+
if (templates.expressions) {
|
|
499
|
+
delete templates.expressions.interval;
|
|
500
|
+
}
|
|
501
|
+
if (templates.statements) {
|
|
502
|
+
delete templates.statements.generated_time_series_select;
|
|
503
|
+
delete templates.statements.generated_time_series_with_cte_range_source;
|
|
504
|
+
}
|
|
505
|
+
return templates;
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
exports.MongoSqlQuery = MongoSqlQuery;
|
|
509
|
+
/**
|
|
510
|
+
* Filter override for MongoSQL — rewrites `ILIKE` to `LOWER(...) LIKE LOWER(...)`.
|
|
511
|
+
*
|
|
512
|
+
* See `MongoSqlQuery.newFilter` for the rationale. Exported so unit tests
|
|
513
|
+
* can exercise `likeIgnoreCase` in isolation without instantiating the
|
|
514
|
+
* whole query stack.
|
|
515
|
+
*/
|
|
516
|
+
class MongoSqlFilter extends schema_compiler_1.BaseFilter {
|
|
517
|
+
/**
|
|
518
|
+
* Emit `LOWER(<col>) [NOT] LIKE LOWER(<wrapped-param>)` for mongosql.
|
|
519
|
+
*
|
|
520
|
+
* Layout mirrors BaseFilter.likeIgnoreCase:
|
|
521
|
+
* - `type === 'contains'`: wrap pattern with `'%' || ... || '%'`
|
|
522
|
+
* - `type === 'starts'`: suffix with `|| '%'` only (no prefix)
|
|
523
|
+
* - `type === 'ends'`: prefix with `'%' ||` only (no suffix)
|
|
524
|
+
*
|
|
525
|
+
* Cube's BaseFilter passes type as 'contains' / 'starts' / 'ends'
|
|
526
|
+
* (NOT the camelized operator — see BaseFilter.likeOr where `type`
|
|
527
|
+
* is hardcoded to one of those three values).
|
|
528
|
+
*
|
|
529
|
+
* `allocateParam` returns Cube's `?` placeholder; the driver's
|
|
530
|
+
* `substituteParameters` inlines literals before sending to mongosql.
|
|
531
|
+
*/
|
|
532
|
+
likeIgnoreCase(column, not, param, type) {
|
|
533
|
+
const p = !type || type === 'contains' || type === 'ends' ? "'%' || " : '';
|
|
534
|
+
const s = !type || type === 'contains' || type === 'starts' ? " || '%'" : '';
|
|
535
|
+
// Wrap the param-allocated placeholder in LOWER so the parser sees
|
|
536
|
+
// `LOWER(<col>) [NOT] LIKE LOWER('%' || ? || '%')`. mongosql's LOWER
|
|
537
|
+
// accepts the concatenated string expression as input.
|
|
538
|
+
//
|
|
539
|
+
// **Performance.** `LOWER(<col>)` is non-sargable — it prevents
|
|
540
|
+
// MongoDB from using any B-tree index on `<col>`. For high-volume
|
|
541
|
+
// case-insensitive search consider EITHER (a) materialising a
|
|
542
|
+
// lowercase shadow column at ingestion time and indexing that, OR
|
|
543
|
+
// (b) using MongoDB's collation feature outside the SQL surface
|
|
544
|
+
// (mongosql v1.8.5 does not expose `COLLATE`).
|
|
545
|
+
const wrapped = `${p}${this.allocateParam(param)}${s}`;
|
|
546
|
+
const direction = not ? ' NOT' : '';
|
|
547
|
+
return `LOWER(${column})${direction} LIKE LOWER(${wrapped})`;
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
exports.MongoSqlFilter = MongoSqlFilter;
|
|
551
|
+
//# sourceMappingURL=MongoSqlQuery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MongoSqlQuery.js","sourceRoot":"","sources":["../src/MongoSqlQuery.ts"],"names":[],"mappings":"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"}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/** Subset of `process.env` we depend on. */
|
|
2
|
+
export type EnvLike = NodeJS.ProcessEnv;
|
|
3
|
+
/** Result of resolving env vars + overrides into a connection-string + driver options. */
|
|
4
|
+
export interface ResolvedUriConfig {
|
|
5
|
+
/** Final URI to hand to the Rust client. Always contains all env-driven params. */
|
|
6
|
+
uri: string;
|
|
7
|
+
/**
|
|
8
|
+
* Effective per-query timeout in milliseconds (drives the aggregation
|
|
9
|
+
* pipeline's `maxTimeMS`). Resolved precedence:
|
|
10
|
+
* 1. `override.queryTimeoutMs` (constructor arg)
|
|
11
|
+
* 2. `CUBEJS_DB_QUERY_TIMEOUT` (Cube-standard, duration-aware)
|
|
12
|
+
* 3. `CUBEJS_MONGOSQL_QUERY_TIMEOUT_MS` (legacy, bare number)
|
|
13
|
+
* Undefined if none set; the native side then uses its built-in default.
|
|
14
|
+
*/
|
|
15
|
+
queryTimeoutMs: number | undefined;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Resolve `(uri, queryTimeoutMs)` from constructor overrides + env.
|
|
19
|
+
*
|
|
20
|
+
* Throws `MONGOSQL_CONFIG_INVALID` when:
|
|
21
|
+
* - neither explicit uri / `CUBEJS_DB_URL` / `CUBEJS_DB_URI` is set
|
|
22
|
+
* AND `CUBEJS_DB_HOST` is also unset;
|
|
23
|
+
* - a duration env var is malformed (e.g. `"forever"`);
|
|
24
|
+
* - a numeric env var fails to parse.
|
|
25
|
+
*/
|
|
26
|
+
export declare function resolveUriConfig(overrideUri: string | undefined, env: EnvLike): ResolvedUriConfig;
|
|
27
|
+
/** Same as `parseDurationToMillisString` but returns the integer directly. Throws on malformed input. */
|
|
28
|
+
export declare function parseDurationToMillis(raw: string, envVarName: string): number;
|
|
29
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAyEA,4CAA4C;AAC5C,MAAM,MAAM,OAAO,GAAG,MAAM,CAAC,UAAU,CAAC;AAExC,0FAA0F;AAC1F,MAAM,WAAW,iBAAiB;IAChC,mFAAmF;IACnF,GAAG,EAAE,MAAM,CAAC;IACZ;;;;;;;OAOG;IACH,cAAc,EAAE,MAAM,GAAG,SAAS,CAAC;CACpC;AA+CD;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,EAAE,GAAG,EAAE,OAAO,GAAG,iBAAiB,CAiBjG;AAsLD,yGAAyG;AACzG,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAQ7E"}
|