From d8fbca80e0ccce6374b679f78c10a8d8a57cc3c6 Mon Sep 17 00:00:00 2001 From: dalton-oliveira Date: Sat, 28 Dec 2024 11:31:47 -0300 Subject: [PATCH 1/2] fix(pg): introspect composite index with mixed types --- drizzle-kit/src/serializer/pgSerializer.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drizzle-kit/src/serializer/pgSerializer.ts b/drizzle-kit/src/serializer/pgSerializer.ts index b0faa5ea8..abc8cf480 100644 --- a/drizzle-kit/src/serializer/pgSerializer.ts +++ b/drizzle-kit/src/serializer/pgSerializer.ts @@ -1563,7 +1563,7 @@ WHERE ON i.indrelid = a.attrelid AND k.attnum = a.attnum JOIN pg_namespace c on c.oid = t.relnamespace LEFT JOIN pg_am AS am ON ic.relam = am.oid - JOIN pg_opclass opc ON opc.oid = ANY(i.indclass) + JOIN pg_opclass opc ON opc.oid = i.indclass[k.i-1] WHERE c.nspname = '${tableSchema}' AND t.relname = '${tableName}';`, From aa45088da5c7474e2c1a1719adc84c06acff9b0c Mon Sep 17 00:00:00 2001 From: dalton-oliveira Date: Sat, 28 Dec 2024 16:12:37 -0300 Subject: [PATCH 2/2] fix: includes tests for introspecting postgres composite index --- drizzle-kit/tests/introspect/pg.test.ts | 14 +++++++++- drizzle-kit/tests/schemaDiffer.ts | 35 +++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/drizzle-kit/tests/introspect/pg.test.ts b/drizzle-kit/tests/introspect/pg.test.ts index 1d9f0f18c..296fc0807 100644 --- a/drizzle-kit/tests/introspect/pg.test.ts +++ b/drizzle-kit/tests/introspect/pg.test.ts @@ -35,7 +35,7 @@ import { varchar, } from 'drizzle-orm/pg-core'; import fs from 'fs'; -import { introspectPgToFile } from 'tests/schemaDiffer'; +import { introspectAfterSqlStatements, introspectPgToFile } from 'tests/schemaDiffer'; import { expect, test } from 'vitest'; if (!fs.existsSync('tests/introspect/postgres')) { @@ -892,3 +892,15 @@ test('multiple policies with roles from schema', async () => { expect(statements.length).toBe(0); expect(sqlStatements.length).toBe(0); }); + +test('composite index', async () => { + const client = new PGlite(); + const indexExpression = `name text_ops, deleted bool_ops, age int4_ops`; + const statements = [ + `CREATE TABLE "users" ("name" text, deleted boolean, age integer);\n`, + `CREATE INDEX "idx" ON "users" USING btree (${indexExpression})`, + ]; + const { tables } = await introspectAfterSqlStatements(client, statements); + const types = tables['public.users']?.indexes.idx?.columns.map((c) => `${c.expression} ${c.opclass}`).join(', ') + expect(types).toBe(indexExpression); +}); \ No newline at end of file diff --git a/drizzle-kit/tests/schemaDiffer.ts b/drizzle-kit/tests/schemaDiffer.ts index 9c7f212aa..a2a3a4e8c 100644 --- a/drizzle-kit/tests/schemaDiffer.ts +++ b/drizzle-kit/tests/schemaDiffer.ts @@ -2240,6 +2240,41 @@ export const diffTestSchemasLibSQL = async ( return { sqlStatements, statements }; }; +export const introspectAfterSqlStatements = async ( + client: PGlite, + sqlStatements: string[], + schemas: string[] = ['public'], + entities?: Entities, +) => { + for (const st of sqlStatements) { + await client.query(st); + } + // introspect to schema + const introspectedSchema = await fromDatabase( + { + query: async (query: string, values?: any[] | undefined) => { + const res = await client.query(query, values); + return res.rows as any[]; + }, + }, + undefined, + schemas, + entities, + ); + + const { version: _initV, dialect: _initD, ...initRest } = introspectedSchema; + + const initSch = { + version: '7', + dialect: 'postgresql', + id: '0', + prevId: '0', + ...initRest, + } as const; + + return pgSchema.parse(initSch); +}; + // --- Introspect to file helpers --- export const introspectPgToFile = async (