Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add vector support #10789

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/entities.md
Expand Up @@ -393,6 +393,8 @@ or
`tsrange`, `tstzrange`, `daterange`, `int4multirange`, `int8multirange`, `nummultirange`,
`tsmultirange`, `tstzmultirange`, `multidaterange`, `geometry`, `geography`, `cube`, `ltree`

> Note: `vector` is also available when the [pgvector](https://github.com/pgvector/pgvector) extension is supported by the postgres installation. You can follow installation instructions from the link in this note.

### Column types for `cockroachdb`

`array`, `bool`, `boolean`, `bytes`, `bytea`, `blob`, `date`, `numeric`, `decimal`, `dec`, `float`,
Expand Down
26 changes: 26 additions & 0 deletions src/driver/postgres/PostgresDriver.ts
Expand Up @@ -190,6 +190,7 @@ export class PostgresDriver implements Driver {
"geography",
"cube",
"ltree",
"vector",
]

/**
Expand All @@ -213,6 +214,7 @@ export class PostgresDriver implements Driver {
"bit",
"varbit",
"bit varying",
"vector",
]

/**
Expand Down Expand Up @@ -421,6 +423,7 @@ export class PostgresDriver implements Driver {
hasCubeColumns,
hasGeometryColumns,
hasLtreeColumns,
hasVectorColumns,
hasExclusionConstraints,
} = extensionsMetadata

Expand Down Expand Up @@ -500,6 +503,18 @@ export class PostgresDriver implements Driver {
"At least one of the entities has a ltree column, but the 'ltree' extension cannot be installed automatically. Please install it manually using superuser rights",
)
}
if (hasVectorColumns)
try {
await this.executeQuery(
connection,
`CREATE EXTENSION IF NOT EXISTS "vector"`,
)
} catch (_) {
logger.log(
"warn",
"At least one of the entities has a vector column, but the 'vector' extension cannot be installed automatically. Please install it manually using superuser rights",
)
}
if (hasExclusionConstraints)
try {
// The btree_gist extension provides operator support in PostgreSQL exclusion constraints
Expand Down Expand Up @@ -568,6 +583,15 @@ export class PostgresDriver implements Driver {
)
},
)
const hasVectorColumns = this.connection.entityMetadatas.some(
(metadata) => {
return (
metadata.columns.filter(
(column) => column.type === "vector",
).length > 0
)
},
)
const hasExclusionConstraints = this.connection.entityMetadatas.some(
(metadata) => {
return metadata.exclusions.length > 0
Expand All @@ -581,6 +605,7 @@ export class PostgresDriver implements Driver {
hasCubeColumns,
hasGeometryColumns,
hasLtreeColumns,
hasVectorColumns,
hasExclusionConstraints,
hasExtensions:
hasUuidColumns ||
Expand All @@ -589,6 +614,7 @@ export class PostgresDriver implements Driver {
hasGeometryColumns ||
hasCubeColumns ||
hasLtreeColumns ||
hasVectorColumns ||
hasExclusionConstraints,
}
}
Expand Down
39 changes: 33 additions & 6 deletions src/driver/postgres/PostgresQueryRunner.ts
Expand Up @@ -601,10 +601,22 @@ export class PostgresQueryRunner
downQueries.push(this.dropIndexSql(table, index))
})
}
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These were changed by npm run format


if (table.comment) {
upQueries.push(new Query("COMMENT ON TABLE " + this.escapePath(table) + " IS '" + table.comment + "'"));
downQueries.push(new Query("COMMENT ON TABLE " + this.escapePath(table) + " IS NULL"));
upQueries.push(
new Query(
"COMMENT ON TABLE " +
this.escapePath(table) +
" IS '" +
table.comment +
"'",
),
)
downQueries.push(
new Query(
"COMMENT ON TABLE " + this.escapePath(table) + " IS NULL",
),
)
}

await this.executeQueries(upQueries, downQueries)
Expand Down Expand Up @@ -3542,8 +3554,9 @@ export class PostgresQueryRunner
// check if column has user-defined data type.
// NOTE: if ENUM type defined with "array:true" it comes with ARRAY type instead of USER-DEFINED
if (
dbColumn["data_type"] === "USER-DEFINED" ||
dbColumn["data_type"] === "ARRAY"
(dbColumn["data_type"] === "USER-DEFINED" ||
dbColumn["data_type"] === "ARRAY") &&
dbColumn["udt_name"] !== "vector"
) {
const { name } =
await this.getUserDefinedTypeName(
Expand Down Expand Up @@ -3595,6 +3608,20 @@ export class PostgresQueryRunner
}
}

if (
dbColumn["data_type"] === "USER-DEFINED" &&
tableColumn.type === "vector"
) {
// vector length is from the format_type e.g. `format_type = vector(n)`
const match = /vector\((\d+)\)/.exec(
dbColumn["format_type"],
)

if (match) {
tableColumn.length = match[1]
}
}

if (
tableColumn.type === "geometry" ||
tableColumn.type === "geography"
Expand Down Expand Up @@ -4744,7 +4771,7 @@ export class PostgresQueryRunner

newComment = this.escapeComment(newComment)
const comment = this.escapeComment(table.comment)

if (newComment === comment) {
return
}
Expand Down
1 change: 1 addition & 0 deletions src/driver/types/ColumnTypes.ts
Expand Up @@ -75,6 +75,7 @@ export type WithLengthColumnType =
| "binary" // mssql
| "varbinary" // mssql, sap
| "string" // cockroachdb, spanner
| "vector" // postgres pgvector

export type WithWidthColumnType =
| "tinyint" // mysql
Expand Down
6 changes: 2 additions & 4 deletions src/query-builder/InsertQueryBuilder.ts
Expand Up @@ -459,10 +459,8 @@ export class InsertQueryBuilder<
// add VALUES expression
if (valuesExpression) {
if (
(
this.connection.driver.options.type === "oracle" ||
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These were changed by npm run format

this.connection.driver.options.type === "sap"
) &&
(this.connection.driver.options.type === "oracle" ||
this.connection.driver.options.type === "sap") &&
this.getValueSets().length > 1
) {
query += ` ${valuesExpression}`
Expand Down
5 changes: 4 additions & 1 deletion src/query-builder/QueryBuilder.ts
Expand Up @@ -522,7 +522,10 @@ export abstract class QueryBuilder<Entity extends ObjectLiteral> {
* Uses same query runner as current QueryBuilder.
*/
createQueryBuilder(queryRunner?: QueryRunner): this {
return new (this.constructor as any)(this.connection, queryRunner ?? this.queryRunner)
return new (this.constructor as any)(
this.connection,
queryRunner ?? this.queryRunner,
)
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/schema-builder/RdbmsSchemaBuilder.ts
Expand Up @@ -604,7 +604,7 @@ export class RdbmsSchemaBuilder implements SchemaBuilder {

if (
DriverUtils.isMySQLFamily(this.connection.driver) ||
this.connection.driver.options.type === 'postgres'
this.connection.driver.options.type === "postgres"
) {
const newComment = metadata.comment
await this.queryRunner.changeTableComment(table, newComment)
Expand Down
13 changes: 13 additions & 0 deletions test/github-issues/10056/entity/message.ts
@@ -0,0 +1,13 @@
import { Column, Entity, PrimaryGeneratedColumn } from "../../../../src"

@Entity({
name: "message",
})
export class Message {
@PrimaryGeneratedColumn()
id: number

// create a vector embedding with 5 dimensions
@Column("vector", { length: 5 })
embedding: string
}