import { type SelectQueryBuilder } from '../query-builder/select-query-builder.js';
import { type TableExpressionOrList } from '../parser/table-parser.js';
import { type FunctionModule } from '../query-builder/function-module.js';
import { type ExtractTypeFromReferenceExpression, type ReferenceExpression, type SimpleReferenceExpression, type StringReference } from '../parser/reference-parser.js';
import type { QueryExecutor } from '../query-executor/query-executor.js';
import { type BinaryOperatorExpression, type FilterObject, type OperandValueExpression, type OperandValueExpressionOrList } from '../parser/binary-operation-parser.js';
import type { Expression } from './expression.js';
import { ExpressionWrapper } from './expression-wrapper.js';
import { type ComparisonOperator, type JSONOperatorWith$, type UnaryOperator } from '../operation-node/operator-node.js';
import type { IsNever, SqlBool } from '../util/type-utils.js';
import { type ExtractTypeFromValueExpression } from '../parser/value-parser.js';
import { CaseBuilder } from '../query-builder/case-builder.js';
import { JSONPathBuilder } from '../query-builder/json-path-builder.js';
import type { OperandExpression } from '../parser/expression-parser.js';
import type { RefTuple2, RefTuple3, RefTuple4, RefTuple5, ValTuple2, ValTuple3, ValTuple4, ValTuple5 } from '../parser/tuple-parser.js';
import type { Selectable } from '../util/column-type.js';
import type { KyselyTypeError } from '../util/type-error.js';
import { type DataTypeExpression } from '../parser/data-type-parser.js';
import type { SelectFrom } from '../parser/select-from-parser.js';
export interface ExpressionBuilder<DB, TB extends keyof DB> {
    /**
     * Creates a binary expression.
     *
     * This function returns an {@link Expression} and can be used pretty much anywhere.
     * See the examples for a couple of possible use cases.
     *
     * ### Examples
     *
     * A simple comparison:
     *
     * ```ts
     * const result = await db.selectFrom('person')
     *   .selectAll()
     *   .where((eb) => eb('first_name', '=', 'Jennifer'))
     *   .execute()
     * ```
     *
     * The generated SQL (PostgreSQL):
     *
     * ```sql
     * select *
     * from "person"
     * where "first_name" = $1
     * ```
     *
     * By default the third argument is interpreted as a value. To pass in
     * a column reference, you can use {@link ref}:
     *
     * ```ts
     * const result = await db.selectFrom('person')
     *   .selectAll()
     *   .where((eb) => eb('first_name', '=', eb.ref('last_name')))
     *   .execute()
     * ```
     *
     * The generated SQL (PostgreSQL):
     *
     * ```sql
     * select *
     * from "person"
     * where "first_name" = "last_name"
     * ```
     *
     * In the following example `eb` is used to increment an integer column:
     *
     * ```ts
     * await db.updateTable('person')
     *   .set((eb) => ({
     *     age: eb('age', '+', 1)
     *   }))
     *   .where('id', '=', 3)
     *   .execute()
     * ```
     *
     * The generated SQL (PostgreSQL):
     *
     * ```sql
     * update "person"
     * set "age" = "age" + $1
     * where "id" = $2
     * ```
     *
     * As always, expressions can be nested. Both the first and the third argument
     * can be any expression:
     *
     * ```ts
     * const result = await db.selectFrom('person')
     *   .selectAll()
     *   .where((eb) => eb(
     *     eb.fn<string>('lower', ['first_name']),
     *     'in',
     *     eb.selectFrom('pet')
     *       .select('pet.name')
     *       .where('pet.species', '=', 'cat')
     *   ))
     *   .execute()
     * ```
     *
     * The generated SQL (PostgreSQL):
     *
     * ```sql
     * select *
     * from "person"
     * where lower("first_name") in (
     *   select "pet"."name"
     *   from "pet"
     *   where "pet"."species" = $1
     * )
     * ```
     */
    <RE extends ReferenceExpression<DB, TB>, OP extends BinaryOperatorExpression, VE extends OperandValueExpressionOrList<DB, TB, RE>>(lhs: RE, op: OP, rhs: VE): ExpressionWrapper<DB, TB, OP extends ComparisonOperator ? SqlBool : OP extends Expression<infer T> ? unknown extends T ? SqlBool : T : ExtractTypeFromReferenceExpression<DB, TB, RE>>;
    /**
     * Returns a copy of `this` expression builder, for destructuring purposes.
     *
     * ### Examples
     *
     * ```ts
     * const result = await db.selectFrom('person')
     *   .where(({ eb, exists, selectFrom }) =>
     *     eb('first_name', '=', 'Jennifer').and(exists(
     *       selectFrom('pet').whereRef('owner_id', '=', 'person.id').select('pet.id')
     *     ))
     *   )
     *   .selectAll()
     *   .execute()
     * ```
     *
     * The generated SQL (PostgreSQL):
     *
     * ```sql
     * select * from "person" where "first_name" = $1 and exists (
     *   select "pet.id" from "pet" where "owner_id" = "person.id"
     * )
     * ```
     */
    get eb(): ExpressionBuilder<DB, TB>;
    /**
     * Returns a {@link FunctionModule} that can be used to write type safe function
     * calls.
     *
     * The difference between this and {@link Kysely.fn} is that this one is more
     * type safe. You can only refer to columns visible to the part of the query
     * you are building. {@link Kysely.fn} allows you to refer to columns in any
     * table of the database even if it doesn't produce valid SQL.
     *
     * ```ts
     * const result = await db.selectFrom('person')
     *   .innerJoin('pet', 'pet.owner_id', 'person.id')
     *   .select((eb) => [
     *     'person.id',
     *     eb.fn.count('pet.id').as('pet_count')
     *   ])
     *   .groupBy('person.id')
     *   .having((eb) => eb.fn.count('pet.id'), '>', 10)
     *   .execute()
     * ```
     *
     * The generated SQL (PostgreSQL):
     *
     * ```sql
     * select "person"."id", count("pet"."id") as "pet_count"
     * from "person"
     * inner join "pet" on "pet"."owner_id" = "person"."id"
     * group by "person"."id"
     * having count("pet"."id") > $1
     * ```
     */
    get fn(): FunctionModule<DB, TB>;
    /**
     * Creates a subquery.
     *
     * The query builder returned by this method is typed in a way that you can refer to
     * all tables of the parent query in addition to the subquery's tables.
     *
     * This method accepts all the same inputs as {@link QueryCreator.selectFrom}.
     *
     * ### Examples
     *
     * This example shows that you can refer to both `pet.owner_id` and `person.id`
     * columns from the subquery. This is needed to be able to create correlated
     * subqueries:
     *
     * ```ts
     * const result = await db.selectFrom('pet')
     *   .select((eb) => [
     *     'pet.name',
     *     eb.selectFrom('person')
     *       .whereRef('person.id', '=', 'pet.owner_id')
     *       .select('person.first_name')
     *       .as('owner_name')
     *   ])
     *   .execute()
     *
     * console.log(result[0]?.owner_name)
     * ```
     *
     * The generated SQL (PostgreSQL):
     *
     * ```sql
     * select
     *   "pet"."name",
     *   ( select "person"."first_name"
     *     from "person"
     *     where "person"."id" = "pet"."owner_id"
     *   ) as "owner_name"
     * from "pet"
     * ```
     *
     * You can use a normal query in place of `(qb) => qb.selectFrom(...)` but in
     * that case Kysely typings wouldn't allow you to reference `pet.owner_id`
     * because `pet` is not joined to that query.
     */
    selectFrom<TE extends TableExpressionOrList<DB, TB>>(from: TE): SelectFrom<DB, TB, TE>;
    /**
     * Creates a `case` statement/operator.
     *
     * ### Examples
     *
     * Kitchen sink example with 2 flavors of `case` operator:
     *
     * ```ts
     * const { title, name } = await db
     *   .selectFrom('person')
     *   .where('id', '=', 123)
     *   .select((eb) => [
     *     eb.fn.coalesce('last_name', 'first_name').as('name'),
     *     eb
     *       .case()
     *       .when('gender', '=', 'male')
     *       .then('Mr.')
     *       .when('gender', '=', 'female')
     *       .then(
     *         eb
     *           .case('marital_status')
     *           .when('single')
     *           .then('Ms.')
     *           .else('Mrs.')
     *           .end()
     *       )
     *       .end()
     *       .as('title'),
     *   ])
     *   .executeTakeFirstOrThrow()
     * ```
     *
     * The generated SQL (PostgreSQL):
     *
     * ```sql
     * select
     *   coalesce("last_name", "first_name") as "name",
     *   case
     *     when "gender" = $1 then $2
     *     when "gender" = $3 then
     *       case "marital_status"
     *         when $4 then $5
     *         else $6
     *       end
     *   end as "title"
     * from "person"
     * where "id" = $7
     * ```
     */
    case(): CaseBuilder<DB, TB>;
    case<C extends SimpleReferenceExpression<DB, TB>>(column: C): CaseBuilder<DB, TB, ExtractTypeFromReferenceExpression<DB, TB, C>>;
    case<E extends Expression<any>>(expression: E): CaseBuilder<DB, TB, ExtractTypeFromValueExpression<E>>;
    /**
     * This method can be used to reference columns within the query's context. For
     * a non-type-safe version of this method see {@link sql}'s version.
     *
     * Additionally, this method can be used to reference nested JSON properties or
     * array elements. See {@link JSONPathBuilder} for more information. For regular
     * JSON path expressions you can use {@link jsonPath}.
     *
     * ### Examples
     *
     * By default the third argument of binary expressions is a value.
     * This function can be used to pass in a column reference instead:
     *
     * ```ts
     * const result = await db.selectFrom('person')
     *   .selectAll('person')
     *   .where((eb) => eb.or([
     *     eb('first_name', '=', eb.ref('last_name')),
     *     eb('first_name', '=', eb.ref('middle_name'))
     *   ]))
     *   .execute()
     * ```
     *
     * The generated SQL (PostgreSQL):
     *
     * ```sql
     * select "person".*
     * from "person"
     * where "first_name" = "last_name" or "first_name" = "middle_name"
     * ```
     *
     * In the next example we use the `ref` method to reference columns of the virtual
     * table `excluded` in a type-safe way to create an upsert operation:
     *
     * ```ts
     * await db.insertInto('person')
     *   .values({
     *     id: 3,
     *     first_name: 'Jennifer',
     *     last_name: 'Aniston',
     *     gender: 'female',
     *   })
     *   .onConflict((oc) => oc
     *     .column('id')
     *     .doUpdateSet(({ ref }) => ({
     *       first_name: ref('excluded.first_name'),
     *       last_name: ref('excluded.last_name'),
     *       gender: ref('excluded.gender'),
     *     }))
     *   )
     *   .execute()
     * ```
     *
     * The generated SQL (PostgreSQL):
     *
     * ```sql
     * insert into "person" ("id", "first_name", "last_name", "gender")
     * values ($1, $2, $3, $4)
     * on conflict ("id") do update set
     *   "first_name" = "excluded"."first_name",
     *   "last_name" = "excluded"."last_name",
     *   "gender" = "excluded"."gender"
     * ```
     *
     * In the next example we use `ref` in a raw sql expression. Unless you want
     * to be as type-safe as possible, this is probably overkill:
     *
     * ```ts
     * import { sql } from 'kysely'
     *
     * await db.updateTable('pet')
     *   .set((eb) => ({
     *     name: sql<string>`concat(${eb.ref('pet.name')}, ${' the animal'})`
     *   }))
     *   .execute()
     * ```
     *
     * The generated SQL (PostgreSQL):
     *
     * ```sql
     * update "pet" set "name" = concat("pet"."name", $1)
     * ```
     *
     * In the next example we use `ref` to reference a nested JSON property:
     *
     * ```ts
     * const result = await db.selectFrom('person')
     *   .where(({ eb, ref }) => eb(
     *     ref('profile', '->').key('addresses').at(0).key('city'),
     *     '=',
     *     'San Diego'
     *   ))
     *   .selectAll()
     *   .execute()
     * ```
     *
     * The generated SQL (PostgreSQL):
     *
     * ```sql
     * select * from "person" where "profile"->'addresses'->0->'city' = $1
     * ```
     *
     * You can also compile to a JSON path expression by using the `->$`or `->>$` operator:
     *
     * ```ts
     * const result = await db.selectFrom('person')
     *   .select(({ ref }) =>
     *     ref('profile', '->$')
     *       .key('addresses')
     *       .at('last')
     *       .key('city')
     *       .as('current_city')
     *   )
     *   .execute()
     * ```
     *
     * The generated SQL (MySQL):
     *
     * ```sql
     * select `profile`->'$.addresses[last].city' as `current_city` from `person`
     * ```
     */
    ref<RE extends StringReference<DB, TB>>(reference: RE): ExpressionWrapper<DB, TB, ExtractTypeFromReferenceExpression<DB, TB, RE>>;
    ref<RE extends StringReference<DB, TB>>(reference: RE, op: JSONOperatorWith$): JSONPathBuilder<ExtractTypeFromReferenceExpression<DB, TB, RE>>;
    /**
     * Creates a JSON path expression with provided column as root document (the $).
     *
     * For a JSON reference expression, see {@link ref}.
     *
     * ### Examples
     *
     * ```ts
     * await db.updateTable('person')
     *   .set('profile', (eb) => eb.fn('json_set', [
     *     'profile',
     *     eb.jsonPath<'profile'>().key('addresses').at('last').key('city'),
     *     eb.val('San Diego')
     *   ]))
     *   .where('id', '=', 3)
     *   .execute()
     * ```
     *
     * The generated SQL (MySQL):
     *
     * ```sql
     * update `person`
     * set `profile` = json_set(`profile`, '$.addresses[last].city', $1)
     * where `id` = $2
     * ```
     */
    jsonPath<$ extends StringReference<DB, TB> = never>(): IsNever<$> extends true ? KyselyTypeError<"You must provide a column reference as this method's $ generic"> : JSONPathBuilder<ExtractTypeFromReferenceExpression<DB, TB, $>>;
    /**
     * Creates a table reference.
     *
     * ### Examples
     *
     * ```ts
     * import { sql } from 'kysely'
     * import type { Pet } from 'type-editor' // imaginary module
     *
     * const result = await db.selectFrom('person')
     *   .innerJoin('pet', 'pet.owner_id', 'person.id')
     *   .select(eb => [
     *     'person.id',
     *     sql<Pet[]>`jsonb_agg(${eb.table('pet')})`.as('pets')
     *   ])
     *   .groupBy('person.id')
     *   .execute()
     * ```
     *
     * The generated SQL (PostgreSQL):
     *
     * ```sql
     * select "person"."id", jsonb_agg("pet") as "pets"
     * from "person"
     * inner join "pet" on "pet"."owner_id" = "person"."id"
     * group by "person"."id"
     * ```
     *
     * If you need a column reference, use {@link ref}.
     */
    table<T extends TB & string>(table: T): ExpressionWrapper<DB, TB, Selectable<DB[T]>>;
    /**
     * Returns a value expression.
     *
     * This can be used to pass in a value where a reference is taken by default.
     *
     * This function returns an {@link Expression} and can be used pretty much anywhere.
     *
     * ### Examples
     *
     * Binary expressions take a reference by default as the first argument. `val` could
     * be used to pass in a value instead:
     *
     * ```ts
     * const result = await db.selectFrom('person')
     *   .selectAll()
     *   .where((eb) => eb(
     *     eb.val('cat'),
     *     '=',
     *     eb.fn.any(
     *       eb.selectFrom('pet')
     *         .select('species')
     *         .whereRef('owner_id', '=', 'person.id')
     *     )
     *   ))
     *   .execute()
     * ```
     *
     * The generated SQL (PostgreSQL):
     *
     * ```sql
     * select *
     * from "person"
     * where $1 = any(
     *   select "species"
     *   from "pet"
     *   where "owner_id" = "person"."id"
     * )
     * ```
     */
    val<VE>(value: VE): ExpressionWrapper<DB, TB, ExtractTypeFromValueExpression<VE>>;
    /**
     * Creates a tuple expression.
     *
     * This creates a tuple using column references by default. See {@link tuple}
     * if you need to create value tuples.
     *
     * ### Examples
     *
     * ```ts
     * const result = await db.selectFrom('person')
     *   .selectAll('person')
     *   .where(({ eb, refTuple, tuple }) => eb(
     *     refTuple('first_name', 'last_name'),
     *     'in',
     *     [
     *       tuple('Jennifer', 'Aniston'),
     *       tuple('Sylvester', 'Stallone')
     *     ]
     *   ))
     *   .execute()
     * ```
     *
     * The generated SQL (PostgreSQL):
     *
     * ```sql
     * select
     *   "person".*
     * from
     *   "person"
     * where
     *   ("first_name", "last_name")
     *   in
     *   (
     *     ($1, $2),
     *     ($3, $4)
     *   )
     * ```
     *
     * In the next example a reference tuple is compared to a subquery. Note that
     * in this case you need to use the {@link @SelectQueryBuilder.$asTuple | $asTuple}
     * function:
     *
     * ```ts
     * const result = await db.selectFrom('person')
     *   .selectAll('person')
     *   .where(({ eb, refTuple, selectFrom }) => eb(
     *     refTuple('first_name', 'last_name'),
     *     'in',
     *     selectFrom('pet')
     *       .select(['name', 'species'])
     *       .where('species', '!=', 'cat')
     *       .$asTuple('name', 'species')
     *   ))
     *   .execute()
     * ```
     *
     * The generated SQL (PostgreSQL):
     *
     * ```sql
     * select
     *   "person".*
     * from
     *   "person"
     * where
     *   ("first_name", "last_name")
     *   in
     *   (
     *     select "name", "species"
     *     from "pet"
     *     where "species" != $1
     *   )
     * ```
     */
    refTuple<R1 extends ReferenceExpression<DB, TB>, R2 extends ReferenceExpression<DB, TB>>(value1: R1, value2: R2): ExpressionWrapper<DB, TB, RefTuple2<DB, TB, R1, R2>>;
    refTuple<R1 extends ReferenceExpression<DB, TB>, R2 extends ReferenceExpression<DB, TB>, R3 extends ReferenceExpression<DB, TB>>(value1: R1, value2: R2, value3: R3): ExpressionWrapper<DB, TB, RefTuple3<DB, TB, R1, R2, R3>>;
    refTuple<R1 extends ReferenceExpression<DB, TB>, R2 extends ReferenceExpression<DB, TB>, R3 extends ReferenceExpression<DB, TB>, R4 extends ReferenceExpression<DB, TB>>(value1: R1, value2: R2, value3: R3, value4: R4): ExpressionWrapper<DB, TB, RefTuple4<DB, TB, R1, R2, R3, R4>>;
    refTuple<R1 extends ReferenceExpression<DB, TB>, R2 extends ReferenceExpression<DB, TB>, R3 extends ReferenceExpression<DB, TB>, R4 extends ReferenceExpression<DB, TB>, R5 extends ReferenceExpression<DB, TB>>(value1: R1, value2: R2, value3: R3, value4: R4, value5: R5): ExpressionWrapper<DB, TB, RefTuple5<DB, TB, R1, R2, R3, R4, R5>>;
    /**
     * Creates a value tuple expression.
     *
     * This creates a tuple using values by default. See {@link refTuple} if you need to create
     * tuples using column references.
     *
     * ### Examples
     *
     * ```ts
     * const result = await db.selectFrom('person')
     *   .selectAll('person')
     *   .where(({ eb, refTuple, tuple }) => eb(
     *     refTuple('first_name', 'last_name'),
     *     'in',
     *     [
     *       tuple('Jennifer', 'Aniston'),
     *       tuple('Sylvester', 'Stallone')
     *     ]
     *   ))
     *   .execute()
     * ```
     *
     * The generated SQL (PostgreSQL):
     *
     * ```sql
     * select
     *   "person".*
     * from
     *   "person"
     * where
     *   ("first_name", "last_name")
     *   in
     *   (
     *     ($1, $2),
     *     ($3, $4)
     *   )
     * ```
     */
    tuple<V1, V2>(value1: V1, value2: V2): ExpressionWrapper<DB, TB, ValTuple2<V1, V2>>;
    tuple<V1, V2, V3>(value1: V1, value2: V2, value3: V3): ExpressionWrapper<DB, TB, ValTuple3<V1, V2, V3>>;
    tuple<V1, V2, V3, V4>(value1: V1, value2: V2, value3: V3, value4: V4): ExpressionWrapper<DB, TB, ValTuple4<V1, V2, V3, V4>>;
    tuple<V1, V2, V3, V4, V5>(value1: V1, value2: V2, value3: V3, value4: V4, value5: V5): ExpressionWrapper<DB, TB, ValTuple5<V1, V2, V3, V4, V5>>;
    /**
     * Returns a literal value expression.
     *
     * Just like `val` but creates a literal value that gets merged in the SQL.
     * To prevent SQL injections, only `boolean`, `number` and `null` values
     * are accepted. If you need `string` or other literals, use `sql.lit` instead.
     *
     * ### Examples
     *
     * ```ts
     * const result = await db.selectFrom('person')
     *   .select((eb) => eb.lit(1).as('one'))
     *   .execute()
     * ```
     *
     * The generated SQL (PostgreSQL):
     *
     * ```sql
     * select 1 as "one" from "person"
     * ```
     */
    lit<VE extends number | boolean | null>(literal: VE): ExpressionWrapper<DB, TB, VE>;
    /**
     * Creates an unary expression.
     *
     * This function returns an {@link Expression} and can be used pretty much anywhere.
     * See the examples for a couple of possible use cases.
     *
     * @see {@link not}, {@link exists} and {@link neg}.
     *
     * ### Examples
     *
     * ```ts
     * const result = await db.selectFrom('person')
     *   .select((eb) => [
     *     'first_name',
     *     eb.unary('-', 'age').as('negative_age')
     *   ])
     *   .execute()
     * ```
     *
     * The generated SQL (PostgreSQL):
     *
     * ```sql
     * select "first_name", -"age"
     * from "person"
     * ```
     */
    unary<RE extends ReferenceExpression<DB, TB>>(op: UnaryOperator, expr: RE): ExpressionWrapper<DB, TB, ExtractTypeFromReferenceExpression<DB, TB, RE>>;
    /**
     * Creates a `not` operation.
     *
     * A shortcut for `unary('not', expr)`.
     *
     * @see {@link unary}
     */
    not<RE extends ReferenceExpression<DB, TB>>(expr: RE): ExpressionWrapper<DB, TB, ExtractTypeFromReferenceExpression<DB, TB, RE>>;
    /**
     * Creates an `exists` operation.
     *
     * A shortcut for `unary('exists', expr)`.
     *
     * @see {@link unary}
     */
    exists<RE extends ReferenceExpression<DB, TB>>(expr: RE): ExpressionWrapper<DB, TB, SqlBool>;
    /**
     * Creates a negation operation.
     *
     * A shortcut for `unary('-', expr)`.
     *
     * @see {@link unary}
     */
    neg<RE extends ReferenceExpression<DB, TB>>(expr: RE): ExpressionWrapper<DB, TB, ExtractTypeFromReferenceExpression<DB, TB, RE>>;
    /**
     * Creates a `between` expression.
     *
     * ### Examples
     *
     * ```ts
     * const result = await db.selectFrom('person')
     *   .selectAll()
     *   .where((eb) => eb.between('age', 40, 60))
     *   .execute()
     * ```
     *
     * The generated SQL (PostgreSQL):
     *
     * ```sql
     * select * from "person" where "age" between $1 and $2
     * ```
     */
    between<RE extends ReferenceExpression<DB, TB>, SE extends OperandValueExpression<DB, TB, RE>, EE extends OperandValueExpression<DB, TB, RE>>(expr: RE, start: SE, end: EE): ExpressionWrapper<DB, TB, SqlBool>;
    /**
     * Creates a `between symmetric` expression.
     *
     * ### Examples
     *
     * ```ts
     * const result = await db.selectFrom('person')
     *   .selectAll()
     *   .where((eb) => eb.betweenSymmetric('age', 40, 60))
     *   .execute()
     * ```
     *
     * The generated SQL (PostgreSQL):
     *
     * ```sql
     * select * from "person" where "age" between symmetric $1 and $2
     * ```
     */
    betweenSymmetric<RE extends ReferenceExpression<DB, TB>, SE extends OperandValueExpression<DB, TB, RE>, EE extends OperandValueExpression<DB, TB, RE>>(expr: RE, start: SE, end: EE): ExpressionWrapper<DB, TB, SqlBool>;
    /**
     * Combines two or more expressions using the logical `and` operator.
     *
     * An empty array produces a `true` expression.
     *
     * This function returns an {@link Expression} and can be used pretty much anywhere.
     * See the examples for a couple of possible use cases.
     *
     * ### Examples
     *
     * In this example we use `and` to create a `WHERE expr1 AND expr2 AND expr3`
     * statement:
     *
     * ```ts
     * const result = await db.selectFrom('person')
     *   .selectAll('person')
     *   .where((eb) => eb.and([
     *     eb('first_name', '=', 'Jennifer'),
     *     eb('first_name', '=', 'Arnold'),
     *     eb('first_name', '=', 'Sylvester')
     *   ]))
     *   .execute()
     * ```
     *
     * The generated SQL (PostgreSQL):
     *
     * ```sql
     * select "person".*
     * from "person"
     * where (
     *   "first_name" = $1
     *   and "first_name" = $2
     *   and "first_name" = $3
     * )
     * ```
     *
     * Optionally you can use the simpler object notation if you only need
     * equality comparisons:
     *
     * ```ts
     * const result = await db.selectFrom('person')
     *   .selectAll('person')
     *   .where((eb) => eb.and({
     *     first_name: 'Jennifer',
     *     last_name: 'Aniston'
     *   }))
     *   .execute()
     * ```
     *
     * The generated SQL (PostgreSQL):
     *
     * ```sql
     * select "person".*
     * from "person"
     * where (
     *   "first_name" = $1
     *   and "last_name" = $2
     * )
     * ```
     */
    and<E extends OperandExpression<SqlBool>>(exprs: ReadonlyArray<E>): ExpressionWrapper<DB, TB, SqlBool>;
    and<E extends Readonly<FilterObject<DB, TB>>>(exprs: E): ExpressionWrapper<DB, TB, SqlBool>;
    /**
     * Combines two or more expressions using the logical `or` operator.
     *
     * An empty array produces a `false` expression.
     *
     * This function returns an {@link Expression} and can be used pretty much anywhere.
     * See the examples for a couple of possible use cases.
     *
     * ### Examples
     *
     * In this example we use `or` to create a `WHERE expr1 OR expr2 OR expr3`
     * statement:
     *
     * ```ts
     * const result = await db.selectFrom('person')
     *   .selectAll('person')
     *   .where((eb) => eb.or([
     *     eb('first_name', '=', 'Jennifer'),
     *     eb('first_name', '=', 'Arnold'),
     *     eb('first_name', '=', 'Sylvester')
     *   ]))
     *   .execute()
     * ```
     *
     * The generated SQL (PostgreSQL):
     *
     * ```sql
     * select "person".*
     * from "person"
     * where (
     *   "first_name" = $1
     *   or "first_name" = $2
     *   or "first_name" = $3
     * )
     * ```
     *
     * Optionally you can use the simpler object notation if you only need
     * equality comparisons:
     *
     * ```ts
     * const result = await db.selectFrom('person')
     *   .selectAll('person')
     *   .where((eb) => eb.or({
     *     first_name: 'Jennifer',
     *     last_name: 'Aniston'
     *   }))
     *   .execute()
     * ```
     *
     * The generated SQL (PostgreSQL):
     *
     * ```sql
     * select "person".*
     * from "person"
     * where (
     *   "first_name" = $1
     *   or "last_name" = $2
     * )
     * ```
     */
    or<E extends OperandExpression<SqlBool>>(exprs: ReadonlyArray<E>): ExpressionWrapper<DB, TB, SqlBool>;
    or<E extends Readonly<FilterObject<DB, TB>>>(exprs: E): ExpressionWrapper<DB, TB, SqlBool>;
    /**
     * Wraps the expression in parentheses.
     *
     * ### Examples
     *
     * ```ts
     * const result = await db.selectFrom('person')
     *   .selectAll('person')
     *   .where((eb) => eb(eb.parens('age', '+', 1), '/', 100), '<', 0.1)
     *   .execute()
     * ```
     *
     * The generated SQL (PostgreSQL):
     *
     * ```sql
     * select "person".*
     * from "person"
     * where ("age" + $1) / $2 < $3
     * ```
     *
     * You can also pass in any expression as the only argument:
     *
     * ```ts
     * const result = await db.selectFrom('person')
     *   .selectAll('person')
     *   .where((eb) => eb.parens(
     *     eb('age', '=', 1).or('age', '=', 2)
     *   ).and(
     *     eb('first_name', '=', 'Jennifer').or('first_name', '=', 'Arnold')
     *   ))
     *   .execute()
     * ```
     *
     * The generated SQL (PostgreSQL):
     *
     * ```sql
     * select "person".*
     * from "person"
     * where ("age" = $1 or "age" = $2) and ("first_name" = $3 or "first_name" = $4)
     * ```
     */
    parens<RE extends ReferenceExpression<DB, TB>, OP extends BinaryOperatorExpression, VE extends OperandValueExpressionOrList<DB, TB, RE>>(lhs: RE, op: OP, rhs: VE): ExpressionWrapper<DB, TB, OP extends ComparisonOperator ? SqlBool : ExtractTypeFromReferenceExpression<DB, TB, RE>>;
    parens<T>(expr: Expression<T>): ExpressionWrapper<DB, TB, T>;
    /**
     * Creates a `cast(expr as dataType)` expression.
     *
     * Since Kysely can't know the mapping between JavaScript and database types,
     * you need to provide both explicitly.
     *
     * ### Examples
     *
     * ```ts
     * const result = await db.selectFrom('person')
     *   .select((eb) => [
     *     'id',
     *     'first_name',
     *     eb.cast<number>('age', 'integer').as('age')
     *   ])
     *   .execute()
     * ```
     *
     * The generated SQL (PostgreSQL):
     *
     * ```sql
     * select cast("age" as integer) as "age"
     * from "person"
     * ```
     */
    cast<T, RE extends ReferenceExpression<DB, TB> = ReferenceExpression<DB, TB>>(expr: RE, dataType: DataTypeExpression): ExpressionWrapper<DB, TB, T>;
    /**
     * See {@link QueryCreator.withSchema}
     *
     * @deprecated Will be removed in kysely 0.25.0.
     */
    withSchema(schema: string): ExpressionBuilder<DB, TB>;
}
export declare function createExpressionBuilder<DB, TB extends keyof DB>(executor?: QueryExecutor): ExpressionBuilder<DB, TB>;
export declare function expressionBuilder<DB, TB extends keyof DB>(_: SelectQueryBuilder<DB, TB, any>): ExpressionBuilder<DB, TB>;
export declare function expressionBuilder<DB, TB extends keyof DB = never>(): ExpressionBuilder<DB, TB>;
