uql-orm 0.66.0 → 0.67.0

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.
Files changed (193) hide show
  1. package/dist/browser/querier/httpQuerier.js +1 -8
  2. package/dist/browser/uql-browser.min.js.map +5 -5
  3. package/dist/bunSql/bunSql.util.d.ts +2 -6
  4. package/dist/bunSql/bunSql.util.js +2 -6
  5. package/dist/bunSql/bunSqlQuerier.d.ts +2 -5
  6. package/dist/bunSql/bunSqlQuerier.js +2 -5
  7. package/dist/cockroachdb/cockroachDialect.d.ts +4 -13
  8. package/dist/cockroachdb/cockroachDialect.js +4 -13
  9. package/dist/context/context.browser.js +2 -10
  10. package/dist/context/context.d.ts +4 -17
  11. package/dist/context/context.js +4 -17
  12. package/dist/dialect/abstractDialect.d.ts +4 -19
  13. package/dist/dialect/abstractDialect.js +2 -20
  14. package/dist/dialect/abstractSqlDialect.d.ts +47 -212
  15. package/dist/dialect/abstractSqlDialect.js +68 -222
  16. package/dist/dialect/aliases.d.ts +2 -12
  17. package/dist/dialect/aliases.js +4 -12
  18. package/dist/dialect/hydrateColumn.d.ts +2 -6
  19. package/dist/dialect/hydrateColumn.js +3 -13
  20. package/dist/dialect/jsonArrayElemMatchUtils.d.ts +1 -7
  21. package/dist/dialect/jsonArrayElemMatchUtils.js +1 -7
  22. package/dist/dialect/jsonSql.d.ts +6 -27
  23. package/dist/dialect/jsonSql.js +6 -27
  24. package/dist/dialect/mergeSqlDialect.d.ts +4 -22
  25. package/dist/dialect/mergeSqlDialect.js +4 -22
  26. package/dist/dialect/mysqlLikeSqlDialect.d.ts +11 -37
  27. package/dist/dialect/mysqlLikeSqlDialect.js +35 -51
  28. package/dist/dialect/pgLikeSqlDialect.d.ts +8 -22
  29. package/dist/dialect/pgLikeSqlDialect.js +36 -39
  30. package/dist/dialect/queryContext.d.ts +4 -22
  31. package/dist/dialect/queryContext.js +4 -22
  32. package/dist/dialect/queryJoins.d.ts +3 -12
  33. package/dist/dialect/queryJoins.js +3 -12
  34. package/dist/dialect/vectorCast.d.ts +2 -12
  35. package/dist/dialect/vectorCast.js +3 -19
  36. package/dist/dialect/vectorSqlDialect.d.ts +8 -38
  37. package/dist/dialect/vectorSqlDialect.js +7 -38
  38. package/dist/entity/decorator/bag.d.ts +6 -19
  39. package/dist/entity/decorator/bag.js +6 -22
  40. package/dist/entity/decorator/entity.d.ts +2 -7
  41. package/dist/entity/decorator/entity.js +2 -7
  42. package/dist/entity/decorator/members.d.ts +7 -30
  43. package/dist/entity/decorator/members.js +3 -12
  44. package/dist/entity/metadata/definition.d.ts +2 -18
  45. package/dist/entity/metadata/definition.js +6 -28
  46. package/dist/http/handler.d.ts +2 -14
  47. package/dist/index.d.ts +3 -1
  48. package/dist/index.js +3 -1
  49. package/dist/libsql/libsqlDialect.d.ts +1 -8
  50. package/dist/libsql/libsqlDialect.js +1 -8
  51. package/dist/maria/mariaDialect.d.ts +3 -5
  52. package/dist/maria/mariaDialect.js +5 -5
  53. package/dist/maria/mariadbQuerier.js +2 -2
  54. package/dist/maria/mariadbQuerierPool.js +1 -6
  55. package/dist/migrate/builder/migrationBuilder.js +3 -19
  56. package/dist/migrate/builder/splitSqlStatements.d.ts +1 -14
  57. package/dist/migrate/builder/splitSqlStatements.js +2 -22
  58. package/dist/migrate/builder/types.d.ts +2 -15
  59. package/dist/migrate/cli-config.js +2 -11
  60. package/dist/migrate/cli.js +2 -7
  61. package/dist/migrate/codegen/entityCodeGenerator.d.ts +0 -15
  62. package/dist/migrate/codegen/entityCodeGenerator.js +15 -44
  63. package/dist/migrate/codegen/fieldOptionsSource.d.ts +1 -8
  64. package/dist/migrate/codegen/fieldOptionsSource.js +3 -22
  65. package/dist/migrate/ddl/indexDdl.d.ts +2 -5
  66. package/dist/migrate/ddl/indexDdl.js +2 -5
  67. package/dist/migrate/ddl/pgIndexDdl.d.ts +3 -13
  68. package/dist/migrate/ddl/pgIndexDdl.js +3 -13
  69. package/dist/migrate/generator/definitionToNode.d.ts +2 -9
  70. package/dist/migrate/generator/definitionToNode.js +3 -17
  71. package/dist/migrate/generator/indexNodeToSchema.d.ts +2 -3
  72. package/dist/migrate/generator/indexNodeToSchema.js +2 -3
  73. package/dist/migrate/generator/mongoCommand.d.ts +1 -8
  74. package/dist/migrate/generator/mongoSchemaGenerator.d.ts +1 -8
  75. package/dist/migrate/generator/mongoSchemaGenerator.js +1 -8
  76. package/dist/migrate/introspection/abstractSqlSchemaIntrospector.d.ts +6 -26
  77. package/dist/migrate/introspection/abstractSqlSchemaIntrospector.js +9 -41
  78. package/dist/migrate/introspection/baseSqlIntrospector.js +0 -1
  79. package/dist/migrate/introspection/mongoIntrospector.d.ts +3 -1
  80. package/dist/migrate/introspection/mongoIntrospector.js +48 -46
  81. package/dist/migrate/introspection/mssqlIntrospector.d.ts +4 -4
  82. package/dist/migrate/introspection/mssqlIntrospector.js +18 -27
  83. package/dist/migrate/introspection/mysqlIntrospector.d.ts +7 -2
  84. package/dist/migrate/introspection/mysqlIntrospector.js +16 -14
  85. package/dist/migrate/introspection/postgresIntrospector.d.ts +24 -9
  86. package/dist/migrate/introspection/postgresIntrospector.js +68 -59
  87. package/dist/migrate/introspection/sqliteIntrospector.d.ts +1 -1
  88. package/dist/migrate/introspection/sqliteIntrospector.js +8 -10
  89. package/dist/migrate/migrator.d.ts +9 -53
  90. package/dist/migrate/migrator.js +32 -65
  91. package/dist/migrate/schemaGenerator.d.ts +16 -66
  92. package/dist/migrate/schemaGenerator.js +21 -74
  93. package/dist/mongo/mongoDialect.d.ts +21 -53
  94. package/dist/mongo/mongoDialect.js +25 -70
  95. package/dist/mongo/mongodbQuerier.d.ts +5 -8
  96. package/dist/mongo/mongodbQuerier.js +31 -65
  97. package/dist/mssql/mssqlDialect.d.ts +8 -34
  98. package/dist/mssql/mssqlDialect.js +37 -51
  99. package/dist/mssql/mssqlQuerier.d.ts +37 -4
  100. package/dist/mssql/mssqlQuerier.js +2 -2
  101. package/dist/mssql/mssqlWireTypes.d.ts +2 -14
  102. package/dist/mssql/mssqlWireTypes.js +2 -14
  103. package/dist/nestjs/uqlModule.js +2 -7
  104. package/dist/pglite/pgliteQuerier.d.ts +1 -9
  105. package/dist/pglite/pgliteQuerierPool.d.ts +4 -26
  106. package/dist/pglite/pgliteQuerierPool.js +3 -18
  107. package/dist/postgres/abstractPgQuerierPool.d.ts +1 -8
  108. package/dist/postgres/abstractPgQuerierPool.js +1 -8
  109. package/dist/postgres/pgNumericTypes.d.ts +3 -26
  110. package/dist/postgres/pgNumericTypes.js +3 -26
  111. package/dist/postgres/postgresDialect.d.ts +4 -10
  112. package/dist/postgres/postgresDialect.js +4 -10
  113. package/dist/querier/abstractQuerier.d.ts +35 -103
  114. package/dist/querier/abstractQuerier.js +105 -201
  115. package/dist/querier/abstractSharedHandleQuerierPool.d.ts +3 -17
  116. package/dist/querier/abstractSharedHandleQuerierPool.js +3 -17
  117. package/dist/querier/abstractSqlQuerier.d.ts +15 -36
  118. package/dist/querier/abstractSqlQuerier.js +49 -131
  119. package/dist/schema/canonicalType.d.ts +3 -21
  120. package/dist/schema/canonicalType.js +22 -67
  121. package/dist/schema/dependencyGraph.d.ts +2 -8
  122. package/dist/schema/dependencyGraph.js +2 -32
  123. package/dist/schema/index.d.ts +1 -25
  124. package/dist/schema/index.js +0 -26
  125. package/dist/schema/indexColumns.d.ts +1 -8
  126. package/dist/schema/indexColumns.js +1 -8
  127. package/dist/schema/indexDifferences.d.ts +7 -40
  128. package/dist/schema/indexDifferences.js +6 -31
  129. package/dist/schema/schemaAST.d.ts +8 -175
  130. package/dist/schema/schemaAST.js +13 -365
  131. package/dist/schema/schemaASTBuilder.d.ts +2 -24
  132. package/dist/schema/schemaASTBuilder.js +2 -30
  133. package/dist/schema/schemaASTDiffer.d.ts +6 -46
  134. package/dist/schema/schemaASTDiffer.js +8 -56
  135. package/dist/schema/types.d.ts +5 -61
  136. package/dist/schema/types.js +3 -6
  137. package/dist/sqlite/abstractSqliteQuerier.d.ts +1 -8
  138. package/dist/sqlite/localSqliteQuerierPool.d.ts +1 -7
  139. package/dist/sqlite/localSqliteQuerierPool.js +1 -7
  140. package/dist/sqlite/nodeSqliteQuerierPool.d.ts +2 -7
  141. package/dist/sqlite/nodeSqliteQuerierPool.js +2 -7
  142. package/dist/sqlite/sqliteDialect.d.ts +5 -20
  143. package/dist/sqlite/sqliteDialect.js +29 -35
  144. package/dist/turso/tursoDialect.d.ts +4 -6
  145. package/dist/turso/tursoDialect.js +4 -6
  146. package/dist/turso/tursoLocalQuerierPool.d.ts +1 -7
  147. package/dist/turso/tursoLocalQuerierPool.js +1 -7
  148. package/dist/turso/tursoQuerierPool.d.ts +2 -6
  149. package/dist/turso/tursoQuerierPool.js +2 -6
  150. package/dist/turso/tursoSessionQuerier.d.ts +1 -7
  151. package/dist/turso/tursoSessionQuerier.js +1 -7
  152. package/dist/type/dialect.d.ts +42 -94
  153. package/dist/type/dialect.js +3 -13
  154. package/dist/type/entity.d.ts +163 -534
  155. package/dist/type/entity.js +26 -9
  156. package/dist/type/logger.d.ts +2 -14
  157. package/dist/type/migration.d.ts +9 -38
  158. package/dist/type/querier.d.ts +9 -28
  159. package/dist/type/querierPool.d.ts +4 -26
  160. package/dist/type/query.d.ts +19 -73
  161. package/dist/type/query.js +2 -7
  162. package/dist/type/queryAggregate.d.ts +18 -98
  163. package/dist/type/queryRaw.d.ts +1 -8
  164. package/dist/type/queryRaw.js +1 -8
  165. package/dist/type/queryWhere.d.ts +13 -61
  166. package/dist/type/universalQuerier.d.ts +18 -105
  167. package/dist/type/utility.d.ts +12 -24
  168. package/dist/type/vector.d.ts +8 -38
  169. package/dist/type/vector.js +1 -1
  170. package/dist/type/wire.d.ts +2 -5
  171. package/dist/util/dialect.util.d.ts +9 -27
  172. package/dist/util/dialect.util.js +10 -27
  173. package/dist/util/field.util.d.ts +2 -31
  174. package/dist/util/field.util.js +3 -43
  175. package/dist/util/fieldOption.util.d.ts +7 -15
  176. package/dist/util/fieldOption.util.js +1 -1
  177. package/dist/util/filters.util.d.ts +2 -5
  178. package/dist/util/filters.util.js +2 -5
  179. package/dist/util/logger.d.ts +2 -6
  180. package/dist/util/logger.js +2 -6
  181. package/dist/util/object.util.d.ts +2 -6
  182. package/dist/util/object.util.js +1 -5
  183. package/dist/util/raw.d.ts +3 -23
  184. package/dist/util/relationQuery.util.d.ts +3 -14
  185. package/dist/util/relationQuery.util.js +3 -14
  186. package/dist/util/rowKey.util.d.ts +2 -10
  187. package/dist/util/rowKey.util.js +2 -10
  188. package/dist/util/sql.util.d.ts +6 -37
  189. package/dist/util/sql.util.js +13 -73
  190. package/dist/util/sqlLiteral.d.ts +2 -13
  191. package/dist/util/sqlLiteral.js +8 -13
  192. package/dist/util/string.util.js +0 -2
  193. package/package.json +4 -4
