@mikro-orm/mssql 7.1.0-dev.14 → 7.1.0-dev.15

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.
@@ -6,6 +6,8 @@ export declare class MsSqlSchemaHelper extends SchemaHelper {
6
6
  false: string[];
7
7
  'getdate()': string[];
8
8
  };
9
+ private static readonly AUTO_NOT_NULL_RE;
10
+ protected get bracketQuotedIdentifiers(): boolean;
9
11
  getManagementDbName(): string;
10
12
  getDropDatabaseSQL(name: string): string;
11
13
  disableForeignKeysSQL(): string;
@@ -7,6 +7,16 @@ export class MsSqlSchemaHelper extends SchemaHelper {
7
7
  false: ['0'],
8
8
  'getdate()': ['current_timestamp'],
9
9
  };
10
+ // `stripAutoNotNullFilter` unwraps balanced per-clause parens before calling `.exec`, so we
11
+ // only need to match the bare form here — previously the pattern allowed independently
12
+ // optional leading/trailing parens, which accepted unbalanced strings like `([col] IS NOT NULL`.
13
+ static AUTO_NOT_NULL_RE = /^\[([^\]]+)\]\s+IS\s+NOT\s+NULL$/i;
14
+ // MSSQL `filter_definition` and `where` predicates use `[…]` bracket-quoting for identifiers,
15
+ // so `splitTopLevelAnd` must treat `[` as opening a quoted span (otherwise `[some and col]`
16
+ // would split mid-identifier).
17
+ get bracketQuotedIdentifiers() {
18
+ return true;
19
+ }
10
20
  getManagementDbName() {
11
21
  return 'master';
12
22
  }
