uql-orm 0.66.0 → 0.67.1

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 +4 -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
@@ -1,5 +1,4 @@
1
- import { type EntityData, type EntityMeta, type EntityWhereMeta, type FieldKey, type FieldOptions, type IsolationLevel, type JsonColumnType, type JsonUpdateOp, type Query, type QueryAggMap, type QueryAggregate, type QueryBuildFn, type QueryComparisonOptions, type QueryConflictPaths, type QueryContext, type QueryContextOptions, type QueryExclude, type QueryFilter, type QueryGroupMap, type QueryGroupOp, type QueryHavingMap, type QueryOptions, type QueryPager, QueryRaw, type QueryRawFnOptions, type QuerySearch, type QuerySelectValue, type QuerySizeComparisonOps, type QuerySortMap, type QueryTextSearchOptions, type QueryVectorNear, type QueryWhere, type QueryWhereArray, type QueryWhereFieldOperatorMap, type QueryWhereOptions, type RelationMeta, type SqlDialectName, type SqlQueryDialect, type Type, type UpdatePayload } from '../type/index.js';
2
- import { type ColumnFamily } from '../util/field.util.js';
1
+ import { type ColumnFamily, type EntityData, type EntityMeta, type EntityWhereMeta, type FieldKey, type FieldOptions, type IsolationLevel, type JsonColumnType, type JsonUpdateOp, type Query, type QueryAggMap, type QueryAggregate, type QueryBuildFn, type QueryComparisonOptions, type QueryConflictPaths, type QueryContext, type QueryContextOptions, type QueryExclude, type QueryGroupMap, type QueryGroupOp, type QueryHavingMap, type QueryOptions, type QueryPage, type QueryPager, QueryRaw, type QueryRawFnOptions, type QuerySearch, type QuerySelectValue, type QuerySizeComparisonOps, type QuerySortMap, type QueryTextSearchOptions, type QueryVectorNear, type QueryWhere, type QueryWhereArray, type QueryWhereOptions, type RelationMeta, type SqlDialectName, type SqlQueryDialect, type Type, type UpdatePayload } from '../type/index.js';
3
2
  import type { HydrateKind } from './hydrateColumn.js';
4
3
  import { type JsonAccessMode } from './jsonSql.js';
5
4
  import { type QueryJoins, type QuerySortOptions } from './queryJoins.js';
@@ -85,17 +84,10 @@ export declare abstract class AbstractSqlDialect extends VectorSqlDialect implem
85
84
  abstract readonly escapeIdChar: '"' | '`';
86
85
  /**
87
86
  * The column type of a database-generated key: only the type, never the key itself, which the table
88
- * declares over its columns as one named constraint. SQLite is the exception - see
89
- * {@link serialDeclaresPrimaryKey}.
87
+ * declares over its columns as one named constraint. SQLite is the exception: see
88
+ * `SqlDialectFeatures.serialDeclaresPrimaryKey`.
90
89
  */
91
90
  abstract readonly autoIncrementSuffix: string;
92
- /**
93
- * Whether {@link autoIncrementSuffix} states `PRIMARY KEY` itself, so the table must not state it again.
94
- *
95
- * True on SQLite alone, where `AUTOINCREMENT` is legal only in the exact phrase
96
- * `INTEGER PRIMARY KEY AUTOINCREMENT` - the key cannot be lifted out of the column there.
97
- */
98
- readonly serialDeclaresPrimaryKey: boolean;
99
91
  abstract readonly tableOptions: string;
100
92
  abstract readonly beginTransactionCommand: string;
101
93
  abstract readonly commitTransactionCommand: string;
@@ -130,24 +122,15 @@ export declare abstract class AbstractSqlDialect extends VectorSqlDialect implem
130
122
  getBeginTransactionStatements(isolationLevel?: IsolationLevel): string[];
131
123
  createContext(options?: QueryContextOptions): QueryContext;
