@query-farm/vgi 0.6.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 (206) hide show
  1. package/LICENSE +134 -0
  2. package/README.md +494 -0
  3. package/dist/__dbg.test-d.d.ts +1 -0
  4. package/dist/arguments/argument-spec.d.ts +51 -0
  5. package/dist/arguments/arguments.d.ts +13 -0
  6. package/dist/arrow/codec/branded.d.ts +83 -0
  7. package/dist/arrow/codec/registry.d.ts +29 -0
  8. package/dist/arrow/codec/repr.d.ts +23 -0
  9. package/dist/arrow/codec/type-descriptors.d.ts +109 -0
  10. package/dist/arrow/impl-arrowjs/build.d.ts +19 -0
  11. package/dist/arrow/impl-arrowjs/canonical.d.ts +15 -0
  12. package/dist/arrow/impl-arrowjs/empty.d.ts +7 -0
  13. package/dist/arrow/impl-arrowjs/filter.d.ts +11 -0
  14. package/dist/arrow/impl-arrowjs/index.d.ts +11 -0
  15. package/dist/arrow/impl-arrowjs/ipc.d.ts +24 -0
  16. package/dist/arrow/impl-arrowjs/iterate.d.ts +39 -0
  17. package/dist/arrow/impl-arrowjs/project.d.ts +10 -0
  18. package/dist/arrow/impl-arrowjs/schema.d.ts +62 -0
  19. package/dist/arrow/impl-arrowjs/statistics.d.ts +13 -0
  20. package/dist/arrow/impl-flechette/build.d.ts +14 -0
  21. package/dist/arrow/impl-flechette/canonical.d.ts +18 -0
  22. package/dist/arrow/impl-flechette/empty.d.ts +9 -0
  23. package/dist/arrow/impl-flechette/filter.d.ts +10 -0
  24. package/dist/arrow/impl-flechette/index.d.ts +11 -0
  25. package/dist/arrow/impl-flechette/ipc.d.ts +33 -0
  26. package/dist/arrow/impl-flechette/iterate.d.ts +29 -0
  27. package/dist/arrow/impl-flechette/message-meta.d.ts +10 -0
  28. package/dist/arrow/impl-flechette/normalize-type.d.ts +11 -0
  29. package/dist/arrow/impl-flechette/project.d.ts +3 -0
  30. package/dist/arrow/impl-flechette/schema.d.ts +47 -0
  31. package/dist/arrow/impl-flechette/statistics.d.ts +13 -0
  32. package/dist/arrow/index.d.ts +11 -0
  33. package/dist/arrow/predicates.d.ts +47 -0
  34. package/dist/arrow/repr.test-d.d.ts +52 -0
  35. package/dist/arrow/schema-types.d.ts +71 -0
  36. package/dist/arrow/types.d.ts +57 -0
  37. package/dist/catalog/attach-option.d.ts +33 -0
  38. package/dist/catalog/attach-options.d.ts +30 -0
  39. package/dist/catalog/composite.d.ts +33 -0
  40. package/dist/catalog/descriptors.d.ts +154 -0
  41. package/dist/catalog/interface.d.ts +239 -0
  42. package/dist/catalog/read-only.d.ts +33 -0
  43. package/dist/client/client.d.ts +189 -0
  44. package/dist/client/errors.d.ts +26 -0
  45. package/dist/client/helpers.d.ts +12 -0
  46. package/dist/client/protocol.d.ts +16 -0
  47. package/dist/client/types.d.ts +125 -0
  48. package/dist/client-entry.d.ts +11 -0
  49. package/dist/client-entry.js +48 -0
  50. package/dist/client-entry.js.map +9 -0
  51. package/dist/codec/asd.d.ts +25 -0
  52. package/dist/crypto.d.ts +36 -0
  53. package/dist/errors.d.ts +24 -0
  54. package/dist/filter-pushdown/collector.d.ts +32 -0
  55. package/dist/filter-pushdown/deserialize.d.ts +16 -0
  56. package/dist/filter-pushdown/evaluate.d.ts +51 -0
  57. package/dist/filter-pushdown/index.d.ts +4 -0
  58. package/dist/filter-pushdown/types.d.ts +84 -0
  59. package/dist/functions/aggregate.d.ts +129 -0
  60. package/dist/functions/copy-from.d.ts +81 -0
  61. package/dist/functions/copy-to.d.ts +121 -0
  62. package/dist/functions/registry.d.ts +16 -0
  63. package/dist/functions/scalar.d.ts +98 -0
  64. package/dist/functions/storage-cf-do.d.ts +47 -0
  65. package/dist/functions/storage.d.ts +86 -0
  66. package/dist/functions/table-buffering.d.ts +99 -0
  67. package/dist/functions/table-in-out.d.ts +64 -0
  68. package/dist/functions/table.d.ts +118 -0
  69. package/dist/functions/types.d.ts +157 -0
  70. package/dist/generated/vgi-client.d.ts +466 -0
  71. package/dist/generated/vgi-protocol-schemas.d.ts +115 -0
  72. package/dist/index.core.d.ts +42 -0
  73. package/dist/index.d.ts +2 -0
  74. package/dist/index.js +10888 -0
  75. package/dist/index.js.map +85 -0
  76. package/dist/metadata/resolve.d.ts +3 -0
  77. package/dist/metadata/serialize.d.ts +12 -0
  78. package/dist/metadata/types.d.ts +47 -0
  79. package/dist/protocol/dispatch.d.ts +23 -0
  80. package/dist/protocol/handlers/aggregate.d.ts +3 -0
  81. package/dist/protocol/handlers/catalog/admin.d.ts +3 -0
  82. package/dist/protocol/handlers/catalog/index.d.ts +3 -0
  83. package/dist/protocol/handlers/catalog/index_methods.d.ts +3 -0
  84. package/dist/protocol/handlers/catalog/macro.d.ts +3 -0
  85. package/dist/protocol/handlers/catalog/shared.d.ts +70 -0
  86. package/dist/protocol/handlers/catalog/table.d.ts +3 -0
  87. package/dist/protocol/handlers/catalog/view.d.ts +3 -0
  88. package/dist/protocol/handlers/function.d.ts +8 -0
  89. package/dist/protocol/handlers/shared.d.ts +31 -0
  90. package/dist/protocol/handlers/table-buffering.d.ts +3 -0
  91. package/dist/protocol/serialize.d.ts +4 -0
  92. package/dist/protocol/serializers/arguments.d.ts +3 -0
  93. package/dist/protocol/serializers/bind.d.ts +9 -0
  94. package/dist/protocol/serializers/cardinality.d.ts +7 -0
  95. package/dist/protocol/serializers/init.d.ts +9 -0
  96. package/dist/protocol/serializers/shared.d.ts +12 -0
  97. package/dist/protocol/state-serializer.d.ts +23 -0
  98. package/dist/protocol/types.d.ts +129 -0
  99. package/dist/secrets/helpers.d.ts +15 -0
  100. package/dist/types.d.ts +52 -0
  101. package/dist/util/arrow/index.d.ts +1 -0
  102. package/dist/util/bytes.d.ts +2 -0
  103. package/dist/util/statistics.d.ts +7 -0
  104. package/dist/worker-cf-entry.d.ts +30 -0
  105. package/dist/worker-cf-entry.js +8767 -0
  106. package/dist/worker-cf-entry.js.map +74 -0
  107. package/dist/worker.d.ts +36 -0
  108. package/package.json +96 -0
  109. package/src/arguments/argument-spec.ts +200 -0
  110. package/src/arguments/arguments.ts +81 -0
  111. package/src/arrow/codec/branded.ts +206 -0
  112. package/src/arrow/codec/registry.ts +674 -0
  113. package/src/arrow/codec/repr.ts +181 -0
  114. package/src/arrow/codec/type-descriptors.ts +137 -0
  115. package/src/arrow/impl-arrowjs/build.ts +88 -0
  116. package/src/arrow/impl-arrowjs/canonical.ts +509 -0
  117. package/src/arrow/impl-arrowjs/empty.ts +72 -0
  118. package/src/arrow/impl-arrowjs/filter.ts +53 -0
  119. package/src/arrow/impl-arrowjs/index.ts +54 -0
  120. package/src/arrow/impl-arrowjs/ipc.ts +67 -0
  121. package/src/arrow/impl-arrowjs/iterate.ts +159 -0
  122. package/src/arrow/impl-arrowjs/project.ts +73 -0
  123. package/src/arrow/impl-arrowjs/schema.ts +256 -0
  124. package/src/arrow/impl-arrowjs/statistics.ts +185 -0
  125. package/src/arrow/impl-flechette/build.ts +65 -0
  126. package/src/arrow/impl-flechette/canonical.ts +289 -0
  127. package/src/arrow/impl-flechette/empty.ts +20 -0
  128. package/src/arrow/impl-flechette/filter.ts +42 -0
  129. package/src/arrow/impl-flechette/index.ts +54 -0
  130. package/src/arrow/impl-flechette/ipc.ts +110 -0
  131. package/src/arrow/impl-flechette/iterate.ts +121 -0
  132. package/src/arrow/impl-flechette/message-meta.ts +175 -0
  133. package/src/arrow/impl-flechette/normalize-type.ts +99 -0
  134. package/src/arrow/impl-flechette/project.ts +64 -0
  135. package/src/arrow/impl-flechette/schema.ts +202 -0
  136. package/src/arrow/impl-flechette/statistics.ts +198 -0
  137. package/src/arrow/index.ts +129 -0
  138. package/src/arrow/predicates.ts +66 -0
  139. package/src/arrow/repr.test-d.ts +189 -0
  140. package/src/arrow/schema-types.ts +213 -0
  141. package/src/arrow/types.ts +74 -0
  142. package/src/catalog/attach-option.ts +107 -0
  143. package/src/catalog/attach-options.ts +79 -0
  144. package/src/catalog/composite.ts +180 -0
  145. package/src/catalog/descriptors.ts +164 -0
  146. package/src/catalog/interface.ts +721 -0
  147. package/src/catalog/read-only.ts +909 -0
  148. package/src/client/client.ts +1348 -0
  149. package/src/client/errors.ts +69 -0
  150. package/src/client/helpers.ts +56 -0
  151. package/src/client/protocol.ts +33 -0
  152. package/src/client/types.ts +140 -0
  153. package/src/client-entry.ts +112 -0
  154. package/src/codec/asd.ts +147 -0
  155. package/src/crypto.ts +143 -0
  156. package/src/errors.ts +61 -0
  157. package/src/filter-pushdown/collector.ts +147 -0
  158. package/src/filter-pushdown/deserialize.ts +253 -0
  159. package/src/filter-pushdown/evaluate.ts +591 -0
  160. package/src/filter-pushdown/index.ts +28 -0
  161. package/src/filter-pushdown/types.ts +91 -0
  162. package/src/functions/aggregate.ts +384 -0
  163. package/src/functions/copy-from.ts +282 -0
  164. package/src/functions/copy-to.ts +319 -0
  165. package/src/functions/registry.ts +258 -0
  166. package/src/functions/scalar.ts +356 -0
  167. package/src/functions/storage-cf-do.ts +303 -0
  168. package/src/functions/storage.ts +521 -0
  169. package/src/functions/table-buffering.ts +562 -0
  170. package/src/functions/table-in-out.ts +373 -0
  171. package/src/functions/table.ts +521 -0
  172. package/src/functions/types.ts +192 -0
  173. package/src/generated/vgi-client.ts +560 -0
  174. package/src/generated/vgi-protocol-schemas.ts +864 -0
  175. package/src/index.core.ts +267 -0
  176. package/src/index.ts +11 -0
  177. package/src/metadata/resolve.ts +109 -0
  178. package/src/metadata/serialize.ts +242 -0
  179. package/src/metadata/types.ts +60 -0
  180. package/src/protocol/dispatch.ts +52 -0
  181. package/src/protocol/handlers/aggregate.ts +355 -0
  182. package/src/protocol/handlers/catalog/admin.ts +368 -0
  183. package/src/protocol/handlers/catalog/index.ts +25 -0
  184. package/src/protocol/handlers/catalog/index_methods.ts +65 -0
  185. package/src/protocol/handlers/catalog/macro.ts +114 -0
  186. package/src/protocol/handlers/catalog/shared.ts +291 -0
  187. package/src/protocol/handlers/catalog/table.ts +401 -0
  188. package/src/protocol/handlers/catalog/view.ts +119 -0
  189. package/src/protocol/handlers/function.ts +302 -0
  190. package/src/protocol/handlers/shared.ts +80 -0
  191. package/src/protocol/handlers/table-buffering.ts +207 -0
  192. package/src/protocol/serialize.ts +23 -0
  193. package/src/protocol/serializers/arguments.ts +160 -0
  194. package/src/protocol/serializers/bind.ts +212 -0
  195. package/src/protocol/serializers/cardinality.ts +45 -0
  196. package/src/protocol/serializers/init.ts +247 -0
  197. package/src/protocol/serializers/shared.ts +46 -0
  198. package/src/protocol/state-serializer.ts +181 -0
  199. package/src/protocol/types.ts +153 -0
  200. package/src/secrets/helpers.ts +70 -0
  201. package/src/types.ts +71 -0
  202. package/src/util/arrow/index.ts +23 -0
  203. package/src/util/bytes.ts +14 -0
  204. package/src/util/statistics.ts +40 -0
  205. package/src/worker-cf-entry.ts +172 -0
  206. package/src/worker.ts +212 -0
