fix: extend GiST index with range types for Postgres driver (#10572)

* fix: extend spatial column types for postgres driver

Extend spatial column type with range types for postgres. This fixes a bug when using spatial indices.

Closes: #10567

* format

* remove only from test, ready for pr

* changed a way how we determine index type

---------

Co-authored-by: Dmitry Zotov <dmzt08@gmail.com>
This commit is contained in:
Joren Vandeweyer 2023-12-29 15:09:30 +01:00 committed by GitHub
parent 72b1d1b865
commit a4900ae15f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 99 additions and 7 deletions

View File

@ -3311,13 +3311,14 @@ export class PostgresQueryRunner
const indicesSql =
`SELECT "ns"."nspname" AS "table_schema", "t"."relname" AS "table_name", "i"."relname" AS "constraint_name", "a"."attname" AS "column_name", ` +
`CASE "ix"."indisunique" WHEN 't' THEN 'TRUE' ELSE'FALSE' END AS "is_unique", pg_get_expr("ix"."indpred", "ix"."indrelid") AS "condition", ` +
`"types"."typname" AS "type_name" ` +
`"types"."typname" AS "type_name", "am"."amname" AS "index_type" ` +
`FROM "pg_class" "t" ` +
`INNER JOIN "pg_index" "ix" ON "ix"."indrelid" = "t"."oid" ` +
`INNER JOIN "pg_attribute" "a" ON "a"."attrelid" = "t"."oid" AND "a"."attnum" = ANY ("ix"."indkey") ` +
`INNER JOIN "pg_namespace" "ns" ON "ns"."oid" = "t"."relnamespace" ` +
`INNER JOIN "pg_class" "i" ON "i"."oid" = "ix"."indexrelid" ` +
`INNER JOIN "pg_type" "types" ON "types"."oid" = "a"."atttypid" ` +
`INNER JOIN "pg_am" "am" ON "i"."relam" = "am"."oid" ` +
`LEFT JOIN "pg_constraint" "cnst" ON "cnst"."conname" = "i"."relname" ` +
`WHERE "t"."relkind" IN ('r', 'p') AND "cnst"."contype" IS NULL AND (${constraintsCondition})`
@ -3939,12 +3940,7 @@ export class PostgresQueryRunner
columnNames: indices.map((i) => i["column_name"]),
isUnique: constraint["is_unique"] === "TRUE",
where: constraint["condition"],
isSpatial: indices.every(
(i) =>
this.driver.spatialTypes.indexOf(
i["type_name"],
) >= 0,
),
isSpatial: constraint["index_type"] === "gist",
isFulltext: false,
})
})

View File

@ -0,0 +1,48 @@
import { Column, Entity, Index, PrimaryGeneratedColumn } from "../../../../src"
@Entity()
export class AddressHistory {
@PrimaryGeneratedColumn("uuid")
uuid: string
@Index()
@Column({ type: "uuid" })
entityUuid: string
@Index()
@Column({ type: "uuid" })
addressUuid: string
@Index({ spatial: true })
@Column({ type: "int4range" })
int4range: string
@Index({ spatial: true })
@Column({ type: "int8range" })
int8range: string
@Index({ spatial: true })
@Column({ type: "numrange" })
numrange: string
@Index({ spatial: true })
@Column({ type: "tsrange" })
tsrange: string
@Index({ spatial: true })
@Column({ type: "tstzrange" })
tstzrange: string
@Index({ spatial: true })
@Column({ type: "daterange" })
daterange: string
@Index({ spatial: true })
@Column({
type: "geometry",
spatialFeatureType: "Point",
srid: 4326,
nullable: true,
})
point: string
}

View File

@ -0,0 +1,48 @@
import "reflect-metadata"
import {
createTestingConnections,
closeTestingConnections,
} from "../../utils/test-utils"
import { DataSource } from "../../../src/index.js"
describe("github issues > #10567 Postgres: Gist index on daterange column recreated every migration", () => {
let dataSources: DataSource[]
before(
async () =>
(dataSources = await createTestingConnections({
entities: [__dirname + "/entity/*{.js,.ts}"],
schemaCreate: false,
dropSchema: true,
enabledDrivers: ["postgres"],
})),
)
after(() => closeTestingConnections(dataSources))
it("can recognize model changes", () =>
Promise.all(
dataSources.map(async (dataSource) => {
const sqlInMemory = await dataSource.driver
.createSchemaBuilder()
.log()
sqlInMemory.upQueries.length.should.be.greaterThan(0)
sqlInMemory.downQueries.length.should.be.greaterThan(0)
}),
))
it("does not generate when no model changes", () =>
Promise.all(
dataSources.map(async (dataSource) => {
await dataSource.driver.createSchemaBuilder().build()
const sqlInMemory = await dataSource.driver
.createSchemaBuilder()
.log()
sqlInMemory.upQueries.length.should.be.equal(0)
sqlInMemory.downQueries.length.should.be.equal(0)
}),
))
})