132
124
  /**
133
- * Builds SQL text in isolation via `build`, so the caller can embed it inline (e.g.
134
- * `"col" = <text>`) instead of appending it at the end of `ctx`. The fragment binds any value
135
- * straight into `ctx`'s own values array - shared by reference, not copied - so `addValue` numbers
136
- * its placeholder correctly against the real query from the start; a fresh, empty array would
137
- * instead number from `1` regardless of how many values `ctx` already has, misnumbering every
138
- * bound value on `$n`-placeholder dialects once `ctx` isn't otherwise empty. Generated aliases are
139
- * shared for the same reason - see {@link SqlQueryContext}.
125
+ * The SQL `build` writes, as text to embed rather than appended to `ctx`. It binds into `ctx`'s own values
126
+ * and aliases, so `$n` placeholders number against the whole statement.
140
127
  */
141
128
  protected buildFragment(ctx: QueryContext, build: QueryBuildFn): string;
142
129
  /** A `raw()` rendered in place, an operand or a projected term: bound, the driver would get the object. */
143
130
  protected rawFragment(ctx: QueryContext, value: QueryRaw, prefix?: string, entity?: Type<unknown>): string;
144
131
  /**
145
- * Each operand rendered into its own fragment, keeping only those that emitted SQL.
146
- *
147
- * Nothing reaches `ctx` until every one has rendered, because an operand that emits nothing - an
148
- * empty `$and`, an `{}` entry - must leave behind neither a dangling separator nor a clause with no
149
- * condition after it. How many terms really emit is also what decides the parentheses, which is why
150
- * the caller counts what comes back rather than what it passed in.
132
+ * Each operand rendered on its own, keeping those that emitted SQL: an empty one leaves no dangling
133
+ * separator, and the count of what emitted decides the parentheses.
151
134
  */
152
135
  protected renderOperands<T>(ctx: QueryContext, operands: readonly T[], render: (ctx: QueryContext, operand: T) => void): string[];
153
136
  addValue(ctx: QueryContext, value: unknown): string;
@@ -162,14 +145,7 @@ export declare abstract class AbstractSqlDialect extends VectorSqlDialect implem
162
145
  */
163
146
  normalizeValues(values: unknown[] | undefined): unknown[] | undefined;
164
147
  placeholder(_index: number): string;
165
- /**
166
- * `RETURNING <id column> AS id`, or nothing at all for a composite key.
167
- *
168
- * The alias names one column, and every column of a composite came from the caller, so there is no
169
- * id the statement could report that the payload does not already carry - the same "no id to give"
170
- * a `firstId` dialect already answers with. Empty rather than a refusal, so an insert and an upsert
171
- * of a composite row both run, and the querier names those rows with `idOf`.
172
- */
148
+ /** `RETURNING <id column> id`, or nothing on a composite key, whose every column the payload already names. */
173
149
  returningId<E>(meta: EntityMeta<E>): string;
174
150
  /** `<id column> AS id` on its own, for a statement composing a `RETURNING` list of several items. */
175
151
  protected returningIdExpression<E>(meta: EntityMeta<E>): string;
@@ -268,16 +244,8 @@ export declare abstract class AbstractSqlDialect extends VectorSqlDialect implem
268
244
  */
269
245
  private static readonly LIKE_OPS;
270
246
  /**
271
- * How this engine matches case-insensitively. One decision, not two: folding the pattern while the
272
- * comparison leaves the column alone matches neither case, which is what `$istartsWith: 'Some'`
273
- * used to do wherever `LIKE` is case-sensitive.
274
- *
275
- * - `ilike`: the engine has a case-insensitive operator (`ILIKE`), so the pattern goes through as written.
276
- * - `native`: plain `LIKE` already ignores case (SQLite, for ASCII). Folding the pattern in JS would
277
- * only break the non-ASCII characters the engine cannot fold anyway - `'É'` would become an `'é'`
278
- * that matches nothing.
279
- * - `fold`: nothing ignores case on its own, so both sides are lowered explicitly. Not indexable as
280
- * such; an expression index over `LOWER(column)` is what makes it so.
247
+ * How the engine matches case-insensitively: `ilike` has the operator, `native` ignores case already
248
+ * (SQLite, where folding in JS would break non-ASCII), and `fold` lowers both sides.
281
249
  */
