@dudousxd/nestjs-filter-clickhouse
Version:
ClickHouse adapter for @dudousxd/nestjs-filter: compiles structured filter input to parameterized ClickHouse SQL.
68 lines • 3.67 kB
TypeScript
import { type ColumnFilter } from '@dudousxd/nestjs-filter';
import { BadRequestException } from '@nestjs/common';
import type { ClickHouseTypeKind, ResolvedClickHouseField } from './table.js';
/** A client value the adapter cannot bind to the field's type (e.g. `age=abc` on a UInt64). */
export declare class ClickHouseValueError extends BadRequestException {
constructor(message: string);
}
/**
* Collects typed query parameters. Every client value is bound as `{name:Type}` and sent in
* `query_params` — nothing client-supplied is ever part of the SQL text.
*/
export declare class ClickHouseParams {
private readonly prefix;
readonly values: Record<string, unknown>;
private n;
constructor(prefix?: string);
/** Binds `value` as a parameter of `type` and returns its placeholder. */
bind(type: string, value: unknown): string;
}
/**
* Encodes a client value for a parameter of the given kind. Query strings deliver text, so text is
* parsed; a value that does not parse is rejected with a 400 rather than handed to ClickHouse,
* which would fail the whole query on the parameter.
*/
export declare function encodeValue(kind: ClickHouseTypeKind, value: unknown, field: string): unknown;
/**
* What an operator compares: an expression, the ClickHouse type its values are bound as, and the
* facts that change an operator's shape.
*/
export interface OperatorTarget {
expr: string;
/** Parameter type for comparisons (the unwrapped base type). */
paramType: string;
kind: ClickHouseTypeKind;
nullable: boolean;
/** The public field name (error messages). */
field: string;
}
export declare function targetOf(field: ResolvedClickHouseField): OperatorTarget;
/**
* Compiles ONE operator over a scalar target into a ClickHouse boolean expression, binding every
* value. Semantics follow the SQL adapters (Postgres as the reference):
*
* - comparisons with NULL are NULL, so negated operators do not match NULL values — including
* `notIn`, which ClickHouse would otherwise answer `1` for a NULL (`transform_null_in = 0`);
* - `contains`/`startsWith`/`endsWith` are case-sensitive, `iContains` is not (UTF-8 aware);
* values are matched literally (`position`, not `LIKE`, so `%`/`_` are not wildcards);
* - `isEmpty` is NULL-or-`''` for strings and NULL elsewhere.
*/
export declare function compileOperator(t: OperatorTarget, filter: ColumnFilter, p: ClickHouseParams): string;
/**
* Compiles an operator over a field, including `Array(T)` fields: positive operators hold when ANY
* element matches (`arrayExists(x -> …, arr)`), negated ones when NO element does; `isEmpty` is
* NULL-or-`[]`. Same semantics as the memory adapter's array fields.
*/
export declare function compileFieldOperator(field: ResolvedClickHouseField, filter: ColumnFilter, p: ClickHouseParams): string;
/**
* Folds `ColumnFilter`s with nested `AND`/`OR` into one expression, with the grouping the other
* adapters use: top-level entries ANDed; a node is `leaf AND (…AND) AND (OR₁ OR OR₂ …)`; a pure
* group node contributes only its children; an unresolvable OR branch is dropped rather than
* widening the group. `leaf` returns `undefined` for a field it cannot resolve.
*/
export declare function compileColumnFilters(filters: ColumnFilter[], leaf: (filter: ColumnFilter) => string | undefined): string | undefined;
/** `(a AND b)`, `a`, or `undefined` for nothing. */
export declare function andAll(parts: string[]): string | undefined;
/** Every field a filter tree references. */
export declare function referencedFields(filters: ColumnFilter[]): Set<string>;
//# sourceMappingURL=sql.d.ts.map