From 7d256d235afe75c179056616d142392a96101637 Mon Sep 17 00:00:00 2001 From: Conor Webb <126772285+ConorWebb96@users.noreply.github.com> Date: Thu, 23 May 2024 15:31:11 +0100 Subject: [PATCH] Enum columns unexpectedly breaking fix (#13756) * Added enum to SQL_MISC_TYPE_MAP to correctly map to FieldType.OPTIONS * improve enum values extraction for multiple single-select support * Tests to ensure enums are typed correctly MySQL and Postgres * Fixed linting issue * Ran prettier --- .../server/src/integration-test/mysql.spec.ts | 36 +++++++++++++++++++ .../src/integration-test/postgres.spec.ts | 31 ++++++++++++++++ packages/server/src/integrations/postgres.ts | 10 +++--- .../server/src/integrations/utils/utils.ts | 1 + 4 files changed, 72 insertions(+), 6 deletions(-) diff --git a/packages/server/src/integration-test/mysql.spec.ts b/packages/server/src/integration-test/mysql.spec.ts index b4eb1035d6..8cf4fb8212 100644 --- a/packages/server/src/integration-test/mysql.spec.ts +++ b/packages/server/src/integration-test/mysql.spec.ts @@ -281,4 +281,40 @@ describe("mysql integrations", () => { ]) }) }) + + describe("POST /api/datasources/:datasourceId/schema", () => { + let tableName: string + + beforeEach(async () => { + tableName = uniqueTableName() + }) + + afterEach(async () => { + await rawQuery(rawDatasource, `DROP TABLE IF EXISTS \`${tableName}\``) + }) + + it("recognises enum columns as options", async () => { + const enumColumnName = "status" + + const createTableQuery = ` + CREATE TABLE \`${tableName}\` ( + \`order_id\` INT AUTO_INCREMENT PRIMARY KEY, + \`customer_name\` VARCHAR(100) NOT NULL, + \`${enumColumnName}\` ENUM('pending', 'processing', 'shipped', 'delivered', 'cancelled') + ); + ` + + await rawQuery(rawDatasource, createTableQuery) + + const response = await makeRequest( + "post", + `/api/datasources/${datasource._id}/schema` + ) + + const table = response.body.datasource.entities[tableName] + + expect(table).toBeDefined() + expect(table.schema[enumColumnName].type).toEqual(FieldType.OPTIONS) + }) + }) }) diff --git a/packages/server/src/integration-test/postgres.spec.ts b/packages/server/src/integration-test/postgres.spec.ts index ec4cb90a86..ccf63d0820 100644 --- a/packages/server/src/integration-test/postgres.spec.ts +++ b/packages/server/src/integration-test/postgres.spec.ts @@ -1122,6 +1122,37 @@ describe("postgres integrations", () => { [tableName]: "Table contains invalid columns.", }) }) + + it("recognises enum columns as options", async () => { + const tableName = `orders_${generator + .guid() + .replaceAll("-", "") + .substring(0, 6)}` + const enumColumnName = "status" + + await rawQuery( + rawDatasource, + ` + CREATE TYPE order_status AS ENUM ('pending', 'processing', 'shipped', 'delivered', 'cancelled'); + + CREATE TABLE ${tableName} ( + order_id SERIAL PRIMARY KEY, + customer_name VARCHAR(100) NOT NULL, + ${enumColumnName} order_status + ); + ` + ) + + const response = await makeRequest( + "post", + `/api/datasources/${datasource._id}/schema` + ) + + const table = response.body.datasource.entities[tableName] + + expect(table).toBeDefined() + expect(table.schema[enumColumnName].type).toEqual(FieldType.OPTIONS) + }) }) describe("Integration compatibility with postgres search_path", () => { diff --git a/packages/server/src/integrations/postgres.ts b/packages/server/src/integrations/postgres.ts index e810986757..584f0ef15d 100644 --- a/packages/server/src/integrations/postgres.ts +++ b/packages/server/src/integrations/postgres.ts @@ -329,14 +329,12 @@ class PostgresIntegration extends Sql implements DatasourcePlus { // Fetch enum values const enumsResponse = await this.client.query(this.ENUM_VALUES()) + // output array, allows for more than 1 single-select to be used at a time const enumValues = enumsResponse.rows?.reduce((acc, row) => { - if (!acc[row.typname]) { - return { - [row.typname]: [row.enumlabel], - } + return { + ...acc, + [row.typname]: [...(acc[row.typname] || []), row.enumlabel], } - acc[row.typname].push(row.enumlabel) - return acc }, {}) for (let column of columnsResponse.rows) { diff --git a/packages/server/src/integrations/utils/utils.ts b/packages/server/src/integrations/utils/utils.ts index 8f3aba8907..5bc90bc295 100644 --- a/packages/server/src/integrations/utils/utils.ts +++ b/packages/server/src/integrations/utils/utils.ts @@ -102,6 +102,7 @@ const SQL_OPTIONS_TYPE_MAP: Record = { const SQL_MISC_TYPE_MAP: Record = { json: FieldType.JSON, bigint: FieldType.BIGINT, + enum: FieldType.OPTIONS, } const SQL_TYPE_MAP: Record = {