282
250
  protected readonly caseInsensitiveMatch: 'ilike' | 'native' | 'fold';
283
251
  /**
@@ -301,19 +269,11 @@ export declare abstract class AbstractSqlDialect extends VectorSqlDialect implem
301
269
  * alias exists only when the field was also selected, which `$where` and `$sort` cannot assume.
302
270
  */
303
271
  private inlinedOperand;
304
- compareFieldOperator<E, K extends keyof QueryWhereFieldOperatorMap<E>>(ctx: QueryContext, entity: Type<E>, key: FieldKey<E>, op: K, val: QueryWhereFieldOperatorMap<E>[K], opts?: QueryOptions): void;
272
+ /** One operator of a field's condition. Both come from the query as data, so neither is trusted. */
273
+ compareFieldOperator<E>(ctx: QueryContext, entity: Type<E>, key: FieldKey<E>, op: string, val: unknown, opts?: QueryOptions): void;
305
274
  /**
306
- * `<operand> <op> <value>` for every operator that needs nothing but its left-hand SQL, or
307
- * `undefined` when `op` is not one of them.
308
- *
309
- * One implementation for three callers that each had their own: a WHERE column, a HAVING aggregate
310
- * expression, and a `$size` count (whose expression is already in the context, so it passes an
311
- * empty operand). They previously disagreed - HAVING carried a second comparison-operator map and
312
- * threw `unsupported HAVING operator` on the `$like` that `QueryHavingMap` accepts, and neither of
313
- * the other two turned `$eq: null` into `IS NULL` the way the WHERE path does.
314
- *
315
- * The operators kept out are the ones that need more than an operand: `$not` recurses through the
316
- * entity, and `$all`/`$size`/`$elemMatch` address a JSON document.
275
+ * `<operand> <op> <value>` for every operator that needs only its left-hand SQL, shared by a column, a
276
+ * `HAVING` expression and a `$size` count; `undefined` for the rest.
317
277
  */
318
278
  protected operatorCondition(ctx: QueryContext, operand: string, op: string, val: unknown): string | undefined;
319
279
  /** {@link operatorCondition}, appended; `false` when `op` needs more than an operand. */
@@ -332,13 +292,9 @@ export declare abstract class AbstractSqlDialect extends VectorSqlDialect implem
332
292
  /** `$size`: the length of the JSON array at `jsonField`, compared against `value`. */
333
293
  protected abstract jsonSize(ctx: QueryContext, jsonField: string, value: number | QuerySizeComparisonOps): string;
334
294
  /**
335
- * Explodes the JSON array at `jsonField` into rows, as the `FROM` of an `EXISTS` subquery, under
336
- * `alias` (from {@link QueryContext.claimAlias} - a fresh name per call, since `$elemMatch`/`$all`
337
- * can recurse into this on a nested array and a fixed, reused alias would let the inner occurrence
338
- * shadow the outer one it needs to correlate against). An empty `fields` means the elements are
339
- * scalars, in which case `asJson` says whether they are read as JSON or as text; otherwise they
340
- * are objects and `fields` are the keys the conditions will read (MySQL needs them upfront for its
341
- * `JSON_TABLE` column list).
295
+ * The JSON array at `jsonField` as rows, the `FROM` of an `EXISTS`, under a fresh `alias` so a nested
296
+ * one cannot shadow it. `fields` are an object element's keys (MySQL lists them up front), empty for
297
+ * scalars, which `asJson` reads as JSON rather than text.
342
298
  */
343
299
  protected abstract jsonElemFrom(jsonField: string, fields: readonly string[], alias: string, asJson?: boolean): string;
344
300
  /**
@@ -348,25 +304,8 @@ export declare abstract class AbstractSqlDialect extends VectorSqlDialect implem
348
304
  */
349
305
  protected abstract jsonElemRef(alias: string, field?: string, asJson?: boolean): string;
