From f658d56467cb5892bf39889c3aee2e7008ebb57b Mon Sep 17 00:00:00 2001 From: mertmit Date: Wed, 20 Apr 2022 19:21:05 +0300 Subject: [PATCH] fix: handling of negative intervals for DATEADD re #1638 Signed-off-by: mertmit --- .../sql/formulav2/formulaQueryBuilderv2.ts | 17 ++++++------- .../lib/sql/functionMappings/mssql.ts | 23 +++-------------- .../lib/sql/functionMappings/mysql.ts | 16 +----------- .../dataMapper/lib/sql/functionMappings/pg.ts | 21 +--------------- .../lib/sql/functionMappings/sqlite.ts | 25 +++---------------- 5 files changed, 18 insertions(+), 84 deletions(-) diff --git a/packages/nocodb/src/lib/dataMapper/lib/sql/formulav2/formulaQueryBuilderv2.ts b/packages/nocodb/src/lib/dataMapper/lib/sql/formulav2/formulaQueryBuilderv2.ts index 56f0d8227a..7bc9327ab5 100644 --- a/packages/nocodb/src/lib/dataMapper/lib/sql/formulav2/formulaQueryBuilderv2.ts +++ b/packages/nocodb/src/lib/dataMapper/lib/sql/formulav2/formulaQueryBuilderv2.ts @@ -564,15 +564,6 @@ export default async function formulaQueryBuilderv2( } } break; - case 'DATEADD': - if (pt.arguments[1].value) { - pt.callee.name = 'DATE_ADD'; - return fn(pt, alias, prevBinaryOp); - } else if (pt.arguments[1].operator == '-') { - pt.callee.name = 'DATE_SUB'; - return fn(pt, alias, prevBinaryOp); - } - break; case 'URL': return fn( { @@ -654,6 +645,14 @@ export default async function formulaQueryBuilderv2( query.wrap('(', ')'); } return query; + } else if (pt.type === 'UnaryExpression') { + const query = knex.raw( + `${pt.operator}${fn(pt.argument, null, pt.operator).toQuery()}${colAlias}` + ); + if (prevBinaryOp && pt.operator !== prevBinaryOp) { + query.wrap('(', ')'); + } + return query; } }; return { builder: fn(tree, alias) }; diff --git a/packages/nocodb/src/lib/dataMapper/lib/sql/functionMappings/mssql.ts b/packages/nocodb/src/lib/dataMapper/lib/sql/functionMappings/mssql.ts index fc45fc4b9e..2a9bb14d6c 100644 --- a/packages/nocodb/src/lib/dataMapper/lib/sql/functionMappings/mssql.ts +++ b/packages/nocodb/src/lib/dataMapper/lib/sql/functionMappings/mssql.ts @@ -89,31 +89,16 @@ const mssql = { .raw(`CAST(${args.fn(args.pt.arguments[0])} as FLOAT)${args.colAlias}`) .wrap('(', ')'); }, - DATE_ADD: ({ fn, knex, pt, colAlias }: MapFnArgs) => { + DATEADD: ({ fn, knex, pt, colAlias }: MapFnArgs) => { + const dateIN = fn(pt.arguments[1]); return knex.raw( `CASE WHEN ${fn(pt.arguments[0])} LIKE '%:%' THEN FORMAT(DATEADD(${String(fn(pt.arguments[2])).replace(/["']/g, '')}, - +${fn(pt.arguments[1])}, ${fn(pt.arguments[0])}), 'yyyy-MM-dd HH:mm') + ${dateIN > 0 ? '+' : ''}${fn(pt.arguments[1])}, ${fn(pt.arguments[0])}), 'yyyy-MM-dd HH:mm') ELSE FORMAT(DATEADD(${String(fn(pt.arguments[2])).replace(/["']/g, '')}, - +${fn(pt.arguments[1])}, ${fn(pt.arguments[0])}), 'yyyy-MM-dd') - END${colAlias}` - ); - }, - DATE_SUB: ({ fn, knex, pt, colAlias }: MapFnArgs) => { - return knex.raw( - `CASE - WHEN ${fn(pt.arguments[0])} LIKE '%:%' THEN - FORMAT(DATEADD(${String(fn(pt.arguments[2])).replace(/["']/g, '')}, - -${fn(pt.arguments[1])}.argument.value, ${fn( - pt.arguments[0] - )}), 'yyyy-MM-dd HH:mm') - ELSE - FORMAT(DATEADD(${String(fn(pt.arguments[2])).replace(/["']/g, '')}, - -${fn(pt.arguments[1])}.argument.value, ${fn( - pt.arguments[0] - )}), 'yyyy-MM-dd') + ${dateIN > 0 ? '+' : ''}${fn(pt.arguments[1])}, ${fn(pt.arguments[0])}), 'yyyy-MM-dd') END${colAlias}` ); } diff --git a/packages/nocodb/src/lib/dataMapper/lib/sql/functionMappings/mysql.ts b/packages/nocodb/src/lib/dataMapper/lib/sql/functionMappings/mysql.ts index c1602330bb..442914abd8 100644 --- a/packages/nocodb/src/lib/dataMapper/lib/sql/functionMappings/mysql.ts +++ b/packages/nocodb/src/lib/dataMapper/lib/sql/functionMappings/mysql.ts @@ -37,7 +37,7 @@ const mysql2 = { .raw(`CAST(${args.fn(args.pt.arguments[0])} as DOUBLE)${args.colAlias}`) .wrap('(', ')'); }, - DATE_ADD: ({ fn, knex, pt, colAlias }: MapFnArgs) => { + DATEADD: ({ fn, knex, pt, colAlias }: MapFnArgs) => { return knex.raw( `CASE WHEN ${fn(pt.arguments[0])} LIKE '%:%' THEN @@ -54,20 +54,6 @@ const mysql2 = { )})) END${colAlias}` ); - }, - DATE_SUB: ({ fn, knex, pt, colAlias }: MapFnArgs) => { - return knex.raw( - `CASE - WHEN ${fn(pt.arguments[0])} LIKE '%:%' THEN - DATE_FORMAT(DATE_ADD(${fn(pt.arguments[0])}, INTERVAL - ${fn(pt.arguments[1])}.argument.value - ${String(fn(pt.arguments[2])).replace(/["']/g, '')}), '%Y-%m-%d %H:%i') - ELSE - DATE(DATE_ADD(${fn(pt.arguments[0])}, INTERVAL - ${fn(pt.arguments[1])}.argument.value - ${String(fn(pt.arguments[2])).replace(/["']/g, '')})) - END${colAlias}` - ); } }; diff --git a/packages/nocodb/src/lib/dataMapper/lib/sql/functionMappings/pg.ts b/packages/nocodb/src/lib/dataMapper/lib/sql/functionMappings/pg.ts index 6623937741..d0bd041aa3 100644 --- a/packages/nocodb/src/lib/dataMapper/lib/sql/functionMappings/pg.ts +++ b/packages/nocodb/src/lib/dataMapper/lib/sql/functionMappings/pg.ts @@ -33,7 +33,7 @@ const pg = { .raw(`CAST(${fn(pt.arguments[0])} as DOUBLE PRECISION)${colAlias}`) .wrap('(', ')'); }, - DATE_ADD: ({ fn, knex, pt, colAlias }: MapFnArgs) => { + DATEADD: ({ fn, knex, pt, colAlias }: MapFnArgs) => { return knex.raw( `CASE WHEN CAST(${fn(pt.arguments[0])} AS text) LIKE '%:%' THEN @@ -47,25 +47,6 @@ const pg = { ${String(fn(pt.arguments[2])).replace(/["']/g, '')}', 'YYYY-MM-DD') END${colAlias}` ); - }, - DATE_SUB: ({ fn, knex, pt, colAlias }: MapFnArgs) => { - return knex.raw( - `CASE - WHEN CAST(${fn(pt.arguments[0])} AS text) LIKE '%:%' THEN - to_char(${fn(pt.arguments[0])} - INTERVAL '${ - fn(pt.arguments[1]).argument.value - } - ${String(fn(pt.arguments[2])).replace( - /["']/g, - '' - )}', 'YYYY-MM-DD HH24:MI') - ELSE - to_char(${fn(pt.arguments[0])} - INTERVAL '${ - fn(pt.arguments[1]).argument.value - } - ${String(fn(pt.arguments[2])).replace(/["']/g, '')}', 'YYYY-MM-DD') - END${colAlias}` - ); } }; diff --git a/packages/nocodb/src/lib/dataMapper/lib/sql/functionMappings/sqlite.ts b/packages/nocodb/src/lib/dataMapper/lib/sql/functionMappings/sqlite.ts index 72b6e52c2f..67bfe7e88b 100644 --- a/packages/nocodb/src/lib/dataMapper/lib/sql/functionMappings/sqlite.ts +++ b/packages/nocodb/src/lib/dataMapper/lib/sql/functionMappings/sqlite.ts @@ -56,43 +56,26 @@ const sqlite3 = { .raw(`CAST(${args.fn(args.pt.arguments[0])} as FLOAT)${args.colAlias}`) .wrap('(', ')'); }, - DATE_ADD: ({ fn, knex, pt, colAlias }: MapFnArgs) => { + DATEADD: ({ fn, knex, pt, colAlias }: MapFnArgs) => { + const dateIN = fn(pt.arguments[1]); return knex.raw( `CASE WHEN ${fn(pt.arguments[0])} LIKE '%:%' THEN STRFTIME('%Y-%m-%d %H:%M', DATETIME(DATETIME(${fn( pt.arguments[0] )}, 'localtime'), - '+${fn(pt.arguments[1])} ${String(fn(pt.arguments[2])).replace( + '${dateIN > 0 ? '+' : ''}${fn(pt.arguments[1])} ${String(fn(pt.arguments[2])).replace( /["']/g, '' )}')) ELSE DATE(DATETIME(${fn(pt.arguments[0])}, 'localtime'), - '+${fn(pt.arguments[1])} ${String(fn(pt.arguments[2])).replace( + '${dateIN > 0 ? '+' : ''}${fn(pt.arguments[1])} ${String(fn(pt.arguments[2])).replace( /["']/g, '' )}') END${colAlias}` ); - }, - DATE_SUB: ({ fn, knex, pt, colAlias }: MapFnArgs) => { - return knex.raw( - `CASE - WHEN ${fn(pt.arguments[0])} LIKE '%:%' THEN - STRFTIME('%Y-%m-%d %H:%M', DATETIME(DATETIME(${fn( - pt.arguments[0] - )}, 'localtime'), - '-${fn(pt.arguments[1]).argument.value} ${String( - fn(pt.arguments[2]) - ).replace(/["']/g, '')}')) - ELSE - DATE(DATETIME(${fn(pt.arguments[0])}, 'localtime'), - '-${fn(pt.arguments[1]).argument.value} ${String( - fn(pt.arguments[2]) - ).replace(/["']/g, '')}') - END${colAlias}` - ); } };