Merge pull request #14212 from Budibase/fix/dupe-columns-sqs
Fix for duplicate columns in SQS
This commit is contained in:
commit
7bc92fef24
|
@ -6,9 +6,11 @@ import {
|
||||||
} from "../../../integrations/tests/utils"
|
} from "../../../integrations/tests/utils"
|
||||||
import {
|
import {
|
||||||
db as dbCore,
|
db as dbCore,
|
||||||
|
context,
|
||||||
MAX_VALID_DATE,
|
MAX_VALID_DATE,
|
||||||
MIN_VALID_DATE,
|
MIN_VALID_DATE,
|
||||||
utils,
|
utils,
|
||||||
|
SQLITE_DESIGN_DOC_ID,
|
||||||
} from "@budibase/backend-core"
|
} from "@budibase/backend-core"
|
||||||
|
|
||||||
import * as setup from "./utilities"
|
import * as setup from "./utilities"
|
||||||
|
@ -2524,4 +2526,38 @@ describe.each([
|
||||||
}).toContainExactly([{ [" name"]: "foo" }])
|
}).toContainExactly([{ [" name"]: "foo" }])
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
isSqs &&
|
||||||
|
describe("duplicate columns", () => {
|
||||||
|
beforeAll(async () => {
|
||||||
|
table = await createTable({
|
||||||
|
name: {
|
||||||
|
name: "name",
|
||||||
|
type: FieldType.STRING,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
await context.doInAppContext(config.getAppId(), async () => {
|
||||||
|
const db = context.getAppDB()
|
||||||
|
const tableDoc = await db.get<Table>(table._id!)
|
||||||
|
tableDoc.schema.Name = {
|
||||||
|
name: "Name",
|
||||||
|
type: FieldType.STRING,
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
// remove the SQLite definitions so that they can be rebuilt as part of the search
|
||||||
|
const sqliteDoc = await db.get(SQLITE_DESIGN_DOC_ID)
|
||||||
|
await db.remove(sqliteDoc)
|
||||||
|
} catch (err) {
|
||||||
|
// no-op
|
||||||
|
}
|
||||||
|
})
|
||||||
|
await createRows([{ name: "foo", Name: "bar" }])
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should handle invalid duplicate column names", async () => {
|
||||||
|
await expectSearch({
|
||||||
|
query: {},
|
||||||
|
}).toContainExactly([{ name: "foo" }])
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -49,6 +49,7 @@ import { dataFilters } from "@budibase/shared-core"
|
||||||
const builder = new sql.Sql(SqlClient.SQL_LITE)
|
const builder = new sql.Sql(SqlClient.SQL_LITE)
|
||||||
const MISSING_COLUMN_REGEX = new RegExp(`no such column: .+`)
|
const MISSING_COLUMN_REGEX = new RegExp(`no such column: .+`)
|
||||||
const MISSING_TABLE_REGX = new RegExp(`no such table: .+`)
|
const MISSING_TABLE_REGX = new RegExp(`no such table: .+`)
|
||||||
|
const DUPLICATE_COLUMN_REGEX = new RegExp(`duplicate column name: .+`)
|
||||||
|
|
||||||
function buildInternalFieldList(
|
function buildInternalFieldList(
|
||||||
table: Table,
|
table: Table,
|
||||||
|
@ -237,9 +238,11 @@ function resyncDefinitionsRequired(status: number, message: string) {
|
||||||
// pre data_ prefix on column names, need to resync
|
// pre data_ prefix on column names, need to resync
|
||||||
return (
|
return (
|
||||||
// there are tables missing - try a resync
|
// there are tables missing - try a resync
|
||||||
(status === 400 && message.match(MISSING_TABLE_REGX)) ||
|
(status === 400 && message?.match(MISSING_TABLE_REGX)) ||
|
||||||
// there are columns missing - try a resync
|
// there are columns missing - try a resync
|
||||||
(status === 400 && message.match(MISSING_COLUMN_REGEX)) ||
|
(status === 400 && message?.match(MISSING_COLUMN_REGEX)) ||
|
||||||
|
// duplicate column name in definitions - need to re-run definition sync
|
||||||
|
(status === 400 && message?.match(DUPLICATE_COLUMN_REGEX)) ||
|
||||||
// no design document found, needs a full sync
|
// no design document found, needs a full sync
|
||||||
(status === 404 && message?.includes(SQLITE_DESIGN_DOC_ID))
|
(status === 404 && message?.includes(SQLITE_DESIGN_DOC_ID))
|
||||||
)
|
)
|
||||||
|
|
|
@ -94,6 +94,9 @@ export function mapToUserColumn(key: string) {
|
||||||
function mapTable(table: Table): SQLiteTables {
|
function mapTable(table: Table): SQLiteTables {
|
||||||
const tables: SQLiteTables = {}
|
const tables: SQLiteTables = {}
|
||||||
const fields: Record<string, { field: string; type: SQLiteType }> = {}
|
const fields: Record<string, { field: string; type: SQLiteType }> = {}
|
||||||
|
// a list to make sure no duplicates - the fields are mapped by SQS with case sensitivity
|
||||||
|
// but need to make sure there are no duplicate columns
|
||||||
|
const usedColumns: string[] = []
|
||||||
for (let [key, column] of Object.entries(table.schema)) {
|
for (let [key, column] of Object.entries(table.schema)) {
|
||||||
// relationships should be handled differently
|
// relationships should be handled differently
|
||||||
if (column.type === FieldType.LINK) {
|
if (column.type === FieldType.LINK) {
|
||||||
|
@ -106,6 +109,12 @@ function mapTable(table: Table): SQLiteTables {
|
||||||
if (!FieldTypeMap[column.type]) {
|
if (!FieldTypeMap[column.type]) {
|
||||||
throw new Error(`Unable to map type "${column.type}" to SQLite type`)
|
throw new Error(`Unable to map type "${column.type}" to SQLite type`)
|
||||||
}
|
}
|
||||||
|
const lcKey = key.toLowerCase()
|
||||||
|
// ignore duplicates
|
||||||
|
if (usedColumns.includes(lcKey)) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
usedColumns.push(lcKey)
|
||||||
fields[mapToUserColumn(key)] = {
|
fields[mapToUserColumn(key)] = {
|
||||||
field: key,
|
field: key,
|
||||||
type: FieldTypeMap[column.type],
|
type: FieldTypeMap[column.type],
|
||||||
|
|
Loading…
Reference in New Issue