Browse Source

fix(nocodb): formula function builder return statement correction

Signed-off-by: Pranav C <pranavxc@gmail.com>
pull/5392/head
Pranav C 2 years ago
parent
commit
7cac920274
  1. 182
      packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/functionMappings/mssql.ts
  2. 216
      packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/functionMappings/sqlite.ts

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

@ -14,9 +14,7 @@ const mssql = {
for (const [i, arg] of Object.entries(args.pt.arguments)) { for (const [i, arg] of Object.entries(args.pt.arguments)) {
if (+i === args.pt.arguments.length - 1) { if (+i === args.pt.arguments.length - 1) {
query += args.knex query += args.knex
.raw( .raw(`\n\tElse ${(await args.fn(arg)).builder.builder.toQuery()}`)
`\n\tElse ${(await await args.fn(arg)).builder.builder.toQuery()}`
)
.toQuery(); .toQuery();
} else { } else {
query += args.knex query += args.knex
@ -37,7 +35,7 @@ const mssql = {
.toQuery(); .toQuery();
} }
} }
return args.knex.raw(`Case ${query}\n End${args.colAlias}`); return { builder: args.knex.raw(`Case ${query}\n End${args.colAlias}`) };
}, },
MAX: async (args: MapFnArgs) => { MAX: async (args: MapFnArgs) => {
if (args.pt.arguments.length === 1) { if (args.pt.arguments.length === 1) {
@ -66,18 +64,20 @@ const mssql = {
} }
} }
return args.knex.raw(`Case ${query}\n End${args.colAlias}`); return { builder: args.knex.raw(`Case ${query}\n End${args.colAlias}`) };
}, },
LOG: async (args: MapFnArgs) => { LOG: async (args: MapFnArgs) => {
return args.knex.raw( return {
`LOG(${( builder: args.knex.raw(
await Promise.all( `LOG(${(
args.pt.arguments await Promise.all(
.reverse() args.pt.arguments
.map(async (ar) => (await args.fn(ar)).builder.toQuery()) .reverse()
) .map(async (ar) => (await args.fn(ar)).builder.toQuery())
).join(',')})${args.colAlias}` )
); ).join(',')})${args.colAlias}`
),
};
}, },
MOD: (pt) => { MOD: (pt) => {
Object.assign(pt, { Object.assign(pt, {
@ -96,94 +96,118 @@ const mssql = {
args.pt.arguments[1] = temp; args.pt.arguments[1] = temp;
}, },
INT: async (args: MapFnArgs) => { INT: async (args: MapFnArgs) => {
return args.knex.raw( return {
`CASE WHEN ISNUMERIC(${( builder: args.knex.raw(
await args.fn(args.pt.arguments[0]) `CASE WHEN ISNUMERIC(${(
).builder.toQuery()}) = 1 THEN FLOOR(${( await args.fn(args.pt.arguments[0])
await args.fn(args.pt.arguments[0]) ).builder.toQuery()}) = 1 THEN FLOOR(${(
).builder.toQuery()}) ELSE 0 END${args.colAlias}` await args.fn(args.pt.arguments[0])
); ).builder.toQuery()}) ELSE 0 END${args.colAlias}`
),
};
}, },
MID: 'SUBSTR', MID: 'SUBSTR',
FLOAT: (args: MapFnArgs) => { FLOAT: async (args: MapFnArgs) => {
return args.knex return {
.raw(`CAST(${args.fn(args.pt.arguments[0])} as FLOAT)${args.colAlias}`) builder: args.knex
.wrap('(', ')'); .raw(
`CAST(${(await args.fn(args.pt.arguments[0])).builder} as FLOAT)${
args.colAlias
}`
)
.wrap('(', ')'),
};
}, },
DATEADD: async ({ fn, knex, pt, colAlias }: MapFnArgs) => { DATEADD: async ({ fn, knex, pt, colAlias }: MapFnArgs) => {
const dateIN = (await fn(pt.arguments[1])).builder; const dateIN = (await fn(pt.arguments[1])).builder;
return knex.raw( return {
`CASE builder: knex.raw(
WHEN ${fn(pt.arguments[0])} LIKE '%:%' THEN `CASE
FORMAT(DATEADD(${String(fn(pt.arguments[2])).replace(/["']/g, '')}, WHEN ${(await fn(pt.arguments[0])).builder} LIKE '%:%' THEN
${dateIN > 0 ? '+' : ''}${fn(pt.arguments[1])}, ${fn( FORMAT(DATEADD(${String((await fn(pt.arguments[2])).builder).replace(
pt.arguments[0] /["']/g,
)}), 'yyyy-MM-dd HH:mm') ''
)},
${dateIN > 0 ? '+' : ''}${(await fn(pt.arguments[1])).builder}, ${
(await fn(pt.arguments[0])).builder
}), 'yyyy-MM-dd HH:mm')
ELSE ELSE
FORMAT(DATEADD(${String(fn(pt.arguments[2])).replace(/["']/g, '')}, FORMAT(DATEADD(${String((await fn(pt.arguments[2])).builder).replace(
${dateIN > 0 ? '+' : ''}${fn(pt.arguments[1])}, ${fn( /["']/g,
pt.arguments[0] ''
)}), 'yyyy-MM-dd') )},
${dateIN > 0 ? '+' : ''}${(await fn(pt.arguments[1])).builder}, ${fn(
pt.arguments[0]
)}), 'yyyy-MM-dd')
END${colAlias}` END${colAlias}`
); ),
};
}, },
DATETIME_DIFF: async ({ fn, knex, pt, colAlias }: MapFnArgs) => { DATETIME_DIFF: async ({ fn, knex, pt, colAlias }: MapFnArgs) => {
const datetime_expr1 = fn(pt.arguments[0]); const datetime_expr1 = (await fn(pt.arguments[0])).builder;
const datetime_expr2 = fn(pt.arguments[1]); const datetime_expr2 = (await fn(pt.arguments[1])).builder;
const rawUnit = pt.arguments[2] const rawUnit = pt.arguments[2]
? (await fn(pt.arguments[2])).builder.bindings[0] ? (await fn(pt.arguments[2])).builder.bindings[0]
: 'seconds'; : 'seconds';
const unit = convertUnits(rawUnit, 'mssql'); const unit = convertUnits(rawUnit, 'mssql');
return knex.raw( return {
`DATEDIFF(${unit}, ${datetime_expr2}, ${datetime_expr1}) ${colAlias}` builder: knex.raw(
); `DATEDIFF(${unit}, ${datetime_expr2}, ${datetime_expr1}) ${colAlias}`
),
};
}, },
WEEKDAY: async ({ fn, knex, pt, colAlias }: MapFnArgs) => { WEEKDAY: async ({ fn, knex, pt, colAlias }: MapFnArgs) => {
// DATEPART(WEEKDAY, DATE): sunday = 1, monday = 2, ..., saturday = 7 // DATEPART(WEEKDAY, DATE): sunday = 1, monday = 2, ..., saturday = 7
// WEEKDAY() returns an index from 0 to 6 for Monday to Sunday // WEEKDAY() returns an index from 0 to 6 for Monday to Sunday
return knex.raw( return {
`(DATEPART(WEEKDAY, ${ builder: knex.raw(
pt.arguments[0].type === 'Literal' `(DATEPART(WEEKDAY, ${
? `'${dayjs((await fn(pt.arguments[0])).builder).format( pt.arguments[0].type === 'Literal'
'YYYY-MM-DD' ? `'${dayjs((await fn(pt.arguments[0])).builder).format(
)}'` 'YYYY-MM-DD'
: fn(pt.arguments[0]) )}'`
}) - 2 - ${getWeekdayByText( : fn(pt.arguments[0])
pt?.arguments[1]?.value }) - 2 - ${getWeekdayByText(
)} % 7 + 7) % 7 ${colAlias}` pt?.arguments[1]?.value
); )} % 7 + 7) % 7 ${colAlias}`
),
};
}, },
AND: async (args: MapFnArgs) => { AND: async (args: MapFnArgs) => {
return args.knex.raw( return {
`CASE WHEN ${args.knex builder: args.knex.raw(
.raw( `CASE WHEN ${args.knex
`${( .raw(
await Promise.all( `${(
args.pt.arguments.map(async (ar) => await Promise.all(
(await args.fn(ar, '', 'AND')).builder.toQuery() args.pt.arguments.map(async (ar) =>
(await args.fn(ar, '', 'AND')).builder.toQuery()
)
) )
) ).join(' AND ')}`
).join(' AND ')}` )
) .wrap('(', ')')
.wrap('(', ')') .toQuery()} THEN 1 ELSE 0 END ${args.colAlias}`
.toQuery()} THEN 1 ELSE 0 END ${args.colAlias}` ),
); };
}, },
OR: async (args: MapFnArgs) => { OR: async (args: MapFnArgs) => {
return args.knex.raw( return {
`CASE WHEN ${args.knex builder: args.knex.raw(
.raw( `CASE WHEN ${args.knex
`${( .raw(
await Promise.all( `${(
args.pt.arguments.map(async (ar) => await Promise.all(
(await args.fn(ar, '', 'OR')).builder.toQuery() args.pt.arguments.map(async (ar) =>
(await args.fn(ar, '', 'OR')).builder.toQuery()
)
) )
) ).join(' OR ')}`
).join(' OR ')}` )
) .wrap('(', ')')
.wrap('(', ')') .toQuery()} THEN 1 ELSE 0 END ${args.colAlias}`
.toQuery()} THEN 1 ELSE 0 END ${args.colAlias}` ),
); };
}, },
}; };

