@gscdump/engine 0.40.2 → 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/README.md +4 -4
- package/dist/_chunks/duckdb.d.mts +2 -9
- package/dist/_chunks/engine.mjs +3 -7
- package/dist/_chunks/entities.mjs +1 -1
- package/dist/_chunks/index.d.mts +3 -8
- package/dist/_chunks/index2.d.mts +1 -2
- package/dist/_chunks/libs/hyparquet-compressors.mjs +1 -1
- package/dist/_chunks/libs/hyparquet.mjs +1 -63
- package/dist/_chunks/libs/icebird.d.mts +1 -81
- package/dist/_chunks/libs/icebird.mjs +4 -330
- package/dist/_chunks/parquet-plan.mjs +248 -3
- package/dist/_chunks/resolver.mjs +16 -2
- package/dist/_chunks/schema.d.mts +2 -2
- package/dist/_chunks/sink.d.mts +4 -5
- package/dist/_chunks/source.mjs +3 -3
- package/dist/_chunks/storage.d.mts +1 -43
- package/dist/_chunks/types.d.mts +8 -0
- package/dist/adapters/node.d.mts +1 -11
- package/dist/adapters/node.mjs +1 -1
- package/dist/analyzer/index.d.mts +1 -1
- package/dist/entities.d.mts +2 -10
- package/dist/entities.mjs +2 -2
- package/dist/iceberg/index.d.mts +2 -3
- package/dist/iceberg/index.mjs +12 -12
- package/dist/index.d.mts +83 -2
- package/dist/index.mjs +365 -6
- package/dist/period/index.d.mts +2 -2
- package/dist/period/index.mjs +1 -1
- package/dist/planner.mjs +1 -2
- package/dist/resolver/index.d.mts +2 -9
- package/dist/resolver/index.mjs +2 -2
- package/dist/rollups.d.mts +3 -20
- package/dist/rollups.mjs +5 -5
- package/dist/scope.d.mts +1 -2
- package/dist/scope.mjs +1 -1
- package/dist/source/index.d.mts +2 -2
- package/dist/source/index.mjs +2 -2
- package/dist/sql-bind.d.mts +1 -29
- package/dist/sql-bind.mjs +1 -1
- package/package.json +7 -22
- package/dist/_chunks/compaction.mjs +0 -251
- package/dist/adapters/r2-manifest.d.mts +0 -82
- package/dist/adapters/r2-manifest.mjs +0 -364
- package/dist/compaction-public.d.mts +0 -15
- package/dist/compaction-public.mjs +0 -5
- package/dist/snapshot.d.mts +0 -2
- package/dist/snapshot.mjs +0 -1
|
@@ -1,7 +1,252 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { dayPartition, inferSearchType, mondayOfWeek, monthPartition, objectKey, quarterOfMonth, quarterPartition, weekPartition } from "./layout.mjs";
|
|
2
|
+
import { currentSchemaVersion, dimensionToColumn } from "./schema.mjs";
|
|
3
3
|
import { METRIC_EXPR, escapeLike, topLevelPagePredicateSql } from "../sql-fragments.mjs";
|
|
4
|
+
import { MS_PER_DAY } from "gscdump/dates";
|
|
4
5
|
import { buildLogicalPlan } from "gscdump/query/plan";
|
|
6
|
+
const DAILY_PARTITION_RE = /^daily\/(\d{4}-\d{2}-\d{2})$/;
|
|
7
|
+
const WEEKLY_PARTITION_RE = /^weekly\/(\d{4}-\d{2}-\d{2})$/;
|
|
8
|
+
const MONTHLY_PARTITION_RE = /^monthly\/(\d{4}-\d{2})$/;
|
|
9
|
+
const QUARTERLY_PARTITION_RE = /^quarterly\/(\d{4})-Q([1-4])$/;
|
|
10
|
+
const DEFAULT_THRESHOLDS = {
|
|
11
|
+
raw: 7,
|
|
12
|
+
d7: 30,
|
|
13
|
+
d30: 90
|
|
14
|
+
};
|
|
15
|
+
const PENDING_WINDOW_DAYS = 4;
|
|
16
|
+
const STAGES = [
|
|
17
|
+
{
|
|
18
|
+
inputTier: "raw",
|
|
19
|
+
outputTier: "d7",
|
|
20
|
+
cutoffDays: DEFAULT_THRESHOLDS.raw,
|
|
21
|
+
bucketKey: (e) => {
|
|
22
|
+
const m = e.partition.match(DAILY_PARTITION_RE);
|
|
23
|
+
if (!m) return void 0;
|
|
24
|
+
return mondayOfWeek(m[1]);
|
|
25
|
+
},
|
|
26
|
+
bucketLatestMs: (monday) => Date.parse(`${monday}T00:00:00Z`) + 6 * MS_PER_DAY,
|
|
27
|
+
outputPartition: weekPartition
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
inputTier: "d7",
|
|
31
|
+
outputTier: "d30",
|
|
32
|
+
cutoffDays: DEFAULT_THRESHOLDS.d7,
|
|
33
|
+
bucketKey: (e) => {
|
|
34
|
+
const m = e.partition.match(WEEKLY_PARTITION_RE);
|
|
35
|
+
if (!m) return void 0;
|
|
36
|
+
return m[1].slice(0, 7);
|
|
37
|
+
},
|
|
38
|
+
bucketLatestMs: monthEndMs,
|
|
39
|
+
outputPartition: monthPartition
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
inputTier: "d30",
|
|
43
|
+
outputTier: "d90",
|
|
44
|
+
cutoffDays: DEFAULT_THRESHOLDS.d30,
|
|
45
|
+
bucketKey: (e) => {
|
|
46
|
+
const m = e.partition.match(MONTHLY_PARTITION_RE);
|
|
47
|
+
if (!m) return void 0;
|
|
48
|
+
return quarterOfMonth(m[1]);
|
|
49
|
+
},
|
|
50
|
+
bucketLatestMs: quarterEndMs,
|
|
51
|
+
outputPartition: quarterPartition
|
|
52
|
+
}
|
|
53
|
+
];
|
|
54
|
+
async function compactTieredImpl(deps, ctx, now, overrides = {}) {
|
|
55
|
+
const thresholds = {
|
|
56
|
+
...DEFAULT_THRESHOLDS,
|
|
57
|
+
...overrides
|
|
58
|
+
};
|
|
59
|
+
const stagesWithThresholds = STAGES.map((s) => ({
|
|
60
|
+
...s,
|
|
61
|
+
cutoffDays: s.outputTier === "d7" ? thresholds.raw : s.outputTier === "d30" ? thresholds.d7 : thresholds.d30
|
|
62
|
+
}));
|
|
63
|
+
for (const stage of stagesWithThresholds) await runStage(deps, ctx, stage, now);
|
|
64
|
+
}
|
|
65
|
+
async function runStage(deps, ctx, stage, now) {
|
|
66
|
+
const cutoff = now - Math.max(stage.cutoffDays, PENDING_WINDOW_DAYS) * MS_PER_DAY;
|
|
67
|
+
const candidates = await deps.manifestStore.listLive({
|
|
68
|
+
userId: ctx.userId,
|
|
69
|
+
siteId: ctx.siteId,
|
|
70
|
+
table: ctx.table,
|
|
71
|
+
tier: stage.inputTier
|
|
72
|
+
});
|
|
73
|
+
const buckets = /* @__PURE__ */ new Map();
|
|
74
|
+
for (const entry of candidates) {
|
|
75
|
+
if (entry.partition.startsWith("hourly/")) continue;
|
|
76
|
+
const key = stage.bucketKey(entry);
|
|
77
|
+
if (!key) continue;
|
|
78
|
+
if (stage.bucketLatestMs(key) >= cutoff) continue;
|
|
79
|
+
const compositeKey = `${inferSearchType(entry)}\0${key}`;
|
|
80
|
+
if (!buckets.has(compositeKey)) buckets.set(compositeKey, []);
|
|
81
|
+
buckets.get(compositeKey).push(entry);
|
|
82
|
+
}
|
|
83
|
+
for (const [compositeKey, entries] of buckets) {
|
|
84
|
+
const [searchType, bucket] = compositeKey.split("\0");
|
|
85
|
+
const targetPartition = stage.outputPartition(bucket);
|
|
86
|
+
if (entries.length === 1 && entries[0].partition === targetPartition) continue;
|
|
87
|
+
await deps.manifestStore.withLock({
|
|
88
|
+
userId: ctx.userId,
|
|
89
|
+
siteId: ctx.siteId,
|
|
90
|
+
table: ctx.table,
|
|
91
|
+
partition: targetPartition
|
|
92
|
+
}, async () => {
|
|
93
|
+
const key = objectKey(ctx, ctx.table, targetPartition, now, searchType);
|
|
94
|
+
const { bytes, rowCount } = await deps.codec.compactRows({ table: ctx.table }, entries.map((e) => e.objectKey), key, deps.dataSource);
|
|
95
|
+
const newEntry = {
|
|
96
|
+
userId: ctx.userId,
|
|
97
|
+
siteId: ctx.siteId,
|
|
98
|
+
table: ctx.table,
|
|
99
|
+
partition: targetPartition,
|
|
100
|
+
objectKey: key,
|
|
101
|
+
rowCount,
|
|
102
|
+
bytes,
|
|
103
|
+
createdAt: now,
|
|
104
|
+
schemaVersion: currentSchemaVersion(ctx.table),
|
|
105
|
+
tier: stage.outputTier,
|
|
106
|
+
...searchType !== "web" ? { searchType } : {}
|
|
107
|
+
};
|
|
108
|
+
await deps.manifestStore.registerVersion(newEntry, entries);
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
function enumeratePartitions(startDate, endDate) {
|
|
113
|
+
const out = [];
|
|
114
|
+
const [sy, sm, sd] = startDate.split("-").map(Number);
|
|
115
|
+
const [ey, em, ed] = endDate.split("-").map(Number);
|
|
116
|
+
const start = Date.UTC(sy, sm - 1, sd);
|
|
117
|
+
const end = Date.UTC(ey, em - 1, ed);
|
|
118
|
+
if (end < start) return out;
|
|
119
|
+
const seenWeeks = /* @__PURE__ */ new Set();
|
|
120
|
+
const seenMonths = /* @__PURE__ */ new Set();
|
|
121
|
+
const seenQuarters = /* @__PURE__ */ new Set();
|
|
122
|
+
for (let t = start; t <= end; t += 864e5) {
|
|
123
|
+
const d = new Date(t);
|
|
124
|
+
const y = d.getUTCFullYear();
|
|
125
|
+
const m = String(d.getUTCMonth() + 1).padStart(2, "0");
|
|
126
|
+
const isoDay = `${y}-${m}-${String(d.getUTCDate()).padStart(2, "0")}`;
|
|
127
|
+
const isoMonth = `${y}-${m}`;
|
|
128
|
+
out.push(dayPartition(isoDay));
|
|
129
|
+
const monday = mondayOfWeek(isoDay);
|
|
130
|
+
if (!seenWeeks.has(monday)) {
|
|
131
|
+
seenWeeks.add(monday);
|
|
132
|
+
out.push(weekPartition(monday));
|
|
133
|
+
}
|
|
134
|
+
if (!seenMonths.has(isoMonth)) {
|
|
135
|
+
seenMonths.add(isoMonth);
|
|
136
|
+
out.push(monthPartition(isoMonth));
|
|
137
|
+
}
|
|
138
|
+
const quarter = quarterOfMonth(isoMonth);
|
|
139
|
+
if (!seenQuarters.has(quarter)) {
|
|
140
|
+
seenQuarters.add(quarter);
|
|
141
|
+
out.push(quarterPartition(quarter));
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
return out;
|
|
145
|
+
}
|
|
146
|
+
function partitionSpan(partition) {
|
|
147
|
+
let m = partition.match(DAILY_PARTITION_RE);
|
|
148
|
+
if (m) {
|
|
149
|
+
const ms = Date.parse(`${m[1]}T00:00:00Z`);
|
|
150
|
+
return {
|
|
151
|
+
rank: 0,
|
|
152
|
+
startMs: ms,
|
|
153
|
+
endMs: ms
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
m = partition.match(WEEKLY_PARTITION_RE);
|
|
157
|
+
if (m) {
|
|
158
|
+
const ms = Date.parse(`${m[1]}T00:00:00Z`);
|
|
159
|
+
return {
|
|
160
|
+
rank: 1,
|
|
161
|
+
startMs: ms,
|
|
162
|
+
endMs: ms + 6 * MS_PER_DAY
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
m = partition.match(MONTHLY_PARTITION_RE);
|
|
166
|
+
if (m) {
|
|
167
|
+
const [y, mo] = m[1].split("-").map(Number);
|
|
168
|
+
return {
|
|
169
|
+
rank: 2,
|
|
170
|
+
startMs: Date.UTC(y, mo - 1, 1),
|
|
171
|
+
endMs: Date.UTC(y, mo, 0)
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
m = partition.match(QUARTERLY_PARTITION_RE);
|
|
175
|
+
if (m) {
|
|
176
|
+
const y = Number(m[1]);
|
|
177
|
+
const q = Number(m[2]);
|
|
178
|
+
return {
|
|
179
|
+
rank: 3,
|
|
180
|
+
startMs: Date.UTC(y, (q - 1) * 3, 1),
|
|
181
|
+
endMs: Date.UTC(y, q * 3, 0)
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
function splitOverlappingTiers(entries, queryRange) {
|
|
186
|
+
const rangeStartMs = queryRange ? Date.parse(`${queryRange.start}T00:00:00Z`) : void 0;
|
|
187
|
+
const rangeEndMs = queryRange ? Date.parse(`${queryRange.end}T00:00:00Z`) : void 0;
|
|
188
|
+
const spanned = [];
|
|
189
|
+
const kept = [];
|
|
190
|
+
const subsumed = [];
|
|
191
|
+
const clampToRange = Number.isFinite(rangeStartMs) && Number.isFinite(rangeEndMs);
|
|
192
|
+
for (const entry of entries) {
|
|
193
|
+
const span = partitionSpan(entry.partition);
|
|
194
|
+
if (!span) {
|
|
195
|
+
kept.push(entry);
|
|
196
|
+
continue;
|
|
197
|
+
}
|
|
198
|
+
const startMs = clampToRange ? Math.max(span.startMs, rangeStartMs) : span.startMs;
|
|
199
|
+
const endMs = clampToRange ? Math.min(span.endMs, rangeEndMs) : span.endMs;
|
|
200
|
+
if (queryRange && startMs > endMs) {
|
|
201
|
+
subsumed.push(entry);
|
|
202
|
+
continue;
|
|
203
|
+
}
|
|
204
|
+
spanned.push({
|
|
205
|
+
entry,
|
|
206
|
+
rank: span.rank,
|
|
207
|
+
startMs,
|
|
208
|
+
endMs
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
spanned.sort((a, b) => a.rank - b.rank || b.entry.createdAt - a.entry.createdAt);
|
|
212
|
+
const coveredBySearchType = /* @__PURE__ */ new Map();
|
|
213
|
+
for (const { entry, startMs, endMs } of spanned) {
|
|
214
|
+
const slice = inferSearchType(entry);
|
|
215
|
+
let covered = coveredBySearchType.get(slice);
|
|
216
|
+
if (!covered) {
|
|
217
|
+
covered = /* @__PURE__ */ new Set();
|
|
218
|
+
coveredBySearchType.set(slice, covered);
|
|
219
|
+
}
|
|
220
|
+
let fullyCovered = true;
|
|
221
|
+
for (let dayMs = startMs; dayMs <= endMs; dayMs += MS_PER_DAY) if (!covered.has(dayMs)) {
|
|
222
|
+
fullyCovered = false;
|
|
223
|
+
break;
|
|
224
|
+
}
|
|
225
|
+
if (fullyCovered) {
|
|
226
|
+
subsumed.push(entry);
|
|
227
|
+
continue;
|
|
228
|
+
}
|
|
229
|
+
kept.push(entry);
|
|
230
|
+
for (let dayMs = startMs; dayMs <= endMs; dayMs += MS_PER_DAY) covered.add(dayMs);
|
|
231
|
+
}
|
|
232
|
+
return {
|
|
233
|
+
kept,
|
|
234
|
+
subsumed
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
function dedupeOverlappingTiers(entries, queryRange) {
|
|
238
|
+
return splitOverlappingTiers(entries, queryRange).kept;
|
|
239
|
+
}
|
|
240
|
+
function monthEndMs(month) {
|
|
241
|
+
const [y, m] = month.split("-").map(Number);
|
|
242
|
+
return Date.UTC(y, m, 0, 23, 59, 59, 999);
|
|
243
|
+
}
|
|
244
|
+
function quarterEndMs(quarter) {
|
|
245
|
+
const [yStr, qStr] = quarter.split("-Q");
|
|
246
|
+
const y = Number(yStr);
|
|
247
|
+
const q = Number(qStr);
|
|
248
|
+
return Date.UTC(y, q * 3, 0, 23, 59, 59, 999);
|
|
249
|
+
}
|
|
5
250
|
const FILES_PLACEHOLDER = "{{FILES}}";
|
|
6
251
|
function buildDimensionWhere(filters, table) {
|
|
7
252
|
const clauses = [];
|
|
@@ -136,4 +381,4 @@ function substituteNamedFiles(sql, sets) {
|
|
|
136
381
|
for (const [name, keys] of Object.entries(sets)) out = out.replace(new RegExp(`\\{\\{${name}\\}\\}`, "g"), fileList(keys));
|
|
137
382
|
return out;
|
|
138
383
|
}
|
|
139
|
-
export { FILES_PLACEHOLDER, compileLogicalQueryPlan, resolveParquetSQL, substituteNamedFiles };
|
|
384
|
+
export { FILES_PLACEHOLDER, compactTieredImpl, compileLogicalQueryPlan, dedupeOverlappingTiers, enumeratePartitions, resolveParquetSQL, splitOverlappingTiers, substituteNamedFiles };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { SCHEMAS, drizzleSchema } from "./schema.mjs";
|
|
2
|
-
import { enumeratePartitions } from "./
|
|
2
|
+
import { enumeratePartitions } from "./parquet-plan.mjs";
|
|
3
3
|
import { escapeLike } from "../sql-fragments.mjs";
|
|
4
4
|
import "../planner.mjs";
|
|
5
5
|
import { DEFAULT_PARTITION_KEY_ENCODING } from "./schema2.mjs";
|
|
@@ -7,6 +7,7 @@ import { UnresolvableDatasetError, buildLogicalComparisonPlan, buildLogicalPlan,
|
|
|
7
7
|
import { PgDialect, pgTable, varchar } from "drizzle-orm/pg-core";
|
|
8
8
|
import { normalizeUrl } from "gscdump/normalize";
|
|
9
9
|
import { sql } from "drizzle-orm";
|
|
10
|
+
import { and as and$1, gte as gte$1, impressions } from "gscdump/query";
|
|
10
11
|
const DIMENSION_SURFACES = {
|
|
11
12
|
page: ["api", "stored"],
|
|
12
13
|
query: ["api", "stored"],
|
|
@@ -523,6 +524,16 @@ function joinComma(parts) {
|
|
|
523
524
|
return sql.join(parts, sql`, `);
|
|
524
525
|
}
|
|
525
526
|
const ORDER_BY_HELPER_PREFIX = "__order_";
|
|
527
|
+
function withMinimumImpressions(state, options) {
|
|
528
|
+
if (options.minimumImpressions === void 0) return state;
|
|
529
|
+
const minimum = Number(options.minimumImpressions);
|
|
530
|
+
if (!Number.isFinite(minimum) || minimum < 0) throw new RangeError("minimumImpressions must be a finite non-negative number");
|
|
531
|
+
const guard = gte$1(impressions, minimum);
|
|
532
|
+
return {
|
|
533
|
+
...state,
|
|
534
|
+
prefilter: state.prefilter ? and$1(state.prefilter, guard) : guard
|
|
535
|
+
};
|
|
536
|
+
}
|
|
526
537
|
function orderByClause(state, prefix = "", columnOverride) {
|
|
527
538
|
if (state.orderBy) {
|
|
528
539
|
const safeCol = (columnOverride ?? state.orderBy.column).replace(/\W/g, "");
|
|
@@ -628,6 +639,7 @@ function compileCollapsed(adapter, q) {
|
|
|
628
639
|
};
|
|
629
640
|
}
|
|
630
641
|
function resolveToSQLOptimized(state, options) {
|
|
642
|
+
state = withMinimumImpressions(state, options);
|
|
631
643
|
const { adapter } = options;
|
|
632
644
|
const { tableKey, groupByDims, hasDate, metrics, wherePredicates, having, queryCanonicalUsed } = buildScope(state, options);
|
|
633
645
|
const table = adapter.fromSql(tableKey, { queryCanonical: queryCanonicalUsed });
|
|
@@ -695,6 +707,7 @@ function resolveToSQLOptimized(state, options) {
|
|
|
695
707
|
return compileCollapsed(adapter, sql`WITH aggregated AS (${cte}) SELECT ${joinComma(outerSelect)} FROM aggregated ${orderByClause(state, "", orderByColumnOverride)} ${limitOffsetClause(state)}`);
|
|
696
708
|
}
|
|
697
709
|
function resolveToSQL(state, options) {
|
|
710
|
+
state = withMinimumImpressions(state, options);
|
|
698
711
|
const { adapter } = options;
|
|
699
712
|
const { tableKey, groupByDims, hasDate, metrics, wherePredicates, having, queryCanonicalUsed } = buildScope(state, options);
|
|
700
713
|
const table = adapter.fromSql(tableKey, { queryCanonical: queryCanonicalUsed });
|
|
@@ -729,6 +742,7 @@ function resolveToSQL(state, options) {
|
|
|
729
742
|
};
|
|
730
743
|
}
|
|
731
744
|
function buildTotalsSql(state, options) {
|
|
745
|
+
state = withMinimumImpressions(state, options);
|
|
732
746
|
const { adapter } = options;
|
|
733
747
|
const { tableKey, metrics, wherePredicates, queryCanonicalUsed } = buildScope(state, options);
|
|
734
748
|
const table = adapter.fromSql(tableKey, { queryCanonical: queryCanonicalUsed });
|
|
@@ -1203,4 +1217,4 @@ function assertSchemaInSync(options) {
|
|
|
1203
1217
|
if (missing.length > 0 || extra.length > 0) throw new Error(`${label} drizzle schema for '${key}' drifted from SCHEMAS. Missing: [${missing.join(", ")}]. Extra: [${extra.join(", ")}].`);
|
|
1204
1218
|
}
|
|
1205
1219
|
}
|
|
1206
|
-
export { DIMENSION_SURFACES, LOGICAL_DATASETS, QuerySourceCoverageError, UnresolvableDatasetError, assertDimensionsSupported, assertSchemaInSync, buildExtrasQueries, buildTotalsSql, canonicalRollupCovers, createIcebergResolverAdapter, createParquetResolverAdapter, createR2SqlResolverAdapter, createResolverAdapter, createRollupExtrasOverlay, createSqlFragments, dimensionColumn, dimensionValue, getDimensionFilters, getFilterDimensions, getInternalFilters, inferLogicalDataset, isDatasetResolvable, matchesDimensionFilter, matchesMetricFilter, matchesTopLevelPage, mergeExtras, metricValue, pgResolverAdapter,
|
|
1220
|
+
export { DIMENSION_SURFACES, LOGICAL_DATASETS, QuerySourceCoverageError, UnresolvableDatasetError, assertDimensionsSupported, assertSchemaInSync, buildExtrasQueries, buildTotalsSql, canonicalRollupCovers, createIcebergResolverAdapter, createParquetResolverAdapter, createR2SqlResolverAdapter, createResolverAdapter, createRollupExtrasOverlay, createSqlFragments, dimensionColumn, dimensionValue, getDimensionFilters, getFilterDimensions, getInternalFilters, inferLogicalDataset, isDatasetResolvable, matchesDimensionFilter, matchesMetricFilter, matchesTopLevelPage, mergeExtras, metricValue, pgResolverAdapter, resolveComparisonSQL, resolveToSQL, resolveToSQLOptimized, runComparisonQuery, runOptimizedQuery, supportsDimensionOnSurface };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ColumnDef
|
|
1
|
+
import { ColumnDef, ColumnType, Row, TableName, TableSchema, TableSchema as TableSchema$1 } from "@gscdump/contracts";
|
|
2
2
|
declare const pages: import("drizzle-orm/pg-core").PgTableWithColumns<{
|
|
3
3
|
name: "pages";
|
|
4
4
|
schema: undefined;
|
|
@@ -2145,4 +2145,4 @@ declare function naturalKeyColumns(table: TableName): readonly string[];
|
|
|
2145
2145
|
*/
|
|
2146
2146
|
declare function dedupeByNaturalKey(table: TableName, rows: readonly Row[]): Row[];
|
|
2147
2147
|
declare function dimensionToColumn(dim: string, _table: TableName): string;
|
|
2148
|
-
export { type ColumnDef
|
|
2148
|
+
export { type ColumnDef, type ColumnType, DrizzleSchema, SCHEMAS, TABLE_METADATA, type TableSchema$1 as TableSchema, allTables, countries, currentSchemaVersion, dateColumnsFor, dates, dedupeByNaturalKey, dimensionToColumn, drizzleSchema, hourly_pages, inferTable, naturalKeyColumns, page_queries, pages, queries, search_appearance, search_appearance_page_queries, search_appearance_pages, search_appearance_queries };
|
package/dist/_chunks/sink.d.mts
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { Row as Row$1, SearchType, TenantCtx as TenantCtx$1 } from "./storage.mjs";
|
|
2
2
|
import { EngineError } from "./errors.mjs";
|
|
3
3
|
import { icebergCreateTable } from "./libs/icebird.mjs";
|
|
4
|
-
import { CatalogCache, CommitRetryOptions, ConnectIcebergOptions, DEFAULT_PARTITION_KEY_ENCODING as DEFAULT_PARTITION_KEY_ENCODING$1, IcebergCatalogConfig, IcebergColumn, IcebergColumn as IcebergColumn$1, IcebergColumnType, IcebergConnection, IcebergConnection as IcebergConnection$1, IcebergListedDataFile, IcebergListedDataFile as IcebergListedDataFile$1, IcebergPartitionField, IcebergPartitionField as IcebergPartitionField$1, IcebergPartitionSpec, IcebergPartitionSpecField, IcebergPartitionTransform, IcebergPrimitiveType, IcebergS3Config, IcebergSchema, IcebergSchemaField, IcebergSortOrder, IcebergSortOrderField, IcebergTableSpec, IcebergTableSpec as IcebergTableSpec$1, PartitionKeyEncoding, PartitionKeyEncoding as PartitionKeyEncoding$1, QueryProfiler, catalogCacheScope, connectIcebergCatalog, ensureIcebergNamespace, invalidateSnapshotRef, listIcebergTables } from "@gscdump/lakehouse";
|
|
5
4
|
import { Result } from "gscdump/result";
|
|
6
|
-
import {
|
|
5
|
+
import { CommitRetryOptions, ConnectIcebergOptions, IcebergCatalogConfig, IcebergColumn, IcebergConnection, IcebergListedDataFile, IcebergPartitionField, IcebergS3Config, IcebergTableSpec, PartitionKeyEncoding, PartitionKeyEncoding as PartitionKeyEncoding$1, QueryProfiler } from "@gscdump/lakehouse";
|
|
7
6
|
import { TableName } from "@gscdump/contracts";
|
|
8
7
|
/** The 9 fact tables that exist as global Iceberg tables. */
|
|
9
8
|
type IcebergTableName = Extract<TableName, 'pages' | 'queries' | 'countries' | 'page_queries' | 'dates' | 'search_appearance' | 'search_appearance_pages' | 'search_appearance_queries' | 'search_appearance_page_queries'>;
|
|
@@ -45,8 +44,8 @@ declare const ICEBERG_PARTITION_SPEC: readonly IcebergPartitionField[];
|
|
|
45
44
|
/**
|
|
46
45
|
* Derive the full Iceberg table spec for a table + encoding. Thin wrapper
|
|
47
46
|
* over {@link gscDataset}'s `tableSpec` (ADR-0021 R2-FIXES C5) — kept as a
|
|
48
|
-
* named export
|
|
49
|
-
*
|
|
47
|
+
* named GSC-specific export. Generic schema authoring types are owned by
|
|
48
|
+
* `@gscdump/lakehouse`.
|
|
50
49
|
*
|
|
51
50
|
* CONTRACT NOTE: implementation agents must treat the RETURNED VALUE as the
|
|
52
51
|
* source of truth — do not hand-list columns elsewhere.
|
|
@@ -254,4 +253,4 @@ interface IcebergAppendSinkOptions extends SinkOptions {
|
|
|
254
253
|
*/
|
|
255
254
|
encoding?: PartitionKeyEncoding$1;
|
|
256
255
|
}
|
|
257
|
-
export {
|
|
256
|
+
export { ICEBERG_FIELD_ID_BASE, ICEBERG_PARTITION_COLUMNS, ICEBERG_PARTITION_SPEC, ICEBERG_SCHEMAS, ICEBERG_SCHEMAS_INT, ICEBERG_SCHEMAS_STRING, ICEBERG_TABLES, INT_SEARCH_TYPE, IcebergAppendSinkOptions, type IcebergS3Config, IcebergTableName, IcebergTableOpResult, ListIcebergDataFilesOptions, SEARCH_TYPE_INT, Sink, SinkCapabilities, SinkCloseResult, SinkOptions, SinkSlice, SinkWriteResult, SliceOverwriteWriter, assertIcebergTable, createIcebergTables, dropIcebergTables$1 as dropIcebergTables, icebergPartitionColumns, icebergPartitionSpecFor, icebergSchemaFor, icebergSchemasFor, icebergSortOrderFor, icebergTableSpec, isIcebergTable, listIcebergDataFiles };
|
package/dist/_chunks/source.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { coerceRows } from "./coerce.mjs";
|
|
2
|
-
import "./layout.mjs";
|
|
3
1
|
import { engineErrors } from "../errors.mjs";
|
|
2
|
+
import "./layout.mjs";
|
|
3
|
+
import { coerceRows } from "./coerce.mjs";
|
|
4
4
|
import { assertDimensionsSupported, getFilterDimensions, pgResolverAdapter, resolveToSQL } from "./resolver.mjs";
|
|
5
5
|
import { runAnalyzerFromSource } from "./dispatch.mjs";
|
|
6
6
|
var AttachedTableMissingError = class extends Error {
|
|
@@ -140,4 +140,4 @@ async function runAnalyzerWithEngine(deps, ctx, params, registry) {
|
|
|
140
140
|
async function queryRows(source, state) {
|
|
141
141
|
return await source.queryRows(state);
|
|
142
142
|
}
|
|
143
|
-
export { AttachedTableMissingError, ENGINE_QUERY_CAPABILITIES, createAttachedTableSource, createEngineQuerySource, createSqlQuerySource, queryRows,
|
|
143
|
+
export { AttachedTableMissingError, ENGINE_QUERY_CAPABILITIES, createAttachedTableSource, createEngineQuerySource, createSqlQuerySource, queryRows, runAnalyzerWithEngine };
|
|
@@ -13,48 +13,6 @@ interface CompactionThresholds {
|
|
|
13
13
|
d30?: number;
|
|
14
14
|
}
|
|
15
15
|
declare function enumeratePartitions(startDate: string, endDate: string): string[];
|
|
16
|
-
/**
|
|
17
|
-
* Split manifest entries into the set worth reading (`kept`) and the set whose
|
|
18
|
-
* every covered day is already served by a finer-or-newer live entry
|
|
19
|
-
* (`subsumed`).
|
|
20
|
-
*
|
|
21
|
-
* Tiered compaction (daily→weekly→monthly→quarterly) is meant to retire its
|
|
22
|
-
* inputs, but coarse files can outlive their finer counterparts: a D1→R2
|
|
23
|
-
* backfill writes daily files that compact to monthly while a later re-sync
|
|
24
|
-
* writes fresh daily/weekly for the same dates, and same-partition re-writes
|
|
25
|
-
* leave a stale prior version live. All stay live, the resolver unions every
|
|
26
|
-
* live tier whose partition intersects the range, and `union_by_name` sums the
|
|
27
|
-
* overlap — impressions/clicks double-count.
|
|
28
|
-
*
|
|
29
|
-
* Entries are walked finest-tier-first, newest-first within a tier, so a
|
|
30
|
-
* coarse or stale file is dropped only when every day it covers is already
|
|
31
|
-
* claimed. Subsumption is evaluated per searchType — a `web` monthly never
|
|
32
|
-
* cancels a `discover` weekly, they cover disjoint data. Partial
|
|
33
|
-
* month-boundary overlap (a weekly straddling two months alongside a kept
|
|
34
|
-
* monthly) still double-counts those boundary days — eliminating that needs
|
|
35
|
-
* per-file date predicates in the SQL, tracked separately. Unrecognised
|
|
36
|
-
* partition shapes (`hourly/`, sidecar keys) are always kept.
|
|
37
|
-
*
|
|
38
|
-
* `queryRange` clamps every entry's day-span to the window the caller will
|
|
39
|
-
* actually read. This is required when `entries` came from a partition-
|
|
40
|
-
* filtered `listLive` (`runSQL` enumerates only the partitions intersecting
|
|
41
|
-
* the query): a `monthly/2026-04` whose Apr 27-30 falls past the query end
|
|
42
|
-
* must not be judged "unsubsumed" just because `weekly/2026-04-27` wasn't
|
|
43
|
-
* enumerated — those out-of-window days are SQL-filtered to nothing anyway.
|
|
44
|
-
* Omit `queryRange` when `entries` is the full manifest (e.g. analysis-sources).
|
|
45
|
-
*/
|
|
46
|
-
declare function splitOverlappingTiers(entries: ManifestEntry[], queryRange?: {
|
|
47
|
-
start: string;
|
|
48
|
-
end: string;
|
|
49
|
-
}): {
|
|
50
|
-
kept: ManifestEntry[];
|
|
51
|
-
subsumed: ManifestEntry[];
|
|
52
|
-
};
|
|
53
|
-
/** Entries worth reading — see {@link splitOverlappingTiers}. */
|
|
54
|
-
declare function dedupeOverlappingTiers(entries: ManifestEntry[], queryRange?: {
|
|
55
|
-
start: string;
|
|
56
|
-
end: string;
|
|
57
|
-
}): ManifestEntry[];
|
|
58
16
|
interface WriteCtx extends TenantCtx {
|
|
59
17
|
table: TableName;
|
|
60
18
|
date?: string;
|
|
@@ -596,4 +554,4 @@ interface EngineOptions {
|
|
|
596
554
|
executor: QueryExecutor;
|
|
597
555
|
now?: () => number;
|
|
598
556
|
}
|
|
599
|
-
export { CodecCtx, CompactionThresholds, CompactionTier, DataSource, EngineOptions, FileSetRef, GcCtx, type Grain$1 as Grain, ListLiveFilter, LockScope, ManifestEntry, ManifestPurgeResult, ManifestStore, ParquetCodec, PurgeFilter, PurgeResult, PurgeUrlsResult, QueryCtx, QueryExecuteOptions, QueryExecuteResult, QueryExecutor, QueryProfiler, QueryResult, QuerySpan, type Row$1 as Row, RunSQLOptions, type SearchType$1 as SearchType, StorageEngine, SyncState, SyncStateDetail, SyncStateFilter, SyncStateKind, SyncStateScope, type TableName$1 as TableName, type TenantCtx$1 as TenantCtx, Watermark, WatermarkFilter, WatermarkScope, WriteCtx, WriteResult,
|
|
557
|
+
export { CodecCtx, CompactionThresholds, CompactionTier, DataSource, EngineOptions, FileSetRef, GcCtx, type Grain$1 as Grain, ListLiveFilter, LockScope, ManifestEntry, ManifestPurgeResult, ManifestStore, ParquetCodec, PurgeFilter, PurgeResult, PurgeUrlsResult, QueryCtx, QueryExecuteOptions, QueryExecuteResult, QueryExecutor, QueryProfiler, QueryResult, QuerySpan, type Row$1 as Row, RunSQLOptions, type SearchType$1 as SearchType, StorageEngine, SyncState, SyncStateDetail, SyncStateFilter, SyncStateKind, SyncStateScope, type TableName$1 as TableName, type TenantCtx$1 as TenantCtx, Watermark, WatermarkFilter, WatermarkScope, WriteCtx, WriteResult, enumeratePartitions };
|
package/dist/_chunks/types.d.mts
CHANGED
|
@@ -40,6 +40,14 @@ interface ResolverOptions<TableKey extends string = string> {
|
|
|
40
40
|
* int partition prunes; `string` for the default string-encoded catalogs.
|
|
41
41
|
*/
|
|
42
42
|
searchType?: string | number;
|
|
43
|
+
/**
|
|
44
|
+
* Optional non-comparison scan guard. When set, direct row/totals queries
|
|
45
|
+
* add `impressions >= value` before aggregation. This can materially reduce
|
|
46
|
+
* stored-row reads because zero-impression long-tail rows contribute
|
|
47
|
+
* nothing to metric aggregates. Comparison SQL deliberately ignores it so
|
|
48
|
+
* `lost`/`declining` rows remain observable.
|
|
49
|
+
*/
|
|
50
|
+
minimumImpressions?: number;
|
|
43
51
|
}
|
|
44
52
|
interface ResolvedSQL {
|
|
45
53
|
sql: string;
|
package/dist/adapters/node.d.mts
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import { DataSource, StorageEngine } from "../_chunks/storage.mjs";
|
|
2
2
|
import { NodeDuckDBOptions, createNodeDuckDBHandle, resetNodeDuckDB } from "./duckdb-node.mjs";
|
|
3
|
-
import { EngineError } from "../_chunks/errors.mjs";
|
|
4
3
|
import { SnapshotIndex } from "../_chunks/snapshot.mjs";
|
|
5
|
-
import { Result } from "gscdump/result";
|
|
6
4
|
import { SearchType } from "gscdump/query";
|
|
7
5
|
import { Row, TableName } from "@gscdump/contracts";
|
|
8
6
|
interface NodeHarnessOptions {
|
|
@@ -74,14 +72,6 @@ interface AttachSnapshotResult {
|
|
|
74
72
|
* `cold_2024_09`. `hot.duckdb` → `hot`.
|
|
75
73
|
*/
|
|
76
74
|
declare function snapshotAlias(fileName: string): string;
|
|
77
|
-
/**
|
|
78
|
-
* Errors-as-values core: validates the snapshot index and presigned-URL map,
|
|
79
|
-
* returning a typed `EngineError` for every modelled failure (bad index version,
|
|
80
|
-
* unsafe schema/YYYY-MM identifier, missing attach URL). Underlying DuckDB
|
|
81
|
-
* `runner` IO failures stay defects and propagate. `attachSnapshotIndex` is the
|
|
82
|
-
* throwing wrapper.
|
|
83
|
-
*/
|
|
84
|
-
declare function attachSnapshotIndexResult(runner: SnapshotQueryRunner, opts: AttachSnapshotOptions): Promise<Result<AttachSnapshotResult, EngineError>>;
|
|
85
75
|
declare function attachSnapshotIndex(runner: SnapshotQueryRunner, opts: AttachSnapshotOptions): Promise<AttachSnapshotResult>;
|
|
86
76
|
interface AttachParquetIndexOptions {
|
|
87
77
|
/**
|
|
@@ -104,4 +94,4 @@ interface AttachParquetIndexResult {
|
|
|
104
94
|
tables: string[];
|
|
105
95
|
}
|
|
106
96
|
declare function attachParquetIndex(runner: SnapshotQueryRunner, opts: AttachParquetIndexOptions): Promise<AttachParquetIndexResult>;
|
|
107
|
-
export { type AttachParquetIndexOptions, type AttachParquetIndexResult, type AttachSnapshotOptions, type AttachSnapshotResult, type NodeDuckDBOptions, type NodeHarness, type NodeHarnessOptions, type SnapshotQueryRunner, attachParquetIndex, attachSnapshotIndex,
|
|
97
|
+
export { type AttachParquetIndexOptions, type AttachParquetIndexResult, type AttachSnapshotOptions, type AttachSnapshotResult, type NodeDuckDBOptions, type NodeHarness, type NodeHarnessOptions, type SnapshotQueryRunner, attachParquetIndex, attachSnapshotIndex, createNodeDuckDBHandle, createNodeHarness, resetNodeDuckDB, snapshotAlias };
|
package/dist/adapters/node.mjs
CHANGED
|
@@ -147,4 +147,4 @@ async function attachSnapshotIndexResult(runner, opts) {
|
|
|
147
147
|
async function attachSnapshotIndex(runner, opts) {
|
|
148
148
|
return unwrapResult(await attachSnapshotIndexResult(runner, opts), snapshotAttachErrorToException);
|
|
149
149
|
}
|
|
150
|
-
export { attachParquetIndex, attachSnapshotIndex,
|
|
150
|
+
export { attachParquetIndex, attachSnapshotIndex, createNodeDuckDBHandle, createNodeHarness, resetNodeDuckDB, snapshotAlias };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { EngineError } from "../_chunks/errors.mjs";
|
|
2
1
|
import { AnalysisParams, AnalysisResult } from "../_chunks/analysis-types.mjs";
|
|
3
2
|
import { AnalysisQuerySource, Analyzer, AnalyzerRegistry, AnalyzerRegistryInit, AnalyzerVariants, BuildContext, DefineAnalyzerOptions, DefinedAnalyzer, Plan, ReduceContext, ReduceCtx, Reducer, RequiredCapability, RowQueriesPlan, SqlExtraQuery, SqlPlan, SqlPlanSpec, TypedRowQuery, createAnalyzerRegistry, defineAnalyzer, requireAdapter } from "../_chunks/registry.mjs";
|
|
3
|
+
import { EngineError } from "../_chunks/errors.mjs";
|
|
4
4
|
declare class AnalyzerCapabilityError extends Error {
|
|
5
5
|
readonly tool: string;
|
|
6
6
|
readonly missing: readonly RequiredCapability[];
|
package/dist/entities.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { DataSource } from "./_chunks/storage.mjs";
|
|
2
2
|
import { ScheduleState } from "./schedule.mjs";
|
|
3
|
-
import {
|
|
3
|
+
import { TenantCtx } from "@gscdump/contracts";
|
|
4
4
|
interface QueryDimRecord {
|
|
5
5
|
query: string;
|
|
6
6
|
/** Lexical canonical, never empty: NULL/'' folds to the raw query. */
|
|
@@ -290,14 +290,6 @@ interface InspectionStore {
|
|
|
290
290
|
interface CreateInspectionStoreOptions {
|
|
291
291
|
dataSource: DataSource;
|
|
292
292
|
}
|
|
293
|
-
/**
|
|
294
|
-
* Column schema for the append-only inspection-event store + its compacted
|
|
295
|
-
* base. Superset of {@link INSPECTION_PARQUET_COLUMNS}: the 16 promoted columns
|
|
296
|
-
* plus the 8 full-fidelity ones the lossy `materialize` parquet dropped. The
|
|
297
|
-
* event files and `base.parquet` share this schema so DuckDB
|
|
298
|
-
* `read_parquet([...], union_by_name = true)` merges base + events cleanly.
|
|
299
|
-
*/
|
|
300
|
-
declare const INSPECTION_EVENT_COLUMNS: readonly ColumnDef[];
|
|
301
293
|
declare function createInspectionStore(opts: CreateInspectionStoreOptions): InspectionStore;
|
|
302
294
|
/** GSC sitemap record we persist. Matches `Schema$WmxSitemap` but as plain JSON. */
|
|
303
295
|
interface SitemapRecord {
|
|
@@ -522,4 +514,4 @@ interface CreateEmptyTypesStoreOptions {
|
|
|
522
514
|
now?: () => number;
|
|
523
515
|
}
|
|
524
516
|
declare function createEmptyTypesStore(opts: CreateEmptyTypesStoreOptions): EmptyTypesStore;
|
|
525
|
-
export { CompactUrlsOptions, CompactUrlsResult, CreateEmptyTypesStoreOptions, CreateIndexingMetadataStoreOptions, CreateInspectionStoreOptions, CreateSitemapStoreOptions, DateRange, DeltaEntry, EmptyTypesDoc, EmptyTypesStore,
|
|
517
|
+
export { CompactUrlsOptions, CompactUrlsResult, CreateEmptyTypesStoreOptions, CreateIndexingMetadataStoreOptions, CreateInspectionStoreOptions, CreateSitemapStoreOptions, DateRange, DeltaEntry, EmptyTypesDoc, EmptyTypesStore, INSPECTION_HISTORY_MAX_BYTES, IndexingMetadataIndex, IndexingMetadataRecord, IndexingMetadataStore, InspectionEventRow, InspectionHistoryShard, InspectionIndex, InspectionParquetRow, InspectionRecord, InspectionStore, LoadUrlsOptions, ParsedUrl, QueryDimDeps, QueryDimMeta, QueryDimRecord, QueryDimStore, ReconcileResult, SitemapHistoryDoc, SitemapIndex, SitemapRecord, SitemapStore, SitemapUrlRecord, SnapshotUrlsResult, buildQueryDimRecords, createEmptyTypesStore, createIndexingMetadataStore, createInspectionStore, createQueryDimStore, createSitemapStore, emptyTypesKey, hashUrl, hashUrlList, indexingMetadataIndexKey, inspectionBaseKey, inspectionEventKey, inspectionEventsPrefix, inspectionHistoryPrefix, inspectionHistoryShardKey, inspectionIndexKey, inspectionParquetKey, queryDimMetaKey, queryDimParquetKey, sitemapHistoryKey, sitemapIndexKey, sitemapUrlsDeltaKey, sitemapUrlsIndexKey, sitemapUrlsIndexPrefix };
|
package/dist/entities.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export {
|
|
1
|
+
import { INSPECTION_HISTORY_MAX_BYTES, buildQueryDimRecords, createEmptyTypesStore, createIndexingMetadataStore, createInspectionStore, createQueryDimStore, createSitemapStore, emptyTypesKey, hashUrl, hashUrlList, indexingMetadataIndexKey, inspectionBaseKey, inspectionEventKey, inspectionEventsPrefix, inspectionHistoryPrefix, inspectionHistoryShardKey, inspectionIndexKey, inspectionParquetKey, queryDimMetaKey, queryDimParquetKey, sitemapHistoryKey, sitemapIndexKey, sitemapUrlsDeltaKey, sitemapUrlsIndexKey, sitemapUrlsIndexPrefix } from "./_chunks/entities.mjs";
|
|
2
|
+
export { INSPECTION_HISTORY_MAX_BYTES, buildQueryDimRecords, createEmptyTypesStore, createIndexingMetadataStore, createInspectionStore, createQueryDimStore, createSitemapStore, emptyTypesKey, hashUrl, hashUrlList, indexingMetadataIndexKey, inspectionBaseKey, inspectionEventKey, inspectionEventsPrefix, inspectionHistoryPrefix, inspectionHistoryShardKey, inspectionIndexKey, inspectionParquetKey, queryDimMetaKey, queryDimParquetKey, sitemapHistoryKey, sitemapIndexKey, sitemapUrlsDeltaKey, sitemapUrlsIndexKey, sitemapUrlsIndexPrefix };
|
package/dist/iceberg/index.d.mts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { icebergCreateTable, icebergManifests, restCatalogLoadTable } from "../_chunks/libs/icebird.mjs";
|
|
1
|
+
import { ICEBERG_FIELD_ID_BASE, ICEBERG_PARTITION_COLUMNS, ICEBERG_PARTITION_SPEC, ICEBERG_SCHEMAS, ICEBERG_SCHEMAS_INT, ICEBERG_SCHEMAS_STRING, ICEBERG_TABLES, INT_SEARCH_TYPE, IcebergAppendSinkOptions, IcebergTableName, IcebergTableOpResult, ListIcebergDataFilesOptions, SEARCH_TYPE_INT, Sink, assertIcebergTable, createIcebergTables, dropIcebergTables, icebergPartitionColumns, icebergPartitionSpecFor, icebergSchemaFor, icebergSchemasFor, icebergSortOrderFor, icebergTableSpec, isIcebergTable, listIcebergDataFiles } from "../_chunks/sink.mjs";
|
|
3
2
|
type IcebergAppendSink = Sink;
|
|
4
3
|
/**
|
|
5
4
|
* Create an `IcebergAppendSink` over the R2 Data Catalog.
|
|
@@ -12,4 +11,4 @@ type IcebergAppendSink = Sink;
|
|
|
12
11
|
* without it every fresh sink/isolate must probe the catalog again.
|
|
13
12
|
*/
|
|
14
13
|
declare function createIcebergAppendSink(options: IcebergAppendSinkOptions): IcebergAppendSink;
|
|
15
|
-
export {
|
|
14
|
+
export { ICEBERG_FIELD_ID_BASE, ICEBERG_PARTITION_COLUMNS, ICEBERG_PARTITION_SPEC, ICEBERG_SCHEMAS, ICEBERG_SCHEMAS_INT, ICEBERG_SCHEMAS_STRING, ICEBERG_TABLES, INT_SEARCH_TYPE, type IcebergAppendSink, type IcebergAppendSinkOptions, type IcebergTableName, type IcebergTableOpResult, type ListIcebergDataFilesOptions, SEARCH_TYPE_INT, assertIcebergTable, createIcebergAppendSink, createIcebergTables, dropIcebergTables, icebergPartitionColumns, icebergPartitionSpecFor, icebergSchemaFor, icebergSchemasFor, icebergSortOrderFor, icebergTableSpec, isIcebergTable, listIcebergDataFiles };
|
package/dist/iceberg/index.mjs
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { TABLE_METADATA } from "../_chunks/schema.mjs";
|
|
2
1
|
import { engineErrors } from "../errors.mjs";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
2
|
+
import { TABLE_METADATA } from "../_chunks/schema.mjs";
|
|
3
|
+
import { DEFAULT_PARTITION_KEY_ENCODING as DEFAULT_PARTITION_KEY_ENCODING$1, ICEBERG_FIELD_ID_BASE, ICEBERG_PARTITION_COLUMNS, ICEBERG_PARTITION_SPEC, ICEBERG_SCHEMAS, ICEBERG_SCHEMAS_INT, ICEBERG_SCHEMAS_STRING, ICEBERG_TABLES, INT_SEARCH_TYPE, SEARCH_TYPE_INT, assertIcebergTable, gscDataset, icebergPartitionColumns, icebergSchemasFor, icebergTableSpec, isIcebergTable } from "../_chunks/schema2.mjs";
|
|
4
|
+
import { icebergCreateTable } from "../_chunks/libs/icebird.mjs";
|
|
6
5
|
import { err, ok } from "gscdump/result";
|
|
7
|
-
import {
|
|
8
|
-
|
|
6
|
+
import { ICEBERG_TYPE_MAP, connectIcebergCatalog, dropIcebergTables as dropIcebergTables$1, resolveIcebergDataFiles } from "@gscdump/lakehouse";
|
|
7
|
+
import { icebergAppendRetrying } from "@gscdump/lakehouse/unsafe-raw";
|
|
8
|
+
function icebergSchemaFor(table, encoding = DEFAULT_PARTITION_KEY_ENCODING$1) {
|
|
9
9
|
return {
|
|
10
10
|
"type": "struct",
|
|
11
11
|
"schema-id": 0,
|
|
@@ -17,7 +17,7 @@ function icebergSchemaFor(table, encoding = DEFAULT_PARTITION_KEY_ENCODING) {
|
|
|
17
17
|
}))
|
|
18
18
|
};
|
|
19
19
|
}
|
|
20
|
-
function icebergPartitionSpecFor(table, encoding = DEFAULT_PARTITION_KEY_ENCODING) {
|
|
20
|
+
function icebergPartitionSpecFor(table, encoding = DEFAULT_PARTITION_KEY_ENCODING$1) {
|
|
21
21
|
const fields = icebergSchemasFor(encoding)[table].columns;
|
|
22
22
|
const fieldId = (name) => {
|
|
23
23
|
const col = fields.find((c) => c.name === name);
|
|
@@ -34,7 +34,7 @@ function icebergPartitionSpecFor(table, encoding = DEFAULT_PARTITION_KEY_ENCODIN
|
|
|
34
34
|
}))
|
|
35
35
|
};
|
|
36
36
|
}
|
|
37
|
-
function icebergSortOrderFor(table, encoding = DEFAULT_PARTITION_KEY_ENCODING) {
|
|
37
|
+
function icebergSortOrderFor(table, encoding = DEFAULT_PARTITION_KEY_ENCODING$1) {
|
|
38
38
|
const fields = icebergSchemasFor(encoding)[table].columns;
|
|
39
39
|
const fieldId = (name) => {
|
|
40
40
|
const col = fields.find((c) => c.name === name);
|
|
@@ -51,7 +51,7 @@ function icebergSortOrderFor(table, encoding = DEFAULT_PARTITION_KEY_ENCODING) {
|
|
|
51
51
|
}))
|
|
52
52
|
};
|
|
53
53
|
}
|
|
54
|
-
async function createIcebergTables(conn, tables = ICEBERG_TABLES, encoding = DEFAULT_PARTITION_KEY_ENCODING) {
|
|
54
|
+
async function createIcebergTables(conn, tables = ICEBERG_TABLES, encoding = DEFAULT_PARTITION_KEY_ENCODING$1) {
|
|
55
55
|
const results = [];
|
|
56
56
|
for (const table of tables) await icebergCreateTable({
|
|
57
57
|
catalog: conn.catalog,
|
|
@@ -76,7 +76,7 @@ async function dropIcebergTables(conn, tables) {
|
|
|
76
76
|
}));
|
|
77
77
|
}
|
|
78
78
|
async function listIcebergDataFiles(conn, opts) {
|
|
79
|
-
const matches = (opts.encoding ?? DEFAULT_PARTITION_KEY_ENCODING) === "string" ? [{
|
|
79
|
+
const matches = (opts.encoding ?? DEFAULT_PARTITION_KEY_ENCODING$1) === "string" ? [{
|
|
80
80
|
field: "site_id",
|
|
81
81
|
value: opts.siteId,
|
|
82
82
|
encoding: "string"
|
|
@@ -178,7 +178,7 @@ function toRecords(slice, rows, encoding) {
|
|
|
178
178
|
}
|
|
179
179
|
function createIcebergAppendSink(options) {
|
|
180
180
|
let connection;
|
|
181
|
-
const encoding = options.encoding ?? DEFAULT_PARTITION_KEY_ENCODING;
|
|
181
|
+
const encoding = options.encoding ?? DEFAULT_PARTITION_KEY_ENCODING$1;
|
|
182
182
|
const buffers = /* @__PURE__ */ new Map();
|
|
183
183
|
function connect() {
|
|
184
184
|
connection ??= connectIcebergCatalog(options.catalog, options.connect);
|
|
@@ -242,4 +242,4 @@ function createIcebergAppendSink(options) {
|
|
|
242
242
|
}
|
|
243
243
|
};
|
|
244
244
|
}
|
|
245
|
-
export {
|
|
245
|
+
export { ICEBERG_FIELD_ID_BASE, ICEBERG_PARTITION_COLUMNS, ICEBERG_PARTITION_SPEC, ICEBERG_SCHEMAS, ICEBERG_SCHEMAS_INT, ICEBERG_SCHEMAS_STRING, ICEBERG_TABLES, INT_SEARCH_TYPE, SEARCH_TYPE_INT, assertIcebergTable, createIcebergAppendSink, createIcebergTables, dropIcebergTables, icebergPartitionColumns, icebergPartitionSpecFor, icebergSchemaFor, icebergSchemasFor, icebergSortOrderFor, icebergTableSpec, isIcebergTable, listIcebergDataFiles };
|