@query-farm/vgi 0.24.1 → 0.25.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.
@@ -21,6 +21,16 @@ export interface AttachOptionSpec {
21
21
  * the options dict delivered to attach()).
22
22
  */
23
23
  default?: unknown;
24
+ /**
25
+ * The caller must supply this option at ATTACH time. A catalog that cannot
26
+ * be attached without it advertises that fact at discovery, so a client can
27
+ * say so before attempting the attach rather than surfacing a failure that
28
+ * reads like an empty catalog.
29
+ *
30
+ * Mutually exclusive with `default` — an option that falls back to a value
31
+ * is by definition satisfiable without the caller.
32
+ */
33
+ required?: boolean;
24
34
  }
25
35
  /**
26
36
  * Serialize an AttachOptionSpec to the wire format the extension expects
@@ -31,3 +41,33 @@ export declare function serializeAttachOptionSpec(spec: AttachOptionSpec): Uint8
31
41
  * Convenience: serialize many specs at once for CatalogInfo.attach_option_specs.
32
42
  */
33
43
  export declare function serializeAttachOptionSpecs(specs: Iterable<AttachOptionSpec>): Uint8Array[];
44
+ /**
45
+ * Deserialize one AttachOptionSpec from the wire format above.
46
+ *
47
+ * Reads by column name, so a spec written by a peer that predates the
48
+ * `required` column deserializes with `required: false` rather than failing —
49
+ * the same tolerance the Python and C++ readers have.
50
+ */
51
+ export declare function deserializeAttachOptionSpec(bytes: Uint8Array): AttachOptionSpec;
52
+ /** Deserialize many specs — the shape `CatalogInfo.attach_option_specs` holds. */
53
+ export declare function deserializeAttachOptionSpecs(specs: Iterable<Uint8Array>): AttachOptionSpec[];
54
+ /**
55
+ * Raised when `attach` omits options declared `required`.
56
+ *
57
+ * Carries the option names in `missing` so a caller can act on them without
58
+ * parsing the message. Mirrors `MissingAttachOptionsError` on the Python side,
59
+ * message included — the extension's integration suite matches on its text.
60
+ */
61
+ export declare class MissingAttachOptionsError extends Error {
62
+ readonly missing: string[];
63
+ constructor(catalogName: string, missing: string[]);
64
+ }
65
+ /**
66
+ * Throw if any `required` spec has no corresponding entry in `options`.
67
+ *
68
+ * Option names are matched case-insensitively, mirroring DuckDB's handling of
69
+ * ATTACH option keys.
70
+ *
71
+ * @throws {MissingAttachOptionsError} If a required option was not supplied.
72
+ */
73
+ export declare function validateRequiredAttachOptions(catalogName: string, specs: Iterable<AttachOptionSpec>, options: Record<string, unknown>): void;
@@ -1,6 +1,7 @@
1
1
  import { CatalogInterface, type AttachOpaqueData, type TransactionOpaqueData, type CatalogAttachResult, type SchemaInfo, type CatalogInfo, type TableInfo, type ViewInfo, type FunctionInfo, type MacroInfo, type IndexInfo, type CopyFromFormatInfo } from "./interface.js";
2
2
  import type { CatalogDescriptor } from "./descriptors.js";
3
3
  import type { FunctionRegistry } from "../functions/registry.js";
