@hemia/db-connector 0.0.10 → 0.0.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,8 +1,8 @@
1
1
  import { createClient } from '@clickhouse/client';
2
2
  import { drizzle } from 'drizzle-orm/postgres-js';
3
3
  export { PostgresJsDatabase } from 'drizzle-orm/postgres-js';
4
- import { isNull, inArray, gt, gte, lt, lte, like, ilike, ne, eq, and } from 'drizzle-orm';
5
- export { and, eq, gt, gte, ilike, inArray, isNull, like, lt, lte, ne, not, or, sql } from 'drizzle-orm';
4
+ import { isNull as isNull$1, inArray as inArray$1, gt as gt$1, gte as gte$1, lt as lt$1, lte as lte$1, like as like$1, ilike as ilike$1, ne as ne$1, eq as eq$1, and as and$1 } from 'drizzle-orm';
5
+ export { and, arrayContained, arrayContains, arrayOverlaps, asc, avg, avgDistinct, between, count, countDistinct, desc, eq, exists, gt, gte, ilike, inArray, isNotNull, isNull, like, lt, lte, max, min, ne, not, notBetween, notExists, notIlike, notInArray, notLike, or, sql, sum, sumDistinct } from 'drizzle-orm';
6
6
  import os from 'os';
7
7
  import fs from 'fs';
8
8
  import net from 'net';
@@ -3120,39 +3120,39 @@ class DrizzlePostgresConnector extends DrizzleSqlConnector {
3120
3120
  if (!column)
3121
3121
  return;
3122
3122
  if (value === null) {
3123
- conditions.push(isNull(column));
3123
+ conditions.push(isNull$1(column));
3124
3124
  }
3125
3125
  else if (Array.isArray(value)) {
3126
- conditions.push(inArray(column, value));
3126
+ conditions.push(inArray$1(column, value));
3127
3127
  }
3128
3128
  else if (typeof value === 'object' && value !== null) {
3129
3129
  if ('$gt' in value) {
3130
- conditions.push(gt(column, value.$gt));
3130
+ conditions.push(gt$1(column, value.$gt));
3131
3131
  }
3132
3132
  if ('$gte' in value) {
3133
- conditions.push(gte(column, value.$gte));
3133
+ conditions.push(gte$1(column, value.$gte));
3134
3134
  }
3135
3135
  if ('$lt' in value) {
3136
- conditions.push(lt(column, value.$lt));
3136
+ conditions.push(lt$1(column, value.$lt));
3137
3137
  }
3138
3138
  if ('$lte' in value) {
3139
- conditions.push(lte(column, value.$lte));
3139
+ conditions.push(lte$1(column, value.$lte));
3140
3140
  }
3141
3141
  if ('$like' in value) {
3142
- conditions.push(like(column, value.$like));
3142
+ conditions.push(like$1(column, value.$like));
3143
3143
  }
3144
3144
  if ('$ilike' in value) {
3145
- conditions.push(ilike(column, value.$ilike));
3145
+ conditions.push(ilike$1(column, value.$ilike));
3146
3146
  }
3147
3147
  if ('$ne' in value) {
3148
- conditions.push(ne(column, value.$ne));
3148
+ conditions.push(ne$1(column, value.$ne));
3149
3149
  }
3150
3150
  }
3151
3151
  else {
3152
- conditions.push(eq(column, value));
3152
+ conditions.push(eq$1(column, value));
3153
3153
  }
3154
3154
  });
3155
- return conditions.length > 0 ? and(...conditions) : undefined;
3155
+ return conditions.length > 0 ? and$1(...conditions) : undefined;
3156
3156
  }
3157
3157
  buildRawWhereClause(where, params, offset = 0) {
3158
3158
  if (!where || Object.keys(where).length === 0)
@@ -4118,14 +4118,73 @@ class ForeignKey {
4118
4118
  return name ?? `${chunks.join("_")}_fk`;
4119
4119
  }
4120
4120
  }
4121
+ function foreignKey(config) {
4122
+ function mappedConfig() {
4123
+ const { name, columns, foreignColumns } = config;
4124
+ return {
4125
+ name,
4126
+ columns,
4127
+ foreignColumns
4128
+ };
4129
+ }
4130
+ return new ForeignKeyBuilder(mappedConfig);
4131
+ }
4121
4132
 
4122
4133
  function iife(fn, ...args) {
4123
4134
  return fn(...args);
4124
4135
  }
4125
4136
 
4137
+ function unique(name) {
4138
+ return new UniqueOnConstraintBuilder(name);
4139
+ }
4126
4140
  function uniqueKeyName(table, columns) {
4127
4141
  return `${table[TableName]}_${columns.join("_")}_unique`;
4128
4142
  }
4143
+ class UniqueConstraintBuilder {
4144
+ constructor(columns, name) {
4145
+ this.name = name;
4146
+ this.columns = columns;
4147
+ }
4148
+ static [entityKind] = "PgUniqueConstraintBuilder";
4149
+ /** @internal */
4150
+ columns;
4151
+ /** @internal */
4152
+ nullsNotDistinctConfig = false;
4153
+ nullsNotDistinct() {
4154
+ this.nullsNotDistinctConfig = true;
4155
+ return this;
4156
+ }
4157
+ /** @internal */
4158
+ build(table) {
4159
+ return new UniqueConstraint(table, this.columns, this.nullsNotDistinctConfig, this.name);
4160
+ }
4161
+ }
4162
+ class UniqueOnConstraintBuilder {
4163
+ static [entityKind] = "PgUniqueOnConstraintBuilder";
4164
+ /** @internal */
4165
+ name;
4166
+ constructor(name) {
4167
+ this.name = name;
4168
+ }
4169
+ on(...columns) {
4170
+ return new UniqueConstraintBuilder(columns, this.name);
4171
+ }
4172
+ }
4173
+ class UniqueConstraint {
4174
+ constructor(table, columns, nullsNotDistinct, name) {
4175
+ this.table = table;
4176
+ this.columns = columns;
4177
+ this.name = name ?? uniqueKeyName(this.table, this.columns.map((column) => column.name));
4178
+ this.nullsNotDistinct = nullsNotDistinct;
4179
+ }
4180
+ static [entityKind] = "PgUniqueConstraint";
4181
+ columns;
4182
+ name;
4183
+ nullsNotDistinct = false;
4184
+ getName() {
4185
+ return this.name;
4186
+ }
4187
+ }
4129
4188
 
