@query-farm/vgi 0.21.0 → 0.22.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/dist/cache-control.d.ts +26 -0
- package/dist/catalog/composite.d.ts +2 -0
- package/dist/catalog/interface.d.ts +11 -0
- package/dist/client-entry.js +5 -3
- package/dist/client-entry.js.map +5 -5
- package/dist/functions/registry.d.ts +31 -0
- package/dist/functions/scalar.d.ts +7 -3
- package/dist/generated/vgi-client.d.ts +16 -0
- package/dist/index.core.d.ts +1 -1
- package/dist/index.js +120 -16
- package/dist/index.js.map +15 -15
- package/dist/protocol/handlers/function.d.ts +8 -0
- package/dist/protocol/handlers/shared.d.ts +4 -0
- package/dist/protocol/types.d.ts +8 -0
- package/dist/serve-entry.js +35 -13
- package/dist/serve-entry.js.map +8 -8
- package/dist/worker-cf-entry.js +115 -14
- package/dist/worker-cf-entry.js.map +13 -13
- package/dist/worker.d.ts +9 -0
- package/package.json +3 -3
- package/src/cache-control.ts +27 -0
- package/src/catalog/composite.ts +9 -0
- package/src/catalog/interface.ts +15 -0
- package/src/catalog/read-only.ts +13 -0
- package/src/functions/registry.ts +106 -1
- package/src/functions/scalar.ts +10 -5
- package/src/generated/vgi-client.ts +17 -1
- package/src/index.core.ts +1 -0
- package/src/protocol/dispatch.ts +1 -0
- package/src/protocol/handlers/function.ts +29 -8
- package/src/protocol/handlers/shared.ts +25 -1
- package/src/protocol/serializers/bind.ts +7 -0
- package/src/protocol/types.ts +8 -0
- package/src/worker.ts +15 -1
|
@@ -5,11 +5,42 @@ export interface OverloadContext {
|
|
|
5
5
|
arguments?: Arguments;
|
|
6
6
|
inputSchema?: VgiSchema | null;
|
|
7
7
|
isScalar?: boolean;
|
|
8
|
+
/**
|
|
9
|
+
* Catalog schema that declares the function, from `BindRequest.schema_name`.
|
|
10
|
+
* A worker may register the same name in more than one schema, so the bare
|
|
11
|
+
* name is not a unique key. When set, resolution is scoped to that schema and
|
|
12
|
+
* never falls back to another one; when absent, every schema is searched.
|
|
13
|
+
*/
|
|
14
|
+
schemaName?: string | null;
|
|
15
|
+
/**
|
|
16
|
+
* Catalog that owns the function, resolved from the bind's
|
|
17
|
+
* `attach_opaque_data`. Two catalogs served by one worker may each declare
|
|
18
|
+
* the same schema *and* function name, in which case only the catalog tells
|
|
19
|
+
* them apart. Absent for calls with no attachment.
|
|
20
|
+
*/
|
|
21
|
+
catalogName?: string | null;
|
|
8
22
|
}
|
|
9
23
|
export declare class FunctionRegistry {
|
|
10
24
|
private _functions;
|
|
25
|
+
private _bySchema;
|
|
26
|
+
private _byCatalog;
|
|
11
27
|
register(func: VgiFunction): void;
|
|
28
|
+
/**
|
|
29
|
+
* Record that `func` is declared in `schemaName`, in addition to the flat
|
|
30
|
+
* by-name index. Idempotent, and independent of `register()` so a function
|
|
31
|
+
* reachable from several schemas (e.g. a scan function referenced by tables in
|
|
32
|
+
* more than one schema) resolves from any of them.
|
|
33
|
+
*/
|
|
34
|
+
registerInSchema(func: VgiFunction, schemaName: string, catalogName?: string): void;
|
|
35
|
+
/** Schemas that declare `functionName`, sorted — for error messages. */
|
|
36
|
+
schemasFor(functionName: string): string[];
|
|
12
37
|
get(name: string, context?: OverloadContext): VgiFunction;
|
|
38
|
+
/**
|
|
39
|
+
* Pick one function from an already-scoped candidate list, by argument shape
|
|
40
|
+
* and types. Scoping (catalog / schema) happens in `get()`; by the time this
|
|
41
|
+
* runs, every candidate is a legitimate overload of the same name.
|
|
42
|
+
*/
|
|
43
|
+
private _disambiguate;
|
|
13
44
|
has(name: string): boolean;
|
|
14
45
|
names(): string[];
|
|
15
46
|
all(): VgiFunction[];
|
|
@@ -112,10 +112,14 @@ export interface ScalarFunctionConfig<P extends Record<string, VgiDataType> = Re
|
|
|
112
112
|
/**
|
|
113
113
|
* Result-cache opt-in: when set, this CacheControl's `vgi.cache.*` metadata
|
|
114
114
|
* rides every output batch's custom metadata (per-batch — NOT the schema,
|
|
115
|
-
* which the IPC stream fixes at open)
|
|
116
|
-
*
|
|
117
|
-
* only — advertising this on a non-pure scalar serves stale rows. Mirrors
|
|
115
|
+
* which the IPC stream fixes at open). A pure, deterministic scalar only —
|
|
116
|
+
* advertising this on a non-pure scalar serves stale rows. Mirrors
|
|
118
117
|
* vgi-python's `ScalarFunction.CACHE_CONTROL`.
|
|
118
|
+
*
|
|
119
|
+
* Per-VALUE memoization (the extension remembering one output per distinct
|
|
120
|
+
* input value) additionally requires `perValue: true`, which is off by
|
|
121
|
+
* default because a memo serve only beats a worker call when the call is
|
|
122
|
+
* expensive — see {@link CacheControl.perValue}.
|
|
119
123
|
*/
|
|
120
124
|
cacheControl?: CacheControl;
|
|
121
125
|
}
|
|
@@ -141,6 +141,7 @@ export interface AggregateBindRequest {
|
|
|
141
141
|
settings?: /** @record-batch */ Uint8Array | null;
|
|
142
142
|
secrets?: /** @record-batch */ Uint8Array | null;
|
|
143
143
|
attach_opaque_data?: Uint8Array | null;
|
|
144
|
+
schema_name?: string | null;
|
|
144
145
|
}
|
|
145
146
|
export interface AggregateBindResponse {
|
|
146
147
|
output_schema: Uint8Array;
|
|
@@ -151,6 +152,7 @@ export interface AggregateCombineRequest {
|
|
|
151
152
|
execution_id: Uint8Array;
|
|
152
153
|
merge_batch: Uint8Array;
|
|
153
154
|
attach_opaque_data?: Uint8Array | null;
|
|
155
|
+
schema_name?: string | null;
|
|
154
156
|
}
|
|
155
157
|
export interface AggregateCombineResponse {
|
|
156
158
|
}
|
|
@@ -159,6 +161,7 @@ export interface AggregateDestructorRequest {
|
|
|
159
161
|
execution_id: Uint8Array;
|
|
160
162
|
group_ids_batch: Uint8Array;
|
|
161
163
|
attach_opaque_data?: Uint8Array | null;
|
|
164
|
+
schema_name?: string | null;
|
|
162
165
|
}
|
|
163
166
|
export interface AggregateDestructorResponse {
|
|
164
167
|
}
|
|
@@ -168,6 +171,7 @@ export interface AggregateFinalizeRequest {
|
|
|
168
171
|
group_ids_batch: Uint8Array;
|
|
169
172
|
output_schema: Uint8Array;
|
|
170
173
|
attach_opaque_data?: Uint8Array | null;
|
|
174
|
+
schema_name?: string | null;
|
|
171
175
|
}
|
|
172
176
|
export interface AggregateFinalizeResponse {
|
|
173
177
|
result_batch: Uint8Array;
|
|
@@ -177,6 +181,7 @@ export interface AggregateStreamingChunkRequest {
|
|
|
177
181
|
execution_id: Uint8Array;
|
|
178
182
|
input_batch: Uint8Array;
|
|
179
183
|
attach_opaque_data?: Uint8Array | null;
|
|
184
|
+
schema_name?: string | null;
|
|
180
185
|
}
|
|
181
186
|
export interface AggregateStreamingChunkResponse {
|
|
182
187
|
result_batch: Uint8Array;
|
|
@@ -185,6 +190,7 @@ export interface AggregateStreamingCloseRequest {
|
|
|
185
190
|
function_name: string;
|
|
186
191
|
execution_id: Uint8Array;
|
|
187
192
|
attach_opaque_data?: Uint8Array | null;
|
|
193
|
+
schema_name?: string | null;
|
|
188
194
|
}
|
|
189
195
|
export interface AggregateStreamingCloseResponse {
|
|
190
196
|
}
|
|
@@ -198,6 +204,7 @@ export interface AggregateStreamingOpenRequest {
|
|
|
198
204
|
settings?: /** @record-batch */ Uint8Array | null;
|
|
199
205
|
secrets?: /** @record-batch */ Uint8Array | null;
|
|
200
206
|
attach_opaque_data?: Uint8Array | null;
|
|
207
|
+
schema_name?: string | null;
|
|
201
208
|
}
|
|
202
209
|
export interface AggregateStreamingOpenResponse {
|
|
203
210
|
execution_id: Uint8Array;
|
|
@@ -207,6 +214,7 @@ export interface AggregateUpdateRequest {
|
|
|
207
214
|
execution_id: Uint8Array;
|
|
208
215
|
input_batch: Uint8Array;
|
|
209
216
|
attach_opaque_data?: Uint8Array | null;
|
|
217
|
+
schema_name?: string | null;
|
|
210
218
|
}
|
|
211
219
|
export interface AggregateUpdateResponse {
|
|
212
220
|
}
|
|
@@ -218,6 +226,7 @@ export interface AggregateWindowRequest {
|
|
|
218
226
|
frame_starts: number[];
|
|
219
227
|
frame_ends: number[];
|
|
220
228
|
attach_opaque_data?: Uint8Array | null;
|
|
229
|
+
schema_name?: string | null;
|
|
221
230
|
}
|
|
222
231
|
export interface AggregateWindowResponse {
|
|
223
232
|
result_batch: Uint8Array;
|
|
@@ -232,6 +241,7 @@ export interface AggregateWindowBatchRequest {
|
|
|
232
241
|
frame_starts: number[];
|
|
233
242
|
frame_ends: number[];
|
|
234
243
|
attach_opaque_data?: Uint8Array | null;
|
|
244
|
+
schema_name?: string | null;
|
|
235
245
|
}
|
|
236
246
|
export interface AggregateWindowBatchResponse {
|
|
237
247
|
result_batch: Uint8Array;
|
|
@@ -241,6 +251,7 @@ export interface AggregateWindowDestructorRequest {
|
|
|
241
251
|
execution_id: Uint8Array;
|
|
242
252
|
partition_id: number;
|
|
243
253
|
attach_opaque_data?: Uint8Array | null;
|
|
254
|
+
schema_name?: string | null;
|
|
244
255
|
}
|
|
245
256
|
export interface AggregateWindowDestructorResponse {
|
|
246
257
|
}
|
|
@@ -255,6 +266,7 @@ export interface AggregateWindowInitRequest {
|
|
|
255
266
|
frame_stats: Uint8Array;
|
|
256
267
|
all_valid: Uint8Array;
|
|
257
268
|
attach_opaque_data?: Uint8Array | null;
|
|
269
|
+
schema_name?: string | null;
|
|
258
270
|
}
|
|
259
271
|
export interface AggregateWindowInitResponse {
|
|
260
272
|
}
|
|
@@ -281,6 +293,7 @@ export interface BindRequest {
|
|
|
281
293
|
at_value?: string | null;
|
|
282
294
|
copy_from?: CopyFromContext | null;
|
|
283
295
|
copy_to?: CopyToContext | null;
|
|
296
|
+
schema_name?: string | null;
|
|
284
297
|
}
|
|
285
298
|
export interface BindResponse {
|
|
286
299
|
output_schema: Uint8Array;
|
|
@@ -409,6 +422,7 @@ export interface TableBufferingCombineRequest {
|
|
|
409
422
|
state_ids: Uint8Array[];
|
|
410
423
|
attach_opaque_data?: Uint8Array | null;
|
|
411
424
|
transaction_id?: Uint8Array | null;
|
|
425
|
+
schema_name?: string | null;
|
|
412
426
|
}
|
|
413
427
|
export interface TableBufferingCombineResponse {
|
|
414
428
|
finalize_state_ids: Uint8Array[];
|
|
@@ -418,6 +432,7 @@ export interface TableBufferingDestructorRequest {
|
|
|
418
432
|
execution_id: Uint8Array;
|
|
419
433
|
attach_opaque_data?: Uint8Array | null;
|
|
420
434
|
transaction_id?: Uint8Array | null;
|
|
435
|
+
schema_name?: string | null;
|
|
421
436
|
}
|
|
422
437
|
export interface TableBufferingDestructorResponse {
|
|
423
438
|
}
|
|
@@ -428,6 +443,7 @@ export interface TableBufferingProcessRequest {
|
|
|
428
443
|
attach_opaque_data?: Uint8Array | null;
|
|
429
444
|
transaction_id?: Uint8Array | null;
|
|
430
445
|
batch_index?: number | null;
|
|
446
|
+
schema_name?: string | null;
|
|
431
447
|
}
|
|
432
448
|
export interface TableBufferingProcessResponse {
|
|
433
449
|
state_id: Uint8Array;
|
package/dist/index.core.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { CACHE_ETAG_KEY, CACHE_EXPIRES_KEY, CACHE_IF_MODIFIED_SINCE_KEY, CACHE_IF_NONE_MATCH_KEY, CACHE_LAST_MODIFIED_KEY, CACHE_NO_STORE_KEY, CACHE_NOT_MODIFIED_KEY, CACHE_PARTITION_SCOPE_KEY, CACHE_REVALIDATABLE_KEY, CACHE_SCOPE_CATALOG, CACHE_SCOPE_KEY, CACHE_SCOPE_TRANSACTION, CACHE_STALE_IF_ERROR_KEY, CACHE_STALE_WHILE_REVALIDATE_KEY, CACHE_TTL_KEY, type CacheControl, cacheControlMetadata, type CacheScope, } from "./cache-control.js";
|
|
1
|
+
export { CACHE_ETAG_KEY, CACHE_EXPIRES_KEY, CACHE_IF_MODIFIED_SINCE_KEY, CACHE_IF_NONE_MATCH_KEY, CACHE_LAST_MODIFIED_KEY, CACHE_NO_STORE_KEY, CACHE_NOT_MODIFIED_KEY, CACHE_PARTITION_SCOPE_KEY, CACHE_PER_VALUE_KEY, CACHE_REVALIDATABLE_KEY, CACHE_SCOPE_CATALOG, CACHE_SCOPE_KEY, CACHE_SCOPE_TRANSACTION, CACHE_STALE_IF_ERROR_KEY, CACHE_STALE_WHILE_REVALIDATE_KEY, CACHE_TTL_KEY, type CacheControl, cacheControlMetadata, type CacheScope, } from "./cache-control.js";
|
|
2
2
|
export { defineScalarFunction, type ScalarFunctionConfig, type ScalarBindParameters, type ScalarParameterDef } from "./functions/scalar.js";
|
|
3
3
|
export { defineTableFunction, type TableFunctionConfig, type TableBindParams, type TableProcessParams } from "./functions/table.js";
|
|
4
4
|
export { defineAggregate, GROUP_COLUMN_NAME, type AggregateFunctionConfig, type AggregateBindParams, type AggregateUpdateParams, type AggregateFinalizeParams, } from "./functions/aggregate.js";
|
package/dist/index.js
CHANGED
|
@@ -2611,6 +2611,7 @@ var CACHE_STALE_WHILE_REVALIDATE_KEY = "vgi.cache.stale_while_revalidate";
|
|
|
2611
2611
|
var CACHE_STALE_IF_ERROR_KEY = "vgi.cache.stale_if_error";
|
|
2612
2612
|
var CACHE_NOT_MODIFIED_KEY = "vgi.cache.not_modified";
|
|
2613
2613
|
var CACHE_PARTITION_SCOPE_KEY = "vgi.cache.partition_scope";
|
|
2614
|
+
var CACHE_PER_VALUE_KEY = "vgi.cache.per_value";
|
|
2614
2615
|
var CACHE_IF_NONE_MATCH_KEY = "vgi.cache.if_none_match";
|
|
2615
2616
|
var CACHE_IF_MODIFIED_SINCE_KEY = "vgi.cache.if_modified_since";
|
|
2616
2617
|
var CACHE_SCOPE_CATALOG = "catalog";
|
|
@@ -2649,6 +2650,8 @@ function cacheControlMetadata(cc, extra) {
|
|
|
2649
2650
|
md.set(CACHE_NOT_MODIFIED_KEY, "1");
|
|
2650
2651
|
if (cc.partitionScope)
|
|
2651
2652
|
md.set(CACHE_PARTITION_SCOPE_KEY, "1");
|
|
2653
|
+
if (cc.perValue)
|
|
2654
|
+
md.set(CACHE_PER_VALUE_KEY, "1");
|
|
2652
2655
|
return md;
|
|
2653
2656
|
}
|
|
2654
2657
|
// src/functions/scalar.ts
|
|
@@ -5105,7 +5108,8 @@ var BIND_REQUEST_SCHEMA = schema2([
|
|
|
5105
5108
|
field2("transaction_opaque_data", binary2(), true),
|
|
5106
5109
|
field2("resolved_secrets_provided", bool2(), false),
|
|
5107
5110
|
field2("at_unit", utf82(), true),
|
|
5108
|
-
field2("at_value", utf82(), true)
|
|
5111
|
+
field2("at_value", utf82(), true),
|
|
5112
|
+
field2("schema_name", utf82(), true)
|
|
5109
5113
|
]);
|
|
5110
5114
|
var COPY_FROM_STRUCT_TYPE = struct2([
|
|
5111
5115
|
field2("format", utf82(), false),
|
|
@@ -5137,7 +5141,8 @@ function serializeBindRequest(req) {
|
|
|
5137
5141
|
transaction_opaque_data: req.transaction_opaque_data ?? null,
|
|
5138
5142
|
resolved_secrets_provided: req.resolved_secrets_provided ?? false,
|
|
5139
5143
|
at_unit: req.at_unit ?? null,
|
|
5140
|
-
at_value: req.at_value ?? null
|
|
5144
|
+
at_value: req.at_value ?? null,
|
|
5145
|
+
schema_name: req.schema_name ?? null
|
|
5141
5146
|
};
|
|
5142
5147
|
const extraFields = [];
|
|
5143
5148
|
if (req.copy_from) {
|
|
@@ -5209,6 +5214,7 @@ function deserializeBindRequest(params) {
|
|
|
5209
5214
|
resolved_secrets_provided: params.resolved_secrets_provided ?? false,
|
|
5210
5215
|
at_unit: params.at_unit ? String(params.at_unit) : null,
|
|
5211
5216
|
at_value: params.at_value ? String(params.at_value) : null,
|
|
5217
|
+
schema_name: params.schema_name ? String(params.schema_name) : null,
|
|
5212
5218
|
copy_from: parseCopyFromContext(params.copy_from),
|
|
5213
5219
|
copy_to: parseCopyToContext(params.copy_to)
|
|
5214
5220
|
};
|
|
@@ -6786,6 +6792,10 @@ function isPromise(v) {
|
|
|
6786
6792
|
}
|
|
6787
6793
|
|
|
6788
6794
|
class CatalogInterface {
|
|
6795
|
+
catalogNameForAttach(_attachOpaqueData) {
|
|
6796
|
+
const names = this.catalogs();
|
|
6797
|
+
return names.length === 1 ? names[0] : null;
|
|
6798
|
+
}
|
|
6789
6799
|
create(name, onConflict, options) {
|
|
6790
6800
|
throw new CatalogReadOnlyError("create");
|
|
6791
6801
|
}
|
|
@@ -7020,6 +7030,17 @@ class ReadOnlyCatalogInterface extends CatalogInterface {
|
|
|
7020
7030
|
super();
|
|
7021
7031
|
this._descriptor = descriptor;
|
|
7022
7032
|
this._registry = registry;
|
|
7033
|
+
for (const sch of descriptor.schemas ?? []) {
|
|
7034
|
+
for (const fn of sch.functions ?? [])
|
|
7035
|
+
registry.registerInSchema(fn, sch.name, descriptor.name);
|
|
7036
|
+
for (const tbl of sch.tables ?? []) {
|
|
7037
|
+
for (const key of ["function", "insertFunction", "updateFunction", "deleteFunction"]) {
|
|
7038
|
+
const fn = tbl[key];
|
|
7039
|
+
if (fn)
|
|
7040
|
+
registry.registerInSchema(fn, sch.name, descriptor.name);
|
|
7041
|
+
}
|
|
7042
|
+
}
|
|
7043
|
+
}
|
|
7023
7044
|
}
|
|
7024
7045
|
catalogs() {
|
|
7025
7046
|
return [this._descriptor.name];
|
|
@@ -7642,6 +7663,13 @@ class CompositeCatalogInterface extends CatalogInterface {
|
|
|
7642
7663
|
}
|
|
7643
7664
|
return route;
|
|
7644
7665
|
}
|
|
7666
|
+
catalogNameForAttach(attachOpaqueData) {
|
|
7667
|
+
try {
|
|
7668
|
+
return this._route(attachOpaqueData).catalogNameForAttach(attachOpaqueData);
|
|
7669
|
+
} catch {
|
|
7670
|
+
return null;
|
|
7671
|
+
}
|
|
7672
|
+
}
|
|
7645
7673
|
catalogs() {
|
|
7646
7674
|
const all = [];
|
|
7647
7675
|
for (const b of this._backends)
|
|
@@ -7870,9 +7898,17 @@ function filterByArgumentTypes(candidates, args, inputSchema, isScalar) {
|
|
|
7870
7898
|
const maxScore = Math.max(...scored.map((s) => s.score));
|
|
7871
7899
|
return scored.filter((s) => s.score === maxScore).map((s) => s.func);
|
|
7872
7900
|
}
|
|
7901
|
+
function schemaKey(schemaName, functionName) {
|
|
7902
|
+
return `${schemaName.toLowerCase()}\x00${functionName}`;
|
|
7903
|
+
}
|
|
7904
|
+
function catalogKey(catalogName, schemaName, functionName) {
|
|
7905
|
+
return `${catalogName.toLowerCase()}\x00${schemaKey(schemaName, functionName)}`;
|
|
7906
|
+
}
|
|
7873
7907
|
|
|
7874
7908
|
class FunctionRegistry {
|
|
7875
7909
|
_functions = new Map;
|
|
7910
|
+
_bySchema = new Map;
|
|
7911
|
+
_byCatalog = new Map;
|
|
7876
7912
|
register(func) {
|
|
7877
7913
|
const name = func.meta.name;
|
|
7878
7914
|
if (!this._functions.has(name)) {
|
|
@@ -7880,11 +7916,57 @@ class FunctionRegistry {
|
|
|
7880
7916
|
}
|
|
7881
7917
|
this._functions.get(name).push(func);
|
|
7882
7918
|
}
|
|
7919
|
+
registerInSchema(func, schemaName, catalogName) {
|
|
7920
|
+
const add = (map3, key) => {
|
|
7921
|
+
const bucket = map3.get(key);
|
|
7922
|
+
if (!bucket) {
|
|
7923
|
+
map3.set(key, [func]);
|
|
7924
|
+
return;
|
|
7925
|
+
}
|
|
7926
|
+
if (!bucket.includes(func))
|
|
7927
|
+
bucket.push(func);
|
|
7928
|
+
};
|
|
7929
|
+
add(this._bySchema, schemaKey(schemaName, func.meta.name));
|
|
7930
|
+
if (catalogName) {
|
|
7931
|
+
add(this._byCatalog, catalogKey(catalogName, schemaName, func.meta.name));
|
|
7932
|
+
}
|
|
7933
|
+
}
|
|
7934
|
+
schemasFor(functionName) {
|
|
7935
|
+
const out = [];
|
|
7936
|
+
for (const key of this._bySchema.keys()) {
|
|
7937
|
+
const [schema3, name] = key.split("\x00");
|
|
7938
|
+
if (name === functionName)
|
|
7939
|
+
out.push(schema3);
|
|
7940
|
+
}
|
|
7941
|
+
return out.sort();
|
|
7942
|
+
}
|
|
7883
7943
|
get(name, context) {
|
|
7884
|
-
|
|
7944
|
+
let candidates = this._functions.get(name);
|
|
7945
|
+
const catalogName = context?.catalogName;
|
|
7946
|
+
const schemaName = context?.schemaName;
|
|
7947
|
+
if (catalogName && schemaName) {
|
|
7948
|
+
const scoped = this._byCatalog.get(catalogKey(catalogName, schemaName, name));
|
|
7949
|
+
if (scoped && scoped.length > 0) {
|
|
7950
|
+
return this._disambiguate(name, scoped, context);
|
|
7951
|
+
}
|
|
7952
|
+
}
|
|
7953
|
+
if (schemaName) {
|
|
7954
|
+
const scoped = this._bySchema.get(schemaKey(schemaName, name));
|
|
7955
|
+
if (scoped && scoped.length > 0) {
|
|
7956
|
+
candidates = scoped;
|
|
7957
|
+
} else if (candidates && candidates.length > 0) {
|
|
7958
|
+
const schemas = this.schemasFor(name);
|
|
7959
|
+
if (schemas.length > 0) {
|
|
7960
|
+
throw new Error(`Function '${name}' is not registered in schema '${schemaName}'. ` + `It is available in: [${schemas.join(", ")}]`);
|
|
7961
|
+
}
|
|
7962
|
+
}
|
|
7963
|
+
}
|
|
7885
7964
|
if (!candidates || candidates.length === 0) {
|
|
7886
7965
|
throw new FunctionNotFoundError(name, this.names());
|
|
7887
7966
|
}
|
|
7967
|
+
return this._disambiguate(name, candidates, context);
|
|
7968
|
+
}
|
|
7969
|
+
_disambiguate(name, candidates, context) {
|
|
7888
7970
|
if (candidates.length === 1) {
|
|
7889
7971
|
return candidates[0];
|
|
7890
7972
|
}
|
|
@@ -8170,11 +8252,21 @@ function wrapResult(values, innerSchema) {
|
|
|
8170
8252
|
const batch = batchFromColumns(Object.fromEntries(a.fields.map((f) => [f.name, [values[f.name] ?? null]])), a);
|
|
8171
8253
|
return { result: serializeBatch(batch) };
|
|
8172
8254
|
}
|
|
8173
|
-
function overloadContext(req) {
|
|
8255
|
+
function overloadContext(req, catalogInterface) {
|
|
8256
|
+
let catalogName = null;
|
|
8257
|
+
if (catalogInterface && req.attach_opaque_data) {
|
|
8258
|
+
try {
|
|
8259
|
+
catalogName = catalogInterface.catalogNameForAttach(req.attach_opaque_data);
|
|
8260
|
+
} catch {
|
|
8261
|
+
catalogName = null;
|
|
8262
|
+
}
|
|
8263
|
+
}
|
|
8174
8264
|
return {
|
|
8175
8265
|
arguments: req.arguments,
|
|
8176
8266
|
inputSchema: req.input_schema,
|
|
8177
|
-
isScalar: String(req.function_type).toLowerCase() === "scalar"
|
|
8267
|
+
isScalar: String(req.function_type).toLowerCase() === "scalar",
|
|
8268
|
+
schemaName: req.schema_name ?? null,
|
|
8269
|
+
catalogName
|
|
8178
8270
|
};
|
|
8179
8271
|
}
|
|
8180
8272
|
function recoverFinalizeState(request, recoverExchangeState) {
|
|
@@ -9147,7 +9239,7 @@ var columnOpParams = schema2([
|
|
|
9147
9239
|
|
|
9148
9240
|
// src/protocol/handlers/function.ts
|
|
9149
9241
|
function registerFunctionMethods(protocol, config) {
|
|
9150
|
-
const { registry, signingKey } = config;
|
|
9242
|
+
const { registry, signingKey, catalogInterface } = config;
|
|
9151
9243
|
async function stripAttach(attach, ctx) {
|
|
9152
9244
|
if (attach == null)
|
|
9153
9245
|
return null;
|
|
@@ -9156,6 +9248,15 @@ function registerFunctionMethods(protocol, config) {
|
|
|
9156
9248
|
return env;
|
|
9157
9249
|
return openAttach(env, ctx?.auth, signingKey);
|
|
9158
9250
|
}
|
|
9251
|
+
async function strippedContext(bindCall, ctx) {
|
|
9252
|
+
let attach = null;
|
|
9253
|
+
try {
|
|
9254
|
+
attach = await stripAttach(bindCall.attach_opaque_data, ctx);
|
|
9255
|
+
} catch {
|
|
9256
|
+
attach = null;
|
|
9257
|
+
}
|
|
9258
|
+
return overloadContext({ ...bindCall, attach_opaque_data: attach }, catalogInterface);
|
|
9259
|
+
}
|
|
9159
9260
|
const initHeaderSchema = schema2([
|
|
9160
9261
|
field2("execution_id", binary2(), false),
|
|
9161
9262
|
field2("opaque_data", binary2(), true),
|
|
@@ -9172,7 +9273,7 @@ function registerFunctionMethods(protocol, config) {
|
|
|
9172
9273
|
const innerParams = unwrapRequest(params.request);
|
|
9173
9274
|
const request = deserializeBindRequest(innerParams);
|
|
9174
9275
|
request.attach_opaque_data = await stripAttach(request.attach_opaque_data, ctx);
|
|
9175
|
-
const func = registry.get(request.function_name, overloadContext(request));
|
|
9276
|
+
const func = registry.get(request.function_name, overloadContext(request, catalogInterface));
|
|
9176
9277
|
const response = await func.bind(request);
|
|
9177
9278
|
const serialized = serializeBindResponse(response);
|
|
9178
9279
|
return wrapResult(serialized, BindResultSchema);
|
|
@@ -9187,7 +9288,7 @@ function registerFunctionMethods(protocol, config) {
|
|
|
9187
9288
|
const innerParams = unwrapRequest(params.request);
|
|
9188
9289
|
const request = deserializeInitRequest(innerParams);
|
|
9189
9290
|
request.bind_call.attach_opaque_data = await stripAttach(request.bind_call.attach_opaque_data, undefined);
|
|
9190
|
-
const func = registry.get(request.bind_call.function_name, overloadContext(request.bind_call));
|
|
9291
|
+
const func = registry.get(request.bind_call.function_name, overloadContext(request.bind_call, catalogInterface));
|
|
9191
9292
|
const initResponse = await func.globalInit(request);
|
|
9192
9293
|
const accumulatedState = recoverFinalizeState(request, config.recoverExchangeState);
|
|
9193
9294
|
const handlers = func.createStreamHandlers(request, initResponse, accumulatedState);
|
|
@@ -9227,7 +9328,7 @@ function registerFunctionMethods(protocol, config) {
|
|
|
9227
9328
|
const initRequestBatch = deserializeBatch(state.initRequestIpc);
|
|
9228
9329
|
const initRequestDict = batchToScalarDict(initRequestBatch);
|
|
9229
9330
|
const request = deserializeInitRequest(initRequestDict);
|
|
9230
|
-
const func = registry.get(state.functionName,
|
|
9331
|
+
const func = registry.get(state.functionName, await strippedContext(request.bind_call));
|
|
9231
9332
|
const executionId = state.executionId;
|
|
9232
9333
|
const opaqueData = state.opaqueData ?? null;
|
|
9233
9334
|
const initResponse = {
|
|
@@ -9275,7 +9376,7 @@ function registerFunctionMethods(protocol, config) {
|
|
|
9275
9376
|
handler: async (params) => {
|
|
9276
9377
|
const innerParams = unwrapRequest(params.request);
|
|
9277
9378
|
const request = deserializeCardinalityRequest(innerParams);
|
|
9278
|
-
const func = registry.get(request.bind_call.function_name,
|
|
9379
|
+
const func = registry.get(request.bind_call.function_name, await strippedContext(request.bind_call));
|
|
9279
9380
|
let cardResult;
|
|
9280
9381
|
if (func.cardinality) {
|
|
9281
9382
|
cardResult = serializeTableCardinality(await func.cardinality(request));
|
|
@@ -9288,10 +9389,10 @@ function registerFunctionMethods(protocol, config) {
|
|
|
9288
9389
|
protocol.unary("table_function_statistics", {
|
|
9289
9390
|
params: REQUEST_PARAMS_SCHEMA,
|
|
9290
9391
|
result: RESULT_BINARY_NULLABLE_SCHEMA,
|
|
9291
|
-
handler: (params) => {
|
|
9392
|
+
handler: async (params) => {
|
|
9292
9393
|
const innerParams = unwrapRequest(params.request);
|
|
9293
9394
|
const request = deserializeCardinalityRequest(innerParams);
|
|
9294
|
-
const func = registry.get(request.bind_call.function_name,
|
|
9395
|
+
const func = registry.get(request.bind_call.function_name, await strippedContext(request.bind_call));
|
|
9295
9396
|
if (!func.statistics)
|
|
9296
9397
|
return { result: null };
|
|
9297
9398
|
const stats = func.statistics(request);
|
|
@@ -9311,7 +9412,7 @@ function registerFunctionMethods(protocol, config) {
|
|
|
9311
9412
|
const bindCall = deserializeBindRequest(bindParams);
|
|
9312
9413
|
const globalExecutionId = toUint8Array(innerParams.global_execution_id);
|
|
9313
9414
|
const bindOpaqueData = innerParams.bind_opaque_data ? toUint8Array(innerParams.bind_opaque_data) : null;
|
|
9314
|
-
const func = registry.get(bindCall.function_name,
|
|
9415
|
+
const func = registry.get(bindCall.function_name, await strippedContext(bindCall));
|
|
9315
9416
|
const map3 = func.dynamicToString ? await func.dynamicToString({ bindCall, bindOpaqueData, globalExecutionId }) : {};
|
|
9316
9417
|
const keys = Object.keys(map3);
|
|
9317
9418
|
const values = keys.map((k) => map3[k] ?? "");
|
|
@@ -10311,7 +10412,8 @@ function buildVgiProtocol(config) {
|
|
|
10311
10412
|
registerFunctionMethods(protocol, {
|
|
10312
10413
|
registry: config.registry,
|
|
10313
10414
|
recoverExchangeState: config.recoverExchangeState,
|
|
10314
|
-
signingKey: config.signingKey
|
|
10415
|
+
signingKey: config.signingKey,
|
|
10416
|
+
catalogInterface: config.catalogInterface
|
|
10315
10417
|
});
|
|
10316
10418
|
registerAggregateMethods(protocol, config.registry);
|
|
10317
10419
|
registerTableBufferingMethods(protocol, config.registry, config.signingKey);
|
|
@@ -11696,7 +11798,7 @@ class Worker {
|
|
|
11696
11798
|
_catalogInterface;
|
|
11697
11799
|
_catalogName;
|
|
11698
11800
|
constructor(config) {
|
|
11699
|
-
this._registry = new FunctionRegistry;
|
|
11801
|
+
this._registry = config.registry ?? new FunctionRegistry;
|
|
11700
11802
|
this._catalogName = config.catalogName;
|
|
11701
11803
|
if (config.functions) {
|
|
11702
11804
|
for (const func of config.functions) {
|
|
@@ -11708,6 +11810,7 @@ class Worker {
|
|
|
11708
11810
|
if (schema3.functions) {
|
|
11709
11811
|
for (const func of schema3.functions) {
|
|
11710
11812
|
this._registry.register(func);
|
|
11813
|
+
this._registry.registerInSchema(func, schema3.name, config.catalog.name);
|
|
11711
11814
|
}
|
|
11712
11815
|
}
|
|
11713
11816
|
}
|
|
@@ -12017,6 +12120,7 @@ export {
|
|
|
12017
12120
|
CACHE_SCOPE_KEY,
|
|
12018
12121
|
CACHE_SCOPE_CATALOG,
|
|
12019
12122
|
CACHE_REVALIDATABLE_KEY,
|
|
12123
|
+
CACHE_PER_VALUE_KEY,
|
|
12020
12124
|
CACHE_PARTITION_SCOPE_KEY,
|
|
12021
12125
|
CACHE_NO_STORE_KEY,
|
|
12022
12126
|
CACHE_NOT_MODIFIED_KEY,
|
|
@@ -12032,4 +12136,4 @@ export {
|
|
|
12032
12136
|
ArgumentValidationError
|
|
12033
12137
|
};
|
|
12034
12138
|
|
|
12035
|
-
//# debugId=
|
|
12139
|
+
//# debugId=AC11F66207EB748964756E2164756E21
|