import { Modifier } from "grafast";
import type { SQL } from "pg-sql2";
import type { PgConditionLike, PgSQLCallbackOrDirect } from "../interfaces.ts";
import type { RuntimeEmbeddable } from "../utils.ts";
export type PgWhereConditionSpec<TAttribute extends string, TMoreEmbeds = never> = PgSQLCallbackOrDirect<SQL | PgWhereConditionAttributeSpec<TAttribute>, RuntimeEmbeddable | TMoreEmbeds>;
export interface PgWhereConditionAttributeSpec<TAttribute extends string> {
    type: "attribute";
    attribute: TAttribute;
    callback: (fragment: SQL) => SQL;
}
export type PgHavingConditionSpec<_TAttribute extends string, TMoreEmbeds = never> = PgSQLCallbackOrDirect<SQL, RuntimeEmbeddable | TMoreEmbeds>;
export interface PgConditionCapableParent {
    alias: SQL;
    where(condition: PgWhereConditionSpec<any>): void;
    having?(condition: PgHavingConditionSpec<any>): void;
}
type PgConditionModeExists = {
    mode: "EXISTS";
    tableExpression: SQL;
    alias?: string;
    equals?: boolean;
};
type PgConditionModeRecordExpression = {
    mode: "RECORD_EXPRESSION";
    /**
     * BEWARE: this expression may be _repeated_ multiple times in the generated
     * query, so it should be inexpensive and have no side effects. Intended for
     * use with columns of a composite type, so expression should typically be
     * wrapped in parenthesis, enabling `(my_table.my_column).my_attribute`
     */
    expression: SQL;
};
export type PgConditionResolvedMode = {
    mode: "PASS_THRU";
} | {
    mode: "AND";
} | {
    mode: "OR";
} | {
    mode: "NOT";
} | PgConditionModeExists | PgConditionModeRecordExpression;
export type PgConditionMode = "PASS_THRU" | "AND" | "OR" | "NOT" | PgConditionResolvedMode;
interface PgConditionOptions {
    /** @defaultValue `false` */
    isHaving?: boolean;
    /** @defaultValue `"PASS_THRU"` */
    mode?: PgConditionMode;
}
export declare class PgCondition<TParent extends PgConditionCapableParent = PgConditionCapableParent> extends Modifier<TParent> implements PgConditionCapableParent, PgConditionLike {
    static $$export: {
        moduleName: string;
        exportName: string;
    };
    private conditions;
    private havingConditions;
    private minimumConditionsLength;
    readonly alias: SQL;
    extensions: DataplanPg.PgConditionExtensions;
    readonly resolvedMode: PgConditionResolvedMode;
    private isHaving;
    constructor(parent: TParent, options: PgConditionOptions);
    constructor(parent: TParent, isHaving?: boolean, mode?: PgConditionMode);
    /**
     * Indicates that additional conditions must be added for this filter to take
     * place. Exists specifically so that postgraphile-plugin-connection-filter
     * can return a condition for children to use, but then not actually add that
     * condition if no children add any requirements to it.
     */
    ignoreUnlessAmended(): void;
    /**
     * Manipulating an ancestor may have unintended consequences. Please exercise
     * extreme caution, and think through all possible side effects. In
     * particular, you don't necessarily know what the ancestor is going to be,
     * so it might not be safe to attempt to manipulate it in the way you have
     * planned.
     */
    dangerouslyGetParent(): TParent;
    toStringMeta(): string;
    orPlan(): PgCondition<this>;
    andPlan(): PgCondition<this>;
    notPlan(): PgCondition<this>;
    existsPlan(options: Omit<PgConditionModeExists, "mode">): PgCondition<this>;
    where(condition: PgWhereConditionSpec<any>): void;
    having(condition: PgHavingConditionSpec<any>): void;
    private transform;
    apply(): void;
}
export declare function pgWhereConditionSpecListToSQL(alias: SQL, conditions: PgWhereConditionSpec<any>[], andOr?: "and" | "or", transform?: (frag: SQL) => SQL): SQL | null;
export {};
//# sourceMappingURL=pgCondition.d.ts.map