/**
 * Wire-format representation of the zql AST interface.
 *
 * `v.Type<...>` types are explicitly declared to facilitate Typescript verification
 * that the schemas satisfy the zql type definitions. (Incidentally, explicit types
 * are also required for recursive schema definitions.)
 */
import * as v from '../../shared/src/valita.ts';
import type { NameMapper } from '../../zero-types/src/name-mapper.ts';
import { type Row } from './data.ts';
export declare const SUBQ_PREFIX = "zsubq_";
export declare const selectorSchema: v.Type<string>;
export declare const toStaticParam: unique symbol;
export declare const orderingSchema: v.Type<readonly (readonly [string, "asc" | "desc"])[]>;
export type System = 'permissions' | 'client' | 'test';
export declare const primitiveSchema: v.UnionType<[v.Type<string>, v.Type<number>, v.Type<boolean>, v.Type<null>]>;
export declare const equalityOpsSchema: v.Type<"=" | "!=" | "IS" | "IS NOT">;
export declare const orderOpsSchema: v.Type<"<" | ">" | "<=" | ">=">;
export declare const likeOpsSchema: v.Type<"LIKE" | "NOT LIKE" | "ILIKE" | "NOT ILIKE">;
export declare const inOpsSchema: v.Type<"IN" | "NOT IN">;
export declare const simpleOperatorSchema: v.UnionType<[v.Type<"=" | "!=" | "IS" | "IS NOT">, v.Type<"<" | ">" | "<=" | ">=">, v.Type<"LIKE" | "NOT LIKE" | "ILIKE" | "NOT ILIKE">, v.Type<"IN" | "NOT IN">]>;
/**
 * A parameter is a value that is not known at the time the query is written
 * and is resolved at runtime.
 *
 * Static parameters refer to something provided by the caller.
 * Static parameters are injected when the query pipeline is built from the AST
 * and do not change for the life of that pipeline.
 *
 * An example static parameter is the current authentication data.
 * When a user is authenticated, queries on the server have access
 * to the user's authentication data in order to evaluate authorization rules.
 * Authentication data doesn't change over the life of a query as a change
 * in auth data would represent a log-in / log-out of the user.
 *
 * AncestorParameters refer to rows encountered while running the query.
 * They are used by subqueries to refer to rows emitted by parent queries.
 */
declare const parameterReferenceSchema: v.ObjectType<Readonly<{
    type: v.Type<"static">;
    anchor: v.Type<"authData" | "preMutationRow">;
    field: v.UnionType<[v.Type<string>, v.ArrayType<v.Type<string>>]>;
}>, undefined>;
export type Parameter = v.Infer<typeof parameterReferenceSchema>;
export declare const simpleConditionSchema: v.Type<SimpleCondition>;
export declare const correlatedSubqueryConditionOperatorSchema: v.Type<CorrelatedSubqueryConditionOperator>;
export declare const correlatedSubqueryConditionSchema: v.Type<CorrelatedSubqueryCondition>;
export declare const conditionSchema: v.Type<Condition>;
export type CompoundKey = readonly [string, ...string[]];
export declare const compoundKeySchema: v.Type<CompoundKey>;
export declare const correlatedSubquerySchemaOmitSubquery: v.ObjectType<Readonly<{
    correlation: v.ObjectType<Readonly<{
        parentField: v.Type<CompoundKey>;
        childField: v.Type<CompoundKey>;
    }>, undefined>;
    hidden: v.Optional<boolean>;
    system: v.Optional<"client" | "permissions" | "test">;
}>, undefined>;
export declare const correlatedSubquerySchema: v.Type<CorrelatedSubquery>;
export declare const astSchema: v.Type<AST>;
export type Bound = {
    row: Row;
    exclusive: boolean;
};
/**
 * As in SQL you can have multiple orderings. We don't currently
 * support ordering on anything other than the root query.
 */
export type OrderPart = readonly [field: string, direction: 'asc' | 'desc'];
export type Ordering = readonly OrderPart[];
export type SimpleOperator = EqualityOps | OrderOps | LikeOps | InOps;
export type EqualityOps = '=' | '!=' | 'IS' | 'IS NOT';
export type OrderOps = '<' | '>' | '<=' | '>=';
export type LikeOps = 'LIKE' | 'NOT LIKE' | 'ILIKE' | 'NOT ILIKE';
export type InOps = 'IN' | 'NOT IN';
export type AST = {
    readonly schema?: string | undefined;
    readonly table: string;
    readonly alias?: string | undefined;
    readonly where?: Condition | undefined;
    readonly related?: readonly CorrelatedSubquery[] | undefined;
    readonly start?: Bound | undefined;
    readonly limit?: number | undefined;
    readonly orderBy?: Ordering | undefined;
};
export type Correlation = {
    readonly parentField: CompoundKey;
    readonly childField: CompoundKey;
};
export type CorrelatedSubquery = {
    /**
     * Only equality correlation are supported for now.
     * E.g., direct foreign key relationships.
     */
    readonly correlation: Correlation;
    readonly subquery: AST;
    readonly system?: System | undefined;
    readonly hidden?: boolean | undefined;
};
export type ValuePosition = LiteralReference | Parameter | ColumnReference;
export type ColumnReference = {
    readonly type: 'column';
    /**
     * Not a path yet as we're currently not allowing
     * comparisons across tables. This will need to
     * be a path through the tree in the near future.
     */
    readonly name: string;
};
export type LiteralReference = {
    readonly type: 'literal';
    readonly value: LiteralValue;
};
export type LiteralValue = string | number | boolean | null | ReadonlyArray<string | number | boolean>;
/**
 * Starting only with SimpleCondition for now.
 * ivm1 supports Conjunctions and Disjunctions.
 * We'll support them in the future.
 */
export type Condition = SimpleCondition | Conjunction | Disjunction | CorrelatedSubqueryCondition;
export type SimpleCondition = {
    readonly type: 'simple';
    readonly op: SimpleOperator;
    readonly left: ValuePosition;
    /**
     * `null` is absent since we do not have an `IS` or `IS NOT`
     * operator defined and `null != null` in SQL.
     */
    readonly right: Exclude<ValuePosition, ColumnReference>;
};
export type Conjunction = {
    type: 'and';
    conditions: readonly Condition[];
};
export type Disjunction = {
    type: 'or';
    conditions: readonly Condition[];
};
export type CorrelatedSubqueryCondition = {
    type: 'correlatedSubquery';
    related: CorrelatedSubquery;
    op: CorrelatedSubqueryConditionOperator;
    flip?: boolean | undefined;
};
export type CorrelatedSubqueryConditionOperator = 'EXISTS' | 'NOT EXISTS';
export declare function normalizeAST(ast: AST): Required<AST>;
export declare function mapAST(ast: AST, mapper: NameMapper): Required<AST>;
export declare function mapCondition(cond: Condition, table: string, mapper: NameMapper): Condition;
export {};
//# sourceMappingURL=ast.d.ts.map