unit tests and logic added to prevent coalesce being used by oracle

This commit is contained in:
Martin McKeaveney 2024-07-22 21:00:20 +01:00
parent c0260b85ff
commit 88ea3fdc07
3 changed files with 100 additions and 20 deletions

View File

@ -435,6 +435,11 @@ class InternalBuilder {
)} = ? THEN 1 ELSE 0 END = 1`, )} = ? THEN 1 ELSE 0 END = 1`,
[value] [value]
) )
} else if (SqlClient.ORACLE) {
query = query[fnc](
`${quotedIdentifier(this.client, key)} = ?`,
[value]
)
} else { } else {
query = query[fnc]( query = query[fnc](
`COALESCE(${quotedIdentifier(this.client, key)} = ?, FALSE)`, `COALESCE(${quotedIdentifier(this.client, key)} = ?, FALSE)`,

View File

@ -153,9 +153,9 @@ export function isValidTime(value: string) {
} }
export function sqlLog(client: string, query: string, values?: any[]) { export function sqlLog(client: string, query: string, values?: any[]) {
if (!environment.SQL_LOGGING_ENABLE) { // if (!environment.SQL_LOGGING_ENABLE) {
return // return
} // }
let string = `[SQL] [${client.toUpperCase()}] query="${query}"` let string = `[SQL] [${client.toUpperCase()}] query="${query}"`
if (values) { if (values) {
string += ` values="${values.join(", ")}"` string += ` values="${values.join(", ")}"`

View File

@ -34,13 +34,13 @@ function endpoint(table: any, operation: any) {
} }
function generateReadJson({ function generateReadJson({
table, table,
fields, fields,
filters, filters,
sort, sort,
paginate, paginate,
}: any = {}): QueryJson { }: any = {}): QueryJson {
const tableObj = { ...TABLE } const tableObj = {...TABLE}
if (table) { if (table) {
tableObj.name = table tableObj.name = table
} }
@ -85,7 +85,7 @@ function generateRelationshipJson(config: { schema?: string } = {}): QueryJson {
column: "products", column: "products",
}, },
], ],
extra: { idFilter: {} }, extra: {idFilter: {}},
meta: { meta: {
table: TABLE, table: TABLE,
}, },
@ -122,7 +122,7 @@ function generateManyRelationshipJson(config: { schema?: string } = {}) {
toPrimary: "product_id", toPrimary: "product_id",
}, },
], ],
extra: { idFilter: {} }, extra: {idFilter: {}},
meta: { meta: {
table: TABLE, table: TABLE,
}, },
@ -139,10 +139,17 @@ describe("SQL query builder", () => {
}) })
it("should add the schema to the LEFT JOIN", () => { it("should add the schema to the LEFT JOIN", () => {
const query = sql._query(generateRelationshipJson({ schema: "production" })) const query = sql._query(generateRelationshipJson({schema: "production"}))
expect(query).toEqual({ expect(query).toEqual({
bindings: [500, 5000], bindings: [500, 5000],
sql: `select "brands"."brand_id" as "brands.brand_id", "brands"."brand_name" as "brands.brand_name", "products"."product_id" as "products.product_id", "products"."product_name" as "products.product_name", "products"."brand_id" as "products.brand_id" from (select * from "production"."brands" order by "test"."id" asc limit $1) as "brands" left join "production"."products" as "products" on "brands"."brand_id" = "products"."brand_id" order by "test"."id" asc limit $2`, sql: `select "brands"."brand_id" as "brands.brand_id",
"brands"."brand_name" as "brands.brand_name",
"products"."product_id" as "products.product_id",
"products"."product_name" as "products.product_name",
"products"."brand_id" as "products.brand_id"
from (select * from "production"."brands" order by "test"."id" asc limit $1) as "brands"
left join "production"."products" as "products" on "brands"."brand_id" = "products"."brand_id"
order by "test"."id" asc limit $2`,
}) })
}) })
@ -150,17 +157,31 @@ describe("SQL query builder", () => {
const query = sql._query(generateRelationshipJson()) const query = sql._query(generateRelationshipJson())
expect(query).toEqual({ expect(query).toEqual({
bindings: [500, 5000], bindings: [500, 5000],
sql: `select "brands"."brand_id" as "brands.brand_id", "brands"."brand_name" as "brands.brand_name", "products"."product_id" as "products.product_id", "products"."product_name" as "products.product_name", "products"."brand_id" as "products.brand_id" from (select * from "brands" order by "test"."id" asc limit $1) as "brands" left join "products" as "products" on "brands"."brand_id" = "products"."brand_id" order by "test"."id" asc limit $2`, sql: `select "brands"."brand_id" as "brands.brand_id",
"brands"."brand_name" as "brands.brand_name",
"products"."product_id" as "products.product_id",
"products"."product_name" as "products.product_name",
"products"."brand_id" as "products.brand_id"
from (select * from "brands" order by "test"."id" asc limit $1) as "brands"
left join "products" as "products" on "brands"."brand_id" = "products"."brand_id"
order by "test"."id" asc limit $2`,
}) })
}) })
it("should add the schema to both the toTable and throughTable in many-to-many join", () => { it("should add the schema to both the toTable and throughTable in many-to-many join", () => {
const query = sql._query( const query = sql._query(
generateManyRelationshipJson({ schema: "production" }) generateManyRelationshipJson({schema: "production"})
) )
expect(query).toEqual({ expect(query).toEqual({
bindings: [500, 5000], bindings: [500, 5000],
sql: `select "stores"."store_id" as "stores.store_id", "stores"."store_name" as "stores.store_name", "products"."product_id" as "products.product_id", "products"."product_name" as "products.product_name" from (select * from "production"."stores" order by "test"."id" asc limit $1) as "stores" left join "production"."stocks" as "stocks" on "stores"."store_id" = "stocks"."store_id" left join "production"."products" as "products" on "products"."product_id" = "stocks"."product_id" order by "test"."id" asc limit $2`, sql: `select "stores"."store_id" as "stores.store_id",
"stores"."store_name" as "stores.store_name",
"products"."product_id" as "products.product_id",
"products"."product_name" as "products.product_name"
from (select * from "production"."stores" order by "test"."id" asc limit $1) as "stores"
left join "production"."stocks" as "stocks" on "stores"."store_id" = "stocks"."store_id"
left join "production"."products" as "products" on "products"."product_id" = "stocks"."product_id"
order by "test"."id" asc limit $2`,
}) })
}) })
@ -176,7 +197,13 @@ describe("SQL query builder", () => {
) )
expect(query).toEqual({ expect(query).toEqual({
bindings: ["john%", limit, 5000], bindings: ["john%", limit, 5000],
sql: `select * from (select * from (select * from (select * from "test" where LOWER("test"."name") LIKE :1 order by "test"."id" asc) where rownum <= :2) "test" order by "test"."id" asc) where rownum <= :3`, sql: `select *
from (select *
from (select *
from (select * from "test" where LOWER("test"."name") LIKE :1 order by "test"."id" asc)
where rownum <= :2) "test"
order by "test"."id" asc)
where rownum <= :3`,
}) })
query = new Sql(SqlClient.ORACLE, limit)._query( query = new Sql(SqlClient.ORACLE, limit)._query(
@ -191,7 +218,17 @@ describe("SQL query builder", () => {
) )
expect(query).toEqual({ expect(query).toEqual({
bindings: ["%20%", "%25%", `%"john"%`, `%"mary"%`, limit, 5000], bindings: ["%20%", "%25%", `%"john"%`, `%"mary"%`, limit, 5000],
sql: `select * from (select * from (select * from (select * from "test" where (COALESCE(LOWER("test"."age"), '') LIKE :1 AND COALESCE(LOWER("test"."age"), '') LIKE :2) and (COALESCE(LOWER("test"."name"), '') LIKE :3 AND COALESCE(LOWER("test"."name"), '') LIKE :4) order by "test"."id" asc) where rownum <= :5) "test" order by "test"."id" asc) where rownum <= :6`, sql: `select *
from (select *
from (select *
from (select *
from "test"
where (COALESCE(LOWER("test"."age"), '') LIKE :1 AND COALESCE(LOWER("test"."age"), '') LIKE :2)
and (COALESCE(LOWER("test"."name"), '') LIKE :3 AND COALESCE(LOWER("test"."name"), '') LIKE :4)
order by "test"."id" asc)
where rownum <= :5) "test"
order by "test"."id" asc)
where rownum <= :6`,
}) })
query = new Sql(SqlClient.ORACLE, limit)._query( query = new Sql(SqlClient.ORACLE, limit)._query(
@ -205,7 +242,45 @@ describe("SQL query builder", () => {
) )
expect(query).toEqual({ expect(query).toEqual({
bindings: [`%jo%`, limit, 5000], bindings: [`%jo%`, limit, 5000],
sql: `select * from (select * from (select * from (select * from "test" where LOWER("test"."name") LIKE :1 order by "test"."id" asc) where rownum <= :2) "test" order by "test"."id" asc) where rownum <= :3`, sql: `select *
from (select *
from (select *
from (select * from "test" where LOWER("test"."name") LIKE :1 order by "test"."id" asc)
where rownum <= :2) "test"
order by "test"."id" asc)
where rownum <= :3`,
})
})
it("should not use a coalesce query for oracle when using the equals filter", () => {
let query = new Sql(SqlClient.ORACLE, limit)._query(
generateReadJson({
filters: {
equal: {
name: "John",
},
},
}))
expect(query).not.toEqual({
bindings: ["John", limit, 5000],
sql: `select * from (select * from (select * from (select * from "test" where COALESCE("test"."id" = :2, FALSE) order by "test"."id" asc) where rownum <= :2) "test" order by "test"."id" asc) where rownum <= :3`,
})
})
it("should use a direct equality query for oracle when using the equals filter", () => {
let query = new Sql(SqlClient.ORACLE, limit)._query(
generateReadJson({
filters: {
equal: {
name: "John",
},
},
}))
expect(query).toEqual({
bindings: ["John", limit, 5000],
sql: `select * from (select * from (select * from (select * from "test" where "test"."name" = :1 order by "test"."id" asc) where rownum <= :2) "test" order by "test"."id" asc) where rownum <= :3`,
}) })
}) })
}) })