4
+ import { type AttachOptionSpec } from "./attach-option.js";
4
5
  export declare class ReadOnlyCatalogInterface extends CatalogInterface {
5
6
  private _descriptor;
6
7
  private _registry;
@@ -8,6 +9,16 @@ export declare class ReadOnlyCatalogInterface extends CatalogInterface {
8
9
  private _version;
9
10
  constructor(descriptor: CatalogDescriptor, registry: FunctionRegistry);
10
11
  catalogs(): string[];
12
+ /**
13
+ * Attach-time options this catalog declares, for the named catalog.
14
+ *
15
+ * Empty by default — the declarative descriptor path carries no attach
16
+ * options. A subclass that advertises specs in `catalogsInfo()` should
17
+ * return the same specs here so `attach()` enforces the `required` ones it
18
+ * advertised. Takes the catalog name because one interface may serve
19
+ * several catalogs with different option sets.
20
+ */
21
+ attachOptionSpecs(_name: string): AttachOptionSpec[];
11
22
  catalogsInfo(): CatalogInfo[];
12
23
  attach(name: string, options?: Record<string, unknown>, dataVersionSpec?: string | null, implementationVersion?: string | null): CatalogAttachResult | Promise<CatalogAttachResult>;
13
24
  detach(attachOpaqueData: AttachOpaqueData): void;
@@ -7,5 +7,7 @@ export type { BindRequest, BindResponse, InitRequest, GlobalInitResponse, TableC
7
7
  export { type SchemaInfo, encodeSchemaInfo, decodeSchemaInfo, type TableInfo, encodeTableInfo, decodeTableInfo, type ViewInfo, encodeViewInfo, decodeViewInfo, type FunctionInfo, encodeFunctionInfo, decodeFunctionInfo, type MacroInfo, encodeMacroInfo, decodeMacroInfo, type CatalogAttachResult, type AttachOpaqueData, type TransactionOpaqueData, } from "./catalog/interface.js";
8
8
  export { VgiError, RowCountMismatchError, FunctionNotFoundError, CatalogReadOnlyError, CatalogNotFoundError, CatalogAlreadyExistsError, ArgumentValidationError, NoCatalogError, } from "./errors.js";
9
9
  export { iterRows, batchFromRows, batchFromColumns, emptyBatch, filterBatch, projectSchema, projectBatch, batchToScalarDict, safeNumber, serializeSchema, deserializeSchema, serializeBatch, deserializeBatch, } from "./util/arrow/index.js";
10
+ export { TypeId, typeSignature } from "./arrow/predicates.js";
11
+ export { type AttachOptionSpec, deserializeAttachOptionSpec, deserializeAttachOptionSpecs, } from "./catalog/attach-option.js";
10
12
  export { toUint8Array } from "./util/bytes.js";
11
13
  export type { RpcClient, StreamSession, LogMessage } from "@query-farm/vgi-rpc";
@@ -58,6 +58,42 @@ function isMap(t) {
58
58
  function isDictionary(t) {
59
59
  return t.typeId === TypeId.Dictionary;
60
60
  }
61
+ function typeSignature(t) {
62
+ if (t == null)
63
+ return "null";
64
+ const a = t;
65
+ const kids = () => Array.isArray(a.children) ? a.children.map((c) => `${c?.name ?? ""}:${typeSignature(c?.type ?? c)}`).join(",") : "";
66
+ switch (t.typeId) {
67
+ case TypeId.Int:
68
+ return `int${a.bitWidth}${a.isSigned ?? a.signed ?? true ? "" : "u"}`;
69
+ case TypeId.Float:
70
+ return `float${a.precision}`;
71
+ case TypeId.Decimal:
72
+ return `decimal${a.bitWidth ?? 128}(${a.precision},${a.scale})`;
73
+ case TypeId.Date:
74
+ case TypeId.Time:
75
+ case TypeId.Duration:
76
+ return `${t.typeId}[${a.unit}]`;
77
+ case TypeId.Timestamp:
78
+ return `ts[${a.unit},${a.timezone ?? ""}]`;
79
+ case TypeId.Interval:
80
+ return `iv[${a.unit}]`;
81
+ case TypeId.FixedSizeBinary:
82
+ return `fsb(${a.byteWidth ?? a.stride})`;
83
+ case TypeId.FixedSizeList:
84
+ return `fsl(${a.listSize ?? a.stride},${kids()})`;
85
+ case TypeId.List:
86
+ case TypeId.Struct:
87
+ case TypeId.Map:
88
+ return `${t.typeId}<${kids()}>`;
89
+ case TypeId.Union:
90
+ return `union(${a.mode},${kids()})`;
91
+ case TypeId.Dictionary:
92
+ return `dict(${typeSignature(a.dictionary)},${typeSignature(a.indices)},${a.ordered ?? a.isOrdered ?? false})`;
93
+ default:
94
+ return Array.isArray(a.children) ? `${t.typeId}<${kids()}>` : String(t.typeId);
95
+ }
96
+ }
61
97
  // src/arrow/impl-arrowjs/index.ts
62
98
  var exports_impl_arrowjs = {};
63
99
  __export(exports_impl_arrowjs, {
@@ -3880,7 +3916,43 @@ function schemaToArgumentSpecs(schema3) {
3880
3916
  }
3881
3917
  return specs;
3882
3918
  }
3919
+ // src/catalog/attach-option.ts
3920
+ var SPEC_SCHEMA = schema2([
3921
+ field2("name", utf82(), false),
3922
+ field2("description", utf82(), false),
3923
+ field2("type", binary2(), false),
3924
+ field2("default_value", binary2(), true),
3925
+ field2("required", bool2(), true)
3926
+ ]);
3927
+ function deserializeAttachOptionSpec(bytes) {
3928
+ const row = [...iterRows(deserializeBatch(bytes))][0];
3929
+ if (row === undefined) {
3930
+ throw new Error("Cannot deserialize AttachOptionSpec from an empty batch");
3931
+ }
3932
+ const typeSchema = deserializeSchema(toUint8Array(row.type));
3933
+ const type = typeSchema.fields[0].type;
3934
+ let value;
3935
+ const defaultBytes = row.default_value;
3936
+ if (defaultBytes != null) {
3937
+ const asBytes = toUint8Array(defaultBytes);
3938
+ if (asBytes.length > 0) {
3939
+ const defaultRow = [...iterRows(deserializeBatch(asBytes))][0];
3940
+ value = defaultRow?.value;
3941
+ }
3942
+ }
3943
+ return {
3944
+ name: String(row.name),
3945
+ description: String(row.description ?? ""),
3946
+ type,
3947
+ ...value === undefined || value === null ? {} : { default: value },
3948
+ required: row.required === true
3949
+ };
3950
+ }
3951
+ function deserializeAttachOptionSpecs(specs) {
3952
+ return Array.from(specs, deserializeAttachOptionSpec);
3953
+ }
3883
3954
  export {
3955
+ typeSignature,
3884
3956
  toUint8Array,
3885
3957
  serializeSchema,
3886
3958
  serializeBatch,
@@ -3898,6 +3970,8 @@ export {
3898
3970
  emptyBatch,
3899
3971
  deserializeSchema,
3900
3972
  deserializeBatch,
3973
+ deserializeAttachOptionSpecs,
3974
+ deserializeAttachOptionSpec,
3901
3975
  decodeViewInfo,
3902
3976
  decodeTableInfo,
3903
3977
  decodeSchemaInfo,
@@ -3910,6 +3984,7 @@ export {
3910
3984
  VgiError,
3911
3985
  VgiClientError,
3912
3986
  VgiClient,
3987
+ TypeId,
3913
3988
  TableInOutPhase,
3914
3989
  RowCountMismatchError,
3915
3990
  OrderPreservation,
@@ -3927,4 +4002,4 @@ export {
3927
4002
  ArgumentValidationError
3928
4003
  };
3929
4004
 
3930
- //# debugId=34D58DEB536066C064756E2164756E21
4005
+ //# debugId=B61D9AABA0B3DE2E64756E2164756E21