uql-orm 0.56.0 → 0.58.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.
- package/README.md +7 -9
- package/dist/browser/uql-browser.min.js +2 -2
- package/dist/browser/uql-browser.min.js.map +4 -4
- package/dist/cockroachdb/cockroachDialect.d.ts +5 -2
- package/dist/cockroachdb/cockroachDialect.js +2 -10
- package/dist/d1/d1SqliteDialect.d.ts +1 -0
- package/dist/d1/d1SqliteDialect.js +2 -0
- package/dist/dialect/abstractSqlDialect.d.ts +196 -33
- package/dist/dialect/abstractSqlDialect.js +410 -203
- package/dist/dialect/aliases.d.ts +10 -7
- package/dist/dialect/aliases.js +12 -7
- package/dist/dialect/hydrateColumn.d.ts +8 -2
- package/dist/dialect/hydrateColumn.js +33 -1
- package/dist/dialect/jsonSql.d.ts +13 -5
- package/dist/dialect/jsonSql.js +24 -7
- package/dist/dialect/mysqlLikeSqlDialect.d.ts +31 -3
- package/dist/dialect/mysqlLikeSqlDialect.js +57 -5
- package/dist/dialect/pgLikeSqlDialect.d.ts +20 -20
- package/dist/dialect/pgLikeSqlDialect.js +23 -48
- package/dist/dialect/pgVectorMetrics.d.ts +13 -0
- package/dist/dialect/pgVectorMetrics.js +17 -0
- package/dist/dialect/queryContext.d.ts +3 -7
- package/dist/dialect/queryContext.js +13 -8
- package/dist/dialect/queryJoins.d.ts +8 -4
- package/dist/dialect/queryJoins.js +26 -11
- package/dist/dialect/vectorSqlDialect.d.ts +2 -2
- package/dist/dialect/vectorSqlDialect.js +2 -3
- package/dist/entity/decorator/bag.d.ts +2 -2
- package/dist/entity/decorator/entity.d.ts +8 -9
- package/dist/entity/decorator/entity.js +6 -7
- package/dist/entity/decorator/members.d.ts +7 -6
- package/dist/entity/decorator/members.js +2 -1
- package/dist/entity/metadata/definition.d.ts +16 -11
- package/dist/entity/metadata/definition.js +54 -42
- package/dist/http/handler.d.ts +2 -2
- package/dist/http/handler.js +0 -1
- package/dist/maria/mariaDialect.d.ts +13 -6
- package/dist/maria/mariaDialect.js +29 -9
- package/dist/migrate/cli.d.ts +2 -3
- package/dist/migrate/cli.js +2 -2
- package/dist/migrate/codegen/entityCodeGenerator.js +6 -4
- package/dist/migrate/codegen/entityTypes.d.ts +1 -1
- package/dist/migrate/codegen/entityTypes.js +4 -3
- package/dist/migrate/codegen/indexDecoratorSource.d.ts +5 -4
- package/dist/migrate/codegen/indexDecoratorSource.js +17 -13
- package/dist/migrate/codegen/sourceLiteral.d.ts +2 -0
- package/dist/migrate/codegen/sourceLiteral.js +4 -0
- package/dist/migrate/ddl/index.d.ts +1 -5
- package/dist/migrate/ddl/index.js +14 -25
- package/dist/migrate/ddl/indexDdl.d.ts +11 -2
- package/dist/migrate/ddl/indexDdl.js +17 -1
- package/dist/migrate/ddl/mssqlIndexDdl.d.ts +10 -0
- package/dist/migrate/ddl/mssqlIndexDdl.js +10 -0
- package/dist/migrate/ddl/mysqlIndexDdl.d.ts +10 -17
- package/dist/migrate/ddl/mysqlIndexDdl.js +16 -27
- package/dist/migrate/ddl/pgIndexDdl.d.ts +18 -8
- package/dist/migrate/ddl/pgIndexDdl.js +29 -12
- package/dist/migrate/generator/mongoSchemaGenerator.d.ts +3 -3
- package/dist/migrate/migrator.d.ts +4 -4
- package/dist/migrate/schemaGenerator.d.ts +8 -8
- package/dist/migrate/schemaGenerator.js +5 -7
- package/dist/migrate/schemaGeneratorAsync.d.ts +2 -3
- package/dist/mongo/mongoDialect.d.ts +31 -18
- package/dist/mongo/mongoDialect.js +146 -104
- package/dist/mongo/mongodbQuerier.d.ts +10 -17
- package/dist/mongo/mongodbQuerier.js +31 -106
- package/dist/mssql/mssqlDialect.d.ts +16 -0
- package/dist/mssql/mssqlDialect.js +26 -4
- package/dist/mysql/mysqlDialect.d.ts +2 -0
- package/dist/mysql/mysqlDialect.js +4 -0
- package/dist/querier/abstractQuerier.d.ts +20 -36
- package/dist/querier/abstractQuerier.js +35 -129
- package/dist/querier/abstractQuerierPool.d.ts +2 -2
- package/dist/querier/abstractSqlQuerier.d.ts +4 -17
- package/dist/querier/abstractSqlQuerier.js +40 -50
- package/dist/schema/canonicalType.js +4 -4
- package/dist/schema/indexDifferences.js +4 -4
- package/dist/schema/schemaASTBuilder.d.ts +3 -3
- package/dist/schema/schemaASTBuilder.js +32 -3
- package/dist/schema/schemaASTDiffer.js +5 -5
- package/dist/sqlite/sqliteDialect.d.ts +20 -1
- package/dist/sqlite/sqliteDialect.js +38 -7
- package/dist/turso/tursoDialect.d.ts +2 -0
- package/dist/turso/tursoDialect.js +2 -0
- package/dist/type/config.d.ts +3 -3
- package/dist/type/dialect.d.ts +4 -5
- package/dist/type/entity.d.ts +110 -69
- package/dist/type/migration.d.ts +7 -7
- package/dist/type/migratorDialect.d.ts +4 -0
- package/dist/type/querier.d.ts +6 -6
- package/dist/type/querierPool.d.ts +2 -2
- package/dist/type/query.d.ts +41 -72
- package/dist/type/query.js +10 -5
- package/dist/type/queryAggregate.d.ts +43 -34
- package/dist/type/queryAggregate.js +1 -1
- package/dist/type/queryWhere.d.ts +12 -9
- package/dist/type/universalQuerier.d.ts +4 -4
- package/dist/util/dialect.util.d.ts +4 -4
- package/dist/util/dialect.util.js +24 -15
- package/dist/util/field.util.d.ts +5 -0
- package/dist/util/field.util.js +19 -0
- package/dist/util/object.util.d.ts +2 -0
- package/dist/util/object.util.js +4 -0
- package/dist/util/relationQuery.util.d.ts +12 -65
- package/dist/util/relationQuery.util.js +27 -81
- package/dist/util/rowKey.util.d.ts +1 -11
- package/dist/util/rowKey.util.js +1 -13
- package/package.json +1 -1
- package/dist/querier/relationCount.d.ts +0 -16
- package/dist/querier/relationCount.js +0 -121
package/dist/migrate/cli.d.ts
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import type { AbstractDialect } from '../dialect/index.js';
|
|
3
2
|
import type { ForeignKeyAction } from '../schema/types.js';
|
|
4
|
-
import type { Config } from '../type/index.js';
|
|
3
|
+
import type { Config, MigratorDialect } from '../type/index.js';
|
|
5
4
|
import { Migrator } from './migrator.js';
|
|
6
5
|
import { createSchemaGeneratorAsync } from './schemaGeneratorAsync.js';
|
|
7
6
|
/** Sync helper for SQL dialects only; returns `undefined` for MongoDB - use {@link createSchemaGeneratorAsync}. */
|
|
8
|
-
export declare function getSchemaGenerator(dialect:
|
|
7
|
+
export declare function getSchemaGenerator(dialect: MigratorDialect, defaultForeignKeyAction?: ForeignKeyAction): import("./schemaGenerator.js").SqlSchemaGenerator | undefined;
|
|
9
8
|
export { createSchemaGeneratorAsync };
|
|
10
9
|
export declare function main(args?: string[]): Promise<void>;
|
|
11
10
|
export declare function runUp(migrator: Migrator, args: string[]): Promise<void>;
|
package/dist/migrate/cli.js
CHANGED
|
@@ -308,7 +308,7 @@ function printDriftGroup(title, drifts, icon, showSuggestion) {
|
|
|
308
308
|
console.log(` Expected: ${drift.expected}, Actual: ${drift.actual}`);
|
|
309
309
|
}
|
|
310
310
|
if (showSuggestion) {
|
|
311
|
-
console.log(`
|
|
311
|
+
console.log(` -> ${drift.suggestion}`);
|
|
312
312
|
}
|
|
313
313
|
}
|
|
314
314
|
console.log('');
|
|
@@ -358,7 +358,7 @@ Configuration:
|
|
|
358
358
|
Create a uql.config.ts or uql.config.js file in your project root.
|
|
359
359
|
You can also specify a custom config path using --config or -c.
|
|
360
360
|
The CLI requires pool.dialect (dialect id = pool.dialect.dialectName).
|
|
361
|
-
See the repo README section "Driver
|
|
361
|
+
See the repo README section "Driver -> pool -> dialect class".
|
|
362
362
|
|
|
363
363
|
export default {
|
|
364
364
|
pool: new PgQuerierPool({ ... }),
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
*/
|
|
12
12
|
import { canonicalToTypeScript } from '../../schema/canonicalType.js';
|
|
13
13
|
import { DEFAULT_FOREIGN_KEY_ACTION, } from '../../schema/types.js';
|
|
14
|
-
import { camelCase, pascalCase, singularize } from '../../util/string.util.js';
|
|
14
|
+
import { camelCase, lowerFirst, pascalCase, singularize } from '../../util/string.util.js';
|
|
15
15
|
import { buildFieldOptionsSource, fieldNeedsRaw } from './fieldOptionsSource.js';
|
|
16
16
|
import { buildIndexDecoratorSource, indexNeedsRaw, isPlainFieldIndex } from './indexDecoratorSource.js';
|
|
17
17
|
/**
|
|
@@ -116,8 +116,9 @@ export class EntityCodeGenerator {
|
|
|
116
116
|
buildEntityDecorators(table) {
|
|
117
117
|
const lines = [];
|
|
118
118
|
if (this.options.includeIndexes) {
|
|
119
|
+
const param = lowerFirst(this.options.classNameTransformer(table.name));
|
|
119
120
|
for (const index of this.declaredIndexes(table)) {
|
|
120
|
-
lines.push(buildIndexDecoratorSource(index, this.options.propertyNameTransformer));
|
|
121
|
+
lines.push(buildIndexDecoratorSource(index, this.options.propertyNameTransformer, param));
|
|
121
122
|
}
|
|
122
123
|
}
|
|
123
124
|
// Entity decorator
|
|
@@ -260,9 +261,10 @@ export class EntityCodeGenerator {
|
|
|
260
261
|
lines.push(` * Inverse relation from ${rel.from.table.name}`);
|
|
261
262
|
lines.push(' */');
|
|
262
263
|
}
|
|
263
|
-
//
|
|
264
|
+
// The inverse side, mapped by the related class's property that points back at this one.
|
|
264
265
|
const inverseProp = this.options.propertyNameTransformer(this.options.singularize(table.name));
|
|
265
|
-
|
|
266
|
+
const param = lowerFirst(relatedClassName);
|
|
267
|
+
lines.push(` @${decoratorName}({ entity: () => ${relatedClassName}, mappedBy: (${param}) => ${param}.${inverseProp} })`);
|
|
266
268
|
// Property
|
|
267
269
|
if (inverseType === 'OneToMany' || inverseType === 'ManyToMany') {
|
|
268
270
|
lines.push(` ${propertyName}?: ${relatedClassName}[];`);
|
|
@@ -4,4 +4,4 @@ import type { Type } from '../../type/index.js';
|
|
|
4
4
|
* compiler too. Interfaces, not the entity classes `generate:from-db` writes: those are the source of
|
|
5
5
|
* a schema, these describe one already defined elsewhere.
|
|
6
6
|
*/
|
|
7
|
-
export declare function entityTypesSource(entities: readonly Type<
|
|
7
|
+
export declare function entityTypesSource(entities: readonly Type<object>[]): string;
|
|
@@ -2,6 +2,7 @@ import { getMeta } from '../../entity/index.js';
|
|
|
2
2
|
import { canonicalToTypeScript } from '../../schema/canonicalType.js';
|
|
3
3
|
import { resolveColumnCanonicalType } from '../../schema/schemaASTBuilder.js';
|
|
4
4
|
import { isToManyRelation, upperFirst } from '../../util/index.js';
|
|
5
|
+
import { isIdentifierName } from './sourceLiteral.js';
|
|
5
6
|
/**
|
|
6
7
|
* A `.d.ts` for the entities as registered, so a shape that only exists at runtime reaches the
|
|
7
8
|
* compiler too. Interfaces, not the entity classes `generate:from-db` writes: those are the source of
|
|
@@ -41,12 +42,12 @@ function interfaceNames(metas) {
|
|
|
41
42
|
}
|
|
42
43
|
/** `text` as an identifier: what cannot be in one is dropped, and what cannot start one is prefixed. */
|
|
43
44
|
function identifier(text) {
|
|
44
|
-
const stripped = text.replace(/[
|
|
45
|
-
return
|
|
45
|
+
const stripped = text.replace(/[^\p{ID_Continue}$\u200C\u200D]/gu, '');
|
|
46
|
+
return isIdentifierName(stripped) ? stripped : `Entity${stripped}`;
|
|
46
47
|
}
|
|
47
48
|
/** A column name a property cannot hold - `hero-image` - is quoted rather than dropped. */
|
|
48
49
|
function member(key, type) {
|
|
49
|
-
const name =
|
|
50
|
+
const name = isIdentifierName(key) ? key : JSON.stringify(key);
|
|
50
51
|
return ` ${name}?: ${type};`;
|
|
51
52
|
}
|
|
52
53
|
/**
|
|
@@ -2,13 +2,14 @@ import type { IndexNode } from '../../schema/types.js';
|
|
|
2
2
|
/**
|
|
3
3
|
* Whether `@Field({ index })` can carry the whole index. It says only "this column is indexed under
|
|
4
4
|
* this name", so anything else the index declares - an expression, a predicate, uniqueness, an access
|
|
5
|
-
* method, stored columns, a stored order - has to be written out as `@Index
|
|
5
|
+
* method, stored columns, a stored order - has to be written out as an `@Index` instead.
|
|
6
6
|
*/
|
|
7
7
|
export declare function isPlainFieldIndex(index: IndexNode): boolean;
|
|
8
8
|
/**
|
|
9
|
-
* One `@Index([...])` as source, for an index no `@Field` can express
|
|
10
|
-
* expression entry, so callers import `raw` when
|
|
9
|
+
* One `@Index((user) => [...])` as source, for an index no `@Field` can express, its columns read off the
|
|
10
|
+
* key map `param` names. Emits `raw(...)` for an expression entry, so callers import `raw` when
|
|
11
|
+
* {@link indexNeedsRaw} holds.
|
|
11
12
|
*/
|
|
12
|
-
export declare function buildIndexDecoratorSource(index: IndexNode, propertyName: (column: string) => string): string;
|
|
13
|
+
export declare function buildIndexDecoratorSource(index: IndexNode, propertyName: (column: string) => string, param: string): string;
|
|
13
14
|
/** Whether emitting this index needs `raw` imported alongside `Index`. */
|
|
14
15
|
export declare function indexNeedsRaw(index: IndexNode): boolean;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { rawTag } from './sourceLiteral.js';
|
|
1
|
+
import { isIdentifierName, quoted, rawTag } from './sourceLiteral.js';
|
|
2
2
|
/**
|
|
3
3
|
* A vector index carries its metric in the operator class pgvector names after it
|
|
4
4
|
* (`vector_cosine_ops`), which is the only place introspection can recover it from. `@Index` requires
|
|
@@ -37,7 +37,7 @@ function significantModifiers(entry) {
|
|
|
37
37
|
/**
|
|
38
38
|
* Whether `@Field({ index })` can carry the whole index. It says only "this column is indexed under
|
|
39
39
|
* this name", so anything else the index declares - an expression, a predicate, uniqueness, an access
|
|
40
|
-
* method, stored columns, a stored order - has to be written out as `@Index
|
|
40
|
+
* method, stored columns, a stored order - has to be written out as an `@Index` instead.
|
|
41
41
|
*/
|
|
42
42
|
export function isPlainFieldIndex(index) {
|
|
43
43
|
const entries = index.entries;
|
|
@@ -53,11 +53,12 @@ export function isPlainFieldIndex(index) {
|
|
|
53
53
|
significantModifiers(entry).length === 0);
|
|
54
54
|
}
|
|
55
55
|
/**
|
|
56
|
-
* One `@Index([...])` as source, for an index no `@Field` can express
|
|
57
|
-
* expression entry, so callers import `raw` when
|
|
56
|
+
* One `@Index((user) => [...])` as source, for an index no `@Field` can express, its columns read off the
|
|
57
|
+
* key map `param` names. Emits `raw(...)` for an expression entry, so callers import `raw` when
|
|
58
|
+
* {@link indexNeedsRaw} holds.
|
|
58
59
|
*/
|
|
59
|
-
export function buildIndexDecoratorSource(index, propertyName) {
|
|
60
|
-
const entries = index.entries.map((entry) => indexEntrySource(entry, propertyName)).join(', ');
|
|
60
|
+
export function buildIndexDecoratorSource(index, propertyName, param) {
|
|
61
|
+
const entries = index.entries.map((entry) => indexEntrySource(entry, propertyName, param)).join(', ');
|
|
61
62
|
const isVector = index.type === 'hnsw' || index.type === 'ivfflat';
|
|
62
63
|
const distance = isVector ? vectorDistance(index) : undefined;
|
|
63
64
|
const options = [];
|
|
@@ -77,21 +78,24 @@ export function buildIndexDecoratorSource(index, propertyName) {
|
|
|
77
78
|
if (index.where)
|
|
78
79
|
options.push(`where: ${rawTag(index.where)}`);
|
|
79
80
|
if (index.include?.length) {
|
|
80
|
-
|
|
81
|
+
const included = index.include.map((column) => memberSource(param, propertyName(column)));
|
|
82
|
+
options.push(`include: (${param}) => [${included.join(', ')}]`);
|
|
81
83
|
}
|
|
82
|
-
return `@Index([${entries}]${options.length > 0 ? `, { ${options.join(', ')} }` : ''})`;
|
|
84
|
+
return `@Index((${param}) => [${entries}]${options.length > 0 ? `, { ${options.join(', ')} }` : ''})`;
|
|
83
85
|
}
|
|
84
86
|
/** Whether emitting this index needs `raw` imported alongside `Index`. */
|
|
85
87
|
export function indexNeedsRaw(index) {
|
|
86
88
|
return Boolean(index.where) || index.entries.some((entry) => entry.expression);
|
|
87
89
|
}
|
|
88
|
-
function indexEntrySource(entry, propertyName) {
|
|
90
|
+
function indexEntrySource(entry, propertyName, param) {
|
|
89
91
|
if (entry.expression) {
|
|
90
92
|
return rawTag(entry.column);
|
|
91
93
|
}
|
|
94
|
+
const column = memberSource(param, propertyName(entry.column));
|
|
92
95
|
const modifiers = significantModifiers(entry);
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
96
|
+
return modifiers.length === 0 ? column : `{ column: ${column}, ${modifiers.join(', ')} }`;
|
|
97
|
+
}
|
|
98
|
+
/** `user.email`, or `user['first-name']` for a property name that is no identifier. */
|
|
99
|
+
function memberSource(param, property) {
|
|
100
|
+
return isIdentifierName(property) ? `${param}.${property}` : `${param}[${quoted(property)}]`;
|
|
97
101
|
}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
/** Whether `text` can name a property unquoted, in any script: `dueño` can, `first-name` cannot. */
|
|
2
|
+
export declare function isIdentifierName(text: string): boolean;
|
|
1
3
|
/**
|
|
2
4
|
* A string as single-quoted source. Introspected text is arbitrary - a comment or a default
|
|
3
5
|
* expression can hold a quote or a backslash - and only escaping both keeps the generated file
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
/** Whether `text` can name a property unquoted, in any script: `dueño` can, `first-name` cannot. */
|
|
2
|
+
export function isIdentifierName(text) {
|
|
3
|
+
return /^[\p{ID_Start}$_][\p{ID_Continue}$\u200C\u200D]*$/u.test(text);
|
|
4
|
+
}
|
|
1
5
|
/**
|
|
2
6
|
* A string as single-quoted source. Introspected text is arbitrary - a comment or a default
|
|
3
7
|
* expression can hold a quote or a backslash - and only escaping both keeps the generated file
|
|
@@ -2,15 +2,11 @@ import type { AbstractSqlDialect } from '../../dialect/abstractSqlDialect.js';
|
|
|
2
2
|
import { IndexDdl } from './indexDdl.js';
|
|
3
3
|
import { TableDdl } from './tableDdl.js';
|
|
4
4
|
export { IndexDdl } from './indexDdl.js';
|
|
5
|
+
export { MsSqlIndexDdl } from './mssqlIndexDdl.js';
|
|
5
6
|
export { MsSqlTableDdl } from './mssqlTableDdl.js';
|
|
6
7
|
export { MariaIndexDdl, MySqlIndexDdl, MysqlLikeIndexDdl } from './mysqlIndexDdl.js';
|
|
7
8
|
export { CockroachIndexDdl, PgIndexDdl } from './pgIndexDdl.js';
|
|
8
9
|
export { TableDdl } from './tableDdl.js';
|
|
9
|
-
/**
|
|
10
|
-
* The index DDL a dialect gets, most specific first. `instanceof` rather than the `dialectName`
|
|
11
|
-
* {@link tableDdlFor} reads, because each family's index DDL is typed to its dialect and the narrowing
|
|
12
|
-
* is what hands it one. Anything else gets the portable form, which is SQLite's.
|
|
13
|
-
*/
|
|
14
10
|
export declare function indexDdlFor(dialect: AbstractSqlDialect): IndexDdl;
|
|
15
11
|
/**
|
|
16
12
|
* The table DDL a dialect gets: SQL Server's, or the portable form every other engine takes. By
|
|
@@ -1,40 +1,29 @@
|
|
|
1
|
-
import { CockroachDialect } from '../../cockroachdb/cockroachDialect.js';
|
|
2
|
-
import { MysqlLikeSqlDialect } from '../../dialect/mysqlLikeSqlDialect.js';
|
|
3
|
-
import { PgLikeSqlDialect } from '../../dialect/pgLikeSqlDialect.js';
|
|
4
|
-
import { MariaDialect } from '../../maria/mariaDialect.js';
|
|
5
|
-
import { MySqlDialect } from '../../mysql/mysqlDialect.js';
|
|
6
1
|
import { IndexDdl } from './indexDdl.js';
|
|
2
|
+
import { MsSqlIndexDdl } from './mssqlIndexDdl.js';
|
|
7
3
|
import { MsSqlTableDdl } from './mssqlTableDdl.js';
|
|
8
|
-
import { MariaIndexDdl, MySqlIndexDdl
|
|
4
|
+
import { MariaIndexDdl, MySqlIndexDdl } from './mysqlIndexDdl.js';
|
|
9
5
|
import { CockroachIndexDdl, PgIndexDdl } from './pgIndexDdl.js';
|
|
10
6
|
import { TableDdl } from './tableDdl.js';
|
|
11
7
|
export { IndexDdl } from './indexDdl.js';
|
|
8
|
+
export { MsSqlIndexDdl } from './mssqlIndexDdl.js';
|
|
12
9
|
export { MsSqlTableDdl } from './mssqlTableDdl.js';
|
|
13
10
|
export { MariaIndexDdl, MySqlIndexDdl, MysqlLikeIndexDdl } from './mysqlIndexDdl.js';
|
|
14
11
|
export { CockroachIndexDdl, PgIndexDdl } from './pgIndexDdl.js';
|
|
15
12
|
export { TableDdl } from './tableDdl.js';
|
|
16
13
|
/**
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
* is what hands it one. Anything else gets the portable form, which is SQLite's.
|
|
14
|
+
* Each engine's index DDL, by the `dialectName` a subclass inherits: by name, so this entry carries no
|
|
15
|
+
* dialect, and exhaustive, so a new engine has to name its own. SQLite's is the portable form.
|
|
20
16
|
*/
|
|
17
|
+
const INDEX_DDL = {
|
|
18
|
+
postgres: PgIndexDdl,
|
|
19
|
+
cockroachdb: CockroachIndexDdl,
|
|
20
|
+
mysql: MySqlIndexDdl,
|
|
21
|
+
mariadb: MariaIndexDdl,
|
|
22
|
+
mssql: MsSqlIndexDdl,
|
|
23
|
+
sqlite: IndexDdl,
|
|
24
|
+
};
|
|
21
25
|
export function indexDdlFor(dialect) {
|
|
22
|
-
|
|
23
|
-
return new CockroachIndexDdl(dialect);
|
|
24
|
-
}
|
|
25
|
-
if (dialect instanceof PgLikeSqlDialect) {
|
|
26
|
-
return new PgIndexDdl(dialect);
|
|
27
|
-
}
|
|
28
|
-
if (dialect instanceof MySqlDialect) {
|
|
29
|
-
return new MySqlIndexDdl(dialect);
|
|
30
|
-
}
|
|
31
|
-
if (dialect instanceof MariaDialect) {
|
|
32
|
-
return new MariaIndexDdl(dialect);
|
|
33
|
-
}
|
|
34
|
-
if (dialect instanceof MysqlLikeSqlDialect) {
|
|
35
|
-
return new MysqlLikeIndexDdl(dialect);
|
|
36
|
-
}
|
|
37
|
-
return new IndexDdl(dialect);
|
|
26
|
+
return new INDEX_DDL[dialect.dialectName](dialect);
|
|
38
27
|
}
|
|
39
28
|
/**
|
|
40
29
|
* The table DDL a dialect gets: SQL Server's, or the portable form every other engine takes. By
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { AbstractSqlDialect } from '../../dialect/abstractSqlDialect.js';
|
|
2
|
-
import type
|
|
2
|
+
import { type IndexType } from '../../schema/types.js';
|
|
3
3
|
import { type IndexColumnSchema, type IndexFeature, type IndexJsonArray, type IndexSchema } from '../../type/index.js';
|
|
4
4
|
/**
|
|
5
5
|
* `CREATE INDEX` for SQL dialects: the statement and the fragments each engine spells differently.
|
|
@@ -20,6 +20,15 @@ export declare class IndexDdl<D extends AbstractSqlDialect = AbstractSqlDialect>
|
|
|
20
20
|
* emitted: each of them is a hard error at the server, not a slower plan.
|
|
21
21
|
*/
|
|
22
22
|
protected readonly indexFeatures: ReadonlySet<IndexFeature>;
|
|
23
|
+
/**
|
|
24
|
+
* Index types this dialect's `CREATE INDEX` takes. SQLite's grammar has no `USING` clause, so every
|
|
25
|
+
* type builds the plain index it has there, which is what lets an entity written for Postgres
|
|
26
|
+
* migrate unchanged. An engine that would reject a type narrows this, and the type is refused.
|
|
27
|
+
*/
|
|
28
|
+
protected readonly indexTypes: ReadonlySet<IndexType>;
|
|
29
|
+
/** What to declare instead of a type this dialect lacks, appended to its refusal. */
|
|
30
|
+
protected readonly indexTypeHints: ReadonlyMap<IndexType, string>;
|
|
31
|
+
private assertIndexType;
|
|
23
32
|
private assertIndexFeatures;
|
|
24
33
|
/**
|
|
25
34
|
* Index types this dialect spells as a keyword of their own (`FULLTEXT INDEX`, `VECTOR INDEX`)
|
|
@@ -51,7 +60,7 @@ export declare class IndexDdl<D extends AbstractSqlDialect = AbstractSqlDialect>
|
|
|
51
60
|
protected indexInclude(_index: IndexSchema): string;
|
|
52
61
|
/** ` USING <method>`, which SQLite's grammar has no place for at all. */
|
|
53
62
|
protected indexAccessMethod(_index: IndexSchema): string;
|
|
54
|
-
/** pgvector's ` WITH (m =
|
|
63
|
+
/** What trails the columns: pgvector's ` WITH (m = ...)`, MySQL's ` USING btree`, MariaDB's ` M=8`. */
|
|
55
64
|
protected indexTuning(_index: IndexSchema): string;
|
|
56
65
|
/**
|
|
57
66
|
* The partial-index predicate. Engines without one reject the index in {@link assertIndexFeatures}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { jsonTypeMode } from '../../dialect/jsonSql.js';
|
|
2
|
+
import { INDEX_TYPES } from '../../schema/types.js';
|
|
2
3
|
import { INDEX_FEATURE_LABELS, } from '../../type/index.js';
|
|
3
4
|
import { getKeys } from '../../util/index.js';
|
|
4
5
|
/**
|
|
@@ -29,6 +30,7 @@ export class IndexDdl {
|
|
|
29
30
|
this.dialect = dialect;
|
|
30
31
|
}
|
|
31
32
|
getCreateIndexStatement(tableName, index, opts = {}) {
|
|
33
|
+
this.assertIndexType(index);
|
|
32
34
|
this.assertIndexFeatures(index);
|
|
33
35
|
const unique = index.unique ? 'UNIQUE ' : '';
|
|
34
36
|
const ifNotExists = (opts.ifNotExists ?? this.dialect.features.indexIfNotExists) ? 'IF NOT EXISTS ' : '';
|
|
@@ -47,6 +49,20 @@ export class IndexDdl {
|
|
|
47
49
|
'partial',
|
|
48
50
|
'jsonPath',
|
|
49
51
|
]);
|
|
52
|
+
/**
|
|
53
|
+
* Index types this dialect's `CREATE INDEX` takes. SQLite's grammar has no `USING` clause, so every
|
|
54
|
+
* type builds the plain index it has there, which is what lets an entity written for Postgres
|
|
55
|
+
* migrate unchanged. An engine that would reject a type narrows this, and the type is refused.
|
|
56
|
+
*/
|
|
57
|
+
indexTypes = new Set(INDEX_TYPES);
|
|
58
|
+
/** What to declare instead of a type this dialect lacks, appended to its refusal. */
|
|
59
|
+
indexTypeHints = new Map();
|
|
60
|
+
assertIndexType(index) {
|
|
61
|
+
if (index.type && !this.indexTypes.has(index.type)) {
|
|
62
|
+
throw new TypeError(`${this.dialect.dialectName} has no ${index.type} index (index "${index.name}")` +
|
|
63
|
+
(this.indexTypeHints.get(index.type) ?? ''));
|
|
64
|
+
}
|
|
65
|
+
}
|
|
50
66
|
assertIndexFeatures(index) {
|
|
51
67
|
for (const feature of getKeys(INDEX_FEATURE_PROBES)) {
|
|
52
68
|
if (INDEX_FEATURE_PROBES[feature](index) && !this.indexFeatures.has(feature)) {
|
|
@@ -111,7 +127,7 @@ export class IndexDdl {
|
|
|
111
127
|
indexAccessMethod(_index) {
|
|
112
128
|
return '';
|
|
113
129
|
}
|
|
114
|
-
/** pgvector's ` WITH (m =
|
|
130
|
+
/** What trails the columns: pgvector's ` WITH (m = ...)`, MySQL's ` USING btree`, MariaDB's ` M=8`. */
|
|
115
131
|
indexTuning(_index) {
|
|
116
132
|
return '';
|
|
117
133
|
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { IndexDdl } from './indexDdl.js';
|
|
2
|
+
/**
|
|
3
|
+
* SQL Server's `CREATE INDEX` is the portable form minus what 2025 rejects: an expression (Msg 16216),
|
|
4
|
+
* the subquery a JSON path compiles to (Msg 1046), and any type but the plain rowstore B-tree, since
|
|
5
|
+
* the index built in its place fails on a `VECTOR` or `nvarchar(max)` column (Msg 1978).
|
|
6
|
+
*/
|
|
7
|
+
export declare class MsSqlIndexDdl extends IndexDdl {
|
|
8
|
+
protected readonly indexFeatures: Set<"expression" | "include" | "jsonArray" | "jsonPath" | "nullsOrder" | "opsClass" | "partial" | "prefixLength">;
|
|
9
|
+
protected readonly indexTypes: Set<"brin" | "btree" | "fulltext" | "gin" | "gist" | "hash" | "hnsw" | "ivfflat" | "vector" | "vectorSearch">;
|
|
10
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { IndexDdl } from './indexDdl.js';
|
|
2
|
+
/**
|
|
3
|
+
* SQL Server's `CREATE INDEX` is the portable form minus what 2025 rejects: an expression (Msg 16216),
|
|
4
|
+
* the subquery a JSON path compiles to (Msg 1046), and any type but the plain rowstore B-tree, since
|
|
5
|
+
* the index built in its place fails on a `VECTOR` or `nvarchar(max)` column (Msg 1978).
|
|
6
|
+
*/
|
|
7
|
+
export class MsSqlIndexDdl extends IndexDdl {
|
|
8
|
+
indexFeatures = new Set(['partial']);
|
|
9
|
+
indexTypes = new Set(['btree']);
|
|
10
|
+
}
|
|
@@ -1,19 +1,13 @@
|
|
|
1
1
|
import type { IndexType } from '../../schema/types.js';
|
|
2
2
|
import type { IndexJsonArray, IndexSchema } from '../../type/index.js';
|
|
3
3
|
import { IndexDdl } from './indexDdl.js';
|
|
4
|
-
/** `CREATE INDEX ... USING btree`, plus the types this family spells as a keyword instead. */
|
|
4
|
+
/** `CREATE INDEX ... (cols) USING btree`, plus the types this family spells as a keyword instead. */
|
|
5
5
|
export declare class MysqlLikeIndexDdl extends IndexDdl {
|
|
6
6
|
protected readonly indexFeatures: Set<"expression" | "include" | "jsonArray" | "jsonPath" | "nullsOrder" | "opsClass" | "partial" | "prefixLength">;
|
|
7
|
+
protected readonly indexTypes: ReadonlySet<IndexType>;
|
|
7
8
|
protected readonly indexTypeKeywords: ReadonlyMap<IndexType, string>;
|
|
8
|
-
/**
|
|
9
|
-
|
|
10
|
-
* type that is neither is one this engine has no index for at all, refused here rather than
|
|
11
|
-
* compiled into a ` USING hnsw` the server can only answer with a syntax error: which of them a
|
|
12
|
-
* dialect *does* have is `indexTypeKeywords`, so declaring one there is all it takes to serve it.
|
|
13
|
-
*/
|
|
14
|
-
protected indexAccessMethod(index: IndexSchema): string;
|
|
15
|
-
/** What to do instead, appended to the refusal above. */
|
|
16
|
-
protected readonly vectorIndexHint: string;
|
|
9
|
+
/** ` USING btree|hash` trails the columns: between the table and them, it is a syntax error here. */
|
|
10
|
+
protected indexTuning(index: IndexSchema): string;
|
|
17
11
|
}
|
|
18
12
|
export declare class MySqlIndexDdl extends MysqlLikeIndexDdl {
|
|
19
13
|
/** The multi-valued index is the only JSON index MySQL has - see `IndexFeature` for why. */
|
|
@@ -25,12 +19,10 @@ export declare class MySqlIndexDdl extends MysqlLikeIndexDdl {
|
|
|
25
19
|
*/
|
|
26
20
|
protected jsonArrayIndexExpr(escapedColumn: string, json: IndexJsonArray): string;
|
|
27
21
|
/**
|
|
28
|
-
* MySQL has
|
|
29
|
-
*
|
|
30
|
-
* Verified against 26.7, which does have `VECTOR` columns and `STRING_TO_VECTOR`, but no distance
|
|
31
|
-
* function outside HeatWave - hence nothing to index for.
|
|
22
|
+
* MySQL 26.7 has `VECTOR` columns and `STRING_TO_VECTOR`, but no distance function outside
|
|
23
|
+
* HeatWave, hence no vector index to build: `USING hnsw` is a syntax error, `VECTOR INDEX` MariaDB's.
|
|
32
24
|
*/
|
|
33
|
-
protected readonly
|
|
25
|
+
protected readonly indexTypeHints: Map<"brin" | "btree" | "fulltext" | "gin" | "gist" | "hash" | "hnsw" | "ivfflat" | "vector" | "vectorSearch", string>;
|
|
34
26
|
}
|
|
35
27
|
export declare class MariaIndexDdl extends MysqlLikeIndexDdl {
|
|
36
28
|
/**
|
|
@@ -41,12 +33,13 @@ export declare class MariaIndexDdl extends MysqlLikeIndexDdl {
|
|
|
41
33
|
protected readonly indexFeatures: Set<"expression" | "include" | "jsonArray" | "jsonPath" | "nullsOrder" | "opsClass" | "partial" | "prefixLength">;
|
|
42
34
|
/** The family's, plus a vector index of its own: `CREATE VECTOR INDEX ... ON t (col)`, 11.7+. */
|
|
43
35
|
protected readonly indexTypeKeywords: ReadonlyMap<IndexType, string>;
|
|
36
|
+
protected readonly indexTypes: Set<"brin" | "btree" | "fulltext" | "gin" | "gist" | "hash" | "hnsw" | "ivfflat" | "vector" | "vectorSearch">;
|
|
37
|
+
/** pgvector's names are not access methods it has; `vector` is its own keyword above. */
|
|
38
|
+
protected readonly indexTypeHints: Map<"brin" | "btree" | "fulltext" | "gin" | "gist" | "hash" | "hnsw" | "ivfflat" | "vector" | "vectorSearch", string>;
|
|
44
39
|
/**
|
|
45
40
|
* `M=n DISTANCE=metric`, trailing its `CREATE VECTOR INDEX`. The metric names are MariaDB's own
|
|
46
41
|
* (`euclidean`, not `l2`), and an unsupported one throws rather than being dropped, which would
|
|
47
42
|
* silently build the index on euclidean - its default - instead of what the entity asked for.
|
|
48
43
|
*/
|
|
49
44
|
protected indexTuning(index: IndexSchema): string;
|
|
50
|
-
/** `vector` is its own keyword above; pgvector's names are not access methods it has. */
|
|
51
|
-
protected readonly vectorIndexHint = "; declare type: 'vector' instead";
|
|
52
45
|
}
|
|
@@ -1,34 +1,21 @@
|
|
|
1
1
|
import { jsonPath } from '../../dialect/jsonSql.js';
|
|
2
2
|
import { MARIA_VECTOR_METRICS } from '../../maria/mariaVectorMetrics.js';
|
|
3
|
-
import {
|
|
3
|
+
import { unsupportedVectorMetric, VECTOR_INDEX_TYPES } from '../../type/vector.js';
|
|
4
4
|
import { IndexDdl } from './indexDdl.js';
|
|
5
5
|
/**
|
|
6
6
|
* A full-text index is its own keyword here (`CREATE FULLTEXT INDEX ... (cols)`); `USING fulltext` is
|
|
7
7
|
* a syntax error, so it is the keyword that changes rather than the access method.
|
|
8
8
|
*/
|
|
9
9
|
const MYSQL_LIKE_INDEX_KEYWORDS = new Map([['fulltext', 'FULLTEXT INDEX']]);
|
|
10
|
-
/** `CREATE INDEX ... USING btree`, plus the types this family spells as a keyword instead. */
|
|
10
|
+
/** `CREATE INDEX ... (cols) USING btree`, plus the types this family spells as a keyword instead. */
|
|
11
11
|
export class MysqlLikeIndexDdl extends IndexDdl {
|
|
12
12
|
indexFeatures = new Set(['expression', 'prefixLength']);
|
|
13
|
+
indexTypes = new Set(['btree', 'hash', 'fulltext']);
|
|
13
14
|
indexTypeKeywords = MYSQL_LIKE_INDEX_KEYWORDS;
|
|
14
|
-
/**
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
* compiled into a ` USING hnsw` the server can only answer with a syntax error: which of them a
|
|
18
|
-
* dialect *does* have is `indexTypeKeywords`, so declaring one there is all it takes to serve it.
|
|
19
|
-
*/
|
|
20
|
-
indexAccessMethod(index) {
|
|
21
|
-
const type = index.type;
|
|
22
|
-
if (!type || this.indexTypeKeywords.has(type)) {
|
|
23
|
-
return '';
|
|
24
|
-
}
|
|
25
|
-
if (isVectorIndexType(type)) {
|
|
26
|
-
throw new TypeError(`${this.dialect.dialectName} has no ${type} index (index "${index.name}")${this.vectorIndexHint}`);
|
|
27
|
-
}
|
|
28
|
-
return ` USING ${type}`;
|
|
15
|
+
/** ` USING btree|hash` trails the columns: between the table and them, it is a syntax error here. */
|
|
16
|
+
indexTuning(index) {
|
|
17
|
+
return index.type && !this.indexTypeKeywords.has(index.type) ? ` USING ${index.type}` : '';
|
|
29
18
|
}
|
|
30
|
-
/** What to do instead, appended to the refusal above. */
|
|
31
|
-
vectorIndexHint = '';
|
|
32
19
|
}
|
|
33
20
|
export class MySqlIndexDdl extends MysqlLikeIndexDdl {
|
|
34
21
|
/** The multi-valued index is the only JSON index MySQL has - see `IndexFeature` for why. */
|
|
@@ -43,12 +30,10 @@ export class MySqlIndexDdl extends MysqlLikeIndexDdl {
|
|
|
43
30
|
return `CAST(${source} AS ${arrayCastType(json)} ARRAY)`;
|
|
44
31
|
}
|
|
45
32
|
/**
|
|
46
|
-
* MySQL has
|
|
47
|
-
*
|
|
48
|
-
* Verified against 26.7, which does have `VECTOR` columns and `STRING_TO_VECTOR`, but no distance
|
|
49
|
-
* function outside HeatWave - hence nothing to index for.
|
|
33
|
+
* MySQL 26.7 has `VECTOR` columns and `STRING_TO_VECTOR`, but no distance function outside
|
|
34
|
+
* HeatWave, hence no vector index to build: `USING hnsw` is a syntax error, `VECTOR INDEX` MariaDB's.
|
|
50
35
|
*/
|
|
51
|
-
|
|
36
|
+
indexTypeHints = new Map(VECTOR_INDEX_TYPES.map((type) => [type, '. Vector search on MySQL needs HeatWave']));
|
|
52
37
|
}
|
|
53
38
|
export class MariaIndexDdl extends MysqlLikeIndexDdl {
|
|
54
39
|
/**
|
|
@@ -62,13 +47,19 @@ export class MariaIndexDdl extends MysqlLikeIndexDdl {
|
|
|
62
47
|
...MYSQL_LIKE_INDEX_KEYWORDS,
|
|
63
48
|
['vector', 'VECTOR INDEX'],
|
|
64
49
|
]);
|
|
50
|
+
indexTypes = new Set(['btree', 'hash', 'fulltext', 'vector']);
|
|
51
|
+
/** pgvector's names are not access methods it has; `vector` is its own keyword above. */
|
|
52
|
+
indexTypeHints = new Map([
|
|
53
|
+
['hnsw', "; declare type: 'vector' instead"],
|
|
54
|
+
['ivfflat', "; declare type: 'vector' instead"],
|
|
55
|
+
]);
|
|
65
56
|
/**
|
|
66
57
|
* `M=n DISTANCE=metric`, trailing its `CREATE VECTOR INDEX`. The metric names are MariaDB's own
|
|
67
58
|
* (`euclidean`, not `l2`), and an unsupported one throws rather than being dropped, which would
|
|
68
59
|
* silently build the index on euclidean - its default - instead of what the entity asked for.
|
|
69
60
|
*/
|
|
70
61
|
indexTuning(index) {
|
|
71
|
-
let tuning = index.m === undefined ? '' : ` M=${index.m}
|
|
62
|
+
let tuning = super.indexTuning(index) + (index.m === undefined ? '' : ` M=${index.m}`);
|
|
72
63
|
if (index.distance) {
|
|
73
64
|
const metric = MARIA_VECTOR_METRICS.get(index.distance);
|
|
74
65
|
if (!metric) {
|
|
@@ -78,8 +69,6 @@ export class MariaIndexDdl extends MysqlLikeIndexDdl {
|
|
|
78
69
|
}
|
|
79
70
|
return tuning;
|
|
80
71
|
}
|
|
81
|
-
/** `vector` is its own keyword above; pgvector's names are not access methods it has. */
|
|
82
|
-
vectorIndexHint = "; declare type: 'vector' instead";
|
|
83
72
|
}
|
|
84
73
|
/**
|
|
85
74
|
* MySQL's `CAST(... AS <type> ARRAY)` targets, the closed list its multi-valued index takes: no
|
|
@@ -1,16 +1,18 @@
|
|
|
1
|
-
import type { PgLikeSqlDialect } from '../../dialect/pgLikeSqlDialect.js';
|
|
2
1
|
import type { IndexColumnSchema, IndexSchema } from '../../type/index.js';
|
|
3
2
|
import { IndexDdl } from './indexDdl.js';
|
|
4
3
|
/** `CREATE INDEX ... USING hnsw ("embedding" vector_cosine_ops) WITH (m = ...)`, pgvector's form. */
|
|
5
|
-
export declare class PgIndexDdl extends IndexDdl
|
|
4
|
+
export declare class PgIndexDdl extends IndexDdl {
|
|
5
|
+
/** Postgres 18's `pg_am`, with pgvector's two. */
|
|
6
|
+
protected readonly indexTypes: Set<"brin" | "btree" | "fulltext" | "gin" | "gist" | "hash" | "hnsw" | "ivfflat" | "vector" | "vectorSearch">;
|
|
7
|
+
protected readonly indexTypeHints: ReadonlyMap<"brin" | "btree" | "fulltext" | "gin" | "gist" | "hash" | "hnsw" | "ivfflat" | "vector" | "vectorSearch", string>;
|
|
6
8
|
protected readonly indexFeatures: Set<"expression" | "include" | "jsonArray" | "jsonPath" | "nullsOrder" | "opsClass" | "partial" | "prefixLength">;
|
|
9
|
+
/** The metrics its vector index takes, each naming the operator class it is built with. */
|
|
10
|
+
protected readonly vectorMetrics: ReadonlyMap<import("../../type/vector.js").VectorDistance, {
|
|
11
|
+
readonly op: string;
|
|
12
|
+
readonly opsSuffix: string;
|
|
13
|
+
}>;
|
|
7
14
|
/** pgvector's own index types; CockroachDB's native one widens this. */
|
|
8
15
|
protected isVectorIndex(index: IndexSchema): boolean;
|
|
9
|
-
/**
|
|
10
|
-
* ` USING <method>`. `fulltext` is refused rather than compiled into a ` USING fulltext` the server
|
|
11
|
-
* can only answer with a syntax error: `$text` computes its `TO_TSVECTOR` per row, which no index
|
|
12
|
-
* over the raw columns serves.
|
|
13
|
-
*/
|
|
14
16
|
protected indexAccessMethod(index: IndexSchema): string;
|
|
15
17
|
/**
|
|
16
18
|
* A vector index's operator class is named `{type}_{metric}_ops`: an index on a `halfvec` column
|
|
@@ -33,9 +35,17 @@ export declare class PgIndexDdl extends IndexDdl<PgLikeSqlDialect> {
|
|
|
33
35
|
*/
|
|
34
36
|
export declare class CockroachIndexDdl extends PgIndexDdl {
|
|
35
37
|
protected readonly indexFeatures: Set<"expression" | "include" | "jsonArray" | "jsonPath" | "nullsOrder" | "opsClass" | "partial" | "prefixLength">;
|
|
38
|
+
/** v26.3 answers `hash` and `brin` "unimplemented", `ivfflat` "unrecognized"; `hnsw` builds its vector index. */
|
|
39
|
+
protected readonly indexTypes: Set<"brin" | "btree" | "fulltext" | "gin" | "gist" | "hash" | "hnsw" | "ivfflat" | "vector" | "vectorSearch">;
|
|
40
|
+
protected readonly indexTypeHints: Map<"brin" | "btree" | "fulltext" | "gin" | "gist" | "hash" | "hnsw" | "ivfflat" | "vector" | "vectorSearch", string>;
|
|
41
|
+
protected readonly vectorMetrics: ReadonlyMap<import("../../type/vector.js").VectorDistance, {
|
|
42
|
+
readonly op: string;
|
|
43
|
+
readonly opsSuffix: string;
|
|
44
|
+
}>;
|
|
36
45
|
private isNativeVectorIndex;
|
|
37
46
|
protected isVectorIndex(index: IndexSchema): boolean;
|
|
38
47
|
protected indexKeyword(index: IndexSchema): string;
|
|
39
48
|
protected indexAccessMethod(index: IndexSchema): string;
|
|
40
|
-
|
|
49
|
+
/** None of pgvector's knobs: `WITH (m = 16)` answers "invalid storage parameter", `hnsw` included. */
|
|
50
|
+
protected indexTuning(): string;
|
|
41
51
|
}
|