@gscdump/engine-duckdb-wasm 0.36.2 → 0.36.3
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/dist/index.mjs +19 -12
- package/package.json +4 -4
package/dist/index.mjs
CHANGED
|
@@ -24,11 +24,18 @@ const DIM_COLUMN = {
|
|
|
24
24
|
date: "date",
|
|
25
25
|
searchAppearance: "search_appearance"
|
|
26
26
|
};
|
|
27
|
-
function
|
|
27
|
+
function quoteIdent(value) {
|
|
28
|
+
return `"${value.replace(/"/g, "\"\"")}"`;
|
|
29
|
+
}
|
|
30
|
+
function qualifiedColumn(table, column) {
|
|
31
|
+
return `${quoteIdent(table)}.${quoteIdent(column)}`;
|
|
32
|
+
}
|
|
33
|
+
function queryCanonicalExpr(table) {
|
|
34
|
+
const queryRef = qualifiedColumn(table, "query");
|
|
28
35
|
return `COALESCE((SELECT qd.query_canonical FROM query_dim qd WHERE qd.query = ${queryRef} LIMIT 1), ${queryRef})`;
|
|
29
36
|
}
|
|
30
|
-
function dimExpr(dim) {
|
|
31
|
-
return dim === "queryCanonical" ? queryCanonicalExpr() : DIM_COLUMN[dim] ?? dim;
|
|
37
|
+
function dimExpr(dim, table) {
|
|
38
|
+
return dim === "queryCanonical" ? queryCanonicalExpr(table) : DIM_COLUMN[dim] ?? dim;
|
|
32
39
|
}
|
|
33
40
|
function tableForDimensions(dims) {
|
|
34
41
|
const set = new Set(dims.filter((d) => d !== "date"));
|
|
@@ -133,7 +140,7 @@ function moverClause(movers) {
|
|
|
133
140
|
default: throw new Error(`[archetype-sql] unknown movers mode: ${movers}`);
|
|
134
141
|
}
|
|
135
142
|
}
|
|
136
|
-
function facetPredicate(query) {
|
|
143
|
+
function facetPredicate(query, table) {
|
|
137
144
|
const facets = query.facets;
|
|
138
145
|
if (!facets?.length) return {
|
|
139
146
|
sql: "",
|
|
@@ -142,7 +149,7 @@ function facetPredicate(query) {
|
|
|
142
149
|
const parts = [];
|
|
143
150
|
const params = [];
|
|
144
151
|
for (const f of facets) {
|
|
145
|
-
const col = dimExpr(f.column);
|
|
152
|
+
const col = dimExpr(f.column, table);
|
|
146
153
|
switch (f.op) {
|
|
147
154
|
case "eq":
|
|
148
155
|
parts.push(`${col} = ?`);
|
|
@@ -177,7 +184,7 @@ function compileArchetypeSql(query) {
|
|
|
177
184
|
}
|
|
178
185
|
case "entity-daily-timeseries": {
|
|
179
186
|
const table = tableForDimensions([query.entity.dimension]);
|
|
180
|
-
const col = dimExpr(query.entity.dimension);
|
|
187
|
+
const col = dimExpr(query.entity.dimension, table);
|
|
181
188
|
const where = rangePredicate(query);
|
|
182
189
|
return {
|
|
183
190
|
table,
|
|
@@ -187,7 +194,7 @@ function compileArchetypeSql(query) {
|
|
|
187
194
|
}
|
|
188
195
|
case "entity-daily-sparkline": {
|
|
189
196
|
const table = tableForDimensions([query.dimension]);
|
|
190
|
-
const col = dimExpr(query.dimension);
|
|
197
|
+
const col = dimExpr(query.dimension, table);
|
|
191
198
|
const where = rangePredicate(query);
|
|
192
199
|
if (query.entities.length === 0) throw new Error("[archetype-sql] entity-daily-sparkline requires resolved entities");
|
|
193
200
|
const placeholders = query.entities.map(() => "?").join(", ");
|
|
@@ -246,8 +253,8 @@ function compileArchetypeSql(query) {
|
|
|
246
253
|
params
|
|
247
254
|
};
|
|
248
255
|
}
|
|
249
|
-
const col = dimExpr(query.dimension);
|
|
250
|
-
const facet = facetPredicate(query);
|
|
256
|
+
const col = dimExpr(query.dimension, table);
|
|
257
|
+
const facet = facetPredicate(query, table);
|
|
251
258
|
const totalCol = query.includeTotal ? ", COUNT(*) OVER() AS __total" : "";
|
|
252
259
|
if (cmp) {
|
|
253
260
|
const curCols = metricList.map((m) => coalesceMetric(m, "c", m)).join(", ");
|
|
@@ -296,7 +303,7 @@ function compileArchetypeSql(query) {
|
|
|
296
303
|
const matchParts = [];
|
|
297
304
|
const matchParams = [];
|
|
298
305
|
for (const [dim, value] of Object.entries(query.match)) {
|
|
299
|
-
const col = dimExpr(dim);
|
|
306
|
+
const col = dimExpr(dim, table);
|
|
300
307
|
if (!col) throw new Error(`[archetype-sql] single-row-lookup: unknown dimension ${dim}`);
|
|
301
308
|
matchParts.push(`${col} = ?`);
|
|
302
309
|
matchParams.push(value);
|
|
@@ -320,7 +327,7 @@ function compileArchetypeSql(query) {
|
|
|
320
327
|
...where.params
|
|
321
328
|
]
|
|
322
329
|
};
|
|
323
|
-
const col = dimExpr(query.seriesDimension);
|
|
330
|
+
const col = dimExpr(query.seriesDimension, table);
|
|
324
331
|
return {
|
|
325
332
|
table,
|
|
326
333
|
sql: `SELECT date, ${col} AS ${query.seriesDimension}, ${metricExpr(query.metric)} AS ${query.metric} FROM ${table} WHERE ${where.sql} GROUP BY date, ${col} ORDER BY date, ${col}`,
|
|
@@ -330,7 +337,7 @@ function compileArchetypeSql(query) {
|
|
|
330
337
|
case "two-dimension-detail": {
|
|
331
338
|
const table = "page_queries";
|
|
332
339
|
const where = rangePredicate(query);
|
|
333
|
-
const facet = facetPredicate(query);
|
|
340
|
+
const facet = facetPredicate(query, table);
|
|
334
341
|
const filterParts = [];
|
|
335
342
|
const filterParams = [];
|
|
336
343
|
if (query.filter?.page) {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gscdump/engine-duckdb-wasm",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.36.
|
|
4
|
+
"version": "0.36.3",
|
|
5
5
|
"description": "DuckDB-WASM engine adapter for @gscdump/analysis — typed browser analytics against parquet via R2.",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Harlan Wilton",
|
|
@@ -45,9 +45,9 @@
|
|
|
45
45
|
},
|
|
46
46
|
"dependencies": {
|
|
47
47
|
"drizzle-orm": "1.0.0-rc.3",
|
|
48
|
-
"@gscdump/
|
|
49
|
-
"gscdump": "0.36.
|
|
50
|
-
"
|
|
48
|
+
"@gscdump/contracts": "0.36.3",
|
|
49
|
+
"@gscdump/engine": "0.36.3",
|
|
50
|
+
"gscdump": "0.36.3"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
53
|
"@duckdb/duckdb-wasm": "^1.32.0",
|