@@ -148,6 +158,7 @@ export class MsSqlSchemaHelper extends SchemaHelper {
148
158
  col.name as column_name,
149
159
  schema_name(t.schema_id) as schema_name,
150
160
  (case when filter_definition is not null then concat('where ', filter_definition) else null end) as expression,
161
+ filter_definition as filter_definition,
151
162
  ind.is_disabled as is_disabled,
152
163
  ind.type as index_type,
153
164
  ind.fill_factor as fill_factor,
@@ -192,15 +203,31 @@ export class MsSqlSchemaHelper extends SchemaHelper {
192
203
  if (index.fill_factor > 0) {
193
204
  indexDef.fillFactor = index.fill_factor;
194
205
  }
195
- if (index.column_name?.match(/[(): ,"'`]/) || index.expression?.match(/where /i)) {
196
- indexDef.expression = index.expression; // required for the `getCreateIndexSQL()` call
206
+ /* v8 ignore next: function-based / computed-column introspection path, same as pre-PR */
207
+ if (index.column_name?.match(/[(): ,"'`]/)) {
208
+ indexDef.expression = index.expression;
197
209
  indexDef.expression = this.getCreateIndexSQL(index.table_name, indexDef, !!index.expression);
198
210
  }
211
+ else if (index.filter_definition) {
212
+ // Auto-NOT-NULL stripping runs post-mapIndexes (needs the consolidated column list).
213
+ indexDef.where = index.filter_definition;
214
+ }
199
215
  ret[key] ??= [];
200
216
  ret[key].push(indexDef);
201
217
  }
202
218
  for (const key of Object.keys(ret)) {
203
219
  ret[key] = await this.mapIndexes(ret[key]);
220
+ for (const idx of ret[key]) {
221
+ if (idx.where) {
222
+ const stripped = this.stripAutoNotNullFilter(idx.where, idx.columnNames, MsSqlSchemaHelper.AUTO_NOT_NULL_RE);
223
+ if (stripped === '') {
224
+ delete idx.where;
225
+ }
226
+ else {
227
+ idx.where = stripped;
228
+ }
229
+ }
230
+ }
204
231
  }
205
232
  return ret;
206
233
  }
@@ -540,7 +567,7 @@ export class MsSqlSchemaHelper extends SchemaHelper {
540
567
  const clustered = index.clustered ? 'clustered ' : '';
541
568
  let sql = `create ${index.unique ? 'unique ' : ''}${clustered}index ${keyName} on ${this.quote(tableName)} `;
542
569
  if (index.expression && partialExpression) {
543
- return sql + `(${index.expression})` + this.getMsSqlIndexSuffix(index);
570
+ return sql + `(${index.expression})` + this.getMsSqlIndexSuffix(index) + this.getIndexWhereClause(index);
544
571
  }
545
572
  // Build column list with advanced options
546
573
  const columns = this.getIndexColumns(index);
@@ -549,7 +576,7 @@ export class MsSqlSchemaHelper extends SchemaHelper {
549
576
  if (index.include?.length) {
550
577
  sql += ` include (${index.include.map(c => this.quote(c)).join(', ')})`;
551
578
  }
552
- sql += this.getMsSqlIndexSuffix(index);
579
+ sql += this.getMsSqlIndexSuffix(index) + this.getIndexWhereClause(index);
553
580
  // Disabled indexes need to be created first, then disabled
554
581
  if (index.disabled) {
555
582
  sql += `;\nalter index ${keyName} on ${this.quote(tableName)} disable`;
@@ -594,13 +621,16 @@ export class MsSqlSchemaHelper extends SchemaHelper {
594
621
  if (index.expression) {
595
622
  return index.expression;
596
623
  }
597
- const needsWhereClause = index.unique && index.columnNames.some(column => table.getColumn(column)?.nullable);
598
- if (!needsWhereClause) {
624
+ const needsAutoNotNull = index.unique && index.columnNames.some(column => table.getColumn(column)?.nullable);
625
+ if (!needsAutoNotNull) {
599
626
  return this.getCreateIndexSQL(table.getShortestName(), index);
600
627
  }
601
- // Generate without disabled suffix, insert WHERE clause, then re-add disabled
602
- let sql = this.getCreateIndexSQL(table.getShortestName(), { ...index, disabled: false });
603
- sql += ' where ' + index.columnNames.map(c => `${this.quote(c)} is not null`).join(' and ');
628
+ // Strip `index.where` from the base SQL so we can combine it with the auto NOT-NULL guard
629
+ // ourselves, wrapping the user predicate in parens to defuse operator precedence
630
+ // (a bare `a = 1 or b = 2 and [col] is not null` would bind as `a = 1 or (b = 2 and )`).
631
+ let sql = this.getCreateIndexSQL(table.getShortestName(), { ...index, where: undefined, disabled: false });
632
+ const autoNotNull = index.columnNames.map(c => `${this.quote(c)} is not null`).join(' and ');
633
+ sql += index.where ? ` where (${index.where}) and ${autoNotNull}` : ` where ${autoNotNull}`;
604
634
  if (index.disabled) {
605
635
  sql += `;\nalter index ${this.quote(index.keyName)} on ${table.getQuotedName()} disable`;
606
636
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mikro-orm/mssql",
3
- "version": "7.1.0-dev.14",
3
+ "version": "7.1.0-dev.15",
4
4
  "description": "TypeScript ORM for Node.js based on Data Mapper, Unit of Work and Identity Map patterns. Supports MongoDB, MySQL, PostgreSQL and SQLite databases as well as usage with vanilla JavaScript.",
5
5
  "keywords": [
6
6
  "data-mapper",
@@ -47,7 +47,7 @@
47
47
  "copy": "node ../../scripts/copy.mjs"
48
48
  },
49
49
  "dependencies": {
50
- "@mikro-orm/sql": "7.1.0-dev.14",
50
+ "@mikro-orm/sql": "7.1.0-dev.15",
51
51
  "kysely": "0.28.16",
52
52
  "tarn": "3.0.2",
53
53
  "tedious": "19.2.1",
@@ -57,7 +57,7 @@
57
57
  "@mikro-orm/core": "^7.0.11"
58
58
  },
59
59
  "peerDependencies": {
60
- "@mikro-orm/core": "7.1.0-dev.14"
60
+ "@mikro-orm/core": "7.1.0-dev.15"
61
61
  },
62
62
  "engines": {
63
63
  "node": ">= 22.17.0"