@@ -0,0 +1,121 @@
1
+ import { type VgiBatch, type VgiDataType } from "../arrow/index.js";
2
+ import type { BindRequest } from "../protocol/types.js";
3
+ import type { FunctionExample } from "./types.js";
4
+ import { type TableBufferingParams, type TableBufferingVgiFunction } from "./table-buffering.js";
5
+ /**
6
+ * A single secret to resolve via the two-phase secret bind, returned from a COPY
7
+ * format's `onSecrets` hook. Mirrors a vgi-python `SecretLookupEntry`.
8
+ */
9
+ export interface CopySecretLookup {
10
+ /** DuckDB secret type to resolve (e.g. `"s3"`, `"vgi_example"`). */
11
+ secretType: string;
12
+ /** Optional scope for longest-prefix matching — typically the COPY path. */
13
+ scope?: string;
14
+ /** Optional secret name for name-based lookup. */
15
+ name?: string;
16
+ }
17
+ /** Declaration of a single COPY option (a named function argument). */
18
+ export interface CopyToOption {
19
+ /** Arrow type of the option value (e.g. `utf8()`, `int64()`). */
20
+ type: VgiDataType;
21
+ /** Per-option description, surfaced by `vgi_copy_formats()`. */
22
+ doc?: string;
23
+ /**
24
+ * Default value. When omitted the option is REQUIRED — the worker throws a
25
+ * clear error at COPY bind if the user does not supply it. Mirrors
26
+ * vgi-python's `Arg(..., default=...)` (no default => required).
27
+ */
28
+ default?: unknown;
29
+ /**
30
+ * Optional allowed value set, validated worker-side at bind. Mirrors
31
+ * vgi-python's `Arg(..., choices=[...])`.
32
+ */
33
+ choices?: unknown[];
34
+ /**
35
+ * Optional inclusive lower bound for numeric options, validated worker-side at
36
+ * bind. Mirrors vgi-python's `Arg(..., ge=...)`.
37
+ */
38
+ ge?: number;
39
+ /**
40
+ * Optional inclusive upper bound for numeric options, validated worker-side at
41
+ * bind. Mirrors vgi-python's `Arg(..., le=...)`.
42
+ */
43
+ le?: number;
44
+ }
45
+ /** Parameters for the per-batch `write` hook. */
46
+ export interface CopyToWriteParams<TArgs = Record<string, unknown>> {
47
+ /** One input batch from the COPY source. */
48
+ batch: VgiBatch;
49
+ /** Parsed COPY options (defaults applied). */
50
+ options: TArgs;
51
+ /** Destination path from the `COPY ... TO 'path'` statement. */
52
+ filePath: string;
53
+ /** Full buffering parameters (settings, secrets, storage, executionId). */
54
+ params: TableBufferingParams<TArgs>;
55
+ }
56
+ /** Parameters for the terminal `close` hook. */
57
+ export interface CopyToCloseParams<TArgs = Record<string, unknown>> {
58
+ /** Parsed COPY options (defaults applied). */
59
+ options: TArgs;
60
+ /** Destination path from the `COPY ... TO 'path'` statement. */
61
+ filePath: string;
62
+ /** Full buffering parameters (settings, secrets, storage, executionId). */
63
+ params: TableBufferingParams<TArgs>;
64
+ }
65
+ export interface CopyToFunctionConfig<TArgs = Record<string, unknown>> {
66
+ /** Handler name (the function's registered name; `Meta.name`). */
67
+ name: string;
68
+ /** SQL `FORMAT` identifier users type, e.g. `COPY t TO 'x' (FORMAT myfmt)`. */
69
+ format: string;
70
+ /** Function description (intrinsic documentation; `Meta.description`). */
71
+ description?: string;
72
+ /** Optional free-text comment surfaced by `vgi_copy_formats()`. */
73
+ comment?: string | null;
74
+ /** COPY direction; only `"to"` is supported here. */
75
+ direction?: string;
76
+ /**
77
+ * When true, the writer requires rows in source order — discovery advertises
78
+ * `ordered=true` and the extension uses a single-threaded sink
79
+ * (`REGULAR_COPY_TO_FILE`) so one worker receives every batch in source
80
+ * order. Mirrors vgi-python's `Meta.sink_order_dependent`.
81
+ */
82
+ ordered?: boolean;
83
+ /** COPY options, keyed by option name. The `file_path` is NOT an option. */
84
+ options?: Record<string, CopyToOption>;
85
+ categories?: string[];
86
+ tags?: Record<string, string>;
87
+ examples?: FunctionExample[];
88
+ requiredSettings?: string[];
89
+ requiredSecrets?: string[];
90
+ /**
91
+ * Optional secret-bind hook: forward CREATE SECRET credentials for
92
+ * secret-backed cloud writes (S3/GCS/HTTP/…). Called during bind (only on the
93
+ * first pass); return the secrets to resolve — typically scoped by the
94
+ * destination `filePath`. The framework's two-phase secret bind resolves each
95
+ * lookup from the caller's SecretManager and surfaces the resolved values on
96
+ * `params.secrets` at `write`/`close` time. Mirrors vgi-python's
97
+ * `CopyToFunction.on_secrets`.
98
+ */
99
+ onSecrets?: (params: {
100
+ options: TArgs;
101
+ filePath: string;
102
+ bindCall: BindRequest;
103
+ }) => CopySecretLookup[] | void;
104
+ /** Persist one input `batch` to a shard (called per sink batch). */
105
+ write: (params: CopyToWriteParams<TArgs>) => void | Promise<void>;
106
+ /**
107
+ * Write the destination and close it, once (called on the coordinator). Read
108
+ * the shards persisted by `write` and perform the terminal write. Called even
109
+ * for empty input. Return the row count (informational).
110
+ */
111
+ close: (params: CopyToCloseParams<TArgs>) => number | void | Promise<number | void>;
112
+ }
113
+ /**
114
+ * Define a custom `COPY ... TO` format writer, returned as a
115
+ * `TableBufferingVgiFunction` (kind `"table_buffering"`) carrying the
116
+ * `copyToFormat` metadata marker. Register it in the catalog's function list
117
+ * like any function; the catalog's `copyFromFormats()` introspection picks it
118
+ * up and advertises the format (direction `"to"`). The worker's
119
+ * `table_buffering_process` / `table_buffering_combine` RPCs drive write/close.
120
+ */
121
+ export declare function defineCopyToFunction<TArgs = Record<string, unknown>>(config: CopyToFunctionConfig<TArgs>): TableBufferingVgiFunction;
@@ -0,0 +1,16 @@
1
+ import type { VgiSchema } from "../arrow/index.js";
2
+ import type { VgiFunction } from "./types.js";
3
+ import type { Arguments } from "../arguments/arguments.js";
4
+ export interface OverloadContext {
5
+ arguments?: Arguments;
6
+ inputSchema?: VgiSchema | null;
7
+ isScalar?: boolean;
8
+ }
9
+ export declare class FunctionRegistry {
10
+ private _functions;
11
+ register(func: VgiFunction): void;
12
+ get(name: string, context?: OverloadContext): VgiFunction;
13
+ has(name: string): boolean;
14
+ names(): string[];
15
+ all(): VgiFunction[];
16
+ }
@@ -0,0 +1,98 @@
1
+ import { type VgiSchema, type VgiBatch, type VgiDataType, type ValueFor, type Repr } from "../arrow/index.js";
2
+ import type { AuthContext } from "@query-farm/vgi-rpc";
3
+ import { FunctionStability, NullHandling } from "../types.js";
4
+ import type { BindRequest } from "../protocol/types.js";
5
+ import type { VgiFunction, FunctionExample } from "./types.js";
6
+ export interface ScalarBindParameters {
7
+ /** Constant argument values (resolved at bind time) */
8
+ constArgs: Record<string, any>;
9
+ /** Schema of all arguments including columnar params */
10
+ argumentsSchema: VgiSchema;
11
+ /** Settings from DuckDB */
12
+ settings: Record<string, any>;
13
+ /** Secrets from DuckDB */
14
+ secrets: Record<string, Record<string, any>>;
15
+ /** Original bind request — exposes attach_opaque_data, transaction_opaque_data, function_type, etc. */
16
+ bindCall: BindRequest;
17
+ }
18
+ /** Ordered parameter definition for scalar functions. */
19
+ export interface ScalarParameterDef {
20
+ name: string;
21
+ type: VgiDataType;
22
+ /** If true, this is a constant parameter (scalar value resolved at bind time). */
23
+ const?: boolean;
24
+ /** If true, this parameter accepts variable number of arguments. */
25
+ varargs?: boolean;
26
+ /** Human-readable per-argument description (surfaced as `vgi_doc`). */
27
+ doc?: string;
28
+ }
29
+ /**
30
+ * The typed compute row for a scalar function: one property per declared
31
+ * columnar param, valued in the representation (`rich` / `raw`) selected by the
32
+ * function's `repr`. (Provided as a convenience type for authors who build rows
33
+ * out of the input batch.)
34
+ */
35
+ export type ScalarComputeRow<P extends Record<string, VgiDataType>, M extends Repr> = {
36
+ [K in keyof P]: ValueFor<P[K], M> | null;
37
+ };
38
+ /** A single output value for a scalar function under representation `M`. */
39
+ export type ScalarOutputValue<R extends VgiDataType, M extends Repr> = ValueFor<R, M> | null;
40
+ /**
41
+ * Accepted compute return shapes: an array (or iterable) of output values in
42
+ * the declared representation, or a pre-built VgiBatch. The representation is
43
+ * enforced statically — returning a `Date` under `repr: 'raw'` (which expects a
44
+ * branded `Date32`/`Date64Ms`), or a branded value under `repr: 'rich'` (which
45
+ * expects a `Date`), is a COMPILE error.
46
+ */
47
+ export type ScalarComputeResult<R extends VgiDataType, M extends Repr> = Array<ScalarOutputValue<R, M>> | Iterable<ScalarOutputValue<R, M>> | VgiBatch;
48
+ export interface ScalarFunctionConfig<P extends Record<string, VgiDataType> = Record<string, VgiDataType>, R extends VgiDataType = VgiDataType, M extends Repr = "rich"> {
49
+ name: string;
50
+ description?: string;
51
+ /** Columnar params (receive Arrow arrays at process time) */
52
+ params?: P;
53
+ /** Constant params (receive scalar values resolved at bind time) */
54
+ constParams?: Record<string, VgiDataType>;
55
+ /**
56
+ * Per-argument descriptions keyed by param name, surfaced as `vgi_doc` field
57
+ * metadata (and via the extension's `vgi_function_arguments()`). Applies to
58
+ * `params` and `constParams`; for the ordered `parameters` list use each
59
+ * entry's `doc` field instead.
60
+ */
61
+ argDocs?: Record<string, string>;
62
+ /**
63
+ * Ordered parameter list. When provided, overrides `params` and `constParams`.
64
+ * Use this when parameters need non-default ordering (e.g. const, param, const).
65
+ */
66
+ parameters?: ScalarParameterDef[];
67
+ /** Output type (static) */
68
+ returns?: R;
69
+ /** Dynamic output type at bind time */
70
+ outputType?: (params: ScalarBindParameters) => VgiDataType | Promise<VgiDataType>;
71
+ /**
72
+ * Value representation for compute I/O. `'rich'` (default) uses JS `Date` for
73
+ * date32/date64 and plain number/bigint elsewhere. `'raw'` uses the branded
74
+ * unit-carrying aliases (Date32, TimestampMicros, UnscaledDecimal, …). The
75
+ * choice flows into compute()'s statically-checked return type and selects
76
+ * the runtime converter used to build the output column.
77
+ */
78
+ repr?: M;
79
+ /**
80
+ * Process: receives the columnar input batch + const values, returns the
81
+ * output column as an array/iterable of values (statically typed from
82
+ * `returns` and `repr`) or a pre-built VgiBatch.
83
+ */
84
+ compute: (batch: VgiBatch, consts: Record<string, any>, info: {
85
+ settings: Record<string, any>;
86
+ secrets: Record<string, Record<string, any>>;
87
+ auth: AuthContext;
88
+ }) => ScalarComputeResult<NoInfer<R>, NoInfer<M>>;
89
+ stability?: FunctionStability;
90
+ nullHandling?: NullHandling;
91
+ examples?: FunctionExample[];
92
+ categories?: string[];
93
+ tags?: Record<string, string>;
94
+ maxWorkers?: number;
95
+ requiredSettings?: string[];
96
+ requiredSecrets?: string[];
97
+ }
98
+ export declare function defineScalarFunction<P extends Record<string, VgiDataType> = Record<string, VgiDataType>, R extends VgiDataType = VgiDataType, M extends Repr = "rich">(config: ScalarFunctionConfig<P, R, M>): VgiFunction;
@@ -0,0 +1,47 @@
1
+ import type { FunctionStorage } from "./storage.js";
2
+ /** Minimal fetch signature satisfied by both the global `fetch` and a
3
+ * Cloudflare service-binding Fetcher (`env.<BINDING>`). */
4
+ export type FetchLike = (input: string, init?: {
5
+ method?: string;
6
+ headers?: Record<string, string>;
7
+ body?: string;
8
+ }) => Promise<Response>;
9
+ export declare class FunctionStorageCfDo implements FunctionStorage {
10
+ private readonly _baseUrl;
11
+ private readonly _token;
12
+ /** Per-attach routing key (att-<hex uuid>); "" until pinned via forShard. */
13
+ private readonly _shardKey;
14
+ /** Fetch implementation. Defaults to the global `fetch`; pass a Cloudflare
15
+ * service-binding Fetcher (env.<BINDING>) when the storage worker lives on
16
+ * the same account/zone — a same-zone public-URL fetch is rejected (CF
17
+ * error 1042), but a service binding routes worker-to-worker directly. */
18
+ private readonly _fetch;
19
+ constructor(opts: {
20
+ url: string;
21
+ token?: string | null;
22
+ shardKey?: string;
23
+ fetch?: FetchLike;
24
+ });
25
+ /** Build an instance from environment variables. */
26
+ static fromEnv(): FunctionStorageCfDo;
27
+ /**
28
+ * Return a view of this backend pinned to one shard key, so callers can route
29
+ * per logical ATTACH. Shares the URL/token; only the shard key differs.
30
+ */
31
+ forShard(shardKey: string): FunctionStorageCfDo;
32
+ workerPut(executionId: Uint8Array, workerId: number, state: Uint8Array): Promise<void>;
33
+ workerCollect(executionId: Uint8Array): Promise<Uint8Array[]>;
34
+ workerScan(executionId: Uint8Array): Promise<Array<[number, Uint8Array]>>;
35
+ queuePush(executionId: Uint8Array, items: Uint8Array[]): Promise<number>;
36
+ queuePop(executionId: Uint8Array): Promise<Uint8Array | null>;
37
+ queueClear(executionId: Uint8Array): Promise<number>;
38
+ stateGet(scopeId: Uint8Array, ns: Uint8Array, key: Uint8Array): Promise<Uint8Array | null>;
39
+ statePut(scopeId: Uint8Array, ns: Uint8Array, key: Uint8Array, value: Uint8Array): Promise<void>;
40
+ stateAppend(scopeId: Uint8Array, ns: Uint8Array, key: Uint8Array, item: Uint8Array): Promise<number>;
41
+ stateLogScan(scopeId: Uint8Array, ns: Uint8Array, key: Uint8Array, afterId?: number, limit?: number | null): Promise<Array<[number, Uint8Array]>>;
42
+ executionClear(scopeId: Uint8Array): Promise<number>;
43
+ private _statePutMany;
44
+ /** Drive state_scan / state_drain across pages. attemptId is null for scan. */
45
+ private _statePaged;
46
+ private _post;
47
+ }
@@ -0,0 +1,86 @@
1
+ export declare class UnknownInvocationError extends Error {
2
+ constructor(message?: string | Uint8Array);
3
+ }
4
+ export interface FunctionStorage {
5
+ workerPut(executionId: Uint8Array, workerId: number, state: Uint8Array): Promise<void>;
6
+ workerCollect(executionId: Uint8Array): Promise<Uint8Array[]>;
7
+ workerScan(executionId: Uint8Array): Promise<Array<[number, Uint8Array]>>;
8
+ queuePush(executionId: Uint8Array, items: Uint8Array[]): Promise<number>;
9
+ queuePop(executionId: Uint8Array): Promise<Uint8Array | null>;
10
+ queueClear(executionId: Uint8Array): Promise<number>;
11
+ stateGet(scopeId: Uint8Array, ns: Uint8Array, key: Uint8Array): Promise<Uint8Array | null>;
12
+ statePut(scopeId: Uint8Array, ns: Uint8Array, key: Uint8Array, value: Uint8Array): Promise<void>;
13
+ stateAppend(scopeId: Uint8Array, ns: Uint8Array, key: Uint8Array, item: Uint8Array): Promise<number>;
14
+ stateLogScan(scopeId: Uint8Array, ns: Uint8Array, key: Uint8Array, afterId?: number, limit?: number | null): Promise<Array<[number, Uint8Array]>>;
15
+ /** Wipe all state + log rows for a scope across every namespace. */
16
+ executionClear(scopeId: Uint8Array): Promise<number>;
17
+ /** Optional cleanup hook. Implementations holding a connection should release it here. */
18
+ close?(): Promise<void> | void;
19
+ }
20
+ export declare const FrameworkNS: {
21
+ readonly BUFFERING_INIT: Uint8Array<ArrayBufferLike>;
22
+ readonly STREAMING_FINALIZE: Uint8Array<ArrayBufferLike>;
23
+ };
24
+ /** Encode an int as 8-byte little-endian, matching Python's pack_int_key. */
25
+ export declare function packIntKey(i: number | bigint): Uint8Array;
26
+ export declare class FunctionStorageSqlite implements FunctionStorage {
27
+ readonly dbPath: string;
28
+ private _db;
29
+ constructor(dbPath?: string);
30
+ close(): void;
31
+ private _ensureTables;
32
+ stateGet(scopeId: Uint8Array, ns: Uint8Array, key: Uint8Array): Promise<Uint8Array | null>;
33
+ statePut(scopeId: Uint8Array, ns: Uint8Array, key: Uint8Array, value: Uint8Array): Promise<void>;
34
+ stateAppend(scopeId: Uint8Array, ns: Uint8Array, key: Uint8Array, item: Uint8Array): Promise<number>;
35
+ stateLogScan(scopeId: Uint8Array, ns: Uint8Array, key: Uint8Array, afterId?: number, limit?: number | null): Promise<Array<[number, Uint8Array]>>;
36
+ executionClear(scopeId: Uint8Array): Promise<number>;
37
+ workerPut(executionId: Uint8Array, workerId: number, state: Uint8Array): Promise<void>;
38
+ workerCollect(executionId: Uint8Array): Promise<Uint8Array[]>;
39
+ workerScan(executionId: Uint8Array): Promise<Array<[number, Uint8Array]>>;
40
+ queuePush(executionId: Uint8Array, items: Uint8Array[]): Promise<number>;
41
+ queuePop(executionId: Uint8Array): Promise<Uint8Array | null>;
42
+ queueClear(executionId: Uint8Array): Promise<number>;
43
+ }
44
+ export declare class BoundStorage {
45
+ private _base;
46
+ private _executionId;
47
+ constructor(storage: FunctionStorage, executionId: Uint8Array);
48
+ put(state: Uint8Array): Promise<void>;
49
+ collect(): Promise<Uint8Array[]>;
50
+ workerScan(): Promise<Array<[number, Uint8Array]>>;
51
+ queuePush(items: Uint8Array[]): Promise<number>;
52
+ queuePop(): Promise<Uint8Array | null>;
53
+ queueClear(): Promise<number>;
54
+ stateGet(ns: Uint8Array, key: Uint8Array): Promise<Uint8Array | null>;
55
+ statePut(ns: Uint8Array, key: Uint8Array, value: Uint8Array): Promise<void>;
56
+ stateAppend(ns: Uint8Array, key: Uint8Array, item: Uint8Array): Promise<number>;
57
+ stateLogScan(ns: Uint8Array, key: Uint8Array, afterId?: number, limit?: number | null): Promise<Array<[number, Uint8Array]>>;
58
+ executionClear(): Promise<number>;
59
+ static packIntKey(i: number | bigint): Uint8Array;
60
+ }
61
+ /**
62
+ * Resolve the FunctionStorage backend from environment variables.
63
+ *
64
+ * Mirrors vgi-python's `_resolve_storage` in `vgi/function.py`.
65
+ *
66
+ * `VGI_WORKER_SHARED_STORAGE` selects the backend (default: `sqlite`):
67
+ * - `memory` — `FunctionStorageSqlite` at `:memory:`. Process-local
68
+ * with no cross-process coordination — single-process
69
+ * deployments only. Ignores `VGI_WORKER_SQLITE_PATH`.
70
+ * - `sqlite` — `FunctionStorageSqlite`. Honors `VGI_WORKER_SQLITE_PATH`
71
+ * (including `:memory:`).
72
+ * - `cloudflare-do` — `FunctionStorageCfDo`. Requires `VGI_CF_DO_URL`;
73
+ * optional `VGI_CF_DO_TOKEN` for bearer auth.
74
+ */
75
+ export declare function resolveStorageFromEnv(): FunctionStorage;
76
+ /**
77
+ * Override the default backend used by the `storage` singleton. Call once at
78
+ * worker startup to inject a pre-built backend that env-driven selection can't
79
+ * construct — notably a `FunctionStorageCfDo` wired to a Cloudflare
80
+ * service-binding Fetcher (the binding lives on `env`, not `process.env`, and a
81
+ * same-zone public-URL fetch is rejected with CF error 1042). Takes precedence
82
+ * over `VGI_WORKER_SHARED_STORAGE`.
83
+ */
84
+ export declare function setStorage(impl: FunctionStorage): void;
85
+ /** Default FunctionStorage instance. Backend is selected via env on first access. */
86
+ export declare const storage: FunctionStorage;
@@ -0,0 +1,99 @@
1
+ import { type VgiSchema, type VgiDataType, type VgiBatch } from "../arrow/index.js";
2
+ import type { OutputCollector } from "@query-farm/vgi-rpc";
3
+ import type { BindRequest, InitRequest, GlobalInitResponse } from "../protocol/types.js";
4
+ import type { TableCardinality } from "../types.js";
5
+ import type { VgiFunction, FunctionExample } from "./types.js";
6
+ import { FunctionStability } from "../types.js";
7
+ import { BoundStorage } from "./storage.js";
8
+ export interface TableBufferingBindParams<TArgs = Record<string, any>> {
9
+ args: TArgs;
10
+ bindCall: BindRequest;
11
+ settings: Record<string, any>;
12
+ secrets: Record<string, Record<string, any>>;
13
+ /** True on the second bind pass, after the connector resolved the secrets
14
+ * requested via the onBind `lookupSecret*` return fields on the first pass. */
15
+ resolvedSecretsProvided: boolean;
16
+ }
17
+ export interface TableBufferingParams<TArgs = Record<string, any>> {
18
+ args: TArgs;
19
+ initCall: InitRequest;
20
+ outputSchema: VgiSchema;
21
+ settings: Record<string, any>;
22
+ secrets: Record<string, Record<string, any>>;
23
+ /** Shared cross-process storage scoped by execution_id. */
24
+ storage: BoundStorage;
25
+ /** Stable across coordinator + secondary workers for one DuckDB execution. */
26
+ executionId: Uint8Array;
27
+ /** Catalog attach identity (plaintext bytes). */
28
+ attachId: Uint8Array;
29
+ /** Hex/raw VGI transaction id, or null. */
30
+ transactionId: Uint8Array | null;
31
+ function_name: string;
32
+ /** Per-chunk batch_index when requiresInputBatchIndex=true; else null. */
33
+ batchIndex: number | null;
34
+ /** In-band log sink for the unary process()/combine() RPCs. */
35
+ clientLog: (level: string, message: string) => void;
36
+ }
37
+ export interface TableBufferingConfig<TArgs = Record<string, any>, TState = any> {
38
+ name: string;
39
+ description?: string;
40
+ args?: Record<string, VgiDataType>;
41
+ namedArgs?: Record<string, VgiDataType>;
42
+ argDefaults?: Record<string, any>;
43
+ /** Bind: default passes through input schema. May be async. Return non-empty
44
+ * `lookupSecret*` lists on the first pass to request DuckDB secrets; the
45
+ * connector then re-binds with `resolvedSecretsProvided` and the resolved
46
+ * values are available in the process/finalize params' `secrets`. */
47
+ onBind?: (params: TableBufferingBindParams<TArgs>) => {
48
+ outputSchema: VgiSchema;
49
+ opaqueData?: Uint8Array;
50
+ lookupSecretTypes?: string[];
51
+ lookupScopes?: string[];
52
+ lookupNames?: string[];
53
+ } | Promise<{
54
+ outputSchema: VgiSchema;
55
+ opaqueData?: Uint8Array;
56
+ lookupSecretTypes?: string[];
57
+ lookupScopes?: string[];
58
+ lookupNames?: string[];
59
+ }>;
60
+ /** Sink: ingest one batch, return an opaque state_id. */
61
+ process: (batch: VgiBatch, params: TableBufferingParams<TArgs>) => Uint8Array | Promise<Uint8Array>;
62
+ /** Combine: group/merge state_ids, return finalize_state_ids. */
63
+ combine: (stateIds: Uint8Array[], params: TableBufferingParams<TArgs>) => Uint8Array[] | Promise<Uint8Array[]>;
64
+ /** Build the initial per-tick finalize state for a finalize_state_id. */
65
+ initialFinalizeState?: (finalizeStateId: Uint8Array, params: TableBufferingParams<TArgs>) => TState | Promise<TState>;
66
+ /** Source tick: emit one batch via out.emit / signal EOS via out.finish. */
67
+ finalize: (params: TableBufferingParams<TArgs>, finalizeStateId: Uint8Array, state: TState, out: OutputCollector) => void | Promise<void>;
68
+ cardinality?: (params: TableBufferingBindParams<TArgs>) => TableCardinality | Promise<TableCardinality>;
69
+ projectionPushdown?: boolean;
70
+ filterPushdown?: boolean;
71
+ autoApplyFilters?: boolean;
72
+ /** Force ParallelSink=false in the C++ operator (single-thread ingest). */
73
+ sinkOrderDependent?: boolean;
74
+ /** Force serial Source drain in finalize_queue order. */
75
+ sourceOrderDependent?: boolean;
76
+ /** Thread DuckDB's per-chunk batch_index into every process() call. */
77
+ requiresInputBatchIndex?: boolean;
78
+ stability?: FunctionStability;
79
+ examples?: FunctionExample[];
80
+ categories?: string[];
81
+ tags?: Record<string, string>;
82
+ maxWorkers?: number;
83
+ requiredSettings?: string[];
84
+ requiredSecrets?: string[];
85
+ }
86
+ /**
87
+ * A table_buffering VgiFunction also carries its callback config so the
88
+ * protocol's unary handlers (process/combine/destructor) can reach it.
89
+ */
90
+ export interface TableBufferingVgiFunction extends VgiFunction {
91
+ bufferingConfig: TableBufferingConfig<any, any>;
92
+ bufferingExtractArgs: (request: BindRequest) => any;
93
+ }
94
+ export declare function defineTableBufferingFunction<TArgs = Record<string, any>, TState = any>(config: TableBufferingConfig<TArgs, TState>): TableBufferingVgiFunction;
95
+ export declare function encodeBufferingInit(request: InitRequest, response: GlobalInitResponse): Uint8Array;
96
+ export declare function decodeBufferingInit(payload: Uint8Array): {
97
+ request: InitRequest;
98
+ response: GlobalInitResponse;
99
+ };
@@ -0,0 +1,64 @@
1
+ import { type VgiSchema, type VgiDataType, type VgiBatch } from "../arrow/index.js";
2
+ import type { OutputCollector } from "@query-farm/vgi-rpc";
3
+ import type { BindRequest, InitRequest, GlobalInitResponse } from "../protocol/types.js";
4
+ import type { VgiFunction, FunctionExample } from "./types.js";
5
+ import { type PushdownFilters } from "../filter-pushdown/index.js";
6
+ import { FunctionStability } from "../types.js";
7
+ import { BoundStorage } from "./storage.js";
8
+ export interface TableInOutBindParams<TArgs = Record<string, any>> {
9
+ args: TArgs;
10
+ bindCall: BindRequest;
11
+ settings: Record<string, any>;
12
+ secrets: Record<string, Record<string, any>>;
13
+ }
14
+ export interface TableInOutProcessParams<TArgs = Record<string, any>> {
15
+ args: TArgs;
16
+ initCall: InitRequest;
17
+ initResponse: GlobalInitResponse;
18
+ outputSchema: VgiSchema;
19
+ settings: Record<string, any>;
20
+ secrets: Record<string, Record<string, any>>;
21
+ pushdownFilters?: PushdownFilters;
22
+ /** Shared storage for cross-phase and cross-worker data (SQLite-backed). */
23
+ storage: BoundStorage;
24
+ }
25
+ export interface TableInOutConfig<TArgs = Record<string, any>, TState = null> {
26
+ name: string;
27
+ description?: string;
28
+ args?: Record<string, VgiDataType>;
29
+ /** Named arguments (optional, DuckDB passes by name) */
30
+ namedArgs?: Record<string, VgiDataType>;
31
+ /** Argument defaults */
32
+ argDefaults?: Record<string, any>;
33
+ /** Bind: default passes through input schema. May be async. */
34
+ onBind?: (params: TableInOutBindParams<TArgs>) => {
35
+ outputSchema: VgiSchema;
36
+ opaqueData?: Uint8Array;
37
+ } | Promise<{
38
+ outputSchema: VgiSchema;
39
+ opaqueData?: Uint8Array;
40
+ }>;
41
+ onInit?: (params: {
42
+ args: TArgs;
43
+ initCall: InitRequest;
44
+ outputSchema: VgiSchema;
45
+ executionId: Uint8Array;
46
+ }) => GlobalInitResponse | Promise<GlobalInitResponse>;
47
+ initialState?: (params: TableInOutProcessParams<TArgs>) => TState;
48
+ /** Process: transform input batch, emit output via out */
49
+ process?: (params: TableInOutProcessParams<TArgs>, state: TState, batch: VgiBatch, out: OutputCollector) => void | Promise<void>;
50
+ /** Finalize: emit final batches after all input processed.
51
+ * Receives all worker states collected from storage (matches Python's finish(params, states)). */
52
+ finalize?: (params: TableInOutProcessParams<TArgs>, states: TState[]) => VgiBatch[] | Promise<VgiBatch[]>;
53
+ projectionPushdown?: boolean;
54
+ filterPushdown?: boolean;
55
+ autoApplyFilters?: boolean;
56
+ stability?: FunctionStability;
57
+ examples?: FunctionExample[];
58
+ categories?: string[];
59
+ tags?: Record<string, string>;
60
+ maxWorkers?: number;
61
+ requiredSettings?: string[];
62
+ requiredSecrets?: string[];
63
+ }
64
+ export declare function defineTableInOutFunction<TArgs = Record<string, any>, TState = null>(config: TableInOutConfig<TArgs, TState>): VgiFunction;
@@ -0,0 +1,118 @@
1
+ import { type VgiSchema, type VgiDataType } from "../arrow/index.js";
2
+ import type { OutputCollector } from "@query-farm/vgi-rpc";
3
+ import type { BindRequest, InitRequest, GlobalInitResponse, TableCardinality } from "../protocol/types.js";
4
+ import type { VgiFunction, FunctionExample } from "./types.js";
5
+ import { type PushdownFilters } from "../filter-pushdown/index.js";
6
+ import type { ColumnStatistics } from "../util/statistics.js";
7
+ import { FunctionStability, type NullHandling, type OrderPreservation, type OrderDependence, type DistinctDependence } from "../types.js";
8
+ import { BoundStorage } from "./storage.js";
9
+ export interface TableBindParams<TArgs = Record<string, any>> {
10
+ args: TArgs;
11
+ bindCall: BindRequest;
12
+ settings: Record<string, any>;
13
+ secrets: Record<string, Record<string, any>>;
14
+ resolvedSecretsProvided: boolean;
15
+ }
16
+ export interface TableProcessParams<TArgs = Record<string, any>> {
17
+ args: TArgs;
18
+ initCall: InitRequest;
19
+ initResponse: GlobalInitResponse;
20
+ outputSchema: VgiSchema;
21
+ settings: Record<string, any>;
22
+ secrets: Record<string, Record<string, any>>;
23
+ pushdownFilters?: PushdownFilters;
24
+ storage?: BoundStorage;
25
+ /**
26
+ * AT (TIMESTAMP|VERSION) clause for this scan, or `undefined` when the scan
27
+ * has no AT clause. Carried on the per-scan bind embedded in the init request
28
+ * (`initCall.bind_call.at_unit` / `.at_value`), so function-backed tables can
29
+ * read time travel at init alongside their pushdown filters. Mirrors
30
+ * vgi-python's `ProcessParams.at_unit` / `.at_value`. See `BindRequest.at_unit`.
31
+ */
32
+ atUnit?: string;
33
+ atValue?: string;
34
+ }
35
+ export interface TableFunctionConfig<TArgs = Record<string, any>, TState = null> {
36
+ name: string;
37
+ description?: string;
38
+ /** Argument schema (positional args) */
39
+ args?: Record<string, VgiDataType>;
40
+ /** Argument docs */
41
+ argDocs?: Record<string, string>;
42
+ /** Argument defaults */
43
+ argDefaults?: Record<string, any>;
44
+ /** Names of args that accept variable number of arguments */
45
+ varargs?: string[];
46
+ /** Bind: return output schema. May be async — handlers `await` the result. */
47
+ onBind: (params: TableBindParams<TArgs>) => {
48
+ outputSchema: VgiSchema;
49
+ opaqueData?: Uint8Array;
50
+ lookupSecretTypes?: string[];
51
+ lookupScopes?: string[];
52
+ lookupNames?: string[];
53
+ } | Promise<{
54
+ outputSchema: VgiSchema;
55
+ opaqueData?: Uint8Array;
56
+ lookupSecretTypes?: string[];
57
+ lookupScopes?: string[];
58
+ lookupNames?: string[];
59
+ }>;
60
+ /** Init (optional). May be async — common when storage is HTTP-backed. */
61
+ onInit?: (params: {
62
+ args: TArgs;
63
+ initCall: InitRequest;
64
+ outputSchema: VgiSchema;
65
+ executionId: Uint8Array;
66
+ storage: BoundStorage;
67
+ }) => GlobalInitResponse | Promise<GlobalInitResponse>;
68
+ /** State factory */
69
+ initialState?: (params: TableProcessParams<TArgs>) => TState;
70
+ /** Process: emit batches via out, call out.finish() when done */
71
+ process: (params: TableProcessParams<TArgs>, state: TState, out: OutputCollector) => void | Promise<void>;
72
+ /** Cardinality hints */
73
+ cardinality?: (params: TableBindParams<TArgs>) => TableCardinality | Promise<TableCardinality>;
74
+ /**
75
+ * Per-column statistics for the function's output. Returned to DuckDB via
76
+ * the `table_function_statistics` RPC; the optimizer uses min/max to
77
+ * eliminate impossible filters at plan time (folding scans to
78
+ * EMPTY_RESULT). Return `null` or an empty array when bounds are unknown.
79
+ */
80
+ statistics?: (params: TableBindParams<TArgs>) => ColumnStatistics[] | null;
81
+ /**
82
+ * Per-execution diagnostics surfaced under EXPLAIN ANALYZE. DuckDB calls
83
+ * this once per parallel scan thread at pipeline FinishSource via the
84
+ * `table_function_dynamic_to_string` RPC. Return ordered key→value
85
+ * strings; the C++ extension merges these with the intrinsic keys
86
+ * (Function, Rows Read, Threads). The framework provides a BoundStorage
87
+ * keyed by the global execution_id so process() can persist counters
88
+ * that this callback then reads back — see profiling_demo for the
89
+ * canonical pattern.
90
+ */
91
+ dynamicToString?: (params: TableBindParams<TArgs>, executionId: Uint8Array, storage: BoundStorage) => Record<string, string> | Promise<Record<string, string>>;
92
+ projectionPushdown?: boolean;
93
+ filterPushdown?: boolean;
94
+ samplingPushdown?: boolean;
95
+ /** Opt in to DuckDB's late-materialization SEMI-join rewrite; requires a
96
+ * UNIQUE, snapshot-stable rowid column. FunctionInfo.late_materialization. */
97
+ lateMaterialization?: boolean;
98
+ supportedExpressionFilters?: string[];
99
+ autoApplyFilters?: boolean;
100
+ stability?: FunctionStability;
101
+ examples?: FunctionExample[];
102
+ categories?: string[];
103
+ tags?: Record<string, string>;
104
+ maxWorkers?: number;
105
+ requiredSettings?: string[];
106
+ requiredSecrets?: string[];
107
+ /** Row-order preservation behavior; flows to DuckDB's
108
+ * TableFunction::order_preservation_type. */
109
+ preservesOrder?: OrderPreservation;
110
+ nullHandling?: NullHandling;
111
+ orderDependent?: OrderDependence;
112
+ distinctDependent?: DistinctDependence;
113
+ /** Emit per-batch `vgi_batch_index`; FunctionInfo.supports_batch_index. */
114
+ supportsBatchIndex?: boolean;
115
+ /** Hive-style partition-columns mode; FunctionInfo.partition_kind. */
116
+ partitionKind?: "NOT_PARTITIONED" | "SINGLE_VALUE_PARTITIONS" | "OVERLAPPING_PARTITIONS" | "DISJOINT_PARTITIONS";
117
+ }
118
+ export declare function defineTableFunction<TArgs = Record<string, any>, TState = null>(config: TableFunctionConfig<TArgs, TState>): VgiFunction;