Browse Source

Merge pull request #4644 from nocodb/fix/formula-empty-result

fix(nocodb): formula returns empty result when identifier is null
pull/4697/merge
աɨռɢӄաօռɢ 2 years ago committed by GitHub
parent
commit
2a33d8ff68
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      packages/nc-gui/utils/dateTimeUtils.ts
  2. 41
      packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/formulav2/formulaQueryBuilderv2.ts
  3. 24
      packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/functionMappings/mssql.ts
  4. 24
      packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/functionMappings/pg.ts
  5. 24
      packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/functionMappings/sqlite.ts

2
packages/nc-gui/utils/dateTimeUtils.ts

@ -19,7 +19,7 @@ export const dateFormats = [
export const timeFormats = ['HH:mm', 'HH:mm:ss']
export const handleTZ = (val: any) => {
if (!val) {
if (val === undefined || val === null) {
return
}
if (typeof val !== 'string') {

41
packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/formulav2/formulaQueryBuilderv2.ts

@ -709,6 +709,47 @@ 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}`;
} else if (
knex.clientType() === 'sqlite3' ||
knex.clientType() === 'pg' ||
knex.clientType() === 'mssql'
) {
if (pt.operator === '=') {
if (pt.left.type === 'Literal' && pt.left.value === '') {
sql = `${right} IS NULL OR CAST(${right} AS TEXT) = ''`;
} else if (pt.right.type === 'Literal' && pt.right.value === '') {
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 CAST(${right} AS TEXT) != ''`;
} else if (pt.right.type === 'Literal' && pt.right.value === '') {
sql = `${left} IS NOT NULL AND CAST(${left} AS TEXT) != ''`;
}
}
if (
(pt.operator === '=' || pt.operator === '!=') &&
prevBinaryOp !== 'AND' &&
prevBinaryOp !== 'OR'
) {
sql = `(CASE WHEN ${sql} THEN true ELSE false END ${colAlias})`;
} else {
sql = `${sql} ${colAlias}`;
}
}
const query = knex.raw(sql);
if (prevBinaryOp && pt.operator !== prevBinaryOp) {
query.wrap('(', ')');

24
packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/functionMappings/mssql.ts

@ -135,6 +135,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;

24
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;

24
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;

Loading…
Cancel
Save