350
306
  /**
351
- * Whether the dialect's array containment ({@link jsonAll}) matches an object element that merely
352
- * *includes* the given keys, as PostgreSQL's `@>` and MySQL's `JSON_CONTAINS` do. SQLite compares
353
- * elements as whole JSON text, so it cannot express a partial match and always expands the
354
- * per-field form below.
355
- */
356
- protected readonly jsonContainmentIsPartial: boolean;
357
- /**
358
- * Whether an exploded *scalar* element keeps its SQL type. SQLite's `JSON_EACH` yields JSON
359
- * booleans as `0`/`1` integers and numbers as numbers, so such an element compares directly to a
360
- * bound value; PostgreSQL and MySQL explode scalars to text, losing the type, so a non-string
361
- * operand there has to compare as JSON (see {@link isJsonbOp}).
362
- */
363
- protected readonly jsonScalarElemKeepsType: boolean;
364
- /**
365
- * `$elemMatch`: at least one element of the JSON array satisfies `match`. Three shapes, decided
366
- * here so every dialect only supplies {@link jsonElemFrom} / {@link jsonElemRef}:
367
- * - keys are operators (`{ $startsWith: 'ad' }`) - scalar elements, conditions on the element;
368
- * - a plain object with no nested operators - containment, which is the only form an index serves;
369
- * - otherwise - per-field conditions over the exploded objects.
307
+ * `$elemMatch`: an element satisfies `match`. Operator keys test a scalar element; a plain object is
308
+ * containment, which an index can serve; anything else tests each exploded object's fields.
370
309
  */
371
310
  protected jsonElemMatch(ctx: QueryContext, jsonField: string, match: Record<string, unknown>): string;
372
311
  /**
@@ -407,16 +346,6 @@ export declare abstract class AbstractSqlDialect extends VectorSqlDialect implem
407
346
  * {@link MergeSqlDialect} needs: SQL Server refuses to page a statement that has none.
408
347
  */
409
348
  pager(ctx: QueryContext, opts: QueryPager, _sorted?: boolean): void;
410
- /** Whether this engine has row locks at all. The SQLite family locks the database instead. */
411
- readonly supportsRowLocks: boolean;
412
- /**
413
- * Whether a `FOR UPDATE` may share a statement with a window function. The MySQL family runs the
414
- * pair; the Postgres family rejects it outright ("FOR UPDATE is not allowed with window functions"),
415
- * which is what a paged read carrying its own `COUNT(*) OVER ()` total becomes under a `$lock`.
416
- */
417
- readonly supportsWindowWithRowLock: boolean;
418
- /** MariaDB is the one engine here that cannot narrow a lock to one table of a join. */
419
- readonly supportsLockOf: boolean;
420
349
  /** Validated before the querier checks for a transaction, so the clearer error wins. */
421
350
  assertLockSupported<E>(entity: Type<E>, q: Query<E>, joins?: QueryJoins): void;
422
351
  /**
@@ -431,17 +360,18 @@ export declare abstract class AbstractSqlDialect extends VectorSqlDialect implem
431
360
  * and the other engines quietly widen the lock to the joined rows.
432
361
  */
433
362
  protected appendLock<E>(ctx: QueryContext, entity: Type<E>, q: Query<E>, joins?: QueryJoins, alias?: string): void;
434
- count<E>(ctx: QueryContext, entity: Type<E>, q: QueryFilter<E>, opts?: QueryOptions): void;
435
363
  /**
436
- * How many rows a `$distinct` read returns, which `COUNT(*)` cannot answer: the deduplication
437
- * happens after it counts, and a window function is no better - it counts before `DISTINCT` too.
438
- * So the deduplicated set is made a derived table and its rows are counted. Every engine here
439
- * supports one; MySQL is the reason it is aliased.
440
- *
441
- * The inner query takes the projection and the filter but never the page: the caller is asking how
442
- * many rows there are beyond the page it already has.
364
+ * `COUNT(*)` over the filter, or over the rows a page settles. The clauses are read off `q` one by one:
365
+ * `/http` hands it over untyped, and a smuggled `$sort` changes no count.
366
+ */
367
+ count<E>(ctx: QueryContext, entity: Type<E>, q: QueryPage<E>, opts?: QueryOptions): void;
368
+ /**
369
+ * How many rows a `$distinct` read returns: the deduplication runs after `COUNT(*)` and a window
370
+ * alike, so the deduplicated set is counted as a derived table, never paged.
443
371
  */
