@query-farm/vgi 0.28.0 → 0.29.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 +26 -7
- package/dist/arguments/argument-spec.d.ts +53 -0
- package/dist/arrow/impl-arrowjs/index.d.ts +1 -1
- package/dist/arrow/impl-arrowjs/iterate.d.ts +10 -1
- package/dist/arrow/impl-arrowjs/schema.d.ts +2 -0
- package/dist/arrow/impl-flechette/index.d.ts +1 -1
- package/dist/arrow/impl-flechette/iterate.d.ts +10 -1
- package/dist/arrow/impl-flechette/schema.d.ts +2 -0
- package/dist/arrow/index.d.ts +1 -1
- package/dist/arrow/schema-types.d.ts +3 -1
- package/dist/arrow/types.d.ts +39 -3
- package/dist/catalog/interface.d.ts +43 -0
- package/dist/client/client.d.ts +1 -1
- package/dist/client-entry.js +360 -178
- package/dist/client-entry.js.map +14 -14
- package/dist/functions/table.d.ts +63 -0
- package/dist/functions/types.d.ts +38 -0
- package/dist/generated/vgi-client.d.ts +59 -0
- package/dist/generated/vgi-protocol-schemas.d.ts +19 -0
- package/dist/http/fetch.d.ts +10 -0
- package/dist/index.core.d.ts +2 -2
- package/dist/index.js +1203 -834
- package/dist/index.js.map +40 -37
- package/dist/protocol/handlers/catalog/shared.d.ts +0 -8
- package/dist/protocol/handlers/function.d.ts +11 -0
- package/dist/protocol/serializers/bind.d.ts +1 -2
- package/dist/protocol/serializers/cardinality.d.ts +1 -2
- package/dist/protocol/serializers/splits.d.ts +126 -0
- package/dist/protocol/types.d.ts +27 -0
- package/dist/request-auth.d.ts +28 -0
- package/dist/serve-entry.d.ts +4 -0
- package/dist/serve-entry.js +745 -359
- package/dist/serve-entry.js.map +32 -29
- package/dist/split-token.d.ts +88 -0
- package/dist/worker-cf-entry.js +1029 -619
- package/dist/worker-cf-entry.js.map +37 -34
- package/package.json +3 -3
- package/src/arguments/argument-spec.ts +81 -0
- package/src/arguments/arguments.ts +0 -1
- package/src/arrow/impl-arrowjs/index.ts +1 -1
- package/src/arrow/impl-arrowjs/iterate.ts +21 -0
- package/src/arrow/impl-arrowjs/schema.ts +4 -0
- package/src/arrow/impl-flechette/index.ts +1 -1
- package/src/arrow/impl-flechette/iterate.ts +24 -1
- package/src/arrow/impl-flechette/schema.ts +4 -0
- package/src/arrow/index.ts +1 -1
- package/src/arrow/schema-types.ts +4 -0
- package/src/arrow/types.ts +39 -3
- package/src/catalog/interface.ts +124 -29
- package/src/catalog/read-only.ts +18 -18
- package/src/client/client.ts +6 -2
- package/src/functions/aggregate.ts +3 -0
- package/src/functions/copy-from.ts +2 -1
- package/src/functions/copy-to.ts +2 -1
- package/src/functions/scalar.ts +11 -0
- package/src/functions/table-buffering.ts +3 -0
- package/src/functions/table-in-out.ts +8 -4
- package/src/functions/table.ts +129 -2
- package/src/functions/types.ts +40 -0
- package/src/generated/vgi-client.ts +63 -1
- package/src/generated/vgi-protocol-schemas.ts +240 -14
- package/src/http/fetch.ts +117 -2
- package/src/index.core.ts +2 -2
- package/src/protocol/handlers/aggregate.ts +10 -5
- package/src/protocol/handlers/catalog/admin.ts +41 -48
- package/src/protocol/handlers/catalog/index_methods.ts +4 -11
- package/src/protocol/handlers/catalog/macro.ts +8 -16
- package/src/protocol/handlers/catalog/shared.ts +10 -57
- package/src/protocol/handlers/catalog/table.ts +33 -96
- package/src/protocol/handlers/catalog/view.ts +13 -17
- package/src/protocol/handlers/function.ts +311 -18
- package/src/protocol/handlers/table-buffering.ts +7 -4
- package/src/protocol/serializers/bind.ts +56 -63
- package/src/protocol/serializers/cardinality.ts +7 -7
- package/src/protocol/serializers/init.ts +52 -10
- package/src/protocol/serializers/splits.ts +219 -0
- package/src/protocol/state-serializer.ts +55 -1
- package/src/protocol/types.ts +27 -0
- package/src/request-auth.ts +73 -0
- package/src/serve-entry.ts +5 -0
- package/src/split-token.ts +297 -0
- package/src/worker-cf-entry.ts +2 -1
- package/src/worker.ts +30 -10
package/src/functions/scalar.ts
CHANGED
|
@@ -41,6 +41,8 @@ import {
|
|
|
41
41
|
argumentSpecsToSchema,
|
|
42
42
|
constraintSpecFields,
|
|
43
43
|
validateConstConstraints,
|
|
44
|
+
assertArrowType,
|
|
45
|
+
assertArrowTypes,
|
|
44
46
|
type ArgumentConstraints,
|
|
45
47
|
} from "../arguments/argument-spec.js";
|
|
46
48
|
import { batchToScalarDict, batchToSecretDict, batchFromColumns, projectBatch, safeNumber } from "../util/arrow/index.js";
|
|
@@ -202,6 +204,15 @@ export function defineScalarFunction<
|
|
|
202
204
|
R extends VgiDataType = VgiDataType,
|
|
203
205
|
M extends Repr = "rich",
|
|
204
206
|
>(config: ScalarFunctionConfig<P, R, M>): VgiFunction {
|
|
207
|
+
assertArrowTypes(config.params, `defineScalarFunction("${config.name}"): params`);
|
|
208
|
+
assertArrowTypes(config.constParams, `defineScalarFunction("${config.name}"): constParams`);
|
|
209
|
+
if (config.returns !== undefined) {
|
|
210
|
+
assertArrowType(config.returns, `defineScalarFunction("${config.name}"): returns`);
|
|
211
|
+
}
|
|
212
|
+
for (const p of config.parameters ?? []) {
|
|
213
|
+
assertArrowType(p.type, `defineScalarFunction("${config.name}"): parameters["${p.name}"].type`);
|
|
214
|
+
}
|
|
215
|
+
|
|
205
216
|
const repr: Repr = config.repr ?? "rich";
|
|
206
217
|
// Build argument specs
|
|
207
218
|
const specs: ArgumentSpec[] = [];
|
|
@@ -40,6 +40,7 @@ import type {
|
|
|
40
40
|
FunctionExample,
|
|
41
41
|
} from "./types.js";
|
|
42
42
|
import type { ArgumentSpec } from "../arguments/argument-spec.js";
|
|
43
|
+
import { assertArrowType, assertArrowTypes } from "../arguments/argument-spec.js";
|
|
43
44
|
import { batchToScalarDict, batchToSecretDict, projectSchema } from "../util/arrow/index.js";
|
|
44
45
|
import { batchFromColumns, readCanonicalValue } from "../arrow/index.js";
|
|
45
46
|
import { codecFor } from "../arrow/codec/registry.js";
|
|
@@ -182,6 +183,8 @@ export function defineTableBufferingFunction<
|
|
|
182
183
|
TArgs = Record<string, any>,
|
|
183
184
|
TState = any,
|
|
184
185
|
>(config: TableBufferingConfig<TArgs, TState>): TableBufferingVgiFunction {
|
|
186
|
+
assertArrowTypes((config as any).args, `defineTableBufferingFunction("${config.name}"): args`);
|
|
187
|
+
|
|
185
188
|
if (config.sinkOrderDependent && config.requiresInputBatchIndex) {
|
|
186
189
|
throw new Error(
|
|
187
190
|
`${config.name}: sinkOrderDependent and requiresInputBatchIndex are ` +
|
|
@@ -19,7 +19,8 @@ import type {
|
|
|
19
19
|
FunctionExample,
|
|
20
20
|
} from "./types.js";
|
|
21
21
|
import type { ArgumentSpec } from "../arguments/argument-spec.js";
|
|
22
|
-
import {
|
|
22
|
+
import { assertArrowType, assertArrowTypes, narrowArgValue } from "../arguments/argument-spec.js";
|
|
23
|
+
import { batchToScalarDict, batchToSecretDict, projectSchema, projectBatch, emptyBatch, safeNumber } from "../util/arrow/index.js";
|
|
23
24
|
import { CACHE_IF_MODIFIED_SINCE_KEY, CACHE_IF_NONE_MATCH_KEY } from "../cache-control.js";
|
|
24
25
|
import {
|
|
25
26
|
buildJoinKeysLookup,
|
|
@@ -132,6 +133,8 @@ export function defineTableInOutFunction<
|
|
|
132
133
|
TArgs = Record<string, any>,
|
|
133
134
|
TState = null,
|
|
134
135
|
>(config: TableInOutConfig<TArgs, TState>): VgiFunction {
|
|
136
|
+
assertArrowTypes((config as any).args, `defineTableInOutFunction("${config.name}"): args`);
|
|
137
|
+
|
|
135
138
|
|
|
136
139
|
// Build argument specs
|
|
137
140
|
const specs: ArgumentSpec[] = [];
|
|
@@ -192,8 +195,9 @@ export function defineTableInOutFunction<
|
|
|
192
195
|
: undefined;
|
|
193
196
|
// For named args, position is a string (the arg name)
|
|
194
197
|
let val = request.arguments.get(spec.position, defaultVal);
|
|
195
|
-
// Arrow Int64
|
|
196
|
-
|
|
198
|
+
// Arrow Int64 arrives as bigint. Narrow when lossless, keep the
|
|
199
|
+
// bigint when not — see narrowArgValue.
|
|
200
|
+
val = narrowArgValue(val);
|
|
197
201
|
args[spec.name] = val;
|
|
198
202
|
}
|
|
199
203
|
return args as TArgs;
|
|
@@ -735,7 +739,7 @@ export function defineRowTransformFunction<
|
|
|
735
739
|
? config.argDefaults[spec.name]
|
|
736
740
|
: undefined;
|
|
737
741
|
let val = request.arguments.get(spec.position, defaultVal ?? null);
|
|
738
|
-
|
|
742
|
+
val = narrowArgValue(val);
|
|
739
743
|
args[spec.name] = val;
|
|
740
744
|
}
|
|
741
745
|
return args as TArgs;
|
package/src/functions/table.ts
CHANGED
|
@@ -15,6 +15,10 @@ import {
|
|
|
15
15
|
import { codecFor } from "../arrow/codec/registry.js";
|
|
16
16
|
import type { OutputCollector } from "@query-farm/vgi-rpc";
|
|
17
17
|
import { DEFAULT_MAX_WORKERS } from "../types.js";
|
|
18
|
+
import type {
|
|
19
|
+
PlanResult,
|
|
20
|
+
TableFunctionPlanRequest,
|
|
21
|
+
} from "../protocol/serializers/splits.js";
|
|
18
22
|
import type {
|
|
19
23
|
BindRequest,
|
|
20
24
|
BindResponse,
|
|
@@ -34,7 +38,9 @@ import {
|
|
|
34
38
|
validateConstConstraints,
|
|
35
39
|
type ArgumentSpec,
|
|
36
40
|
type ArgumentConstraints,
|
|
41
|
+
narrowArgValue,
|
|
37
42
|
} from "../arguments/argument-spec.js";
|
|
43
|
+
import { assertArrowType, assertArrowTypes } from "../arguments/argument-spec.js";
|
|
38
44
|
import { batchToScalarDict, batchToSecretDict, projectSchema, safeNumber } from "../util/arrow/index.js";
|
|
39
45
|
import {
|
|
40
46
|
buildJoinKeysLookup,
|
|
@@ -144,6 +150,15 @@ export interface TableProcessParams<TArgs = Record<string, any>> {
|
|
|
144
150
|
settings: Record<string, any>;
|
|
145
151
|
secrets: Record<string, Record<string, any>>;
|
|
146
152
|
pushdownFilters?: PushdownFilters;
|
|
153
|
+
/**
|
|
154
|
+
* The verified payloads of the splits this init claimed, in the order given,
|
|
155
|
+
* or undefined when this is not a split scan.
|
|
156
|
+
*
|
|
157
|
+
* Undefined is meaningfully different from an empty array: undefined means
|
|
158
|
+
* the client did not plan (a split-only function should fail loudly rather
|
|
159
|
+
* than answer the same query differently), empty means a claim of no work.
|
|
160
|
+
*/
|
|
161
|
+
splitPayloads?: Uint8Array[];
|
|
147
162
|
storage?: BoundStorage;
|
|
148
163
|
/**
|
|
149
164
|
* AT (TIMESTAMP|VERSION) clause for this scan, or `undefined` when the scan
|
|
@@ -227,6 +242,45 @@ export interface TableFunctionConfig<
|
|
|
227
242
|
) => void | Promise<void>;
|
|
228
243
|
/** Cardinality hints */
|
|
229
244
|
cardinality?: (params: TableBindParams<TArgs>) => TableCardinality | Promise<TableCardinality>;
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Divide this scan into named, independently redeemable splits.
|
|
248
|
+
*
|
|
249
|
+
* Declaring it (together with `meta.supportsSplits`) is what opts a function
|
|
250
|
+
* into the split path; omitting it means the whole scan is one unit of work.
|
|
251
|
+
*
|
|
252
|
+
* A split *names* work rather than describing it. "These three files at
|
|
253
|
+
* version 47" survives a retry; "rows 0-999 of whatever this returns now"
|
|
254
|
+
* does not — and a distributed engine WILL retry, so the difference is
|
|
255
|
+
* correctness, not tidiness. The same split may also be redeemed more than
|
|
256
|
+
* once (recursive CTEs, re-collected DataFrames, task retry) and may be
|
|
257
|
+
* abandoned mid-stream (LIMIT, TopK, an empty join build side); neither is an
|
|
258
|
+
* error.
|
|
259
|
+
*
|
|
260
|
+
* Set only `payload` on each split. The framework stamps the consistency
|
|
261
|
+
* anchor, the bind fingerprint and (where a key exists) the seal.
|
|
262
|
+
*
|
|
263
|
+
* Size splits into comparable units of work and honour `targetSplitBytes`: a
|
|
264
|
+
* claiming client treats them as interchangeable because it cannot see
|
|
265
|
+
* per-split cost, so wildly uneven splits leave its makespan bounded by the
|
|
266
|
+
* largest one.
|
|
267
|
+
*/
|
|
268
|
+
plan?: (
|
|
269
|
+
params: TableBindParams<TArgs>,
|
|
270
|
+
request: TableFunctionPlanRequest,
|
|
271
|
+
) => PlanResult | Promise<PlanResult>;
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* Called on a split init with the VERIFIED payloads for the splits this
|
|
275
|
+
* connection claimed — the envelope is already opened and stripped, so
|
|
276
|
+
* unverified bytes never reach here.
|
|
277
|
+
*
|
|
278
|
+
* Any state carried from planning to reading must live in cross-process
|
|
279
|
+
* storage keyed by `execution_id`: the process that plans is, in the general
|
|
280
|
+
* case, not the process that reads — and under a distributed engine it is not
|
|
281
|
+
* even the same host.
|
|
282
|
+
*/
|
|
283
|
+
onSplit?: (payloads: Uint8Array[], params: TableBindParams<TArgs>) => void | Promise<void>;
|
|
230
284
|
/**
|
|
231
285
|
* Per-column statistics for the function's output. Returned to DuckDB via
|
|
232
286
|
* the `table_function_statistics` RPC; the optimizer uses min/max to
|
|
@@ -275,12 +329,33 @@ export interface TableFunctionConfig<
|
|
|
275
329
|
supportsBatchIndex?: boolean;
|
|
276
330
|
/** Hive-style partition-columns mode; FunctionInfo.partition_kind. */
|
|
277
331
|
partitionKind?: "NOT_PARTITIONED" | "SINGLE_VALUE_PARTITIONS" | "OVERLAPPING_PARTITIONS" | "DISJOINT_PARTITIONS";
|
|
332
|
+
/**
|
|
333
|
+
* This function divides its scan into named, independently redeemable splits;
|
|
334
|
+
* FunctionInfo.supports_splits. Declare it together with `plan` and `onSplit`.
|
|
335
|
+
*
|
|
336
|
+
* It is what a distributed engine reads to decide it can retry a task against
|
|
337
|
+
* this function, and what makes the client call `plan()` at all — without it a
|
|
338
|
+
* split-capable function is scanned as one undivided unit, silently.
|
|
339
|
+
*/
|
|
340
|
+
supportsSplits?: boolean;
|
|
341
|
+
/**
|
|
342
|
+
* How long a minted split token stays redeemable, or undefined for UNBOUNDED
|
|
343
|
+
* (NOT "expires immediately"); FunctionInfo.split_token_ttl_seconds.
|
|
344
|
+
*
|
|
345
|
+
* A client refuses a plan whose TTL is below its own scheduling horizon,
|
|
346
|
+
* because an expired token is a failed query rather than a degradation:
|
|
347
|
+
* nothing re-plans when one expires, since a distributed engine retries the
|
|
348
|
+
* serialized task it was handed and has no path back to the planner.
|
|
349
|
+
*/
|
|
350
|
+
splitTokenTtlSeconds?: number;
|
|
278
351
|
}
|
|
279
352
|
|
|
280
353
|
export function defineTableFunction<
|
|
281
354
|
TArgs = Record<string, any>,
|
|
282
355
|
TState = null,
|
|
283
356
|
>(config: TableFunctionConfig<TArgs, TState>): VgiFunction {
|
|
357
|
+
assertArrowTypes((config as any).args, `defineTableFunction("${config.name}"): args`);
|
|
358
|
+
|
|
284
359
|
// Build argument specs
|
|
285
360
|
const specs: ArgumentSpec[] = [];
|
|
286
361
|
let posIdx = 0;
|
|
@@ -325,6 +400,8 @@ export function defineTableFunction<
|
|
|
325
400
|
distinctDependent: config.distinctDependent,
|
|
326
401
|
supportsBatchIndex: config.supportsBatchIndex,
|
|
327
402
|
partitionKind: config.partitionKind,
|
|
403
|
+
supportsSplits: config.supportsSplits,
|
|
404
|
+
splitTokenTtlSeconds: config.splitTokenTtlSeconds,
|
|
328
405
|
};
|
|
329
406
|
|
|
330
407
|
function extractArgs(request: BindRequest): TArgs {
|
|
@@ -342,8 +419,9 @@ export function defineTableFunction<
|
|
|
342
419
|
// converts positional args to named args)
|
|
343
420
|
val = request.arguments.get(spec.name, defaultVal);
|
|
344
421
|
}
|
|
345
|
-
// Arrow Int64
|
|
346
|
-
|
|
422
|
+
// Arrow Int64 arrives as bigint. Narrow when lossless, keep the
|
|
423
|
+
// bigint when not — see narrowArgValue.
|
|
424
|
+
val = narrowArgValue(val);
|
|
347
425
|
// Enforce declared constraints at bind (table args are all bind-time).
|
|
348
426
|
const constraints = config.argConstraints?.[spec.name];
|
|
349
427
|
if (constraints) validateConstConstraints(spec.name, constraints, val);
|
|
@@ -378,6 +456,28 @@ export function defineTableFunction<
|
|
|
378
456
|
const executionId = new Uint8Array(16);
|
|
379
457
|
crypto.getRandomValues(executionId);
|
|
380
458
|
|
|
459
|
+
// A SPLIT init is neither primary nor secondary. It carries an
|
|
460
|
+
// execution_id like a secondary, so it must not re-run global init — but
|
|
461
|
+
// unlike a secondary it MUST run user code, because the payload is what
|
|
462
|
+
// names the work. The secondary branch below runs none, which is why this
|
|
463
|
+
// is a third branch rather than a flag on that one.
|
|
464
|
+
if (request.split_payloads) {
|
|
465
|
+
if (config.onSplit) {
|
|
466
|
+
await config.onSplit(request.split_payloads, {
|
|
467
|
+
args: extractArgs(request.bind_call),
|
|
468
|
+
bindCall: request.bind_call,
|
|
469
|
+
settings: batchToScalarDict(request.bind_call.settings),
|
|
470
|
+
secrets: batchToSecretDict(request.bind_call.secrets),
|
|
471
|
+
resolvedSecretsProvided: request.bind_call.resolved_secrets_provided ?? false,
|
|
472
|
+
});
|
|
473
|
+
}
|
|
474
|
+
return {
|
|
475
|
+
max_workers: config.maxWorkers ?? 1,
|
|
476
|
+
execution_id: request.execution_id ?? executionId,
|
|
477
|
+
opaque_data: null,
|
|
478
|
+
};
|
|
479
|
+
}
|
|
480
|
+
|
|
381
481
|
if (request.execution_id) {
|
|
382
482
|
// Secondary init - reuse execution ID
|
|
383
483
|
return {
|
|
@@ -440,6 +540,7 @@ export function defineTableFunction<
|
|
|
440
540
|
settings,
|
|
441
541
|
secrets,
|
|
442
542
|
pushdownFilters,
|
|
543
|
+
splitPayloads: request.split_payloads ?? undefined,
|
|
443
544
|
storage: boundStorage,
|
|
444
545
|
atUnit: request.bind_call.at_unit ?? undefined,
|
|
445
546
|
atValue: request.bind_call.at_value ?? undefined,
|
|
@@ -523,6 +624,32 @@ export function defineTableFunction<
|
|
|
523
624
|
}
|
|
524
625
|
: undefined,
|
|
525
626
|
|
|
627
|
+
// Wired through with decoded arguments, exactly as cardinality and
|
|
628
|
+
// statistics are.
|
|
629
|
+
//
|
|
630
|
+
// It was previously declared on the config type and never passed to the
|
|
631
|
+
// returned function, so the hook was DEAD: a worker could declare
|
|
632
|
+
// `supportsSplits` and a `plan`, advertise split capability on the wire, and
|
|
633
|
+
// silently serve the framework default of one empty-payload split. Nothing
|
|
634
|
+
// failed — the scan just quietly stopped being divided.
|
|
635
|
+
plan: config.plan
|
|
636
|
+
? (request: TableFunctionPlanRequest) => {
|
|
637
|
+
const args = extractArgs(request.bind_call);
|
|
638
|
+
const settings = batchToScalarDict(request.bind_call.settings);
|
|
639
|
+
const secrets = batchToSecretDict(request.bind_call.secrets);
|
|
640
|
+
return config.plan!(
|
|
641
|
+
{
|
|
642
|
+
args,
|
|
643
|
+
bindCall: request.bind_call,
|
|
644
|
+
settings,
|
|
645
|
+
secrets,
|
|
646
|
+
resolvedSecretsProvided: request.bind_call.resolved_secrets_provided ?? false,
|
|
647
|
+
},
|
|
648
|
+
request,
|
|
649
|
+
);
|
|
650
|
+
}
|
|
651
|
+
: undefined,
|
|
652
|
+
|
|
526
653
|
statistics: config.statistics
|
|
527
654
|
? (request: TableFunctionCardinalityRequest) => {
|
|
528
655
|
const args = extractArgs(request.bind_call);
|
package/src/functions/types.ts
CHANGED
|
@@ -102,6 +102,38 @@ export interface FunctionMeta {
|
|
|
102
102
|
* `supports_batch_index`.
|
|
103
103
|
*/
|
|
104
104
|
supportsBatchIndex?: boolean;
|
|
105
|
+
/**
|
|
106
|
+
* table (generator): the scan divides into named, independently redeemable
|
|
107
|
+
* splits (see the `plan` / `onSplit` hooks). Surfaces as FunctionInfo
|
|
108
|
+
* `supports_splits`.
|
|
109
|
+
*
|
|
110
|
+
* The declaration is what a distributed engine reads to decide whether it can
|
|
111
|
+
* retry a task: a split NAMES its work, so re-running one reads exactly the
|
|
112
|
+
* same rows. Without it, the division lives behind an opaque worker-side queue
|
|
113
|
+
* and a retry reads neither what it read before nor what it missed.
|
|
114
|
+
*/
|
|
115
|
+
supportsSplits?: boolean;
|
|
116
|
+
/**
|
|
117
|
+
* table (generator): the worker applies every pushed filter EXACTLY, so the
|
|
118
|
+
* engine may drop its own copy rather than re-filtering. Wrong answers if
|
|
119
|
+
* declared falsely — leave unset unless certain.
|
|
120
|
+
*/
|
|
121
|
+
filtersExactlyApplied?: boolean;
|
|
122
|
+
/**
|
|
123
|
+
* table (generator): addressable positions in the data, for incremental and
|
|
124
|
+
* streaming reads. The engine owns the checkpoint; this declares only that
|
|
125
|
+
* positions are meaningful to externalize.
|
|
126
|
+
*/
|
|
127
|
+
supportsPositions?: boolean;
|
|
128
|
+
/**
|
|
129
|
+
* table (generator): how long a split token stays redeemable.
|
|
130
|
+
*
|
|
131
|
+
* UNSET MEANS UNBOUNDED, not "expires immediately" — a client must not assume
|
|
132
|
+
* a TTL exists, or long-running streams are foreclosed. A client rejects a
|
|
133
|
+
* plan whose TTL is below its own planning-to-task-start horizon, which on a
|
|
134
|
+
* busy cluster is hours rather than seconds.
|
|
135
|
+
*/
|
|
136
|
+
splitTokenTtlSeconds?: number;
|
|
105
137
|
/**
|
|
106
138
|
* table (generator): Hive-style partition-columns mode. Functions declare
|
|
107
139
|
* a PartitionKind and annotate bind-schema fields; emitted batches carry
|
|
@@ -180,6 +212,14 @@ export interface VgiFunction {
|
|
|
180
212
|
accumulatedState?: any,
|
|
181
213
|
): StreamHandlers;
|
|
182
214
|
cardinality?(request: TableFunctionCardinalityRequest): TableCardinality | Promise<TableCardinality>;
|
|
215
|
+
/**
|
|
216
|
+
* Divide a scan into named, independently redeemable splits. Absent means the
|
|
217
|
+
* function is not split-capable: the whole scan is one unit of work, and the
|
|
218
|
+
* framework answers with a single empty-payload split.
|
|
219
|
+
*/
|
|
220
|
+
plan?(request: import("../protocol/serializers/splits.js").TableFunctionPlanRequest):
|
|
221
|
+
| import("../protocol/serializers/splits.js").PlanResult
|
|
222
|
+
| Promise<import("../protocol/serializers/splits.js").PlanResult>;
|
|
183
223
|
/**
|
|
184
224
|
* Per-column statistics for this table function's output given the user's
|
|
185
225
|
* bind-time arguments. Returns null/[] when stats are unknown. Wired to the
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// GENERATED by vgi.codegen.ts_client. DO NOT EDIT BY HAND.
|
|
3
3
|
//
|
|
4
4
|
// Generator: vgi-gen-ts-client v1
|
|
5
|
-
// Content hash:
|
|
5
|
+
// Content hash: bda03237975e
|
|
6
6
|
//
|
|
7
7
|
// To regenerate:
|
|
8
8
|
// uv run --project ~/Development/vgi-python vgi-gen-ts-client \
|
|
@@ -129,6 +129,10 @@ export interface FunctionInfo {
|
|
|
129
129
|
order_preservation?: OrderPreservation | null;
|
|
130
130
|
max_workers?: number | null;
|
|
131
131
|
supports_batch_index: boolean;
|
|
132
|
+
supports_splits: boolean;
|
|
133
|
+
filters_exactly_applied: boolean;
|
|
134
|
+
supports_positions: boolean;
|
|
135
|
+
split_token_ttl_seconds?: number | null;
|
|
132
136
|
partition_kind: PartitionKind;
|
|
133
137
|
order_dependent: OrderDependence;
|
|
134
138
|
distinct_dependent: DistinctDependence;
|
|
@@ -368,6 +372,7 @@ export interface CatalogAttachRequest {
|
|
|
368
372
|
options?: /** @record-batch */ Uint8Array | null;
|
|
369
373
|
data_version_spec?: string | null;
|
|
370
374
|
implementation_version?: string | null;
|
|
375
|
+
client_capabilities?: Uint8Array | null;
|
|
371
376
|
}
|
|
372
377
|
|
|
373
378
|
export interface CatalogAttachResult {
|
|
@@ -483,6 +488,8 @@ export interface InitRequest {
|
|
|
483
488
|
projection_ids?: number[] | null;
|
|
484
489
|
pushdown_filters?: /** @record-batch */ Uint8Array | null;
|
|
485
490
|
join_keys?: /** @record-batch */ Uint8Array[] | null;
|
|
491
|
+
split_tokens?: Uint8Array[] | null;
|
|
492
|
+
row_limit?: number | null;
|
|
486
493
|
phase?: TableInOutFunctionInitPhase | null;
|
|
487
494
|
finalize_state_id?: Uint8Array | null;
|
|
488
495
|
execution_id?: Uint8Array | null;
|
|
@@ -555,6 +562,61 @@ export interface TableFunctionDynamicToStringResponse {
|
|
|
555
562
|
values: string[];
|
|
556
563
|
}
|
|
557
564
|
|
|
565
|
+
export interface TableFunctionPlanRequest {
|
|
566
|
+
bind_call: BindRequest;
|
|
567
|
+
bind_opaque_data?: Uint8Array | null;
|
|
568
|
+
projection_ids?: number[] | null;
|
|
569
|
+
pushdown_filters?: /** @record-batch */ Uint8Array | null;
|
|
570
|
+
join_keys?: /** @record-batch */ Uint8Array[] | null;
|
|
571
|
+
row_limit?: number | null;
|
|
572
|
+
target_split_bytes?: number | null;
|
|
573
|
+
min_splits?: number | null;
|
|
574
|
+
max_splits_per_response?: number | null;
|
|
575
|
+
cursor?: Uint8Array | null;
|
|
576
|
+
refined_filters?: /** @record-batch */ Uint8Array | null;
|
|
577
|
+
filters_complete: boolean;
|
|
578
|
+
start_position?: Uint8Array | null;
|
|
579
|
+
end_position?: Uint8Array | null;
|
|
580
|
+
order_by_column_name?: string | null;
|
|
581
|
+
order_by_direction?: OrderByDirection | null;
|
|
582
|
+
order_by_null_order?: OrderByNullOrder | null;
|
|
583
|
+
order_by_limit?: number | null;
|
|
584
|
+
tablesample_percentage?: number | null;
|
|
585
|
+
tablesample_seed?: number | null;
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
export interface ScanSplit {
|
|
589
|
+
payload: Uint8Array;
|
|
590
|
+
token: Uint8Array;
|
|
591
|
+
estimated_rows?: number | null;
|
|
592
|
+
rows_exact: boolean;
|
|
593
|
+
estimated_bytes?: number | null;
|
|
594
|
+
partition_bounds?: /** @record-batch */ Uint8Array | null;
|
|
595
|
+
column_statistics?: Uint8Array | null;
|
|
596
|
+
location_ids?: number[] | null;
|
|
597
|
+
start_position?: Uint8Array | null;
|
|
598
|
+
end_position?: Uint8Array | null;
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
export interface PlanResponse {
|
|
602
|
+
splits: ScanSplit[] | Uint8Array[];
|
|
603
|
+
next_cursors?: Uint8Array[] | null;
|
|
604
|
+
execution_id?: Uint8Array | null;
|
|
605
|
+
init_opaque_data?: Uint8Array | null;
|
|
606
|
+
max_workers?: number | null;
|
|
607
|
+
estimated_total_splits?: number | null;
|
|
608
|
+
estimated_total_rows?: number | null;
|
|
609
|
+
estimated_total_bytes?: number | null;
|
|
610
|
+
catalog_version?: number | null;
|
|
611
|
+
scope: string;
|
|
612
|
+
locations?: string[] | null;
|
|
613
|
+
partitioning?: Uint8Array[] | null;
|
|
614
|
+
sort_order?: Uint8Array[] | null;
|
|
615
|
+
cache_max_age_seconds?: number | null;
|
|
616
|
+
start_position?: Uint8Array | null;
|
|
617
|
+
end_position?: Uint8Array | null;
|
|
618
|
+
}
|
|
619
|
+
|
|
558
620
|
export interface TableFunctionStatisticsRequest {
|
|
559
621
|
bind_call: BindRequest;
|
|
560
622
|
bind_opaque_data?: Uint8Array | null;
|