@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.
@@ -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), so the extension can memoize the
116
- * scalar's output per distinct input value. A pure, deterministic scalar
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;
@@ -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
- const candidates = this._functions.get(name);
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, overloadContext(request.bind_call));
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, overloadContext(request.bind_call));
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, overloadContext(request.bind_call));
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, overloadContext(bindCall));
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=16E563A7CD4C6BEC64756E2164756E21
12139
+ //# debugId=AC11F66207EB748964756E2164756E21