import { SelectQueryBuilder } from '../query-builder/select-query-builder.js'; import { TableExpression, From, FromTables, ExtractTableAlias, AnyAliasedTable, PickTableWithAlias } from '../parser/table-parser.js'; import { FunctionModule } from '../query-builder/function-module.js'; import { ExtractTypeFromReferenceExpression, ReferenceExpression, SimpleReferenceExpression, StringReference } from '../parser/reference-parser.js'; import { QueryExecutor } from '../query-executor/query-executor.js'; import { BinaryOperatorExpression, FilterObject, OperandValueExpression, OperandValueExpressionOrList } from '../parser/binary-operation-parser.js'; import { Expression } from './expression.js'; import { ExpressionWrapper } from './expression-wrapper.js'; import { ComparisonOperator, JSONOperatorWith$, UnaryOperator } from '../operation-node/operator-node.js'; import { IsNever, SqlBool } from '../util/type-utils.js'; import { ExtractTypeFromValueExpression } from '../parser/value-parser.js'; import { CaseBuilder } from '../query-builder/case-builder.js'; import { JSONPathBuilder } from '../query-builder/json-path-builder.js'; import { OperandExpression } from '../parser/expression-parser.js'; import { RefTuple2, RefTuple3, RefTuple4, RefTuple5, ValTuple2, ValTuple3, ValTuple4, ValTuple5 } from '../parser/tuple-parser.js'; import { Selectable } from '../util/column-type.js'; import { KyselyTypeError } from '../util/type-error.js'; import { DataTypeExpression } from '../parser/data-type-parser.js'; export interface ExpressionBuilder { /** * 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 * eb.selectFrom('person') * .selectAll() * .where((eb) => eb('first_name', '=', 'Jennifer')) * ``` * * 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 * eb.selectFrom('person') * .selectAll() * .where((eb) => eb('first_name', '=', eb.ref('last_name'))) * ``` * * 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 * db.updateTable('person') * .set((eb) => ({ * age: eb('age', '+', 1) * })) * .where('id', '=', id) * ``` * * 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 * eb.selectFrom('person') * .selectAll() * .where((eb) => eb( * eb.fn('lower', ['first_name']), * 'in', * eb.selectFrom('pet') * .select('pet.name') * .where('pet.species', '=', 'cat') * )) * ``` */ , OP extends BinaryOperatorExpression, VE extends OperandValueExpressionOrList>(lhs: RE, op: OP, rhs: VE): ExpressionWrapper>; /** * Returns a copy of `this` expression builder, for destructuring purposes. * * ### Examples * * ```ts * db.selectFrom('person') * .where(({ eb, exists, selectFrom }) => * eb('first_name', '=', 'Jennifer').and( * exists(selectFrom('pet').whereRef('owner_id', '=', 'person.id').select('pet.id')) * ) * ) * .selectAll() * ``` * * 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; /** * 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 * 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; /** * 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(from: TE[]): SelectQueryBuilder, {}>; selectFrom>(from: TE[]): SelectQueryBuilder, FromTables, {}>; selectFrom(from: TE): SelectQueryBuilder, {}>; selectFrom>(from: TE): SelectQueryBuilder, TB | ExtractTableAlias, TE>, {}>; selectFrom>(from: TE): SelectQueryBuilder, FromTables, {}>; /** * Creates a `case` statement/operator. * * ### Examples * * Kitchen sink example with 2 flavors of `case` operator: * * ```ts * import { sql } from 'kysely' * * 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('maritalStatus') * .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 "maritalStatus" * when $4 then $5 * else $6 * end * end as "title" * from "person" * where "id" = $7 * ``` */ case(): CaseBuilder; case>(column: C): CaseBuilder>; case>(expression: E): CaseBuilder>; /** * 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 * db.selectFrom('person') * .selectAll('person') * .where((eb) => eb.or([ * eb('first_name', '=', eb.ref('last_name')), * eb('first_name', '=', eb.ref('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 * db.insertInto('person') * .values(person) * .onConflict((oc) => oc * .column('id') * .doUpdateSet(({ ref }) => ({ * first_name: ref('excluded.first_name'), * last_name: ref('excluded.last_name') * })) * ) * ``` * * 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 * db.update('pet').set((eb) => ({ * name: sql`concat(${eb.ref('pet.name')}, ${suffix})` * })) * ``` * * In the next example we use `ref` to reference a nested JSON property: * * ```ts * db.selectFrom('person') * .where(({ eb, ref }) => eb( * ref('address', '->').key('state').key('abbr'), * '=', * 'CA' * )) * .selectAll() * ``` * * The generated SQL (PostgreSQL): * * ```sql * select * from "person" where "address"->'state'->'abbr' = $1 * ``` * * You can also compile to a JSON path expression by using the `->$`or `->>$` operator: * * ```ts * db.selectFrom('person') * .select(({ ref }) => * ref('experience', '->$') * .at('last') * .key('title') * .as('current_job') * ) * ``` * * The generated SQL (MySQL): * * ```sql * select `experience`->'$[last].title' as `current_job` from `person` * ``` */ ref>(reference: RE): ExpressionWrapper>; ref>(reference: RE, op: JSONOperatorWith$): JSONPathBuilder>; /** * Creates a JSON path expression with provided column as root document (the $). * * For a JSON reference expression, see {@link ref}. * * ### Examples * * ```ts * db.updateTable('person') * .set('experience', (eb) => eb.fn('json_set', [ * 'experience', * eb.jsonPath<'experience'>().at('last').key('title'), * eb.val('CEO') * ])) * .where('id', '=', id) * .execute() * ``` * * The generated SQL (MySQL): * * ```sql * update `person` * set `experience` = json_set(`experience`, '$[last].title', ?) * where `id` = ? * ``` */ jsonPath<$ extends StringReference = never>(): IsNever<$> extends true ? KyselyTypeError<"You must provide a column reference as this method's $ generic"> : JSONPathBuilder>; /** * Creates a table reference. * * ```ts * db.selectFrom('person') * .innerJoin('pet', 'pet.owner_id', 'person.id') * .select(eb => [ * 'person.id', * sql`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" * ``` */ table(table: T): ExpressionWrapper>; /** * 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 * eb(val(38), '=', ref('age')) * ``` * * The generated SQL (PostgreSQL): * * ```sql * $1 = "age" * ``` */ val(value: VE): ExpressionWrapper>; /** * 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 * db.selectFrom('person') * .selectAll('person') * .where(({ eb, refTuple, tuple }) => eb( * refTuple('first_name', 'last_name'), * 'in', * [ * tuple('Jennifer', 'Aniston'), * tuple('Sylvester', 'Stallone') * ] * )) * ``` * * 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 * 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') * )) * ``` * * The generated SQL (PostgreSQL): * * ```sql * select * "person".* * from * "person" * where * ("first_name", "last_name") * in * ( * select "name", "species" * from "pet" * where "species" != $1 * ) * ``` */ refTuple, R2 extends ReferenceExpression>(value1: R1, value2: R2): ExpressionWrapper>; refTuple, R2 extends ReferenceExpression, R3 extends ReferenceExpression>(value1: R1, value2: R2, value3: R3): ExpressionWrapper>; refTuple, R2 extends ReferenceExpression, R3 extends ReferenceExpression, R4 extends ReferenceExpression>(value1: R1, value2: R2, value3: R3, value4: R4): ExpressionWrapper>; refTuple, R2 extends ReferenceExpression, R3 extends ReferenceExpression, R4 extends ReferenceExpression, R5 extends ReferenceExpression>(value1: R1, value2: R2, value3: R3, value4: R4, value5: R5): ExpressionWrapper>; /** * 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 * db.selectFrom('person') * .selectAll('person') * .where(({ eb, refTuple, tuple }) => eb( * refTuple('first_name', 'last_name'), * 'in', * [ * tuple('Jennifer', 'Aniston'), * tuple('Sylvester', 'Stallone') * ] * )) * ``` * * The generated SQL (PostgreSQL): * * ```sql * select * "person".* * from * "person" * where * ("first_name", "last_name") * in * ( * ($1, $2), * ($3, $4) * ) * ``` */ tuple(value1: V1, value2: V2): ExpressionWrapper>; tuple(value1: V1, value2: V2, value3: V3): ExpressionWrapper>; tuple(value1: V1, value2: V2, value3: V3, value4: V4): ExpressionWrapper>; tuple(value1: V1, value2: V2, value3: V3, value4: V4, value5: V5): ExpressionWrapper>; /** * 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 * db.selectFrom('person') * .select((eb) => eb.lit(1).as('one')) * ``` * * The generated SQL (PostgreSQL): * * ```sql * select 1 as "one" from "person" * ``` */ lit(literal: VE): ExpressionWrapper; /** * 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 * db.selectFrom('person') * .select((eb) => [ * 'first_name', * eb.unary('-', 'age').as('negative_age') * ]) * ``` * * The generated SQL (PostgreSQL): * * ```sql * select "first_name", -"age" * from "person" * ``` */ unary>(op: UnaryOperator, expr: RE): ExpressionWrapper>; /** * Creates a `not` operation. * * A shortcut for `unary('not', expr)`. * * @see {@link unary} */ not>(expr: RE): ExpressionWrapper>; /** * Creates an `exists` operation. * * A shortcut for `unary('exists', expr)`. * * @see {@link unary} */ exists>(expr: RE): ExpressionWrapper; /** * Creates a negation operation. * * A shortcut for `unary('-', expr)`. * * @see {@link unary} */ neg>(expr: RE): ExpressionWrapper>; /** * Creates a `between` expression. * * ### Examples * * ```ts * db.selectFrom('person') * .selectAll() * .where((eb) => eb.between('age', 40, 60)) * ``` * * The generated SQL (PostgreSQL): * * ```sql * select * from "person" where "age" between $1 and $2 * ``` */ between, SE extends OperandValueExpression, EE extends OperandValueExpression>(expr: RE, start: SE, end: EE): ExpressionWrapper; /** * Creates a `between symmetric` expression. * * ### Examples * * ```ts * db.selectFrom('person') * .selectAll() * .where((eb) => eb.betweenSymmetric('age', 40, 60)) * ``` * * The generated SQL (PostgreSQL): * * ```sql * select * from "person" where "age" between symmetric $1 and $2 * ``` */ betweenSymmetric, SE extends OperandValueExpression, EE extends OperandValueExpression>(expr: RE, start: SE, end: EE): ExpressionWrapper; /** * 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 * db.selectFrom('person') * .selectAll('person') * .where((eb) => eb.and([ * eb('first_name', '=', 'Jennifer'), * eb('fist_name', '=', 'Arnold'), * eb('fist_name', '=', 'Sylvester') * ])) * ``` * * 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 * db.selectFrom('person') * .selectAll('person') * .where((eb) => eb.and({ * first_name: 'Jennifer', * last_name: 'Aniston' * })) * ``` * * The generated SQL (PostgreSQL): * * ```sql * select "person".* * from "person" * where ( * "first_name" = $1 * and "last_name" = $2 * ) * ``` */ and>(exprs: ReadonlyArray): ExpressionWrapper; and>>(exprs: E): ExpressionWrapper; /** * 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 * db.selectFrom('person') * .selectAll('person') * .where((eb) => eb.or([ * eb('first_name', '=', 'Jennifer'), * eb('fist_name', '=', 'Arnold'), * eb('fist_name', '=', 'Sylvester') * ])) * ``` * * 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 * db.selectFrom('person') * .selectAll('person') * .where((eb) => eb.or({ * first_name: 'Jennifer', * last_name: 'Aniston' * })) * ``` * * The generated SQL (PostgreSQL): * * ```sql * select "person".* * from "person" * where ( * "first_name" = $1 * or "last_name" = $2 * ) * ``` */ or>(exprs: ReadonlyArray): ExpressionWrapper; or>>(exprs: E): ExpressionWrapper; /** * Wraps the expression in parentheses. * * ### Examples * * ```ts * db.selectFrom('person') * .selectAll('person') * .where((eb) => eb(eb.parens('age', '+', 1), '/', 100), '<', 0.1)) * ``` * * 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 * db.selectFrom('person') * .selectAll('person') * .where((eb) => eb.parens( * eb('age', '=', 1).or('age', '=', 2)) * ).and( * eb('first_name', '=', 'Jennifer').or('first_name', '=', 'Arnold') * )) * ``` * * The generated SQL (PostgreSQL): * * ```sql * select "person".* * from "person" * where ("age" = $1 or "age" = $2) and ("first_name" = $3 or "first_name" = $4) * ``` */ parens, OP extends BinaryOperatorExpression, VE extends OperandValueExpressionOrList>(lhs: RE, op: OP, rhs: VE): ExpressionWrapper>; parens(expr: Expression): ExpressionWrapper; /** * 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 * db.selectFrom('person') * .select((eb) => [ * 'id', * 'first_name', * eb.cast('age', 'integer').as('age') * ]) * ``` * * The generated SQL (PostgreSQL): * * ```sql * select cast("age" as integer) as "age" * from "person" * ``` */ cast = ReferenceExpression>(expr: RE, dataType: DataTypeExpression): ExpressionWrapper; /** * See {@link QueryCreator.withSchema} * * @deprecated Will be removed in kysely 0.25.0. */ withSchema(schema: string): ExpressionBuilder; } export declare function createExpressionBuilder(executor?: QueryExecutor): ExpressionBuilder; export declare function expressionBuilder(_: SelectQueryBuilder): ExpressionBuilder; export declare function expressionBuilder(): ExpressionBuilder;