kysely 0.26.0 → 0.26.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (212) hide show
  1. package/README.md +6 -6
  2. package/dist/cjs/dialect/dialect-adapter-base.d.ts +3 -3
  3. package/dist/cjs/dialect/mysql/mysql-adapter.d.ts +3 -2
  4. package/dist/cjs/dialect/mysql/mysql-adapter.js +2 -2
  5. package/dist/cjs/dialect/postgres/postgres-adapter.d.ts +3 -2
  6. package/dist/cjs/dialect/postgres/postgres-adapter.js +2 -2
  7. package/dist/cjs/dialect/postgres/postgres-dialect-config.d.ts +2 -2
  8. package/dist/cjs/dialect/sqlite/sqlite-adapter.d.ts +4 -2
  9. package/dist/cjs/dialect/sqlite/sqlite-adapter.js +2 -2
  10. package/dist/cjs/driver/runtime-driver.js +17 -2
  11. package/dist/cjs/expression/expression-builder.d.ts +299 -28
  12. package/dist/cjs/expression/expression-builder.js +36 -26
  13. package/dist/cjs/expression/expression-wrapper.d.ts +177 -8
  14. package/dist/cjs/expression/expression-wrapper.js +4 -4
  15. package/dist/cjs/expression/expression.d.ts +64 -1
  16. package/dist/cjs/helpers/mysql.d.ts +11 -8
  17. package/dist/cjs/helpers/mysql.js +21 -32
  18. package/dist/cjs/helpers/postgres.d.ts +8 -5
  19. package/dist/cjs/helpers/postgres.js +8 -5
  20. package/dist/cjs/helpers/sqlite.d.ts +164 -0
  21. package/dist/cjs/helpers/sqlite.js +180 -0
  22. package/dist/cjs/index.d.ts +3 -1
  23. package/dist/cjs/index.js +1 -0
  24. package/dist/cjs/kysely.d.ts +4 -3
  25. package/dist/cjs/kysely.js +1 -1
  26. package/dist/cjs/operation-node/common-table-expression-node.d.ts +4 -0
  27. package/dist/cjs/operation-node/common-table-expression-node.js +6 -0
  28. package/dist/cjs/operation-node/delete-query-node.d.ts +1 -1
  29. package/dist/cjs/operation-node/delete-query-node.js +3 -3
  30. package/dist/cjs/operation-node/operation-node-transformer.d.ts +2 -0
  31. package/dist/cjs/operation-node/operation-node-transformer.js +8 -0
  32. package/dist/cjs/operation-node/operation-node-visitor.d.ts +2 -0
  33. package/dist/cjs/operation-node/operation-node-visitor.js +1 -0
  34. package/dist/cjs/operation-node/operation-node.d.ts +1 -1
  35. package/dist/cjs/operation-node/operator-node.d.ts +3 -3
  36. package/dist/cjs/operation-node/operator-node.js +3 -0
  37. package/dist/cjs/operation-node/order-by-node.d.ts +2 -2
  38. package/dist/cjs/operation-node/order-by-node.js +4 -4
  39. package/dist/cjs/operation-node/over-node.d.ts +1 -1
  40. package/dist/cjs/operation-node/over-node.js +3 -3
  41. package/dist/cjs/operation-node/select-query-node.d.ts +5 -4
  42. package/dist/cjs/operation-node/select-query-node.js +13 -7
  43. package/dist/cjs/operation-node/tuple-node.d.ts +12 -0
  44. package/dist/cjs/operation-node/tuple-node.js +18 -0
  45. package/dist/cjs/parser/binary-operation-parser.d.ts +11 -7
  46. package/dist/cjs/parser/binary-operation-parser.js +35 -46
  47. package/dist/cjs/parser/expression-parser.d.ts +9 -4
  48. package/dist/cjs/parser/join-parser.d.ts +2 -2
  49. package/dist/cjs/parser/join-parser.js +2 -3
  50. package/dist/cjs/parser/order-by-parser.d.ts +6 -2
  51. package/dist/cjs/parser/order-by-parser.js +41 -7
  52. package/dist/cjs/parser/parse-utils.js +2 -2
  53. package/dist/cjs/parser/reference-parser.js +1 -1
  54. package/dist/cjs/parser/select-parser.d.ts +5 -5
  55. package/dist/cjs/parser/set-operation-parser.d.ts +3 -1
  56. package/dist/cjs/parser/set-operation-parser.js +13 -4
  57. package/dist/cjs/parser/tuple-parser.d.ts +47 -0
  58. package/dist/cjs/parser/tuple-parser.js +2 -0
  59. package/dist/cjs/parser/value-parser.d.ts +4 -2
  60. package/dist/cjs/parser/value-parser.js +12 -1
  61. package/dist/cjs/parser/with-parser.d.ts +3 -2
  62. package/dist/cjs/parser/with-parser.js +16 -4
  63. package/dist/cjs/plugin/camel-case/camel-case-plugin.d.ts +3 -3
  64. package/dist/cjs/plugin/camel-case/camel-case-plugin.js +4 -8
  65. package/dist/cjs/plugin/parse-json-results/parse-json-results-plugin.d.ts +13 -0
  66. package/dist/cjs/plugin/parse-json-results/parse-json-results-plugin.js +50 -14
  67. package/dist/cjs/query-builder/aggregate-function-builder.d.ts +5 -5
  68. package/dist/cjs/query-builder/aggregate-function-builder.js +2 -2
  69. package/dist/cjs/query-builder/case-builder.js +8 -4
  70. package/dist/cjs/query-builder/cte-builder.d.ts +20 -0
  71. package/dist/cjs/query-builder/cte-builder.js +39 -0
  72. package/dist/cjs/query-builder/delete-query-builder.d.ts +74 -24
  73. package/dist/cjs/query-builder/delete-query-builder.js +3 -3
  74. package/dist/cjs/query-builder/function-module.d.ts +41 -6
  75. package/dist/cjs/query-builder/function-module.js +3 -0
  76. package/dist/cjs/query-builder/having-interface.d.ts +2 -5
  77. package/dist/cjs/query-builder/insert-query-builder.d.ts +1 -1
  78. package/dist/cjs/query-builder/join-builder.d.ts +2 -6
  79. package/dist/cjs/query-builder/join-builder.js +2 -2
  80. package/dist/cjs/query-builder/json-path-builder.d.ts +60 -4
  81. package/dist/cjs/query-builder/on-conflict-builder.d.ts +143 -44
  82. package/dist/cjs/query-builder/on-conflict-builder.js +4 -4
  83. package/dist/cjs/query-builder/over-builder.js +1 -1
  84. package/dist/cjs/query-builder/select-query-builder.d.ts +245 -86
  85. package/dist/cjs/query-builder/select-query-builder.js +72 -924
  86. package/dist/cjs/query-builder/update-query-builder.d.ts +106 -25
  87. package/dist/cjs/query-builder/update-query-builder.js +2 -2
  88. package/dist/cjs/query-builder/where-interface.d.ts +71 -24
  89. package/dist/cjs/query-compiler/default-query-compiler.d.ts +3 -0
  90. package/dist/cjs/query-compiler/default-query-compiler.js +39 -7
  91. package/dist/cjs/query-creator.d.ts +74 -2
  92. package/dist/cjs/query-creator.js +83 -6
  93. package/dist/cjs/raw-builder/raw-builder.d.ts +88 -49
  94. package/dist/cjs/raw-builder/raw-builder.js +18 -45
  95. package/dist/cjs/raw-builder/sql.js +8 -8
  96. package/dist/cjs/schema/alter-table-builder.d.ts +4 -0
  97. package/dist/cjs/schema/alter-table-builder.js +12 -0
  98. package/dist/cjs/schema/create-index-builder.d.ts +1 -1
  99. package/dist/cjs/schema/create-index-builder.js +1 -1
  100. package/dist/cjs/util/column-type.d.ts +7 -6
  101. package/dist/cjs/util/json-object-args.d.ts +3 -0
  102. package/dist/cjs/util/json-object-args.js +35 -0
  103. package/dist/cjs/util/object-utils.d.ts +1 -0
  104. package/dist/cjs/util/object-utils.js +9 -1
  105. package/dist/cjs/util/type-utils.d.ts +10 -10
  106. package/dist/esm/dialect/dialect-adapter-base.d.ts +3 -3
  107. package/dist/esm/dialect/mysql/mysql-adapter.d.ts +3 -2
  108. package/dist/esm/dialect/mysql/mysql-adapter.js +2 -2
  109. package/dist/esm/dialect/postgres/postgres-adapter.d.ts +3 -2
  110. package/dist/esm/dialect/postgres/postgres-adapter.js +2 -2
  111. package/dist/esm/dialect/postgres/postgres-dialect-config.d.ts +2 -2
  112. package/dist/esm/dialect/sqlite/sqlite-adapter.d.ts +4 -2
  113. package/dist/esm/dialect/sqlite/sqlite-adapter.js +2 -2
  114. package/dist/esm/driver/runtime-driver.js +17 -2
  115. package/dist/esm/expression/expression-builder.d.ts +299 -28
  116. package/dist/esm/expression/expression-builder.js +40 -30
  117. package/dist/esm/expression/expression-wrapper.d.ts +177 -8
  118. package/dist/esm/expression/expression-wrapper.js +5 -5
  119. package/dist/esm/expression/expression.d.ts +64 -1
  120. package/dist/esm/helpers/mysql.d.ts +11 -8
  121. package/dist/esm/helpers/mysql.js +21 -32
  122. package/dist/esm/helpers/postgres.d.ts +8 -5
  123. package/dist/esm/helpers/postgres.js +8 -5
  124. package/dist/esm/helpers/sqlite.d.ts +164 -0
  125. package/dist/esm/helpers/sqlite.js +175 -0
  126. package/dist/esm/index.d.ts +3 -1
  127. package/dist/esm/index.js +1 -0
  128. package/dist/esm/kysely.d.ts +4 -3
  129. package/dist/esm/kysely.js +1 -1
  130. package/dist/esm/operation-node/common-table-expression-node.d.ts +4 -0
  131. package/dist/esm/operation-node/common-table-expression-node.js +6 -0
  132. package/dist/esm/operation-node/delete-query-node.d.ts +1 -1
  133. package/dist/esm/operation-node/delete-query-node.js +3 -3
  134. package/dist/esm/operation-node/operation-node-transformer.d.ts +2 -0
  135. package/dist/esm/operation-node/operation-node-transformer.js +8 -0
  136. package/dist/esm/operation-node/operation-node-visitor.d.ts +2 -0
  137. package/dist/esm/operation-node/operation-node-visitor.js +1 -0
  138. package/dist/esm/operation-node/operation-node.d.ts +1 -1
  139. package/dist/esm/operation-node/operator-node.d.ts +3 -3
  140. package/dist/esm/operation-node/operator-node.js +3 -0
  141. package/dist/esm/operation-node/order-by-node.d.ts +2 -2
  142. package/dist/esm/operation-node/order-by-node.js +4 -4
  143. package/dist/esm/operation-node/over-node.d.ts +1 -1
  144. package/dist/esm/operation-node/over-node.js +3 -3
  145. package/dist/esm/operation-node/select-query-node.d.ts +5 -4
  146. package/dist/esm/operation-node/select-query-node.js +13 -7
  147. package/dist/esm/operation-node/tuple-node.d.ts +12 -0
  148. package/dist/esm/operation-node/tuple-node.js +16 -0
  149. package/dist/esm/parser/binary-operation-parser.d.ts +11 -7
  150. package/dist/esm/parser/binary-operation-parser.js +36 -47
  151. package/dist/esm/parser/expression-parser.d.ts +9 -4
  152. package/dist/esm/parser/join-parser.d.ts +2 -2
  153. package/dist/esm/parser/join-parser.js +3 -4
  154. package/dist/esm/parser/order-by-parser.d.ts +6 -2
  155. package/dist/esm/parser/order-by-parser.js +40 -7
  156. package/dist/esm/parser/parse-utils.js +3 -3
  157. package/dist/esm/parser/reference-parser.js +1 -1
  158. package/dist/esm/parser/select-parser.d.ts +5 -5
  159. package/dist/esm/parser/set-operation-parser.d.ts +3 -1
  160. package/dist/esm/parser/set-operation-parser.js +11 -2
  161. package/dist/esm/parser/tuple-parser.d.ts +47 -0
  162. package/dist/esm/parser/tuple-parser.js +2 -0
  163. package/dist/esm/parser/value-parser.d.ts +4 -2
  164. package/dist/esm/parser/value-parser.js +10 -1
  165. package/dist/esm/parser/with-parser.d.ts +3 -2
  166. package/dist/esm/parser/with-parser.js +16 -4
  167. package/dist/esm/plugin/camel-case/camel-case-plugin.d.ts +3 -3
  168. package/dist/esm/plugin/camel-case/camel-case-plugin.js +5 -9
  169. package/dist/esm/plugin/parse-json-results/parse-json-results-plugin.d.ts +13 -0
  170. package/dist/esm/plugin/parse-json-results/parse-json-results-plugin.js +51 -15
  171. package/dist/esm/query-builder/aggregate-function-builder.d.ts +5 -5
  172. package/dist/esm/query-builder/aggregate-function-builder.js +3 -3
  173. package/dist/esm/query-builder/case-builder.js +10 -6
  174. package/dist/esm/query-builder/cte-builder.d.ts +20 -0
  175. package/dist/esm/query-builder/cte-builder.js +36 -0
  176. package/dist/esm/query-builder/delete-query-builder.d.ts +74 -24
  177. package/dist/esm/query-builder/delete-query-builder.js +4 -4
  178. package/dist/esm/query-builder/function-module.d.ts +41 -6
  179. package/dist/esm/query-builder/function-module.js +3 -0
  180. package/dist/esm/query-builder/having-interface.d.ts +2 -5
  181. package/dist/esm/query-builder/insert-query-builder.d.ts +1 -1
  182. package/dist/esm/query-builder/join-builder.d.ts +2 -6
  183. package/dist/esm/query-builder/join-builder.js +3 -3
  184. package/dist/esm/query-builder/json-path-builder.d.ts +60 -4
  185. package/dist/esm/query-builder/on-conflict-builder.d.ts +143 -44
  186. package/dist/esm/query-builder/on-conflict-builder.js +5 -5
  187. package/dist/esm/query-builder/over-builder.js +1 -1
  188. package/dist/esm/query-builder/select-query-builder.d.ts +245 -86
  189. package/dist/esm/query-builder/select-query-builder.js +72 -923
  190. package/dist/esm/query-builder/update-query-builder.d.ts +106 -25
  191. package/dist/esm/query-builder/update-query-builder.js +3 -3
  192. package/dist/esm/query-builder/where-interface.d.ts +71 -24
  193. package/dist/esm/query-compiler/default-query-compiler.d.ts +3 -0
  194. package/dist/esm/query-compiler/default-query-compiler.js +39 -7
  195. package/dist/esm/query-creator.d.ts +74 -2
  196. package/dist/esm/query-creator.js +84 -7
  197. package/dist/esm/raw-builder/raw-builder.d.ts +88 -49
  198. package/dist/esm/raw-builder/raw-builder.js +17 -42
  199. package/dist/esm/raw-builder/sql.js +9 -9
  200. package/dist/esm/schema/alter-table-builder.d.ts +4 -0
  201. package/dist/esm/schema/alter-table-builder.js +12 -0
  202. package/dist/esm/schema/create-index-builder.d.ts +1 -1
  203. package/dist/esm/schema/create-index-builder.js +2 -2
  204. package/dist/esm/util/column-type.d.ts +7 -6
  205. package/dist/esm/util/json-object-args.d.ts +3 -0
  206. package/dist/esm/util/json-object-args.js +32 -0
  207. package/dist/esm/util/object-utils.d.ts +1 -0
  208. package/dist/esm/util/object-utils.js +7 -0
  209. package/dist/esm/util/type-utils.d.ts +10 -10
  210. package/helpers/sqlite.d.ts +1 -0
  211. package/helpers/sqlite.js +1 -0
  212. package/package.json +7 -4
