@gscdump/lakehouse 1.3.0 → 1.3.2
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/_chunks/catalog.mjs +32 -2
- package/dist/_chunks/libs/icebird.mjs +110 -5
- package/dist/index.d.mts +16 -1
- package/dist/index.mjs +35 -2
- package/package.json +1 -1
package/dist/_chunks/catalog.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { stringifyBigintSafe } from "../bigint.mjs";
|
|
2
|
-
import { cachingResolver, icebergAppend, icebergDropTable, icebergManifests, restCatalogConnect, restCatalogCreateNamespace, restCatalogListTables, restCatalogLoadTable, s3SignedResolver } from "./libs/icebird.mjs";
|
|
2
|
+
import { cachingResolver, icebergAppend, icebergAppendBatches, icebergDropTable, icebergManifests, restCatalogConnect, restCatalogCreateNamespace, restCatalogListTables, restCatalogLoadTable, s3SignedResolver } from "./libs/icebird.mjs";
|
|
3
3
|
function reportCatalogCacheError(cache, operation, key, error) {
|
|
4
4
|
try {
|
|
5
5
|
if (cache.onError) cache.onError(operation, key, error);
|
|
@@ -240,6 +240,36 @@ async function icebergAppendRetrying(args, options = {}) {
|
|
|
240
240
|
await sleep(Math.floor(random() * ceiling));
|
|
241
241
|
}
|
|
242
242
|
}
|
|
243
|
+
async function icebergAppendBatchesRetrying(args, options) {
|
|
244
|
+
const maxAttempts = options.maxAttempts ?? 6;
|
|
245
|
+
const baseDelayMs = options.baseDelayMs ?? 1e3;
|
|
246
|
+
const maxDelayMs = options.maxDelayMs ?? 2e4;
|
|
247
|
+
const sleep = options.sleep ?? defaultCommitSleep;
|
|
248
|
+
const random = options.random ?? Math.random;
|
|
249
|
+
const appendId = options.appendId;
|
|
250
|
+
const { batchFactory, ...appendArgs } = args;
|
|
251
|
+
const stampedArgs = {
|
|
252
|
+
...appendArgs,
|
|
253
|
+
snapshotProperties: {
|
|
254
|
+
...appendArgs.snapshotProperties,
|
|
255
|
+
[APPEND_ID_SUMMARY_KEY]: appendId
|
|
256
|
+
}
|
|
257
|
+
};
|
|
258
|
+
if (await appendAlreadyLanded(args, appendId)) return false;
|
|
259
|
+
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
260
|
+
const err = await icebergAppendBatches({
|
|
261
|
+
...stampedArgs,
|
|
262
|
+
batches: batchFactory()
|
|
263
|
+
}).then(() => void 0, (e) => e);
|
|
264
|
+
if (err === void 0) return true;
|
|
265
|
+
if (!isCommitRateLimited(err)) throw err;
|
|
266
|
+
if (await appendAlreadyLanded(args, appendId)) return true;
|
|
267
|
+
if (attempt === maxAttempts - 1) throw err;
|
|
268
|
+
const ceiling = Math.min(maxDelayMs, baseDelayMs * 2 ** attempt);
|
|
269
|
+
await sleep(Math.floor(random() * ceiling));
|
|
270
|
+
}
|
|
271
|
+
return false;
|
|
272
|
+
}
|
|
243
273
|
async function deriveAppendId(args) {
|
|
244
274
|
const records = args.records ?? [];
|
|
245
275
|
if (records.length === 0) return globalThis.crypto.randomUUID();
|
|
@@ -399,4 +429,4 @@ async function resolveIcebergDataFiles(conn, opts) {
|
|
|
399
429
|
}
|
|
400
430
|
return out;
|
|
401
431
|
}
|
|
402
|
-
export { ICEBERG_TYPE_MAP, buildManifestPartitionFilter, cacheGet, cachePut, catalogCacheScope, connectIcebergCatalog, dropIcebergTables, ensureIcebergNamespace, icebergAppendRetrying, invalidateSnapshotRef, isCommitRateLimited, listIcebergTables, resolveIcebergDataFiles };
|
|
432
|
+
export { ICEBERG_TYPE_MAP, buildManifestPartitionFilter, cacheGet, cachePut, catalogCacheScope, connectIcebergCatalog, dropIcebergTables, ensureIcebergNamespace, icebergAppendBatchesRetrying, icebergAppendRetrying, invalidateSnapshotRef, isCommitRateLimited, listIcebergTables, resolveIcebergDataFiles };
|
|
@@ -3145,7 +3145,7 @@ function compareKeys(ka, kb, resultType, desc, nullsFirst) {
|
|
|
3145
3145
|
const c = compare(ka, kb, resultType);
|
|
3146
3146
|
return desc ? -c : c;
|
|
3147
3147
|
}
|
|
3148
|
-
async function prepareAppend({ tableUrl, metadata, records, resolver, sortOrderId }) {
|
|
3148
|
+
async function prepareAppend({ tableUrl, metadata, records, resolver, sortOrderId, snapshotId }) {
|
|
3149
3149
|
if (!tableUrl) throw new Error("tableUrl is required");
|
|
3150
3150
|
if (!resolver?.writer) throw new Error("resolver.writer is required");
|
|
3151
3151
|
const writerFn = resolver.writer;
|
|
@@ -3156,7 +3156,7 @@ async function prepareAppend({ tableUrl, metadata, records, resolver, sortOrderI
|
|
|
3156
3156
|
const schema = metadata.schemas.find((s) => s["schema-id"] === metadata["current-schema-id"]);
|
|
3157
3157
|
if (!schema) throw new Error("current schema not found in metadata");
|
|
3158
3158
|
validateSchemaForVersion(schema, formatVersion);
|
|
3159
|
-
const
|
|
3159
|
+
const appendSnapshotId = snapshotId ?? newSnapshotId(metadata);
|
|
3160
3160
|
const manifestUuid = uuid4();
|
|
3161
3161
|
checkWriteFormat(metadata.properties?.["write.format.default"]);
|
|
3162
3162
|
const codec = resolveParquetCodec(metadata.properties?.["write.parquet.compression-codec"]);
|
|
@@ -3206,7 +3206,7 @@ async function prepareAppend({ tableUrl, metadata, records, resolver, sortOrderI
|
|
|
3206
3206
|
writer: manifestWriter,
|
|
3207
3207
|
schema,
|
|
3208
3208
|
partitionSpec,
|
|
3209
|
-
snapshotId,
|
|
3209
|
+
snapshotId: appendSnapshotId,
|
|
3210
3210
|
dataFiles: writtenDataFiles.map((f) => f.dataFile),
|
|
3211
3211
|
formatVersion
|
|
3212
3212
|
});
|
|
@@ -3215,7 +3215,7 @@ async function prepareAppend({ tableUrl, metadata, records, resolver, sortOrderI
|
|
|
3215
3215
|
const addedFilesSize = writtenDataFiles.reduce((sum, f) => sum + f.dataFile.file_size_in_bytes, 0n);
|
|
3216
3216
|
const partitions = buildPartitionSummaries(writtenDataFiles.map((f) => f.dataFile.partition), schema, partitionSpec);
|
|
3217
3217
|
return {
|
|
3218
|
-
snapshotId,
|
|
3218
|
+
snapshotId: appendSnapshotId,
|
|
3219
3219
|
manifestUuid,
|
|
3220
3220
|
formatVersion,
|
|
3221
3221
|
manifestPath,
|
|
@@ -3284,6 +3284,70 @@ async function stageSnapshotForAppend({ tableUrl, metadata, prepared, resolver,
|
|
|
3284
3284
|
writtenFiles: []
|
|
3285
3285
|
});
|
|
3286
3286
|
}
|
|
3287
|
+
async function stageSnapshotForAppendBatches({ tableUrl, metadata, prepared, resolver, snapshotProperties }) {
|
|
3288
|
+
if (!tableUrl) throw new Error("tableUrl is required");
|
|
3289
|
+
if (!resolver?.writer) throw new Error("resolver.writer is required");
|
|
3290
|
+
if (prepared.length === 0) throw new Error("prepared batches must not be empty");
|
|
3291
|
+
const first = prepared[0];
|
|
3292
|
+
for (const batch of prepared) {
|
|
3293
|
+
if (batch.snapshotId !== first.snapshotId) throw new Error("prepared batches must share one snapshot id");
|
|
3294
|
+
if (batch.formatVersion !== first.formatVersion) throw new Error("prepared batches must share one format version");
|
|
3295
|
+
}
|
|
3296
|
+
const sequenceNumber = BigInt(metadata["last-sequence-number"] ?? 0) + 1n;
|
|
3297
|
+
const timestampMs = Date.now();
|
|
3298
|
+
const newManifests = prepared.map((batch) => ({
|
|
3299
|
+
manifest_path: batch.manifestPath,
|
|
3300
|
+
manifest_length: batch.manifestLength,
|
|
3301
|
+
partition_spec_id: batch.partitionSpecId,
|
|
3302
|
+
content: 0,
|
|
3303
|
+
sequence_number: sequenceNumber,
|
|
3304
|
+
min_sequence_number: sequenceNumber,
|
|
3305
|
+
added_snapshot_id: first.snapshotId,
|
|
3306
|
+
added_files_count: batch.addedDataFilesCount,
|
|
3307
|
+
existing_files_count: 0,
|
|
3308
|
+
deleted_files_count: 0,
|
|
3309
|
+
added_rows_count: batch.addedRowCount,
|
|
3310
|
+
existing_rows_count: 0n,
|
|
3311
|
+
deleted_rows_count: 0n,
|
|
3312
|
+
partitions: batch.partitions
|
|
3313
|
+
}));
|
|
3314
|
+
const addedDataFilesCount = prepared.reduce((sum, batch) => sum + batch.addedDataFilesCount, 0);
|
|
3315
|
+
const recordsCount = prepared.reduce((sum, batch) => sum + batch.recordsCount, 0);
|
|
3316
|
+
const addedFilesSize = prepared.reduce((sum, batch) => sum + batch.addedFilesSize, 0n);
|
|
3317
|
+
const prevSummary = currentSnapshot(metadata)?.summary;
|
|
3318
|
+
const prevTotals = {
|
|
3319
|
+
records: BigInt(prevSummary?.["total-records"] ?? "0"),
|
|
3320
|
+
size: BigInt(prevSummary?.["total-files-size"] ?? "0"),
|
|
3321
|
+
files: BigInt(prevSummary?.["total-data-files"] ?? "0")
|
|
3322
|
+
};
|
|
3323
|
+
const summary = {
|
|
3324
|
+
operation: "append",
|
|
3325
|
+
"added-data-files": String(addedDataFilesCount),
|
|
3326
|
+
"added-records": String(recordsCount),
|
|
3327
|
+
"added-files-size": String(addedFilesSize),
|
|
3328
|
+
"changed-partition-count": String(addedDataFilesCount),
|
|
3329
|
+
"total-records": String(prevTotals.records + BigInt(recordsCount)),
|
|
3330
|
+
"total-files-size": String(prevTotals.size + addedFilesSize),
|
|
3331
|
+
"total-data-files": String(prevTotals.files + BigInt(addedDataFilesCount)),
|
|
3332
|
+
"total-delete-files": "0",
|
|
3333
|
+
"total-position-deletes": "0",
|
|
3334
|
+
"total-equality-deletes": "0",
|
|
3335
|
+
...snapshotProperties ?? {}
|
|
3336
|
+
};
|
|
3337
|
+
return await buildSnapshotUpdate({
|
|
3338
|
+
tableUrl,
|
|
3339
|
+
metadata,
|
|
3340
|
+
resolver,
|
|
3341
|
+
snapshotId: first.snapshotId,
|
|
3342
|
+
sequenceNumber,
|
|
3343
|
+
manifestUuid: first.manifestUuid,
|
|
3344
|
+
timestampMs,
|
|
3345
|
+
formatVersion: first.formatVersion,
|
|
3346
|
+
newManifests,
|
|
3347
|
+
summary,
|
|
3348
|
+
writtenFiles: []
|
|
3349
|
+
});
|
|
3350
|
+
}
|
|
3287
3351
|
function checkWriteFormat(value) {
|
|
3288
3352
|
if (value === void 0) return;
|
|
3289
3353
|
if (value.toLowerCase() !== "parquet") throw new Error(`unsupported write.format.default: ${value}`);
|
|
@@ -3415,6 +3479,47 @@ async function icebergAppend({ catalog, namespace, table, tableUrl, resolver, re
|
|
|
3415
3479
|
})
|
|
3416
3480
|
});
|
|
3417
3481
|
}
|
|
3482
|
+
async function icebergAppendBatches({ catalog, namespace, table, tableUrl, resolver, batches, sortOrderId, snapshotProperties }) {
|
|
3483
|
+
const ctx = await loadTable({
|
|
3484
|
+
catalog,
|
|
3485
|
+
namespace,
|
|
3486
|
+
table,
|
|
3487
|
+
tableUrl,
|
|
3488
|
+
resolver
|
|
3489
|
+
});
|
|
3490
|
+
const writer = requireResolver(ctx.resolver, "icebergAppendBatches");
|
|
3491
|
+
const prepared = [];
|
|
3492
|
+
let snapshotId;
|
|
3493
|
+
for await (const records of batches) {
|
|
3494
|
+
if (records.length === 0) continue;
|
|
3495
|
+
const batch = await prepareAppend({
|
|
3496
|
+
tableUrl: ctx.tableUrl,
|
|
3497
|
+
metadata: ctx.metadata,
|
|
3498
|
+
records,
|
|
3499
|
+
resolver: writer,
|
|
3500
|
+
sortOrderId,
|
|
3501
|
+
snapshotId
|
|
3502
|
+
});
|
|
3503
|
+
snapshotId ??= batch.snapshotId;
|
|
3504
|
+
prepared.push(batch);
|
|
3505
|
+
}
|
|
3506
|
+
if (prepared.length === 0) return ctx.metadata;
|
|
3507
|
+
return await commitWithRetry({
|
|
3508
|
+
catalog,
|
|
3509
|
+
target: {
|
|
3510
|
+
namespace,
|
|
3511
|
+
table
|
|
3512
|
+
},
|
|
3513
|
+
ctx,
|
|
3514
|
+
stage: (workingCtx) => stageSnapshotForAppendBatches({
|
|
3515
|
+
tableUrl: workingCtx.tableUrl,
|
|
3516
|
+
metadata: workingCtx.metadata,
|
|
3517
|
+
prepared,
|
|
3518
|
+
resolver: requireResolver(workingCtx.resolver, "icebergAppendBatches"),
|
|
3519
|
+
snapshotProperties
|
|
3520
|
+
})
|
|
3521
|
+
});
|
|
3522
|
+
}
|
|
3418
3523
|
async function icebergCreateTable({ catalog, namespace, table, tableUrl, schema, partitionSpec, sortOrder, properties, formatVersion, stageCreate }) {
|
|
3419
3524
|
if (catalog.type === "rest") {
|
|
3420
3525
|
if (!namespace || !table) throw new Error("namespace and table are required for rest catalogs");
|
|
@@ -3746,4 +3851,4 @@ function s3SignedResolver({ accessKeyId, secretAccessKey, sessionToken, region,
|
|
|
3746
3851
|
return () => new Promise((resolve) => setTimeout(resolve, 0));
|
|
3747
3852
|
})();
|
|
3748
3853
|
new TextEncoder();
|
|
3749
|
-
export { cachingResolver, icebergAppend, icebergCreateTable, icebergDropTable, icebergManifests, restCatalogConnect, restCatalogCreateNamespace, restCatalogListTables, restCatalogLoadTable, s3SignedResolver };
|
|
3854
|
+
export { cachingResolver, icebergAppend, icebergAppendBatches, icebergCreateTable, icebergDropTable, icebergManifests, restCatalogConnect, restCatalogCreateNamespace, restCatalogListTables, restCatalogLoadTable, s3SignedResolver };
|
package/dist/index.d.mts
CHANGED
|
@@ -83,6 +83,15 @@ interface AppendResult {
|
|
|
83
83
|
/** Rows dropped by the identity guard (missing/out-of-range required identity value). */
|
|
84
84
|
skipped: number;
|
|
85
85
|
}
|
|
86
|
+
type AppendBatchSource = () => Iterable<readonly Record<string, unknown>[]> | AsyncIterable<readonly Record<string, unknown>[]>;
|
|
87
|
+
interface AppendBatchesOptions extends AppendCommitOptions {
|
|
88
|
+
/** Stable across job retries; recorded in snapshot metadata for landed checks. */
|
|
89
|
+
appendId: string;
|
|
90
|
+
}
|
|
91
|
+
interface AppendBatchesResult extends AppendResult {
|
|
92
|
+
/** False when this append id was already present before the call. */
|
|
93
|
+
committed: boolean;
|
|
94
|
+
}
|
|
86
95
|
interface AppendSinkCloseResult extends AppendResult {
|
|
87
96
|
flushed: boolean;
|
|
88
97
|
error?: unknown;
|
|
@@ -112,6 +121,12 @@ interface IcebergDataset {
|
|
|
112
121
|
* date column pre-converted via {@link toIcebergDayCount}.
|
|
113
122
|
*/
|
|
114
123
|
appendRows: (conn: IcebergConnection, rows: readonly Record<string, unknown>[], opts?: AppendCommitOptions) => Promise<AppendResult>;
|
|
124
|
+
/**
|
|
125
|
+
* Lazily process bounded row batches, writing multiple data files into one
|
|
126
|
+
* append snapshot and one catalog commit. Dedupe keys must be disjoint
|
|
127
|
+
* across source batches.
|
|
128
|
+
*/
|
|
129
|
+
appendBatches: (conn: IcebergConnection, source: AppendBatchSource, opts: AppendBatchesOptions) => Promise<AppendBatchesResult>;
|
|
115
130
|
/**
|
|
116
131
|
* PURE row processing — the identity INT32 guard, dedupe (identity+dims+
|
|
117
132
|
* naturalKey, last-wins) and cluster pre-sort `appendRows`/`appendSink`
|
|
@@ -143,4 +158,4 @@ interface IcebergDataset {
|
|
|
143
158
|
* from the def. See {@link IcebergDatasetDef}.
|
|
144
159
|
*/
|
|
145
160
|
declare function defineIcebergDataset(def: IcebergDatasetDef): IcebergDataset;
|
|
146
|
-
export { type AppendCommitOptions, type AppendResult, type AppendSink, type AppendSinkCloseResult, type AppendSinkOptions, type CatalogCache, type CommitRetryOptions, type ConnectIcebergOptions, DEFAULT_PARTITION_KEY_ENCODING, type DatasetDim, type DatasetIdentity, ICEBERG_TYPE_MAP, type IcebergCatalogConfig, type IcebergColumn, type IcebergColumnType, type IcebergConnection, type IcebergDataset, type IcebergDatasetColumnDef, type IcebergDatasetDef, type IcebergDatasetLedger, type IcebergFieldSummary, type IcebergListedDataFile, type IcebergPartitionField, type IcebergPartitionSpec, type IcebergPartitionSpecField, type IcebergPartitionTransform, type IcebergPrimitiveType, type IcebergS3Config, type IcebergSchema, type IcebergSchemaField, type IcebergSortOrder, type IcebergSortOrderField, type IcebergTableOpResult, type IcebergTableSpec, type ManifestPartitionFilter, type PartitionKeyEncoding, type PartitionValueMatch, type QueryProfiler, type ResolveDataFilesOptions, type ResolveIcebergDataFilesOptions, bigintJsonReplacer, buildManifestPartitionFilter, cacheGet, cachePut, catalogCacheScope, coerceBigIntToNumber, connectIcebergCatalog, defineIcebergDataset, deriveTableSpec, dropIcebergTables, encodeJsonBigintSafe, ensureIcebergNamespace, invalidateSnapshotRef, listIcebergTables, resolveIcebergDataFiles, stringifyBigintSafe, toIcebergDayCount };
|
|
161
|
+
export { type AppendBatchSource, type AppendBatchesOptions, type AppendBatchesResult, type AppendCommitOptions, type AppendResult, type AppendSink, type AppendSinkCloseResult, type AppendSinkOptions, type CatalogCache, type CommitRetryOptions, type ConnectIcebergOptions, DEFAULT_PARTITION_KEY_ENCODING, type DatasetDim, type DatasetIdentity, ICEBERG_TYPE_MAP, type IcebergCatalogConfig, type IcebergColumn, type IcebergColumnType, type IcebergConnection, type IcebergDataset, type IcebergDatasetColumnDef, type IcebergDatasetDef, type IcebergDatasetLedger, type IcebergFieldSummary, type IcebergListedDataFile, type IcebergPartitionField, type IcebergPartitionSpec, type IcebergPartitionSpecField, type IcebergPartitionTransform, type IcebergPrimitiveType, type IcebergS3Config, type IcebergSchema, type IcebergSchemaField, type IcebergSortOrder, type IcebergSortOrderField, type IcebergTableOpResult, type IcebergTableSpec, type ManifestPartitionFilter, type PartitionKeyEncoding, type PartitionValueMatch, type QueryProfiler, type ResolveDataFilesOptions, type ResolveIcebergDataFilesOptions, bigintJsonReplacer, buildManifestPartitionFilter, cacheGet, cachePut, catalogCacheScope, coerceBigIntToNumber, connectIcebergCatalog, defineIcebergDataset, deriveTableSpec, dropIcebergTables, encodeJsonBigintSafe, ensureIcebergNamespace, invalidateSnapshotRef, listIcebergTables, resolveIcebergDataFiles, stringifyBigintSafe, toIcebergDayCount };
|
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { bigintJsonReplacer, coerceBigIntToNumber, encodeJsonBigintSafe, stringifyBigintSafe } from "./bigint.mjs";
|
|
2
2
|
import { icebergCreateTable } from "./_chunks/libs/icebird.mjs";
|
|
3
|
-
import { ICEBERG_TYPE_MAP, buildManifestPartitionFilter, cacheGet, cachePut, catalogCacheScope, connectIcebergCatalog, dropIcebergTables, ensureIcebergNamespace, icebergAppendRetrying, invalidateSnapshotRef, listIcebergTables, resolveIcebergDataFiles } from "./_chunks/catalog.mjs";
|
|
3
|
+
import { ICEBERG_TYPE_MAP, buildManifestPartitionFilter, cacheGet, cachePut, catalogCacheScope, connectIcebergCatalog, dropIcebergTables, ensureIcebergNamespace, icebergAppendBatchesRetrying, icebergAppendRetrying, invalidateSnapshotRef, listIcebergTables, resolveIcebergDataFiles } from "./_chunks/catalog.mjs";
|
|
4
4
|
import { DEFAULT_PARTITION_KEY_ENCODING } from "./schema.mjs";
|
|
5
5
|
const INT32_MIN = -2147483648;
|
|
6
6
|
const INT32_MAX = 2147483647;
|
|
@@ -140,7 +140,10 @@ function buildRowProcessor(def, tableSpec) {
|
|
|
140
140
|
}
|
|
141
141
|
}
|
|
142
142
|
for (const name of dimNames) out[name] = def.dims[name].toPartitionValue(String(row[name]));
|
|
143
|
-
for (const col of def.columns)
|
|
143
|
+
for (const col of def.columns) {
|
|
144
|
+
const value = row[col.name];
|
|
145
|
+
out[col.name] = col.type === "LONG" ? typeof value === "number" ? BigInt(value) : value : coerceBigIntToNumber(value);
|
|
146
|
+
}
|
|
144
147
|
return out;
|
|
145
148
|
}
|
|
146
149
|
function dedupe(rows) {
|
|
@@ -240,6 +243,35 @@ function defineIcebergDataset(def) {
|
|
|
240
243
|
skipped
|
|
241
244
|
};
|
|
242
245
|
}
|
|
246
|
+
async function appendBatches(conn, source, opts) {
|
|
247
|
+
let accepted = 0;
|
|
248
|
+
let skipped = 0;
|
|
249
|
+
const batchFactory = async function* () {
|
|
250
|
+
accepted = 0;
|
|
251
|
+
skipped = 0;
|
|
252
|
+
for await (const rows of source()) {
|
|
253
|
+
const prepared = process(rows);
|
|
254
|
+
accepted += prepared.records.length;
|
|
255
|
+
skipped += prepared.skipped;
|
|
256
|
+
if (prepared.records.length > 0) yield prepared.records;
|
|
257
|
+
}
|
|
258
|
+
};
|
|
259
|
+
const committed = await icebergAppendBatchesRetrying({
|
|
260
|
+
catalog: conn.catalog,
|
|
261
|
+
namespace: conn.namespace,
|
|
262
|
+
table: def.table,
|
|
263
|
+
resolver: conn.resolver,
|
|
264
|
+
batchFactory
|
|
265
|
+
}, {
|
|
266
|
+
...opts.commitRetry,
|
|
267
|
+
appendId: opts.appendId
|
|
268
|
+
});
|
|
269
|
+
return {
|
|
270
|
+
accepted,
|
|
271
|
+
skipped,
|
|
272
|
+
committed
|
|
273
|
+
};
|
|
274
|
+
}
|
|
243
275
|
function appendSink(opts) {
|
|
244
276
|
let buffer = [];
|
|
245
277
|
let connection;
|
|
@@ -320,6 +352,7 @@ function defineIcebergDataset(def) {
|
|
|
320
352
|
icebergSortOrder: () => sortOrder,
|
|
321
353
|
createTable,
|
|
322
354
|
appendRows,
|
|
355
|
+
appendBatches,
|
|
323
356
|
prepareRows: process,
|
|
324
357
|
appendSink,
|
|
325
358
|
readerPredicate,
|
package/package.json
CHANGED