@gscdump/engine 0.28.3 → 0.30.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.
@@ -18,4 +18,27 @@ declare const METRIC_EXPR: Record<Metric, string>;
18
18
  * on the resolved column expression so drizzle can pass a column ref.
19
19
  */
20
20
  declare function topLevelPagePredicateSql(pathExpr: string): string;
21
- export { METRIC_EXPR, escapeLike, topLevelPagePredicateSql };
21
+ /**
22
+ * How a canonicalized date column is emitted by {@link dateReplaceClause}:
23
+ * - `'date'` keeps a real `DATE` value (`CAST(col AS DATE)`). Right for views
24
+ * and `.duckdb` exports the app re-queries, where the column type matters.
25
+ * - `'string'` emits an ISO `YYYY-MM-DD` string (`strftime(CAST(col AS DATE)…)`).
26
+ * Right for row materialisation to JSON/CSV/NDJSON, where a `DATE` would
27
+ * serialize as an opaque object / epoch.
28
+ */
29
+ type DateCanonicalForm = 'date' | 'string';
30
+ /**
31
+ * Build a `read_parquet` `REPLACE (…)` clause that canonicalizes legacy `date`
32
+ * columns. `date` lands as VARCHAR in older parquets (BYTE_ARRAY/UTF8, written
33
+ * before the schema enforced DATE); DuckDB infers the column type from the file,
34
+ * so without this every read path would expose VARCHAR despite SCHEMAS declaring
35
+ * DATE. The `CAST(col AS DATE)` is a no-op for already-DATE columns and
36
+ * vectorized parsing for VARCHAR ones, so output stays canonical either way.
37
+ *
38
+ * Pure: the caller passes the table's DATE column names (derived from `SCHEMAS`)
39
+ * so this fragment carries no schema/drizzle dependency. Returns `''` when the
40
+ * table has no DATE columns, so callers can interpolate it unconditionally:
41
+ * `SELECT * ${dateReplaceClause(cols)} FROM read_parquet(…)`.
42
+ */
43
+ declare function dateReplaceClause(dateColumns: readonly string[], form?: DateCanonicalForm): string;
44
+ export { DateCanonicalForm, METRIC_EXPR, dateReplaceClause, escapeLike, topLevelPagePredicateSql };
@@ -10,4 +10,9 @@ const METRIC_EXPR = {
10
10
  function topLevelPagePredicateSql(pathExpr) {
11
11
  return `LENGTH(${pathExpr}) - LENGTH(REPLACE(${pathExpr}, '/', '')) <= 1`;
12
12
  }
13
- export { METRIC_EXPR, escapeLike, topLevelPagePredicateSql };
13
+ function dateReplaceClause(dateColumns, form = "string") {
14
+ if (dateColumns.length === 0) return "";
15
+ const cast = (n) => form === "date" ? `CAST(${n} AS DATE) AS ${n}` : `strftime(CAST(${n} AS DATE), '%Y-%m-%d') AS ${n}`;
16
+ return `REPLACE (${dateColumns.map(cast).join(", ")})`;
17
+ }
18
+ export { METRIC_EXPR, dateReplaceClause, escapeLike, topLevelPagePredicateSql };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@gscdump/engine",
3
3
  "type": "module",
4
- "version": "0.28.3",
4
+ "version": "0.30.0",
5
5
  "description": "Append-only Parquet/DuckDB storage engine + planner + adapters for the gscdump pipeline. Node + edge runtimes; opt-in heavy peers.",
6
6
  "author": {
7
7
  "name": "Harlan Wilton",
@@ -172,8 +172,8 @@
172
172
  },
173
173
  "peerDependencies": {
174
174
  "@duckdb/duckdb-wasm": "^1.32.0",
175
- "hyparquet": "^1.26.0",
176
- "hyparquet-writer": "^0.15.6"
175
+ "hyparquet": "^1.26.1",
176
+ "hyparquet-writer": "^0.16.1"
177
177
  },
178
178
  "peerDependenciesMeta": {
179
179
  "@duckdb/duckdb-wasm": {
@@ -188,11 +188,11 @@
188
188
  },
189
189
  "dependencies": {
190
190
  "drizzle-orm": "1.0.0-rc.3",
191
- "hyparquet": "^1.26.0",
192
- "hyparquet-writer": "^0.15.6",
191
+ "hyparquet": "^1.26.1",
192
+ "hyparquet-writer": "^0.16.1",
193
193
  "proper-lockfile": "^4.1.2",
194
- "@gscdump/contracts": "0.28.3",
195
- "gscdump": "0.28.3"
194
+ "@gscdump/contracts": "0.30.0",
195
+ "gscdump": "0.30.0"
196
196
  },
197
197
  "devDependencies": {
198
198
  "@duckdb/duckdb-wasm": "^1.32.0",