444
372
  countDistinct<E>(ctx: QueryContext, entity: Type<E>, q: Query<E>, opts?: QueryOptions): void;
373
+ /** `SELECT COUNT(*)` over the rows `rows` appends, as a derived table. */
374
+ private countRows;
445
375
  /**
446
376
  * The statistic the engine already keeps, as a `count` column. Overridden by the dialects that
447
377
  * keep one; the rest throw, because falling back to `COUNT(*)` would run exactly the scan the
@@ -481,21 +411,8 @@ export declare abstract class AbstractSqlDialect extends VectorSqlDialect implem
481
411
  */
482
412
  private readOptions;
483
413
  insert<E>(ctx: QueryContext, entity: Type<E>, payload: E | E[], opts?: QueryOptions): void;
484
- /**
485
- * Where the clause reporting an insert's generated ids goes. `suffix` is `RETURNING ...` at the end
486
- * of the statement, which every engine here but one spells that way; SQL Server's `OUTPUT` has no
487
- * trailing form and sits between the column list and `VALUES`.
488
- *
489
- * A knob rather than a pair of hooks: one concept decides where the string {@link returningId}
490
- * already built ends up, so the two ends cannot disagree.
491
- */
414
+ /** Where an insert's id clause goes: `RETURNING` at the end, or SQL Server's `OUTPUT` before `VALUES`. */
492
415
  readonly returningPosition: 'suffix' | 'after-target';
493
- /**
494
- * Whether a multi-row upsert's `RETURNING` lists its rows in payload order. Where it does not, the
495
- * ids are read back by the conflict columns instead, since placing them in order would name the
496
- * wrong rows.
497
- */
498
- readonly upsertReturningOrdered: boolean;
499
416
  /**
500
417
  * `INSERT INTO ... VALUES (...)` and nothing more. The upsert builders extend this rather than
501
418
  * {@link insert}: their own clause has to come before the `RETURNING`, not after it.
@@ -503,13 +420,7 @@ export declare abstract class AbstractSqlDialect extends VectorSqlDialect implem
503
420
  protected appendInsertValues<E>(ctx: QueryContext, entity: Type<E>, payload: E | E[],
504
421
  /** Spliced between the column list and `VALUES`; see {@link returningPosition}. */
505
422
  afterTarget?: string): void;
506
- /**
507
- * The columns an insert writes and the records it writes them from, resolved once.
508
- *
509
- * Split out of {@link appendInsertValues} because a `MERGE` needs the same rows as a `VALUES` row
510
- * source rather than as an `INSERT`, and both have to apply `onInsert` defaults and the
511
- * JSON/vector binding rules identically.
512
- */
423
+ /** The columns an insert writes and the rows it writes, resolved once, and shared with a `MERGE`'s row source. */
513
424
  protected insertShape<E>(entity: Type<E>, payload: E | E[]): InsertShape<E>;
514
425
  /** `(a, b), (c, d)` - the row constructor an INSERT and a MERGE source both write. */
515
426
  protected appendValueRows<E>(ctx: QueryContext, { payloads, keys, fields, kinds }: InsertShape<E>): void;
@@ -521,31 +432,17 @@ export declare abstract class AbstractSqlDialect extends VectorSqlDialect implem
521
432
  protected appendDefaultInsertValue(ctx: QueryContext, _field: FieldOptions | undefined): void;
522
433
  update<E>(ctx: QueryContext, entity: Type<E>, q: QuerySearch<E>, payload: UpdatePayload<E>, opts?: QueryOptions): void;