@@ -36,36 +36,15 @@ export declare function jsonElemExists(from: string, conditions: readonly string
36
36
  */
37
37
  export type JsonAccessMode = 'json' | 'numeric' | 'text';
38
38
  /**
39
- * How a JSON scalar has to be compared against `value` (or, for `$in`/`$nin`, against every element
40
- * of it). Extracting a JSON value yields *text*, which loses the type, so each operand type is
41
- * compared in the representation every engine agrees on:
42
- * - `numeric` - cast the accessor. Keeps `1` equal to a stored `1.0`, which strict JSON equality
43
- * would not, and satisfies drivers that send typed parameters (`text = integer` otherwise).
44
- * - `json` - compare the JSON value against a JSON-encoded parameter. No cast recovers a boolean
45
- * portably: PostgreSQL raises `text = boolean` and MySQL matches `'true'` against `1`.
46
- * - `text` - compare as extracted, which is also what the string operators need.
47
- *
48
- * Mixed operand types fall back to `text`, since one comparison cannot be two shapes at once.
39
+ * How a JSON scalar compares against `value`, since extraction yields text: `numeric` casts (so `1` equals
40
+ * `1.0`), `json` compares JSON values (the only portable boolean), and `text` compares as extracted,
41
+ * also for mixed operands.
49
42
  */
50
43
  export declare function jsonCompareMode(value: unknown): JsonAccessMode;
51
- /**
52
- * The mode a *declared* type asks for: {@link jsonCompareMode}'s twin, reading the type instead of an
53
- * operand. An index over a JSON path is only reachable by a comparison that extracts it the same way,
54
- * so the two have to answer alike - which is why they are one pair over one vocabulary.
55
- *
56
- * Reads the type through `util/field.util`'s own classifier, which the dialects already carry:
57
- * resolving it through `schema/canonicalType` instead pulls that whole module into every consumer
58
- * bundle.
59
- */
44
+ /** The mode a declared type asks for, {@link jsonCompareMode}'s twin: an index over a path is reached only by a comparison extracting it alike. */
60
45
  export declare function jsonTypeMode(type: FieldType): JsonAccessMode;
61
46
  /**
62
- * Whether the operator reads the JSON *value* instead of its text form. The array operators always
63
- * do. Equality joins them for boolean operands, because extracting JSON as text loses the type in
64
- * a way no cast recovers portably: PostgreSQL raises `operator does not exist: text = boolean`,
65
- * MySQL compares `'true'` to `1` and silently matches nothing, and SQLite's `JSON_EXTRACT` yields
66
- * `1`. Comparing the JSON value against a JSON-encoded parameter is exact on every dialect.
67
- *
68
- * Numbers stay on the text accessor with a numeric cast, which keeps `1` equal to `1.0` - JSON
69
- * equality would not.
47
+ * Whether the operator reads the JSON value rather than its text: the array operators, and equality
48
+ * against a boolean, which no cast recovers portably from text.
70
49
  */
71
50
  export declare function isJsonbOp(op: string, value?: unknown): boolean;
@@ -53,16 +53,9 @@ export function jsonElemExists(from, conditions) {
53
53
  return `EXISTS (SELECT 1 FROM ${from}${where})`;
54
54
  }
55
55
  /**
56
- * How a JSON scalar has to be compared against `value` (or, for `$in`/`$nin`, against every element
57
- * of it). Extracting a JSON value yields *text*, which loses the type, so each operand type is
58
- * compared in the representation every engine agrees on:
59
- * - `numeric` - cast the accessor. Keeps `1` equal to a stored `1.0`, which strict JSON equality
60
- * would not, and satisfies drivers that send typed parameters (`text = integer` otherwise).
61
- * - `json` - compare the JSON value against a JSON-encoded parameter. No cast recovers a boolean
62
- * portably: PostgreSQL raises `text = boolean` and MySQL matches `'true'` against `1`.
63
- * - `text` - compare as extracted, which is also what the string operators need.
64
- *
65
- * Mixed operand types fall back to `text`, since one comparison cannot be two shapes at once.
56
+ * How a JSON scalar compares against `value`, since extraction yields text: `numeric` casts (so `1` equals
57
+ * `1.0`), `json` compares JSON values (the only portable boolean), and `text` compares as extracted,
58
+ * also for mixed operands.
66
59
  */
67
60
  export function jsonCompareMode(value) {
68
61
  const operands = Array.isArray(value) ? value : [value];
@@ -74,15 +67,7 @@ export function jsonCompareMode(value) {
74
67
  }
75
68
  return operands.every((operand) => typeof operand === 'number') ? 'numeric' : 'text';
76
69
  }
77
- /**
78
- * The mode a *declared* type asks for: {@link jsonCompareMode}'s twin, reading the type instead of an
79
- * operand. An index over a JSON path is only reachable by a comparison that extracts it the same way,
80
- * so the two have to answer alike - which is why they are one pair over one vocabulary.
81
- *
82
- * Reads the type through `util/field.util`'s own classifier, which the dialects already carry:
83
- * resolving it through `schema/canonicalType` instead pulls that whole module into every consumer
84
- * bundle.
85
- */
70
+ /** The mode a declared type asks for, {@link jsonCompareMode}'s twin: an index over a path is reached only by a comparison extracting it alike. */
86
71
  export function jsonTypeMode(type) {
87
72
  const family = columnFamily(type);
88
73
  if (family === 'numeric') {
@@ -91,14 +76,8 @@ export function jsonTypeMode(type) {
91
76
  return family === 'boolean' ? 'json' : 'text';
92
77
  }
93
78
  /**
94
- * Whether the operator reads the JSON *value* instead of its text form. The array operators always
95
- * do. Equality joins them for boolean operands, because extracting JSON as text loses the type in
96
- * a way no cast recovers portably: PostgreSQL raises `operator does not exist: text = boolean`,
97
- * MySQL compares `'true'` to `1` and silently matches nothing, and SQLite's `JSON_EXTRACT` yields
98
- * `1`. Comparing the JSON value against a JSON-encoded parameter is exact on every dialect.
99
- *
100
- * Numbers stay on the text accessor with a numeric cast, which keeps `1` equal to `1.0` - JSON
101
- * equality would not.
79
+ * Whether the operator reads the JSON value rather than its text: the array operators, and equality
80
+ * against a boolean, which no cast recovers portably from text.
102
81
  */
103
82
  export function isJsonbOp(op, value) {
104
83
  if (op === '$all' || op === '$size' || op === '$elemMatch') {
@@ -1,33 +1,15 @@
1
1
  import type { QueryConflictPaths, QueryContext, QueryPager, Type } from '../type/index.js';
2
2
  import { AbstractSqlDialect } from './abstractSqlDialect.js';
3
- /**
4
- * Shared SQL between SQL Server and Oracle: the two engines that spell paging and upsert the way the
5
- * standard does, where the Postgres and MySQL families each predate it.
6
- *
7
- * A family base rather than a pair of knobs, the way {@link PgLikeSqlDialect} and
8
- * {@link MysqlLikeSqlDialect} already are - `pager` and `upsert` are both plain overrides, so nothing
9
- * in the core has to learn that a second spelling exists.
10
- */
3
+ /** What SQL Server and Oracle share: paging and upsert spelled as the standard does. */
11
4
  export declare abstract class MergeSqlDialect extends AbstractSqlDialect {
12
5
  readonly escapeIdChar = "\"";
13
- /**
14
- * `OFFSET ... ROWS FETCH NEXT ... ROWS ONLY`, and an `ORDER BY` where the statement has none.
15
- *
16
- * SQL Server refuses to page an unordered statement. A constant `ORDER BY` costs one clause the
17
- * optimizer discards and keeps `$limit` and `$skip` meaning the same thing here as everywhere
18
- * else; the alternative, `TOP (n)` in the select list, needs a second hook and still leaves a
19
- * `$skip` with no `$sort` unanswerable.
20
- */
6
+ /** `OFFSET ... FETCH NEXT`, and a constant `ORDER BY` where there is none, since SQL Server refuses to page without one. */
21
7
  pager(ctx: QueryContext, opts: QueryPager & {
22
8
  $distinct?: boolean;
23
9
  }, sorted?: boolean): void;
24
10
  /**
25
- * `MERGE`, which both engines take in place of the `ON CONFLICT`/`ON DUPLICATE KEY` the other
26
- * families have. The rows go in as a `VALUES` row source rather than an `INSERT`, built by
27
- * {@link AbstractSqlDialect.insertShape} so both shapes apply `onInsert` defaults identically.
28
- *
29
- * Every value binds before the assignments are rendered, so a `?`-placeholder engine needs none of
30
- * the scratch-context reordering `ON CONFLICT` does - the source is read positionally, in order.
11
+ * `MERGE`, its rows a `VALUES` source built by {@link AbstractSqlDialect.insertShape}. Every value binds
12
+ * before the assignments, so `?` placeholders read in order.
31
13
  */
32
14
  upsert<E>(ctx: QueryContext, entity: Type<E>, conflictPaths: QueryConflictPaths<E>, payload: E | E[], extraReturning?: string): void;
33
15
  /** `<target>.<col> = <source>.<col>` for every conflict key, which is what makes a row "the same". */
@@ -2,24 +2,10 @@ import { getMeta } from '../entity/index.js';
2
2
  import { assertNonNegativeInteger, getKeys } from '../util/index.js';
3
3
  import { AbstractSqlDialect } from './abstractSqlDialect.js';
4
4
  import { UPSERT_SOURCE_ALIAS } from './aliases.js';
5
- /**
6
- * Shared SQL between SQL Server and Oracle: the two engines that spell paging and upsert the way the
7
- * standard does, where the Postgres and MySQL families each predate it.
8
- *
9
- * A family base rather than a pair of knobs, the way {@link PgLikeSqlDialect} and
10
- * {@link MysqlLikeSqlDialect} already are - `pager` and `upsert` are both plain overrides, so nothing
11
- * in the core has to learn that a second spelling exists.
12
- */
5
+ /** What SQL Server and Oracle share: paging and upsert spelled as the standard does. */
13
6
  export class MergeSqlDialect extends AbstractSqlDialect {
14
7
  escapeIdChar = '"';
15
- /**
16
- * `OFFSET ... ROWS FETCH NEXT ... ROWS ONLY`, and an `ORDER BY` where the statement has none.
17
- *
18
- * SQL Server refuses to page an unordered statement. A constant `ORDER BY` costs one clause the
19
- * optimizer discards and keeps `$limit` and `$skip` meaning the same thing here as everywhere
20
- * else; the alternative, `TOP (n)` in the select list, needs a second hook and still leaves a
21
- * `$skip` with no `$sort` unanswerable.
22
- */
8
+ /** `OFFSET ... FETCH NEXT`, and a constant `ORDER BY` where there is none, since SQL Server refuses to page without one. */
23
9
  pager(ctx, opts, sorted = false) {
24
10
  if (opts.$limit === undefined && opts.$skip === undefined) {
25
11
  return;
@@ -35,12 +21,8 @@ export class MergeSqlDialect extends AbstractSqlDialect {
35
21
  }
36
22
  }
37
23
  /**
38
- * `MERGE`, which both engines take in place of the `ON CONFLICT`/`ON DUPLICATE KEY` the other
39
- * families have. The rows go in as a `VALUES` row source rather than an `INSERT`, built by
40
- * {@link AbstractSqlDialect.insertShape} so both shapes apply `onInsert` defaults identically.
41
- *
42
- * Every value binds before the assignments are rendered, so a `?`-placeholder engine needs none of
43
- * the scratch-context reordering `ON CONFLICT` does - the source is read positionally, in order.
24
+ * `MERGE`, its rows a `VALUES` source built by {@link AbstractSqlDialect.insertShape}. Every value binds
25
+ * before the assignments, so `?` placeholders read in order.
44
26
  */
45
27
  upsert(ctx, entity, conflictPaths, payload, extraReturning = '') {
46
28
  const meta = getMeta(entity);
@@ -1,18 +1,10 @@
1
- import type { DialectFeatures, EntityMeta, FieldOptions, InsertIdSource, Query, QueryConflictPaths, QueryContext, QueryOptions, QueryPager, QuerySizeComparisonOps, QueryTextSearchOptions, Type } from '../type/index.js';
1
+ import type { EntityMeta, FieldOptions, InsertIdSource, Query, QueryConflictPaths, QueryContext, QueryOptions, QueryPager, QuerySizeComparisonOps, QueryTextSearchOptions, SqlDialectFeatures, Type } from '../type/index.js';
2
2
  import { AbstractSqlDialect, type DerivedRelation, type RelationRows } from './abstractSqlDialect.js';
3
- /**
4
- * Shared JSON-array / JSON-object operator implementation between MySQL and MariaDB.
5
- *
6
- * Both dialects support the MySQL-compatible JSON functions/operators used by:
7
- * - `$size` (JSON_LENGTH)
8
- * - `$all` (JSON_CONTAINS)
9
- * - `$elemMatch` (JSON_TABLE, or fast JSON_CONTAINS for the simple case)
10
- * - the update operators `$set` (JSON_SET), `$unset` (JSON_REMOVE), `$push` (JSON_MERGE_PRESERVE)
11
- * and `$pull` (JSON_REPLACE over JSON_TABLE)
12
- */
3
+ /** What the MySQL-family engines have. */
4
+ export declare const MYSQL_FEATURES: SqlDialectFeatures;
5
+ /** What MySQL and MariaDB share, their JSON functions above all: `JSON_LENGTH`, `JSON_CONTAINS`, `JSON_TABLE`, `JSON_SET`. */
13
6
  export declare abstract class MysqlLikeSqlDialect extends AbstractSqlDialect {
14
- /** Default {@link DialectFeatures} for MySQL-compatible SQL dialects. */
15
- protected readonly featureDefaults: DialectFeatures;
7
+ readonly features: SqlDialectFeatures;
16
8
  /**
17
9
  * `information_schema` keeps InnoDB's own row estimate, which is live enough to answer before
18
10
  * anything has been analyzed. `DATABASE()` where the entity names no schema, so the estimate comes
@@ -21,13 +13,7 @@ export declare abstract class MysqlLikeSqlDialect extends AbstractSqlDialect {
21
13
  estimatedCount<E>(ctx: QueryContext, entity: Type<E>): void;
22
14
  /** `OFFSET` is only legal after a `LIMIT` here, so a bare `$skip` needs one. */
23
15
  pager(ctx: QueryContext, opts: QueryPager): void;
24
- /**
25
- * Signed, though MySQL's own convention is `UNSIGNED`: a foreign key column takes its type from the
26
- * key it points at, resolved through the *canonical* type, which has no way to know this string said
27
- * `UNSIGNED`. The two then disagree and the engine refuses the constraint - the same trap knex hit
28
- * (knex#6129) and MikroORM still carries (mikro-orm#5485). Signed is also the portable half: no
29
- * other engine here has unsigned integers, so an `@Id` means one range everywhere.
30
- */
16
+ /** A signed key, so a foreign key taking its type from it matches, as MySQL refuses an `UNSIGNED` mismatch. */
31
17
  readonly autoIncrementSuffix = "AUTO_INCREMENT";
32
18
  readonly escapeIdChar = "`";
33
19
  readonly tableOptions = "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4";
@@ -42,19 +28,11 @@ export declare abstract class MysqlLikeSqlDialect extends AbstractSqlDialect {
42
28
  readonly booleanLiteral = "integer";
43
29
  readonly insertIdSource: InsertIdSource;
44
30
  /**
45
- * `INSERT ... ON DUPLICATE KEY UPDATE`, and `INSERT IGNORE` when every non-conflict column is itself a
46
- * conflict key so there is nothing to assign. Neither form takes a conflict target: MySQL picks the
47
- * unique index for you.
48
- *
49
- * The update assignments are built into their own context and pushed afterwards, since they read
50
- * the inserted row rather than binding, and any value they *do* bind (an `onUpdate` field absent from
51
- * the payload) has to land after the insert's for a `?`-placeholder driver.
31
+ * `INSERT ... ON DUPLICATE KEY UPDATE`, or `INSERT IGNORE` where there is nothing to assign. The
32
+ * assignments bind after the insert, where a `?` reads them.
52
33
  */
53
34
  upsert<E>(ctx: QueryContext, entity: Type<E>, conflictPaths: QueryConflictPaths<E>, payload: E | E[]): void;
54
- /**
55
- * Appended to both branches above. Empty on MySQL, which has no `INSERT ... RETURNING`; MariaDB
56
- * 10.5+ has it, and used to restate this whole method just to add it.
57
- */
35
+ /** Appended to both branches above: empty on MySQL, which has no `INSERT ... RETURNING`. */
58
36
  protected upsertReturning<E>(_meta: EntityMeta<E>): string;
59
37
  /**
60
38
  * The alias the inserted row is given after the values list, and read back by the assignments.
@@ -132,12 +110,8 @@ export declare abstract class MysqlLikeSqlDialect extends AbstractSqlDialect {
132
110
  protected jsonAll(ctx: QueryContext, jsonField: string, value: unknown): string;
133
111
  protected jsonSize(ctx: QueryContext, jsonField: string, value: number | QuerySizeComparisonOps): string;
134
112
  /**
135
- * `JSON_TABLE` needs its columns declared upfront, so the object form maps `fields` to columns.
136
- * The scalar form's column is `JSON`, not `TEXT`, when `asJson` - `TEXT PATH '$'` silently reads
137
- * a compound (array/object) element as `NULL`, since MySQL doesn't coerce those to text; only a
138
- * true scalar element survives that coercion. A nested `$elemMatch` (each element being an array
139
- * that itself gets exploded) always requests `asJson`, so this is what makes that case reach the
140
- * inner elements at all rather than finding nothing.
113
+ * `JSON_TABLE` with its columns declared up front. A scalar element reads as `JSON` where `asJson`,
114
+ * since `TEXT` reads a nested array as `NULL`.
141
115
  */
142
116
  protected jsonElemFrom(jsonField: string, fields: readonly string[], alias: string, asJson?: boolean): string;
143
117
  protected jsonElemRef(alias: string, field?: string, asJson?: boolean): string;
@@ -11,34 +11,36 @@ import { aggregatesRelations } from './queryJoins.js';
11
11
  * and the largest `group_concat_max_len` either engine takes.
12
12
  */
13
13
  const MAX_LIMIT = BigInt.asUintN(64, -1n);
14
- /**
15
- * Shared JSON-array / JSON-object operator implementation between MySQL and MariaDB.
16
- *
17
- * Both dialects support the MySQL-compatible JSON functions/operators used by:
18
- * - `$size` (JSON_LENGTH)
19
- * - `$all` (JSON_CONTAINS)
20
- * - `$elemMatch` (JSON_TABLE, or fast JSON_CONTAINS for the simple case)
21
- * - the update operators `$set` (JSON_SET), `$unset` (JSON_REMOVE), `$push` (JSON_MERGE_PRESERVE)
22
- * and `$pull` (JSON_REPLACE over JSON_TABLE)
23
- */
14
+ /** What the MySQL-family engines have. */
15
+ export const MYSQL_FEATURES = {
16
+ ifNotExists: true,
17
+ indexIfNotExists: false,
18
+ schemas: true,
19
+ dropTableCascade: false,
20
+ foreignKeyAlter: true,
21
+ primaryKeyAlter: true,
22
+ generatedColumnAdd: true,
23
+ commentSyntax: 'inline',
24
+ vectorIndexRequiresNotNull: false,
25
+ vectorSupportsLength: false,
26
+ supportsTimestamptz: false,
27
+ stringSizing: 'varchar',
28
+ supportsUnsigned: true,
29
+ serverSideCursors: false,
30
+ rowLocks: true,
31
+ rowLockWithWindow: true,
32
+ rowLockOf: true,
33
+ orderedUpsertReturning: true,
34
+ orderedJsonAggregates: true,
35
+ partialJsonContainment: true,
36
+ typedJsonElements: false,
37
+ narrowVectorTypes: false,
38
+ vectorTuningNeedsTransaction: false,
39
+ serialDeclaresPrimaryKey: false,
40
+ };
41
+ /** What MySQL and MariaDB share, their JSON functions above all: `JSON_LENGTH`, `JSON_CONTAINS`, `JSON_TABLE`, `JSON_SET`. */
24
42
  export class MysqlLikeSqlDialect extends AbstractSqlDialect {
25
- /** Default {@link DialectFeatures} for MySQL-compatible SQL dialects. */
26
- featureDefaults = {
27
- ifNotExists: true,
28
- indexIfNotExists: false,
29
- schemas: true,
30
- dropTableCascade: false,
31
- foreignKeyAlter: true,
32
- primaryKeyAlter: true,
33
- generatedColumnAdd: true,
34
- commentSyntax: 'inline',
35
- vectorIndexRequiresNotNull: false,
36
- vectorSupportsLength: false,
37
- supportsTimestamptz: false,
38
- stringSizing: 'varchar',
39
- supportsUnsigned: true,
40
- serverSideCursors: false,
41
- };
43
+ features = MYSQL_FEATURES;
42
44
  /**
43
45
  * `information_schema` keeps InnoDB's own row estimate, which is live enough to answer before
44
46
  * anything has been analyzed. `DATABASE()` where the entity names no schema, so the estimate comes
@@ -64,13 +66,7 @@ export class MysqlLikeSqlDialect extends AbstractSqlDialect {
64
66
  }
65
67
  super.pager(ctx, opts);
66
68
  }
67
- /**
68
- * Signed, though MySQL's own convention is `UNSIGNED`: a foreign key column takes its type from the
69
- * key it points at, resolved through the *canonical* type, which has no way to know this string said
70
- * `UNSIGNED`. The two then disagree and the engine refuses the constraint - the same trap knex hit
71
- * (knex#6129) and MikroORM still carries (mikro-orm#5485). Signed is also the portable half: no
72
- * other engine here has unsigned integers, so an `@Id` means one range everywhere.
73
- */
69
+ /** A signed key, so a foreign key taking its type from it matches, as MySQL refuses an `UNSIGNED` mismatch. */
74
70
  autoIncrementSuffix = 'AUTO_INCREMENT';
75
71
  escapeIdChar = '`';
76
72
  tableOptions = 'ENGINE=InnoDB DEFAULT CHARSET=utf8mb4';
@@ -87,13 +83,8 @@ export class MysqlLikeSqlDialect extends AbstractSqlDialect {
87
83
  // `innodb_autoinc_lock_mode` caveat on `buildUpdateResult` in `util/sql.util.ts`.
88
84
  insertIdSource = 'firstId';
89
85
  /**
90
- * `INSERT ... ON DUPLICATE KEY UPDATE`, and `INSERT IGNORE` when every non-conflict column is itself a
91
- * conflict key so there is nothing to assign. Neither form takes a conflict target: MySQL picks the
92
- * unique index for you.
93
- *
94
- * The update assignments are built into their own context and pushed afterwards, since they read
95
- * the inserted row rather than binding, and any value they *do* bind (an `onUpdate` field absent from
96
- * the payload) has to land after the insert's for a `?`-placeholder driver.
86
+ * `INSERT ... ON DUPLICATE KEY UPDATE`, or `INSERT IGNORE` where there is nothing to assign. The
87
+ * assignments bind after the insert, where a `?` reads them.
97
88
  */
98
89
  upsert(ctx, entity, conflictPaths, payload) {
99
90
  const meta = getMeta(entity);
@@ -113,10 +104,7 @@ export class MysqlLikeSqlDialect extends AbstractSqlDialect {
113
104
  ctx.append(returning);
114
105
  ctx.pushValue(...insertCtx.values);
115
106
  }
116
- /**
117
- * Appended to both branches above. Empty on MySQL, which has no `INSERT ... RETURNING`; MariaDB
118
- * 10.5+ has it, and used to restate this whole method just to add it.
119
- */
107
+ /** Appended to both branches above: empty on MySQL, which has no `INSERT ... RETURNING`. */
120
108
  upsertReturning(_meta) {
121
109
  return '';
122
110
  }
@@ -250,12 +238,8 @@ export class MysqlLikeSqlDialect extends AbstractSqlDialect {
250
238
  return this.buildFragment(ctx, (fragmentCtx) => this.buildSizeComparison(fragmentCtx, () => fragmentCtx.append(`JSON_LENGTH(${jsonField})`), value));
251
239
  }
252
240
  /**
253
- * `JSON_TABLE` needs its columns declared upfront, so the object form maps `fields` to columns.
254
- * The scalar form's column is `JSON`, not `TEXT`, when `asJson` - `TEXT PATH '$'` silently reads
255
- * a compound (array/object) element as `NULL`, since MySQL doesn't coerce those to text; only a
256
- * true scalar element survives that coercion. A nested `$elemMatch` (each element being an array
257
- * that itself gets exploded) always requests `asJson`, so this is what makes that case reach the
258
- * inner elements at all rather than finding nothing.
241
+ * `JSON_TABLE` with its columns declared up front. A scalar element reads as `JSON` where `asJson`,
242
+ * since `TEXT` reads a nested array as `NULL`.
259
243
  */
260
244
  jsonElemFrom(jsonField, fields, alias, asJson = false) {
261
245
  const columns = fields.length
@@ -1,27 +1,18 @@
1
- import { type DialectFeatures, type DriverCapabilities, type EntityMeta, type FieldOptions, type JsonColumnType, type Query, type QueryContext, type QuerySizeComparisonOps, type QueryTextSearchOptions, type Type } from '../type/index.js';
1
+ import { type DriverCapabilities, type EntityMeta, type FieldOptions, type JsonColumnType, type Query, type QueryContext, type QuerySizeComparisonOps, type QueryTextSearchOptions, type SqlDialectFeatures, type Type } from '../type/index.js';
2
2
  import type { DialectOptions } from './abstractDialect.js';
3
3
  import { AbstractSqlDialect, type RelationRows } from './abstractSqlDialect.js';
4
4
  /** A Postgres-wire dialect's options: the base's, and how its driver binds a parameter. */
5
5
  export type PgLikeDialectOptions = DialectOptions & {
6
6
  readonly driverCapabilities?: Partial<DriverCapabilities>;
7
7
  };
8
- /**
9
- * Shared AST/quoting/JSONB/full-text-search/vector-search implementation between Postgres and
10
- * CockroachDB (wire- and SQL-compatible for everything below, including `TO_TSVECTOR`/`TO_TSQUERY`
11
- * and pgvector's `<=>`/`<->`/`<#>` distance operators, which CockroachDB implements natively).
12
- * `xmax`-based upsert `created` detection is Postgres-only (CockroachDB has no `xmax`/`ctid`) and
13
- * stays in {@link PostgresDialect}, along with the `vectorExtension`/`vectorIndexStyle` values that
14
- * differ (Postgres needs `CREATE EXTENSION vector` and pgvector's `USING ivfflat/hnsw` index
15
- * syntax; CockroachDB's vector type and `CREATE VECTOR INDEX` syntax are both native).
16
- */
8
+ /** What the Postgres-wire engines have. */
9
+ export declare const PG_FEATURES: SqlDialectFeatures;
10
+ /** What Postgres and CockroachDB share: JSONB, full-text search, pgvector's operators, and the upsert. */
17
11
  export declare abstract class PgLikeSqlDialect extends AbstractSqlDialect {
18
12
  /** How the driver binds a parameter: node-`pg`'s, unless the pool states its own. */
19
13
  readonly driverCapabilities: DriverCapabilities;
20
14
  constructor(options?: PgLikeDialectOptions);
21
- /** `FOR UPDATE` and a window function cannot share a statement here. See the base declaration. */
22
- readonly supportsWindowWithRowLock = false;
23
- /** Default {@link DialectFeatures} for Postgres-wire dialects. */
24
- protected readonly featureDefaults: DialectFeatures;
15
+ readonly features: SqlDialectFeatures;
25
16
  readonly escapeIdChar = "\"";
26
17
  readonly autoIncrementSuffix: string;
27
18
  readonly tableOptions = "";
@@ -53,8 +44,6 @@ export declare abstract class PgLikeSqlDialect extends AbstractSqlDialect {
53
44
  readonly op: string;
54
45
  readonly opsSuffix: string;
55
46
  }>;
56
- /** `SET LOCAL` applies to the enclosing transaction and to nothing at all without one. */
57
- readonly vectorTuningNeedsTransaction = true;
58
47
  /**
59
48
  * The GUC each pgvector index type reads for "how much of the index to explore". They are not the
60
49
  * same quantity - `ef_search` is a candidate-list size, `probes` a count of lists - which is why
@@ -62,11 +51,8 @@ export declare abstract class PgLikeSqlDialect extends AbstractSqlDialect {
62
51
  */
63
52
  private static readonly ANN_SETTINGS;
64
53
  /**
65
- * `SET LOCAL hnsw.ef_search = N`, plus `hnsw.iterative_scan` when the query also filters by
66
- * distance. Without iterative scan, HNSW returns its candidate list and the predicate then removes
67
- * from it, so a `$near` can hand back fewer rows than qualify - the recall bug `$candidates`
68
- * exists to answer. `strict_order`, never `relaxed_order`: the latter returns rows out of distance
69
- * order, which would quietly contradict the `ORDER BY` the caller asked for.
54
+ * `SET LOCAL hnsw.ef_search = N`, plus `hnsw.iterative_scan = strict_order` where the query also filters
55
+ * by distance, which would otherwise drop rows the candidate list missed.
70
56
  */
71
57
  vectorTuningStatements<E>(meta: EntityMeta<E>, q: Query<E>): readonly string[];
72
58
  normalizeValue(value: unknown): unknown;
@@ -89,7 +75,7 @@ export declare abstract class PgLikeSqlDialect extends AbstractSqlDialect {
89
75
  protected readonly caseInsensitiveMatch = "ilike";
90
76
  protected get neOp(): string;
91
77
  /** One array parameter, which a context that inlines values has none of: it lists them instead. */
92
- protected formatIn(ctx: QueryContext, values: unknown[], negate: boolean): string;
78
+ protected formatIn(ctx: QueryContext, operand: string, values: unknown[], negate: boolean): string;
93
79
  protected numericCast(expr: string): string;
94
80
  protected appendJsonValue(ctx: QueryContext, value: unknown, type: JsonColumnType): void;
95
81
  /**
@@ -7,15 +7,34 @@ import { BYTES_PREFIX } from './hydrateColumn.js';
7
7
  import { jsonSetTarget } from './jsonSql.js';
8
8
  import { PG_VECTOR_METRICS } from './pgVectorMetrics.js';
9
9
  import { resolveVectorCast, toSparsevecLiteral } from './vectorCast.js';
10
- /**
11
- * Shared AST/quoting/JSONB/full-text-search/vector-search implementation between Postgres and
12
- * CockroachDB (wire- and SQL-compatible for everything below, including `TO_TSVECTOR`/`TO_TSQUERY`
13
- * and pgvector's `<=>`/`<->`/`<#>` distance operators, which CockroachDB implements natively).
14
- * `xmax`-based upsert `created` detection is Postgres-only (CockroachDB has no `xmax`/`ctid`) and
15
- * stays in {@link PostgresDialect}, along with the `vectorExtension`/`vectorIndexStyle` values that
16
- * differ (Postgres needs `CREATE EXTENSION vector` and pgvector's `USING ivfflat/hnsw` index
17
- * syntax; CockroachDB's vector type and `CREATE VECTOR INDEX` syntax are both native).
18
- */
10
+ /** What the Postgres-wire engines have. */
11
+ export const PG_FEATURES = {
12
+ ifNotExists: true,
13
+ indexIfNotExists: true,
14
+ schemas: true,
15
+ dropTableCascade: true,
16
+ foreignKeyAlter: true,
17
+ primaryKeyAlter: true,
18
+ generatedColumnAdd: true,
19
+ commentSyntax: 'statement',
20
+ vectorIndexRequiresNotNull: false,
21
+ vectorSupportsLength: true,
22
+ supportsTimestamptz: true,
23
+ stringSizing: 'bounded-text',
24
+ supportsUnsigned: false,
25
+ serverSideCursors: true,
26
+ rowLocks: true,
27
+ rowLockWithWindow: false,
28
+ rowLockOf: true,
29
+ orderedUpsertReturning: true,
30
+ orderedJsonAggregates: true,
31
+ partialJsonContainment: true,
32
+ typedJsonElements: false,
33
+ narrowVectorTypes: false,
34
+ vectorTuningNeedsTransaction: true,
35
+ serialDeclaresPrimaryKey: false,
36
+ };
37
+ /** What Postgres and CockroachDB share: JSONB, full-text search, pgvector's operators, and the upsert. */
19
38
  export class PgLikeSqlDialect extends AbstractSqlDialect {
20
39
  /** How the driver binds a parameter: node-`pg`'s, unless the pool states its own. */
21
40
  driverCapabilities;
@@ -23,25 +42,7 @@ export class PgLikeSqlDialect extends AbstractSqlDialect {
23
42
  super(options);
24
43
  this.driverCapabilities = { nativeArrays: true, explicitJsonCast: false, ...options.driverCapabilities };
25
44
  }
26
- /** `FOR UPDATE` and a window function cannot share a statement here. See the base declaration. */
27
- supportsWindowWithRowLock = false;
28
- /** Default {@link DialectFeatures} for Postgres-wire dialects. */
29
- featureDefaults = {
30
- ifNotExists: true,
31
- indexIfNotExists: true,
32
- schemas: true,
33
- dropTableCascade: true,
34
- foreignKeyAlter: true,
35
- primaryKeyAlter: true,
36
- generatedColumnAdd: true,
37
- commentSyntax: 'statement',
38
- vectorIndexRequiresNotNull: false,
39
- vectorSupportsLength: true,
40
- supportsTimestamptz: true,
41
- stringSizing: 'bounded-text',
42
- supportsUnsigned: false,
43
- serverSideCursors: true,
44
- };
45
+ features = PG_FEATURES;
45
46
  escapeIdChar = '"';
46
47
  // Shared default for both dialects. CockroachDB docs flag sequential PKs as a hotspotting risk
47
48
  // under heavy concurrent insert load (writes concentrate on one range); this default still beats
@@ -80,8 +81,6 @@ export class PgLikeSqlDialect extends AbstractSqlDialect {
80
81
  insertIdSource = 'returning';
81
82
  maxBindValues = 65535;
82
83
  vectorMetrics = PG_VECTOR_METRICS;
83
- /** `SET LOCAL` applies to the enclosing transaction and to nothing at all without one. */
84
- vectorTuningNeedsTransaction = true;
85
84
  /**
86
85
  * The GUC each pgvector index type reads for "how much of the index to explore". They are not the
87
86
  * same quantity - `ef_search` is a candidate-list size, `probes` a count of lists - which is why
@@ -92,11 +91,8 @@ export class PgLikeSqlDialect extends AbstractSqlDialect {
92
91
  ['ivfflat', 'ivfflat.probes'],
93
92
  ]);
94
93
  /**
95
- * `SET LOCAL hnsw.ef_search = N`, plus `hnsw.iterative_scan` when the query also filters by
96
- * distance. Without iterative scan, HNSW returns its candidate list and the predicate then removes
97
- * from it, so a `$near` can hand back fewer rows than qualify - the recall bug `$candidates`
98
- * exists to answer. `strict_order`, never `relaxed_order`: the latter returns rows out of distance
99
- * order, which would quietly contradict the `ORDER BY` the caller asked for.
94
+ * `SET LOCAL hnsw.ef_search = N`, plus `hnsw.iterative_scan = strict_order` where the query also filters
95
+ * by distance, which would otherwise drop rows the candidate list missed.
100
96
  */
101
97
  vectorTuningStatements(meta, q) {
102
98
  const indexType = this.tunedVectorIndex(meta, q)?.type;
@@ -162,11 +158,12 @@ export class PgLikeSqlDialect extends AbstractSqlDialect {
162
158
  return 'IS DISTINCT FROM';
163
159
  }
164
160
  /** One array parameter, which a context that inlines values has none of: it lists them instead. */
165
- formatIn(ctx, values, negate) {
166
- if (values.length === 0 || ctx.inlineValues)
167
- return super.formatIn(ctx, values, negate);
161
+ formatIn(ctx, operand, values, negate) {
162
+ if (!values.length || ctx.inlineValues) {
163
+ return super.formatIn(ctx, operand, values, negate);
164
+ }
168
165
  const ph = this.addValue(ctx, values);
169
- return negate ? ` <> ALL(${ph})` : ` = ANY(${ph})`;
166
+ return negate ? `${operand} <> ALL(${ph})` : `${operand} = ANY(${ph})`;
170
167
  }
171
168
  numericCast(expr) {
172
169
  return `(${expr})::numeric`;
@@ -1,11 +1,5 @@
1
1
  import type { QueryContext, SqlQueryDialect } from '../type/index.js';
2
- /**
3
- * SqlQueryContext is an implementation of the QueryContext interface specifically for SQL-based dialects.
4
- * It follows the "Accumulator" or "Builder" pattern to construct SQL queries and their corresponding parameters.
5
- *
6
- * This pattern solves the problem of building complex SQL strings while safely managing parameterized values,
7
- * preventing SQL injection and handling dialect-specific parameter placeholders (e.g., '?' for MySQL, '$n' for PostgreSQL).
8
- */
2
+ /** A SQL statement being built: its text, and the values it binds, placeholders numbered by the dialect. */
9
3
  export declare class SqlQueryContext implements QueryContext {
10
4
  readonly dialect: SqlQueryDialect;
11
5
  private readonly statement?;
@@ -14,14 +8,8 @@ export declare class SqlQueryContext implements QueryContext {
14
8
  private readonly params;
15
9
  private readonly tableAliases;
16
10
  /**
17
- * @param dialect The SQL dialect used to determine how values should be formatted as placeholders.
18
- * @param params An existing values array to bind into instead of a fresh one - shared by a
19
- * fragment context built via {@link AbstractSqlDialect.buildFragment}, so a bound value's
20
- * placeholder is numbered correctly against the real query from the moment it's added, rather
21
- * than needing to be reconciled after the fact.
22
- * @param statement The context this one renders a fragment of, which owns the claimed aliases: a
23
- * fragment is part of one statement, so its aliases have to be unique across the whole of it.
24
- * @param inlineValues See {@link QueryContext.inlineValues}; a fragment takes its statement's.
11
+ * `params` and `statement` are a fragment's parent's, so a value numbers against the whole statement and
12
+ * an alias is unique across it; a fragment inlines values where its statement does.
25
13
  */
26
14
  constructor(dialect: SqlQueryDialect, params?: unknown[], statement?: SqlQueryContext | undefined, inlineValues?: boolean);
27
15
  createFragment(): QueryContext;
@@ -37,13 +25,7 @@ export declare class SqlQueryContext implements QueryContext {
37
25
  * where this context inlines values.
38
26
  */
39
27
  addValue(value: unknown): this;
40
- /**
41
- * Pushes values to the parameters list without appending placeholders to the SQL.
42
- * This is useful when the placeholder is already present in the SQL string or handled elsewhere.
43
- *
44
- * @param values The values to be added to the parameters.
45
- * @returns The current context instance for method chaining.
46
- */
28
+ /** Binds values whose placeholders the SQL already carries. */
47
29
  pushValue(...values: unknown[]): this;
48
30
  claimAlias(name: string, parent?: string): string;
49
31
  /**