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
This commit is contained in:
Conor Webb 2024-05-23 15:31:11 +01:00 committed by GitHub
parent c531e5913d
commit 7d256d235a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 72 additions and 6 deletions

View File

@ -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)
})
})
}) })

View File

@ -1122,6 +1122,37 @@ describe("postgres integrations", () => {
[tableName]: "Table contains invalid columns.", [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", () => { describe("Integration compatibility with postgres search_path", () => {

View File

@ -329,14 +329,12 @@ class PostgresIntegration extends Sql implements DatasourcePlus {
// Fetch enum values // Fetch enum values
const enumsResponse = await this.client.query(this.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) => { const enumValues = enumsResponse.rows?.reduce((acc, row) => {
if (!acc[row.typname]) { return {
return { ...acc,
[row.typname]: [row.enumlabel], [row.typname]: [...(acc[row.typname] || []), row.enumlabel],
}
} }
acc[row.typname].push(row.enumlabel)
return acc
}, {}) }, {})
for (let column of columnsResponse.rows) { for (let column of columnsResponse.rows) {

View File

@ -102,6 +102,7 @@ const SQL_OPTIONS_TYPE_MAP: Record<string, PrimitiveTypes> = {
const SQL_MISC_TYPE_MAP: Record<string, PrimitiveTypes> = { const SQL_MISC_TYPE_MAP: Record<string, PrimitiveTypes> = {
json: FieldType.JSON, json: FieldType.JSON,
bigint: FieldType.BIGINT, bigint: FieldType.BIGINT,
enum: FieldType.OPTIONS,
} }
const SQL_TYPE_MAP: Record<string, PrimitiveTypes> = { const SQL_TYPE_MAP: Record<string, PrimitiveTypes> = {