Browse Source

fix(gui): cast division output to float in formula

re #530

Signed-off-by: Pranav C <pranavxc@gmail.com>
pull/559/head
Pranav C 3 years ago
parent
commit
a98c9321fa
  1. 37
      packages/nocodb/src/lib/dataMapper/lib/sql/formulaQueryBuilderFromString.ts
  2. 15
      packages/nocodb/src/lib/dataMapper/lib/sql/functionMappings/commonFns.ts
  3. 4
      packages/nocodb/src/lib/dataMapper/lib/sql/functionMappings/mssql.ts
  4. 3
      packages/nocodb/src/lib/dataMapper/lib/sql/functionMappings/mysql.ts
  5. 3
      packages/nocodb/src/lib/dataMapper/lib/sql/functionMappings/pg.ts
  6. 3
      packages/nocodb/src/lib/dataMapper/lib/sql/functionMappings/sqlite.ts
  7. 8
      packages/nocodb/src/lib/dataMapper/lib/sql/mapFunctionName.ts

37
packages/nocodb/src/lib/dataMapper/lib/sql/formulaQueryBuilderFromString.ts

@ -27,18 +27,18 @@ export default function formulaQueryBuilder(tree, alias, knex, aliasToColumn = {
return fn(pt.arguments[0], a, prevBinaryOp)
}
break;
case 'AVG':
if (pt.arguments.length > 1) {
return fn({
type: 'BinaryExpression',
operator: '/',
left: {...pt, callee: {name: 'SUM'}},
right: {type: 'Literal', value: pt.arguments.length}
}, a, prevBinaryOp)
} else {
return fn(pt.arguments[0], a, prevBinaryOp)
}
break;
// case 'AVG':
// if (pt.arguments.length > 1) {
// return fn({
// type: 'BinaryExpression',
// operator: '/',
// left: {...pt, callee: {name: 'SUM'}},
// right: {type: 'Literal', value: pt.arguments.length}
// }, a, prevBinaryOp)
// } else {
// return fn(pt.arguments[0], a, prevBinaryOp)
// }
// break;
case 'CONCAT':
if (knex.clientType() === 'sqlite3') {
if (pt.arguments.length > 1) {
@ -54,7 +54,7 @@ export default function formulaQueryBuilder(tree, alias, knex, aliasToColumn = {
}
break;
default: {
const res = mapFunctionName({pt, knex, alias, aliasToCol: aliasToColumn, fn, colAlias})
const res = mapFunctionName({pt, knex, alias, a, aliasToCol: aliasToColumn, fn, colAlias, prevBinaryOp})
if (res) return res;
}
break
@ -70,6 +70,17 @@ export default function formulaQueryBuilder(tree, alias, knex, aliasToColumn = {
pt.operator = '='
}
if (pt.operator === '/') {
pt.left = {
callee: {name: 'FLOAT'},
type: 'CallExpression',
arguments: [
pt.left
]
}
}
const query = knex.raw(`${fn(pt.left, null, pt.operator).toQuery()} ${pt.operator} ${fn(pt.right, null, pt.operator).toQuery()}${colAlias}`)
if (prevBinaryOp && pt.operator !== prevBinaryOp) {
query.wrap('(', ')')

15
packages/nocodb/src/lib/dataMapper/lib/sql/functionMappings/commonFns.ts

@ -31,4 +31,19 @@ export default {
OR: (args: MapFnArgs) => {
return args.knex.raw(`${args.knex.raw(`${args.pt.arguments.map(ar => args.fn(ar).toQuery()).join(' OR ')}`).wrap('(', ')').toQuery()}${args.colAlias}`)
},
AVG: (args: MapFnArgs) => {
if (args.pt.arguments.length > 1) {
return args.fn({
type: 'BinaryExpression',
operator: '/',
left: {...args.pt, callee: {name: 'SUM'}},
right: {type: 'Literal', value: args.pt.arguments.length}
}, args.a, args.prevBinaryOp)
} else {
return args.fn(args.pt.arguments[0], args.a, args.prevBinaryOp)
}
},
FLOAT: (args: MapFnArgs) => {
return args.fn(args.pt?.arguments?.[0]).wrap('(',')');
}
}

4
packages/nocodb/src/lib/dataMapper/lib/sql/functionMappings/mssql.ts

@ -52,6 +52,8 @@ const mssql = {
return args.knex.raw(`CASE WHEN ISNUMERIC(${args.fn(args.pt.arguments[0]).toQuery()}) = 1 THEN FLOOR(${args.fn(args.pt.arguments[0]).toQuery()}) ELSE 0 END${args.colAlias}`)
},
MID:'SUBSTR',
}
FLOAT: (args: MapFnArgs) => {
return args.knex.raw(`CAST(${args.fn(args.pt.arguments[0])} as FLOAT)${args.colAlias}`).wrap('(',')')
}}
export default mssql;

3
packages/nocodb/src/lib/dataMapper/lib/sql/functionMappings/mysql.ts

@ -23,6 +23,9 @@ const mysql2 = {
return args.knex.raw(`SUBSTR(${args.fn(args.pt.arguments[0])},-${args.fn(args.pt.arguments[1])})${args.colAlias}`)
},
MID:'SUBSTR',
FLOAT: (args: MapFnArgs) => {
return args.knex.raw(`CAST(${args.fn(args.pt.arguments[0])} as DOUBLE)${args.colAlias}`).wrap('(',')')
}
}

3
packages/nocodb/src/lib/dataMapper/lib/sql/functionMappings/pg.ts

@ -18,6 +18,9 @@ const pg = {
return args.knex.raw(`REGEXP_REPLACE(COALESCE(${args.fn(args.pt.arguments[0])}::character varying, '0'), '[^0-9]+|\\.[0-9]+' ,'')${args.colAlias}`)
},
MID: 'SUBSTR',
FLOAT: (args: MapFnArgs) => {
return args.knex.raw(`CAST(${args.fn(args.pt.arguments[0])} as DOUBLE PRECISION)${args.colAlias}`).wrap('(',')')
}
}

3
packages/nocodb/src/lib/dataMapper/lib/sql/functionMappings/sqlite.ts

@ -33,6 +33,9 @@ const sqlite3 = {
return args.knex.raw(`SUBSTR(${args.fn(args.pt.arguments[0])},-${args.fn(args.pt.arguments[1])})${args.colAlias}`)
},
MID: 'SUBSTR',
FLOAT: (args: MapFnArgs) => {
return args.knex.raw(`CAST(${args.fn(args.pt.arguments[0])} as FLOAT)${args.colAlias}`).wrap('(',')')
}
}

8
packages/nocodb/src/lib/dataMapper/lib/sql/mapFunctionName.ts

@ -10,13 +10,17 @@ export interface MapFnArgs {
aliasToCol: { [alias: string]: string },
knex: XKnex,
alias: string,
fn: (...args: any) => QueryBuilder,
colAlias:string
a?: string,
fn: (...args: any) => QueryBuilder | any,
colAlias: string,
prevBinaryOp?: any
}
const mapFunctionName = (args: MapFnArgs): any => {
const name = args.pt.callee.name;
let val;
switch (args.knex.clientType()) {
case 'mysql':
case 'mysql2':

Loading…
Cancel
Save