@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.
Files changed (83) hide show
  1. package/README.md +26 -7
  2. package/dist/arguments/argument-spec.d.ts +53 -0
  3. package/dist/arrow/impl-arrowjs/index.d.ts +1 -1
  4. package/dist/arrow/impl-arrowjs/iterate.d.ts +10 -1
  5. package/dist/arrow/impl-arrowjs/schema.d.ts +2 -0
  6. package/dist/arrow/impl-flechette/index.d.ts +1 -1
  7. package/dist/arrow/impl-flechette/iterate.d.ts +10 -1
  8. package/dist/arrow/impl-flechette/schema.d.ts +2 -0
  9. package/dist/arrow/index.d.ts +1 -1
  10. package/dist/arrow/schema-types.d.ts +3 -1
  11. package/dist/arrow/types.d.ts +39 -3
  12. package/dist/catalog/interface.d.ts +43 -0
  13. package/dist/client/client.d.ts +1 -1
  14. package/dist/client-entry.js +360 -178
  15. package/dist/client-entry.js.map +14 -14
  16. package/dist/functions/table.d.ts +63 -0
  17. package/dist/functions/types.d.ts +38 -0
  18. package/dist/generated/vgi-client.d.ts +59 -0
  19. package/dist/generated/vgi-protocol-schemas.d.ts +19 -0
  20. package/dist/http/fetch.d.ts +10 -0
  21. package/dist/index.core.d.ts +2 -2
  22. package/dist/index.js +1203 -834
  23. package/dist/index.js.map +40 -37
  24. package/dist/protocol/handlers/catalog/shared.d.ts +0 -8
  25. package/dist/protocol/handlers/function.d.ts +11 -0
  26. package/dist/protocol/serializers/bind.d.ts +1 -2
  27. package/dist/protocol/serializers/cardinality.d.ts +1 -2
  28. package/dist/protocol/serializers/splits.d.ts +126 -0
  29. package/dist/protocol/types.d.ts +27 -0
  30. package/dist/request-auth.d.ts +28 -0
  31. package/dist/serve-entry.d.ts +4 -0
  32. package/dist/serve-entry.js +745 -359
  33. package/dist/serve-entry.js.map +32 -29
  34. package/dist/split-token.d.ts +88 -0
  35. package/dist/worker-cf-entry.js +1029 -619
  36. package/dist/worker-cf-entry.js.map +37 -34
  37. package/package.json +3 -3
  38. package/src/arguments/argument-spec.ts +81 -0
  39. package/src/arguments/arguments.ts +0 -1
  40. package/src/arrow/impl-arrowjs/index.ts +1 -1
  41. package/src/arrow/impl-arrowjs/iterate.ts +21 -0
  42. package/src/arrow/impl-arrowjs/schema.ts +4 -0
  43. package/src/arrow/impl-flechette/index.ts +1 -1
  44. package/src/arrow/impl-flechette/iterate.ts +24 -1
  45. package/src/arrow/impl-flechette/schema.ts +4 -0
  46. package/src/arrow/index.ts +1 -1
  47. package/src/arrow/schema-types.ts +4 -0
  48. package/src/arrow/types.ts +39 -3
  49. package/src/catalog/interface.ts +124 -29
  50. package/src/catalog/read-only.ts +18 -18
  51. package/src/client/client.ts +6 -2
  52. package/src/functions/aggregate.ts +3 -0
  53. package/src/functions/copy-from.ts +2 -1
  54. package/src/functions/copy-to.ts +2 -1
  55. package/src/functions/scalar.ts +11 -0
  56. package/src/functions/table-buffering.ts +3 -0
  57. package/src/functions/table-in-out.ts +8 -4
  58. package/src/functions/table.ts +129 -2
  59. package/src/functions/types.ts +40 -0
  60. package/src/generated/vgi-client.ts +63 -1
  61. package/src/generated/vgi-protocol-schemas.ts +240 -14
  62. package/src/http/fetch.ts +117 -2
  63. package/src/index.core.ts +2 -2
  64. package/src/protocol/handlers/aggregate.ts +10 -5
  65. package/src/protocol/handlers/catalog/admin.ts +41 -48
  66. package/src/protocol/handlers/catalog/index_methods.ts +4 -11
  67. package/src/protocol/handlers/catalog/macro.ts +8 -16
  68. package/src/protocol/handlers/catalog/shared.ts +10 -57
  69. package/src/protocol/handlers/catalog/table.ts +33 -96
  70. package/src/protocol/handlers/catalog/view.ts +13 -17
  71. package/src/protocol/handlers/function.ts +311 -18
  72. package/src/protocol/handlers/table-buffering.ts +7 -4
  73. package/src/protocol/serializers/bind.ts +56 -63
  74. package/src/protocol/serializers/cardinality.ts +7 -7
  75. package/src/protocol/serializers/init.ts +52 -10
  76. package/src/protocol/serializers/splits.ts +219 -0
  77. package/src/protocol/state-serializer.ts +55 -1
  78. package/src/protocol/types.ts +27 -0
  79. package/src/request-auth.ts +73 -0
  80. package/src/serve-entry.ts +5 -0
  81. package/src/split-token.ts +297 -0
  82. package/src/worker-cf-entry.ts +2 -1
  83. package/src/worker.ts +30 -10
@@ -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 { batchToScalarDict, batchToSecretDict, projectSchema, projectBatch, emptyBatch } from "../util/arrow/index.js";
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 values come through as BigInt — coerce to number
196
- if (typeof val === "bigint") val = Number(val);
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
- if (typeof val === "bigint") val = Number(val);
742
+ val = narrowArgValue(val);
739
743
  args[spec.name] = val;
740
744
  }
741
745
  return args as TArgs;
@@ -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 values come through as BigInt — coerce to number
346
- if (typeof val === "bigint") val = safeNumber(val);
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);
@@ -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: e0862da99312
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;