select.cjs 29 KB

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