216
packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/functionMappings/sqlite.ts

@ -12,95 +12,109 @@ const sqlite3 = {
...commonFns, ...commonFns,
LEN: 'LENGTH', LEN: 'LENGTH',
async CEILING(args) { async CEILING(args) {
return args.knex.raw( return {
`round(${(await args.fn(args.pt.arguments[0])).builder} + 0.5)${ builder: args.knex.raw(
args.colAlias `round(${(await args.fn(args.pt.arguments[0])).builder} + 0.5)${
}` args.colAlias
); }`
),
};
}, },
async FLOOR(args) { async FLOOR(args) {
return args.knex.raw( return {
`round(${(await args.fn(args.pt.arguments[0])).builder} - 0.5)${ builder: args.knex.raw(
args.colAlias `round(${(await args.fn(args.pt.arguments[0])).builder} - 0.5)${
}` args.colAlias
); }`
),
};
}, },
MOD: async (args: MapFnArgs) => { MOD: async (args: MapFnArgs) => {
return ( return args.fn({
await args.fn({ type: 'BinaryExpression',
type: 'BinaryExpression', operator: '%',
operator: '%', left: args.pt.arguments[0],
left: args.pt.arguments[0], right: args.pt.arguments[1],
right: args.pt.arguments[1], });
})
).builder;
}, },
async REPEAT(args: MapFnArgs) { async REPEAT(args: MapFnArgs) {
return args.knex.raw( return {
`replace(printf('%.' || ${ builder: args.knex.raw(
(await args.fn(args.pt.arguments[1])).builder `replace(printf('%.' || ${
} || 'c', '/'),'/',${(await args.fn(args.pt.arguments[0])).builder})${ (await args.fn(args.pt.arguments[1])).builder
args.colAlias } || 'c', '/'),'/',${(await args.fn(args.pt.arguments[0])).builder})${
}` args.colAlias
); }`
),
};
}, },
NOW: 'DATE', NOW: 'DATE',
SEARCH: 'INSTR', SEARCH: 'INSTR',
async INT(args: MapFnArgs) { async INT(args: MapFnArgs) {
return args.knex.raw( return {
`CAST(${(await args.fn(args.pt.arguments[0])).builder} as INTEGER)${ builder: args.knex.raw(
args.colAlias `CAST(${(await args.fn(args.pt.arguments[0])).builder} as INTEGER)${
}` args.colAlias
); }`
),
};
}, },
LEFT: async (args: MapFnArgs) => { LEFT: async (args: MapFnArgs) => {
return args.knex.raw( return {
`SUBSTR(${(await args.fn(args.pt.arguments[0])).builder},1,${ builder: args.knex.raw(
(await args.fn(args.pt.arguments[1])).builder `SUBSTR(${(await args.fn(args.pt.arguments[0])).builder},1,${
})${args.colAlias}` (await args.fn(args.pt.arguments[1])).builder
); })${args.colAlias}`
),
};
}, },
RIGHT: async (args: MapFnArgs) => { RIGHT: async (args: MapFnArgs) => {
return args.knex.raw( return {
`SUBSTR(${(await args.fn(args.pt.arguments[0])).builder},-(${ builder: args.knex.raw(
(await args.fn(args.pt.arguments[1])).builder `SUBSTR(${(await args.fn(args.pt.arguments[0])).builder},-(${
}))${args.colAlias}` (await args.fn(args.pt.arguments[1])).builder
); }))${args.colAlias}`
),
};
}, },
MID: 'SUBSTR', MID: 'SUBSTR',
FLOAT: async (args: MapFnArgs) => { FLOAT: async (args: MapFnArgs) => {
return args.knex return {
.raw( builder: args.knex
`CAST(${(await args.fn(args.pt.arguments[0])).builder} as FLOAT)${ .raw(
args.colAlias `CAST(${(await args.fn(args.pt.arguments[0])).builder} as FLOAT)${
}` args.colAlias
) }`
.wrap('(', ')'); )
.wrap('(', ')'),
};
}, },
DATEADD: async ({ fn, knex, pt, colAlias }: MapFnArgs) => { DATEADD: async ({ fn, knex, pt, colAlias }: MapFnArgs) => {
const dateIN = (await fn(pt.arguments[1])).builder; const dateIN = (await fn(pt.arguments[1])).builder;
return knex.raw( return {
`CASE builder: knex.raw(
`CASE
WHEN ${(await fn(pt.arguments[0])).builder} LIKE '%:%' THEN WHEN ${(await fn(pt.arguments[0])).builder} LIKE '%:%' THEN
STRFTIME('%Y-%m-%d %H:%M', DATETIME(DATETIME(${fn( STRFTIME('%Y-%m-%d %H:%M', DATETIME(DATETIME(${fn(
pt.arguments[0] pt.arguments[0]
)}, 'localtime'), )}, 'localtime'),
${dateIN > 0 ? '+' : ''}${ ${dateIN > 0 ? '+' : ''}${
(await fn(pt.arguments[1])).builder (await fn(pt.arguments[1])).builder
} || ' ${String((await fn(pt.arguments[2])).builder).replace( } || ' ${String((await fn(pt.arguments[2])).builder).replace(
/["']/g, /["']/g,
'' ''
)}')) )}'))
ELSE ELSE
DATE(DATETIME(${(await fn(pt.arguments[0])).builder}, 'localtime'), DATE(DATETIME(${(await fn(pt.arguments[0])).builder}, 'localtime'),
${dateIN > 0 ? '+' : ''}${ ${dateIN > 0 ? '+' : ''}${
(await fn(pt.arguments[1])).builder (await fn(pt.arguments[1])).builder
} || ' ${String((await fn(pt.arguments[2])).builder).replace( } || ' ${String((await fn(pt.arguments[2])).builder).replace(
/["']/g, /["']/g,
'' ''
)}') )}')
END${colAlias}` END${colAlias}`
); ),
};
}, },
DATETIME_DIFF: async ({ fn, knex, pt, colAlias }: MapFnArgs) => { DATETIME_DIFF: async ({ fn, knex, pt, colAlias }: MapFnArgs) => {
let datetime_expr1 = (await fn(pt.arguments[0])).builder; let datetime_expr1 = (await fn(pt.arguments[0])).builder;
@ -174,54 +188,60 @@ const sqlite3 = {
default: default:
sql = ''; sql = '';
} }
return knex.raw(`${sql} ${colAlias}`); return { builder: knex.raw(`${sql} ${colAlias}`) };
}, },
WEEKDAY: async ({ fn, knex, pt, colAlias }: MapFnArgs) => { WEEKDAY: async ({ fn, knex, pt, colAlias }: MapFnArgs) => {
// strftime('%w', date) - day of week 0 - 6 with Sunday == 0 // strftime('%w', date) - day of week 0 - 6 with Sunday == 0
// WEEKDAY() returns an index from 0 to 6 for Monday to Sunday // WEEKDAY() returns an index from 0 to 6 for Monday to Sunday
return knex.raw( return {
`(strftime('%w', ${ builder: knex.raw(
pt.arguments[0].type === 'Literal' `(strftime('%w', ${
? `'${dayjs((await fn(pt.arguments[0])).builder).format( pt.arguments[0].type === 'Literal'
'YYYY-MM-DD' ? `'${dayjs((await fn(pt.arguments[0])).builder).format(
)}'` 'YYYY-MM-DD'
: (await fn(pt.arguments[0])).builder )}'`
}) - 1 - ${getWeekdayByText( : (await fn(pt.arguments[0])).builder
pt?.arguments[1]?.value }) - 1 - ${getWeekdayByText(
)} % 7 + 7) % 7 ${colAlias}` pt?.arguments[1]?.value
); )} % 7 + 7) % 7 ${colAlias}`
),
};
}, },
AND: async (args: MapFnArgs) => { AND: async (args: MapFnArgs) => {
return args.knex.raw( return {
`CASE WHEN ${args.knex builder: args.knex.raw(
.raw( `CASE WHEN ${args.knex
`${( .raw(
await Promise.all( `${(
args.pt.arguments.map(async (ar) => await Promise.all(
(await args.fn(ar, '', 'AND')).builder.toQuery() args.pt.arguments.map(async (ar) =>
(await args.fn(ar, '', 'AND')).builder.toQuery()
)
) )
) ).join(' AND ')}`
).join(' AND ')}` )
) .wrap('(', ')')
.wrap('(', ')') .toQuery()} THEN 1 ELSE 0 END ${args.colAlias}`
.toQuery()} THEN 1 ELSE 0 END ${args.colAlias}` ),
); };
}, },
OR: async (args: MapFnArgs) => { OR: async (args: MapFnArgs) => {
return args.knex.raw( return {
`CASE WHEN ${args.knex builder: args.knex.raw(
.raw( `CASE WHEN ${args.knex
`${( .raw(
await Promise.all( `${(
args.pt.arguments.map(async (ar) => await Promise.all(
(await args.fn(ar, '', 'OR')).builder.toQuery() args.pt.arguments.map(async (ar) =>
(await args.fn(ar, '', 'OR')).builder.toQuery()
)
) )
) ).join(' OR ')}`
).join(' OR ')}` )
) .wrap('(', ')')
.wrap('(', ')') .toQuery()} THEN 1 ELSE 0 END ${args.colAlias}`
.toQuery()} THEN 1 ELSE 0 END ${args.colAlias}` ),
); };
}, },
}; };

Loading…
Cancel
Save