4130
4189
  function parsePgArrayValue(arrayString, startFrom, inQuotes) {
4131
4190
  for (let i = startFrom; i < arrayString.length; i++) {
@@ -4328,6 +4387,19 @@ class ExtraConfigColumn extends PgColumn {
4328
4387
  return this;
4329
4388
  }
4330
4389
  }
4390
+ class IndexedColumn {
4391
+ static [entityKind] = "IndexedColumn";
4392
+ constructor(name, keyAsName, type, indexConfig) {
4393
+ this.name = name;
4394
+ this.keyAsName = keyAsName;
4395
+ this.type = type;
4396
+ this.indexConfig = indexConfig;
4397
+ }
4398
+ name;
4399
+ keyAsName;
4400
+ type;
4401
+ indexConfig;
4402
+ }
4331
4403
  class PgArrayBuilder extends PgColumnBuilder {
4332
4404
  static [entityKind] = "PgArrayBuilder";
4333
4405
  constructor(name, baseBuilder, size) {
@@ -4472,6 +4544,9 @@ class Subquery {
4472
4544
  // return new SQL([this]);
4473
4545
  // }
4474
4546
  }
4547
+ class WithSubquery extends Subquery {
4548
+ static [entityKind] = "WithSubquery";
4549
+ }
4475
4550
 
4476
4551
  const tracer = {
4477
4552
  startActiveSpan(name, fn) {
@@ -4537,6 +4612,12 @@ class Table {
4537
4612
  this[BaseName] = baseName;
4538
4613
  }
4539
4614
  }
4615
+ function getTableName(table) {
4616
+ return table[TableName];
4617
+ }
4618
+ function getTableUniqueName(table) {
4619
+ return `${table[Schema] ?? "public"}.${table[TableName]}`;
4620
+ }
4540
4621
 
4541
4622
  function isSQLWrapper(value) {
4542
4623
  return value !== null && value !== void 0 && typeof value.getSQL === "function";
@@ -4776,6 +4857,9 @@ class Name {
4776
4857
  return new SQL([this]);
4777
4858
  }
4778
4859
  }
4860
+ function isDriverValueEncoder(value) {
4861
+ return typeof value === "object" && value !== null && "mapToDriverValue" in value && typeof value.mapToDriverValue === "function";
4862
+ }
4779
4863
  const noopDecoder = {
4780
4864
  mapFromDriverValue: (value) => value
4781
4865
  };
@@ -4908,6 +4992,162 @@ Subquery.prototype.getSQL = function() {
4908
4992
  return new SQL([this]);
4909
4993
  };
4910
4994
 
4995
+ class ColumnAliasProxyHandler {
4996
+ constructor(table) {
4997
+ this.table = table;
4998
+ }
4999
+ static [entityKind] = "ColumnAliasProxyHandler";
5000
+ get(columnObj, prop) {
5001
+ if (prop === "table") {
5002
+ return this.table;
5003
+ }
5004
+ return columnObj[prop];
5005
+ }
5006
+ }
5007
+ class TableAliasProxyHandler {
5008
+ constructor(alias, replaceOriginalName) {
5009
+ this.alias = alias;
5010
+ this.replaceOriginalName = replaceOriginalName;
5011
+ }
5012
+ static [entityKind] = "TableAliasProxyHandler";
5013
+ get(target, prop) {
5014
+ if (prop === Table.Symbol.IsAlias) {
5015
+ return true;
5016
+ }
5017
+ if (prop === Table.Symbol.Name) {
5018
+ return this.alias;
5019
+ }
5020
+ if (this.replaceOriginalName && prop === Table.Symbol.OriginalName) {
5021
+ return this.alias;
5022
+ }
5023
+ if (prop === ViewBaseConfig) {
5024
+ return {
5025
+ ...target[ViewBaseConfig],
5026
+ name: this.alias,
5027
+ isAlias: true
5028
+ };
5029
+ }
5030
+ if (prop === Table.Symbol.Columns) {
5031
+ const columns = target[Table.Symbol.Columns];
5032
+ if (!columns) {
5033
+ return columns;
5034
+ }
5035
+ const proxiedColumns = {};
5036
+ Object.keys(columns).map((key) => {
5037
+ proxiedColumns[key] = new Proxy(
5038
+ columns[key],
5039
+ new ColumnAliasProxyHandler(new Proxy(target, this))
5040
+ );
5041
+ });
5042
+ return proxiedColumns;
5043
+ }
5044
+ const value = target[prop];
5045
+ if (is(value, Column)) {
5046
+ return new Proxy(value, new ColumnAliasProxyHandler(new Proxy(target, this)));
5047
+ }
5048
+ return value;
5049
+ }
5050
+ }
5051
+ function aliasedTable(table, tableAlias) {
5052
+ return new Proxy(table, new TableAliasProxyHandler(tableAlias, false));
5053
+ }
5054
+ function aliasedTableColumn(column, tableAlias) {
5055
+ return new Proxy(
5056
+ column,
5057
+ new ColumnAliasProxyHandler(new Proxy(column.table, new TableAliasProxyHandler(tableAlias, false)))
5058
+ );
5059
+ }
5060
+ function mapColumnsInAliasedSQLToAlias(query, alias) {
5061
+ return new SQL.Aliased(mapColumnsInSQLToAlias(query.sql, alias), query.fieldAlias);
5062
+ }
5063
+ function mapColumnsInSQLToAlias(query, alias) {
5064
+ return sql.join(query.queryChunks.map((c) => {
5065
+ if (is(c, Column)) {
5066
+ return aliasedTableColumn(c, alias);
5067
+ }
5068
+ if (is(c, SQL)) {
5069
+ return mapColumnsInSQLToAlias(c, alias);
5070
+ }
5071
+ if (is(c, SQL.Aliased)) {
5072
+ return mapColumnsInAliasedSQLToAlias(c, alias);
5073
+ }
5074
+ return c;
5075
+ }));
5076
+ }
5077
+
5078
+ class CheckBuilder {
5079
+ constructor(name, value) {
5080
+ this.name = name;
5081
+ this.value = value;
5082
+ }
5083
+ static [entityKind] = "PgCheckBuilder";
5084
+ brand;
5085
+ /** @internal */
5086
+ build(table) {
5087
+ return new Check(table, this);
5088
+ }
5089
+ }
5090
+ class Check {
5091
+ constructor(table, builder) {
5092
+ this.table = table;
5093
+ this.name = builder.name;
5094
+ this.value = builder.value;
5095
+ }
5096
+ static [entityKind] = "PgCheck";
5097
+ name;
5098
+ value;
5099
+ }
5100
+ function check(name, value) {
5101
+ return new CheckBuilder(name, value);
5102
+ }
5103
+
5104
+ function orderSelectedFields(fields, pathPrefix) {
5105
+ return Object.entries(fields).reduce((result, [name, field]) => {
5106
+ if (typeof name !== "string") {
5107
+ return result;
5108
+ }
5109
+ const newPath = pathPrefix ? [...pathPrefix, name] : [name];
5110
+ if (is(field, Column) || is(field, SQL) || is(field, SQL.Aliased) || is(field, Subquery)) {
5111
+ result.push({ path: newPath, field });
5112
+ } else if (is(field, Table)) {
5113
+ result.push(...orderSelectedFields(field[Table.Symbol.Columns], newPath));
5114
+ } else {
5115
+ result.push(...orderSelectedFields(field, newPath));
5116
+ }
5117
+ return result;
5118
+ }, []);
5119
+ }
5120
+ function haveSameKeys(left, right) {
5121
+ const leftKeys = Object.keys(left);
5122
+ const rightKeys = Object.keys(right);
5123
+ if (leftKeys.length !== rightKeys.length) {
5124
+ return false;
5125
+ }
5126
+ for (const [index, key] of leftKeys.entries()) {
5127
+ if (key !== rightKeys[index]) {
5128
+ return false;
5129
+ }
5130
+ }
5131
+ return true;
5132
+ }
5133
+ function applyMixins(baseClass, extendedClasses) {
5134
+ for (const extendedClass of extendedClasses) {
5135
+ for (const name of Object.getOwnPropertyNames(extendedClass.prototype)) {
5136
+ if (name === "constructor") continue;
5137
+ Object.defineProperty(
5138
+ baseClass.prototype,
5139
+ name,
5140
+ Object.getOwnPropertyDescriptor(extendedClass.prototype, name) || /* @__PURE__ */ Object.create(null)
5141
+ );
5142
+ }
5143
+ }
5144
+ }
5145
+ function getTableColumns(table) {
5146
+ return table[Table.Symbol.Columns];
5147
+ }
5148
+ function getTableLikeName(table) {
5149
+ return is(table, Subquery) ? table._.alias : is(table, View) ? table[ViewBaseConfig].name : is(table, SQL) ? void 0 : table[Table.Symbol.IsAlias] ? table[Table.Symbol.Name] : table[Table.Symbol.BaseName];
5150
+ }
4911
5151
  function getColumnNameAndConfig(a, b) {
4912
5152
  return {
4913
5153
  name: typeof a === "string" && a.length > 0 ? a : "",
@@ -5626,6 +5866,7 @@ function numeric(a, b) {
5626
5866
  const mode = config?.mode;
5627
5867
  return mode === "number" ? new PgNumericNumberBuilder(name, config?.precision, config?.scale) : mode === "bigint" ? new PgNumericBigIntBuilder(name, config?.precision, config?.scale) : new PgNumericBuilder(name, config?.precision, config?.scale);
5628
5868
  }
5869
+ const decimal = numeric;
5629
5870
 
5630
5871
  class PgPointTupleBuilder extends PgColumnBuilder {
5631
5872
  static [entityKind] = "PgPointTupleBuilder";
@@ -6198,6 +6439,96 @@ function vector(a, b) {
6198
6439
  return new PgVectorBuilder(name, config);
6199
6440
  }
6200
6441
 
6442
+ class QueryPromise {
6443
+ static [entityKind] = "QueryPromise";
6444
+ [Symbol.toStringTag] = "QueryPromise";
6445
+ catch(onRejected) {
6446
+ return this.then(void 0, onRejected);
6447
+ }
6448
+ finally(onFinally) {
6449
+ return this.then(
6450
+ (value) => {
6451
+ onFinally?.();
6452
+ return value;
6453
+ },
6454
+ (reason) => {
6455
+ onFinally?.();
6456
+ throw reason;
6457
+ }
6458
+ );
6459
+ }
6460
+ then(onFulfilled, onRejected) {
6461
+ return this.execute().then(onFulfilled, onRejected);
6462
+ }
6463
+ }
6464
+
6465
+ class SelectionProxyHandler {
6466
+ static [entityKind] = "SelectionProxyHandler";
6467
+ config;
6468
+ constructor(config) {
6469
+ this.config = { ...config };
6470
+ }
6471
+ get(subquery, prop) {
6472
+ if (prop === "_") {
6473
+ return {
6474
+ ...subquery["_"],
6475
+ selectedFields: new Proxy(
6476
+ subquery._.selectedFields,
6477
+ this
6478
+ )
6479
+ };
6480
+ }
6481
+ if (prop === ViewBaseConfig) {
6482
+ return {
6483
+ ...subquery[ViewBaseConfig],
6484
+ selectedFields: new Proxy(
6485
+ subquery[ViewBaseConfig].selectedFields,
6486
+ this
6487
+ )
6488
+ };
6489
+ }
6490
+ if (typeof prop === "symbol") {
6491
+ return subquery[prop];
6492
+ }
6493
+ const columns = is(subquery, Subquery) ? subquery._.selectedFields : is(subquery, View) ? subquery[ViewBaseConfig].selectedFields : subquery;
6494
+ const value = columns[prop];
6495
+ if (is(value, SQL.Aliased)) {
6496
+ if (this.config.sqlAliasedBehavior === "sql" && !value.isSelectionField) {
6497
+ return value.sql;
6498
+ }
6499
+ const newValue = value.clone();
6500
+ newValue.isSelectionField = true;
6501
+ return newValue;
6502
+ }
6503
+ if (is(value, SQL)) {
6504
+ if (this.config.sqlBehavior === "sql") {
6505
+ return value;
6506
+ }
6507
+ throw new Error(
6508
+ `You tried to reference "${prop}" field from a subquery, which is a raw SQL field, but it doesn't have an alias declared. Please add an alias to the field using ".as('alias')" method.`
6509
+ );
6510
+ }
6511
+ if (is(value, Column)) {
6512
+ if (this.config.alias) {
6513
+ return new Proxy(
6514
+ value,
6515
+ new ColumnAliasProxyHandler(
6516
+ new Proxy(
6517
+ value.table,
6518
+ new TableAliasProxyHandler(this.config.alias, this.config.replaceOriginalName ?? false)
6519
+ )
6520
+ )
6521
+ );
6522
+ }
6523
+ return value;
6524
+ }
6525
+ if (typeof value !== "object" || value === null) {
6526
+ return value;
6527
+ }
6528
+ return new Proxy(value, new SelectionProxyHandler(this.config));
6529
+ }
6530
+ }
6531
+
6201
6532
  function getPgColumnBuilders() {
6202
6533
  return {
6203
6534
  bigint,
@@ -6290,4 +6621,2785 @@ const pgTable = (name, columns, extraConfig) => {
6290
6621
  return pgTableWithSchema(name, columns, extraConfig, void 0);
6291
6622
  };
6292
6623
 
6293
- export { ClickHouseConnector, CoreSqlTypes, DBConnector, DBError, DBNoSQLType, DBOLAPType, DBSQLType, DrizzlePostgresConnector, DrizzleSQLType, DrizzleSqlConnector, MySQLConnectionError, NoSQLConnector, OLAPConnector, SqlConnector, boolean, integer, json, jsonb, pgEnum, pgTable, serial, text, timestamp, varchar };
6624
+ class IndexBuilderOn {
6625
+ constructor(unique, name) {
6626
+ this.unique = unique;
6627
+ this.name = name;
6628
+ }
6629
+ static [entityKind] = "PgIndexBuilderOn";
6630
+ on(...columns) {
6631
+ return new IndexBuilder(
6632
+ columns.map((it) => {
6633
+ if (is(it, SQL)) {
6634
+ return it;
6635
+ }
6636
+ it = it;
6637
+ const clonedIndexedColumn = new IndexedColumn(it.name, !!it.keyAsName, it.columnType, it.indexConfig);
6638
+ it.indexConfig = JSON.parse(JSON.stringify(it.defaultConfig));
6639
+ return clonedIndexedColumn;
6640
+ }),
6641
+ this.unique,
6642
+ false,
6643
+ this.name
6644
+ );
6645
+ }
6646
+ onOnly(...columns) {
6647
+ return new IndexBuilder(
6648
+ columns.map((it) => {
6649
+ if (is(it, SQL)) {
6650
+ return it;
6651
+ }
6652
+ it = it;
6653
+ const clonedIndexedColumn = new IndexedColumn(it.name, !!it.keyAsName, it.columnType, it.indexConfig);
6654
+ it.indexConfig = it.defaultConfig;
6655
+ return clonedIndexedColumn;
6656
+ }),
6657
+ this.unique,
6658
+ true,
6659
+ this.name
6660
+ );
6661
+ }
6662
+ /**
6663
+ * Specify what index method to use. Choices are `btree`, `hash`, `gist`, `spgist`, `gin`, `brin`, or user-installed access methods like `bloom`. The default method is `btree.
6664
+ *
6665
+ * If you have the `pg_vector` extension installed in your database, you can use the `hnsw` and `ivfflat` options, which are predefined types.
6666
+ *
6667
+ * **You can always specify any string you want in the method, in case Drizzle doesn't have it natively in its types**
6668
+ *
6669
+ * @param method The name of the index method to be used
6670
+ * @param columns
6671
+ * @returns
6672
+ */
6673
+ using(method, ...columns) {
6674
+ return new IndexBuilder(
6675
+ columns.map((it) => {
6676
+ if (is(it, SQL)) {
6677
+ return it;
6678
+ }
6679
+ it = it;
6680
+ const clonedIndexedColumn = new IndexedColumn(it.name, !!it.keyAsName, it.columnType, it.indexConfig);
6681
+ it.indexConfig = JSON.parse(JSON.stringify(it.defaultConfig));
6682
+ return clonedIndexedColumn;
6683
+ }),
6684
+ this.unique,
6685
+ true,
6686
+ this.name,
6687
+ method
6688
+ );
6689
+ }
6690
+ }
6691
+ class IndexBuilder {
6692
+ static [entityKind] = "PgIndexBuilder";
6693
+ /** @internal */
6694
+ config;
6695
+ constructor(columns, unique, only, name, method = "btree") {
6696
+ this.config = {
6697
+ name,
6698
+ columns,
6699
+ unique,
6700
+ only,
6701
+ method
6702
+ };
6703
+ }
6704
+ concurrently() {
6705
+ this.config.concurrently = true;
6706
+ return this;
6707
+ }
6708
+ with(obj) {
6709
+ this.config.with = obj;
6710
+ return this;
6711
+ }
6712
+ where(condition) {
6713
+ this.config.where = condition;
6714
+ return this;
6715
+ }
6716
+ /** @internal */
6717
+ build(table) {
6718
+ return new Index(this.config, table);
6719
+ }
6720
+ }
6721
+ class Index {
6722
+ static [entityKind] = "PgIndex";
6723
+ config;
6724
+ constructor(config, table) {
6725
+ this.config = { ...config, table };
6726
+ }
6727
+ }
6728
+ function index(name) {
6729
+ return new IndexBuilderOn(false, name);
6730
+ }
6731
+ function uniqueIndex(name) {
6732
+ return new IndexBuilderOn(true, name);
6733
+ }
6734
+
6735
+ function primaryKey(...config) {
6736
+ if (config[0].columns) {
6737
+ return new PrimaryKeyBuilder(config[0].columns, config[0].name);
6738
+ }
6739
+ return new PrimaryKeyBuilder(config);
6740
+ }
6741
+ class PrimaryKeyBuilder {
6742
+ static [entityKind] = "PgPrimaryKeyBuilder";
6743
+ /** @internal */
6744
+ columns;
6745
+ /** @internal */
6746
+ name;
6747
+ constructor(columns, name) {
6748
+ this.columns = columns;
6749
+ this.name = name;
6750
+ }
6751
+ /** @internal */
6752
+ build(table) {
6753
+ return new PrimaryKey(table, this.columns, this.name);
6754
+ }
6755
+ }
6756
+ class PrimaryKey {
6757
+ constructor(table, columns, name) {
6758
+ this.table = table;
6759
+ this.columns = columns;
6760
+ this.name = name;
6761
+ }
6762
+ static [entityKind] = "PgPrimaryKey";
6763
+ columns;
6764
+ name;
6765
+ getName() {
6766
+ return this.name ?? `${this.table[PgTable.Symbol.Name]}_${this.columns.map((column) => column.name).join("_")}_pk`;
6767
+ }
6768
+ }
6769
+
6770
+ const PgViewConfig = Symbol.for("drizzle:PgViewConfig");
6771
+
6772
+ function toSnakeCase(input) {
6773
+ const words = input.replace(/['\u2019]/g, "").match(/[\da-z]+|[A-Z]+(?![a-z])|[A-Z][\da-z]+/g) ?? [];
6774
+ return words.map((word) => word.toLowerCase()).join("_");
6775
+ }
6776
+ function toCamelCase(input) {
6777
+ const words = input.replace(/['\u2019]/g, "").match(/[\da-z]+|[A-Z]+(?![a-z])|[A-Z][\da-z]+/g) ?? [];
6778
+ return words.reduce((acc, word, i) => {
6779
+ const formattedWord = i === 0 ? word.toLowerCase() : `${word[0].toUpperCase()}${word.slice(1)}`;
6780
+ return acc + formattedWord;
6781
+ }, "");
6782
+ }
6783
+ function noopCase(input) {
6784
+ return input;
6785
+ }
6786
+ class CasingCache {
6787
+ static [entityKind] = "CasingCache";
6788
+ /** @internal */
6789
+ cache = {};
6790
+ cachedTables = {};
6791
+ convert;
6792
+ constructor(casing) {
6793
+ this.convert = casing === "snake_case" ? toSnakeCase : casing === "camelCase" ? toCamelCase : noopCase;
6794
+ }
6795
+ getColumnCasing(column) {
6796
+ if (!column.keyAsName) return column.name;
6797
+ const schema = column.table[Table.Symbol.Schema] ?? "public";
6798
+ const tableName = column.table[Table.Symbol.OriginalName];
6799
+ const key = `${schema}.${tableName}.${column.name}`;
6800
+ if (!this.cache[key]) {
6801
+ this.cacheTable(column.table);
6802
+ }
6803
+ return this.cache[key];
6804
+ }
6805
+ cacheTable(table) {
6806
+ const schema = table[Table.Symbol.Schema] ?? "public";
6807
+ const tableName = table[Table.Symbol.OriginalName];
6808
+ const tableKey = `${schema}.${tableName}`;
6809
+ if (!this.cachedTables[tableKey]) {
6810
+ for (const column of Object.values(table[Table.Symbol.Columns])) {
6811
+ const columnKey = `${tableKey}.${column.name}`;
6812
+ this.cache[columnKey] = this.convert(column.name);
6813
+ }
6814
+ this.cachedTables[tableKey] = true;
6815
+ }
6816
+ }
6817
+ clearCache() {
6818
+ this.cache = {};
6819
+ this.cachedTables = {};
6820
+ }
6821
+ }
6822
+
6823
+ class DrizzleError extends Error {
6824
+ static [entityKind] = "DrizzleError";
6825
+ constructor({ message, cause }) {
6826
+ super(message);
6827
+ this.name = "DrizzleError";
6828
+ this.cause = cause;
6829
+ }
6830
+ }
6831
+
6832
+ function bindIfParam(value, column) {
6833
+ if (isDriverValueEncoder(column) && !isSQLWrapper(value) && !is(value, Param) && !is(value, Placeholder) && !is(value, Column) && !is(value, Table) && !is(value, View)) {
6834
+ return new Param(value, column);
6835
+ }
6836
+ return value;
6837
+ }
6838
+ const eq = (left, right) => {
6839
+ return sql`${left} = ${bindIfParam(right, left)}`;
6840
+ };
6841
+ const ne = (left, right) => {
6842
+ return sql`${left} <> ${bindIfParam(right, left)}`;
6843
+ };
6844
+ function and(...unfilteredConditions) {
6845
+ const conditions = unfilteredConditions.filter(
6846
+ (c) => c !== void 0
6847
+ );
6848
+ if (conditions.length === 0) {
6849
+ return void 0;
6850
+ }
6851
+ if (conditions.length === 1) {
6852
+ return new SQL(conditions);
6853
+ }
6854
+ return new SQL([
6855
+ new StringChunk("("),
6856
+ sql.join(conditions, new StringChunk(" and ")),
6857
+ new StringChunk(")")
6858
+ ]);
6859
+ }
6860
+ function or(...unfilteredConditions) {
6861
+ const conditions = unfilteredConditions.filter(
6862
+ (c) => c !== void 0
6863
+ );
6864
+ if (conditions.length === 0) {
6865
+ return void 0;
6866
+ }
6867
+ if (conditions.length === 1) {
6868
+ return new SQL(conditions);
6869
+ }
6870
+ return new SQL([
6871
+ new StringChunk("("),
6872
+ sql.join(conditions, new StringChunk(" or ")),
6873
+ new StringChunk(")")
6874
+ ]);
6875
+ }
6876
+ function not(condition) {
6877
+ return sql`not ${condition}`;
6878
+ }
6879
+ const gt = (left, right) => {
6880
+ return sql`${left} > ${bindIfParam(right, left)}`;
6881
+ };
6882
+ const gte = (left, right) => {
6883
+ return sql`${left} >= ${bindIfParam(right, left)}`;
6884
+ };
6885
+ const lt = (left, right) => {
6886
+ return sql`${left} < ${bindIfParam(right, left)}`;
6887
+ };
6888
+ const lte = (left, right) => {
6889
+ return sql`${left} <= ${bindIfParam(right, left)}`;
6890
+ };
6891
+ function inArray(column, values) {
6892
+ if (Array.isArray(values)) {
6893
+ if (values.length === 0) {
6894
+ return sql`false`;
6895
+ }
6896
+ return sql`${column} in ${values.map((v) => bindIfParam(v, column))}`;
6897
+ }
6898
+ return sql`${column} in ${bindIfParam(values, column)}`;
6899
+ }
6900
+ function notInArray(column, values) {
6901
+ if (Array.isArray(values)) {
6902
+ if (values.length === 0) {
6903
+ return sql`true`;
6904
+ }
6905
+ return sql`${column} not in ${values.map((v) => bindIfParam(v, column))}`;
6906
+ }
6907
+ return sql`${column} not in ${bindIfParam(values, column)}`;
6908
+ }
6909
+ function isNull(value) {
6910
+ return sql`${value} is null`;
6911
+ }
6912
+ function isNotNull(value) {
6913
+ return sql`${value} is not null`;
6914
+ }
6915
+ function exists(subquery) {
6916
+ return sql`exists ${subquery}`;
6917
+ }
6918
+ function notExists(subquery) {
6919
+ return sql`not exists ${subquery}`;
6920
+ }
6921
+ function between(column, min, max) {
6922
+ return sql`${column} between ${bindIfParam(min, column)} and ${bindIfParam(
6923
+ max,
6924
+ column
6925
+ )}`;
6926
+ }
6927
+ function notBetween(column, min, max) {
6928
+ return sql`${column} not between ${bindIfParam(
6929
+ min,
6930
+ column
6931
+ )} and ${bindIfParam(max, column)}`;
6932
+ }
6933
+ function like(column, value) {
6934
+ return sql`${column} like ${value}`;
6935
+ }
6936
+ function notLike(column, value) {
6937
+ return sql`${column} not like ${value}`;
6938
+ }
6939
+ function ilike(column, value) {
6940
+ return sql`${column} ilike ${value}`;
6941
+ }
6942
+ function notIlike(column, value) {
6943
+ return sql`${column} not ilike ${value}`;
6944
+ }
6945
+
6946
+ function asc(column) {
6947
+ return sql`${column} asc`;
6948
+ }
6949
+ function desc(column) {
6950
+ return sql`${column} desc`;
6951
+ }
6952
+
6953
+ class Relation {
6954
+ constructor(sourceTable, referencedTable, relationName) {
6955
+ this.sourceTable = sourceTable;
6956
+ this.referencedTable = referencedTable;
6957
+ this.relationName = relationName;
6958
+ this.referencedTableName = referencedTable[Table.Symbol.Name];
6959
+ }
6960
+ static [entityKind] = "Relation";
6961
+ referencedTableName;
6962
+ fieldName;
6963
+ }
6964
+ class One extends Relation {
6965
+ constructor(sourceTable, referencedTable, config, isNullable) {
6966
+ super(sourceTable, referencedTable, config?.relationName);
6967
+ this.config = config;
6968
+ this.isNullable = isNullable;
6969
+ }
6970
+ static [entityKind] = "One";
6971
+ withFieldName(fieldName) {
6972
+ const relation = new One(
6973
+ this.sourceTable,
6974
+ this.referencedTable,
6975
+ this.config,
6976
+ this.isNullable
6977
+ );
6978
+ relation.fieldName = fieldName;
6979
+ return relation;
6980
+ }
6981
+ }
6982
+ class Many extends Relation {
6983
+ constructor(sourceTable, referencedTable, config) {
6984
+ super(sourceTable, referencedTable, config?.relationName);
6985
+ this.config = config;
6986
+ }
6987
+ static [entityKind] = "Many";
6988
+ withFieldName(fieldName) {
6989
+ const relation = new Many(
6990
+ this.sourceTable,
6991
+ this.referencedTable,
6992
+ this.config
6993
+ );
6994
+ relation.fieldName = fieldName;
6995
+ return relation;
6996
+ }
6997
+ }
6998
+ function getOperators() {
6999
+ return {
7000
+ and,
7001
+ between,
7002
+ eq,
7003
+ exists,
7004
+ gt,
7005
+ gte,
7006
+ ilike,
7007
+ inArray,
7008
+ isNull,
7009
+ isNotNull,
7010
+ like,
7011
+ lt,
7012
+ lte,
7013
+ ne,
7014
+ not,
7015
+ notBetween,
7016
+ notExists,
7017
+ notLike,
7018
+ notIlike,
7019
+ notInArray,
7020
+ or,
7021
+ sql
7022
+ };
7023
+ }
7024
+ function getOrderByOperators() {
7025
+ return {
7026
+ sql,
7027
+ asc,
7028
+ desc
7029
+ };
7030
+ }
7031
+ function normalizeRelation(schema, tableNamesMap, relation) {
7032
+ if (is(relation, One) && relation.config) {
7033
+ return {
7034
+ fields: relation.config.fields,
7035
+ references: relation.config.references
7036
+ };
7037
+ }
7038
+ const referencedTableTsName = tableNamesMap[getTableUniqueName(relation.referencedTable)];
7039
+ if (!referencedTableTsName) {
7040
+ throw new Error(
7041
+ `Table "${relation.referencedTable[Table.Symbol.Name]}" not found in schema`
7042
+ );
7043
+ }
7044
+ const referencedTableConfig = schema[referencedTableTsName];
7045
+ if (!referencedTableConfig) {
7046
+ throw new Error(`Table "${referencedTableTsName}" not found in schema`);
7047
+ }
7048
+ const sourceTable = relation.sourceTable;
7049
+ const sourceTableTsName = tableNamesMap[getTableUniqueName(sourceTable)];
7050
+ if (!sourceTableTsName) {
7051
+ throw new Error(
7052
+ `Table "${sourceTable[Table.Symbol.Name]}" not found in schema`
7053
+ );
7054
+ }
7055
+ const reverseRelations = [];
7056
+ for (const referencedTableRelation of Object.values(
7057
+ referencedTableConfig.relations
7058
+ )) {
7059
+ if (relation.relationName && relation !== referencedTableRelation && referencedTableRelation.relationName === relation.relationName || !relation.relationName && referencedTableRelation.referencedTable === relation.sourceTable) {
7060
+ reverseRelations.push(referencedTableRelation);
7061
+ }
7062
+ }
7063
+ if (reverseRelations.length > 1) {
7064
+ throw relation.relationName ? new Error(
7065
+ `There are multiple relations with name "${relation.relationName}" in table "${referencedTableTsName}"`
7066
+ ) : new Error(
7067
+ `There are multiple relations between "${referencedTableTsName}" and "${relation.sourceTable[Table.Symbol.Name]}". Please specify relation name`
7068
+ );
7069
+ }
7070
+ if (reverseRelations[0] && is(reverseRelations[0], One) && reverseRelations[0].config) {
7071
+ return {
7072
+ fields: reverseRelations[0].config.references,
7073
+ references: reverseRelations[0].config.fields
7074
+ };
7075
+ }
7076
+ throw new Error(
7077
+ `There is not enough information to infer relation "${sourceTableTsName}.${relation.fieldName}"`
7078
+ );
7079
+ }
7080
+
7081
+ class PgViewBase extends View {
7082
+ static [entityKind] = "PgViewBase";
7083
+ }
7084
+
7085
+ class PgDialect {
7086
+ static [entityKind] = "PgDialect";
7087
+ /** @internal */
7088
+ casing;
7089
+ constructor(config) {
7090
+ this.casing = new CasingCache(config?.casing);
7091
+ }
7092
+ async migrate(migrations, session, config) {
7093
+ const migrationsTable = typeof config === "string" ? "__drizzle_migrations" : config.migrationsTable ?? "__drizzle_migrations";
7094
+ const migrationsSchema = typeof config === "string" ? "drizzle" : config.migrationsSchema ?? "drizzle";
7095
+ const migrationTableCreate = sql`
7096
+ CREATE TABLE IF NOT EXISTS ${sql.identifier(migrationsSchema)}.${sql.identifier(migrationsTable)} (
7097
+ id SERIAL PRIMARY KEY,
7098
+ hash text NOT NULL,
7099
+ created_at bigint
7100
+ )
7101
+ `;
7102
+ await session.execute(sql`CREATE SCHEMA IF NOT EXISTS ${sql.identifier(migrationsSchema)}`);
7103
+ await session.execute(migrationTableCreate);
7104
+ const dbMigrations = await session.all(
7105
+ sql`select id, hash, created_at from ${sql.identifier(migrationsSchema)}.${sql.identifier(migrationsTable)} order by created_at desc limit 1`
7106
+ );
7107
+ const lastDbMigration = dbMigrations[0];
7108
+ await session.transaction(async (tx) => {
7109
+ for await (const migration of migrations) {
7110
+ if (!lastDbMigration || Number(lastDbMigration.created_at) < migration.folderMillis) {
7111
+ for (const stmt of migration.sql) {
7112
+ await tx.execute(sql.raw(stmt));
7113
+ }
7114
+ await tx.execute(
7115
+ sql`insert into ${sql.identifier(migrationsSchema)}.${sql.identifier(migrationsTable)} ("hash", "created_at") values(${migration.hash}, ${migration.folderMillis})`
7116
+ );
7117
+ }
7118
+ }
7119
+ });
7120
+ }
7121
+ escapeName(name) {
7122
+ return `"${name}"`;
7123
+ }
7124
+ escapeParam(num) {
7125
+ return `$${num + 1}`;
7126
+ }
7127
+ escapeString(str) {
7128
+ return `'${str.replace(/'/g, "''")}'`;
7129
+ }
7130
+ buildWithCTE(queries) {
7131
+ if (!queries?.length) return void 0;
7132
+ const withSqlChunks = [sql`with `];
7133
+ for (const [i, w] of queries.entries()) {
7134
+ withSqlChunks.push(sql`${sql.identifier(w._.alias)} as (${w._.sql})`);
7135
+ if (i < queries.length - 1) {
7136
+ withSqlChunks.push(sql`, `);
7137
+ }
7138
+ }
7139
+ withSqlChunks.push(sql` `);
7140
+ return sql.join(withSqlChunks);
7141
+ }
7142
+ buildDeleteQuery({ table, where, returning, withList }) {
7143
+ const withSql = this.buildWithCTE(withList);
7144
+ const returningSql = returning ? sql` returning ${this.buildSelection(returning, { isSingleTable: true })}` : void 0;
7145
+ const whereSql = where ? sql` where ${where}` : void 0;
7146
+ return sql`${withSql}delete from ${table}${whereSql}${returningSql}`;
7147
+ }
7148
+ buildUpdateSet(table, set) {
7149
+ const tableColumns = table[Table.Symbol.Columns];
7150
+ const columnNames = Object.keys(tableColumns).filter(
7151
+ (colName) => set[colName] !== void 0 || tableColumns[colName]?.onUpdateFn !== void 0
7152
+ );
7153
+ const setSize = columnNames.length;
7154
+ return sql.join(columnNames.flatMap((colName, i) => {
7155
+ const col = tableColumns[colName];
7156
+ const onUpdateFnResult = col.onUpdateFn?.();
7157
+ const value = set[colName] ?? (is(onUpdateFnResult, SQL) ? onUpdateFnResult : sql.param(onUpdateFnResult, col));
7158
+ const res = sql`${sql.identifier(this.casing.getColumnCasing(col))} = ${value}`;
7159
+ if (i < setSize - 1) {
7160
+ return [res, sql.raw(", ")];
7161
+ }
7162
+ return [res];
7163
+ }));
7164
+ }
7165
+ buildUpdateQuery({ table, set, where, returning, withList, from, joins }) {
7166
+ const withSql = this.buildWithCTE(withList);
7167
+ const tableName = table[PgTable.Symbol.Name];
7168
+ const tableSchema = table[PgTable.Symbol.Schema];
7169
+ const origTableName = table[PgTable.Symbol.OriginalName];
7170
+ const alias = tableName === origTableName ? void 0 : tableName;
7171
+ const tableSql = sql`${tableSchema ? sql`${sql.identifier(tableSchema)}.` : void 0}${sql.identifier(origTableName)}${alias && sql` ${sql.identifier(alias)}`}`;
7172
+ const setSql = this.buildUpdateSet(table, set);
7173
+ const fromSql = from && sql.join([sql.raw(" from "), this.buildFromTable(from)]);
7174
+ const joinsSql = this.buildJoins(joins);
7175
+ const returningSql = returning ? sql` returning ${this.buildSelection(returning, { isSingleTable: !from })}` : void 0;
7176
+ const whereSql = where ? sql` where ${where}` : void 0;
7177
+ return sql`${withSql}update ${tableSql} set ${setSql}${fromSql}${joinsSql}${whereSql}${returningSql}`;
7178
+ }
7179
+ /**
7180
+ * Builds selection SQL with provided fields/expressions
7181
+ *
7182
+ * Examples:
7183
+ *
7184
+ * `select <selection> from`
7185
+ *
7186
+ * `insert ... returning <selection>`
7187
+ *
7188
+ * If `isSingleTable` is true, then columns won't be prefixed with table name
7189
+ */
7190
+ buildSelection(fields, { isSingleTable = false } = {}) {
7191
+ const columnsLen = fields.length;
7192
+ const chunks = fields.flatMap(({ field }, i) => {
7193
+ const chunk = [];
7194
+ if (is(field, SQL.Aliased) && field.isSelectionField) {
7195
+ chunk.push(sql.identifier(field.fieldAlias));
7196
+ } else if (is(field, SQL.Aliased) || is(field, SQL)) {
7197
+ const query = is(field, SQL.Aliased) ? field.sql : field;
7198
+ if (isSingleTable) {
7199
+ chunk.push(
7200
+ new SQL(
7201
+ query.queryChunks.map((c) => {
7202
+ if (is(c, PgColumn)) {
7203
+ return sql.identifier(this.casing.getColumnCasing(c));
7204
+ }
7205
+ return c;
7206
+ })
7207
+ )
7208
+ );
7209
+ } else {
7210
+ chunk.push(query);
7211
+ }
7212
+ if (is(field, SQL.Aliased)) {
7213
+ chunk.push(sql` as ${sql.identifier(field.fieldAlias)}`);
7214
+ }
7215
+ } else if (is(field, Column)) {
7216
+ if (isSingleTable) {
7217
+ chunk.push(sql.identifier(this.casing.getColumnCasing(field)));
7218
+ } else {
7219
+ chunk.push(field);
7220
+ }
7221
+ } else if (is(field, Subquery)) {
7222
+ const entries = Object.entries(field._.selectedFields);
7223
+ if (entries.length === 1) {
7224
+ const entry = entries[0][1];
7225
+ const fieldDecoder = is(entry, SQL) ? entry.decoder : is(entry, Column) ? { mapFromDriverValue: (v) => entry.mapFromDriverValue(v) } : entry.sql.decoder;
7226
+ if (fieldDecoder) {
7227
+ field._.sql.decoder = fieldDecoder;
7228
+ }
7229
+ }
7230
+ chunk.push(field);
7231
+ }
7232
+ if (i < columnsLen - 1) {
7233
+ chunk.push(sql`, `);
7234
+ }
7235
+ return chunk;
7236
+ });
7237
+ return sql.join(chunks);
7238
+ }
7239
+ buildJoins(joins) {
7240
+ if (!joins || joins.length === 0) {
7241
+ return void 0;
7242
+ }
7243
+ const joinsArray = [];
7244
+ for (const [index, joinMeta] of joins.entries()) {
7245
+ if (index === 0) {
7246
+ joinsArray.push(sql` `);
7247
+ }
7248
+ const table = joinMeta.table;
7249
+ const lateralSql = joinMeta.lateral ? sql` lateral` : void 0;
7250
+ const onSql = joinMeta.on ? sql` on ${joinMeta.on}` : void 0;
7251
+ if (is(table, PgTable)) {
7252
+ const tableName = table[PgTable.Symbol.Name];
7253
+ const tableSchema = table[PgTable.Symbol.Schema];
7254
+ const origTableName = table[PgTable.Symbol.OriginalName];
7255
+ const alias = tableName === origTableName ? void 0 : joinMeta.alias;
7256
+ joinsArray.push(
7257
+ sql`${sql.raw(joinMeta.joinType)} join${lateralSql} ${tableSchema ? sql`${sql.identifier(tableSchema)}.` : void 0}${sql.identifier(origTableName)}${alias && sql` ${sql.identifier(alias)}`}${onSql}`
7258
+ );
7259
+ } else if (is(table, View)) {
7260
+ const viewName = table[ViewBaseConfig].name;
7261
+ const viewSchema = table[ViewBaseConfig].schema;
7262
+ const origViewName = table[ViewBaseConfig].originalName;
7263
+ const alias = viewName === origViewName ? void 0 : joinMeta.alias;
7264
+ joinsArray.push(
7265
+ sql`${sql.raw(joinMeta.joinType)} join${lateralSql} ${viewSchema ? sql`${sql.identifier(viewSchema)}.` : void 0}${sql.identifier(origViewName)}${alias && sql` ${sql.identifier(alias)}`}${onSql}`
7266
+ );
7267
+ } else {
7268
+ joinsArray.push(
7269
+ sql`${sql.raw(joinMeta.joinType)} join${lateralSql} ${table}${onSql}`
7270
+ );
7271
+ }
7272
+ if (index < joins.length - 1) {
7273
+ joinsArray.push(sql` `);
7274
+ }
7275
+ }
7276
+ return sql.join(joinsArray);
7277
+ }
7278
+ buildFromTable(table) {
7279
+ if (is(table, Table) && table[Table.Symbol.IsAlias]) {
7280
+ let fullName = sql`${sql.identifier(table[Table.Symbol.OriginalName])}`;
7281
+ if (table[Table.Symbol.Schema]) {
7282
+ fullName = sql`${sql.identifier(table[Table.Symbol.Schema])}.${fullName}`;
7283
+ }
7284
+ return sql`${fullName} ${sql.identifier(table[Table.Symbol.Name])}`;
7285
+ }
7286
+ return table;
7287
+ }
7288
+ buildSelectQuery({
7289
+ withList,
7290
+ fields,
7291
+ fieldsFlat,
7292
+ where,
7293
+ having,
7294
+ table,
7295
+ joins,
7296
+ orderBy,
7297
+ groupBy,
7298
+ limit,
7299
+ offset,
7300
+ lockingClause,
7301
+ distinct,
7302
+ setOperators
7303
+ }) {
7304
+ const fieldsList = fieldsFlat ?? orderSelectedFields(fields);
7305
+ for (const f of fieldsList) {
7306
+ if (is(f.field, Column) && getTableName(f.field.table) !== (is(table, Subquery) ? table._.alias : is(table, PgViewBase) ? table[ViewBaseConfig].name : is(table, SQL) ? void 0 : getTableName(table)) && !((table2) => joins?.some(
7307
+ ({ alias }) => alias === (table2[Table.Symbol.IsAlias] ? getTableName(table2) : table2[Table.Symbol.BaseName])
7308
+ ))(f.field.table)) {
7309
+ const tableName = getTableName(f.field.table);
7310
+ throw new Error(
7311
+ `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?`
7312
+ );
7313
+ }
7314
+ }
7315
+ const isSingleTable = !joins || joins.length === 0;
7316
+ const withSql = this.buildWithCTE(withList);
7317
+ let distinctSql;
7318
+ if (distinct) {
7319
+ distinctSql = distinct === true ? sql` distinct` : sql` distinct on (${sql.join(distinct.on, sql`, `)})`;
7320
+ }
7321
+ const selection = this.buildSelection(fieldsList, { isSingleTable });
7322
+ const tableSql = this.buildFromTable(table);
7323
+ const joinsSql = this.buildJoins(joins);
7324
+ const whereSql = where ? sql` where ${where}` : void 0;
7325
+ const havingSql = having ? sql` having ${having}` : void 0;
7326
+ let orderBySql;
7327
+ if (orderBy && orderBy.length > 0) {
7328
+ orderBySql = sql` order by ${sql.join(orderBy, sql`, `)}`;
7329
+ }
7330
+ let groupBySql;
7331
+ if (groupBy && groupBy.length > 0) {
7332
+ groupBySql = sql` group by ${sql.join(groupBy, sql`, `)}`;
7333
+ }
7334
+ const limitSql = typeof limit === "object" || typeof limit === "number" && limit >= 0 ? sql` limit ${limit}` : void 0;
7335
+ const offsetSql = offset ? sql` offset ${offset}` : void 0;
7336
+ const lockingClauseSql = sql.empty();
7337
+ if (lockingClause) {
7338
+ const clauseSql = sql` for ${sql.raw(lockingClause.strength)}`;
7339
+ if (lockingClause.config.of) {
7340
+ clauseSql.append(
7341
+ sql` of ${sql.join(
7342
+ Array.isArray(lockingClause.config.of) ? lockingClause.config.of : [lockingClause.config.of],
7343
+ sql`, `
7344
+ )}`
7345
+ );
7346
+ }
7347
+ if (lockingClause.config.noWait) {
7348
+ clauseSql.append(sql` nowait`);
7349
+ } else if (lockingClause.config.skipLocked) {
7350
+ clauseSql.append(sql` skip locked`);
7351
+ }
7352
+ lockingClauseSql.append(clauseSql);
7353
+ }
7354
+ const finalQuery = sql`${withSql}select${distinctSql} ${selection} from ${tableSql}${joinsSql}${whereSql}${groupBySql}${havingSql}${orderBySql}${limitSql}${offsetSql}${lockingClauseSql}`;
7355
+ if (setOperators.length > 0) {
7356
+ return this.buildSetOperations(finalQuery, setOperators);
7357
+ }
7358
+ return finalQuery;
7359
+ }
7360
+ buildSetOperations(leftSelect, setOperators) {
7361
+ const [setOperator, ...rest] = setOperators;
7362
+ if (!setOperator) {
7363
+ throw new Error("Cannot pass undefined values to any set operator");
7364
+ }
7365
+ if (rest.length === 0) {
7366
+ return this.buildSetOperationQuery({ leftSelect, setOperator });
7367
+ }
7368
+ return this.buildSetOperations(
7369
+ this.buildSetOperationQuery({ leftSelect, setOperator }),
7370
+ rest
7371
+ );
7372
+ }
7373
+ buildSetOperationQuery({
7374
+ leftSelect,
7375
+ setOperator: { type, isAll, rightSelect, limit, orderBy, offset }
7376
+ }) {
7377
+ const leftChunk = sql`(${leftSelect.getSQL()}) `;
7378
+ const rightChunk = sql`(${rightSelect.getSQL()})`;
7379
+ let orderBySql;
7380
+ if (orderBy && orderBy.length > 0) {
7381
+ const orderByValues = [];
7382
+ for (const singleOrderBy of orderBy) {
7383
+ if (is(singleOrderBy, PgColumn)) {
7384
+ orderByValues.push(sql.identifier(singleOrderBy.name));
7385
+ } else if (is(singleOrderBy, SQL)) {
7386
+ for (let i = 0; i < singleOrderBy.queryChunks.length; i++) {
7387
+ const chunk = singleOrderBy.queryChunks[i];
7388
+ if (is(chunk, PgColumn)) {
7389
+ singleOrderBy.queryChunks[i] = sql.identifier(chunk.name);
7390
+ }
7391
+ }
7392
+ orderByValues.push(sql`${singleOrderBy}`);
7393
+ } else {
7394
+ orderByValues.push(sql`${singleOrderBy}`);
7395
+ }
7396
+ }
7397
+ orderBySql = sql` order by ${sql.join(orderByValues, sql`, `)} `;
7398
+ }
7399
+ const limitSql = typeof limit === "object" || typeof limit === "number" && limit >= 0 ? sql` limit ${limit}` : void 0;
7400
+ const operatorChunk = sql.raw(`${type} ${isAll ? "all " : ""}`);
7401
+ const offsetSql = offset ? sql` offset ${offset}` : void 0;
7402
+ return sql`${leftChunk}${operatorChunk}${rightChunk}${orderBySql}${limitSql}${offsetSql}`;
7403
+ }
7404
+ buildInsertQuery({ table, values: valuesOrSelect, onConflict, returning, withList, select, overridingSystemValue_ }) {
7405
+ const valuesSqlList = [];
7406
+ const columns = table[Table.Symbol.Columns];
7407
+ const colEntries = Object.entries(columns).filter(([_, col]) => !col.shouldDisableInsert());
7408
+ const insertOrder = colEntries.map(
7409
+ ([, column]) => sql.identifier(this.casing.getColumnCasing(column))
7410
+ );
7411
+ if (select) {
7412
+ const select2 = valuesOrSelect;
7413
+ if (is(select2, SQL)) {
7414
+ valuesSqlList.push(select2);
7415
+ } else {
7416
+ valuesSqlList.push(select2.getSQL());
7417
+ }
7418
+ } else {
7419
+ const values = valuesOrSelect;
7420
+ valuesSqlList.push(sql.raw("values "));
7421
+ for (const [valueIndex, value] of values.entries()) {
7422
+ const valueList = [];
7423
+ for (const [fieldName, col] of colEntries) {
7424
+ const colValue = value[fieldName];
7425
+ if (colValue === void 0 || is(colValue, Param) && colValue.value === void 0) {
7426
+ if (col.defaultFn !== void 0) {
7427
+ const defaultFnResult = col.defaultFn();
7428
+ const defaultValue = is(defaultFnResult, SQL) ? defaultFnResult : sql.param(defaultFnResult, col);
7429
+ valueList.push(defaultValue);
7430
+ } else if (!col.default && col.onUpdateFn !== void 0) {
7431
+ const onUpdateFnResult = col.onUpdateFn();
7432
+ const newValue = is(onUpdateFnResult, SQL) ? onUpdateFnResult : sql.param(onUpdateFnResult, col);
7433
+ valueList.push(newValue);
7434
+ } else {
7435
+ valueList.push(sql`default`);
7436
+ }
7437
+ } else {
7438
+ valueList.push(colValue);
7439
+ }
7440
+ }
7441
+ valuesSqlList.push(valueList);
7442
+ if (valueIndex < values.length - 1) {
7443
+ valuesSqlList.push(sql`, `);
7444
+ }
7445
+ }
7446
+ }
7447
+ const withSql = this.buildWithCTE(withList);
7448
+ const valuesSql = sql.join(valuesSqlList);
7449
+ const returningSql = returning ? sql` returning ${this.buildSelection(returning, { isSingleTable: true })}` : void 0;
7450
+ const onConflictSql = onConflict ? sql` on conflict ${onConflict}` : void 0;
7451
+ const overridingSql = overridingSystemValue_ === true ? sql`overriding system value ` : void 0;
7452
+ return sql`${withSql}insert into ${table} ${insertOrder} ${overridingSql}${valuesSql}${onConflictSql}${returningSql}`;
7453
+ }
7454
+ buildRefreshMaterializedViewQuery({ view, concurrently, withNoData }) {
7455
+ const concurrentlySql = concurrently ? sql` concurrently` : void 0;
7456
+ const withNoDataSql = withNoData ? sql` with no data` : void 0;
7457
+ return sql`refresh materialized view${concurrentlySql} ${view}${withNoDataSql}`;
7458
+ }
7459
+ prepareTyping(encoder) {
7460
+ if (is(encoder, PgJsonb) || is(encoder, PgJson)) {
7461
+ return "json";
7462
+ } else if (is(encoder, PgNumeric)) {
7463
+ return "decimal";
7464
+ } else if (is(encoder, PgTime)) {
7465
+ return "time";
7466
+ } else if (is(encoder, PgTimestamp) || is(encoder, PgTimestampString)) {
7467
+ return "timestamp";
7468
+ } else if (is(encoder, PgDate) || is(encoder, PgDateString)) {
7469
+ return "date";
7470
+ } else if (is(encoder, PgUUID)) {
7471
+ return "uuid";
7472
+ } else {
7473
+ return "none";
7474
+ }
7475
+ }
7476
+ sqlToQuery(sql2, invokeSource) {
7477
+ return sql2.toQuery({
7478
+ casing: this.casing,
7479
+ escapeName: this.escapeName,
7480
+ escapeParam: this.escapeParam,
7481
+ escapeString: this.escapeString,
7482
+ prepareTyping: this.prepareTyping,
7483
+ invokeSource
7484
+ });
7485
+ }
7486
+ // buildRelationalQueryWithPK({
7487
+ // fullSchema,
7488
+ // schema,
7489
+ // tableNamesMap,
7490
+ // table,
7491
+ // tableConfig,
7492
+ // queryConfig: config,
7493
+ // tableAlias,
7494
+ // isRoot = false,
7495
+ // joinOn,
7496
+ // }: {
7497
+ // fullSchema: Record<string, unknown>;
7498
+ // schema: TablesRelationalConfig;
7499
+ // tableNamesMap: Record<string, string>;
7500
+ // table: PgTable;
7501
+ // tableConfig: TableRelationalConfig;
7502
+ // queryConfig: true | DBQueryConfig<'many', true>;
7503
+ // tableAlias: string;
7504
+ // isRoot?: boolean;
7505
+ // joinOn?: SQL;
7506
+ // }): BuildRelationalQueryResult<PgTable, PgColumn> {
7507
+ // // For { "<relation>": true }, return a table with selection of all columns
7508
+ // if (config === true) {
7509
+ // const selectionEntries = Object.entries(tableConfig.columns);
7510
+ // const selection: BuildRelationalQueryResult<PgTable, PgColumn>['selection'] = selectionEntries.map((
7511
+ // [key, value],
7512
+ // ) => ({
7513
+ // dbKey: value.name,
7514
+ // tsKey: key,
7515
+ // field: value as PgColumn,
7516
+ // relationTableTsKey: undefined,
7517
+ // isJson: false,
7518
+ // selection: [],
7519
+ // }));
7520
+ // return {
7521
+ // tableTsKey: tableConfig.tsName,
7522
+ // sql: table,
7523
+ // selection,
7524
+ // };
7525
+ // }
7526
+ // // let selection: BuildRelationalQueryResult<PgTable, PgColumn>['selection'] = [];
7527
+ // // let selectionForBuild = selection;
7528
+ // const aliasedColumns = Object.fromEntries(
7529
+ // Object.entries(tableConfig.columns).map(([key, value]) => [key, aliasedTableColumn(value, tableAlias)]),
7530
+ // );
7531
+ // const aliasedRelations = Object.fromEntries(
7532
+ // Object.entries(tableConfig.relations).map(([key, value]) => [key, aliasedRelation(value, tableAlias)]),
7533
+ // );
7534
+ // const aliasedFields = Object.assign({}, aliasedColumns, aliasedRelations);
7535
+ // let where, hasUserDefinedWhere;
7536
+ // if (config.where) {
7537
+ // const whereSql = typeof config.where === 'function' ? config.where(aliasedFields, operators) : config.where;
7538
+ // where = whereSql && mapColumnsInSQLToAlias(whereSql, tableAlias);
7539
+ // hasUserDefinedWhere = !!where;
7540
+ // }
7541
+ // where = and(joinOn, where);
7542
+ // // const fieldsSelection: { tsKey: string; value: PgColumn | SQL.Aliased; isExtra?: boolean }[] = [];
7543
+ // let joins: Join[] = [];
7544
+ // let selectedColumns: string[] = [];
7545
+ // // Figure out which columns to select
7546
+ // if (config.columns) {
7547
+ // let isIncludeMode = false;
7548
+ // for (const [field, value] of Object.entries(config.columns)) {
7549
+ // if (value === undefined) {
7550
+ // continue;
7551
+ // }
7552
+ // if (field in tableConfig.columns) {
7553
+ // if (!isIncludeMode && value === true) {
7554
+ // isIncludeMode = true;
7555
+ // }
7556
+ // selectedColumns.push(field);
7557
+ // }
7558
+ // }
7559
+ // if (selectedColumns.length > 0) {
7560
+ // selectedColumns = isIncludeMode
7561
+ // ? selectedColumns.filter((c) => config.columns?.[c] === true)
7562
+ // : Object.keys(tableConfig.columns).filter((key) => !selectedColumns.includes(key));
7563
+ // }
7564
+ // } else {
7565
+ // // Select all columns if selection is not specified
7566
+ // selectedColumns = Object.keys(tableConfig.columns);
7567
+ // }
7568
+ // // for (const field of selectedColumns) {
7569
+ // // const column = tableConfig.columns[field]! as PgColumn;
7570
+ // // fieldsSelection.push({ tsKey: field, value: column });
7571
+ // // }
7572
+ // let initiallySelectedRelations: {
7573
+ // tsKey: string;
7574
+ // queryConfig: true | DBQueryConfig<'many', false>;
7575
+ // relation: Relation;
7576
+ // }[] = [];
7577
+ // // let selectedRelations: BuildRelationalQueryResult<PgTable, PgColumn>['selection'] = [];
7578
+ // // Figure out which relations to select
7579
+ // if (config.with) {
7580
+ // initiallySelectedRelations = Object.entries(config.with)
7581
+ // .filter((entry): entry is [typeof entry[0], NonNullable<typeof entry[1]>] => !!entry[1])
7582
+ // .map(([tsKey, queryConfig]) => ({ tsKey, queryConfig, relation: tableConfig.relations[tsKey]! }));
7583
+ // }
7584
+ // const manyRelations = initiallySelectedRelations.filter((r) =>
7585
+ // is(r.relation, Many)
7586
+ // && (schema[tableNamesMap[r.relation.referencedTable[Table.Symbol.Name]]!]?.primaryKey.length ?? 0) > 0
7587
+ // );
7588
+ // // If this is the last Many relation (or there are no Many relations), we are on the innermost subquery level
7589
+ // const isInnermostQuery = manyRelations.length < 2;
7590
+ // const selectedExtras: {
7591
+ // tsKey: string;
7592
+ // value: SQL.Aliased;
7593
+ // }[] = [];
7594
+ // // Figure out which extras to select
7595
+ // if (isInnermostQuery && config.extras) {
7596
+ // const extras = typeof config.extras === 'function'
7597
+ // ? config.extras(aliasedFields, { sql })
7598
+ // : config.extras;
7599
+ // for (const [tsKey, value] of Object.entries(extras)) {
7600
+ // selectedExtras.push({
7601
+ // tsKey,
7602
+ // value: mapColumnsInAliasedSQLToAlias(value, tableAlias),
7603
+ // });
7604
+ // }
7605
+ // }
7606
+ // // Transform `fieldsSelection` into `selection`
7607
+ // // `fieldsSelection` shouldn't be used after this point
7608
+ // // for (const { tsKey, value, isExtra } of fieldsSelection) {
7609
+ // // selection.push({
7610
+ // // dbKey: is(value, SQL.Aliased) ? value.fieldAlias : tableConfig.columns[tsKey]!.name,
7611
+ // // tsKey,
7612
+ // // field: is(value, Column) ? aliasedTableColumn(value, tableAlias) : value,
7613
+ // // relationTableTsKey: undefined,
7614
+ // // isJson: false,
7615
+ // // isExtra,
7616
+ // // selection: [],
7617
+ // // });
7618
+ // // }
7619
+ // let orderByOrig = typeof config.orderBy === 'function'
7620
+ // ? config.orderBy(aliasedFields, orderByOperators)
7621
+ // : config.orderBy ?? [];
7622
+ // if (!Array.isArray(orderByOrig)) {
7623
+ // orderByOrig = [orderByOrig];
7624
+ // }
7625
+ // const orderBy = orderByOrig.map((orderByValue) => {
7626
+ // if (is(orderByValue, Column)) {
7627
+ // return aliasedTableColumn(orderByValue, tableAlias) as PgColumn;
7628
+ // }
7629
+ // return mapColumnsInSQLToAlias(orderByValue, tableAlias);
7630
+ // });
7631
+ // const limit = isInnermostQuery ? config.limit : undefined;
7632
+ // const offset = isInnermostQuery ? config.offset : undefined;
7633
+ // // For non-root queries without additional config except columns, return a table with selection
7634
+ // if (
7635
+ // !isRoot
7636
+ // && initiallySelectedRelations.length === 0
7637
+ // && selectedExtras.length === 0
7638
+ // && !where
7639
+ // && orderBy.length === 0
7640
+ // && limit === undefined
7641
+ // && offset === undefined
7642
+ // ) {
7643
+ // return {
7644
+ // tableTsKey: tableConfig.tsName,
7645
+ // sql: table,
7646
+ // selection: selectedColumns.map((key) => ({
7647
+ // dbKey: tableConfig.columns[key]!.name,
7648
+ // tsKey: key,
7649
+ // field: tableConfig.columns[key] as PgColumn,
7650
+ // relationTableTsKey: undefined,
7651
+ // isJson: false,
7652
+ // selection: [],
7653
+ // })),
7654
+ // };
7655
+ // }
7656
+ // const selectedRelationsWithoutPK:
7657
+ // // Process all relations without primary keys, because they need to be joined differently and will all be on the same query level
7658
+ // for (
7659
+ // const {
7660
+ // tsKey: selectedRelationTsKey,
7661
+ // queryConfig: selectedRelationConfigValue,
7662
+ // relation,
7663
+ // } of initiallySelectedRelations
7664
+ // ) {
7665
+ // const normalizedRelation = normalizeRelation(schema, tableNamesMap, relation);
7666
+ // const relationTableName = relation.referencedTable[Table.Symbol.Name];
7667
+ // const relationTableTsName = tableNamesMap[relationTableName]!;
7668
+ // const relationTable = schema[relationTableTsName]!;
7669
+ // if (relationTable.primaryKey.length > 0) {
7670
+ // continue;
7671
+ // }
7672
+ // const relationTableAlias = `${tableAlias}_${selectedRelationTsKey}`;
7673
+ // const joinOn = and(
7674
+ // ...normalizedRelation.fields.map((field, i) =>
7675
+ // eq(
7676
+ // aliasedTableColumn(normalizedRelation.references[i]!, relationTableAlias),
7677
+ // aliasedTableColumn(field, tableAlias),
7678
+ // )
7679
+ // ),
7680
+ // );
7681
+ // const builtRelation = this.buildRelationalQueryWithoutPK({
7682
+ // fullSchema,
7683
+ // schema,
7684
+ // tableNamesMap,
7685
+ // table: fullSchema[relationTableTsName] as PgTable,
7686
+ // tableConfig: schema[relationTableTsName]!,
7687
+ // queryConfig: selectedRelationConfigValue,
7688
+ // tableAlias: relationTableAlias,
7689
+ // joinOn,
7690
+ // nestedQueryRelation: relation,
7691
+ // });
7692
+ // const field = sql`${sql.identifier(relationTableAlias)}.${sql.identifier('data')}`.as(selectedRelationTsKey);
7693
+ // joins.push({
7694
+ // on: sql`true`,
7695
+ // table: new Subquery(builtRelation.sql as SQL, {}, relationTableAlias),
7696
+ // alias: relationTableAlias,
7697
+ // joinType: 'left',
7698
+ // lateral: true,
7699
+ // });
7700
+ // selectedRelations.push({
7701
+ // dbKey: selectedRelationTsKey,
7702
+ // tsKey: selectedRelationTsKey,
7703
+ // field,
7704
+ // relationTableTsKey: relationTableTsName,
7705
+ // isJson: true,
7706
+ // selection: builtRelation.selection,
7707
+ // });
7708
+ // }
7709
+ // const oneRelations = initiallySelectedRelations.filter((r): r is typeof r & { relation: One } =>
7710
+ // is(r.relation, One)
7711
+ // );
7712
+ // // Process all One relations with PKs, because they can all be joined on the same level
7713
+ // for (
7714
+ // const {
7715
+ // tsKey: selectedRelationTsKey,
7716
+ // queryConfig: selectedRelationConfigValue,
7717
+ // relation,
7718
+ // } of oneRelations
7719
+ // ) {
7720
+ // const normalizedRelation = normalizeRelation(schema, tableNamesMap, relation);
7721
+ // const relationTableName = relation.referencedTable[Table.Symbol.Name];
7722
+ // const relationTableTsName = tableNamesMap[relationTableName]!;
7723
+ // const relationTableAlias = `${tableAlias}_${selectedRelationTsKey}`;
7724
+ // const relationTable = schema[relationTableTsName]!;
7725
+ // if (relationTable.primaryKey.length === 0) {
7726
+ // continue;
7727
+ // }
7728
+ // const joinOn = and(
7729
+ // ...normalizedRelation.fields.map((field, i) =>
7730
+ // eq(
7731
+ // aliasedTableColumn(normalizedRelation.references[i]!, relationTableAlias),
7732
+ // aliasedTableColumn(field, tableAlias),
7733
+ // )
7734
+ // ),
7735
+ // );
7736
+ // const builtRelation = this.buildRelationalQueryWithPK({
7737
+ // fullSchema,
7738
+ // schema,
7739
+ // tableNamesMap,
7740
+ // table: fullSchema[relationTableTsName] as PgTable,
7741
+ // tableConfig: schema[relationTableTsName]!,
7742
+ // queryConfig: selectedRelationConfigValue,
7743
+ // tableAlias: relationTableAlias,
7744
+ // joinOn,
7745
+ // });
7746
+ // const field = sql`case when ${sql.identifier(relationTableAlias)} is null then null else json_build_array(${
7747
+ // sql.join(
7748
+ // builtRelation.selection.map(({ field }) =>
7749
+ // is(field, SQL.Aliased)
7750
+ // ? sql`${sql.identifier(relationTableAlias)}.${sql.identifier(field.fieldAlias)}`
7751
+ // : is(field, Column)
7752
+ // ? aliasedTableColumn(field, relationTableAlias)
7753
+ // : field
7754
+ // ),
7755
+ // sql`, `,
7756
+ // )
7757
+ // }) end`.as(selectedRelationTsKey);
7758
+ // const isLateralJoin = is(builtRelation.sql, SQL);
7759
+ // joins.push({
7760
+ // on: isLateralJoin ? sql`true` : joinOn,
7761
+ // table: is(builtRelation.sql, SQL)
7762
+ // ? new Subquery(builtRelation.sql, {}, relationTableAlias)
7763
+ // : aliasedTable(builtRelation.sql, relationTableAlias),
7764
+ // alias: relationTableAlias,
7765
+ // joinType: 'left',
7766
+ // lateral: is(builtRelation.sql, SQL),
7767
+ // });
7768
+ // selectedRelations.push({
7769
+ // dbKey: selectedRelationTsKey,
7770
+ // tsKey: selectedRelationTsKey,
7771
+ // field,
7772
+ // relationTableTsKey: relationTableTsName,
7773
+ // isJson: true,
7774
+ // selection: builtRelation.selection,
7775
+ // });
7776
+ // }
7777
+ // let distinct: PgSelectConfig['distinct'];
7778
+ // let tableFrom: PgTable | Subquery = table;
7779
+ // // Process first Many relation - each one requires a nested subquery
7780
+ // const manyRelation = manyRelations[0];
7781
+ // if (manyRelation) {
7782
+ // const {
7783
+ // tsKey: selectedRelationTsKey,
7784
+ // queryConfig: selectedRelationQueryConfig,
7785
+ // relation,
7786
+ // } = manyRelation;
7787
+ // distinct = {
7788
+ // on: tableConfig.primaryKey.map((c) => aliasedTableColumn(c as PgColumn, tableAlias)),
7789
+ // };
7790
+ // const normalizedRelation = normalizeRelation(schema, tableNamesMap, relation);
7791
+ // const relationTableName = relation.referencedTable[Table.Symbol.Name];
7792
+ // const relationTableTsName = tableNamesMap[relationTableName]!;
7793
+ // const relationTableAlias = `${tableAlias}_${selectedRelationTsKey}`;
7794
+ // const joinOn = and(
7795
+ // ...normalizedRelation.fields.map((field, i) =>
7796
+ // eq(
7797
+ // aliasedTableColumn(normalizedRelation.references[i]!, relationTableAlias),
7798
+ // aliasedTableColumn(field, tableAlias),
7799
+ // )
7800
+ // ),
7801
+ // );
7802
+ // const builtRelationJoin = this.buildRelationalQueryWithPK({
7803
+ // fullSchema,
7804
+ // schema,
7805
+ // tableNamesMap,
7806
+ // table: fullSchema[relationTableTsName] as PgTable,
7807
+ // tableConfig: schema[relationTableTsName]!,
7808
+ // queryConfig: selectedRelationQueryConfig,
7809
+ // tableAlias: relationTableAlias,
7810
+ // joinOn,
7811
+ // });
7812
+ // const builtRelationSelectionField = sql`case when ${
7813
+ // sql.identifier(relationTableAlias)
7814
+ // } is null then '[]' else json_agg(json_build_array(${
7815
+ // sql.join(
7816
+ // builtRelationJoin.selection.map(({ field }) =>
7817
+ // is(field, SQL.Aliased)
7818
+ // ? sql`${sql.identifier(relationTableAlias)}.${sql.identifier(field.fieldAlias)}`
7819
+ // : is(field, Column)
7820
+ // ? aliasedTableColumn(field, relationTableAlias)
7821
+ // : field
7822
+ // ),
7823
+ // sql`, `,
7824
+ // )
7825
+ // })) over (partition by ${sql.join(distinct.on, sql`, `)}) end`.as(selectedRelationTsKey);
7826
+ // const isLateralJoin = is(builtRelationJoin.sql, SQL);
7827
+ // joins.push({
7828
+ // on: isLateralJoin ? sql`true` : joinOn,
7829
+ // table: isLateralJoin
7830
+ // ? new Subquery(builtRelationJoin.sql as SQL, {}, relationTableAlias)
7831
+ // : aliasedTable(builtRelationJoin.sql as PgTable, relationTableAlias),
7832
+ // alias: relationTableAlias,
7833
+ // joinType: 'left',
7834
+ // lateral: isLateralJoin,
7835
+ // });
7836
+ // // Build the "from" subquery with the remaining Many relations
7837
+ // const builtTableFrom = this.buildRelationalQueryWithPK({
7838
+ // fullSchema,
7839
+ // schema,
7840
+ // tableNamesMap,
7841
+ // table,
7842
+ // tableConfig,
7843
+ // queryConfig: {
7844
+ // ...config,
7845
+ // where: undefined,
7846
+ // orderBy: undefined,
7847
+ // limit: undefined,
7848
+ // offset: undefined,
7849
+ // with: manyRelations.slice(1).reduce<NonNullable<typeof config['with']>>(
7850
+ // (result, { tsKey, queryConfig: configValue }) => {
7851
+ // result[tsKey] = configValue;
7852
+ // return result;
7853
+ // },
7854
+ // {},
7855
+ // ),
7856
+ // },
7857
+ // tableAlias,
7858
+ // });
7859
+ // selectedRelations.push({
7860
+ // dbKey: selectedRelationTsKey,
7861
+ // tsKey: selectedRelationTsKey,
7862
+ // field: builtRelationSelectionField,
7863
+ // relationTableTsKey: relationTableTsName,
7864
+ // isJson: true,
7865
+ // selection: builtRelationJoin.selection,
7866
+ // });
7867
+ // // selection = builtTableFrom.selection.map((item) =>
7868
+ // // is(item.field, SQL.Aliased)
7869
+ // // ? { ...item, field: sql`${sql.identifier(tableAlias)}.${sql.identifier(item.field.fieldAlias)}` }
7870
+ // // : item
7871
+ // // );
7872
+ // // selectionForBuild = [{
7873
+ // // dbKey: '*',
7874
+ // // tsKey: '*',
7875
+ // // field: sql`${sql.identifier(tableAlias)}.*`,
7876
+ // // selection: [],
7877
+ // // isJson: false,
7878
+ // // relationTableTsKey: undefined,
7879
+ // // }];
7880
+ // // const newSelectionItem: (typeof selection)[number] = {
7881
+ // // dbKey: selectedRelationTsKey,
7882
+ // // tsKey: selectedRelationTsKey,
7883
+ // // field,
7884
+ // // relationTableTsKey: relationTableTsName,
7885
+ // // isJson: true,
7886
+ // // selection: builtRelationJoin.selection,
7887
+ // // };
7888
+ // // selection.push(newSelectionItem);
7889
+ // // selectionForBuild.push(newSelectionItem);
7890
+ // tableFrom = is(builtTableFrom.sql, PgTable)
7891
+ // ? builtTableFrom.sql
7892
+ // : new Subquery(builtTableFrom.sql, {}, tableAlias);
7893
+ // }
7894
+ // if (selectedColumns.length === 0 && selectedRelations.length === 0 && selectedExtras.length === 0) {
7895
+ // throw new DrizzleError(`No fields selected for table "${tableConfig.tsName}" ("${tableAlias}")`);
7896
+ // }
7897
+ // let selection: BuildRelationalQueryResult<PgTable, PgColumn>['selection'];
7898
+ // function prepareSelectedColumns() {
7899
+ // return selectedColumns.map((key) => ({
7900
+ // dbKey: tableConfig.columns[key]!.name,
7901
+ // tsKey: key,
7902
+ // field: tableConfig.columns[key] as PgColumn,
7903
+ // relationTableTsKey: undefined,
7904
+ // isJson: false,
7905
+ // selection: [],
7906
+ // }));
7907
+ // }
7908
+ // function prepareSelectedExtras() {
7909
+ // return selectedExtras.map((item) => ({
7910
+ // dbKey: item.value.fieldAlias,
7911
+ // tsKey: item.tsKey,
7912
+ // field: item.value,
7913
+ // relationTableTsKey: undefined,
7914
+ // isJson: false,
7915
+ // selection: [],
7916
+ // }));
7917
+ // }
7918
+ // if (isRoot) {
7919
+ // selection = [
7920
+ // ...prepareSelectedColumns(),
7921
+ // ...prepareSelectedExtras(),
7922
+ // ];
7923
+ // }
7924
+ // if (hasUserDefinedWhere || orderBy.length > 0) {
7925
+ // tableFrom = new Subquery(
7926
+ // this.buildSelectQuery({
7927
+ // table: is(tableFrom, PgTable) ? aliasedTable(tableFrom, tableAlias) : tableFrom,
7928
+ // fields: {},
7929
+ // fieldsFlat: selectionForBuild.map(({ field }) => ({
7930
+ // path: [],
7931
+ // field: is(field, Column) ? aliasedTableColumn(field, tableAlias) : field,
7932
+ // })),
7933
+ // joins,
7934
+ // distinct,
7935
+ // }),
7936
+ // {},
7937
+ // tableAlias,
7938
+ // );
7939
+ // selectionForBuild = selection.map((item) =>
7940
+ // is(item.field, SQL.Aliased)
7941
+ // ? { ...item, field: sql`${sql.identifier(tableAlias)}.${sql.identifier(item.field.fieldAlias)}` }
7942
+ // : item
7943
+ // );
7944
+ // joins = [];
7945
+ // distinct = undefined;
7946
+ // }
7947
+ // const result = this.buildSelectQuery({
7948
+ // table: is(tableFrom, PgTable) ? aliasedTable(tableFrom, tableAlias) : tableFrom,
7949
+ // fields: {},
7950
+ // fieldsFlat: selectionForBuild.map(({ field }) => ({
7951
+ // path: [],
7952
+ // field: is(field, Column) ? aliasedTableColumn(field, tableAlias) : field,
7953
+ // })),
7954
+ // where,
7955
+ // limit,
7956
+ // offset,
7957
+ // joins,
7958
+ // orderBy,
7959
+ // distinct,
7960
+ // });
7961
+ // return {
7962
+ // tableTsKey: tableConfig.tsName,
7963
+ // sql: result,
7964
+ // selection,
7965
+ // };
7966
+ // }
7967
+ buildRelationalQueryWithoutPK({
7968
+ fullSchema,
7969
+ schema,
7970
+ tableNamesMap,
7971
+ table,
7972
+ tableConfig,
7973
+ queryConfig: config,
7974
+ tableAlias,
7975
+ nestedQueryRelation,
7976
+ joinOn
7977
+ }) {
7978
+ let selection = [];
7979
+ let limit, offset, orderBy = [], where;
7980
+ const joins = [];
7981
+ if (config === true) {
7982
+ const selectionEntries = Object.entries(tableConfig.columns);
7983
+ selection = selectionEntries.map(([key, value]) => ({
7984
+ dbKey: value.name,
7985
+ tsKey: key,
7986
+ field: aliasedTableColumn(value, tableAlias),
7987
+ relationTableTsKey: void 0,
7988
+ isJson: false,
7989
+ selection: []
7990
+ }));
7991
+ } else {
7992
+ const aliasedColumns = Object.fromEntries(
7993
+ Object.entries(tableConfig.columns).map(([key, value]) => [key, aliasedTableColumn(value, tableAlias)])
7994
+ );
7995
+ if (config.where) {
7996
+ const whereSql = typeof config.where === "function" ? config.where(aliasedColumns, getOperators()) : config.where;
7997
+ where = whereSql && mapColumnsInSQLToAlias(whereSql, tableAlias);
7998
+ }
7999
+ const fieldsSelection = [];
8000
+ let selectedColumns = [];
8001
+ if (config.columns) {
8002
+ let isIncludeMode = false;
8003
+ for (const [field, value] of Object.entries(config.columns)) {
8004
+ if (value === void 0) {
8005
+ continue;
8006
+ }
8007
+ if (field in tableConfig.columns) {
8008
+ if (!isIncludeMode && value === true) {
8009
+ isIncludeMode = true;
8010
+ }
8011
+ selectedColumns.push(field);
8012
+ }
8013
+ }
8014
+ if (selectedColumns.length > 0) {
8015
+ selectedColumns = isIncludeMode ? selectedColumns.filter((c) => config.columns?.[c] === true) : Object.keys(tableConfig.columns).filter((key) => !selectedColumns.includes(key));
8016
+ }
8017
+ } else {
8018
+ selectedColumns = Object.keys(tableConfig.columns);
8019
+ }
8020
+ for (const field of selectedColumns) {
8021
+ const column = tableConfig.columns[field];
8022
+ fieldsSelection.push({ tsKey: field, value: column });
8023
+ }
8024
+ let selectedRelations = [];
8025
+ if (config.with) {
8026
+ selectedRelations = Object.entries(config.with).filter((entry) => !!entry[1]).map(([tsKey, queryConfig]) => ({ tsKey, queryConfig, relation: tableConfig.relations[tsKey] }));
8027
+ }
8028
+ let extras;
8029
+ if (config.extras) {
8030
+ extras = typeof config.extras === "function" ? config.extras(aliasedColumns, { sql }) : config.extras;
8031
+ for (const [tsKey, value] of Object.entries(extras)) {
8032
+ fieldsSelection.push({
8033
+ tsKey,
8034
+ value: mapColumnsInAliasedSQLToAlias(value, tableAlias)
8035
+ });
8036
+ }
8037
+ }
8038
+ for (const { tsKey, value } of fieldsSelection) {
8039
+ selection.push({
8040
+ dbKey: is(value, SQL.Aliased) ? value.fieldAlias : tableConfig.columns[tsKey].name,
8041
+ tsKey,
8042
+ field: is(value, Column) ? aliasedTableColumn(value, tableAlias) : value,
8043
+ relationTableTsKey: void 0,
8044
+ isJson: false,
8045
+ selection: []
8046
+ });
8047
+ }
8048
+ let orderByOrig = typeof config.orderBy === "function" ? config.orderBy(aliasedColumns, getOrderByOperators()) : config.orderBy ?? [];
8049
+ if (!Array.isArray(orderByOrig)) {
8050
+ orderByOrig = [orderByOrig];
8051
+ }
8052
+ orderBy = orderByOrig.map((orderByValue) => {
8053
+ if (is(orderByValue, Column)) {
8054
+ return aliasedTableColumn(orderByValue, tableAlias);
8055
+ }
8056
+ return mapColumnsInSQLToAlias(orderByValue, tableAlias);
8057
+ });
8058
+ limit = config.limit;
8059
+ offset = config.offset;
8060
+ for (const {
8061
+ tsKey: selectedRelationTsKey,
8062
+ queryConfig: selectedRelationConfigValue,
8063
+ relation
8064
+ } of selectedRelations) {
8065
+ const normalizedRelation = normalizeRelation(schema, tableNamesMap, relation);
8066
+ const relationTableName = getTableUniqueName(relation.referencedTable);
8067
+ const relationTableTsName = tableNamesMap[relationTableName];
8068
+ const relationTableAlias = `${tableAlias}_${selectedRelationTsKey}`;
8069
+ const joinOn2 = and(
8070
+ ...normalizedRelation.fields.map(
8071
+ (field2, i) => eq(
8072
+ aliasedTableColumn(normalizedRelation.references[i], relationTableAlias),
8073
+ aliasedTableColumn(field2, tableAlias)
8074
+ )
8075
+ )
8076
+ );
8077
+ const builtRelation = this.buildRelationalQueryWithoutPK({
8078
+ fullSchema,
8079
+ schema,
8080
+ tableNamesMap,
8081
+ table: fullSchema[relationTableTsName],
8082
+ tableConfig: schema[relationTableTsName],
8083
+ queryConfig: is(relation, One) ? selectedRelationConfigValue === true ? { limit: 1 } : { ...selectedRelationConfigValue, limit: 1 } : selectedRelationConfigValue,
8084
+ tableAlias: relationTableAlias,
8085
+ joinOn: joinOn2,
8086
+ nestedQueryRelation: relation
8087
+ });
8088
+ const field = sql`${sql.identifier(relationTableAlias)}.${sql.identifier("data")}`.as(selectedRelationTsKey);
8089
+ joins.push({
8090
+ on: sql`true`,
8091
+ table: new Subquery(builtRelation.sql, {}, relationTableAlias),
8092
+ alias: relationTableAlias,
8093
+ joinType: "left",
8094
+ lateral: true
8095
+ });
8096
+ selection.push({
8097
+ dbKey: selectedRelationTsKey,
8098
+ tsKey: selectedRelationTsKey,
8099
+ field,
8100
+ relationTableTsKey: relationTableTsName,
8101
+ isJson: true,
8102
+ selection: builtRelation.selection
8103
+ });
8104
+ }
8105
+ }
8106
+ if (selection.length === 0) {
8107
+ throw new DrizzleError({ message: `No fields selected for table "${tableConfig.tsName}" ("${tableAlias}")` });
8108
+ }
8109
+ let result;
8110
+ where = and(joinOn, where);
8111
+ if (nestedQueryRelation) {
8112
+ let field = sql`json_build_array(${sql.join(
8113
+ selection.map(
8114
+ ({ field: field2, tsKey, isJson }) => isJson ? sql`${sql.identifier(`${tableAlias}_${tsKey}`)}.${sql.identifier("data")}` : is(field2, SQL.Aliased) ? field2.sql : field2
8115
+ ),
8116
+ sql`, `
8117
+ )})`;
8118
+ if (is(nestedQueryRelation, Many)) {
8119
+ field = sql`coalesce(json_agg(${field}${orderBy.length > 0 ? sql` order by ${sql.join(orderBy, sql`, `)}` : void 0}), '[]'::json)`;
8120
+ }
8121
+ const nestedSelection = [{
8122
+ dbKey: "data",
8123
+ tsKey: "data",
8124
+ field: field.as("data"),
8125
+ isJson: true,
8126
+ relationTableTsKey: tableConfig.tsName,
8127
+ selection
8128
+ }];
8129
+ const needsSubquery = limit !== void 0 || offset !== void 0 || orderBy.length > 0;
8130
+ if (needsSubquery) {
8131
+ result = this.buildSelectQuery({
8132
+ table: aliasedTable(table, tableAlias),
8133
+ fields: {},
8134
+ fieldsFlat: [{
8135
+ path: [],
8136
+ field: sql.raw("*")
8137
+ }],
8138
+ where,
8139
+ limit,
8140
+ offset,
8141
+ orderBy,
8142
+ setOperators: []
8143
+ });
8144
+ where = void 0;
8145
+ limit = void 0;
8146
+ offset = void 0;
8147
+ orderBy = [];
8148
+ } else {
8149
+ result = aliasedTable(table, tableAlias);
8150
+ }
8151
+ result = this.buildSelectQuery({
8152
+ table: is(result, PgTable) ? result : new Subquery(result, {}, tableAlias),
8153
+ fields: {},
8154
+ fieldsFlat: nestedSelection.map(({ field: field2 }) => ({
8155
+ path: [],
8156
+ field: is(field2, Column) ? aliasedTableColumn(field2, tableAlias) : field2
8157
+ })),
8158
+ joins,
8159
+ where,
8160
+ limit,
8161
+ offset,
8162
+ orderBy,
8163
+ setOperators: []
8164
+ });
8165
+ } else {
8166
+ result = this.buildSelectQuery({
8167
+ table: aliasedTable(table, tableAlias),
8168
+ fields: {},
8169
+ fieldsFlat: selection.map(({ field }) => ({
8170
+ path: [],
8171
+ field: is(field, Column) ? aliasedTableColumn(field, tableAlias) : field
8172
+ })),
8173
+ joins,
8174
+ where,
8175
+ limit,
8176
+ offset,
8177
+ orderBy,
8178
+ setOperators: []
8179
+ });
8180
+ }
8181
+ return {
8182
+ tableTsKey: tableConfig.tsName,
8183
+ sql: result,
8184
+ selection
8185
+ };
8186
+ }
8187
+ }
8188
+
8189
+ class TypedQueryBuilder {
8190
+ static [entityKind] = "TypedQueryBuilder";
8191
+ /** @internal */
8192
+ getSelectedFields() {
8193
+ return this._.selectedFields;
8194
+ }
8195
+ }
8196
+
8197
+ class PgSelectBuilder {
8198
+ static [entityKind] = "PgSelectBuilder";
8199
+ fields;
8200
+ session;
8201
+ dialect;
8202
+ withList = [];
8203
+ distinct;
8204
+ constructor(config) {
8205
+ this.fields = config.fields;
8206
+ this.session = config.session;
8207
+ this.dialect = config.dialect;
8208
+ if (config.withList) {
8209
+ this.withList = config.withList;
8210
+ }
8211
+ this.distinct = config.distinct;
8212
+ }
8213
+ authToken;
8214
+ /** @internal */
8215
+ setToken(token) {
8216
+ this.authToken = token;
8217
+ return this;
8218
+ }
8219
+ /**
8220
+ * Specify the table, subquery, or other target that you're
8221
+ * building a select query against.
8222
+ *
8223
+ * {@link https://www.postgresql.org/docs/current/sql-select.html#SQL-FROM | Postgres from documentation}
8224
+ */
8225
+ from(source) {
8226
+ const isPartialSelect = !!this.fields;
8227
+ const src = source;
8228
+ let fields;
8229
+ if (this.fields) {
8230
+ fields = this.fields;
8231
+ } else if (is(src, Subquery)) {
8232
+ fields = Object.fromEntries(
8233
+ Object.keys(src._.selectedFields).map((key) => [key, src[key]])
8234
+ );
8235
+ } else if (is(src, PgViewBase)) {
8236
+ fields = src[ViewBaseConfig].selectedFields;
8237
+ } else if (is(src, SQL)) {
8238
+ fields = {};
8239
+ } else {
8240
+ fields = getTableColumns(src);
8241
+ }
8242
+ return new PgSelectBase({
8243
+ table: src,
8244
+ fields,
8245
+ isPartialSelect,
8246
+ session: this.session,
8247
+ dialect: this.dialect,
8248
+ withList: this.withList,
8249
+ distinct: this.distinct
8250
+ }).setToken(this.authToken);
8251
+ }
8252
+ }
8253
+ class PgSelectQueryBuilderBase extends TypedQueryBuilder {
8254
+ static [entityKind] = "PgSelectQueryBuilder";
8255
+ _;
8256
+ config;
8257
+ joinsNotNullableMap;
8258
+ tableName;
8259
+ isPartialSelect;
8260
+ session;
8261
+ dialect;
8262
+ cacheConfig = void 0;
8263
+ usedTables = /* @__PURE__ */ new Set();
8264
+ constructor({ table, fields, isPartialSelect, session, dialect, withList, distinct }) {
8265
+ super();
8266
+ this.config = {
8267
+ withList,
8268
+ table,
8269
+ fields: { ...fields },
8270
+ distinct,
8271
+ setOperators: []
8272
+ };
8273
+ this.isPartialSelect = isPartialSelect;
8274
+ this.session = session;
8275
+ this.dialect = dialect;
8276
+ this._ = {
8277
+ selectedFields: fields,
8278
+ config: this.config
8279
+ };
8280
+ this.tableName = getTableLikeName(table);
8281
+ this.joinsNotNullableMap = typeof this.tableName === "string" ? { [this.tableName]: true } : {};
8282
+ for (const item of extractUsedTable(table)) this.usedTables.add(item);
8283
+ }
8284
+ /** @internal */
8285
+ getUsedTables() {
8286
+ return [...this.usedTables];
8287
+ }
8288
+ createJoin(joinType, lateral) {
8289
+ return (table, on) => {
8290
+ const baseTableName = this.tableName;
8291
+ const tableName = getTableLikeName(table);
8292
+ for (const item of extractUsedTable(table)) this.usedTables.add(item);
8293
+ if (typeof tableName === "string" && this.config.joins?.some((join) => join.alias === tableName)) {
8294
+ throw new Error(`Alias "${tableName}" is already used in this query`);
8295
+ }
8296
+ if (!this.isPartialSelect) {
8297
+ if (Object.keys(this.joinsNotNullableMap).length === 1 && typeof baseTableName === "string") {
8298
+ this.config.fields = {
8299
+ [baseTableName]: this.config.fields
8300
+ };
8301
+ }
8302
+ if (typeof tableName === "string" && !is(table, SQL)) {
8303
+ const selection = is(table, Subquery) ? table._.selectedFields : is(table, View) ? table[ViewBaseConfig].selectedFields : table[Table.Symbol.Columns];
8304
+ this.config.fields[tableName] = selection;
8305
+ }
8306
+ }
8307
+ if (typeof on === "function") {
8308
+ on = on(
8309
+ new Proxy(
8310
+ this.config.fields,
8311
+ new SelectionProxyHandler({ sqlAliasedBehavior: "sql", sqlBehavior: "sql" })
8312
+ )
8313
+ );
8314
+ }
8315
+ if (!this.config.joins) {
8316
+ this.config.joins = [];
8317
+ }
8318
+ this.config.joins.push({ on, table, joinType, alias: tableName, lateral });
8319
+ if (typeof tableName === "string") {
8320
+ switch (joinType) {
8321
+ case "left": {
8322
+ this.joinsNotNullableMap[tableName] = false;
8323
+ break;
8324
+ }
8325
+ case "right": {
8326
+ this.joinsNotNullableMap = Object.fromEntries(
8327
+ Object.entries(this.joinsNotNullableMap).map(([key]) => [key, false])
8328
+ );
8329
+ this.joinsNotNullableMap[tableName] = true;
8330
+ break;
8331
+ }
8332
+ case "cross":
8333
+ case "inner": {
8334
+ this.joinsNotNullableMap[tableName] = true;
8335
+ break;
8336
+ }
8337
+ case "full": {
8338
+ this.joinsNotNullableMap = Object.fromEntries(
8339
+ Object.entries(this.joinsNotNullableMap).map(([key]) => [key, false])
8340
+ );
8341
+ this.joinsNotNullableMap[tableName] = false;
8342
+ break;
8343
+ }
8344
+ }
8345
+ }
8346
+ return this;
8347
+ };
8348
+ }
8349
+ /**
8350
+ * Executes a `left join` operation by adding another table to the current query.
8351
+ *
8352
+ * 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.
8353
+ *
8354
+ * See docs: {@link https://orm.drizzle.team/docs/joins#left-join}
8355
+ *
8356
+ * @param table the table to join.
8357
+ * @param on the `on` clause.
8358
+ *
8359
+ * @example
8360
+ *
8361
+ * ```ts
8362
+ * // Select all users and their pets
8363
+ * const usersWithPets: { user: User; pets: Pet | null; }[] = await db.select()
8364
+ * .from(users)
8365
+ * .leftJoin(pets, eq(users.id, pets.ownerId))
8366
+ *
8367
+ * // Select userId and petId
8368
+ * const usersIdsAndPetIds: { userId: number; petId: number | null; }[] = await db.select({
8369
+ * userId: users.id,
8370
+ * petId: pets.id,
8371
+ * })
8372
+ * .from(users)
8373
+ * .leftJoin(pets, eq(users.id, pets.ownerId))
8374
+ * ```
8375
+ */
8376
+ leftJoin = this.createJoin("left", false);
8377
+ /**
8378
+ * Executes a `left join lateral` operation by adding subquery to the current query.
8379
+ *
8380
+ * A `lateral` join allows the right-hand expression to refer to columns from the left-hand side.
8381
+ *
8382
+ * 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.
8383
+ *
8384
+ * See docs: {@link https://orm.drizzle.team/docs/joins#left-join-lateral}
8385
+ *
8386
+ * @param table the subquery to join.
8387
+ * @param on the `on` clause.
8388
+ */
8389
+ leftJoinLateral = this.createJoin("left", true);
8390
+ /**
8391
+ * Executes a `right join` operation by adding another table to the current query.
8392
+ *
8393
+ * 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.
8394
+ *
8395
+ * See docs: {@link https://orm.drizzle.team/docs/joins#right-join}
8396
+ *
8397
+ * @param table the table to join.
8398
+ * @param on the `on` clause.
8399
+ *
8400
+ * @example
8401
+ *
8402
+ * ```ts
8403
+ * // Select all users and their pets
8404
+ * const usersWithPets: { user: User | null; pets: Pet; }[] = await db.select()
8405
+ * .from(users)
8406
+ * .rightJoin(pets, eq(users.id, pets.ownerId))
8407
+ *
8408
+ * // Select userId and petId
8409
+ * const usersIdsAndPetIds: { userId: number | null; petId: number; }[] = await db.select({
8410
+ * userId: users.id,
8411
+ * petId: pets.id,
8412
+ * })
8413
+ * .from(users)
8414
+ * .rightJoin(pets, eq(users.id, pets.ownerId))
8415
+ * ```
8416
+ */
8417
+ rightJoin = this.createJoin("right", false);
8418
+ /**
8419
+ * Executes an `inner join` operation, creating a new table by combining rows from two tables that have matching values.
8420
+ *
8421
+ * 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.
8422
+ *
8423
+ * See docs: {@link https://orm.drizzle.team/docs/joins#inner-join}
8424
+ *
8425
+ * @param table the table to join.
8426
+ * @param on the `on` clause.
8427
+ *
8428
+ * @example
8429
+ *
8430
+ * ```ts
8431
+ * // Select all users and their pets
8432
+ * const usersWithPets: { user: User; pets: Pet; }[] = await db.select()
8433
+ * .from(users)
8434
+ * .innerJoin(pets, eq(users.id, pets.ownerId))
8435
+ *
8436
+ * // Select userId and petId
8437
+ * const usersIdsAndPetIds: { userId: number; petId: number; }[] = await db.select({
8438
+ * userId: users.id,
8439
+ * petId: pets.id,
8440
+ * })
8441
+ * .from(users)
8442
+ * .innerJoin(pets, eq(users.id, pets.ownerId))
8443
+ * ```
8444
+ */
8445
+ innerJoin = this.createJoin("inner", false);
8446
+ /**
8447
+ * Executes an `inner join lateral` operation, creating a new table by combining rows from two queries that have matching values.
8448
+ *
8449
+ * A `lateral` join allows the right-hand expression to refer to columns from the left-hand side.
8450
+ *
8451
+ * 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.
8452
+ *
8453
+ * See docs: {@link https://orm.drizzle.team/docs/joins#inner-join-lateral}
8454
+ *
8455
+ * @param table the subquery to join.
8456
+ * @param on the `on` clause.
8457
+ */
8458
+ innerJoinLateral = this.createJoin("inner", true);
8459
+ /**
8460
+ * Executes a `full join` operation by combining rows from two tables into a new table.
8461
+ *
8462
+ * 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.
8463
+ *
8464
+ * See docs: {@link https://orm.drizzle.team/docs/joins#full-join}
8465
+ *
8466
+ * @param table the table to join.
8467
+ * @param on the `on` clause.
8468
+ *
8469
+ * @example
8470
+ *
8471
+ * ```ts
8472
+ * // Select all users and their pets
8473
+ * const usersWithPets: { user: User | null; pets: Pet | null; }[] = await db.select()
8474
+ * .from(users)
8475
+ * .fullJoin(pets, eq(users.id, pets.ownerId))
8476
+ *
8477
+ * // Select userId and petId
8478
+ * const usersIdsAndPetIds: { userId: number | null; petId: number | null; }[] = await db.select({
8479
+ * userId: users.id,
8480
+ * petId: pets.id,
8481
+ * })
8482
+ * .from(users)
8483
+ * .fullJoin(pets, eq(users.id, pets.ownerId))
8484
+ * ```
8485
+ */
8486
+ fullJoin = this.createJoin("full", false);
8487
+ /**
8488
+ * Executes a `cross join` operation by combining rows from two tables into a new table.
8489
+ *
8490
+ * Calling this method retrieves all rows from both main and joined tables, merging all rows from each table.
8491
+ *
8492
+ * See docs: {@link https://orm.drizzle.team/docs/joins#cross-join}
8493
+ *
8494
+ * @param table the table to join.
8495
+ *
8496
+ * @example
8497
+ *
8498
+ * ```ts
8499
+ * // Select all users, each user with every pet
8500
+ * const usersWithPets: { user: User; pets: Pet; }[] = await db.select()
8501
+ * .from(users)
8502
+ * .crossJoin(pets)
8503
+ *
8504
+ * // Select userId and petId
8505
+ * const usersIdsAndPetIds: { userId: number; petId: number; }[] = await db.select({
8506
+ * userId: users.id,
8507
+ * petId: pets.id,
8508
+ * })
8509
+ * .from(users)
8510
+ * .crossJoin(pets)
8511
+ * ```
8512
+ */
8513
+ crossJoin = this.createJoin("cross", false);
8514
+ /**
8515
+ * Executes a `cross join lateral` operation by combining rows from two queries into a new table.
8516
+ *
8517
+ * A `lateral` join allows the right-hand expression to refer to columns from the left-hand side.
8518
+ *
8519
+ * Calling this method retrieves all rows from both main and joined queries, merging all rows from each query.
8520
+ *
8521
+ * See docs: {@link https://orm.drizzle.team/docs/joins#cross-join-lateral}
8522
+ *
8523
+ * @param table the query to join.
8524
+ */
8525
+ crossJoinLateral = this.createJoin("cross", true);
8526
+ createSetOperator(type, isAll) {
8527
+ return (rightSelection) => {
8528
+ const rightSelect = typeof rightSelection === "function" ? rightSelection(getPgSetOperators()) : rightSelection;
8529
+ if (!haveSameKeys(this.getSelectedFields(), rightSelect.getSelectedFields())) {
8530
+ throw new Error(
8531
+ "Set operator error (union / intersect / except): selected fields are not the same or are in a different order"
8532
+ );
8533
+ }
8534
+ this.config.setOperators.push({ type, isAll, rightSelect });
8535
+ return this;
8536
+ };
8537
+ }
8538
+ /**
8539
+ * Adds `union` set operator to the query.
8540
+ *
8541
+ * Calling this method will combine the result sets of the `select` statements and remove any duplicate rows that appear across them.
8542
+ *
8543
+ * See docs: {@link https://orm.drizzle.team/docs/set-operations#union}
8544
+ *
8545
+ * @example
8546
+ *
8547
+ * ```ts
8548
+ * // Select all unique names from customers and users tables
8549
+ * await db.select({ name: users.name })
8550
+ * .from(users)
8551
+ * .union(
8552
+ * db.select({ name: customers.name }).from(customers)
8553
+ * );
8554
+ * // or
8555
+ * import { union } from 'drizzle-orm/pg-core'
8556
+ *
8557
+ * await union(
8558
+ * db.select({ name: users.name }).from(users),
8559
+ * db.select({ name: customers.name }).from(customers)
8560
+ * );
8561
+ * ```
8562
+ */
8563
+ union = this.createSetOperator("union", false);
8564
+ /**
8565
+ * Adds `union all` set operator to the query.
8566
+ *
8567
+ * Calling this method will combine the result-set of the `select` statements and keep all duplicate rows that appear across them.
8568
+ *
8569
+ * See docs: {@link https://orm.drizzle.team/docs/set-operations#union-all}
8570
+ *
8571
+ * @example
8572
+ *
8573
+ * ```ts
8574
+ * // Select all transaction ids from both online and in-store sales
8575
+ * await db.select({ transaction: onlineSales.transactionId })
8576
+ * .from(onlineSales)
8577
+ * .unionAll(
8578
+ * db.select({ transaction: inStoreSales.transactionId }).from(inStoreSales)
8579
+ * );
8580
+ * // or
8581
+ * import { unionAll } from 'drizzle-orm/pg-core'
8582
+ *
8583
+ * await unionAll(
8584
+ * db.select({ transaction: onlineSales.transactionId }).from(onlineSales),
8585
+ * db.select({ transaction: inStoreSales.transactionId }).from(inStoreSales)
8586
+ * );
8587
+ * ```
8588
+ */
8589
+ unionAll = this.createSetOperator("union", true);
8590
+ /**
8591
+ * Adds `intersect` set operator to the query.
8592
+ *
8593
+ * Calling this method will retain only the rows that are present in both result sets and eliminate duplicates.
8594
+ *
8595
+ * See docs: {@link https://orm.drizzle.team/docs/set-operations#intersect}
8596
+ *
8597
+ * @example
8598
+ *
8599
+ * ```ts
8600
+ * // Select course names that are offered in both departments A and B
8601
+ * await db.select({ courseName: depA.courseName })
8602
+ * .from(depA)
8603
+ * .intersect(
8604
+ * db.select({ courseName: depB.courseName }).from(depB)
8605
+ * );
8606
+ * // or
8607
+ * import { intersect } from 'drizzle-orm/pg-core'
8608
+ *
8609
+ * await intersect(
8610
+ * db.select({ courseName: depA.courseName }).from(depA),
8611
+ * db.select({ courseName: depB.courseName }).from(depB)
8612
+ * );
8613
+ * ```
8614
+ */
8615
+ intersect = this.createSetOperator("intersect", false);
8616
+ /**
8617
+ * Adds `intersect all` set operator to the query.
8618
+ *
8619
+ * Calling this method will retain only the rows that are present in both result sets including all duplicates.
8620
+ *
8621
+ * See docs: {@link https://orm.drizzle.team/docs/set-operations#intersect-all}
8622
+ *
8623
+ * @example
8624
+ *
8625
+ * ```ts
8626
+ * // Select all products and quantities that are ordered by both regular and VIP customers
8627
+ * await db.select({
8628
+ * productId: regularCustomerOrders.productId,
8629
+ * quantityOrdered: regularCustomerOrders.quantityOrdered
8630
+ * })
8631
+ * .from(regularCustomerOrders)
8632
+ * .intersectAll(
8633
+ * db.select({
8634
+ * productId: vipCustomerOrders.productId,
8635
+ * quantityOrdered: vipCustomerOrders.quantityOrdered
8636
+ * })
8637
+ * .from(vipCustomerOrders)
8638
+ * );
8639
+ * // or
8640
+ * import { intersectAll } from 'drizzle-orm/pg-core'
8641
+ *
8642
+ * await intersectAll(
8643
+ * db.select({
8644
+ * productId: regularCustomerOrders.productId,
8645
+ * quantityOrdered: regularCustomerOrders.quantityOrdered
8646
+ * })
8647
+ * .from(regularCustomerOrders),
8648
+ * db.select({
8649
+ * productId: vipCustomerOrders.productId,
8650
+ * quantityOrdered: vipCustomerOrders.quantityOrdered
8651
+ * })
8652
+ * .from(vipCustomerOrders)
8653
+ * );
8654
+ * ```
8655
+ */
8656
+ intersectAll = this.createSetOperator("intersect", true);
8657
+ /**
8658
+ * Adds `except` set operator to the query.
8659
+ *
8660
+ * 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.
8661
+ *
8662
+ * See docs: {@link https://orm.drizzle.team/docs/set-operations#except}
8663
+ *
8664
+ * @example
8665
+ *
8666
+ * ```ts
8667
+ * // Select all courses offered in department A but not in department B
8668
+ * await db.select({ courseName: depA.courseName })
8669
+ * .from(depA)
8670
+ * .except(
8671
+ * db.select({ courseName: depB.courseName }).from(depB)
8672
+ * );
8673
+ * // or
8674
+ * import { except } from 'drizzle-orm/pg-core'
8675
+ *
8676
+ * await except(
8677
+ * db.select({ courseName: depA.courseName }).from(depA),
8678
+ * db.select({ courseName: depB.courseName }).from(depB)
8679
+ * );
8680
+ * ```
8681
+ */
8682
+ except = this.createSetOperator("except", false);
8683
+ /**
8684
+ * Adds `except all` set operator to the query.
8685
+ *
8686
+ * 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.
8687
+ *
8688
+ * See docs: {@link https://orm.drizzle.team/docs/set-operations#except-all}
8689
+ *
8690
+ * @example
8691
+ *
8692
+ * ```ts
8693
+ * // Select all products that are ordered by regular customers but not by VIP customers
8694
+ * await db.select({
8695
+ * productId: regularCustomerOrders.productId,
8696
+ * quantityOrdered: regularCustomerOrders.quantityOrdered,
8697
+ * })
8698
+ * .from(regularCustomerOrders)
8699
+ * .exceptAll(
8700
+ * db.select({
8701
+ * productId: vipCustomerOrders.productId,
8702
+ * quantityOrdered: vipCustomerOrders.quantityOrdered,
8703
+ * })
8704
+ * .from(vipCustomerOrders)
8705
+ * );
8706
+ * // or
8707
+ * import { exceptAll } from 'drizzle-orm/pg-core'
8708
+ *
8709
+ * await exceptAll(
8710
+ * db.select({
8711
+ * productId: regularCustomerOrders.productId,
8712
+ * quantityOrdered: regularCustomerOrders.quantityOrdered
8713
+ * })
8714
+ * .from(regularCustomerOrders),
8715
+ * db.select({
8716
+ * productId: vipCustomerOrders.productId,
8717
+ * quantityOrdered: vipCustomerOrders.quantityOrdered
8718
+ * })
8719
+ * .from(vipCustomerOrders)
8720
+ * );
8721
+ * ```
8722
+ */
8723
+ exceptAll = this.createSetOperator("except", true);
8724
+ /** @internal */
8725
+ addSetOperators(setOperators) {
8726
+ this.config.setOperators.push(...setOperators);
8727
+ return this;
8728
+ }
8729
+ /**
8730
+ * Adds a `where` clause to the query.
8731
+ *
8732
+ * Calling this method will select only those rows that fulfill a specified condition.
8733
+ *
8734
+ * See docs: {@link https://orm.drizzle.team/docs/select#filtering}
8735
+ *
8736
+ * @param where the `where` clause.
8737
+ *
8738
+ * @example
8739
+ * You can use conditional operators and `sql function` to filter the rows to be selected.
8740
+ *
8741
+ * ```ts
8742
+ * // Select all cars with green color
8743
+ * await db.select().from(cars).where(eq(cars.color, 'green'));
8744
+ * // or
8745
+ * await db.select().from(cars).where(sql`${cars.color} = 'green'`)
8746
+ * ```
8747
+ *
8748
+ * You can logically combine conditional operators with `and()` and `or()` operators:
8749
+ *
8750
+ * ```ts
8751
+ * // Select all BMW cars with a green color
8752
+ * await db.select().from(cars).where(and(eq(cars.color, 'green'), eq(cars.brand, 'BMW')));
8753
+ *
8754
+ * // Select all cars with the green or blue color
8755
+ * await db.select().from(cars).where(or(eq(cars.color, 'green'), eq(cars.color, 'blue')));
8756
+ * ```
8757
+ */
8758
+ where(where) {
8759
+ if (typeof where === "function") {
8760
+ where = where(
8761
+ new Proxy(
8762
+ this.config.fields,
8763
+ new SelectionProxyHandler({ sqlAliasedBehavior: "sql", sqlBehavior: "sql" })
8764
+ )
8765
+ );
8766
+ }
8767
+ this.config.where = where;
8768
+ return this;
8769
+ }
8770
+ /**
8771
+ * Adds a `having` clause to the query.
8772
+ *
8773
+ * 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.
8774
+ *
8775
+ * See docs: {@link https://orm.drizzle.team/docs/select#aggregations}
8776
+ *
8777
+ * @param having the `having` clause.
8778
+ *
8779
+ * @example
8780
+ *
8781
+ * ```ts
8782
+ * // Select all brands with more than one car
8783
+ * await db.select({
8784
+ * brand: cars.brand,
8785
+ * count: sql<number>`cast(count(${cars.id}) as int)`,
8786
+ * })
8787
+ * .from(cars)
8788
+ * .groupBy(cars.brand)
8789
+ * .having(({ count }) => gt(count, 1));
8790
+ * ```
8791
+ */
8792
+ having(having) {
8793
+ if (typeof having === "function") {
8794
+ having = having(
8795
+ new Proxy(
8796
+ this.config.fields,
8797
+ new SelectionProxyHandler({ sqlAliasedBehavior: "sql", sqlBehavior: "sql" })
8798
+ )
8799
+ );
8800
+ }
8801
+ this.config.having = having;
8802
+ return this;
8803
+ }
8804
+ groupBy(...columns) {
8805
+ if (typeof columns[0] === "function") {
8806
+ const groupBy = columns[0](
8807
+ new Proxy(
8808
+ this.config.fields,
8809
+ new SelectionProxyHandler({ sqlAliasedBehavior: "alias", sqlBehavior: "sql" })
8810
+ )
8811
+ );
8812
+ this.config.groupBy = Array.isArray(groupBy) ? groupBy : [groupBy];
8813
+ } else {
8814
+ this.config.groupBy = columns;
8815
+ }
8816
+ return this;
8817
+ }
8818
+ orderBy(...columns) {
8819
+ if (typeof columns[0] === "function") {
8820
+ const orderBy = columns[0](
8821
+ new Proxy(
8822
+ this.config.fields,
8823
+ new SelectionProxyHandler({ sqlAliasedBehavior: "alias", sqlBehavior: "sql" })
8824
+ )
8825
+ );
8826
+ const orderByArray = Array.isArray(orderBy) ? orderBy : [orderBy];
8827
+ if (this.config.setOperators.length > 0) {
8828
+ this.config.setOperators.at(-1).orderBy = orderByArray;
8829
+ } else {
8830
+ this.config.orderBy = orderByArray;
8831
+ }
8832
+ } else {
8833
+ const orderByArray = columns;
8834
+ if (this.config.setOperators.length > 0) {
8835
+ this.config.setOperators.at(-1).orderBy = orderByArray;
8836
+ } else {
8837
+ this.config.orderBy = orderByArray;
8838
+ }
8839
+ }
8840
+ return this;
8841
+ }
8842
+ /**
8843
+ * Adds a `limit` clause to the query.
8844
+ *
8845
+ * Calling this method will set the maximum number of rows that will be returned by this query.
8846
+ *
8847
+ * See docs: {@link https://orm.drizzle.team/docs/select#limit--offset}
8848
+ *
8849
+ * @param limit the `limit` clause.
8850
+ *
8851
+ * @example
8852
+ *
8853
+ * ```ts
8854
+ * // Get the first 10 people from this query.
8855
+ * await db.select().from(people).limit(10);
8856
+ * ```
8857
+ */
8858
+ limit(limit) {
8859
+ if (this.config.setOperators.length > 0) {
8860
+ this.config.setOperators.at(-1).limit = limit;
8861
+ } else {
8862
+ this.config.limit = limit;
8863
+ }
8864
+ return this;
8865
+ }
8866
+ /**
8867
+ * Adds an `offset` clause to the query.
8868
+ *
8869
+ * Calling this method will skip a number of rows when returning results from this query.
8870
+ *
8871
+ * See docs: {@link https://orm.drizzle.team/docs/select#limit--offset}
8872
+ *
8873
+ * @param offset the `offset` clause.
8874
+ *
8875
+ * @example
8876
+ *
8877
+ * ```ts
8878
+ * // Get the 10th-20th people from this query.
8879
+ * await db.select().from(people).offset(10).limit(10);
8880
+ * ```
8881
+ */
8882
+ offset(offset) {
8883
+ if (this.config.setOperators.length > 0) {
8884
+ this.config.setOperators.at(-1).offset = offset;
8885
+ } else {
8886
+ this.config.offset = offset;
8887
+ }
8888
+ return this;
8889
+ }
8890
+ /**
8891
+ * Adds a `for` clause to the query.
8892
+ *
8893
+ * Calling this method will specify a lock strength for this query that controls how strictly it acquires exclusive access to the rows being queried.
8894
+ *
8895
+ * See docs: {@link https://www.postgresql.org/docs/current/sql-select.html#SQL-FOR-UPDATE-SHARE}
8896
+ *
8897
+ * @param strength the lock strength.
8898
+ * @param config the lock configuration.
8899
+ */
8900
+ for(strength, config = {}) {
8901
+ this.config.lockingClause = { strength, config };
8902
+ return this;
8903
+ }
8904
+ /** @internal */
8905
+ getSQL() {
8906
+ return this.dialect.buildSelectQuery(this.config);
8907
+ }
8908
+ toSQL() {
8909
+ const { typings: _typings, ...rest } = this.dialect.sqlToQuery(this.getSQL());
8910
+ return rest;
8911
+ }
8912
+ as(alias) {
8913
+ const usedTables = [];
8914
+ usedTables.push(...extractUsedTable(this.config.table));
8915
+ if (this.config.joins) {
8916
+ for (const it of this.config.joins) usedTables.push(...extractUsedTable(it.table));
8917
+ }
8918
+ return new Proxy(
8919
+ new Subquery(this.getSQL(), this.config.fields, alias, false, [...new Set(usedTables)]),
8920
+ new SelectionProxyHandler({ alias, sqlAliasedBehavior: "alias", sqlBehavior: "error" })
8921
+ );
8922
+ }
8923
+ /** @internal */
8924
+ getSelectedFields() {
8925
+ return new Proxy(
8926
+ this.config.fields,
8927
+ new SelectionProxyHandler({ alias: this.tableName, sqlAliasedBehavior: "alias", sqlBehavior: "error" })
8928
+ );
8929
+ }
8930
+ $dynamic() {
8931
+ return this;
8932
+ }
8933
+ $withCache(config) {
8934
+ this.cacheConfig = config === void 0 ? { config: {}, enable: true, autoInvalidate: true } : config === false ? { enable: false } : { enable: true, autoInvalidate: true, ...config };
8935
+ return this;
8936
+ }
8937
+ }
8938
+ class PgSelectBase extends PgSelectQueryBuilderBase {
8939
+ static [entityKind] = "PgSelect";
8940
+ /** @internal */
8941
+ _prepare(name) {
8942
+ const { session, config, dialect, joinsNotNullableMap, authToken, cacheConfig, usedTables } = this;
8943
+ if (!session) {
8944
+ throw new Error("Cannot execute a query on a query builder. Please use a database instance instead.");
8945
+ }
8946
+ const { fields } = config;
8947
+ return tracer.startActiveSpan("drizzle.prepareQuery", () => {
8948
+ const fieldsList = orderSelectedFields(fields);
8949
+ const query = session.prepareQuery(dialect.sqlToQuery(this.getSQL()), fieldsList, name, true, void 0, {
8950
+ type: "select",
8951
+ tables: [...usedTables]
8952
+ }, cacheConfig);
8953
+ query.joinsNotNullableMap = joinsNotNullableMap;
8954
+ return query.setToken(authToken);
8955
+ });
8956
+ }
8957
+ /**
8958
+ * Create a prepared statement for this query. This allows
8959
+ * the database to remember this query for the given session
8960
+ * and call it by name, rather than specifying the full query.
8961
+ *
8962
+ * {@link https://www.postgresql.org/docs/current/sql-prepare.html | Postgres prepare documentation}
8963
+ */
8964
+ prepare(name) {
8965
+ return this._prepare(name);
8966
+ }
8967
+ authToken;
8968
+ /** @internal */
8969
+ setToken(token) {
8970
+ this.authToken = token;
8971
+ return this;
8972
+ }
8973
+ execute = (placeholderValues) => {
8974
+ return tracer.startActiveSpan("drizzle.operation", () => {
8975
+ return this._prepare().execute(placeholderValues, this.authToken);
8976
+ });
8977
+ };
8978
+ }
8979
+ applyMixins(PgSelectBase, [QueryPromise]);
8980
+ function createSetOperator(type, isAll) {
8981
+ return (leftSelect, rightSelect, ...restSelects) => {
8982
+ const setOperators = [rightSelect, ...restSelects].map((select) => ({
8983
+ type,
8984
+ isAll,
8985
+ rightSelect: select
8986
+ }));
8987
+ for (const setOperator of setOperators) {
8988
+ if (!haveSameKeys(leftSelect.getSelectedFields(), setOperator.rightSelect.getSelectedFields())) {
8989
+ throw new Error(
8990
+ "Set operator error (union / intersect / except): selected fields are not the same or are in a different order"
8991
+ );
8992
+ }
8993
+ }
8994
+ return leftSelect.addSetOperators(setOperators);
8995
+ };
8996
+ }
8997
+ const getPgSetOperators = () => ({
8998
+ union,
8999
+ unionAll,
9000
+ intersect,
9001
+ intersectAll,
9002
+ except,
9003
+ exceptAll
9004
+ });
9005
+ const union = createSetOperator("union", false);
9006
+ const unionAll = createSetOperator("union", true);
9007
+ const intersect = createSetOperator("intersect", false);
9008
+ const intersectAll = createSetOperator("intersect", true);
9009
+ const except = createSetOperator("except", false);
9010
+ const exceptAll = createSetOperator("except", true);
9011
+
9012
+ class QueryBuilder {
9013
+ static [entityKind] = "PgQueryBuilder";
9014
+ dialect;
9015
+ dialectConfig;
9016
+ constructor(dialect) {
9017
+ this.dialect = is(dialect, PgDialect) ? dialect : void 0;
9018
+ this.dialectConfig = is(dialect, PgDialect) ? void 0 : dialect;
9019
+ }
9020
+ $with = (alias, selection) => {
9021
+ const queryBuilder = this;
9022
+ const as = (qb) => {
9023
+ if (typeof qb === "function") {
9024
+ qb = qb(queryBuilder);
9025
+ }
9026
+ return new Proxy(
9027
+ new WithSubquery(
9028
+ qb.getSQL(),
9029
+ selection ?? ("getSelectedFields" in qb ? qb.getSelectedFields() ?? {} : {}),
9030
+ alias,
9031
+ true
9032
+ ),
9033
+ new SelectionProxyHandler({ alias, sqlAliasedBehavior: "alias", sqlBehavior: "error" })
9034
+ );
9035
+ };
9036
+ return { as };
9037
+ };
9038
+ with(...queries) {
9039
+ const self = this;
9040
+ function select(fields) {
9041
+ return new PgSelectBuilder({
9042
+ fields: fields ?? void 0,
9043
+ session: void 0,
9044
+ dialect: self.getDialect(),
9045
+ withList: queries
9046
+ });
9047
+ }
9048
+ function selectDistinct(fields) {
9049
+ return new PgSelectBuilder({
9050
+ fields: fields ?? void 0,
9051
+ session: void 0,
9052
+ dialect: self.getDialect(),
9053
+ distinct: true
9054
+ });
9055
+ }
9056
+ function selectDistinctOn(on, fields) {
9057
+ return new PgSelectBuilder({
9058
+ fields: fields ?? void 0,
9059
+ session: void 0,
9060
+ dialect: self.getDialect(),
9061
+ distinct: { on }
9062
+ });
9063
+ }
9064
+ return { select, selectDistinct, selectDistinctOn };
9065
+ }
9066
+ select(fields) {
9067
+ return new PgSelectBuilder({
9068
+ fields: fields ?? void 0,
9069
+ session: void 0,
9070
+ dialect: this.getDialect()
9071
+ });
9072
+ }
9073
+ selectDistinct(fields) {
9074
+ return new PgSelectBuilder({
9075
+ fields: fields ?? void 0,
9076
+ session: void 0,
9077
+ dialect: this.getDialect(),
9078
+ distinct: true
9079
+ });
9080
+ }
9081
+ selectDistinctOn(on, fields) {
9082
+ return new PgSelectBuilder({
9083
+ fields: fields ?? void 0,
9084
+ session: void 0,
9085
+ dialect: this.getDialect(),
9086
+ distinct: { on }
9087
+ });
9088
+ }
9089
+ // Lazy load dialect to avoid circular dependency
9090
+ getDialect() {
9091
+ if (!this.dialect) {
9092
+ this.dialect = new PgDialect(this.dialectConfig);
9093
+ }
9094
+ return this.dialect;
9095
+ }
9096
+ }
9097
+
9098
+ class DefaultViewBuilderCore {
9099
+ constructor(name, schema) {
9100
+ this.name = name;
9101
+ this.schema = schema;
9102
+ }
9103
+ static [entityKind] = "PgDefaultViewBuilderCore";
9104
+ config = {};
9105
+ with(config) {
9106
+ this.config.with = config;
9107
+ return this;
9108
+ }
9109
+ }
9110
+ class ViewBuilder extends DefaultViewBuilderCore {
9111
+ static [entityKind] = "PgViewBuilder";
9112
+ as(qb) {
9113
+ if (typeof qb === "function") {
9114
+ qb = qb(new QueryBuilder());
9115
+ }
9116
+ const selectionProxy = new SelectionProxyHandler({
9117
+ alias: this.name,
9118
+ sqlBehavior: "error",
9119
+ sqlAliasedBehavior: "alias",
9120
+ replaceOriginalName: true
9121
+ });
9122
+ const aliasedSelection = new Proxy(qb.getSelectedFields(), selectionProxy);
9123
+ return new Proxy(
9124
+ new PgView({
9125
+ pgConfig: this.config,
9126
+ config: {
9127
+ name: this.name,
9128
+ schema: this.schema,
9129
+ selectedFields: aliasedSelection,
9130
+ query: qb.getSQL().inlineParams()
9131
+ }
9132
+ }),
9133
+ selectionProxy
9134
+ );
9135
+ }
9136
+ }
9137
+ class ManualViewBuilder extends DefaultViewBuilderCore {
9138
+ static [entityKind] = "PgManualViewBuilder";
9139
+ columns;
9140
+ constructor(name, columns, schema) {
9141
+ super(name, schema);
9142
+ this.columns = getTableColumns(pgTable(name, columns));
9143
+ }
9144
+ existing() {
9145
+ return new Proxy(
9146
+ new PgView({
9147
+ pgConfig: void 0,
9148
+ config: {
9149
+ name: this.name,
9150
+ schema: this.schema,
9151
+ selectedFields: this.columns,
9152
+ query: void 0
9153
+ }
9154
+ }),
9155
+ new SelectionProxyHandler({
9156
+ alias: this.name,
9157
+ sqlBehavior: "error",
9158
+ sqlAliasedBehavior: "alias",
9159
+ replaceOriginalName: true
9160
+ })
9161
+ );
9162
+ }
9163
+ as(query) {
9164
+ return new Proxy(
9165
+ new PgView({
9166
+ pgConfig: this.config,
9167
+ config: {
9168
+ name: this.name,
9169
+ schema: this.schema,
9170
+ selectedFields: this.columns,
9171
+ query: query.inlineParams()
9172
+ }
9173
+ }),
9174
+ new SelectionProxyHandler({
9175
+ alias: this.name,
9176
+ sqlBehavior: "error",
9177
+ sqlAliasedBehavior: "alias",
9178
+ replaceOriginalName: true
9179
+ })
9180
+ );
9181
+ }
9182
+ }
9183
+ class MaterializedViewBuilderCore {
9184
+ constructor(name, schema) {
9185
+ this.name = name;
9186
+ this.schema = schema;
9187
+ }
9188
+ static [entityKind] = "PgMaterializedViewBuilderCore";
9189
+ config = {};
9190
+ using(using) {
9191
+ this.config.using = using;
9192
+ return this;
9193
+ }
9194
+ with(config) {
9195
+ this.config.with = config;
9196
+ return this;
9197
+ }
9198
+ tablespace(tablespace) {
9199
+ this.config.tablespace = tablespace;
9200
+ return this;
9201
+ }
9202
+ withNoData() {
9203
+ this.config.withNoData = true;
9204
+ return this;
9205
+ }
9206
+ }
9207
+ class MaterializedViewBuilder extends MaterializedViewBuilderCore {
9208
+ static [entityKind] = "PgMaterializedViewBuilder";
9209
+ as(qb) {
9210
+ if (typeof qb === "function") {
9211
+ qb = qb(new QueryBuilder());
9212
+ }
9213
+ const selectionProxy = new SelectionProxyHandler({
9214
+ alias: this.name,
9215
+ sqlBehavior: "error",
9216
+ sqlAliasedBehavior: "alias",
9217
+ replaceOriginalName: true
9218
+ });
9219
+ const aliasedSelection = new Proxy(qb.getSelectedFields(), selectionProxy);
9220
+ return new Proxy(
9221
+ new PgMaterializedView({
9222
+ pgConfig: {
9223
+ with: this.config.with,
9224
+ using: this.config.using,
9225
+ tablespace: this.config.tablespace,
9226
+ withNoData: this.config.withNoData
9227
+ },
9228
+ config: {
9229
+ name: this.name,
9230
+ schema: this.schema,
9231
+ selectedFields: aliasedSelection,
9232
+ query: qb.getSQL().inlineParams()
9233
+ }
9234
+ }),
9235
+ selectionProxy
9236
+ );
9237
+ }
9238
+ }
9239
+ class ManualMaterializedViewBuilder extends MaterializedViewBuilderCore {
9240
+ static [entityKind] = "PgManualMaterializedViewBuilder";
9241
+ columns;
9242
+ constructor(name, columns, schema) {
9243
+ super(name, schema);
9244
+ this.columns = getTableColumns(pgTable(name, columns));
9245
+ }
9246
+ existing() {
9247
+ return new Proxy(
9248
+ new PgMaterializedView({
9249
+ pgConfig: {
9250
+ tablespace: this.config.tablespace,
9251
+ using: this.config.using,
9252
+ with: this.config.with,
9253
+ withNoData: this.config.withNoData
9254
+ },
9255
+ config: {
9256
+ name: this.name,
9257
+ schema: this.schema,
9258
+ selectedFields: this.columns,
9259
+ query: void 0
9260
+ }
9261
+ }),
9262
+ new SelectionProxyHandler({
9263
+ alias: this.name,
9264
+ sqlBehavior: "error",
9265
+ sqlAliasedBehavior: "alias",
9266
+ replaceOriginalName: true
9267
+ })
9268
+ );
9269
+ }
9270
+ as(query) {
9271
+ return new Proxy(
9272
+ new PgMaterializedView({
9273
+ pgConfig: {
9274
+ tablespace: this.config.tablespace,
9275
+ using: this.config.using,
9276
+ with: this.config.with,
9277
+ withNoData: this.config.withNoData
9278
+ },
9279
+ config: {
9280
+ name: this.name,
9281
+ schema: this.schema,
9282
+ selectedFields: this.columns,
9283
+ query: query.inlineParams()
9284
+ }
9285
+ }),
9286
+ new SelectionProxyHandler({
9287
+ alias: this.name,
9288
+ sqlBehavior: "error",
9289
+ sqlAliasedBehavior: "alias",
9290
+ replaceOriginalName: true
9291
+ })
9292
+ );
9293
+ }
9294
+ }
9295
+ class PgView extends PgViewBase {
9296
+ static [entityKind] = "PgView";
9297
+ [PgViewConfig];
9298
+ constructor({ pgConfig, config }) {
9299
+ super(config);
9300
+ if (pgConfig) {
9301
+ this[PgViewConfig] = {
9302
+ with: pgConfig.with
9303
+ };
9304
+ }
9305
+ }
9306
+ }
9307
+ const PgMaterializedViewConfig = Symbol.for("drizzle:PgMaterializedViewConfig");
9308
+ class PgMaterializedView extends PgViewBase {
9309
+ static [entityKind] = "PgMaterializedView";
9310
+ [PgMaterializedViewConfig];
9311
+ constructor({ pgConfig, config }) {
9312
+ super(config);
9313
+ this[PgMaterializedViewConfig] = {
9314
+ with: pgConfig?.with,
9315
+ using: pgConfig?.using,
9316
+ tablespace: pgConfig?.tablespace,
9317
+ withNoData: pgConfig?.withNoData
9318
+ };
9319
+ }
9320
+ }
9321
+ function pgViewWithSchema(name, selection, schema) {
9322
+ if (selection) {
9323
+ return new ManualViewBuilder(name, selection, schema);
9324
+ }
9325
+ return new ViewBuilder(name, schema);
9326
+ }
9327
+ function pgMaterializedViewWithSchema(name, selection, schema) {
9328
+ if (selection) {
9329
+ return new ManualMaterializedViewBuilder(name, selection, schema);
9330
+ }
9331
+ return new MaterializedViewBuilder(name, schema);
9332
+ }
9333
+ function pgView(name, columns) {
9334
+ return pgViewWithSchema(name, columns, void 0);
9335
+ }
9336
+ function pgMaterializedView(name, columns) {
9337
+ return pgMaterializedViewWithSchema(name, columns, void 0);
9338
+ }
9339
+
9340
+ function extractUsedTable(table) {
9341
+ if (is(table, PgTable)) {
9342
+ return [table[Schema] ? `${table[Schema]}.${table[Table.Symbol.BaseName]}` : table[Table.Symbol.BaseName]];
9343
+ }
9344
+ if (is(table, Subquery)) {
9345
+ return table._.usedTables ?? [];
9346
+ }
9347
+ if (is(table, SQL)) {
9348
+ return table.usedTables ?? [];
9349
+ }
9350
+ return [];
9351
+ }
9352
+
9353
+ class PgSequence {
9354
+ constructor(seqName, seqOptions, schema) {
9355
+ this.seqName = seqName;
9356
+ this.seqOptions = seqOptions;
9357
+ this.schema = schema;
9358
+ }
9359
+ static [entityKind] = "PgSequence";
9360
+ }
9361
+ function pgSequenceWithSchema(name, options, schema) {
9362
+ return new PgSequence(name, options, schema);
9363
+ }
9364
+
9365
+ class PgSchema {
9366
+ constructor(schemaName) {
9367
+ this.schemaName = schemaName;
9368
+ }
9369
+ static [entityKind] = "PgSchema";
9370
+ table = (name, columns, extraConfig) => {
9371
+ return pgTableWithSchema(name, columns, extraConfig, this.schemaName);
9372
+ };
9373
+ view = (name, columns) => {
9374
+ return pgViewWithSchema(name, columns, this.schemaName);
9375
+ };
9376
+ materializedView = (name, columns) => {
9377
+ return pgMaterializedViewWithSchema(name, columns, this.schemaName);
9378
+ };
9379
+ enum(enumName, input) {
9380
+ return Array.isArray(input) ? pgEnumWithSchema(
9381
+ enumName,
9382
+ [...input],
9383
+ this.schemaName
9384
+ ) : pgEnumObjectWithSchema(enumName, input, this.schemaName);
9385
+ }
9386
+ sequence = (name, options) => {
9387
+ return pgSequenceWithSchema(name, options, this.schemaName);
9388
+ };
9389
+ getSQL() {
9390
+ return new SQL([sql.identifier(this.schemaName)]);
9391
+ }
9392
+ shouldOmitSQLParens() {
9393
+ return true;
9394
+ }
9395
+ }
9396
+ function pgSchema(name) {
9397
+ if (name === "public") {
9398
+ throw new Error(
9399
+ `You can't specify 'public' as schema name. Postgres is using public schema by default. If you want to use 'public' schema, just use pgTable() instead of creating a schema`
9400
+ );
9401
+ }
9402
+ return new PgSchema(name);
9403
+ }
9404
+
9405
+ export { ClickHouseConnector, CoreSqlTypes, DBConnector, DBError, DBNoSQLType, DBOLAPType, DBSQLType, DrizzlePostgresConnector, DrizzleSQLType, DrizzleSqlConnector, MySQLConnectionError, NoSQLConnector, OLAPConnector, SqlConnector, bigint, bigserial, boolean, char, check, cidr, date, decimal, doublePrecision, foreignKey, geometry, index, inet, integer, interval, json, jsonb, line, macaddr, macaddr8, numeric, pgEnum, pgMaterializedView, pgSchema, pgTable, pgView, point, primaryKey, real, serial, smallint, smallserial, text, time, timestamp, unique, uniqueIndex, uuid, varchar };