From 1102be7cf8448ef62f999640b76676ffe574ea8e Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Fri, 9 Dec 2022 18:52:15 +0800 Subject: [PATCH 1/7] fix(nocodb): empty result when identifier is null --- .../lib/sql/formulav2/formulaQueryBuilderv2.ts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/formulav2/formulaQueryBuilderv2.ts b/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/formulav2/formulaQueryBuilderv2.ts index 0c382ea3b4..5ce2ade250 100644 --- a/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/formulav2/formulaQueryBuilderv2.ts +++ b/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/formulav2/formulaQueryBuilderv2.ts @@ -664,6 +664,20 @@ export default async function formulaQueryBuilderv2( sql = `COALESCE(${left}, '') ${pt.operator} COALESCE(${right},'')${colAlias}`; } + if (knex.clientType() === 'mysql2') { + sql = `IFNULL(${left} ${pt.operator} ${right}, ${ + pt.operator === '=' + ? pt.left.type === 'Literal' + ? pt.left.value === '' + : pt.right.value === '' + : pt.operator === '!=' + ? pt.left.type !== 'Literal' + ? pt.left.value === '' + : pt.right.value === '' + : 0 + }) ${colAlias}`; + } + const query = knex.raw(sql); if (prevBinaryOp && pt.operator !== prevBinaryOp) { query.wrap('(', ')'); From 5c19bd3c9a2cdd7c1d776ac40682122beb9b622d Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Wed, 21 Dec 2022 18:46:17 +0800 Subject: [PATCH 2/7] fix(nc-gui): check undefined or null instead for boolean case --- packages/nc-gui/utils/dateTimeUtils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/nc-gui/utils/dateTimeUtils.ts b/packages/nc-gui/utils/dateTimeUtils.ts index 8736221840..674b063854 100644 --- a/packages/nc-gui/utils/dateTimeUtils.ts +++ b/packages/nc-gui/utils/dateTimeUtils.ts @@ -17,7 +17,7 @@ export const dateFormats = [ ] export const handleTZ = (val: any) => { - if (!val) { + if (val === undefined || val === null) { return } if (typeof val !== 'string') { From eea2c6e5d0c30dd89b626b9e994704749d9d591a Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Wed, 21 Dec 2022 18:46:39 +0800 Subject: [PATCH 3/7] fix(nc-gui): missing result for PG --- .../lib/sql/formulav2/formulaQueryBuilderv2.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/formulav2/formulaQueryBuilderv2.ts b/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/formulav2/formulaQueryBuilderv2.ts index ecfd94e6ac..2637810013 100644 --- a/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/formulav2/formulaQueryBuilderv2.ts +++ b/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/formulav2/formulaQueryBuilderv2.ts @@ -721,6 +721,18 @@ export default async function formulaQueryBuilderv2( : pt.right.value === '' : 0 }) ${colAlias}`; + } else if (knex.clientType() === 'pg') { + sql = `COALESCE(${left} ${pt.operator} ${right}, ${ + pt.operator === '=' + ? pt.left.type === 'Literal' + ? pt.left.value === '' + : pt.right.value === '' + : pt.operator === '!=' + ? pt.left.type !== 'Literal' + ? pt.left.value === '' + : pt.right.value === '' + : false + }) ${colAlias}`; } const query = knex.raw(sql); From aa91fb2cca2d42982ceaad39af75a73bb47a926e Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Wed, 21 Dec 2022 18:56:54 +0800 Subject: [PATCH 4/7] fix(nocodb): missing result for sqlite3 --- .../lib/sql/formulav2/formulaQueryBuilderv2.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/formulav2/formulaQueryBuilderv2.ts b/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/formulav2/formulaQueryBuilderv2.ts index 2637810013..91240d6e92 100644 --- a/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/formulav2/formulaQueryBuilderv2.ts +++ b/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/formulav2/formulaQueryBuilderv2.ts @@ -721,7 +721,10 @@ export default async function formulaQueryBuilderv2( : pt.right.value === '' : 0 }) ${colAlias}`; - } else if (knex.clientType() === 'pg') { + } else if ( + knex.clientType() === 'pg' || + knex.clientType() === 'sqlite3' + ) { sql = `COALESCE(${left} ${pt.operator} ${right}, ${ pt.operator === '=' ? pt.left.type === 'Literal' From f584211eaa7d206805d47b869a689958327b891e Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Wed, 21 Dec 2022 21:28:25 +0800 Subject: [PATCH 5/7] fix(nocodb): add case when for AND and OR in MSSQL fn --- .../lib/sql/functionMappings/mssql.ts | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/functionMappings/mssql.ts b/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/functionMappings/mssql.ts index 1358a87411..903478af5f 100644 --- a/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/functionMappings/mssql.ts +++ b/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/functionMappings/mssql.ts @@ -123,6 +123,30 @@ const mssql = { )} % 7 + 7) % 7 ${colAlias}` ); }, + AND: (args: MapFnArgs) => { + return args.knex.raw( + `CASE WHEN ${args.knex + .raw( + `${args.pt.arguments + .map((ar) => args.fn(ar, '', 'AND').toQuery()) + .join(' AND ')}` + ) + .wrap('(', ')') + .toQuery()} THEN 1 ELSE 0 END ${args.colAlias}` + ); + }, + OR: (args: MapFnArgs) => { + return args.knex.raw( + `CASE WHEN ${args.knex + .raw( + `${args.pt.arguments + .map((ar) => args.fn(ar, '', 'OR').toQuery()) + .join(' OR ')}` + ) + .wrap('(', ')') + .toQuery()} THEN 1 ELSE 0 END ${args.colAlias}` + ); + }, }; export default mssql; From 4cef10222db474d5b3a07f597a691f4afce61ea5 Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Wed, 21 Dec 2022 21:29:07 +0800 Subject: [PATCH 6/7] fix(nocodb): empty result for MSSQL --- .../sql/formulav2/formulaQueryBuilderv2.ts | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/formulav2/formulaQueryBuilderv2.ts b/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/formulav2/formulaQueryBuilderv2.ts index 91240d6e92..8b091d2fa8 100644 --- a/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/formulav2/formulaQueryBuilderv2.ts +++ b/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/formulav2/formulaQueryBuilderv2.ts @@ -736,8 +736,27 @@ export default async function formulaQueryBuilderv2( : pt.right.value === '' : false }) ${colAlias}`; - } + } else if (knex.clientType() === 'mssql') { + if (pt.operator === '=') { + if (pt.left.type === 'Literal' && pt.left.value === '') { + sql = `${right} IS NULL OR ${right} = ''`; + } else if (pt.right.type === 'Literal' && pt.right.value === '') { + sql = `${left} IS NULL OR ${left} = ''`; + } + } else if (pt.operator === '!=') { + if (pt.left.type === 'Literal' && pt.left.value === '') { + sql = `${right} IS NOT NULL AND ${right} != ''`; + } else if (pt.right.type === 'Literal' && pt.right.value === '') { + sql = `${left} IS NOT NULL AND ${left} != ''`; + } + } + if (prevBinaryOp !== 'AND' && prevBinaryOp !== 'OR') { + sql = `CASE WHEN ${sql} THEN 1 ELSE 0 END ${colAlias}`; + } else { + sql = `${sql} ${colAlias}`; + } + } const query = knex.raw(sql); if (prevBinaryOp && pt.operator !== prevBinaryOp) { query.wrap('(', ')'); From 5c72e923aaa4d5eea883d59c0cc47d3311988031 Mon Sep 17 00:00:00 2001 From: Wing-Kam Wong Date: Fri, 23 Dec 2022 17:18:35 +0800 Subject: [PATCH 7/7] fix(nocodb): fix formula queries --- .../sql/formulav2/formulaQueryBuilderv2.ts | 31 +++++++------------ .../lib/sql/functionMappings/pg.ts | 24 ++++++++++++++ .../lib/sql/functionMappings/sqlite.ts | 24 ++++++++++++++ 3 files changed, 60 insertions(+), 19 deletions(-) diff --git a/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/formulav2/formulaQueryBuilderv2.ts b/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/formulav2/formulaQueryBuilderv2.ts index 8b091d2fa8..b9a47522d1 100644 --- a/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/formulav2/formulaQueryBuilderv2.ts +++ b/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/formulav2/formulaQueryBuilderv2.ts @@ -722,37 +722,30 @@ export default async function formulaQueryBuilderv2( : 0 }) ${colAlias}`; } else if ( + knex.clientType() === 'sqlite3' || knex.clientType() === 'pg' || - knex.clientType() === 'sqlite3' + knex.clientType() === 'mssql' ) { - sql = `COALESCE(${left} ${pt.operator} ${right}, ${ - pt.operator === '=' - ? pt.left.type === 'Literal' - ? pt.left.value === '' - : pt.right.value === '' - : pt.operator === '!=' - ? pt.left.type !== 'Literal' - ? pt.left.value === '' - : pt.right.value === '' - : false - }) ${colAlias}`; - } else if (knex.clientType() === 'mssql') { if (pt.operator === '=') { if (pt.left.type === 'Literal' && pt.left.value === '') { - sql = `${right} IS NULL OR ${right} = ''`; + sql = `${right} IS NULL OR CAST(${right} AS TEXT) = ''`; } else if (pt.right.type === 'Literal' && pt.right.value === '') { - sql = `${left} IS NULL OR ${left} = ''`; + sql = `${left} IS NULL OR CAST(${left} AS TEXT) = ''`; } } else if (pt.operator === '!=') { if (pt.left.type === 'Literal' && pt.left.value === '') { - sql = `${right} IS NOT NULL AND ${right} != ''`; + sql = `${right} IS NOT NULL AND CAST(${right} AS TEXT) != ''`; } else if (pt.right.type === 'Literal' && pt.right.value === '') { - sql = `${left} IS NOT NULL AND ${left} != ''`; + sql = `${left} IS NOT NULL AND CAST(${left} AS TEXT) != ''`; } } - if (prevBinaryOp !== 'AND' && prevBinaryOp !== 'OR') { - sql = `CASE WHEN ${sql} THEN 1 ELSE 0 END ${colAlias}`; + if ( + (pt.operator === '=' || pt.operator === '!=') && + prevBinaryOp !== 'AND' && + prevBinaryOp !== 'OR' + ) { + sql = `(CASE WHEN ${sql} THEN true ELSE false END ${colAlias})`; } else { sql = `${sql} ${colAlias}`; } diff --git a/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/functionMappings/pg.ts b/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/functionMappings/pg.ts index 72ee49bcfa..1157d853cf 100644 --- a/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/functionMappings/pg.ts +++ b/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/functionMappings/pg.ts @@ -114,6 +114,30 @@ const pg = { )} % 7 + 7) ::INTEGER % 7 ${colAlias}` ); }, + AND: (args: MapFnArgs) => { + return args.knex.raw( + `CASE WHEN ${args.knex + .raw( + `${args.pt.arguments + .map((ar) => args.fn(ar, '', 'AND').toQuery()) + .join(' AND ')}` + ) + .wrap('(', ')') + .toQuery()} THEN 1 ELSE 0 END ${args.colAlias}` + ); + }, + OR: (args: MapFnArgs) => { + return args.knex.raw( + `CASE WHEN ${args.knex + .raw( + `${args.pt.arguments + .map((ar) => args.fn(ar, '', 'OR').toQuery()) + .join(' OR ')}` + ) + .wrap('(', ')') + .toQuery()} THEN 1 ELSE 0 END ${args.colAlias}` + ); + }, }; export default pg; diff --git a/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/functionMappings/sqlite.ts b/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/functionMappings/sqlite.ts index ad384aeedf..9c5f500431 100644 --- a/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/functionMappings/sqlite.ts +++ b/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/functionMappings/sqlite.ts @@ -152,6 +152,30 @@ const sqlite3 = { )} % 7 + 7) % 7 ${colAlias}` ); }, + AND: (args: MapFnArgs) => { + return args.knex.raw( + `CASE WHEN ${args.knex + .raw( + `${args.pt.arguments + .map((ar) => args.fn(ar, '', 'AND').toQuery()) + .join(' AND ')}` + ) + .wrap('(', ')') + .toQuery()} THEN 1 ELSE 0 END ${args.colAlias}` + ); + }, + OR: (args: MapFnArgs) => { + return args.knex.raw( + `CASE WHEN ${args.knex + .raw( + `${args.pt.arguments + .map((ar) => args.fn(ar, '', 'OR').toQuery()) + .join(' OR ')}` + ) + .wrap('(', ')') + .toQuery()} THEN 1 ELSE 0 END ${args.colAlias}` + ); + }, }; export default sqlite3;