-
-
Notifications
You must be signed in to change notification settings - Fork 6.5k
feat(postgres): add support for PostgreSQL indices #11318
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
feat(postgres): add support for PostgreSQL indices #11318
Conversation
|
Awesome works guys! Can't wait for this to land as I'd love to be able to declare full-text search indices in TypeORM! |
| @Entity() | ||
| export class User { | ||
| @PrimaryGeneratedColumn('uuid') | ||
| @Index({type: 'hash'}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you please add the columns for other types of indexes in this test?
|
I would also add a test to see what happens with adding an index to unsupported DB |
Thanks for pointing that out!
I also improved the test cases based on your comments. |
OSA413
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a few questions, why gist is spatial, what is spatial, and why we fall back into btree in the compare method in PostgresDriver.ts?
|
@OSA413 Apparently, some tests were failing because I created a test that didn't properly check whether the SQLite driver was selected. I'm still new to this project, and I'm just trying to improve it! I hope you understand my newbie mistakes 😅 .
With this PR, I didn't intend to introduce breaking changes. Currently, in (typeorm:master), when an index has the A Gist index is used for 2D geometric data types, which is where "spatial" comes from.
|
gioboa
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@freePixel can you resolve the conflict please?
WalkthroughAdds a PostgreSQL-specific optional index Changes
Sequence Diagram(s)sequenceDiagram
participant U as User code / Decorator
participant M as MetadataStorage
participant SB as RdbmsSchemaBuilder
participant D as Driver
participant DB as Database
U->>M: declare indices (may include `type`)
M-->>SB: provide IndexMetadata (with optional `type`)
SB->>D: isIndicesTypeSupported()?
alt Driver supports types (Postgres)
D-->>SB: true
SB->>D: compareTableIndexTypes?(existing, desired)
D-->>SB: match / mismatch
SB->>D: CREATE INDEX ... USING <type> (via buildIndexTypeClause)
D->>DB: execute SQL with USING clause
DB-->>D: success
else Driver does NOT support types
D-->>SB: false
alt desired index has `type`
SB-->>U: throw TypeORMError("driver does not support index 'type' property")
else
SB->>D: CREATE INDEX (no USING clause)
D->>DB: execute SQL
DB-->>D: success
end
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes
Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Nitpick comments (15)
src/driver/react-native/ReactNativeDriver.ts (1)
898-903: Minor: Consider clarifying JSDoc wording.The JSDoc says "supports type indices" but "index types" might be more grammatically precise and consistent with the feature name.
/** - * Returns true if driver supports type indices + * Returns true if driver supports index types */ isIndicesTypeSupported(): boolean { return false }src/driver/mongodb/MongoDriver.ts (1)
486-491: Minor: Consider clarifying JSDoc wording.The JSDoc says "supports type indices" but "index types" might be more grammatically precise and consistent with the feature name.
/** - * Returns true if driver supports type indices + * Returns true if driver supports index types */ isIndicesTypeSupported(): boolean { return false }docs/docs/advanced-topics/3-indices.md (1)
147-155: Optional: Consider enhancing the documentation example.The documentation is clear, but the example could be more comprehensive by showing:
- All available index types (btree, hash, gist, spgist, gin, brin)
- Usage with column names for multi-column indices
- Combination with other options like
uniqueorconcurrent## Index Type If you need to specify a custom type for the index, you can use the `type` property. If the `spatial` property is set, this field will be ignored. ```typescript +// Single column with index type @Index({ type: 'hash' }) +@Column() +email: string + +// Multi-column index with type +@Index(['firstName', 'lastName'], { type: 'btree' }) + +// Available types: 'btree', 'hash', 'gist', 'spgist', 'gin', 'brin'This feature is currently supported only for PostgreSQL.
</blockquote></details> <details> <summary>src/driver/oracle/OracleDriver.ts (1)</summary><blockquote> `945-950`: **Minor: Consider clarifying JSDoc wording.** The JSDoc says "supports type indices" but "index types" might be more grammatically precise and consistent with the feature name. ```diff /** - * Returns true if driver supports type indices + * Returns true if driver supports index types */ isIndicesTypeSupported(): boolean { return false }src/driver/sqlserver/SqlServerDriver.ts (1)
940-945: Minor: Consider clarifying JSDoc wording.The JSDoc says "supports type indices" but "index types" might be more grammatically precise and consistent with the feature name.
/** - * Returns true if driver supports type indices + * Returns true if driver supports index types */ isIndicesTypeSupported(): boolean { return false }src/driver/cockroachdb/CockroachDriver.ts (1)
981-986: Minor: Consider clarifying JSDoc wording.The JSDoc says "supports type indices" but "index types" might be more grammatically precise and consistent with the feature name.
/** - * Returns true if driver supports type indices + * Returns true if driver supports index types */ isIndicesTypeSupported(): boolean { return false }src/driver/spanner/SpannerDriver.ts (1)
713-718: Minor: Consider clarifying JSDoc wording.The JSDoc says "supports type indices" but "index types" might be more grammatically precise and consistent with the feature name.
/** - * Returns true if driver supports type indices + * Returns true if driver supports index types */ isIndicesTypeSupported(): boolean { return false }src/decorator/options/IndexOptions.ts (1)
69-74: Clarify documented literals fortypeto matchTableIndexTypesThe new
type?: TableIndexTypesoption and PostgreSQL-only note look good. To reduce ambiguity, consider mentioning the actual string literals ("btree","hash","gist","spgist","gin","brin") in the comment so it’s obvious that values are lowercase and matchTableIndexTypes.src/driver/mysql/MysqlDriver.ts (1)
1166-1171: MySQL index-type capability correctly disabled; tweak comment wordingReturning
falsefromisIndicesTypeSupported()is appropriate so MySQL is excluded from PostgreSQL-style index types and can be gated centrally. You might optionally rephrase the comment to “Returns true if driver supports index types” for slightly clearer wording.src/metadata-args/IndexMetadataArgs.ts (1)
89-94: Aligntypedocumentation with concrete string valuesThe new
type?: TableIndexTypesfield and PostgreSQL-only note are appropriate. As a small clarity improvement, consider explicitly listing the accepted lowercase string values ("btree","hash","gist","spgist","gin","brin") so consumers don’t have to look upTableIndexTypesto know the valid inputs.src/driver/sap/SapDriver.ts (1)
862-867: SAP HANA: index-type capability correctly marked unsupportedHaving
isIndicesTypeSupported()returnfalseis consistent with this driver’s current feature set and lets schema-building logic uniformly gate use of thetypeoption. As with the MySQL driver, you might optionally rename the comment to “supports index types” for slightly clearer phrasing.src/schema-builder/RdbmsSchemaBuilder.ts (1)
1016-1026: Good guard for unsupported drivers; consider tightening the check slightlyThe preflight in
createNewIndicescleanly prevents creating indices withtypeon drivers that do not support index types, which matches the new error behavior indropOldIndices.Two small polish suggestions:
- Use
.someto clarify intent (boolean existence check rather than retrieving the first element):- if ( - newIndices.find( - (idx) => - !!idx.type && - !this.connection.driver.isIndicesTypeSupported(), - ) - ) { + if ( + newIndices.some( + (idx) => + idx.type && + !this.connection.driver.isIndicesTypeSupported(), + ) + ) {
- Optionally mention the index name in the error message to help users pinpoint the offending index.
Both are non-blocking; current logic is functionally correct.
src/driver/postgres/PostgresDriver.ts (1)
31-32: Index type support and comparison logic for Postgres look solidThe
isIndicesTypeSupported()flag andcompareTableIndexTypesimplementation are consistent with Postgres semantics:
- Defaulting missing types to
"btree"aligns with PostgreSQL’s default index method.- Treating
isSpatialas"gist"preserves legacy behavior while still allowing explicittype: "gist".- Case-insensitive comparison correctly handles any casing from metadata or introspection.
You might optionally tweak the JSDoc to say “index types” instead of “type indices,” but behavior-wise this is ready to go.
Also applies to: 1444-1449, 1464-1469
src/metadata/IndexMetadata.ts (1)
7-8:typemetadata wiring is correct; consider updating theisSpatialcommentThe new
type?: TableIndexTypesfield and its propagation in the constructor integrate cleanly with the rest of the schema/index pipeline, and the change:this.isSpatial = !!options.args.spatial || options.args.type === "gist"nicely ensures that
@Index({ type: "gist" })behaves as a spatial index as expected in Postgres.One minor nit: the JSDoc above
isSpatialstill says “Works only in MySQL.” Given this new behavior, it would be clearer to mention thatisSpatialis also used to drive GiST index handling in Postgres.Also applies to: 123-129, 158-160, 170-171
src/driver/postgres/PostgresQueryRunner.ts (1)
4349-4373: MakebuildIndexTypeClausemore robust and slightly clearerThe helper is a good place to centralize validation and prevent index‑type injection. A couple of small tweaks would make it more ergonomic and defensive:
- Treat index types case‑insensitively (so
"GiST"etc. don’t fail even if passed from JS consumers).- Include the offending type in the error message for easier debugging.
- Minor: use
constfor theSetand avoid reusing thetypevariable name for the normalized form.For example:
- private buildIndexTypeClause(index: TableIndex) { - // List of index types supported by PostgreSQL - // https://www.postgresql.org/docs/current/indexes-types.html - let pgValidIdxTypes = new Set<string>([ - "btree", - "hash", - "gist", - "spgist", - "gin", - "brin", - ]) - - let type = index.isSpatial ? "gist" : index.type - - if (typeof type !== "string") return null - - if (!pgValidIdxTypes.has(type)) - throw new TypeORMError(`Unsupported index type`) - - return `USING ${type}` - } + private buildIndexTypeClause(index: TableIndex) { + // List of index types supported by PostgreSQL + // https://www.postgresql.org/docs/current/indexes-types.html + const pgValidIdxTypes = new Set<string>([ + "btree", + "hash", + "gist", + "spgist", + "gin", + "brin", + ]) + + const rawType = index.isSpatial ? "gist" : index.type + if (typeof rawType !== "string") return null + + const type = rawType.toLowerCase() + + if (!pgValidIdxTypes.has(type)) { + throw new TypeORMError( + `Unsupported index type "${rawType}" for PostgreSQL`, + ) + } + + return `USING ${type}` + }You might also consider reusing
buildIndexTypeClausefromcreateViewIndexSqlin a follow‑up if you decide to support explicit types on view indices as well.Also applies to: 4379-4389
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (26)
docs/docs/advanced-topics/3-indices.md(1 hunks)src/decorator/Index.ts(1 hunks)src/decorator/options/IndexOptions.ts(2 hunks)src/driver/Driver.ts(2 hunks)src/driver/aurora-mysql/AuroraMysqlDriver.ts(1 hunks)src/driver/cockroachdb/CockroachDriver.ts(1 hunks)src/driver/mongodb/MongoDriver.ts(1 hunks)src/driver/mysql/MysqlDriver.ts(1 hunks)src/driver/oracle/OracleDriver.ts(1 hunks)src/driver/postgres/PostgresDriver.ts(3 hunks)src/driver/postgres/PostgresQueryRunner.ts(2 hunks)src/driver/react-native/ReactNativeDriver.ts(1 hunks)src/driver/sap/SapDriver.ts(1 hunks)src/driver/spanner/SpannerDriver.ts(1 hunks)src/driver/sqlite-abstract/AbstractSqliteDriver.ts(1 hunks)src/driver/sqlserver/SqlServerDriver.ts(1 hunks)src/metadata-args/IndexMetadataArgs.ts(2 hunks)src/metadata/IndexMetadata.ts(4 hunks)src/schema-builder/RdbmsSchemaBuilder.ts(3 hunks)src/schema-builder/options/TableIndexOptions.ts(2 hunks)src/schema-builder/options/TableIndexTypes.ts(1 hunks)src/schema-builder/table/TableIndex.ts(5 hunks)test/functional/indices/index-types/entity/User.ts(1 hunks)test/functional/indices/index-types/entity/User2.ts(1 hunks)test/functional/indices/index-types/entity/User3.ts(1 hunks)test/functional/indices/index-types/index-types.ts(1 hunks)
🧰 Additional context used
🧠 Learnings (6)
📓 Common learnings
Learnt from: alumni
Repo: typeorm/typeorm PR: 11581
File: docs/docs/drivers/postgres.md:23-23
Timestamp: 2025-07-27T20:50:10.364Z
Learning: The correct data source type for Aurora PostgreSQL in TypeORM is `aurora-postgres`, not `aurora-data-api-pg`. The `aurora-data-api-pg` driver was renamed to `aurora-postgres` according to the CHANGELOG.md. This is defined in the DatabaseType union type and AuroraPostgresConnectionOptions interface.
📚 Learning: 2025-10-16T19:19:25.146Z
Learnt from: ZBAGI
Repo: typeorm/typeorm PR: 11724
File: test/functional/schema-builder/entity/react-native/Post.ts:0-0
Timestamp: 2025-10-16T19:19:25.146Z
Learning: In TypeORM tests, react-native uses SQLite as its underlying database, not MySQL or MariaDB. SQLite treats double quotes as identifier quotes, making them appropriate for CHECK constraints and other SQL expressions in react-native entity files.
Applied to files:
test/functional/indices/index-types/index-types.ts
📚 Learning: 2025-07-27T20:50:10.364Z
Learnt from: alumni
Repo: typeorm/typeorm PR: 11581
File: docs/docs/drivers/postgres.md:23-23
Timestamp: 2025-07-27T20:50:10.364Z
Learning: The correct data source type for Aurora PostgreSQL in TypeORM is `aurora-postgres`, not `aurora-data-api-pg`. The `aurora-data-api-pg` driver was renamed to `aurora-postgres` according to the CHANGELOG.md. This is defined in the DatabaseType union type and AuroraPostgresConnectionOptions interface.
Applied to files:
src/driver/aurora-mysql/AuroraMysqlDriver.tssrc/driver/postgres/PostgresDriver.tssrc/driver/postgres/PostgresQueryRunner.tssrc/schema-builder/RdbmsSchemaBuilder.ts
📚 Learning: 2025-08-16T18:51:14.170Z
Learnt from: alumni
Repo: typeorm/typeorm PR: 11576
File: src/data-source/DataSource.ts:542-546
Timestamp: 2025-08-16T18:51:14.170Z
Learning: When improving type safety in TypeORM's query execution chain, adding generics to the QueryRunner.query method allows for proper type propagation from DataSource.query<T> through to QueryResult<T>, eliminating the need for type casts like 'as any' and 'as T'.
Applied to files:
src/driver/postgres/PostgresQueryRunner.ts
📚 Learning: 2025-07-27T17:29:18.547Z
Learnt from: alumni
Repo: typeorm/typeorm PR: 11581
File: docs/docs/drivers/mongodb.md:9-13
Timestamp: 2025-07-27T17:29:18.547Z
Learning: TypeORM supports MongoDB driver versions "^5.8.0 || ^6.0.0" according to the peerDependencies in package.json. The v4 driver is NOT supported. Always check package.json for accurate peer dependency information.
Applied to files:
src/driver/mongodb/MongoDriver.ts
📚 Learning: 2025-07-27T17:29:18.547Z
Learnt from: alumni
Repo: typeorm/typeorm PR: 11581
File: docs/docs/drivers/mongodb.md:9-13
Timestamp: 2025-07-27T17:29:18.547Z
Learning: TypeORM is compatible only with mongodb@^6, not v4 as previously suggested. The package.json file contains the authoritative peer dependency information for the MongoDB driver version compatibility.
Applied to files:
src/schema-builder/RdbmsSchemaBuilder.ts
🧬 Code graph analysis (13)
test/functional/indices/index-types/index-types.ts (2)
test/utils/test-utils.ts (3)
createTestingConnections(388-482)reloadTestingDatabases(504-509)closeTestingConnections(487-499)src/error/TypeORMError.ts (1)
TypeORMError(1-17)
src/schema-builder/options/TableIndexOptions.ts (1)
src/schema-builder/options/TableIndexTypes.ts (1)
TableIndexTypes(1-7)
test/functional/indices/index-types/entity/User2.ts (3)
test/functional/indices/index-types/entity/User.ts (1)
Entity(8-36)src/decorator/columns/PrimaryGeneratedColumn.ts (1)
PrimaryGeneratedColumn(55-119)src/decorator/columns/Column.ts (1)
Column(134-220)
test/functional/indices/index-types/entity/User3.ts (1)
src/decorator/columns/PrimaryGeneratedColumn.ts (1)
PrimaryGeneratedColumn(55-119)
src/driver/postgres/PostgresDriver.ts (2)
src/metadata/IndexMetadata.ts (1)
IndexMetadata(12-281)src/schema-builder/table/TableIndex.ts (1)
TableIndex(8-137)
src/metadata/IndexMetadata.ts (1)
src/schema-builder/options/TableIndexTypes.ts (1)
TableIndexTypes(1-7)
src/driver/Driver.ts (2)
src/metadata/IndexMetadata.ts (1)
IndexMetadata(12-281)src/schema-builder/table/TableIndex.ts (1)
TableIndex(8-137)
src/driver/postgres/PostgresQueryRunner.ts (3)
src/schema-builder/table/TableIndex.ts (1)
TableIndex(8-137)src/error/TypeORMError.ts (1)
TypeORMError(1-17)src/driver/Query.ts (1)
Query(4-8)
src/schema-builder/table/TableIndex.ts (1)
src/schema-builder/options/TableIndexTypes.ts (1)
TableIndexTypes(1-7)
test/functional/indices/index-types/entity/User.ts (3)
test/functional/indices/index-types/entity/User2.ts (1)
Entity(8-16)src/decorator/columns/PrimaryGeneratedColumn.ts (1)
PrimaryGeneratedColumn(55-119)src/decorator/columns/Column.ts (1)
Column(134-220)
src/metadata-args/IndexMetadataArgs.ts (1)
src/schema-builder/options/TableIndexTypes.ts (1)
TableIndexTypes(1-7)
src/schema-builder/RdbmsSchemaBuilder.ts (1)
src/error/TypeORMError.ts (1)
TypeORMError(1-17)
src/decorator/options/IndexOptions.ts (1)
src/schema-builder/options/TableIndexTypes.ts (1)
TableIndexTypes(1-7)
🔇 Additional comments (14)
src/schema-builder/options/TableIndexTypes.ts (1)
1-7: LGTM! Clean type definition for PostgreSQL index types.The type union correctly includes all major PostgreSQL index types (B-tree, Hash, GiST, SP-GiST, GIN, BRIN) as documented in the PostgreSQL documentation.
src/decorator/options/IndexOptions.ts (1)
1-1: Import ofTableIndexTypesis correctly wiredThe import path and usage cleanly reuse the shared
TableIndexTypesunion for index options; no issues here.src/decorator/Index.ts (1)
135-135: Index decorator correctly propagatestypeinto metadataWiring
type: options ? options.type : undefinedinto the metadata payload is consistent with how other options are handled and ensuresIndexOptions.typeflows through toIndexMetadataArgswithout changing existing overload behavior.src/metadata-args/IndexMetadataArgs.ts (1)
1-1: Index metadata now correctly referencesTableIndexTypesImporting
TableIndexTypeshere keeps index-type information consistent across metadata layers; this matches the decorator and table index wiring.test/functional/indices/index-types/entity/User3.ts (1)
1-7: LGTM!The minimal entity structure is appropriate for testing the unsupported driver scenario.
src/driver/aurora-mysql/AuroraMysqlDriver.ts (1)
984-989: LGTM!The implementation correctly indicates that Aurora MySQL does not support PostgreSQL-style index types, consistent with the broader driver capability model.
src/schema-builder/table/TableIndex.ts (1)
3-3: LGTM!The
typeproperty is properly integrated throughout the TableIndex class with correct initialization, cloning, and creation from IndexMetadata. Documentation clearly indicates PostgreSQL-specific usage.Also applies to: 63-68, 89-89, 110-110, 134-134
src/schema-builder/options/TableIndexOptions.ts (1)
1-2: LGTM!The
typeproperty is correctly added to the interface with appropriate documentation indicating PostgreSQL-specific usage.Also applies to: 64-69
src/driver/sqlite-abstract/AbstractSqliteDriver.ts (1)
900-905: LGTM!The implementation correctly indicates that SQLite does not support index types, aligning with the driver capability model introduced in this PR.
test/functional/indices/index-types/entity/User2.ts (1)
1-16: LGTM!The entity correctly demonstrates index type usage for testing error handling on unsupported drivers.
src/driver/Driver.ts (1)
19-20: LGTM!The Driver interface additions properly define the index type capability API:
isIndicesTypeSupported()provides a clear capability checkcompareTableIndexTypes()is appropriately optional for driver-specific comparison logicThe method signatures are well-documented and align with the broader index type support introduced across the codebase.
Also applies to: 288-299
test/functional/indices/index-types/index-types.ts (1)
82-91: The review comment is incorrect. "brin" is already included in the TableIndexTypes union.The
TableIndexTypestype definition includes "brin" as a valid member alongside other index types. Theas anycast on line 88 is unnecessary but does not indicate a type mismatch or missing type definition. The type definition is already correct and complete.Likely an incorrect or invalid review comment.
src/driver/postgres/PostgresQueryRunner.ts (1)
4015-4035: Index type metadata wiring frompg_amlooks correctSetting
TableIndex.isSpatialfromconstraint["index_type"] === "gist"and propagatingtype: constraint["index_type"]intoTableIndexwill let the driver round‑trip PostgreSQL index types cleanly and keeps GiST spatial behavior intact. I don’t see issues here.test/functional/indices/index-types/entity/User.ts (1)
1-35: Good coverage of PostgreSQL index types in the test entityThis entity cleanly exercises all supported index types (btree, hash, gist, spgist, gin, brin) with appropriate column types and decorators, which should give solid end‑to‑end test coverage for the new
Index.typeoption.
| if ( | ||
| this.connection.driver.isIndicesTypeSupported() && | ||
| typeof this.connection.driver | ||
| .compareTableIndexTypes === "function" && | ||
| !this.connection.driver.compareTableIndexTypes( | ||
| indexMetadata, | ||
| tableIndex, | ||
| ) | ||
| ) | ||
| return true | ||
|
|
||
| if ( | ||
| !this.connection.driver.isIndicesTypeSupported() && | ||
| indexMetadata.type | ||
| ) | ||
| throw new TypeORMError( | ||
| `Current database driver does not support index 'type' property`, | ||
| ) | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Index type comparison is missing for view indices, risking schema drift
The new branch in dropOldIndices correctly:
- compares index types via
driver.compareTableIndexTypeswhenisIndicesTypeSupported()is true, and - throws a
TypeORMErrorifindexMetadata.typeis used on a driver that does not support index types.
However, the Postgres-specific view section below (Lines 463–499) still ignores the index type. A @Index({ type: "gin" }) change on a materialized view would not trigger a drop/recreate, leaving the database index type out of sync with metadata.
Consider mirroring the table logic for views, e.g.:
if (indexMetadata) {
if (indexMetadata.synchronize === false)
return false
if (indexMetadata.isUnique !== tableIndex.isUnique)
return true
if (
indexMetadata.isSpatial !== tableIndex.isSpatial
)
return true
+
+ if (
+ this.connection.driver.isIndicesTypeSupported &&
+ typeof this.connection.driver
+ .compareTableIndexTypes === "function" &&
+ !this.connection.driver.compareTableIndexTypes(
+ indexMetadata,
+ tableIndex,
+ )
+ ) {
+ return true
+ }(Here, the unsupported-driver case is not needed because this branch only runs when options.type === "postgres".)
Also applies to: 463-499
🤖 Prompt for AI Agents
In src/schema-builder/RdbmsSchemaBuilder.ts around lines 402-420 and 463-499,
the view-index branch doesn't compare index types so changes like @Index({type:
"gin"}) on materialized views won't trigger drop/recreate; update the Postgres
view-index comparison to mirror the table logic by calling
this.connection.driver.compareTableIndexTypes(indexMetadata, tableIndex) when
driver.isIndicesTypeSupported() and treat a false result as a mismatch (i.e.,
cause the index to be dropped/recreated), and do not add the unsupported-driver
throw because this branch only executes for options.type === "postgres".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The question is, do we need to update indexes for such cases? After some thinking I guess that this is needed to be duplicated/mirrored as CodeRabbit suggests. If I understand correctly, views don't store any data (including indexes), but the code is trying to update the related table. I think that this may break some things.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@OSA413, excellent question! You're right that regular views don't store data or indexes. However, this code path specifically handles materialized views in PostgreSQL, which are quite different:
Materialized views in PostgreSQL:
- Do store data physically (like tables)
- Can have indexes created on them
- Are commonly indexed to improve query performance on the cached data
Looking at the code in createNewViewIndices (around line 2197 in the full file), there's already a guard:
if (!view || !view.materialized) continue;This ensures only materialized views are processed. Since materialized views support indexes and the PR adds index type support, the CodeRabbit suggestion makes sense for consistency:
- Tables: Index type changes trigger drop/recreate ✅ (implemented in this PR)
- Materialized views: Index type changes should also trigger drop/recreate ✅ (currently missing)
Without mirroring the logic, changing @Index({ type: "hash" }) to @Index({ type: "gin" }) on a materialized view would leave the old hash index in place rather than recreating it as a GIN index—causing schema drift.
Recommendation: Apply CodeRabbit's suggestion to the view-index comparison section (lines 463-499) to maintain consistency with table index handling. Since this branch already requires options.type === "postgres", you only need the compareTableIndexTypes check, not the unsupported-driver error.
🧠 Learnings used
Learnt from: alumni
Repo: typeorm/typeorm PR: 11581
File: docs/docs/drivers/mongodb.md:9-13
Timestamp: 2025-07-27T17:29:18.547Z
Learning: TypeORM is compatible only with mongodb@^6, not v4 as previously suggested. The package.json file contains the authoritative peer dependency information for the MongoDB driver version compatibility.
Learnt from: alumni
Repo: typeorm/typeorm PR: 11581
File: docs/docs/drivers/postgres.md:23-23
Timestamp: 2025-07-27T20:50:10.364Z
Learning: The correct data source type for Aurora PostgreSQL in TypeORM is `aurora-postgres`, not `aurora-data-api-pg`. The `aurora-data-api-pg` driver was renamed to `aurora-postgres` according to the CHANGELOG.md. This is defined in the DatabaseType union type and AuroraPostgresConnectionOptions interface.
Learnt from: alumni
Repo: typeorm/typeorm PR: 11581
File: docs/docs/drivers/mongodb.md:9-13
Timestamp: 2025-07-27T17:29:18.547Z
Learning: TypeORM supports MongoDB driver versions "^5.8.0 || ^6.0.0" according to the peerDependencies in package.json. The v4 driver is NOT supported. Always check package.json for accurate peer dependency information.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My arguments are over, I'm requesting the help of the maintainers. (my knowledge of views is quite limited)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@OSA413, that's a reasonable approach—this is indeed a nuanced decision about materialized view schema synchronization that benefits from maintainer expertise.
Summary for maintainers:
The question is whether the index type comparison logic added for tables (lines 402-420) should also be applied to the PostgreSQL materialized view index section (lines 463-499).
Current state:
- ✅ Tables: Index type changes (e.g.,
@Index({ type: "hash" })→@Index({ type: "gin" })) trigger drop/recreate viadriver.compareTableIndexTypes - ❌ Materialized views: Same change would not trigger drop/recreate—the old index type persists
Technical context:
- PostgreSQL materialized views can have indexes (unlike regular views)
- The code already filters for
view.materializedat line ~2197 increateNewViewIndices - This branch only executes when
options.type === "postgres"
Question: Should materialized view indexes follow the same type-change detection as table indexes for consistency, or is there a reason to handle them differently?
The suggested fix would add the compareTableIndexTypes check to the view-index comparison block, mirroring what was done for tables.
🧠 Learnings used
Learnt from: alumni
Repo: typeorm/typeorm PR: 11581
File: docs/docs/drivers/mongodb.md:9-13
Timestamp: 2025-07-27T17:29:18.547Z
Learning: TypeORM is compatible only with mongodb@^6, not v4 as previously suggested. The package.json file contains the authoritative peer dependency information for the MongoDB driver version compatibility.
Learnt from: alumni
Repo: typeorm/typeorm PR: 11581
File: docs/docs/drivers/postgres.md:23-23
Timestamp: 2025-07-27T20:50:10.364Z
Learning: The correct data source type for Aurora PostgreSQL in TypeORM is `aurora-postgres`, not `aurora-data-api-pg`. The `aurora-data-api-pg` driver was renamed to `aurora-postgres` according to the CHANGELOG.md. This is defined in the DatabaseType union type and AuroraPostgresConnectionOptions interface.
Learnt from: alumni
Repo: typeorm/typeorm PR: 11581
File: docs/docs/drivers/mongodb.md:9-13
Timestamp: 2025-07-27T17:29:18.547Z
Learning: TypeORM supports MongoDB driver versions "^5.8.0 || ^6.0.0" according to the peerDependencies in package.json. The v4 driver is NOT supported. Always check package.json for accurate peer dependency information.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hello @freePixel, I think this may need your attention.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was not aware of view indexes, I'll have to create some tests for it and verify why they are not being created for both @ViewColumn and @ViewEntity decorators.
| it("Should throw an error if index type is set and driver does not support index types", async () => { | ||
| const connections = await createTestingConnections({ | ||
| entities: [User3], | ||
| enabledDrivers: ["sqlite"], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this should be extended to the other drivers that don't support index types.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've extended the test to include other drivers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd only add the tests for Postgres, but I get that we want to test one driver that is different. Sqlite was a good choice, it doesn't support index types.
I don't like that now there are a lot of tests in one test file.
If I will implement this for the SapDriver (BTREE | CPBTREE | INVERTED HASH | INVERTED VALUE | INVERTED INDIVIDUAL) or for MySQL/MariaDB (BTREE | HASH | RTREE), I will likely extract the driver that I'm implementing into a new folder and remove the rest 🤷🏻
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've separated tests in separate files.
| @@ -0,0 +1,7 @@ | |||
| export type TableIndexTypes = | |||
| | "btree" | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be great if you could add a comment for each line that these are for Postgres, so we add support for the other DBs, we can append the driver to the comment. Helps keep track of features.
G0maa
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM (after resolving @alumni comments), thanks for your contribution 🚀
|
@alumni thanks for the review. I'll be very busy over the next few days, and also need some time to think through your comments and adjust the implementation accordingly. |
|
Take your time - most of the changes are rather simple. The only one that needs thinking is avoiding the pg-specific I wonder if it's better to leave it as it is in this PR or if we should adjust the conditions in |
…esql-indices-support
PR Code Suggestions ✨Latest suggestions up to afa5de1
Previous suggestionsSuggestions up to commit 1afea72
Suggestions up to commit 963d3f7
Suggestions up to commit da813fc
Suggestions up to commit 32c7dab
Suggestions up to commit 7829bb0
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
I've implemented suggestion according with @alumni comments and answered the comments. |
|
It seems that tests failed for postgres (17) but it's related with a network error as you can see from the logs. |
gioboa
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
May I ask you to solve the conflicts please?
Thanks for your help @freePixel
…/10964-postgresql-indices-support
|
I think we didn't notice that the test file names don't end in TODO: we'll need to check if there are others we forgot about and fix them :) |

Description of change
Implements #10964 and adds support for all PostgreSQL index types
(B-Tree, Hash, GiST, SP-GiST, GIN, BRIN) as described in the PostgreSQL documentation.
This is also applicable for postgreSQL view indexes.
A new optional
typeoption of typeTableIndexTypeshas been added to theIndexdecorator.The implementation is designed in a way that allows it to be easily extended to support other database drivers beyond PostgreSQL.
Pull-Request Checklist
masterbranchnpm run formatto apply prettier formattingnpm run testpasses with this changeFixes #0000Summary by CodeRabbit
New Features
Documentation
Behavior / Validation
Tests
✏️ Tip: You can customize this high-level summary in your review settings.