select.cjs 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863
  1. "use strict";
  2. var __defProp = Object.defineProperty;
  3. var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
  4. var __getOwnPropNames = Object.getOwnPropertyNames;
  5. var __hasOwnProp = Object.prototype.hasOwnProperty;
  6. var __export = (target, all) => {
  7. for (var name in all)
  8. __defProp(target, name, { get: all[name], enumerable: true });
  9. };
  10. var __copyProps = (to, from, except2, desc) => {
  11. if (from && typeof from === "object" || typeof from === "function") {
  12. for (let key of __getOwnPropNames(from))
  13. if (!__hasOwnProp.call(to, key) && key !== except2)
  14. __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  15. }
  16. return to;
  17. };
  18. var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
  19. var select_exports = {};
  20. __export(select_exports, {
  21. GelSelectBase: () => GelSelectBase,
  22. GelSelectBuilder: () => GelSelectBuilder,
  23. GelSelectQueryBuilderBase: () => GelSelectQueryBuilderBase,
  24. except: () => except,
  25. exceptAll: () => exceptAll,
  26. intersect: () => intersect,
  27. intersectAll: () => intersectAll,
  28. union: () => union,
  29. unionAll: () => unionAll
  30. });
  31. module.exports = __toCommonJS(select_exports);
  32. var import_entity = require("../../entity.cjs");
  33. var import_view_base = require("../view-base.cjs");
  34. var import_query_builder = require("../../query-builders/query-builder.cjs");
  35. var import_query_promise = require("../../query-promise.cjs");
  36. var import_selection_proxy = require("../../selection-proxy.cjs");
  37. var import_sql = require("../../sql/sql.cjs");
  38. var import_subquery = require("../../subquery.cjs");
  39. var import_table = require("../../table.cjs");
  40. var import_tracing = require("../../tracing.cjs");
  41. var import_utils = require("../../utils.cjs");
  42. var import_utils2 = require("../../utils.cjs");
  43. var import_view_common = require("../../view-common.cjs");
  44. var import_utils3 = require("../utils.cjs");
  45. class GelSelectBuilder {
  46. static [import_entity.entityKind] = "GelSelectBuilder";
  47. fields;
  48. session;
  49. dialect;
  50. withList = [];
  51. distinct;
  52. constructor(config) {
  53. this.fields = config.fields;
  54. this.session = config.session;
  55. this.dialect = config.dialect;
  56. if (config.withList) {
  57. this.withList = config.withList;
  58. }
  59. this.distinct = config.distinct;
  60. }
  61. authToken;
  62. /** @internal */
  63. setToken(token) {
  64. this.authToken = token;
  65. return this;
  66. }
  67. /**
  68. * Specify the table, subquery, or other target that you're
  69. * building a select query against.
  70. *
  71. * {@link https://www.postgresql.org/docs/current/sql-select.html#SQL-FROM | Postgres from documentation}
  72. */
  73. from(source) {
  74. const isPartialSelect = !!this.fields;
  75. let fields;
  76. if (this.fields) {
  77. fields = this.fields;
  78. } else if ((0, import_entity.is)(source, import_subquery.Subquery)) {
  79. fields = Object.fromEntries(
  80. Object.keys(source._.selectedFields).map((key) => [key, source[key]])
  81. );
  82. } else if ((0, import_entity.is)(source, import_view_base.GelViewBase)) {
  83. fields = source[import_view_common.ViewBaseConfig].selectedFields;
  84. } else if ((0, import_entity.is)(source, import_sql.SQL)) {
  85. fields = {};
  86. } else {
  87. fields = (0, import_utils.getTableColumns)(source);
  88. }
  89. return new GelSelectBase({
  90. table: source,
  91. fields,
  92. isPartialSelect,
  93. session: this.session,
  94. dialect: this.dialect,
  95. withList: this.withList,
  96. distinct: this.distinct
  97. });
  98. }
  99. }
  100. class GelSelectQueryBuilderBase extends import_query_builder.TypedQueryBuilder {
  101. static [import_entity.entityKind] = "GelSelectQueryBuilder";
  102. _;
  103. config;
  104. joinsNotNullableMap;
  105. tableName;
  106. isPartialSelect;
  107. session;
  108. dialect;
  109. cacheConfig = void 0;
  110. usedTables = /* @__PURE__ */ new Set();
  111. constructor({ table, fields, isPartialSelect, session, dialect, withList, distinct }) {
  112. super();
  113. this.config = {
  114. withList,
  115. table,
  116. fields: { ...fields },
  117. distinct,
  118. setOperators: []
  119. };
  120. this.isPartialSelect = isPartialSelect;
  121. this.session = session;
  122. this.dialect = dialect;
  123. this._ = {
  124. selectedFields: fields,
  125. config: this.config
  126. };
  127. this.tableName = (0, import_utils.getTableLikeName)(table);
  128. this.joinsNotNullableMap = typeof this.tableName === "string" ? { [this.tableName]: true } : {};
  129. for (const item of (0, import_utils3.extractUsedTable)(table)) this.usedTables.add(item);
  130. }
  131. /** @internal */
  132. getUsedTables() {
  133. return [...this.usedTables];
  134. }
  135. createJoin(joinType, lateral) {
  136. return (table, on) => {
  137. const baseTableName = this.tableName;
  138. const tableName = (0, import_utils.getTableLikeName)(table);
  139. if (typeof tableName === "string" && this.config.joins?.some((join) => join.alias === tableName)) {
  140. throw new Error(`Alias "${tableName}" is already used in this query`);
  141. }
  142. for (const item of (0, import_utils3.extractUsedTable)(table)) this.usedTables.add(item);
  143. if (!this.isPartialSelect) {
  144. if (Object.keys(this.joinsNotNullableMap).length === 1 && typeof baseTableName === "string") {
  145. this.config.fields = {
  146. [baseTableName]: this.config.fields
  147. };
  148. }
  149. if (typeof tableName === "string" && !(0, import_entity.is)(table, import_sql.SQL)) {
  150. const selection = (0, import_entity.is)(table, import_subquery.Subquery) ? table._.selectedFields : (0, import_entity.is)(table, import_sql.View) ? table[import_view_common.ViewBaseConfig].selectedFields : table[import_table.Table.Symbol.Columns];
  151. this.config.fields[tableName] = selection;
  152. }
  153. }
  154. if (typeof on === "function") {
  155. on = on(
  156. new Proxy(
  157. this.config.fields,
  158. new import_selection_proxy.SelectionProxyHandler({ sqlAliasedBehavior: "sql", sqlBehavior: "sql" })
  159. )
  160. );
  161. }
  162. if (!this.config.joins) {
  163. this.config.joins = [];
  164. }
  165. this.config.joins.push({ on, table, joinType, alias: tableName, lateral });
  166. if (typeof tableName === "string") {
  167. switch (joinType) {
  168. case "left": {
  169. this.joinsNotNullableMap[tableName] = false;
  170. break;
  171. }
  172. case "right": {
  173. this.joinsNotNullableMap = Object.fromEntries(
  174. Object.entries(this.joinsNotNullableMap).map(([key]) => [key, false])
  175. );
  176. this.joinsNotNullableMap[tableName] = true;
  177. break;
  178. }
  179. case "cross":
  180. case "inner": {
  181. this.joinsNotNullableMap[tableName] = true;
  182. break;
  183. }
  184. case "full": {
  185. this.joinsNotNullableMap = Object.fromEntries(
  186. Object.entries(this.joinsNotNullableMap).map(([key]) => [key, false])
  187. );
  188. this.joinsNotNullableMap[tableName] = false;
  189. break;
  190. }
  191. }
  192. }
  193. return this;
  194. };
  195. }
  196. /**
  197. * Executes a `left join` operation by adding another table to the current query.
  198. *
  199. * Calling this method associates each row of the table with the corresponding row from the joined table, if a match is found. If no matching row exists, it sets all columns of the joined table to null.
  200. *
  201. * See docs: {@link https://orm.drizzle.team/docs/joins#left-join}
  202. *
  203. * @param table the table to join.
  204. * @param on the `on` clause.
  205. *
  206. * @example
  207. *
  208. * ```ts
  209. * // Select all users and their pets
  210. * const usersWithPets: { user: User; pets: Pet | null; }[] = await db.select()
  211. * .from(users)
  212. * .leftJoin(pets, eq(users.id, pets.ownerId))
  213. *
  214. * // Select userId and petId
  215. * const usersIdsAndPetIds: { userId: number; petId: number | null; }[] = await db.select({
  216. * userId: users.id,
  217. * petId: pets.id,
  218. * })
  219. * .from(users)
  220. * .leftJoin(pets, eq(users.id, pets.ownerId))
  221. * ```
  222. */
  223. leftJoin = this.createJoin("left", false);
  224. /**
  225. * Executes a `left join lateral` operation by adding subquery to the current query.
  226. *
  227. * A `lateral` join allows the right-hand expression to refer to columns from the left-hand side.
  228. *
  229. * Calling this method associates each row of the table with the corresponding row from the joined table, if a match is found. If no matching row exists, it sets all columns of the joined table to null.
  230. *
  231. * See docs: {@link https://orm.drizzle.team/docs/joins#left-join-lateral}
  232. *
  233. * @param table the subquery to join.
  234. * @param on the `on` clause.
  235. */
  236. leftJoinLateral = this.createJoin("left", true);
  237. /**
  238. * Executes a `right join` operation by adding another table to the current query.
  239. *
  240. * Calling this method associates each row of the joined table with the corresponding row from the main table, if a match is found. If no matching row exists, it sets all columns of the main table to null.
  241. *
  242. * See docs: {@link https://orm.drizzle.team/docs/joins#right-join}
  243. *
  244. * @param table the table to join.
  245. * @param on the `on` clause.
  246. *
  247. * @example
  248. *
  249. * ```ts
  250. * // Select all users and their pets
  251. * const usersWithPets: { user: User | null; pets: Pet; }[] = await db.select()
  252. * .from(users)
  253. * .rightJoin(pets, eq(users.id, pets.ownerId))
  254. *
  255. * // Select userId and petId
  256. * const usersIdsAndPetIds: { userId: number | null; petId: number; }[] = await db.select({
  257. * userId: users.id,
  258. * petId: pets.id,
  259. * })
  260. * .from(users)
  261. * .rightJoin(pets, eq(users.id, pets.ownerId))
  262. * ```
  263. */
  264. rightJoin = this.createJoin("right", false);
  265. /**
  266. * Executes an `inner join` operation, creating a new table by combining rows from two tables that have matching values.
  267. *
  268. * Calling this method retrieves rows that have corresponding entries in both joined tables. Rows without matching entries in either table are excluded, resulting in a table that includes only matching pairs.
  269. *
  270. * See docs: {@link https://orm.drizzle.team/docs/joins#inner-join}
  271. *
  272. * @param table the table to join.
  273. * @param on the `on` clause.
  274. *
  275. * @example
  276. *
  277. * ```ts
  278. * // Select all users and their pets
  279. * const usersWithPets: { user: User; pets: Pet; }[] = await db.select()
  280. * .from(users)
  281. * .innerJoin(pets, eq(users.id, pets.ownerId))
  282. *
  283. * // Select userId and petId
  284. * const usersIdsAndPetIds: { userId: number; petId: number; }[] = await db.select({
  285. * userId: users.id,
  286. * petId: pets.id,
  287. * })
  288. * .from(users)
  289. * .innerJoin(pets, eq(users.id, pets.ownerId))
  290. * ```
  291. */
  292. innerJoin = this.createJoin("inner", false);
  293. /**
  294. * Executes an `inner join lateral` operation, creating a new table by combining rows from two queries that have matching values.
  295. *
  296. * A `lateral` join allows the right-hand expression to refer to columns from the left-hand side.
  297. *
  298. * Calling this method retrieves rows that have corresponding entries in both joined tables. Rows without matching entries in either table are excluded, resulting in a table that includes only matching pairs.
  299. *
  300. * See docs: {@link https://orm.drizzle.team/docs/joins#inner-join-lateral}
  301. *
  302. * @param table the subquery to join.
  303. * @param on the `on` clause.
  304. */
  305. innerJoinLateral = this.createJoin("inner", true);
  306. /**
  307. * Executes a `full join` operation by combining rows from two tables into a new table.
  308. *
  309. * Calling this method retrieves all rows from both main and joined tables, merging rows with matching values and filling in `null` for non-matching columns.
  310. *
  311. * See docs: {@link https://orm.drizzle.team/docs/joins#full-join}
  312. *
  313. * @param table the table to join.
  314. * @param on the `on` clause.
  315. *
  316. * @example
  317. *
  318. * ```ts
  319. * // Select all users and their pets
  320. * const usersWithPets: { user: User | null; pets: Pet | null; }[] = await db.select()
  321. * .from(users)
  322. * .fullJoin(pets, eq(users.id, pets.ownerId))
  323. *
  324. * // Select userId and petId
  325. * const usersIdsAndPetIds: { userId: number | null; petId: number | null; }[] = await db.select({
  326. * userId: users.id,
  327. * petId: pets.id,
  328. * })
  329. * .from(users)
  330. * .fullJoin(pets, eq(users.id, pets.ownerId))
  331. * ```
  332. */
  333. fullJoin = this.createJoin("full", false);
  334. /**
  335. * Executes a `cross join` operation by combining rows from two tables into a new table.
  336. *
  337. * Calling this method retrieves all rows from both main and joined tables, merging all rows from each table.
  338. *
  339. * See docs: {@link https://orm.drizzle.team/docs/joins#cross-join}
  340. *
  341. * @param table the table to join.
  342. *
  343. * @example
  344. *
  345. * ```ts
  346. * // Select all users, each user with every pet
  347. * const usersWithPets: { user: User; pets: Pet; }[] = await db.select()
  348. * .from(users)
  349. * .crossJoin(pets)
  350. *
  351. * // Select userId and petId
  352. * const usersIdsAndPetIds: { userId: number; petId: number; }[] = await db.select({
  353. * userId: users.id,
  354. * petId: pets.id,
  355. * })
  356. * .from(users)
  357. * .crossJoin(pets)
  358. * ```
  359. */
  360. crossJoin = this.createJoin("cross", false);
  361. /**
  362. * Executes a `cross join lateral` operation by combining rows from two queries into a new table.
  363. *
  364. * A `lateral` join allows the right-hand expression to refer to columns from the left-hand side.
  365. *
  366. * Calling this method retrieves all rows from both main and joined queries, merging all rows from each query.
  367. *
  368. * See docs: {@link https://orm.drizzle.team/docs/joins#cross-join-lateral}
  369. *
  370. * @param table the query to join.
  371. */
  372. crossJoinLateral = this.createJoin("cross", true);
  373. createSetOperator(type, isAll) {
  374. return (rightSelection) => {
  375. const rightSelect = typeof rightSelection === "function" ? rightSelection(getGelSetOperators()) : rightSelection;
  376. if (!(0, import_utils.haveSameKeys)(this.getSelectedFields(), rightSelect.getSelectedFields())) {
  377. throw new Error(
  378. "Set operator error (union / intersect / except): selected fields are not the same or are in a different order"
  379. );
  380. }
  381. this.config.setOperators.push({ type, isAll, rightSelect });
  382. return this;
  383. };
  384. }
  385. /**
  386. * Adds `union` set operator to the query.
  387. *
  388. * Calling this method will combine the result sets of the `select` statements and remove any duplicate rows that appear across them.
  389. *
  390. * See docs: {@link https://orm.drizzle.team/docs/set-operations#union}
  391. *
  392. * @example
  393. *
  394. * ```ts
  395. * // Select all unique names from customers and users tables
  396. * await db.select({ name: users.name })
  397. * .from(users)
  398. * .union(
  399. * db.select({ name: customers.name }).from(customers)
  400. * );
  401. * // or
  402. * import { union } from 'drizzle-orm/gel-core'
  403. *
  404. * await union(
  405. * db.select({ name: users.name }).from(users),
  406. * db.select({ name: customers.name }).from(customers)
  407. * );
  408. * ```
  409. */
  410. union = this.createSetOperator("union", false);
  411. /**
  412. * Adds `union all` set operator to the query.
  413. *
  414. * Calling this method will combine the result-set of the `select` statements and keep all duplicate rows that appear across them.
  415. *
  416. * See docs: {@link https://orm.drizzle.team/docs/set-operations#union-all}
  417. *
  418. * @example
  419. *
  420. * ```ts
  421. * // Select all transaction ids from both online and in-store sales
  422. * await db.select({ transaction: onlineSales.transactionId })
  423. * .from(onlineSales)
  424. * .unionAll(
  425. * db.select({ transaction: inStoreSales.transactionId }).from(inStoreSales)
  426. * );
  427. * // or
  428. * import { unionAll } from 'drizzle-orm/gel-core'
  429. *
  430. * await unionAll(
  431. * db.select({ transaction: onlineSales.transactionId }).from(onlineSales),
  432. * db.select({ transaction: inStoreSales.transactionId }).from(inStoreSales)
  433. * );
  434. * ```
  435. */
  436. unionAll = this.createSetOperator("union", true);
  437. /**
  438. * Adds `intersect` set operator to the query.
  439. *
  440. * Calling this method will retain only the rows that are present in both result sets and eliminate duplicates.
  441. *
  442. * See docs: {@link https://orm.drizzle.team/docs/set-operations#intersect}
  443. *
  444. * @example
  445. *
  446. * ```ts
  447. * // Select course names that are offered in both departments A and B
  448. * await db.select({ courseName: depA.courseName })
  449. * .from(depA)
  450. * .intersect(
  451. * db.select({ courseName: depB.courseName }).from(depB)
  452. * );
  453. * // or
  454. * import { intersect } from 'drizzle-orm/gel-core'
  455. *
  456. * await intersect(
  457. * db.select({ courseName: depA.courseName }).from(depA),
  458. * db.select({ courseName: depB.courseName }).from(depB)
  459. * );
  460. * ```
  461. */
  462. intersect = this.createSetOperator("intersect", false);
  463. /**
  464. * Adds `intersect all` set operator to the query.
  465. *
  466. * Calling this method will retain only the rows that are present in both result sets including all duplicates.
  467. *
  468. * See docs: {@link https://orm.drizzle.team/docs/set-operations#intersect-all}
  469. *
  470. * @example
  471. *
  472. * ```ts
  473. * // Select all products and quantities that are ordered by both regular and VIP customers
  474. * await db.select({
  475. * productId: regularCustomerOrders.productId,
  476. * quantityOrdered: regularCustomerOrders.quantityOrdered
  477. * })
  478. * .from(regularCustomerOrders)
  479. * .intersectAll(
  480. * db.select({
  481. * productId: vipCustomerOrders.productId,
  482. * quantityOrdered: vipCustomerOrders.quantityOrdered
  483. * })
  484. * .from(vipCustomerOrders)
  485. * );
  486. * // or
  487. * import { intersectAll } from 'drizzle-orm/gel-core'
  488. *
  489. * await intersectAll(
  490. * db.select({
  491. * productId: regularCustomerOrders.productId,
  492. * quantityOrdered: regularCustomerOrders.quantityOrdered
  493. * })
  494. * .from(regularCustomerOrders),
  495. * db.select({
  496. * productId: vipCustomerOrders.productId,
  497. * quantityOrdered: vipCustomerOrders.quantityOrdered
  498. * })
  499. * .from(vipCustomerOrders)
  500. * );
  501. * ```
  502. */
  503. intersectAll = this.createSetOperator("intersect", true);
  504. /**
  505. * Adds `except` set operator to the query.
  506. *
  507. * Calling this method will retrieve all unique rows from the left query, except for the rows that are present in the result set of the right query.
  508. *
  509. * See docs: {@link https://orm.drizzle.team/docs/set-operations#except}
  510. *
  511. * @example
  512. *
  513. * ```ts
  514. * // Select all courses offered in department A but not in department B
  515. * await db.select({ courseName: depA.courseName })
  516. * .from(depA)
  517. * .except(
  518. * db.select({ courseName: depB.courseName }).from(depB)
  519. * );
  520. * // or
  521. * import { except } from 'drizzle-orm/gel-core'
  522. *
  523. * await except(
  524. * db.select({ courseName: depA.courseName }).from(depA),
  525. * db.select({ courseName: depB.courseName }).from(depB)
  526. * );
  527. * ```
  528. */
  529. except = this.createSetOperator("except", false);
  530. /**
  531. * Adds `except all` set operator to the query.
  532. *
  533. * Calling this method will retrieve all rows from the left query, except for the rows that are present in the result set of the right query.
  534. *
  535. * See docs: {@link https://orm.drizzle.team/docs/set-operations#except-all}
  536. *
  537. * @example
  538. *
  539. * ```ts
  540. * // Select all products that are ordered by regular customers but not by VIP customers
  541. * await db.select({
  542. * productId: regularCustomerOrders.productId,
  543. * quantityOrdered: regularCustomerOrders.quantityOrdered,
  544. * })
  545. * .from(regularCustomerOrders)
  546. * .exceptAll(
  547. * db.select({
  548. * productId: vipCustomerOrders.productId,
  549. * quantityOrdered: vipCustomerOrders.quantityOrdered,
  550. * })
  551. * .from(vipCustomerOrders)
  552. * );
  553. * // or
  554. * import { exceptAll } from 'drizzle-orm/gel-core'
  555. *
  556. * await exceptAll(
  557. * db.select({
  558. * productId: regularCustomerOrders.productId,
  559. * quantityOrdered: regularCustomerOrders.quantityOrdered
  560. * })
  561. * .from(regularCustomerOrders),
  562. * db.select({
  563. * productId: vipCustomerOrders.productId,
  564. * quantityOrdered: vipCustomerOrders.quantityOrdered
  565. * })
  566. * .from(vipCustomerOrders)
  567. * );
  568. * ```
  569. */
  570. exceptAll = this.createSetOperator("except", true);
  571. /** @internal */
  572. addSetOperators(setOperators) {
  573. this.config.setOperators.push(...setOperators);
  574. return this;
  575. }
  576. /**
  577. * Adds a `where` clause to the query.
  578. *
  579. * Calling this method will select only those rows that fulfill a specified condition.
  580. *
  581. * See docs: {@link https://orm.drizzle.team/docs/select#filtering}
  582. *
  583. * @param where the `where` clause.
  584. *
  585. * @example
  586. * You can use conditional operators and `sql function` to filter the rows to be selected.
  587. *
  588. * ```ts
  589. * // Select all cars with green color
  590. * await db.select().from(cars).where(eq(cars.color, 'green'));
  591. * // or
  592. * await db.select().from(cars).where(sql`${cars.color} = 'green'`)
  593. * ```
  594. *
  595. * You can logically combine conditional operators with `and()` and `or()` operators:
  596. *
  597. * ```ts
  598. * // Select all BMW cars with a green color
  599. * await db.select().from(cars).where(and(eq(cars.color, 'green'), eq(cars.brand, 'BMW')));
  600. *
  601. * // Select all cars with the green or blue color
  602. * await db.select().from(cars).where(or(eq(cars.color, 'green'), eq(cars.color, 'blue')));
  603. * ```
  604. */
  605. where(where) {
  606. if (typeof where === "function") {
  607. where = where(
  608. new Proxy(
  609. this.config.fields,
  610. new import_selection_proxy.SelectionProxyHandler({ sqlAliasedBehavior: "sql", sqlBehavior: "sql" })
  611. )
  612. );
  613. }
  614. this.config.where = where;
  615. return this;
  616. }
  617. /**
  618. * Adds a `having` clause to the query.
  619. *
  620. * Calling this method will select only those rows that fulfill a specified condition. It is typically used with aggregate functions to filter the aggregated data based on a specified condition.
  621. *
  622. * See docs: {@link https://orm.drizzle.team/docs/select#aggregations}
  623. *
  624. * @param having the `having` clause.
  625. *
  626. * @example
  627. *
  628. * ```ts
  629. * // Select all brands with more than one car
  630. * await db.select({
  631. * brand: cars.brand,
  632. * count: sql<number>`cast(count(${cars.id}) as int)`,
  633. * })
  634. * .from(cars)
  635. * .groupBy(cars.brand)
  636. * .having(({ count }) => gt(count, 1));
  637. * ```
  638. */
  639. having(having) {
  640. if (typeof having === "function") {
  641. having = having(
  642. new Proxy(
  643. this.config.fields,
  644. new import_selection_proxy.SelectionProxyHandler({ sqlAliasedBehavior: "sql", sqlBehavior: "sql" })
  645. )
  646. );
  647. }
  648. this.config.having = having;
  649. return this;
  650. }
  651. groupBy(...columns) {
  652. if (typeof columns[0] === "function") {
  653. const groupBy = columns[0](
  654. new Proxy(
  655. this.config.fields,
  656. new import_selection_proxy.SelectionProxyHandler({ sqlAliasedBehavior: "alias", sqlBehavior: "sql" })
  657. )
  658. );
  659. this.config.groupBy = Array.isArray(groupBy) ? groupBy : [groupBy];
  660. } else {
  661. this.config.groupBy = columns;
  662. }
  663. return this;
  664. }
  665. orderBy(...columns) {
  666. if (typeof columns[0] === "function") {
  667. const orderBy = columns[0](
  668. new Proxy(
  669. this.config.fields,
  670. new import_selection_proxy.SelectionProxyHandler({ sqlAliasedBehavior: "alias", sqlBehavior: "sql" })
  671. )
  672. );
  673. const orderByArray = Array.isArray(orderBy) ? orderBy : [orderBy];
  674. if (this.config.setOperators.length > 0) {
  675. this.config.setOperators.at(-1).orderBy = orderByArray;
  676. } else {
  677. this.config.orderBy = orderByArray;
  678. }
  679. } else {
  680. const orderByArray = columns;
  681. if (this.config.setOperators.length > 0) {
  682. this.config.setOperators.at(-1).orderBy = orderByArray;
  683. } else {
  684. this.config.orderBy = orderByArray;
  685. }
  686. }
  687. return this;
  688. }
  689. /**
  690. * Adds a `limit` clause to the query.
  691. *
  692. * Calling this method will set the maximum number of rows that will be returned by this query.
  693. *
  694. * See docs: {@link https://orm.drizzle.team/docs/select#limit--offset}
  695. *
  696. * @param limit the `limit` clause.
  697. *
  698. * @example
  699. *
  700. * ```ts
  701. * // Get the first 10 people from this query.
  702. * await db.select().from(people).limit(10);
  703. * ```
  704. */
  705. limit(limit) {
  706. if (this.config.setOperators.length > 0) {
  707. this.config.setOperators.at(-1).limit = limit;
  708. } else {
  709. this.config.limit = limit;
  710. }
  711. return this;
  712. }
  713. /**
  714. * Adds an `offset` clause to the query.
  715. *
  716. * Calling this method will skip a number of rows when returning results from this query.
  717. *
  718. * See docs: {@link https://orm.drizzle.team/docs/select#limit--offset}
  719. *
  720. * @param offset the `offset` clause.
  721. *
  722. * @example
  723. *
  724. * ```ts
  725. * // Get the 10th-20th people from this query.
  726. * await db.select().from(people).offset(10).limit(10);
  727. * ```
  728. */
  729. offset(offset) {
  730. if (this.config.setOperators.length > 0) {
  731. this.config.setOperators.at(-1).offset = offset;
  732. } else {
  733. this.config.offset = offset;
  734. }
  735. return this;
  736. }
  737. /**
  738. * Adds a `for` clause to the query.
  739. *
  740. * Calling this method will specify a lock strength for this query that controls how strictly it acquires exclusive access to the rows being queried.
  741. *
  742. * See docs: {@link https://www.postgresql.org/docs/current/sql-select.html#SQL-FOR-UPDATE-SHARE}
  743. *
  744. * @param strength the lock strength.
  745. * @param config the lock configuration.
  746. */
  747. for(strength, config = {}) {
  748. this.config.lockingClause = { strength, config };
  749. return this;
  750. }
  751. /** @internal */
  752. getSQL() {
  753. return this.dialect.buildSelectQuery(this.config);
  754. }
  755. toSQL() {
  756. const { typings: _typings, ...rest } = this.dialect.sqlToQuery(this.getSQL());
  757. return rest;
  758. }
  759. as(alias) {
  760. const usedTables = [];
  761. usedTables.push(...(0, import_utils3.extractUsedTable)(this.config.table));
  762. if (this.config.joins) {
  763. for (const it of this.config.joins) usedTables.push(...(0, import_utils3.extractUsedTable)(it.table));
  764. }
  765. return new Proxy(
  766. new import_subquery.Subquery(this.getSQL(), this.config.fields, alias, false, [...new Set(usedTables)]),
  767. new import_selection_proxy.SelectionProxyHandler({ alias, sqlAliasedBehavior: "alias", sqlBehavior: "error" })
  768. );
  769. }
  770. /** @internal */
  771. getSelectedFields() {
  772. return new Proxy(
  773. this.config.fields,
  774. new import_selection_proxy.SelectionProxyHandler({ alias: this.tableName, sqlAliasedBehavior: "alias", sqlBehavior: "error" })
  775. );
  776. }
  777. $dynamic() {
  778. return this;
  779. }
  780. }
  781. class GelSelectBase extends GelSelectQueryBuilderBase {
  782. static [import_entity.entityKind] = "GelSelect";
  783. /** @internal */
  784. _prepare(name) {
  785. const { session, config, dialect, joinsNotNullableMap, cacheConfig, usedTables } = this;
  786. if (!session) {
  787. throw new Error("Cannot execute a query on a query builder. Please use a database instance instead.");
  788. }
  789. return import_tracing.tracer.startActiveSpan("drizzle.prepareQuery", () => {
  790. const fieldsList = (0, import_utils2.orderSelectedFields)(config.fields);
  791. const query = session.prepareQuery(dialect.sqlToQuery(this.getSQL()), fieldsList, name, true, void 0, {
  792. type: "select",
  793. tables: [...usedTables]
  794. }, cacheConfig);
  795. query.joinsNotNullableMap = joinsNotNullableMap;
  796. return query;
  797. });
  798. }
  799. $withCache(config) {
  800. this.cacheConfig = config === void 0 ? { config: {}, enable: true, autoInvalidate: true } : config === false ? { enable: false } : { enable: true, autoInvalidate: true, ...config };
  801. return this;
  802. }
  803. /**
  804. * Create a prepared statement for this query. This allows
  805. * the database to remember this query for the given session
  806. * and call it by name, rather than specifying the full query.
  807. *
  808. * {@link https://www.postgresql.org/docs/current/sql-prepare.html | Postgres prepare documentation}
  809. */
  810. prepare(name) {
  811. return this._prepare(name);
  812. }
  813. execute = (placeholderValues) => {
  814. return import_tracing.tracer.startActiveSpan("drizzle.operation", () => {
  815. return this._prepare().execute(placeholderValues);
  816. });
  817. };
  818. }
  819. (0, import_utils.applyMixins)(GelSelectBase, [import_query_promise.QueryPromise]);
  820. function createSetOperator(type, isAll) {
  821. return (leftSelect, rightSelect, ...restSelects) => {
  822. const setOperators = [rightSelect, ...restSelects].map((select) => ({
  823. type,
  824. isAll,
  825. rightSelect: select
  826. }));
  827. for (const setOperator of setOperators) {
  828. if (!(0, import_utils.haveSameKeys)(leftSelect.getSelectedFields(), setOperator.rightSelect.getSelectedFields())) {
  829. throw new Error(
  830. "Set operator error (union / intersect / except): selected fields are not the same or are in a different order"
  831. );
  832. }
  833. }
  834. return leftSelect.addSetOperators(setOperators);
  835. };
  836. }
  837. const getGelSetOperators = () => ({
  838. union,
  839. unionAll,
  840. intersect,
  841. intersectAll,
  842. except,
  843. exceptAll
  844. });
  845. const union = createSetOperator("union", false);
  846. const unionAll = createSetOperator("union", true);
  847. const intersect = createSetOperator("intersect", false);
  848. const intersectAll = createSetOperator("intersect", true);
  849. const except = createSetOperator("except", false);
  850. const exceptAll = createSetOperator("except", true);
  851. // Annotate the CommonJS export names for ESM import in node:
  852. 0 && (module.exports = {
  853. GelSelectBase,
  854. GelSelectBuilder,
  855. GelSelectQueryBuilderBase,
  856. except,
  857. exceptAll,
  858. intersect,
  859. intersectAll,
  860. union,
  861. unionAll
  862. });
  863. //# sourceMappingURL=select.cjs.map