dialect.cjs 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679
  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, except, desc) => {
  11. if (from && typeof from === "object" || typeof from === "function") {
  12. for (let key of __getOwnPropNames(from))
  13. if (!__hasOwnProp.call(to, key) && key !== except)
  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 dialect_exports = {};
  20. __export(dialect_exports, {
  21. SingleStoreDialect: () => SingleStoreDialect
  22. });
  23. module.exports = __toCommonJS(dialect_exports);
  24. var import_alias = require("../alias.cjs");
  25. var import_casing = require("../casing.cjs");
  26. var import_column = require("../column.cjs");
  27. var import_entity = require("../entity.cjs");
  28. var import_errors = require("../errors.cjs");
  29. var import_relations = require("../relations.cjs");
  30. var import_expressions = require("../sql/expressions/index.cjs");
  31. var import_sql = require("../sql/sql.cjs");
  32. var import_subquery = require("../subquery.cjs");
  33. var import_table = require("../table.cjs");
  34. var import_utils = require("../utils.cjs");
  35. var import_view_common = require("../view-common.cjs");
  36. var import_common = require("./columns/common.cjs");
  37. var import_table2 = require("./table.cjs");
  38. class SingleStoreDialect {
  39. static [import_entity.entityKind] = "SingleStoreDialect";
  40. /** @internal */
  41. casing;
  42. constructor(config) {
  43. this.casing = new import_casing.CasingCache(config?.casing);
  44. }
  45. async migrate(migrations, session, config) {
  46. const migrationsTable = config.migrationsTable ?? "__drizzle_migrations";
  47. const migrationTableCreate = import_sql.sql`
  48. create table if not exists ${import_sql.sql.identifier(migrationsTable)} (
  49. id serial primary key,
  50. hash text not null,
  51. created_at bigint
  52. )
  53. `;
  54. await session.execute(migrationTableCreate);
  55. const dbMigrations = await session.all(
  56. import_sql.sql`select id, hash, created_at from ${import_sql.sql.identifier(migrationsTable)} order by created_at desc limit 1`
  57. );
  58. const lastDbMigration = dbMigrations[0];
  59. await session.transaction(async (tx) => {
  60. for (const migration of migrations) {
  61. if (!lastDbMigration || Number(lastDbMigration.created_at) < migration.folderMillis) {
  62. for (const stmt of migration.sql) {
  63. await tx.execute(import_sql.sql.raw(stmt));
  64. }
  65. await tx.execute(
  66. import_sql.sql`insert into ${import_sql.sql.identifier(
  67. migrationsTable
  68. )} (\`hash\`, \`created_at\`) values(${migration.hash}, ${migration.folderMillis})`
  69. );
  70. }
  71. }
  72. });
  73. }
  74. escapeName(name) {
  75. return `\`${name.replace(/`/g, "``")}\``;
  76. }
  77. escapeParam(_num) {
  78. return `?`;
  79. }
  80. escapeString(str) {
  81. return `'${str.replace(/'/g, "''")}'`;
  82. }
  83. buildWithCTE(queries) {
  84. if (!queries?.length) return void 0;
  85. const withSqlChunks = [import_sql.sql`with `];
  86. for (const [i, w] of queries.entries()) {
  87. withSqlChunks.push(import_sql.sql`${import_sql.sql.identifier(w._.alias)} as (${w._.sql})`);
  88. if (i < queries.length - 1) {
  89. withSqlChunks.push(import_sql.sql`, `);
  90. }
  91. }
  92. withSqlChunks.push(import_sql.sql` `);
  93. return import_sql.sql.join(withSqlChunks);
  94. }
  95. buildDeleteQuery({
  96. table,
  97. where,
  98. returning,
  99. withList,
  100. limit,
  101. orderBy
  102. }) {
  103. const withSql = this.buildWithCTE(withList);
  104. const returningSql = returning ? import_sql.sql` returning ${this.buildSelection(returning, { isSingleTable: true })}` : void 0;
  105. const whereSql = where ? import_sql.sql` where ${where}` : void 0;
  106. const orderBySql = this.buildOrderBy(orderBy);
  107. const limitSql = this.buildLimit(limit);
  108. return import_sql.sql`${withSql}delete from ${table}${whereSql}${orderBySql}${limitSql}${returningSql}`;
  109. }
  110. buildUpdateSet(table, set) {
  111. const tableColumns = table[import_table.Table.Symbol.Columns];
  112. const columnNames = Object.keys(tableColumns).filter(
  113. (colName) => set[colName] !== void 0 || tableColumns[colName]?.onUpdateFn !== void 0
  114. );
  115. const setSize = columnNames.length;
  116. return import_sql.sql.join(
  117. columnNames.flatMap((colName, i) => {
  118. const col = tableColumns[colName];
  119. const onUpdateFnResult = col.onUpdateFn?.();
  120. const value = set[colName] ?? ((0, import_entity.is)(onUpdateFnResult, import_sql.SQL) ? onUpdateFnResult : import_sql.sql.param(onUpdateFnResult, col));
  121. const res = import_sql.sql`${import_sql.sql.identifier(this.casing.getColumnCasing(col))} = ${value}`;
  122. if (i < setSize - 1) {
  123. return [res, import_sql.sql.raw(", ")];
  124. }
  125. return [res];
  126. })
  127. );
  128. }
  129. buildUpdateQuery({
  130. table,
  131. set,
  132. where,
  133. returning,
  134. withList,
  135. limit,
  136. orderBy
  137. }) {
  138. const withSql = this.buildWithCTE(withList);
  139. const setSql = this.buildUpdateSet(table, set);
  140. const returningSql = returning ? import_sql.sql` returning ${this.buildSelection(returning, { isSingleTable: true })}` : void 0;
  141. const whereSql = where ? import_sql.sql` where ${where}` : void 0;
  142. const orderBySql = this.buildOrderBy(orderBy);
  143. const limitSql = this.buildLimit(limit);
  144. return import_sql.sql`${withSql}update ${table} set ${setSql}${whereSql}${orderBySql}${limitSql}${returningSql}`;
  145. }
  146. /**
  147. * Builds selection SQL with provided fields/expressions
  148. *
  149. * Examples:
  150. *
  151. * `select <selection> from`
  152. *
  153. * `insert ... returning <selection>`
  154. *
  155. * If `isSingleTable` is true, then columns won't be prefixed with table name
  156. */
  157. buildSelection(fields, { isSingleTable = false } = {}) {
  158. const columnsLen = fields.length;
  159. const chunks = fields.flatMap(({ field }, i) => {
  160. const chunk = [];
  161. if ((0, import_entity.is)(field, import_sql.SQL.Aliased) && field.isSelectionField) {
  162. chunk.push(import_sql.sql.identifier(field.fieldAlias));
  163. } else if ((0, import_entity.is)(field, import_sql.SQL.Aliased) || (0, import_entity.is)(field, import_sql.SQL)) {
  164. const query = (0, import_entity.is)(field, import_sql.SQL.Aliased) ? field.sql : field;
  165. if (isSingleTable) {
  166. chunk.push(
  167. new import_sql.SQL(
  168. query.queryChunks.map((c) => {
  169. if ((0, import_entity.is)(c, import_common.SingleStoreColumn)) {
  170. return import_sql.sql.identifier(this.casing.getColumnCasing(c));
  171. }
  172. return c;
  173. })
  174. )
  175. );
  176. } else {
  177. chunk.push(query);
  178. }
  179. if ((0, import_entity.is)(field, import_sql.SQL.Aliased)) {
  180. chunk.push(import_sql.sql` as ${import_sql.sql.identifier(field.fieldAlias)}`);
  181. }
  182. } else if ((0, import_entity.is)(field, import_column.Column)) {
  183. if (isSingleTable) {
  184. chunk.push(import_sql.sql.identifier(this.casing.getColumnCasing(field)));
  185. } else {
  186. chunk.push(field);
  187. }
  188. } else if ((0, import_entity.is)(field, import_subquery.Subquery)) {
  189. const entries = Object.entries(field._.selectedFields);
  190. if (entries.length === 1) {
  191. const entry = entries[0][1];
  192. const fieldDecoder = (0, import_entity.is)(entry, import_sql.SQL) ? entry.decoder : (0, import_entity.is)(entry, import_column.Column) ? { mapFromDriverValue: (v) => entry.mapFromDriverValue(v) } : entry.sql.decoder;
  193. if (fieldDecoder) {
  194. field._.sql.decoder = fieldDecoder;
  195. }
  196. }
  197. chunk.push(field);
  198. }
  199. if (i < columnsLen - 1) {
  200. chunk.push(import_sql.sql`, `);
  201. }
  202. return chunk;
  203. });
  204. return import_sql.sql.join(chunks);
  205. }
  206. buildLimit(limit) {
  207. return typeof limit === "object" || typeof limit === "number" && limit >= 0 ? import_sql.sql` limit ${limit}` : void 0;
  208. }
  209. buildOrderBy(orderBy) {
  210. return orderBy && orderBy.length > 0 ? import_sql.sql` order by ${import_sql.sql.join(orderBy, import_sql.sql`, `)}` : void 0;
  211. }
  212. buildSelectQuery({
  213. withList,
  214. fields,
  215. fieldsFlat,
  216. where,
  217. having,
  218. table,
  219. joins,
  220. orderBy,
  221. groupBy,
  222. limit,
  223. offset,
  224. lockingClause,
  225. distinct,
  226. setOperators
  227. }) {
  228. const fieldsList = fieldsFlat ?? (0, import_utils.orderSelectedFields)(fields);
  229. for (const f of fieldsList) {
  230. if ((0, import_entity.is)(f.field, import_column.Column) && (0, import_table.getTableName)(f.field.table) !== ((0, import_entity.is)(table, import_subquery.Subquery) ? table._.alias : (0, import_entity.is)(table, import_sql.SQL) ? void 0 : (0, import_table.getTableName)(table)) && !((table2) => joins?.some(
  231. ({ alias }) => alias === (table2[import_table.Table.Symbol.IsAlias] ? (0, import_table.getTableName)(table2) : table2[import_table.Table.Symbol.BaseName])
  232. ))(f.field.table)) {
  233. const tableName = (0, import_table.getTableName)(f.field.table);
  234. throw new Error(
  235. `Your "${f.path.join(
  236. "->"
  237. )}" field references a column "${tableName}"."${f.field.name}", but the table "${tableName}" is not part of the query! Did you forget to join it?`
  238. );
  239. }
  240. }
  241. const isSingleTable = !joins || joins.length === 0;
  242. const withSql = this.buildWithCTE(withList);
  243. const distinctSql = distinct ? import_sql.sql` distinct` : void 0;
  244. const selection = this.buildSelection(fieldsList, { isSingleTable });
  245. const tableSql = (() => {
  246. if ((0, import_entity.is)(table, import_table.Table) && table[import_table.Table.Symbol.IsAlias]) {
  247. return import_sql.sql`${import_sql.sql`${import_sql.sql.identifier(table[import_table.Table.Symbol.Schema] ?? "")}.`.if(table[import_table.Table.Symbol.Schema])}${import_sql.sql.identifier(
  248. table[import_table.Table.Symbol.OriginalName]
  249. )} ${import_sql.sql.identifier(table[import_table.Table.Symbol.Name])}`;
  250. }
  251. return table;
  252. })();
  253. const joinsArray = [];
  254. if (joins) {
  255. for (const [index, joinMeta] of joins.entries()) {
  256. if (index === 0) {
  257. joinsArray.push(import_sql.sql` `);
  258. }
  259. const table2 = joinMeta.table;
  260. const lateralSql = joinMeta.lateral ? import_sql.sql` lateral` : void 0;
  261. const onSql = joinMeta.on ? import_sql.sql` on ${joinMeta.on}` : void 0;
  262. if ((0, import_entity.is)(table2, import_table2.SingleStoreTable)) {
  263. const tableName = table2[import_table2.SingleStoreTable.Symbol.Name];
  264. const tableSchema = table2[import_table2.SingleStoreTable.Symbol.Schema];
  265. const origTableName = table2[import_table2.SingleStoreTable.Symbol.OriginalName];
  266. const alias = tableName === origTableName ? void 0 : joinMeta.alias;
  267. joinsArray.push(
  268. import_sql.sql`${import_sql.sql.raw(joinMeta.joinType)} join${lateralSql} ${tableSchema ? import_sql.sql`${import_sql.sql.identifier(tableSchema)}.` : void 0}${import_sql.sql.identifier(origTableName)}${alias && import_sql.sql` ${import_sql.sql.identifier(alias)}`}${onSql}`
  269. );
  270. } else if ((0, import_entity.is)(table2, import_sql.View)) {
  271. const viewName = table2[import_view_common.ViewBaseConfig].name;
  272. const viewSchema = table2[import_view_common.ViewBaseConfig].schema;
  273. const origViewName = table2[import_view_common.ViewBaseConfig].originalName;
  274. const alias = viewName === origViewName ? void 0 : joinMeta.alias;
  275. joinsArray.push(
  276. import_sql.sql`${import_sql.sql.raw(joinMeta.joinType)} join${lateralSql} ${viewSchema ? import_sql.sql`${import_sql.sql.identifier(viewSchema)}.` : void 0}${import_sql.sql.identifier(origViewName)}${alias && import_sql.sql` ${import_sql.sql.identifier(alias)}`}${onSql}`
  277. );
  278. } else {
  279. joinsArray.push(
  280. import_sql.sql`${import_sql.sql.raw(joinMeta.joinType)} join${lateralSql} ${table2}${onSql}`
  281. );
  282. }
  283. if (index < joins.length - 1) {
  284. joinsArray.push(import_sql.sql` `);
  285. }
  286. }
  287. }
  288. const joinsSql = import_sql.sql.join(joinsArray);
  289. const whereSql = where ? import_sql.sql` where ${where}` : void 0;
  290. const havingSql = having ? import_sql.sql` having ${having}` : void 0;
  291. const orderBySql = this.buildOrderBy(orderBy);
  292. const groupBySql = groupBy && groupBy.length > 0 ? import_sql.sql` group by ${import_sql.sql.join(groupBy, import_sql.sql`, `)}` : void 0;
  293. const limitSql = this.buildLimit(limit);
  294. const offsetSql = offset ? import_sql.sql` offset ${offset}` : void 0;
  295. let lockingClausesSql;
  296. if (lockingClause) {
  297. const { config, strength } = lockingClause;
  298. lockingClausesSql = import_sql.sql` for ${import_sql.sql.raw(strength)}`;
  299. if (config.noWait) {
  300. lockingClausesSql.append(import_sql.sql` nowait`);
  301. } else if (config.skipLocked) {
  302. lockingClausesSql.append(import_sql.sql` skip locked`);
  303. }
  304. }
  305. const finalQuery = import_sql.sql`${withSql}select${distinctSql} ${selection} from ${tableSql}${joinsSql}${whereSql}${groupBySql}${havingSql}${orderBySql}${limitSql}${offsetSql}${lockingClausesSql}`;
  306. if (setOperators.length > 0) {
  307. return this.buildSetOperations(finalQuery, setOperators);
  308. }
  309. return finalQuery;
  310. }
  311. buildSetOperations(leftSelect, setOperators) {
  312. const [setOperator, ...rest] = setOperators;
  313. if (!setOperator) {
  314. throw new Error("Cannot pass undefined values to any set operator");
  315. }
  316. if (rest.length === 0) {
  317. return this.buildSetOperationQuery({ leftSelect, setOperator });
  318. }
  319. return this.buildSetOperations(
  320. this.buildSetOperationQuery({ leftSelect, setOperator }),
  321. rest
  322. );
  323. }
  324. buildSetOperationQuery({
  325. leftSelect,
  326. setOperator: { type, isAll, rightSelect, limit, orderBy, offset }
  327. }) {
  328. const leftChunk = import_sql.sql`(${leftSelect.getSQL()}) `;
  329. const rightChunk = import_sql.sql`(${rightSelect.getSQL()})`;
  330. let orderBySql;
  331. if (orderBy && orderBy.length > 0) {
  332. const orderByValues = [];
  333. for (const orderByUnit of orderBy) {
  334. if ((0, import_entity.is)(orderByUnit, import_common.SingleStoreColumn)) {
  335. orderByValues.push(
  336. import_sql.sql.identifier(this.casing.getColumnCasing(orderByUnit))
  337. );
  338. } else if ((0, import_entity.is)(orderByUnit, import_sql.SQL)) {
  339. for (let i = 0; i < orderByUnit.queryChunks.length; i++) {
  340. const chunk = orderByUnit.queryChunks[i];
  341. if ((0, import_entity.is)(chunk, import_common.SingleStoreColumn)) {
  342. orderByUnit.queryChunks[i] = import_sql.sql.identifier(
  343. this.casing.getColumnCasing(chunk)
  344. );
  345. }
  346. }
  347. orderByValues.push(import_sql.sql`${orderByUnit}`);
  348. } else {
  349. orderByValues.push(import_sql.sql`${orderByUnit}`);
  350. }
  351. }
  352. orderBySql = import_sql.sql` order by ${import_sql.sql.join(orderByValues, import_sql.sql`, `)} `;
  353. }
  354. const limitSql = typeof limit === "object" || typeof limit === "number" && limit >= 0 ? import_sql.sql` limit ${limit}` : void 0;
  355. const operatorChunk = import_sql.sql.raw(`${type} ${isAll ? "all " : ""}`);
  356. const offsetSql = offset ? import_sql.sql` offset ${offset}` : void 0;
  357. return import_sql.sql`${leftChunk}${operatorChunk}${rightChunk}${orderBySql}${limitSql}${offsetSql}`;
  358. }
  359. buildInsertQuery({
  360. table,
  361. values,
  362. ignore,
  363. onConflict
  364. }) {
  365. const valuesSqlList = [];
  366. const columns = table[import_table.Table.Symbol.Columns];
  367. const colEntries = Object.entries(
  368. columns
  369. ).filter(([_, col]) => !col.shouldDisableInsert());
  370. const insertOrder = colEntries.map(([, column]) => import_sql.sql.identifier(this.casing.getColumnCasing(column)));
  371. const generatedIdsResponse = [];
  372. for (const [valueIndex, value] of values.entries()) {
  373. const generatedIds = {};
  374. const valueList = [];
  375. for (const [fieldName, col] of colEntries) {
  376. const colValue = value[fieldName];
  377. if (colValue === void 0 || (0, import_entity.is)(colValue, import_sql.Param) && colValue.value === void 0) {
  378. if (col.defaultFn !== void 0) {
  379. const defaultFnResult = col.defaultFn();
  380. generatedIds[fieldName] = defaultFnResult;
  381. const defaultValue = (0, import_entity.is)(defaultFnResult, import_sql.SQL) ? defaultFnResult : import_sql.sql.param(defaultFnResult, col);
  382. valueList.push(defaultValue);
  383. } else if (!col.default && col.onUpdateFn !== void 0) {
  384. const onUpdateFnResult = col.onUpdateFn();
  385. const newValue = (0, import_entity.is)(onUpdateFnResult, import_sql.SQL) ? onUpdateFnResult : import_sql.sql.param(onUpdateFnResult, col);
  386. valueList.push(newValue);
  387. } else {
  388. valueList.push(import_sql.sql`default`);
  389. }
  390. } else {
  391. if (col.defaultFn && (0, import_entity.is)(colValue, import_sql.Param)) {
  392. generatedIds[fieldName] = colValue.value;
  393. }
  394. valueList.push(colValue);
  395. }
  396. }
  397. generatedIdsResponse.push(generatedIds);
  398. valuesSqlList.push(valueList);
  399. if (valueIndex < values.length - 1) {
  400. valuesSqlList.push(import_sql.sql`, `);
  401. }
  402. }
  403. const valuesSql = import_sql.sql.join(valuesSqlList);
  404. const ignoreSql = ignore ? import_sql.sql` ignore` : void 0;
  405. const onConflictSql = onConflict ? import_sql.sql` on duplicate key ${onConflict}` : void 0;
  406. return {
  407. sql: import_sql.sql`insert${ignoreSql} into ${table} ${insertOrder} values ${valuesSql}${onConflictSql}`,
  408. generatedIds: generatedIdsResponse
  409. };
  410. }
  411. sqlToQuery(sql2, invokeSource) {
  412. return sql2.toQuery({
  413. casing: this.casing,
  414. escapeName: this.escapeName,
  415. escapeParam: this.escapeParam,
  416. escapeString: this.escapeString,
  417. invokeSource
  418. });
  419. }
  420. buildRelationalQuery({
  421. fullSchema,
  422. schema,
  423. tableNamesMap,
  424. table,
  425. tableConfig,
  426. queryConfig: config,
  427. tableAlias,
  428. nestedQueryRelation,
  429. joinOn
  430. }) {
  431. let selection = [];
  432. let limit, offset, orderBy, where;
  433. const joins = [];
  434. if (config === true) {
  435. const selectionEntries = Object.entries(tableConfig.columns);
  436. selection = selectionEntries.map(([key, value]) => ({
  437. dbKey: value.name,
  438. tsKey: key,
  439. field: (0, import_alias.aliasedTableColumn)(value, tableAlias),
  440. relationTableTsKey: void 0,
  441. isJson: false,
  442. selection: []
  443. }));
  444. } else {
  445. const aliasedColumns = Object.fromEntries(
  446. Object.entries(tableConfig.columns).map(([key, value]) => [
  447. key,
  448. (0, import_alias.aliasedTableColumn)(value, tableAlias)
  449. ])
  450. );
  451. if (config.where) {
  452. const whereSql = typeof config.where === "function" ? config.where(aliasedColumns, (0, import_relations.getOperators)()) : config.where;
  453. where = whereSql && (0, import_alias.mapColumnsInSQLToAlias)(whereSql, tableAlias);
  454. }
  455. const fieldsSelection = [];
  456. let selectedColumns = [];
  457. if (config.columns) {
  458. let isIncludeMode = false;
  459. for (const [field, value] of Object.entries(config.columns)) {
  460. if (value === void 0) {
  461. continue;
  462. }
  463. if (field in tableConfig.columns) {
  464. if (!isIncludeMode && value === true) {
  465. isIncludeMode = true;
  466. }
  467. selectedColumns.push(field);
  468. }
  469. }
  470. if (selectedColumns.length > 0) {
  471. selectedColumns = isIncludeMode ? selectedColumns.filter((c) => config.columns?.[c] === true) : Object.keys(tableConfig.columns).filter(
  472. (key) => !selectedColumns.includes(key)
  473. );
  474. }
  475. } else {
  476. selectedColumns = Object.keys(tableConfig.columns);
  477. }
  478. for (const field of selectedColumns) {
  479. const column = tableConfig.columns[field];
  480. fieldsSelection.push({ tsKey: field, value: column });
  481. }
  482. let selectedRelations = [];
  483. if (config.with) {
  484. selectedRelations = Object.entries(config.with).filter(
  485. (entry) => !!entry[1]
  486. ).map(([tsKey, queryConfig]) => ({
  487. tsKey,
  488. queryConfig,
  489. relation: tableConfig.relations[tsKey]
  490. }));
  491. }
  492. let extras;
  493. if (config.extras) {
  494. extras = typeof config.extras === "function" ? config.extras(aliasedColumns, { sql: import_sql.sql }) : config.extras;
  495. for (const [tsKey, value] of Object.entries(extras)) {
  496. fieldsSelection.push({
  497. tsKey,
  498. value: (0, import_alias.mapColumnsInAliasedSQLToAlias)(value, tableAlias)
  499. });
  500. }
  501. }
  502. for (const { tsKey, value } of fieldsSelection) {
  503. selection.push({
  504. dbKey: (0, import_entity.is)(value, import_sql.SQL.Aliased) ? value.fieldAlias : tableConfig.columns[tsKey].name,
  505. tsKey,
  506. field: (0, import_entity.is)(value, import_column.Column) ? (0, import_alias.aliasedTableColumn)(value, tableAlias) : value,
  507. relationTableTsKey: void 0,
  508. isJson: false,
  509. selection: []
  510. });
  511. }
  512. let orderByOrig = typeof config.orderBy === "function" ? config.orderBy(aliasedColumns, (0, import_relations.getOrderByOperators)()) : config.orderBy ?? [];
  513. if (!Array.isArray(orderByOrig)) {
  514. orderByOrig = [orderByOrig];
  515. }
  516. orderBy = orderByOrig.map((orderByValue) => {
  517. if ((0, import_entity.is)(orderByValue, import_column.Column)) {
  518. return (0, import_alias.aliasedTableColumn)(
  519. orderByValue,
  520. tableAlias
  521. );
  522. }
  523. return (0, import_alias.mapColumnsInSQLToAlias)(orderByValue, tableAlias);
  524. });
  525. limit = config.limit;
  526. offset = config.offset;
  527. for (const {
  528. tsKey: selectedRelationTsKey,
  529. queryConfig: selectedRelationConfigValue,
  530. relation
  531. } of selectedRelations) {
  532. const normalizedRelation = (0, import_relations.normalizeRelation)(
  533. schema,
  534. tableNamesMap,
  535. relation
  536. );
  537. const relationTableName = (0, import_table.getTableUniqueName)(relation.referencedTable);
  538. const relationTableTsName = tableNamesMap[relationTableName];
  539. const relationTableAlias = `${tableAlias}_${selectedRelationTsKey}`;
  540. const joinOn2 = (0, import_expressions.and)(
  541. ...normalizedRelation.fields.map(
  542. (field2, i) => (0, import_expressions.eq)(
  543. (0, import_alias.aliasedTableColumn)(
  544. normalizedRelation.references[i],
  545. relationTableAlias
  546. ),
  547. (0, import_alias.aliasedTableColumn)(field2, tableAlias)
  548. )
  549. )
  550. );
  551. const builtRelation = this.buildRelationalQuery({
  552. fullSchema,
  553. schema,
  554. tableNamesMap,
  555. table: fullSchema[relationTableTsName],
  556. tableConfig: schema[relationTableTsName],
  557. queryConfig: (0, import_entity.is)(relation, import_relations.One) ? selectedRelationConfigValue === true ? { limit: 1 } : { ...selectedRelationConfigValue, limit: 1 } : selectedRelationConfigValue,
  558. tableAlias: relationTableAlias,
  559. joinOn: joinOn2,
  560. nestedQueryRelation: relation
  561. });
  562. const field = import_sql.sql`${import_sql.sql.identifier(relationTableAlias)}.${import_sql.sql.identifier("data")}`.as(
  563. selectedRelationTsKey
  564. );
  565. joins.push({
  566. on: import_sql.sql`true`,
  567. table: new import_subquery.Subquery(builtRelation.sql, {}, relationTableAlias),
  568. alias: relationTableAlias,
  569. joinType: "left",
  570. lateral: true
  571. });
  572. selection.push({
  573. dbKey: selectedRelationTsKey,
  574. tsKey: selectedRelationTsKey,
  575. field,
  576. relationTableTsKey: relationTableTsName,
  577. isJson: true,
  578. selection: builtRelation.selection
  579. });
  580. }
  581. }
  582. if (selection.length === 0) {
  583. throw new import_errors.DrizzleError({
  584. message: `No fields selected for table "${tableConfig.tsName}" ("${tableAlias}")`
  585. });
  586. }
  587. let result;
  588. where = (0, import_expressions.and)(joinOn, where);
  589. if (nestedQueryRelation) {
  590. let field = import_sql.sql`JSON_TO_ARRAY(${import_sql.sql.join(
  591. selection.map(
  592. ({ field: field2, tsKey, isJson }) => isJson ? import_sql.sql`${import_sql.sql.identifier(`${tableAlias}_${tsKey}`)}.${import_sql.sql.identifier("data")}` : (0, import_entity.is)(field2, import_sql.SQL.Aliased) ? field2.sql : field2
  593. ),
  594. import_sql.sql`, `
  595. )})`;
  596. if ((0, import_entity.is)(nestedQueryRelation, import_relations.Many)) {
  597. field = import_sql.sql`json_agg(${field})`;
  598. }
  599. const nestedSelection = [
  600. {
  601. dbKey: "data",
  602. tsKey: "data",
  603. field: field.as("data"),
  604. isJson: true,
  605. relationTableTsKey: tableConfig.tsName,
  606. selection
  607. }
  608. ];
  609. const needsSubquery = limit !== void 0 || offset !== void 0 || (orderBy?.length ?? 0) > 0;
  610. if (needsSubquery) {
  611. result = this.buildSelectQuery({
  612. table: (0, import_alias.aliasedTable)(table, tableAlias),
  613. fields: {},
  614. fieldsFlat: [
  615. {
  616. path: [],
  617. field: import_sql.sql.raw("*")
  618. },
  619. ...((orderBy?.length ?? 0) > 0 ? [
  620. {
  621. path: [],
  622. field: import_sql.sql`row_number() over (order by ${import_sql.sql.join(orderBy, import_sql.sql`, `)})`
  623. }
  624. ] : [])
  625. ],
  626. where,
  627. limit,
  628. offset,
  629. setOperators: []
  630. });
  631. where = void 0;
  632. limit = void 0;
  633. offset = void 0;
  634. orderBy = void 0;
  635. } else {
  636. result = (0, import_alias.aliasedTable)(table, tableAlias);
  637. }
  638. result = this.buildSelectQuery({
  639. table: (0, import_entity.is)(result, import_table2.SingleStoreTable) ? result : new import_subquery.Subquery(result, {}, tableAlias),
  640. fields: {},
  641. fieldsFlat: nestedSelection.map(({ field: field2 }) => ({
  642. path: [],
  643. field: (0, import_entity.is)(field2, import_column.Column) ? (0, import_alias.aliasedTableColumn)(field2, tableAlias) : field2
  644. })),
  645. joins,
  646. where,
  647. limit,
  648. offset,
  649. orderBy,
  650. setOperators: []
  651. });
  652. } else {
  653. result = this.buildSelectQuery({
  654. table: (0, import_alias.aliasedTable)(table, tableAlias),
  655. fields: {},
  656. fieldsFlat: selection.map(({ field }) => ({
  657. path: [],
  658. field: (0, import_entity.is)(field, import_column.Column) ? (0, import_alias.aliasedTableColumn)(field, tableAlias) : field
  659. })),
  660. joins,
  661. where,
  662. limit,
  663. offset,
  664. orderBy,
  665. setOperators: []
  666. });
  667. }
  668. return {
  669. tableTsKey: tableConfig.tsName,
  670. sql: result,
  671. selection
  672. };
  673. }
  674. }
  675. // Annotate the CommonJS export names for ESM import in node:
  676. 0 && (module.exports = {
  677. SingleStoreDialect
  678. });
  679. //# sourceMappingURL=dialect.cjs.map