523
434
  /**
524
- * `INSERT ... ON CONFLICT (...) DO UPDATE/NOTHING RETURNING ...`, which SQLite adopted from Postgres
525
- * and which every dialect here speaks except the MySQL family (see {@link MysqlLikeSqlDialect}).
526
- *
527
- * Two orderings matter, and they pull in opposite directions. The assignments are computed *before*
528
- * the insert, because `appendInsertValues` fills `onInsert` fields into the payload and a column that
529
- * exists only there - `createdAt` - must not join the update set. Their bound values are pushed
530
- * *after* it, because a `?` placeholder is positional and the clause comes last in the statement.
531
- * {@link PgLikeSqlDialect} overrides this: `$N` placeholders make array order irrelevant, so it can
532
- * bind into the main context and skip the second one.
435
+ * `INSERT ... ON CONFLICT ... DO UPDATE/NOTHING RETURNING`. The assignments are built before the insert
436
+ * fills `onInsert` columns, which must stay out of them, and their values bound after it, where a `?` reads them.
533
437
  */
534
438
  upsert<E>(ctx: QueryContext, entity: Type<E>, conflictPaths: QueryConflictPaths<E>, payload: E | E[],
535
439
  /** One more `RETURNING` item, as a bare expression: this joins the list and adds the keyword. */
536
440
  extraReturning?: string): void;
537
- /**
538
- * Whether the upsert's update assignments can bind straight into the statement's own context.
539
- *
540
- * They cannot on a `?`-placeholder dialect: the assignments are built before the insert but read
541
- * after it, so their values have to be pushed afterwards to land in the right positional order.
542
- * A `$n` placeholder carries its own index, so there is nothing to reorder - but it also cannot use
543
- * the scratch context, whose numbering would restart at `$1` and collide with the insert's.
544
- */
441
+ /** Whether the upsert's assignments bind straight into the statement, as numbered `$n` placeholders can. */
545
442
  protected readonly upsertUpdateBindsInPlace: boolean;
546
443
  /** How an `ON CONFLICT` assignment reads the row that was being inserted. */
547
444
  protected readonly upsertExcluded: (columnName: string) => string;
548
- protected getUpsertUpdateAssignments<E>(ctx: QueryContext, meta: EntityMeta<E>, conflictPaths: QueryConflictPaths<E>, payload: E | E[], callback?: (columnName: string) => string): string;
445
+ protected getUpsertUpdateAssignments<E>(ctx: QueryContext, meta: EntityMeta<E>, conflictPaths: QueryConflictPaths<E>, payload: E | E[], callback: (columnName: string) => string): string;
549
446
  protected getUpsertConflictPathsStr<E>(meta: EntityMeta<E>, conflictPaths: QueryConflictPaths<E>): string;
550
447
  delete<E>(ctx: QueryContext, entity: Type<E>, q: QuerySearch<E>, opts?: QueryOptions): void;
551
448
  escapeId(val: string | undefined, forbidQualified?: boolean, addDot?: boolean): string;
@@ -562,52 +459,20 @@ export declare abstract class AbstractSqlDialect extends VectorSqlDialect implem
562
459
  * every INSERT/UPDATE.
563
460
  */
564
461
  protected formatPersistableValue(ctx: QueryContext, field: FieldOptions | undefined, value: unknown): void;
565
- /**
566
- * How a column's values are written. A function of the column, not of the value, so a bulk insert
567
- * classifies each column once instead of re-deciding per row: a 20-row, 6-column insert used to ask
568
- * 120 times to get the same six answers.
569
- */
462
+ /** How a column's values are written: a function of the column, so a bulk insert classifies each once. */
570
463
  protected persistKind(field: FieldOptions | undefined): PersistKind;
