import type { JSONValue } from '../../../shared/src/json.ts';
import type { AST, Condition, Disjunction, Ordering } from '../../../zero-protocol/src/ast.ts';
import type { Row } from '../../../zero-protocol/src/data.ts';
import type { PrimaryKey } from '../../../zero-protocol/src/primary-key.ts';
import { type FilterInput } from '../ivm/filter-operators.ts';
import type { Input, InputBase, Storage } from '../ivm/operator.ts';
import type { Source, SourceInput } from '../ivm/source.ts';
import type { DebugDelegate } from './debug-delegate.ts';
import { type NoSubqueryCondition } from './filter.ts';
export type StaticQueryParameters = {
    authData: Record<string, JSONValue>;
    preMutationRow?: Row | undefined;
};
/**
 * Interface required of caller to buildPipeline. Connects to constructed
 * pipeline to delegate environment to provide sources and storage.
 */
export interface BuilderDelegate {
    readonly applyFiltersAnyway?: boolean | undefined;
    readonly debug?: DebugDelegate | undefined;
    /**
     * When true, allows NOT EXISTS conditions in queries.
     * Defaults to false.
     *
     * We only set this to true on the server.
     * The client-side query engine cannot support NOT EXISTS because:
     * 1. Zero only syncs a subset of data to the client
     * 2. On the client, we can't distinguish between a row not existing vs.
     *    a row not being synced to the client
     * 3. NOT EXISTS requires complete knowledge of what doesn't exist
     */
    readonly enableNotExists?: boolean | undefined;
    /**
     * Called once for each source needed by the AST.
     * Might be called multiple times with same tableName. It is OK to return
     * same storage instance in that case.
     */
    getSource(tableName: string): Source | undefined;
    /**
     * Called once for each operator that requires storage. Should return a new
     * unique storage object for each call.
     */
    createStorage(name: string): Storage;
    decorateInput(input: Input, name: string): Input;
    addEdge(source: InputBase, dest: InputBase): void;
    decorateFilterInput(input: FilterInput, name: string): FilterInput;
    decorateSourceInput(input: SourceInput, queryID: string): Input;
    /**
     * The AST is mapped on-the-wire between client and server names.
     *
     * There is no "wire" for zqlite tests so this function is provided
     * to allow tests to remap the AST.
     */
    mapAst?: ((ast: AST) => AST) | undefined;
}
/**
 * Builds a pipeline from an AST. Caller must provide a delegate to create source
 * and storage interfaces as necessary.
 *
 * Usage:
 *
 * ```ts
 * class MySink implements Output {
 *   readonly #input: Input;
 *
 *   constructor(input: Input) {
 *     this.#input = input;
 *     input.setOutput(this);
 *   }
 *
 *   push(change: Change, _: Operator) {
 *     console.log(change);
 *   }
 * }
 *
 * const input = buildPipeline(ast, myDelegate, hash(ast));
 * const sink = new MySink(input);
 * ```
 */
export declare function buildPipeline(ast: AST, delegate: BuilderDelegate, queryID: string): Input;
export declare function bindStaticParameters(ast: AST, staticQueryParameters: StaticQueryParameters | undefined): AST;
export declare function applyOr(input: FilterInput, condition: Disjunction, delegate: BuilderDelegate, name: string): FilterInput;
export declare function groupSubqueryConditions(condition: Disjunction): [subqueryConditions: Condition[], otherConditions: NoSubqueryCondition[]];
export declare function isNotAndDoesNotContainSubquery(condition: Condition): condition is NoSubqueryCondition;
export declare function assertOrderingIncludesPK(ordering: Ordering, pk: PrimaryKey): void;
export declare function conditionIncludesFlippedSubqueryAtAnyLevel(cond: Condition): boolean;
export declare function partitionBranches(conditions: readonly Condition[], predicate: (c: Condition) => boolean): readonly [Condition[], Condition[]];
//# sourceMappingURL=builder.d.ts.map