dialect.js 42 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123
  1. import { aliasedTable, aliasedTableColumn, mapColumnsInAliasedSQLToAlias, mapColumnsInSQLToAlias } from "../alias.js";
  2. import { CasingCache } from "../casing.js";
  3. import { Column } from "../column.js";
  4. import { entityKind, is } from "../entity.js";
  5. import { DrizzleError } from "../errors.js";
  6. import { GelColumn, GelDecimal, GelJson, GelUUID } from "./columns/index.js";
  7. import { GelTable } from "./table.js";
  8. import {
  9. getOperators,
  10. getOrderByOperators,
  11. Many,
  12. normalizeRelation,
  13. One
  14. } from "../relations.js";
  15. import { and, eq, View } from "../sql/index.js";
  16. import {
  17. Param,
  18. SQL,
  19. sql
  20. } from "../sql/sql.js";
  21. import { Subquery } from "../subquery.js";
  22. import { getTableName, getTableUniqueName, Table } from "../table.js";
  23. import { orderSelectedFields } from "../utils.js";
  24. import { ViewBaseConfig } from "../view-common.js";
  25. import { GelTimestamp } from "./columns/timestamp.js";
  26. import { GelViewBase } from "./view-base.js";
  27. class GelDialect {
  28. static [entityKind] = "GelDialect";
  29. /** @internal */
  30. casing;
  31. constructor(config) {
  32. this.casing = new CasingCache(config?.casing);
  33. }
  34. // TODO can not migrate gel with drizzle
  35. // async migrate(migrations: MigrationMeta[], session: GelSession, config: string | MigrationConfig): Promise<void> {
  36. // const migrationsTable = typeof config === 'string'
  37. // ? '__drizzle_migrations'
  38. // : config.migrationsTable ?? '__drizzle_migrations';
  39. // const migrationsSchema = typeof config === 'string' ? 'drizzle' : config.migrationsSchema ?? 'drizzle';
  40. // const migrationTableCreate = sql`
  41. // CREATE TABLE IF NOT EXISTS ${sql.identifier(migrationsSchema)}.${sql.identifier(migrationsTable)} (
  42. // id SERIAL PRIMARY KEY,
  43. // hash text NOT NULL,
  44. // created_at bigint
  45. // )
  46. // `;
  47. // await session.execute(sql`CREATE SCHEMA IF NOT EXISTS ${sql.identifier(migrationsSchema)}`);
  48. // await session.execute(migrationTableCreate);
  49. // const dbMigrations = await session.all<{ id: number; hash: string; created_at: string }>(
  50. // sql`select id, hash, created_at from ${sql.identifier(migrationsSchema)}.${
  51. // sql.identifier(migrationsTable)
  52. // } order by created_at desc limit 1`,
  53. // );
  54. // const lastDbMigration = dbMigrations[0];
  55. // await session.transaction(async (tx) => {
  56. // for await (const migration of migrations) {
  57. // if (
  58. // !lastDbMigration
  59. // || Number(lastDbMigration.created_at) < migration.folderMillis
  60. // ) {
  61. // for (const stmt of migration.sql) {
  62. // await tx.execute(sql.raw(stmt));
  63. // }
  64. // await tx.execute(
  65. // sql`insert into ${sql.identifier(migrationsSchema)}.${
  66. // sql.identifier(migrationsTable)
  67. // } ("hash", "created_at") values(${migration.hash}, ${migration.folderMillis})`,
  68. // );
  69. // }
  70. // }
  71. // });
  72. // }
  73. escapeName(name) {
  74. return `"${name}"`;
  75. }
  76. escapeParam(num) {
  77. return `$${num + 1}`;
  78. }
  79. escapeString(str) {
  80. return `'${str.replace(/'/g, "''")}'`;
  81. }
  82. buildWithCTE(queries) {
  83. if (!queries?.length) return void 0;
  84. const withSqlChunks = [sql`with `];
  85. for (const [i, w] of queries.entries()) {
  86. withSqlChunks.push(sql`${sql.identifier(w._.alias)} as (${w._.sql})`);
  87. if (i < queries.length - 1) {
  88. withSqlChunks.push(sql`, `);
  89. }
  90. }
  91. withSqlChunks.push(sql` `);
  92. return sql.join(withSqlChunks);
  93. }
  94. buildDeleteQuery({ table, where, returning, withList }) {
  95. const withSql = this.buildWithCTE(withList);
  96. const returningSql = returning ? sql` returning ${this.buildSelection(returning, { isSingleTable: true })}` : void 0;
  97. const whereSql = where ? sql` where ${where}` : void 0;
  98. return sql`${withSql}delete from ${table}${whereSql}${returningSql}`;
  99. }
  100. buildUpdateSet(table, set) {
  101. const tableColumns = table[Table.Symbol.Columns];
  102. const columnNames = Object.keys(tableColumns).filter(
  103. (colName) => set[colName] !== void 0 || tableColumns[colName]?.onUpdateFn !== void 0
  104. );
  105. const setSize = columnNames.length;
  106. return sql.join(columnNames.flatMap((colName, i) => {
  107. const col = tableColumns[colName];
  108. const onUpdateFnResult = col.onUpdateFn?.();
  109. const value = set[colName] ?? (is(onUpdateFnResult, SQL) ? onUpdateFnResult : sql.param(onUpdateFnResult, col));
  110. const res = sql`${sql.identifier(this.casing.getColumnCasing(col))} = ${value}`;
  111. if (i < setSize - 1) {
  112. return [res, sql.raw(", ")];
  113. }
  114. return [res];
  115. }));
  116. }
  117. buildUpdateQuery({ table, set, where, returning, withList, from, joins }) {
  118. const withSql = this.buildWithCTE(withList);
  119. const tableName = table[GelTable.Symbol.Name];
  120. const tableSchema = table[GelTable.Symbol.Schema];
  121. const origTableName = table[GelTable.Symbol.OriginalName];
  122. const alias = tableName === origTableName ? void 0 : tableName;
  123. const tableSql = sql`${tableSchema ? sql`${sql.identifier(tableSchema)}.` : void 0}${sql.identifier(origTableName)}${alias && sql` ${sql.identifier(alias)}`}`;
  124. const setSql = this.buildUpdateSet(table, set);
  125. const fromSql = from && sql.join([sql.raw(" from "), this.buildFromTable(from)]);
  126. const joinsSql = this.buildJoins(joins);
  127. const returningSql = returning ? sql` returning ${this.buildSelection(returning, { isSingleTable: !from })}` : void 0;
  128. const whereSql = where ? sql` where ${where}` : void 0;
  129. return sql`${withSql}update ${tableSql} set ${setSql}${fromSql}${joinsSql}${whereSql}${returningSql}`;
  130. }
  131. /**
  132. * Builds selection SQL with provided fields/expressions
  133. *
  134. * Examples:
  135. *
  136. * `select <selection> from`
  137. *
  138. * `insert ... returning <selection>`
  139. *
  140. * If `isSingleTable` is true, then columns won't be prefixed with table name
  141. * ^ Temporarily disabled behaviour, see comments within method for a reasoning
  142. */
  143. buildSelection(fields, { isSingleTable = false } = {}) {
  144. const columnsLen = fields.length;
  145. const chunks = fields.flatMap(({ field }, i) => {
  146. const chunk = [];
  147. if (is(field, SQL.Aliased) && field.isSelectionField) {
  148. chunk.push(sql.identifier(field.fieldAlias));
  149. } else if (is(field, SQL.Aliased) || is(field, SQL)) {
  150. const query = is(field, SQL.Aliased) ? field.sql : field;
  151. chunk.push(query);
  152. if (is(field, SQL.Aliased)) {
  153. chunk.push(sql` as ${sql.identifier(field.fieldAlias)}`);
  154. }
  155. } else if (is(field, Column)) {
  156. chunk.push(field);
  157. } else if (is(field, Subquery)) {
  158. const entries = Object.entries(field._.selectedFields);
  159. if (entries.length === 1) {
  160. const entry = entries[0][1];
  161. const fieldDecoder = is(entry, SQL) ? entry.decoder : is(entry, Column) ? { mapFromDriverValue: (v) => entry.mapFromDriverValue(v) } : entry.sql.decoder;
  162. if (fieldDecoder) {
  163. field._.sql.decoder = fieldDecoder;
  164. }
  165. }
  166. chunk.push(field);
  167. }
  168. if (i < columnsLen - 1) {
  169. chunk.push(sql`, `);
  170. }
  171. return chunk;
  172. });
  173. return sql.join(chunks);
  174. }
  175. buildJoins(joins) {
  176. if (!joins || joins.length === 0) {
  177. return void 0;
  178. }
  179. const joinsArray = [];
  180. for (const [index, joinMeta] of joins.entries()) {
  181. if (index === 0) {
  182. joinsArray.push(sql` `);
  183. }
  184. const table = joinMeta.table;
  185. const lateralSql = joinMeta.lateral ? sql` lateral` : void 0;
  186. const onSql = joinMeta.on ? sql` on ${joinMeta.on}` : void 0;
  187. if (is(table, GelTable)) {
  188. const tableName = table[GelTable.Symbol.Name];
  189. const tableSchema = table[GelTable.Symbol.Schema];
  190. const origTableName = table[GelTable.Symbol.OriginalName];
  191. const alias = tableName === origTableName ? void 0 : joinMeta.alias;
  192. joinsArray.push(
  193. sql`${sql.raw(joinMeta.joinType)} join${lateralSql} ${tableSchema ? sql`${sql.identifier(tableSchema)}.` : void 0}${sql.identifier(origTableName)}${alias && sql` ${sql.identifier(alias)}`}${onSql}`
  194. );
  195. } else if (is(table, View)) {
  196. const viewName = table[ViewBaseConfig].name;
  197. const viewSchema = table[ViewBaseConfig].schema;
  198. const origViewName = table[ViewBaseConfig].originalName;
  199. const alias = viewName === origViewName ? void 0 : joinMeta.alias;
  200. joinsArray.push(
  201. sql`${sql.raw(joinMeta.joinType)} join${lateralSql} ${viewSchema ? sql`${sql.identifier(viewSchema)}.` : void 0}${sql.identifier(origViewName)}${alias && sql` ${sql.identifier(alias)}`}${onSql}`
  202. );
  203. } else {
  204. joinsArray.push(
  205. sql`${sql.raw(joinMeta.joinType)} join${lateralSql} ${table}${onSql}`
  206. );
  207. }
  208. if (index < joins.length - 1) {
  209. joinsArray.push(sql` `);
  210. }
  211. }
  212. return sql.join(joinsArray);
  213. }
  214. buildFromTable(table) {
  215. if (is(table, Table) && table[Table.Symbol.OriginalName] !== table[Table.Symbol.Name]) {
  216. let fullName = sql`${sql.identifier(table[Table.Symbol.OriginalName])}`;
  217. if (table[Table.Symbol.Schema]) {
  218. fullName = sql`${sql.identifier(table[Table.Symbol.Schema])}.${fullName}`;
  219. }
  220. return sql`${fullName} ${sql.identifier(table[Table.Symbol.Name])}`;
  221. }
  222. return table;
  223. }
  224. buildSelectQuery({
  225. withList,
  226. fields,
  227. fieldsFlat,
  228. where,
  229. having,
  230. table,
  231. joins,
  232. orderBy,
  233. groupBy,
  234. limit,
  235. offset,
  236. lockingClause,
  237. distinct,
  238. setOperators
  239. }) {
  240. const fieldsList = fieldsFlat ?? orderSelectedFields(fields);
  241. for (const f of fieldsList) {
  242. if (is(f.field, Column) && getTableName(f.field.table) !== (is(table, Subquery) ? table._.alias : is(table, GelViewBase) ? table[ViewBaseConfig].name : is(table, SQL) ? void 0 : getTableName(table)) && !((table2) => joins?.some(
  243. ({ alias }) => alias === (table2[Table.Symbol.IsAlias] ? getTableName(table2) : table2[Table.Symbol.BaseName])
  244. ))(f.field.table)) {
  245. const tableName = getTableName(f.field.table);
  246. throw new Error(
  247. `Your "${f.path.join("->")}" field references a column "${tableName}"."${f.field.name}", but the table "${tableName}" is not part of the query! Did you forget to join it?`
  248. );
  249. }
  250. }
  251. const isSingleTable = !joins || joins.length === 0;
  252. const withSql = this.buildWithCTE(withList);
  253. let distinctSql;
  254. if (distinct) {
  255. distinctSql = distinct === true ? sql` distinct` : sql` distinct on (${sql.join(distinct.on, sql`, `)})`;
  256. }
  257. const selection = this.buildSelection(fieldsList, { isSingleTable });
  258. const tableSql = this.buildFromTable(table);
  259. const joinsSql = this.buildJoins(joins);
  260. const whereSql = where ? sql` where ${where}` : void 0;
  261. const havingSql = having ? sql` having ${having}` : void 0;
  262. let orderBySql;
  263. if (orderBy && orderBy.length > 0) {
  264. orderBySql = sql` order by ${sql.join(orderBy, sql`, `)}`;
  265. }
  266. let groupBySql;
  267. if (groupBy && groupBy.length > 0) {
  268. groupBySql = sql` group by ${sql.join(groupBy, sql`, `)}`;
  269. }
  270. const limitSql = typeof limit === "object" || typeof limit === "number" && limit >= 0 ? sql` limit ${limit}` : void 0;
  271. const offsetSql = offset ? sql` offset ${offset}` : void 0;
  272. const lockingClauseSql = sql.empty();
  273. if (lockingClause) {
  274. const clauseSql = sql` for ${sql.raw(lockingClause.strength)}`;
  275. if (lockingClause.config.of) {
  276. clauseSql.append(
  277. sql` of ${sql.join(
  278. Array.isArray(lockingClause.config.of) ? lockingClause.config.of : [lockingClause.config.of],
  279. sql`, `
  280. )}`
  281. );
  282. }
  283. if (lockingClause.config.noWait) {
  284. clauseSql.append(sql` nowait`);
  285. } else if (lockingClause.config.skipLocked) {
  286. clauseSql.append(sql` skip locked`);
  287. }
  288. lockingClauseSql.append(clauseSql);
  289. }
  290. const finalQuery = sql`${withSql}select${distinctSql} ${selection} from ${tableSql}${joinsSql}${whereSql}${groupBySql}${havingSql}${orderBySql}${limitSql}${offsetSql}${lockingClauseSql}`;
  291. if (setOperators.length > 0) {
  292. return this.buildSetOperations(finalQuery, setOperators);
  293. }
  294. return finalQuery;
  295. }
  296. buildSetOperations(leftSelect, setOperators) {
  297. const [setOperator, ...rest] = setOperators;
  298. if (!setOperator) {
  299. throw new Error("Cannot pass undefined values to any set operator");
  300. }
  301. if (rest.length === 0) {
  302. return this.buildSetOperationQuery({ leftSelect, setOperator });
  303. }
  304. return this.buildSetOperations(
  305. this.buildSetOperationQuery({ leftSelect, setOperator }),
  306. rest
  307. );
  308. }
  309. buildSetOperationQuery({
  310. leftSelect,
  311. setOperator: { type, isAll, rightSelect, limit, orderBy, offset }
  312. }) {
  313. const leftChunk = sql`(${leftSelect.getSQL()}) `;
  314. const rightChunk = sql`(${rightSelect.getSQL()})`;
  315. let orderBySql;
  316. if (orderBy && orderBy.length > 0) {
  317. const orderByValues = [];
  318. for (const singleOrderBy of orderBy) {
  319. if (is(singleOrderBy, GelColumn)) {
  320. orderByValues.push(sql.identifier(singleOrderBy.name));
  321. } else if (is(singleOrderBy, SQL)) {
  322. for (let i = 0; i < singleOrderBy.queryChunks.length; i++) {
  323. const chunk = singleOrderBy.queryChunks[i];
  324. if (is(chunk, GelColumn)) {
  325. singleOrderBy.queryChunks[i] = sql.identifier(chunk.name);
  326. }
  327. }
  328. orderByValues.push(sql`${singleOrderBy}`);
  329. } else {
  330. orderByValues.push(sql`${singleOrderBy}`);
  331. }
  332. }
  333. orderBySql = sql` order by ${sql.join(orderByValues, sql`, `)} `;
  334. }
  335. const limitSql = typeof limit === "object" || typeof limit === "number" && limit >= 0 ? sql` limit ${limit}` : void 0;
  336. const operatorChunk = sql.raw(`${type} ${isAll ? "all " : ""}`);
  337. const offsetSql = offset ? sql` offset ${offset}` : void 0;
  338. return sql`${leftChunk}${operatorChunk}${rightChunk}${orderBySql}${limitSql}${offsetSql}`;
  339. }
  340. buildInsertQuery({ table, values: valuesOrSelect, onConflict, returning, withList, select, overridingSystemValue_ }) {
  341. const valuesSqlList = [];
  342. const columns = table[Table.Symbol.Columns];
  343. const colEntries = Object.entries(columns).filter(([_, col]) => !col.shouldDisableInsert());
  344. const insertOrder = colEntries.map(
  345. ([, column]) => sql.identifier(this.casing.getColumnCasing(column))
  346. );
  347. if (select) {
  348. const select2 = valuesOrSelect;
  349. if (is(select2, SQL)) {
  350. valuesSqlList.push(select2);
  351. } else {
  352. valuesSqlList.push(select2.getSQL());
  353. }
  354. } else {
  355. const values = valuesOrSelect;
  356. valuesSqlList.push(sql.raw("values "));
  357. for (const [valueIndex, value] of values.entries()) {
  358. const valueList = [];
  359. for (const [fieldName, col] of colEntries) {
  360. const colValue = value[fieldName];
  361. if (colValue === void 0 || is(colValue, Param) && colValue.value === void 0) {
  362. if (col.defaultFn !== void 0) {
  363. const defaultFnResult = col.defaultFn();
  364. const defaultValue = is(defaultFnResult, SQL) ? defaultFnResult : sql.param(defaultFnResult, col);
  365. valueList.push(defaultValue);
  366. } else if (!col.default && col.onUpdateFn !== void 0) {
  367. const onUpdateFnResult = col.onUpdateFn();
  368. const newValue = is(onUpdateFnResult, SQL) ? onUpdateFnResult : sql.param(onUpdateFnResult, col);
  369. valueList.push(newValue);
  370. } else {
  371. valueList.push(sql`default`);
  372. }
  373. } else {
  374. valueList.push(colValue);
  375. }
  376. }
  377. valuesSqlList.push(valueList);
  378. if (valueIndex < values.length - 1) {
  379. valuesSqlList.push(sql`, `);
  380. }
  381. }
  382. }
  383. const withSql = this.buildWithCTE(withList);
  384. const valuesSql = sql.join(valuesSqlList);
  385. const returningSql = returning ? sql` returning ${this.buildSelection(returning, { isSingleTable: true })}` : void 0;
  386. const onConflictSql = onConflict ? sql` on conflict ${onConflict}` : void 0;
  387. const overridingSql = overridingSystemValue_ === true ? sql`overriding system value ` : void 0;
  388. return sql`${withSql}insert into ${table} ${insertOrder} ${overridingSql}${valuesSql}${onConflictSql}${returningSql}`;
  389. }
  390. buildRefreshMaterializedViewQuery({ view, concurrently, withNoData }) {
  391. const concurrentlySql = concurrently ? sql` concurrently` : void 0;
  392. const withNoDataSql = withNoData ? sql` with no data` : void 0;
  393. return sql`refresh materialized view${concurrentlySql} ${view}${withNoDataSql}`;
  394. }
  395. prepareTyping(encoder) {
  396. if (is(encoder, GelJson)) {
  397. return "json";
  398. } else if (is(encoder, GelDecimal)) {
  399. return "decimal";
  400. } else if (is(encoder, GelTimestamp)) {
  401. return "timestamp";
  402. } else if (is(encoder, GelUUID)) {
  403. return "uuid";
  404. } else {
  405. return "none";
  406. }
  407. }
  408. sqlToQuery(sql2, invokeSource) {
  409. return sql2.toQuery({
  410. casing: this.casing,
  411. escapeName: this.escapeName,
  412. escapeParam: this.escapeParam,
  413. escapeString: this.escapeString,
  414. prepareTyping: this.prepareTyping,
  415. invokeSource
  416. });
  417. }
  418. // buildRelationalQueryWithPK({
  419. // fullSchema,
  420. // schema,
  421. // tableNamesMap,
  422. // table,
  423. // tableConfig,
  424. // queryConfig: config,
  425. // tableAlias,
  426. // isRoot = false,
  427. // joinOn,
  428. // }: {
  429. // fullSchema: Record<string, unknown>;
  430. // schema: TablesRelationalConfig;
  431. // tableNamesMap: Record<string, string>;
  432. // table: GelTable;
  433. // tableConfig: TableRelationalConfig;
  434. // queryConfig: true | DBQueryConfig<'many', true>;
  435. // tableAlias: string;
  436. // isRoot?: boolean;
  437. // joinOn?: SQL;
  438. // }): BuildRelationalQueryResult<GelTable, GelColumn> {
  439. // // For { "<relation>": true }, return a table with selection of all columns
  440. // if (config === true) {
  441. // const selectionEntries = Object.entries(tableConfig.columns);
  442. // const selection: BuildRelationalQueryResult<GelTable, GelColumn>['selection'] = selectionEntries.map((
  443. // [key, value],
  444. // ) => ({
  445. // dbKey: value.name,
  446. // tsKey: key,
  447. // field: value as GelColumn,
  448. // relationTableTsKey: undefined,
  449. // isJson: false,
  450. // selection: [],
  451. // }));
  452. // return {
  453. // tableTsKey: tableConfig.tsName,
  454. // sql: table,
  455. // selection,
  456. // };
  457. // }
  458. // // let selection: BuildRelationalQueryResult<GelTable, GelColumn>['selection'] = [];
  459. // // let selectionForBuild = selection;
  460. // const aliasedColumns = Object.fromEntries(
  461. // Object.entries(tableConfig.columns).map(([key, value]) => [key, aliasedTableColumn(value, tableAlias)]),
  462. // );
  463. // const aliasedRelations = Object.fromEntries(
  464. // Object.entries(tableConfig.relations).map(([key, value]) => [key, aliasedRelation(value, tableAlias)]),
  465. // );
  466. // const aliasedFields = Object.assign({}, aliasedColumns, aliasedRelations);
  467. // let where, hasUserDefinedWhere;
  468. // if (config.where) {
  469. // const whereSql = typeof config.where === 'function' ? config.where(aliasedFields, operators) : config.where;
  470. // where = whereSql && mapColumnsInSQLToAlias(whereSql, tableAlias);
  471. // hasUserDefinedWhere = !!where;
  472. // }
  473. // where = and(joinOn, where);
  474. // // const fieldsSelection: { tsKey: string; value: GelColumn | SQL.Aliased; isExtra?: boolean }[] = [];
  475. // let joins: Join[] = [];
  476. // let selectedColumns: string[] = [];
  477. // // Figure out which columns to select
  478. // if (config.columns) {
  479. // let isIncludeMode = false;
  480. // for (const [field, value] of Object.entries(config.columns)) {
  481. // if (value === undefined) {
  482. // continue;
  483. // }
  484. // if (field in tableConfig.columns) {
  485. // if (!isIncludeMode && value === true) {
  486. // isIncludeMode = true;
  487. // }
  488. // selectedColumns.push(field);
  489. // }
  490. // }
  491. // if (selectedColumns.length > 0) {
  492. // selectedColumns = isIncludeMode
  493. // ? selectedColumns.filter((c) => config.columns?.[c] === true)
  494. // : Object.keys(tableConfig.columns).filter((key) => !selectedColumns.includes(key));
  495. // }
  496. // } else {
  497. // // Select all columns if selection is not specified
  498. // selectedColumns = Object.keys(tableConfig.columns);
  499. // }
  500. // // for (const field of selectedColumns) {
  501. // // const column = tableConfig.columns[field]! as GelColumn;
  502. // // fieldsSelection.push({ tsKey: field, value: column });
  503. // // }
  504. // let initiallySelectedRelations: {
  505. // tsKey: string;
  506. // queryConfig: true | DBQueryConfig<'many', false>;
  507. // relation: Relation;
  508. // }[] = [];
  509. // // let selectedRelations: BuildRelationalQueryResult<GelTable, GelColumn>['selection'] = [];
  510. // // Figure out which relations to select
  511. // if (config.with) {
  512. // initiallySelectedRelations = Object.entries(config.with)
  513. // .filter((entry): entry is [typeof entry[0], NonNullable<typeof entry[1]>] => !!entry[1])
  514. // .map(([tsKey, queryConfig]) => ({ tsKey, queryConfig, relation: tableConfig.relations[tsKey]! }));
  515. // }
  516. // const manyRelations = initiallySelectedRelations.filter((r) =>
  517. // is(r.relation, Many)
  518. // && (schema[tableNamesMap[r.relation.referencedTable[Table.Symbol.Name]]!]?.primaryKey.length ?? 0) > 0
  519. // );
  520. // // If this is the last Many relation (or there are no Many relations), we are on the innermost subquery level
  521. // const isInnermostQuery = manyRelations.length < 2;
  522. // const selectedExtras: {
  523. // tsKey: string;
  524. // value: SQL.Aliased;
  525. // }[] = [];
  526. // // Figure out which extras to select
  527. // if (isInnermostQuery && config.extras) {
  528. // const extras = typeof config.extras === 'function'
  529. // ? config.extras(aliasedFields, { sql })
  530. // : config.extras;
  531. // for (const [tsKey, value] of Object.entries(extras)) {
  532. // selectedExtras.push({
  533. // tsKey,
  534. // value: mapColumnsInAliasedSQLToAlias(value, tableAlias),
  535. // });
  536. // }
  537. // }
  538. // // Transform `fieldsSelection` into `selection`
  539. // // `fieldsSelection` shouldn't be used after this point
  540. // // for (const { tsKey, value, isExtra } of fieldsSelection) {
  541. // // selection.push({
  542. // // dbKey: is(value, SQL.Aliased) ? value.fieldAlias : tableConfig.columns[tsKey]!.name,
  543. // // tsKey,
  544. // // field: is(value, Column) ? aliasedTableColumn(value, tableAlias) : value,
  545. // // relationTableTsKey: undefined,
  546. // // isJson: false,
  547. // // isExtra,
  548. // // selection: [],
  549. // // });
  550. // // }
  551. // let orderByOrig = typeof config.orderBy === 'function'
  552. // ? config.orderBy(aliasedFields, orderByOperators)
  553. // : config.orderBy ?? [];
  554. // if (!Array.isArray(orderByOrig)) {
  555. // orderByOrig = [orderByOrig];
  556. // }
  557. // const orderBy = orderByOrig.map((orderByValue) => {
  558. // if (is(orderByValue, Column)) {
  559. // return aliasedTableColumn(orderByValue, tableAlias) as GelColumn;
  560. // }
  561. // return mapColumnsInSQLToAlias(orderByValue, tableAlias);
  562. // });
  563. // const limit = isInnermostQuery ? config.limit : undefined;
  564. // const offset = isInnermostQuery ? config.offset : undefined;
  565. // // For non-root queries without additional config except columns, return a table with selection
  566. // if (
  567. // !isRoot
  568. // && initiallySelectedRelations.length === 0
  569. // && selectedExtras.length === 0
  570. // && !where
  571. // && orderBy.length === 0
  572. // && limit === undefined
  573. // && offset === undefined
  574. // ) {
  575. // return {
  576. // tableTsKey: tableConfig.tsName,
  577. // sql: table,
  578. // selection: selectedColumns.map((key) => ({
  579. // dbKey: tableConfig.columns[key]!.name,
  580. // tsKey: key,
  581. // field: tableConfig.columns[key] as GelColumn,
  582. // relationTableTsKey: undefined,
  583. // isJson: false,
  584. // selection: [],
  585. // })),
  586. // };
  587. // }
  588. // const selectedRelationsWithoutPK:
  589. // // Process all relations without primary keys, because they need to be joined differently and will all be on the same query level
  590. // for (
  591. // const {
  592. // tsKey: selectedRelationTsKey,
  593. // queryConfig: selectedRelationConfigValue,
  594. // relation,
  595. // } of initiallySelectedRelations
  596. // ) {
  597. // const normalizedRelation = normalizeRelation(schema, tableNamesMap, relation);
  598. // const relationTableName = relation.referencedTable[Table.Symbol.Name];
  599. // const relationTableTsName = tableNamesMap[relationTableName]!;
  600. // const relationTable = schema[relationTableTsName]!;
  601. // if (relationTable.primaryKey.length > 0) {
  602. // continue;
  603. // }
  604. // const relationTableAlias = `${tableAlias}_${selectedRelationTsKey}`;
  605. // const joinOn = and(
  606. // ...normalizedRelation.fields.map((field, i) =>
  607. // eq(
  608. // aliasedTableColumn(normalizedRelation.references[i]!, relationTableAlias),
  609. // aliasedTableColumn(field, tableAlias),
  610. // )
  611. // ),
  612. // );
  613. // const builtRelation = this.buildRelationalQueryWithoutPK({
  614. // fullSchema,
  615. // schema,
  616. // tableNamesMap,
  617. // table: fullSchema[relationTableTsName] as GelTable,
  618. // tableConfig: schema[relationTableTsName]!,
  619. // queryConfig: selectedRelationConfigValue,
  620. // tableAlias: relationTableAlias,
  621. // joinOn,
  622. // nestedQueryRelation: relation,
  623. // });
  624. // const field = sql`${sql.identifier(relationTableAlias)}.${sql.identifier('data')}`.as(selectedRelationTsKey);
  625. // joins.push({
  626. // on: sql`true`,
  627. // table: new Subquery(builtRelation.sql as SQL, {}, relationTableAlias),
  628. // alias: relationTableAlias,
  629. // joinType: 'left',
  630. // lateral: true,
  631. // });
  632. // selectedRelations.push({
  633. // dbKey: selectedRelationTsKey,
  634. // tsKey: selectedRelationTsKey,
  635. // field,
  636. // relationTableTsKey: relationTableTsName,
  637. // isJson: true,
  638. // selection: builtRelation.selection,
  639. // });
  640. // }
  641. // const oneRelations = initiallySelectedRelations.filter((r): r is typeof r & { relation: One } =>
  642. // is(r.relation, One)
  643. // );
  644. // // Process all One relations with PKs, because they can all be joined on the same level
  645. // for (
  646. // const {
  647. // tsKey: selectedRelationTsKey,
  648. // queryConfig: selectedRelationConfigValue,
  649. // relation,
  650. // } of oneRelations
  651. // ) {
  652. // const normalizedRelation = normalizeRelation(schema, tableNamesMap, relation);
  653. // const relationTableName = relation.referencedTable[Table.Symbol.Name];
  654. // const relationTableTsName = tableNamesMap[relationTableName]!;
  655. // const relationTableAlias = `${tableAlias}_${selectedRelationTsKey}`;
  656. // const relationTable = schema[relationTableTsName]!;
  657. // if (relationTable.primaryKey.length === 0) {
  658. // continue;
  659. // }
  660. // const joinOn = and(
  661. // ...normalizedRelation.fields.map((field, i) =>
  662. // eq(
  663. // aliasedTableColumn(normalizedRelation.references[i]!, relationTableAlias),
  664. // aliasedTableColumn(field, tableAlias),
  665. // )
  666. // ),
  667. // );
  668. // const builtRelation = this.buildRelationalQueryWithPK({
  669. // fullSchema,
  670. // schema,
  671. // tableNamesMap,
  672. // table: fullSchema[relationTableTsName] as GelTable,
  673. // tableConfig: schema[relationTableTsName]!,
  674. // queryConfig: selectedRelationConfigValue,
  675. // tableAlias: relationTableAlias,
  676. // joinOn,
  677. // });
  678. // const field = sql`case when ${sql.identifier(relationTableAlias)} is null then null else json_build_array(${
  679. // sql.join(
  680. // builtRelation.selection.map(({ field }) =>
  681. // is(field, SQL.Aliased)
  682. // ? sql`${sql.identifier(relationTableAlias)}.${sql.identifier(field.fieldAlias)}`
  683. // : is(field, Column)
  684. // ? aliasedTableColumn(field, relationTableAlias)
  685. // : field
  686. // ),
  687. // sql`, `,
  688. // )
  689. // }) end`.as(selectedRelationTsKey);
  690. // const isLateralJoin = is(builtRelation.sql, SQL);
  691. // joins.push({
  692. // on: isLateralJoin ? sql`true` : joinOn,
  693. // table: is(builtRelation.sql, SQL)
  694. // ? new Subquery(builtRelation.sql, {}, relationTableAlias)
  695. // : aliasedTable(builtRelation.sql, relationTableAlias),
  696. // alias: relationTableAlias,
  697. // joinType: 'left',
  698. // lateral: is(builtRelation.sql, SQL),
  699. // });
  700. // selectedRelations.push({
  701. // dbKey: selectedRelationTsKey,
  702. // tsKey: selectedRelationTsKey,
  703. // field,
  704. // relationTableTsKey: relationTableTsName,
  705. // isJson: true,
  706. // selection: builtRelation.selection,
  707. // });
  708. // }
  709. // let distinct: GelSelectConfig['distinct'];
  710. // let tableFrom: GelTable | Subquery = table;
  711. // // Process first Many relation - each one requires a nested subquery
  712. // const manyRelation = manyRelations[0];
  713. // if (manyRelation) {
  714. // const {
  715. // tsKey: selectedRelationTsKey,
  716. // queryConfig: selectedRelationQueryConfig,
  717. // relation,
  718. // } = manyRelation;
  719. // distinct = {
  720. // on: tableConfig.primaryKey.map((c) => aliasedTableColumn(c as GelColumn, tableAlias)),
  721. // };
  722. // const normalizedRelation = normalizeRelation(schema, tableNamesMap, relation);
  723. // const relationTableName = relation.referencedTable[Table.Symbol.Name];
  724. // const relationTableTsName = tableNamesMap[relationTableName]!;
  725. // const relationTableAlias = `${tableAlias}_${selectedRelationTsKey}`;
  726. // const joinOn = and(
  727. // ...normalizedRelation.fields.map((field, i) =>
  728. // eq(
  729. // aliasedTableColumn(normalizedRelation.references[i]!, relationTableAlias),
  730. // aliasedTableColumn(field, tableAlias),
  731. // )
  732. // ),
  733. // );
  734. // const builtRelationJoin = this.buildRelationalQueryWithPK({
  735. // fullSchema,
  736. // schema,
  737. // tableNamesMap,
  738. // table: fullSchema[relationTableTsName] as GelTable,
  739. // tableConfig: schema[relationTableTsName]!,
  740. // queryConfig: selectedRelationQueryConfig,
  741. // tableAlias: relationTableAlias,
  742. // joinOn,
  743. // });
  744. // const builtRelationSelectionField = sql`case when ${
  745. // sql.identifier(relationTableAlias)
  746. // } is null then '[]' else json_agg(json_build_array(${
  747. // sql.join(
  748. // builtRelationJoin.selection.map(({ field }) =>
  749. // is(field, SQL.Aliased)
  750. // ? sql`${sql.identifier(relationTableAlias)}.${sql.identifier(field.fieldAlias)}`
  751. // : is(field, Column)
  752. // ? aliasedTableColumn(field, relationTableAlias)
  753. // : field
  754. // ),
  755. // sql`, `,
  756. // )
  757. // })) over (partition by ${sql.join(distinct.on, sql`, `)}) end`.as(selectedRelationTsKey);
  758. // const isLateralJoin = is(builtRelationJoin.sql, SQL);
  759. // joins.push({
  760. // on: isLateralJoin ? sql`true` : joinOn,
  761. // table: isLateralJoin
  762. // ? new Subquery(builtRelationJoin.sql as SQL, {}, relationTableAlias)
  763. // : aliasedTable(builtRelationJoin.sql as GelTable, relationTableAlias),
  764. // alias: relationTableAlias,
  765. // joinType: 'left',
  766. // lateral: isLateralJoin,
  767. // });
  768. // // Build the "from" subquery with the remaining Many relations
  769. // const builtTableFrom = this.buildRelationalQueryWithPK({
  770. // fullSchema,
  771. // schema,
  772. // tableNamesMap,
  773. // table,
  774. // tableConfig,
  775. // queryConfig: {
  776. // ...config,
  777. // where: undefined,
  778. // orderBy: undefined,
  779. // limit: undefined,
  780. // offset: undefined,
  781. // with: manyRelations.slice(1).reduce<NonNullable<typeof config['with']>>(
  782. // (result, { tsKey, queryConfig: configValue }) => {
  783. // result[tsKey] = configValue;
  784. // return result;
  785. // },
  786. // {},
  787. // ),
  788. // },
  789. // tableAlias,
  790. // });
  791. // selectedRelations.push({
  792. // dbKey: selectedRelationTsKey,
  793. // tsKey: selectedRelationTsKey,
  794. // field: builtRelationSelectionField,
  795. // relationTableTsKey: relationTableTsName,
  796. // isJson: true,
  797. // selection: builtRelationJoin.selection,
  798. // });
  799. // // selection = builtTableFrom.selection.map((item) =>
  800. // // is(item.field, SQL.Aliased)
  801. // // ? { ...item, field: sql`${sql.identifier(tableAlias)}.${sql.identifier(item.field.fieldAlias)}` }
  802. // // : item
  803. // // );
  804. // // selectionForBuild = [{
  805. // // dbKey: '*',
  806. // // tsKey: '*',
  807. // // field: sql`${sql.identifier(tableAlias)}.*`,
  808. // // selection: [],
  809. // // isJson: false,
  810. // // relationTableTsKey: undefined,
  811. // // }];
  812. // // const newSelectionItem: (typeof selection)[number] = {
  813. // // dbKey: selectedRelationTsKey,
  814. // // tsKey: selectedRelationTsKey,
  815. // // field,
  816. // // relationTableTsKey: relationTableTsName,
  817. // // isJson: true,
  818. // // selection: builtRelationJoin.selection,
  819. // // };
  820. // // selection.push(newSelectionItem);
  821. // // selectionForBuild.push(newSelectionItem);
  822. // tableFrom = is(builtTableFrom.sql, GelTable)
  823. // ? builtTableFrom.sql
  824. // : new Subquery(builtTableFrom.sql, {}, tableAlias);
  825. // }
  826. // if (selectedColumns.length === 0 && selectedRelations.length === 0 && selectedExtras.length === 0) {
  827. // throw new DrizzleError(`No fields selected for table "${tableConfig.tsName}" ("${tableAlias}")`);
  828. // }
  829. // let selection: BuildRelationalQueryResult<GelTable, GelColumn>['selection'];
  830. // function prepareSelectedColumns() {
  831. // return selectedColumns.map((key) => ({
  832. // dbKey: tableConfig.columns[key]!.name,
  833. // tsKey: key,
  834. // field: tableConfig.columns[key] as GelColumn,
  835. // relationTableTsKey: undefined,
  836. // isJson: false,
  837. // selection: [],
  838. // }));
  839. // }
  840. // function prepareSelectedExtras() {
  841. // return selectedExtras.map((item) => ({
  842. // dbKey: item.value.fieldAlias,
  843. // tsKey: item.tsKey,
  844. // field: item.value,
  845. // relationTableTsKey: undefined,
  846. // isJson: false,
  847. // selection: [],
  848. // }));
  849. // }
  850. // if (isRoot) {
  851. // selection = [
  852. // ...prepareSelectedColumns(),
  853. // ...prepareSelectedExtras(),
  854. // ];
  855. // }
  856. // if (hasUserDefinedWhere || orderBy.length > 0) {
  857. // tableFrom = new Subquery(
  858. // this.buildSelectQuery({
  859. // table: is(tableFrom, GelTable) ? aliasedTable(tableFrom, tableAlias) : tableFrom,
  860. // fields: {},
  861. // fieldsFlat: selectionForBuild.map(({ field }) => ({
  862. // path: [],
  863. // field: is(field, Column) ? aliasedTableColumn(field, tableAlias) : field,
  864. // })),
  865. // joins,
  866. // distinct,
  867. // }),
  868. // {},
  869. // tableAlias,
  870. // );
  871. // selectionForBuild = selection.map((item) =>
  872. // is(item.field, SQL.Aliased)
  873. // ? { ...item, field: sql`${sql.identifier(tableAlias)}.${sql.identifier(item.field.fieldAlias)}` }
  874. // : item
  875. // );
  876. // joins = [];
  877. // distinct = undefined;
  878. // }
  879. // const result = this.buildSelectQuery({
  880. // table: is(tableFrom, GelTable) ? aliasedTable(tableFrom, tableAlias) : tableFrom,
  881. // fields: {},
  882. // fieldsFlat: selectionForBuild.map(({ field }) => ({
  883. // path: [],
  884. // field: is(field, Column) ? aliasedTableColumn(field, tableAlias) : field,
  885. // })),
  886. // where,
  887. // limit,
  888. // offset,
  889. // joins,
  890. // orderBy,
  891. // distinct,
  892. // });
  893. // return {
  894. // tableTsKey: tableConfig.tsName,
  895. // sql: result,
  896. // selection,
  897. // };
  898. // }
  899. buildRelationalQueryWithoutPK({
  900. fullSchema,
  901. schema,
  902. tableNamesMap,
  903. table,
  904. tableConfig,
  905. queryConfig: config,
  906. tableAlias,
  907. nestedQueryRelation,
  908. joinOn
  909. }) {
  910. let selection = [];
  911. let limit, offset, orderBy = [], where;
  912. const joins = [];
  913. if (config === true) {
  914. const selectionEntries = Object.entries(tableConfig.columns);
  915. selection = selectionEntries.map(([key, value]) => ({
  916. dbKey: value.name,
  917. tsKey: key,
  918. field: aliasedTableColumn(value, tableAlias),
  919. relationTableTsKey: void 0,
  920. isJson: false,
  921. selection: []
  922. }));
  923. } else {
  924. const aliasedColumns = Object.fromEntries(
  925. Object.entries(tableConfig.columns).map(([key, value]) => [key, aliasedTableColumn(value, tableAlias)])
  926. );
  927. if (config.where) {
  928. const whereSql = typeof config.where === "function" ? config.where(aliasedColumns, getOperators()) : config.where;
  929. where = whereSql && mapColumnsInSQLToAlias(whereSql, tableAlias);
  930. }
  931. const fieldsSelection = [];
  932. let selectedColumns = [];
  933. if (config.columns) {
  934. let isIncludeMode = false;
  935. for (const [field, value] of Object.entries(config.columns)) {
  936. if (value === void 0) {
  937. continue;
  938. }
  939. if (field in tableConfig.columns) {
  940. if (!isIncludeMode && value === true) {
  941. isIncludeMode = true;
  942. }
  943. selectedColumns.push(field);
  944. }
  945. }
  946. if (selectedColumns.length > 0) {
  947. selectedColumns = isIncludeMode ? selectedColumns.filter((c) => config.columns?.[c] === true) : Object.keys(tableConfig.columns).filter((key) => !selectedColumns.includes(key));
  948. }
  949. } else {
  950. selectedColumns = Object.keys(tableConfig.columns);
  951. }
  952. for (const field of selectedColumns) {
  953. const column = tableConfig.columns[field];
  954. fieldsSelection.push({ tsKey: field, value: column });
  955. }
  956. let selectedRelations = [];
  957. if (config.with) {
  958. selectedRelations = Object.entries(config.with).filter((entry) => !!entry[1]).map(([tsKey, queryConfig]) => ({ tsKey, queryConfig, relation: tableConfig.relations[tsKey] }));
  959. }
  960. let extras;
  961. if (config.extras) {
  962. extras = typeof config.extras === "function" ? config.extras(aliasedColumns, { sql }) : config.extras;
  963. for (const [tsKey, value] of Object.entries(extras)) {
  964. fieldsSelection.push({
  965. tsKey,
  966. value: mapColumnsInAliasedSQLToAlias(value, tableAlias)
  967. });
  968. }
  969. }
  970. for (const { tsKey, value } of fieldsSelection) {
  971. selection.push({
  972. dbKey: is(value, SQL.Aliased) ? value.fieldAlias : tableConfig.columns[tsKey].name,
  973. tsKey,
  974. field: is(value, Column) ? aliasedTableColumn(value, tableAlias) : value,
  975. relationTableTsKey: void 0,
  976. isJson: false,
  977. selection: []
  978. });
  979. }
  980. let orderByOrig = typeof config.orderBy === "function" ? config.orderBy(aliasedColumns, getOrderByOperators()) : config.orderBy ?? [];
  981. if (!Array.isArray(orderByOrig)) {
  982. orderByOrig = [orderByOrig];
  983. }
  984. orderBy = orderByOrig.map((orderByValue) => {
  985. if (is(orderByValue, Column)) {
  986. return aliasedTableColumn(orderByValue, tableAlias);
  987. }
  988. return mapColumnsInSQLToAlias(orderByValue, tableAlias);
  989. });
  990. limit = config.limit;
  991. offset = config.offset;
  992. for (const {
  993. tsKey: selectedRelationTsKey,
  994. queryConfig: selectedRelationConfigValue,
  995. relation
  996. } of selectedRelations) {
  997. const normalizedRelation = normalizeRelation(schema, tableNamesMap, relation);
  998. const relationTableName = getTableUniqueName(relation.referencedTable);
  999. const relationTableTsName = tableNamesMap[relationTableName];
  1000. const relationTableAlias = `${tableAlias}_${selectedRelationTsKey}`;
  1001. const joinOn2 = and(
  1002. ...normalizedRelation.fields.map(
  1003. (field2, i) => eq(
  1004. aliasedTableColumn(normalizedRelation.references[i], relationTableAlias),
  1005. aliasedTableColumn(field2, tableAlias)
  1006. )
  1007. )
  1008. );
  1009. const builtRelation = this.buildRelationalQueryWithoutPK({
  1010. fullSchema,
  1011. schema,
  1012. tableNamesMap,
  1013. table: fullSchema[relationTableTsName],
  1014. tableConfig: schema[relationTableTsName],
  1015. queryConfig: is(relation, One) ? selectedRelationConfigValue === true ? { limit: 1 } : { ...selectedRelationConfigValue, limit: 1 } : selectedRelationConfigValue,
  1016. tableAlias: relationTableAlias,
  1017. joinOn: joinOn2,
  1018. nestedQueryRelation: relation
  1019. });
  1020. const field = sql`${sql.identifier(relationTableAlias)}.${sql.identifier("data")}`.as(selectedRelationTsKey);
  1021. joins.push({
  1022. on: sql`true`,
  1023. table: new Subquery(builtRelation.sql, {}, relationTableAlias),
  1024. alias: relationTableAlias,
  1025. joinType: "left",
  1026. lateral: true
  1027. });
  1028. selection.push({
  1029. dbKey: selectedRelationTsKey,
  1030. tsKey: selectedRelationTsKey,
  1031. field,
  1032. relationTableTsKey: relationTableTsName,
  1033. isJson: true,
  1034. selection: builtRelation.selection
  1035. });
  1036. }
  1037. }
  1038. if (selection.length === 0) {
  1039. throw new DrizzleError({ message: `No fields selected for table "${tableConfig.tsName}" ("${tableAlias}")` });
  1040. }
  1041. let result;
  1042. where = and(joinOn, where);
  1043. if (nestedQueryRelation) {
  1044. let field = sql`json_build_array(${sql.join(
  1045. selection.map(
  1046. ({ field: field2, tsKey, isJson }) => isJson ? sql`${sql.identifier(`${tableAlias}_${tsKey}`)}.${sql.identifier("data")}` : is(field2, SQL.Aliased) ? field2.sql : field2
  1047. ),
  1048. sql`, `
  1049. )})`;
  1050. if (is(nestedQueryRelation, Many)) {
  1051. field = sql`coalesce(json_agg(${field}${orderBy.length > 0 ? sql` order by ${sql.join(orderBy, sql`, `)}` : void 0}), '[]'::json)`;
  1052. }
  1053. const nestedSelection = [{
  1054. dbKey: "data",
  1055. tsKey: "data",
  1056. field: field.as("data"),
  1057. isJson: true,
  1058. relationTableTsKey: tableConfig.tsName,
  1059. selection
  1060. }];
  1061. const needsSubquery = limit !== void 0 || offset !== void 0 || orderBy.length > 0;
  1062. if (needsSubquery) {
  1063. result = this.buildSelectQuery({
  1064. table: aliasedTable(table, tableAlias),
  1065. fields: {},
  1066. fieldsFlat: [{
  1067. path: [],
  1068. field: sql.raw("*")
  1069. }],
  1070. where,
  1071. limit,
  1072. offset,
  1073. orderBy,
  1074. setOperators: []
  1075. });
  1076. where = void 0;
  1077. limit = void 0;
  1078. offset = void 0;
  1079. orderBy = [];
  1080. } else {
  1081. result = aliasedTable(table, tableAlias);
  1082. }
  1083. result = this.buildSelectQuery({
  1084. table: is(result, GelTable) ? result : new Subquery(result, {}, tableAlias),
  1085. fields: {},
  1086. fieldsFlat: nestedSelection.map(({ field: field2 }) => ({
  1087. path: [],
  1088. field: is(field2, Column) ? aliasedTableColumn(field2, tableAlias) : field2
  1089. })),
  1090. joins,
  1091. where,
  1092. limit,
  1093. offset,
  1094. orderBy,
  1095. setOperators: []
  1096. });
  1097. } else {
  1098. result = this.buildSelectQuery({
  1099. table: aliasedTable(table, tableAlias),
  1100. fields: {},
  1101. fieldsFlat: selection.map(({ field }) => ({
  1102. path: [],
  1103. field: is(field, Column) ? aliasedTableColumn(field, tableAlias) : field
  1104. })),
  1105. joins,
  1106. where,
  1107. limit,
  1108. offset,
  1109. orderBy,
  1110. setOperators: []
  1111. });
  1112. }
  1113. return {
  1114. tableTsKey: tableConfig.tsName,
  1115. sql: result,
  1116. selection
  1117. };
  1118. }
  1119. }
  1120. export {
  1121. GelDialect
  1122. };
  1123. //# sourceMappingURL=dialect.js.map