@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.
Files changed (2) hide show
  1. package/dist/index.mjs +19 -12
  2. 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 queryCanonicalExpr(queryRef = "query") {
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.2",
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/engine": "0.36.2",
49
- "gscdump": "0.36.2",
50
- "@gscdump/contracts": "0.36.2"
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",