@@ -14,1106 +14,267 @@ import { freeze } from '../util/object-utils.js';
14
14
  import { parseGroupBy } from '../parser/group-by-parser.js';
15
15
  import { isNoResultErrorConstructor, NoResultError, } from './no-result-error.js';
16
16
  import { IdentifierNode } from '../operation-node/identifier-node.js';
17
- import { parseSetOperation } from '../parser/set-operation-parser.js';
18
- import { parseFilter, parseReferentialComparison, } from '../parser/binary-operation-parser.js';
19
- export class SelectQueryBuilder {
17
+ import { parseSetOperations, } from '../parser/set-operation-parser.js';
18
+ import { parseValueBinaryOperationOrExpression, parseReferentialBinaryOperation, } from '../parser/binary-operation-parser.js';
19
+ import { ExpressionWrapper } from '../expression/expression-wrapper.js';
20
+ class SelectQueryBuilderImpl {
20
21
  #props;
21
22
  constructor(props) {
22
23
  this.#props = freeze(props);
23
24
  }
24
- /** @private */
25
25
  get expressionType() {
26
26
  return undefined;
27
27
  }
28
28
  where(...args) {
29
- return new SelectQueryBuilder({
29
+ return new SelectQueryBuilderImpl({
30
30
  ...this.#props,
31
- queryNode: QueryNode.cloneWithWhere(this.#props.queryNode, parseFilter(args)),
31
+ queryNode: QueryNode.cloneWithWhere(this.#props.queryNode, parseValueBinaryOperationOrExpression(args)),
32
32
  });
33
33
  }
34
34
  whereRef(lhs, op, rhs) {
35
- return new SelectQueryBuilder({
35
+ return new SelectQueryBuilderImpl({
36
36
  ...this.#props,
37
- queryNode: QueryNode.cloneWithWhere(this.#props.queryNode, parseReferentialComparison(lhs, op, rhs)),
37
+ queryNode: QueryNode.cloneWithWhere(this.#props.queryNode, parseReferentialBinaryOperation(lhs, op, rhs)),
38
38
  });
39
39
  }
40
40
  having(...args) {
41
- return new SelectQueryBuilder({
41
+ return new SelectQueryBuilderImpl({
42
42
  ...this.#props,
43
- queryNode: SelectQueryNode.cloneWithHaving(this.#props.queryNode, parseFilter(args)),
43
+ queryNode: SelectQueryNode.cloneWithHaving(this.#props.queryNode, parseValueBinaryOperationOrExpression(args)),
44
44
  });
45
45
  }
46
46
  havingRef(lhs, op, rhs) {
47
- return new SelectQueryBuilder({
47
+ return new SelectQueryBuilderImpl({
48
48
  ...this.#props,
49
- queryNode: SelectQueryNode.cloneWithHaving(this.#props.queryNode, parseReferentialComparison(lhs, op, rhs)),
49
+ queryNode: SelectQueryNode.cloneWithHaving(this.#props.queryNode, parseReferentialBinaryOperation(lhs, op, rhs)),
50
50
  });
51
51
  }
52
- /**
53
- * Adds a select statement to the query.
54
- *
55
- * When a column (or any expression) is selected, Kysely adds its type to the return
56
- * type of the query. Kysely is smart enough to parse the selection names and types
57
- * from aliased columns, subqueries, raw expressions etc.
58
- *
59
- * Kysely only allows you to select columns and expressions that exist and would
60
- * produce valid SQL. However, Kysely is not perfect and there may be cases where
61
- * the type inference doesn't work and you need to override it. You can always
62
- * use the {@link Kysely.dynamic | dynamic} module and the {@link sql} tag
63
- * to override the types.
64
- *
65
- * Select calls are additive. Calling `select('id').select('first_name')` is the
66
- * same as calling `select(['id', 'first_name'])`.
67
- *
68
- * To select all columns of the query or specific tables see the
69
- * {@link selectAll} method.
70
- *
71
- * See the {@link $if} method if you are looking for a way to add selections
72
- * based on a runtime condition.
73
- *
74
- * ### Examples
75
- *
76
- * <!-- siteExample("select", "A single column", 10) -->
77
- *
78
- * Select a single column:
79
- *
80
- * ```ts
81
- * const persons = await db
82
- * .selectFrom('person')
83
- * .select('id')
84
- * .where('first_name', '=', 'Arnold')
85
- * .execute()
86
- * ```
87
- *
88
- * The generated SQL (PostgreSQL):
89
- *
90
- * ```sql
91
- * select "id" from "person" where "first_name" = $1
92
- * ```
93
- *
94
- * <!-- siteExample("select", "Column with a table", 20) -->
95
- *
96
- * Select a single column and specify a table:
97
- *
98
- * ```ts
99
- * const persons = await db
100
- * .selectFrom(['person', 'pet'])
101
- * .select('person.id')
102
- * .execute()
103
- * ```
104
- *
105
- * The generated SQL (PostgreSQL):
106
- *
107
- * ```sql
108
- * select "person"."id" from "person", "pet"
109
- * ```
110
- *
111
- * <!-- siteExample("select", "Multiple columns", 30) -->
112
- *
113
- * Select multiple columns:
114
- *
115
- * ```ts
116
- * const persons = await db
117
- * .selectFrom('person')
118
- * .select(['person.id', 'first_name'])
119
- * .execute()
120
- * ```
121
- *
122
- * The generated SQL (PostgreSQL):
123
- *
124
- * ```sql
125
- * select "person"."id", "first_name" from "person"
126
- * ```
127
- *
128
- * <!-- siteExample("select", "Aliases", 40) -->
129
- *
130
- * You can provide an alias for the selections by appending `as the_alias` to the selection.
131
- *
132
- * ```ts
133
- * const persons = await db
134
- * .selectFrom('person')
135
- * .select([
136
- * 'first_name as fn',
137
- * 'person.last_name as ln'
138
- * ])
139
- * .execute()
140
- * ```
141
- *
142
- * The generated SQL (PostgreSQL):
143
- *
144
- * ```sql
145
- * select
146
- * "first_name" as "fn",
147
- * "person"."last_name" as "ln"
148
- * from "person"
149
- * ```
150
- *
151
- * <!-- siteExample("select", "Complex selections", 50) -->
152
- *
153
- * You can select arbitrary expression including subqueries and raw sql snippets.
154
- * When you do that, you need to give a name for the selections using the `as` method:
155
- *
156
- * ```ts
157
- * import { sql } from 'kysely'
158
- *
159
- * const persons = await db.selectFrom('person')
160
- * .select(({ selectFrom, or, cmpr }) => [
161
- * // Select a correlated subquery
162
- * selectFrom('pet')
163
- * .whereRef('person.id', '=', 'pet.owner_id')
164
- * .select('pet.name')
165
- * .orderBy('pet.name')
166
- * .limit(1)
167
- * .as('first_pet_name'),
168
- *
169
- * // Build and select an expression using
170
- * // the expression builder
171
- * or([
172
- * cmpr('first_name', '=', 'Jennifer'),
173
- * cmpr('first_name', '=', 'Arnold')
174
- * ]).as('is_jennifer_or_arnold'),
175
- *
176
- * // Select a raw sql expression
177
- * sql<string>`concat(first_name, ' ', last_name)`.as('full_name')
178
- * ])
179
- * .execute()
180
- * ```
181
- *
182
- * The generated SQL (PostgreSQL):
183
- *
184
- * ```sql
185
- * select
186
- * (
187
- * select "pet"."name"
188
- * from "pet"
189
- * where "person"."id" = "pet"."owner_id"
190
- * order by "pet"."name"
191
- * limit $1
192
- * ) as "pet_name",
193
- * ("first_name" = $2 or "first_name" = $3) as "jennifer_or_arnold",
194
- * concat(first_name, ' ', last_name) as "full_name"
195
- * from "person"
196
- * ```
197
- *
198
- * In case you use the {@link sql} tag you need to specify the type of the expression
199
- * (in this example `string`).
200
- *
201
- * All the examples above assume you know the column names at compile time.
202
- * While it's better to build your code like that (that way you also know
203
- * the types) sometimes it's not possible or you just prefer to write more
204
- * dynamic code.
205
- * <br><br>
206
- * In this example, we use the `dynamic` module's methods to add selections
207
- * dynamically:
208
- *
209
- * ```ts
210
- * const { ref } = db.dynamic
211
- *
212
- * // Some column name provided by the user. Value not known at compile time.
213
- * const columnFromUserInput = req.query.select;
214
- *
215
- * // A type that lists all possible values `columnFromUserInput` can have.
216
- * // You can use `keyof Person` if any column of an interface is allowed.
217
- * type PossibleColumns = 'last_name' | 'first_name' | 'birth_date'
218
- *
219
- * const spersons = await db
220
- * .selectFrom('person')
221
- * .select([
222
- * ref<PossibleColumns>(columnFromUserInput)
223
- * 'id'
224
- * ])
225
- * .execute()
226
- *
227
- * // The resulting type contains all `PossibleColumns` as optional fields
228
- * // because we cannot know which field was actually selected before
229
- * // running the code.
230
- * const lastName: string | undefined = persons[0].last_name
231
- * const firstName: string | undefined = persons[0].first_name
232
- * const birthDate: string | undefined = persons[0].birth_date
233
- *
234
- * // The result type also contains the compile time selection `id`.
235
- * persons[0].id
236
- * ```
237
- */
238
52
  select(selection) {
239
- return new SelectQueryBuilder({
53
+ return new SelectQueryBuilderImpl({
240
54
  ...this.#props,
241
55
  queryNode: SelectQueryNode.cloneWithSelections(this.#props.queryNode, parseSelectArg(selection)),
242
56
  });
243
57
  }
244
58
  distinctOn(selection) {
245
- return new SelectQueryBuilder({
59
+ return new SelectQueryBuilderImpl({
246
60
  ...this.#props,
247
61
  queryNode: SelectQueryNode.cloneWithDistinctOn(this.#props.queryNode, parseReferenceExpressionOrList(selection)),
248
62
  });
249
63
  }
250
- /**
251
- * This can be used to add any additional SQL to the front of the query __after__ the `select` keyword.
252
- *
253
- * ### Examples
254
- *
255
- * ```ts
256
- * db.selectFrom('person')
257
- * .modifyFront(sql`sql_no_cache`)
258
- * .select('first_name')
259
- * .execute()
260
- * ```
261
- *
262
- * The generated SQL (MySQL):
263
- *
264
- * ```sql
265
- * select sql_no_cache `first_name`
266
- * from `person`
267
- * ```
268
- */
269
64
  modifyFront(modifier) {
270
- return new SelectQueryBuilder({
65
+ return new SelectQueryBuilderImpl({
271
66
  ...this.#props,
272
67
  queryNode: SelectQueryNode.cloneWithFrontModifier(this.#props.queryNode, SelectModifierNode.createWithExpression(modifier.toOperationNode())),
273
68
  });
274
69
  }
275
- /**
276
- * This can be used to add any additional SQL to the end of the query.
277
- *
278
- * Also see {@link forUpdate}, {@link forShare}, {@link forKeyShare}, {@link forNoKeyUpdate}
279
- * {@link skipLocked} and {@link noWait}.
280
- *
281
- * ### Examples
282
- *
283
- * ```ts
284
- * db.selectFrom('person')
285
- * .select('first_name')
286
- * .modifyEnd(sql`for update`)
287
- * .execute()
288
- * ```
289
- *
290
- * The generated SQL (PostgreSQL):
291
- *
292
- * ```sql
293
- * select "first_name"
294
- * from "person"
295
- * for update
296
- * ```
297
- */
298
70
  modifyEnd(modifier) {
299
- return new SelectQueryBuilder({
71
+ return new SelectQueryBuilderImpl({
300
72
  ...this.#props,
301
73
  queryNode: SelectQueryNode.cloneWithEndModifier(this.#props.queryNode, SelectModifierNode.createWithExpression(modifier.toOperationNode())),
302
74
  });
303
75
  }
304
- /**
305
- * Makes the selection distinct.
306
- *
307
- * <!-- siteExample("select", "Distinct", 70) -->
308
- *
309
- * ### Examples
310
- *
311
- * ```ts
312
- * const persons = await db.selectFrom('person')
313
- * .select('first_name')
314
- * .distinct()
315
- * .execute()
316
- * ```
317
- *
318
- * The generated SQL (PostgreSQL):
319
- *
320
- * ```sql
321
- * select distinct "first_name" from "person"
322
- * ```
323
- */
324
76
  distinct() {
325
- return new SelectQueryBuilder({
77
+ return new SelectQueryBuilderImpl({
326
78
  ...this.#props,
327
79
  queryNode: SelectQueryNode.cloneWithFrontModifier(this.#props.queryNode, SelectModifierNode.create('Distinct')),
328
80
  });
329
81
  }
330
- /**
331
- * Adds the `for update` modifier to a select query on supported databases.
332
- */
333
82
  forUpdate() {
334
- return new SelectQueryBuilder({
83
+ return new SelectQueryBuilderImpl({
335
84
  ...this.#props,
336
85
  queryNode: SelectQueryNode.cloneWithEndModifier(this.#props.queryNode, SelectModifierNode.create('ForUpdate')),
337
86
  });
338
87
  }
339
- /**
340
- * Adds the `for share` modifier to a select query on supported databases.
341
- */
342
88
  forShare() {
343
- return new SelectQueryBuilder({
89
+ return new SelectQueryBuilderImpl({
344
90
  ...this.#props,
345
91
  queryNode: SelectQueryNode.cloneWithEndModifier(this.#props.queryNode, SelectModifierNode.create('ForShare')),
346
92
  });
347
93
  }
348
- /**
349
- * Adds the `for key share` modifier to a select query on supported databases.
350
- */
351
94
  forKeyShare() {
352
- return new SelectQueryBuilder({
95
+ return new SelectQueryBuilderImpl({
353
96
  ...this.#props,
354
97
  queryNode: SelectQueryNode.cloneWithEndModifier(this.#props.queryNode, SelectModifierNode.create('ForKeyShare')),
355
98
  });
356
99
  }
357
- /**
358
- * Adds the `for no key update` modifier to a select query on supported databases.
359
- */
360
100
  forNoKeyUpdate() {
361
- return new SelectQueryBuilder({
101
+ return new SelectQueryBuilderImpl({
362
102
  ...this.#props,
363
103
  queryNode: SelectQueryNode.cloneWithEndModifier(this.#props.queryNode, SelectModifierNode.create('ForNoKeyUpdate')),
364
104
  });
365
105
  }
366
- /**
367
- * Adds the `skip locked` modifier to a select query on supported databases.
368
- */
369
106
  skipLocked() {
370
- return new SelectQueryBuilder({
107
+ return new SelectQueryBuilderImpl({
371
108
  ...this.#props,
372
109
  queryNode: SelectQueryNode.cloneWithEndModifier(this.#props.queryNode, SelectModifierNode.create('SkipLocked')),
373
110
  });
374
111
  }
375
- /**
376
- * Adds the `nowait` modifier to a select query on supported databases.
377
- */
378
112
  noWait() {
379
- return new SelectQueryBuilder({
113
+ return new SelectQueryBuilderImpl({
380
114
  ...this.#props,
381
115
  queryNode: SelectQueryNode.cloneWithEndModifier(this.#props.queryNode, SelectModifierNode.create('NoWait')),
382
116
  });
383
117
  }
384
118
  selectAll(table) {
385
- return new SelectQueryBuilder({
119
+ return new SelectQueryBuilderImpl({
386
120
  ...this.#props,
387
121
  queryNode: SelectQueryNode.cloneWithSelections(this.#props.queryNode, parseSelectAll(table)),
388
122
  });
389
123
  }
390
124
  innerJoin(...args) {
391
- return new SelectQueryBuilder({
125
+ return new SelectQueryBuilderImpl({
392
126
  ...this.#props,
393
127
  queryNode: QueryNode.cloneWithJoin(this.#props.queryNode, parseJoin('InnerJoin', args)),
394
128
  });
395
129
  }
396
130
  leftJoin(...args) {
397
- return new SelectQueryBuilder({
131
+ return new SelectQueryBuilderImpl({
398
132
  ...this.#props,
399
133
  queryNode: QueryNode.cloneWithJoin(this.#props.queryNode, parseJoin('LeftJoin', args)),
400
134
  });
401
135
  }
402
136
  rightJoin(...args) {
403
- return new SelectQueryBuilder({
137
+ return new SelectQueryBuilderImpl({
404
138
  ...this.#props,
405
139
  queryNode: QueryNode.cloneWithJoin(this.#props.queryNode, parseJoin('RightJoin', args)),
406
140
  });
407
141
  }
408
142
  fullJoin(...args) {
409
- return new SelectQueryBuilder({
143
+ return new SelectQueryBuilderImpl({
410
144
  ...this.#props,
411
145
  queryNode: QueryNode.cloneWithJoin(this.#props.queryNode, parseJoin('FullJoin', args)),
412
146
  });
413
147
  }
414
148
  innerJoinLateral(...args) {
415
- return new SelectQueryBuilder({
149
+ return new SelectQueryBuilderImpl({
416
150
  ...this.#props,
417
151
  queryNode: QueryNode.cloneWithJoin(this.#props.queryNode, parseJoin('LateralInnerJoin', args)),
418
152
  });
419
153
  }
420
154
  leftJoinLateral(...args) {
421
- return new SelectQueryBuilder({
155
+ return new SelectQueryBuilderImpl({
422
156
  ...this.#props,
423
157
  queryNode: QueryNode.cloneWithJoin(this.#props.queryNode, parseJoin('LateralLeftJoin', args)),
424
158
  });
425
159
  }
426
- /**
427
- * Adds an `order by` clause to the query.
428
- *
429
- * `orderBy` calls are additive. To order by multiple columns, call `orderBy`
430
- * multiple times.
431
- *
432
- * The first argument is the expression to order by and the second is the
433
- * order (`asc` or `desc`).
434
- *
435
- * ### Examples
436
- *
437
- * ```ts
438
- * await db
439
- * .selectFrom('person')
440
- * .select('person.first_name as fn')
441
- * .orderBy('id')
442
- * .orderBy('fn', 'desc')
443
- * .execute()
444
- * ```
445
- *
446
- * The generated SQL (PostgreSQL):
447
- *
448
- * ```sql
449
- * select "person"."first_name" as "fn"
450
- * from "person"
451
- * order by "id" asc, "fn" desc
452
- * ```
453
- *
454
- * The order by expression can also be a raw sql expression or a subquery
455
- * in addition to column references:
456
- *
457
- * ```ts
458
- * import { sql } from 'kysely'
459
- *
460
- * await db
461
- * .selectFrom('person')
462
- * .selectAll()
463
- * .orderBy((eb) => eb.selectFrom('pet')
464
- * .select('pet.name')
465
- * .whereRef('pet.owner_id', '=', 'person.id')
466
- * .limit(1)
467
- * )
468
- * .orderBy(
469
- * sql`concat(first_name, last_name)`
470
- * )
471
- * .execute()
472
- * ```
473
- *
474
- * The generated SQL (PostgreSQL):
475
- *
476
- * ```sql
477
- * select *
478
- * from "person"
479
- * order by
480
- * ( select "pet"."name"
481
- * from "pet"
482
- * where "pet"."owner_id" = "person"."id"
483
- * limit 1
484
- * ) asc,
485
- * concat(first_name, last_name) asc
486
- * ```
487
- *
488
- * `dynamic.ref` can be used to refer to columns not known at
489
- * compile time:
490
- *
491
- * ```ts
492
- * async function someQuery(orderBy: string) {
493
- * const { ref } = db.dynamic
494
- *
495
- * return await db
496
- * .selectFrom('person')
497
- * .select('person.first_name as fn')
498
- * .orderBy(ref(orderBy))
499
- * .execute()
500
- * }
501
- *
502
- * someQuery('fn')
503
- * ```
504
- *
505
- * The generated SQL (PostgreSQL):
506
- *
507
- * ```sql
508
- * select "person"."first_name" as "fn"
509
- * from "person"
510
- * order by "fn" asc
511
- * ```
512
- */
513
- orderBy(orderBy, direction) {
514
- return new SelectQueryBuilder({
160
+ orderBy(...args) {
161
+ return new SelectQueryBuilderImpl({
515
162
  ...this.#props,
516
- queryNode: SelectQueryNode.cloneWithOrderByItem(this.#props.queryNode, parseOrderBy(orderBy, direction)),
163
+ queryNode: SelectQueryNode.cloneWithOrderByItems(this.#props.queryNode, parseOrderBy(args)),
517
164
  });
518
165
  }
519
- /**
520
- * Adds a `group by` clause to the query.
521
- *
522
- * ### Examples
523
- *
524
- * ```ts
525
- * import { sql } from 'kysely'
526
- *
527
- * await db
528
- * .selectFrom('person')
529
- * .select([
530
- * 'first_name',
531
- * sql`max(id)`.as('max_id')
532
- * ])
533
- * .groupBy('first_name')
534
- * .execute()
535
- * ```
536
- *
537
- * The generated SQL (PostgreSQL):
538
- *
539
- * ```sql
540
- * select "first_name", max(id)
541
- * from "person"
542
- * group by "first_name"
543
- * ```
544
- *
545
- * `groupBy` also accepts an array:
546
- *
547
- * ```ts
548
- * import { sql } from 'kysely'
549
- *
550
- * await db
551
- * .selectFrom('person')
552
- * .select([
553
- * 'first_name',
554
- * 'last_name',
555
- * sql`max(id)`.as('max_id')
556
- * ])
557
- * .groupBy([
558
- * 'first_name',
559
- * 'last_name'
560
- * ])
561
- * .execute()
562
- * ```
563
- *
564
- * The generated SQL (PostgreSQL):
565
- *
566
- * ```sql
567
- * select "first_name", "last_name", max(id)
568
- * from "person"
569
- * group by "first_name", "last_name"
570
- * ```
571
- *
572
- * The group by expressions can also be subqueries or
573
- * raw sql expressions:
574
- *
575
- * ```ts
576
- * import { sql } from 'kysely'
577
- *
578
- * await db
579
- * .selectFrom('person')
580
- * .select([
581
- * 'first_name',
582
- * 'last_name',
583
- * sql`max(id)`.as('max_id')
584
- * ])
585
- * .groupBy([
586
- * sql`concat(first_name, last_name)`,
587
- * (qb) => qb.selectFrom('pet').select('id').limit(1)
588
- * ])
589
- * .execute()
590
- * ```
591
- *
592
- * `dynamic.ref` can be used to refer to columns not known at
593
- * compile time:
594
- *
595
- * ```ts
596
- * async function someQuery(groupBy: string) {
597
- * const { ref } = db.dynamic
598
- *
599
- * return await db
600
- * .selectFrom('person')
601
- * .select('first_name')
602
- * .groupBy(ref(groupBy))
603
- * .execute()
604
- * }
605
- *
606
- * someQuery('first_name')
607
- * ```
608
- *
609
- * The generated SQL (PostgreSQL):
610
- *
611
- * ```sql
612
- * select "first_name"
613
- * from "person"
614
- * group by "first_name"
615
- * ```
616
- */
617
166
  groupBy(groupBy) {
618
- return new SelectQueryBuilder({
167
+ return new SelectQueryBuilderImpl({
619
168
  ...this.#props,
620
169
  queryNode: SelectQueryNode.cloneWithGroupByItems(this.#props.queryNode, parseGroupBy(groupBy)),
621
170
  });
622
171
  }
623
- /**
624
- * Adds a limit clause to the query.
625
- *
626
- * ### Examples
627
- *
628
- * Select the first 10 rows of the result:
629
- *
630
- * ```ts
631
- * return await db
632
- * .selectFrom('person')
633
- * .select('first_name')
634
- * .limit(10)
635
- * ```
636
- *
637
- * Select rows from index 10 to index 19 of the result:
638
- *
639
- * ```ts
640
- * return await db
641
- * .selectFrom('person')
642
- * .select('first_name')
643
- * .offset(10)
644
- * .limit(10)
645
- * ```
646
- */
647
172
  limit(limit) {
648
- return new SelectQueryBuilder({
173
+ return new SelectQueryBuilderImpl({
649
174
  ...this.#props,
650
175
  queryNode: SelectQueryNode.cloneWithLimit(this.#props.queryNode, LimitNode.create(limit)),
651
176
  });
652
177
  }
653
- /**
654
- * Adds an offset clause to the query.
655
- *
656
- * ### Examples
657
- *
658
- * Select rows from index 10 to index 19 of the result:
659
- *
660
- * ```ts
661
- * return await db
662
- * .selectFrom('person')
663
- * .select('first_name')
664
- * .offset(10)
665
- * .limit(10)
666
- * ```
667
- */
668
178
  offset(offset) {
669
- return new SelectQueryBuilder({
179
+ return new SelectQueryBuilderImpl({
670
180
  ...this.#props,
671
181
  queryNode: SelectQueryNode.cloneWithOffset(this.#props.queryNode, OffsetNode.create(offset)),
672
182
  });
673
183
  }
674
- /**
675
- * Combines another select query or raw expression to this query using `union`.
676
- *
677
- * The output row type of the combined query must match `this` query.
678
- *
679
- * ### Examples
680
- *
681
- * ```ts
682
- * db.selectFrom('person')
683
- * .select(['id', 'first_name as name'])
684
- * .union(db.selectFrom('pet').select(['id', 'name']))
685
- * .orderBy('name')
686
- * ```
687
- */
688
184
  union(expression) {
689
- return new SelectQueryBuilder({
185
+ return new SelectQueryBuilderImpl({
690
186
  ...this.#props,
691
- queryNode: SelectQueryNode.cloneWithSetOperation(this.#props.queryNode, parseSetOperation('union', expression, false)),
187
+ queryNode: SelectQueryNode.cloneWithSetOperations(this.#props.queryNode, parseSetOperations('union', expression, false)),
692
188
  });
693
189
  }
694
- /**
695
- * Combines another select query or raw expression to this query using `union all`.
696
- *
697
- * The output row type of the combined query must match `this` query.
698
- *
699
- * ### Examples
700
- *
701
- * ```ts
702
- * db.selectFrom('person')
703
- * .select(['id', 'first_name as name'])
704
- * .unionAll(db.selectFrom('pet').select(['id', 'name']))
705
- * .orderBy('name')
706
- * ```
707
- */
708
190
  unionAll(expression) {
709
- return new SelectQueryBuilder({
191
+ return new SelectQueryBuilderImpl({
710
192
  ...this.#props,
711
- queryNode: SelectQueryNode.cloneWithSetOperation(this.#props.queryNode, parseSetOperation('union', expression, true)),
193
+ queryNode: SelectQueryNode.cloneWithSetOperations(this.#props.queryNode, parseSetOperations('union', expression, true)),
712
194
  });
713
195
  }
714
- /**
715
- * Combines another select query or raw expression to this query using `intersect`.
716
- *
717
- * The output row type of the combined query must match `this` query.
718
- *
719
- * ### Examples
720
- *
721
- * ```ts
722
- * db.selectFrom('person')
723
- * .select(['id', 'first_name as name'])
724
- * .intersect(db.selectFrom('pet').select(['id', 'name']))
725
- * .orderBy('name')
726
- * ```
727
- */
728
196
  intersect(expression) {
729
- return new SelectQueryBuilder({
197
+ return new SelectQueryBuilderImpl({
730
198
  ...this.#props,
731
- queryNode: SelectQueryNode.cloneWithSetOperation(this.#props.queryNode, parseSetOperation('intersect', expression, false)),
199
+ queryNode: SelectQueryNode.cloneWithSetOperations(this.#props.queryNode, parseSetOperations('intersect', expression, false)),
732
200
  });
733
201
  }
734
- /**
735
- * Combines another select query or raw expression to this query using `intersect all`.
736
- *
737
- * The output row type of the combined query must match `this` query.
738
- *
739
- * ### Examples
740
- *
741
- * ```ts
742
- * db.selectFrom('person')
743
- * .select(['id', 'first_name as name'])
744
- * .intersectAll(db.selectFrom('pet').select(['id', 'name']))
745
- * .orderBy('name')
746
- * ```
747
- */
748
202
  intersectAll(expression) {
749
- return new SelectQueryBuilder({
203
+ return new SelectQueryBuilderImpl({
750
204
  ...this.#props,
751
- queryNode: SelectQueryNode.cloneWithSetOperation(this.#props.queryNode, parseSetOperation('intersect', expression, true)),
205
+ queryNode: SelectQueryNode.cloneWithSetOperations(this.#props.queryNode, parseSetOperations('intersect', expression, true)),
752
206
  });
753
207
  }
754
- /**
755
- * Combines another select query or raw expression to this query using `except`.
756
- *
757
- * The output row type of the combined query must match `this` query.
758
- *
759
- * ### Examples
760
- *
761
- * ```ts
762
- * db.selectFrom('person')
763
- * .select(['id', 'first_name as name'])
764
- * .except(db.selectFrom('pet').select(['id', 'name']))
765
- * .orderBy('name')
766
- * ```
767
- */
768
208
  except(expression) {
769
- return new SelectQueryBuilder({
209
+ return new SelectQueryBuilderImpl({
770
210
  ...this.#props,
771
- queryNode: SelectQueryNode.cloneWithSetOperation(this.#props.queryNode, parseSetOperation('except', expression, false)),
211
+ queryNode: SelectQueryNode.cloneWithSetOperations(this.#props.queryNode, parseSetOperations('except', expression, false)),
772
212
  });
773
213
  }
774
- /**
775
- * Combines another select query or raw expression to this query using `except all`.
776
- *
777
- * The output row type of the combined query must match `this` query.
778
- *
779
- * ### Examples
780
- *
781
- * ```ts
782
- * db.selectFrom('person')
783
- * .select(['id', 'first_name as name'])
784
- * .exceptAll(db.selectFrom('pet').select(['id', 'name']))
785
- * .orderBy('name')
786
- * ```
787
- */
788
214
  exceptAll(expression) {
789
- return new SelectQueryBuilder({
215
+ return new SelectQueryBuilderImpl({
790
216
  ...this.#props,
791
- queryNode: SelectQueryNode.cloneWithSetOperation(this.#props.queryNode, parseSetOperation('except', expression, true)),
217
+ queryNode: SelectQueryNode.cloneWithSetOperations(this.#props.queryNode, parseSetOperations('except', expression, true)),
792
218
  });
793
219
  }
794
- /**
795
- * Gives an alias for the query. This method is only useful for sub queries.
796
- *
797
- * ### Examples
798
- *
799
- * ```ts
800
- * const pets = await db.selectFrom('pet')
801
- * .selectAll('pet')
802
- * .select(
803
- * (qb) => qb.selectFrom('person')
804
- * .select('first_name')
805
- * .whereRef('pet.owner_id', '=', 'person.id')
806
- * .as('owner_first_name')
807
- * )
808
- * .execute()
809
- *
810
- * pets[0].owner_first_name
811
- * ```
812
- */
813
220
  as(alias) {
814
- return new AliasedSelectQueryBuilder(this, alias);
221
+ return new AliasedSelectQueryBuilderImpl(this, alias);
815
222
  }
816
- /**
817
- * Clears all select clauses from the query.
818
- *
819
- * ### Examples
820
- *
821
- * ```ts
822
- * db.selectFrom('person')
823
- * .select(['id', 'first_name'])
824
- * .clearSelect()
825
- * .select(['id', 'gender'])
826
- * ```
827
- *
828
- * The generated SQL(PostgreSQL):
829
- *
830
- * ```sql
831
- * select "id", "gender" from "person"
832
- * ```
833
- */
834
223
  clearSelect() {
835
- return new SelectQueryBuilder({
224
+ return new SelectQueryBuilderImpl({
836
225
  ...this.#props,
837
226
  queryNode: SelectQueryNode.cloneWithoutSelections(this.#props.queryNode),
838
227
  });
839
228
  }
840
229
  clearWhere() {
841
- return new SelectQueryBuilder({
230
+ return new SelectQueryBuilderImpl({
842
231
  ...this.#props,
843
232
  queryNode: QueryNode.cloneWithoutWhere(this.#props.queryNode),
844
233
  });
845
234
  }
846
- /**
847
- * Clears limit clause from the query.
848
- *
849
- * ### Examples
850
- *
851
- * ```ts
852
- * db.selectFrom('person')
853
- * .selectAll()
854
- * .limit(10)
855
- * .clearLimit()
856
- * ```
857
- *
858
- * The generated SQL(PostgreSQL):
859
- *
860
- * ```sql
861
- * select * from "person"
862
- * ```
863
- */
864
235
  clearLimit() {
865
- return new SelectQueryBuilder({
236
+ return new SelectQueryBuilderImpl({
866
237
  ...this.#props,
867
238
  queryNode: SelectQueryNode.cloneWithoutLimit(this.#props.queryNode),
868
239
  });
869
240
  }
870
- /**
871
- * Clears offset clause from the query.
872
- *
873
- * ### Examples
874
- *
875
- * ```ts
876
- * db.selectFrom('person')
877
- * .selectAll()
878
- * .limit(10)
879
- * .offset(20)
880
- * .clearOffset()
881
- * ```
882
- *
883
- * The generated SQL(PostgreSQL):
884
- *
885
- * ```sql
886
- * select * from "person" limit 10
887
- * ```
888
- */
889
241
  clearOffset() {
890
- return new SelectQueryBuilder({
242
+ return new SelectQueryBuilderImpl({
891
243
  ...this.#props,
892
244
  queryNode: SelectQueryNode.cloneWithoutOffset(this.#props.queryNode),
893
245
  });
894
246
  }
895
- /**
896
- * Clears all `order by` clauses from the query.
897
- *
898
- * ### Examples
899
- *
900
- * ```ts
901
- * db.selectFrom('person')
902
- * .selectAll()
903
- * .orderBy('id')
904
- * .clearOrderBy()
905
- * ```
906
- *
907
- * The generated SQL(PostgreSQL):
908
- *
909
- * ```sql
910
- * select * from "person"
911
- * ```
912
- */
913
247
  clearOrderBy() {
914
- return new SelectQueryBuilder({
248
+ return new SelectQueryBuilderImpl({
915
249
  ...this.#props,
916
250
  queryNode: SelectQueryNode.cloneWithoutOrderBy(this.#props.queryNode),
917
251
  });
918
252
  }
919
- /**
920
- * Simply calls the provided function passing `this` as the only argument. `$call` returns
921
- * what the provided function returns.
922
- *
923
- * If you want to conditionally call a method on `this`, see
924
- * the {@link $if} method.
925
- *
926
- * ### Examples
927
- *
928
- * The next example uses a helper function `log` to log a query:
929
- *
930
- * ```ts
931
- * function log<T extends Compilable>(qb: T): T {
932
- * console.log(qb.compile())
933
- * return qb
934
- * }
935
- *
936
- * db.selectFrom('person')
937
- * .selectAll()
938
- * .$call(log)
939
- * .execute()
940
- * ```
941
- */
942
253
  $call(func) {
943
254
  return func(this);
944
255
  }
945
- /**
946
- * Call `func(this)` if `condition` is true.
947
- *
948
- * NOTE: This method has an impact on typescript performance and it should only be used
949
- * when necessary. Remember that you can call most methods like `where` conditionally
950
- * like this:
951
- *
952
- * ```ts
953
- * let query = db.selectFrom('person').selectAll()
954
- *
955
- * if (firstName) {
956
- * query = query.where('first_name', '=', firstName)
957
- * }
958
- *
959
- * if (lastName) {
960
- * query = query.where('last_name', '=', lastName)
961
- * }
962
- *
963
- * const result = await query.execute()
964
- * ```
965
- *
966
- * This method is mainly useful with optional selects. Any `select` or `selectAll`
967
- * method called inside the callback add optional fields to the result type. This is
968
- * because we can't know if those selections were actually made before running the code.
969
- *
970
- * Also see [this recipe](https://github.com/koskimas/kysely/tree/master/site/docs/recipes/conditional-selects.md)
971
- *
972
- * ### Examples
973
- *
974
- * ```ts
975
- * async function getPerson(id: number, withLastName: boolean) {
976
- * return await db
977
- * .selectFrom('person')
978
- * .select(['id', 'first_name'])
979
- * .$if(withLastName, (qb) => qb.select('last_name'))
980
- * .where('id', '=', id)
981
- * .executeTakeFirstOrThrow()
982
- * }
983
- * ```
984
- *
985
- * Any selections added inside the `if` callback will be added as optional fields to the
986
- * output type since we can't know if the selections were actually made before running
987
- * the code. In the example above the return type of the `getPerson` function is:
988
- *
989
- * ```ts
990
- * {
991
- * id: number
992
- * first_name: string
993
- * last_name?: string
994
- * }
995
- * ```
996
- *
997
- * You can also call any other methods inside the callback:
998
- *
999
- * ```ts
1000
- * db.selectFrom('person')
1001
- * .select('person.id')
1002
- * .$if(filterByFirstName, (qb) => qb.where('first_name', '=', firstName))
1003
- * .$if(filterByPetCount, (qb) => qb
1004
- * .innerJoin('pet', 'pet.owner_id', 'person.id')
1005
- * .having((eb) => eb.fn.count('pet.id'), '>', petCountLimit)
1006
- * .groupBy('person.id')
1007
- * )
1008
- * ```
1009
- */
1010
256
  $if(condition, func) {
1011
257
  if (condition) {
1012
258
  return func(this);
1013
259
  }
1014
- return new SelectQueryBuilder({
260
+ return new SelectQueryBuilderImpl({
1015
261
  ...this.#props,
1016
262
  });
1017
263
  }
1018
- /**
1019
- * Change the output type of the query.
1020
- *
1021
- * You should only use this method as the last resort if the types
1022
- * don't support your use case.
1023
- */
1024
264
  $castTo() {
1025
- return new SelectQueryBuilder(this.#props);
265
+ return new SelectQueryBuilderImpl(this.#props);
1026
266
  }
1027
- /**
1028
- * Narrows (parts of) the output type of the query.
1029
- *
1030
- * Kysely tries to be as type-safe as possible, but in some cases we have to make
1031
- * compromises for better maintainability and compilation performance. At present,
1032
- * Kysely doesn't narrow the output type of the query when using {@link where}, {@link having}
1033
- * or {@link JoinQueryBuilder.on}.
1034
- *
1035
- * This utility method is very useful for these situations, as it removes unncessary
1036
- * runtime assertion/guard code. Its input type is limited to the output type
1037
- * of the query, so you can't add a column that doesn't exist, or change a column's
1038
- * type to something that doesn't exist in its union type.
1039
- *
1040
- * ### Examples
1041
- *
1042
- * Turn this code:
1043
- *
1044
- * ```ts
1045
- * const person = await db.selectFrom('person')
1046
- * .where('nullable_column', 'is not', null)
1047
- * .selectAll()
1048
- * .executeTakeFirstOrThrow()
1049
- *
1050
- * if (person.nullable_column) {
1051
- * functionThatExpectsPersonWithNonNullValue(person)
1052
- * }
1053
- * ```
1054
- *
1055
- * Into this:
1056
- *
1057
- * ```ts
1058
- * const person = await db.selectFrom('person')
1059
- * .where('nullable_column', 'is not', null)
1060
- * .selectAll()
1061
- * .$narrowType<{ nullable_column: string }>()
1062
- * .executeTakeFirstOrThrow()
1063
- *
1064
- * functionThatExpectsPersonWithNonNullValue(person)
1065
- * ```
1066
- */
1067
267
  $narrowType() {
1068
- return new SelectQueryBuilder(this.#props);
268
+ return new SelectQueryBuilderImpl(this.#props);
1069
269
  }
1070
- /**
1071
- * Asserts that query's output row type equals the given type `T`.
1072
- *
1073
- * This method can be used to simplify excessively complex types to make typescript happy
1074
- * and much faster.
1075
- *
1076
- * Kysely uses complex type magic to achieve its type safety. This complexity is sometimes too much
1077
- * for typescript and you get errors like this:
1078
- *
1079
- * ```
1080
- * error TS2589: Type instantiation is excessively deep and possibly infinite.
1081
- * ```
1082
- *
1083
- * In these case you can often use this method to help typescript a little bit. When you use this
1084
- * method to assert the output type of a query, Kysely can drop the complex output type that
1085
- * consists of multiple nested helper types and replace it with the simple asserted type.
1086
- *
1087
- * Using this method doesn't reduce type safety at all. You have to pass in a type that is
1088
- * structurally equal to the current type.
1089
- *
1090
- * ### Examples
1091
- *
1092
- * ```ts
1093
- * const result = await db
1094
- * .with('first_and_last', (qb) => qb
1095
- * .selectFrom('person')
1096
- * .select(['first_name', 'last_name'])
1097
- * .$assertType<{ first_name: string, last_name: string }>()
1098
- * )
1099
- * .with('age', (qb) => qb
1100
- * .selectFrom('person')
1101
- * .select('age')
1102
- * .$assertType<{ age: number }>()
1103
- * )
1104
- * .selectFrom(['first_and_last', 'age'])
1105
- * .selectAll()
1106
- * .executeTakeFirstOrThrow()
1107
- * ```
1108
- */
1109
270
  $assertType() {
1110
- return new SelectQueryBuilder(this.#props);
271
+ return new SelectQueryBuilderImpl(this.#props);
272
+ }
273
+ $asTuple() {
274
+ return new ExpressionWrapper(this.toOperationNode());
1111
275
  }
1112
- /**
1113
- * Returns a copy of this SelectQueryBuilder instance with the given plugin installed.
1114
- */
1115
276
  withPlugin(plugin) {
1116
- return new SelectQueryBuilder({
277
+ return new SelectQueryBuilderImpl({
1117
278
  ...this.#props,
1118
279
  executor: this.#props.executor.withPlugin(plugin),
1119
280
  });
@@ -1124,32 +285,15 @@ export class SelectQueryBuilder {
1124
285
  compile() {
1125
286
  return this.#props.executor.compileQuery(this.toOperationNode(), this.#props.queryId);
1126
287
  }
1127
- /**
1128
- * Executes the query and returns an array of rows.
1129
- *
1130
- * Also see the {@link executeTakeFirst} and {@link executeTakeFirstOrThrow} methods.
1131
- */
1132
288
  async execute() {
1133
289
  const compiledQuery = this.compile();
1134
290
  const result = await this.#props.executor.executeQuery(compiledQuery, this.#props.queryId);
1135
291
  return result.rows;
1136
292
  }
1137
- /**
1138
- * Executes the query and returns the first result or undefined if
1139
- * the query returned no result.
1140
- */
1141
293
  async executeTakeFirst() {
1142
294
  const [result] = await this.execute();
1143
295
  return result;
1144
296
  }
1145
- /**
1146
- * Executes the query and returns the first result or throws if
1147
- * the query returned no result.
1148
- *
1149
- * By default an instance of {@link NoResultError} is thrown, but you can
1150
- * provide a custom error class, or callback to throw a different
1151
- * error.
1152
- */
1153
297
  async executeTakeFirstOrThrow(errorConstructor = NoResultError) {
1154
298
  const result = await this.executeTakeFirst();
1155
299
  if (result === undefined) {
@@ -1168,33 +312,38 @@ export class SelectQueryBuilder {
1168
312
  }
1169
313
  }
1170
314
  async explain(format, options) {
1171
- const builder = new SelectQueryBuilder({
315
+ const builder = new SelectQueryBuilderImpl({
1172
316
  ...this.#props,
1173
317
  queryNode: QueryNode.cloneWithExplain(this.#props.queryNode, format, options),
1174
318
  });
1175
319
  return await builder.execute();
1176
320
  }
1177
321
  }
1178
- preventAwait(SelectQueryBuilder, "don't await SelectQueryBuilder instances directly. To execute the query you need to call `execute` or `executeTakeFirst`.");
322
+ preventAwait(SelectQueryBuilderImpl, "don't await SelectQueryBuilder instances directly. To execute the query you need to call `execute` or `executeTakeFirst`.");
323
+ export function createSelectQueryBuilder(props) {
324
+ return new SelectQueryBuilderImpl(props);
325
+ }
1179
326
  /**
1180
327
  * {@link SelectQueryBuilder} with an alias. The result of calling {@link SelectQueryBuilder.as}.
1181
328
  */
1182
- export class AliasedSelectQueryBuilder {
329
+ class AliasedSelectQueryBuilderImpl {
1183
330
  #queryBuilder;
1184
331
  #alias;
1185
332
  constructor(queryBuilder, alias) {
1186
333
  this.#queryBuilder = queryBuilder;
1187
334
  this.#alias = alias;
1188
335
  }
1189
- /** @private */
1190
336
  get expression() {
1191
337
  return this.#queryBuilder;
1192
338
  }
1193
- /** @private */
1194
339
  get alias() {
1195
340
  return this.#alias;
1196
341
  }
342
+ get selectQueryBuilder() {
343
+ return this.#queryBuilder;
344
+ }
1197
345
  toOperationNode() {
1198
346
  return AliasNode.create(this.#queryBuilder.toOperationNode(), IdentifierNode.create(this.#alias));
1199
347
  }
1200
348
  }
349
+ preventAwait(AliasedSelectQueryBuilderImpl, "don't await AliasedSelectQueryBuilder instances directly. AliasedSelectQueryBuilder should never be executed directly since it's always a part of another query.");