571
464
  /**
572
- * Which of an entity's columns need decoding on READ, and how: the inverse of {@link persistKind},
573
- * cached per entity for the same reason it classifies per column. A 1000-row read of a 10-field
574
- * entity otherwise asks {@link columnFamily} (which lowercases a string on every call) 10,000 times
575
- * to get the same ten answers. Most entities land here for their numeric columns alone, where the
576
- * per-row cost is one `typeof` against a value the driver usually decoded already.
577
- *
578
- * Dialect-aware exactly like {@link supportedVectorType}, because it has to be: a `sparsevec` field
579
- * is written as a plain dense vector everywhere but Postgres, so reading it back by the field's own
580
- * declared cast would look for a sparse literal that was never stored.
581
- *
582
- * A type lands here rather than at the driver when the wire type alone cannot decide it, and only
583
- * the declaration can: `Boolean` is 0/1 in a SQLite INTEGER and a MySQL `TINYINT(1)`, both
584
- * indistinguishable from a genuine small integer; a decimal is text from pg *and* mysql2, and only
585
- * the field says it was meant as a number; and `type: BigInt` shares BIGINT with `type: Number`, so
586
- * the wire decode has to be undone for it. All are no-ops where the driver already decoded.
587
- *
588
- * Classified through the same {@link columnFamily} the rest of the library uses, not against the
589
- * constructors: `type` accepts a string logical type for every one of these (`@Field({ type:
590
- * 'decimal' })`), and matching `=== Number` alone left those reading back as text.
465
+ * The columns a read decodes, and how, cached per entity and revision. They are the ones the wire cannot
466
+ * decide alone: a boolean stored as an integer, a decimal read as text, a `BigInt`, and a related row's
467
+ * values, which cross JSON as text.
591
468
  */
592
469
  hydratableFields<E>(entity: Type<E>): readonly HydratableField[];
593
470
  /**
594
- * The same classification for an aggregate row. Not cached, because these columns are a shape of the
595
- * query rather than of the entity, and it is computed once per call either way.
596
- *
597
- * Mirrors `QueryAggregateFnResult`, which is the contract callers already compile against:
598
- * `$count`/`$sum`/`$avg` are a number whatever they aggregate, while `$min`/`$max` and every
599
- * `$group` column keep the aggregated field's own type, so they decode as that field would. Without
600
- * it a `$sum` over a BIGINT column came back as `'500'` from a result type that says `number`, since
601
- * Postgres widens that sum to NUMERIC and no driver can know it was meant as a JS number.
471
+ * The same for an aggregate's row, per query: a count or total is a number however the engine widened
472
+ * it, and `$min`/`$max` or a grouped column decodes as its field does.
602
473
  */
603
474
  hydratableAggregates<E, G extends QueryGroupMap<E>, A extends QueryAggMap<E>>(entity: Type<E>, q: QueryAggregate<E, G, A>): readonly HydratableField[];
604
- /**
605
- * The mirror of {@link persistKind}: what one column decodes as, or nothing if it needs no decode. A
606
- * date and bytes decode because a related row crosses JSON, which spells both as text.
607
- *
608
- * `BigInt` is asked first because it shares the numeric family with `Number`: let the switch answer
609
- * it and every `type: BigInt` property silently decodes to a JS number again.
610
- */
475
+ /** What one column decodes as, the inverse of {@link persistKind}. `BigInt` first, since it shares the numeric family. */
611
476
  protected hydrateKind(field: FieldOptions | undefined): HydrateKind | undefined;
612
477
  private readonly hydratable;
613
478
  /** The one type dispatch for a persisted value, over a column kind decided by the caller. */
@@ -620,17 +485,8 @@ export declare abstract class AbstractSqlDialect extends VectorSqlDialect implem
620
485
  */
621
486
  protected jsonCast(operand: string): string;
622
487
  /**
623
- * Generate the full `"col" = <expression>` assignment for a JSON update operator payload.
624
- * Called from `update()` when a field value is a {@link JsonUpdateOp}.
625
- *
626
- * Each operator wraps the expression built so far, innermost-first in the order stated on
627
- * {@link JsonUpdateOp} (`$pull` -> `$set` -> `$push` -> `$unset`), so dialects only supply the
628
- * four SQL fragments below. Two invariants keep every dialect consistent and keep bound values in
629
- * step with their placeholders:
630
- * - `$pull` is innermost and its subquery reads `escapedCol`, so its value binds exactly once.
631
- * - Later fragments reference `expr` at most once, so a `$pull` subquery is never duplicated
632
- * (which would bind its value twice on positional-placeholder dialects). PostgreSQL's `$push`
633
- * is the one exception, and is safe there because its placeholders are numbered.
488
+ * `"col" = <expr>` for a JSON update, each operator wrapping the last: `$pull`, `$set`, `$push`, `$unset`.
489
+ * `$pull` reads the column and every later one its expression once, so no value binds twice.
634
490
  */
