import { type Column } from "../columns.ts"; import type { BufferReader, BufferWriter } from "../io.ts"; import { type DeserializerState, type SerializationNode } from "../serialization.ts"; import type { TypedArray } from "../types.ts"; /** * Sentinel value representing SQL NULL in toLiteral serialization. * Used to distinguish actual NULL from the string "NULL". */ export declare const SQL_NULL: unique symbol; /** Convert SQL_NULL symbol to "NULL" string for nested literals */ export declare function nullToLiteral(lit: string | typeof SQL_NULL): string; export declare function wrapQuoted(s: string, quoted?: boolean): string; /** Get a Uint8Array view over a TypedArray's underlying buffer, respecting byteOffset. */ export declare function asBytes(arr: ArrayBufferView): Uint8Array; export declare function parseTypeList(inner: string): string[]; export interface NamedElement { name: string | null; type: string; /** * True when the name was backtick-quoted. A quoted name is always a literal * identifier — `` `SKIP` `` is a path named SKIP, while an unquoted SKIP in a * JSON type is a skip directive — so consumers that treat keywords specially * must check this. */ quoted: boolean; } export declare function parseTupleElements(inner: string): NamedElement[]; export declare function extractTypeArgs(type: string): string; /** * Seedable pseudo-random number generator used by codec generators. * * The concrete implementation lives in the fuzz harness; only the type ships in * the package so codec `generate()` methods can be typed against it. */ export interface Rng { /** Float in [0, 1). */ next(): number; /** Integer in [min, max] inclusive. */ int(min: number, max: number): number; } /** * Context threaded through codec `generate()` calls. * * Carries the seeded RNG (for failure replay), a depth budget that bounds * recursive nesting, and a Dynamic/JSON type pool. `DynamicCodec` discovers its * types lazily from the wire and has no type universe at construction, so it * samples from `pickDynamicType()` rather than from local codecs. */ export interface GenContext { readonly rng: Rng; /** Remaining nesting budget; at 0 containers emit empty/leaf values. */ readonly depth: number; /** * Shared per-cell element budget bounding total Array/Map elements, so large or * deeply nested containers cannot blow up. Decremented as lengths are chosen. */ readonly budget: { remaining: number; }; /** Child context with `depth - 1` (clamped at 0). */ descend(): GenContext; /** Sample a ClickHouse type string for a Dynamic/JSON value. */ pickDynamicType(): string; } export interface ColumnBuilder { push(value: unknown): void; pushAll(values: ArrayLike): void; finish(): Column; } export interface Codec { /** ClickHouse type string this codec handles */ readonly type: string; encode(col: Column, sizeHint?: number): Uint8Array; decode(reader: BufferReader, rows: number, state: DeserializerState): Column; fromValues(values: unknown[] | TypedArray): Column; fromRows?(rows: readonly unknown[][], columnIndex: number): Column; makeBuilder?(expectedRows?: number): ColumnBuilder; zeroValue(): unknown; estimateSize(rows: number): number; /** * Write/read the per-block wire metadata that precedes column data * (LowCardinality key version, Variant mode, Dynamic type list, JSON path * list). Required even for prefix-less codecs so composites forward to * children unconditionally. */ writePrefix(writer: BufferWriter, col: Column): void; readPrefix(reader: BufferReader, state: DeserializerState): void; readKinds(reader: BufferReader): SerializationNode; /** * Serialize a single value to ClickHouse literal string syntax. * * @param value - The value to serialize * @param quoted - Controls string formatting: * - false (default): For HTTP query params. Control chars escaped, no quotes. * - true: For nested values in Array/Tuple/Map. Fully escaped and single-quoted. * @returns The serialized literal string, or SQL_NULL symbol for null values */ toLiteral(value: unknown, quoted?: boolean): string | typeof SQL_NULL; /** * Generate a random value in the same representation `decode()` returns. * Used by the client-generated CH-anchored fuzzer (`fuzz/generated.ts`). */ generate(ctx: GenContext): unknown; /** * Compare a generated value `a` against the value `b` decoded after a * ClickHouse round-trip. Near-strict equality; overridden for cases where the * decoded representation is not deterministic (e.g. Map ordering). */ compare(a: unknown, b: unknown): boolean; } /** * Escape control characters in a string for ClickHouse. * Always escapes: backslash, tab, newline, carriage return * Optionally escapes: single quote (for string literals) */ export declare function escapeString(s: string, escapeSingleQuote?: boolean): string; export declare function makeDefaultColumnBuilder(codec: Pick, expectedRows?: number): ColumnBuilder; export declare function columnFromRows(codec: Pick, rows: readonly unknown[][], columnIndex: number): Column; export declare function defaultDeserializerState(): DeserializerState; /** * Create child deserializer state for nested type at given index. * Falls back to dense serialization if child node doesn't exist * (older ClickHouse versions or incomplete tree). */ export declare function childState(state: DeserializerState, index: number): DeserializerState; /** * Read serialization kinds for wrapper codec with 1 child. * Used by Array, Nullable, LowCardinality. */ export declare function readKinds1(reader: BufferReader, child: Codec): SerializationNode; /** * Read serialization kinds for wrapper codec with 2 children. * Used by Map (key + value). */ export declare function readKinds2(reader: BufferReader, childA: Codec, childB: Codec): SerializationNode; /** * Read serialization kinds for wrapper codec with N children. * Used by Tuple, Variant, Dynamic, JSON. */ export declare function readKindsMany(reader: BufferReader, children: readonly Codec[]): SerializationNode; /** * Base class for codecs that support sparse serialization. * Centralizes the sparse check pattern - subclasses implement decodeDense(). */ /** * Structural deep-equal used by the default `compare`. Uses `Object.is` for * primitives (correct for NaN and -0), recurses arrays, and falls back to * own-enumerable-key comparison for plain objects. `Uint8Array` and `Date` are * compared element/time-wise. */ export declare function deepCompare(a: unknown, b: unknown): boolean; export declare abstract class BaseCodec implements Codec { abstract readonly type: string; abstract encode(col: Column, sizeHint?: number): Uint8Array; abstract fromValues(values: unknown[] | TypedArray): Column; abstract zeroValue(): unknown; abstract estimateSize(rows: number): number; abstract decodeDense(reader: BufferReader, rows: number, state: DeserializerState): Column; abstract serializeLiteral(value: unknown, quoted?: boolean): string; abstract generate(ctx: GenContext): unknown; toLiteral(value: unknown, quoted?: boolean): string | typeof SQL_NULL; compare(a: unknown, b: unknown): boolean; fromRows(rows: readonly unknown[][], columnIndex: number): Column; makeBuilder(expectedRows?: number): ColumnBuilder; decode(reader: BufferReader, rows: number, state: DeserializerState): Column; readKinds(reader: BufferReader): SerializationNode; writePrefix(_writer: BufferWriter, _col: Column): void; readPrefix(_reader: BufferReader, _state: DeserializerState): void; } //# sourceMappingURL=base.d.ts.map