635
491
  protected formatJsonUpdate(ctx: QueryContext, escapedCol: string, value: JsonUpdateOp, field?: FieldOptions): void;
636
492
  /**
@@ -747,11 +603,6 @@ export declare abstract class AbstractSqlDialect extends VectorSqlDialect implem
747
603
  * correlate a derived table. [The design](../../../../architecture/relations-in-one-statement.md).
748
604
  */
749
605
  protected abstract appendRelationArray(ctx: QueryContext, rows: RelationRows): void;
750
- /**
751
- * Whether the engine's JSON aggregate takes an `ORDER BY` of its own. Where it does not, a relation's
752
- * rows carry no sort term out and keep their own order, which a derived table hands its aggregate.
753
- */
754
- protected readonly orderedAggregates: boolean;
755
606
  /**
756
607
  * The rows read as a derived table, their values crossing JSON and, where the aggregate orders, each
757
608
  * sort term carried out beside them for it to order by, since a derived table's order is not promised
@@ -784,24 +635,11 @@ export declare abstract class AbstractSqlDialect extends VectorSqlDialect implem
784
635
  * @param sizeExprFn - function that appends the size expression to ctx (e.g. `JSONB_ARRAY_LENGTH("col")`)
785
636
  */
786
637
  protected buildSizeComparison(ctx: QueryContext, sizeExprFn: () => void, sizeVal: number | QuerySizeComparisonOps): void;
787
- /**
788
- * `<distance expr> <op> ?` - the `$where` half of vector search, where `$sort` is the ranking half.
789
- *
790
- * The bounds are validated here rather than left to the shared renderer, which also knows `$like`
791
- * and `$in`; and `$eq`/`$ne` are absent on purpose, since a distance is a float. `/http` casts
792
- * client JSON straight to `Query`, so an unknown key has to be refused rather than ignored.
793
- */
638
+ /** `<distance> <op> ?`, the `$where` half of a vector search, its bounds checked here since `/http` input is untyped. */
794
639
  protected compareVectorNear<E>(ctx: QueryContext, meta: EntityMeta<E>, key: string, near: QueryVectorNear): void;
795
640
  /** The runtime half of {@link QuerySizeComparisonOps}: what a count can sensibly be compared with. */
796
641
  private static readonly SIZE_COMPARE_OPS;
797
- /**
798
- * Append a single size comparison operator and value. No operand: the count expression is already
799
- * in the context, so this contributes only the ` <op> <value>` tail.
800
- *
801
- * Gated on {@link SIZE_COMPARE_OPS} rather than on whatever the shared renderer accepts, because
802
- * that renderer also knows `$like`, `$regex` and `$in`, none of which mean anything against a
803
- * count. `$size: { $like: 5 }` has to stay the error it always was.
804
- */
642
+ /** ` <op> <value>` after a count already written, refusing any operator a count cannot be compared with. */
805
643
  private appendSizeOp;
806
644
  /** ANSI-style single-quote escaping. MySQL-family dialects override this for backslash escaping. */
807
645
  escape(value: unknown): string;
@@ -820,11 +658,8 @@ export declare abstract class AbstractSqlDialect extends VectorSqlDialect implem
820
658
  */
821
659
  protected get neOp(): string;
822
660
  protected neExpr(field: string, ph: string): string;
823
- /**
824
- * Formats an IN/NOT IN expression, binding each value individually.
825
- * Postgres overrides to use `= ANY($1)` / `<> ALL($1)` with a single array parameter.
826
- */
827
- protected formatIn(ctx: QueryContext, values: unknown[], negate: boolean): string;
661
+ /** `operand IN (...)` binding each value, or the constant an empty set reduces to: no value is in it. */
662
+ protected formatIn(ctx: QueryContext, operand: string, values: unknown[], negate: boolean): string;
828
663
  /** Reads extracted JSON text as a number, which every engine spells its own way. */
829
664
  protected abstract numericCast(expr: string): string;
830
665
  toString(): string;