|
|
@ -3,11 +3,13 @@ import { jsepCurlyHook, UITypes } from 'nocodb-sdk'; |
|
|
|
import mapFunctionName from '../mapFunctionName'; |
|
|
|
import mapFunctionName from '../mapFunctionName'; |
|
|
|
import genRollupSelectv2 from '../genRollupSelectv2'; |
|
|
|
import genRollupSelectv2 from '../genRollupSelectv2'; |
|
|
|
import FormulaColumn from '../../../../../models/FormulaColumn'; |
|
|
|
import FormulaColumn from '../../../../../models/FormulaColumn'; |
|
|
|
import { validateDateWithUnknownFormat } from '../helpers/formulaFnHelper'; |
|
|
|
import { |
|
|
|
|
|
|
|
convertDateFormatForConcat, |
|
|
|
|
|
|
|
validateDateWithUnknownFormat, |
|
|
|
|
|
|
|
} from '../helpers/formulaFnHelper'; |
|
|
|
import { CacheGetType, CacheScope } from '../../../../../utils/globals'; |
|
|
|
import { CacheGetType, CacheScope } from '../../../../../utils/globals'; |
|
|
|
import NocoCache from '../../../../../cache/NocoCache'; |
|
|
|
import NocoCache from '../../../../../cache/NocoCache'; |
|
|
|
import Column from '../../../../../models/Column'; |
|
|
|
import type Column from '../../../../../models/Column'; |
|
|
|
import { convertDateFormat } from '../helpers/convertDateFormat'; |
|
|
|
|
|
|
|
import type Model from '../../../../../models/Model'; |
|
|
|
import type Model from '../../../../../models/Model'; |
|
|
|
import type RollupColumn from '../../../../../models/RollupColumn'; |
|
|
|
import type RollupColumn from '../../../../../models/RollupColumn'; |
|
|
|
import type { XKnex } from '../../../index'; |
|
|
|
import type { XKnex } from '../../../index'; |
|
|
@ -636,38 +638,15 @@ async function _formulaQueryBuilder( |
|
|
|
pt.arguments.map(async (arg) => { |
|
|
|
pt.arguments.map(async (arg) => { |
|
|
|
let query = (await fn(arg)).builder.toQuery(); |
|
|
|
let query = (await fn(arg)).builder.toQuery(); |
|
|
|
if (pt.callee.name === 'CONCAT') { |
|
|
|
if (pt.callee.name === 'CONCAT') { |
|
|
|
if ( |
|
|
|
if (knex.clientType() !== 'sqlite3') { |
|
|
|
arg.type === 'Identifier' && |
|
|
|
query = await convertDateFormatForConcat( |
|
|
|
arg.name in columnIdToUidt && |
|
|
|
arg, |
|
|
|
columnIdToUidt[arg.name] === UITypes.Date |
|
|
|
columnIdToUidt, |
|
|
|
) { |
|
|
|
query, |
|
|
|
const meta = ( |
|
|
|
knex.clientType() |
|
|
|
await Column.get({ |
|
|
|
); |
|
|
|
colId: arg.name, |
|
|
|
} else { |
|
|
|
}) |
|
|
|
// sqlite3: special handling - See BinaryExpression
|
|
|
|
).meta; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (knex.clientType() === 'mysql2') { |
|
|
|
|
|
|
|
query = `DATE_FORMAT(${query}, '${convertDateFormat( |
|
|
|
|
|
|
|
meta.date_format, |
|
|
|
|
|
|
|
knex.clientType() |
|
|
|
|
|
|
|
)}')`;
|
|
|
|
|
|
|
|
} else if (knex.clientType() === 'pg') { |
|
|
|
|
|
|
|
query = `TO_CHAR(${query}, '${convertDateFormat( |
|
|
|
|
|
|
|
meta.date_format, |
|
|
|
|
|
|
|
knex.clientType() |
|
|
|
|
|
|
|
)}')`;
|
|
|
|
|
|
|
|
} else if (knex.clientType() === 'sqlite') { |
|
|
|
|
|
|
|
query = `strftime('${convertDateFormat( |
|
|
|
|
|
|
|
meta.date_format, |
|
|
|
|
|
|
|
knex.clientType() |
|
|
|
|
|
|
|
)}', ${query})`;
|
|
|
|
|
|
|
|
} else if (knex.clientType() === 'mssql') { |
|
|
|
|
|
|
|
query = `FORMAT(${query}, '${convertDateFormat( |
|
|
|
|
|
|
|
meta.date_format, |
|
|
|
|
|
|
|
knex.clientType() |
|
|
|
|
|
|
|
)}')`;
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (knex.clientType() === 'mysql2') { |
|
|
|
if (knex.clientType() === 'mysql2') { |
|
|
@ -714,8 +693,8 @@ async function _formulaQueryBuilder( |
|
|
|
pt.left.fnName = pt.left.fnName || 'ARITH'; |
|
|
|
pt.left.fnName = pt.left.fnName || 'ARITH'; |
|
|
|
pt.right.fnName = pt.right.fnName || 'ARITH'; |
|
|
|
pt.right.fnName = pt.right.fnName || 'ARITH'; |
|
|
|
|
|
|
|
|
|
|
|
const left = (await fn(pt.left, null, pt.operator)).builder.toQuery(); |
|
|
|
let left = (await fn(pt.left, null, pt.operator)).builder.toQuery(); |
|
|
|
const right = (await fn(pt.right, null, pt.operator)).builder.toQuery(); |
|
|
|
let right = (await fn(pt.right, null, pt.operator)).builder.toQuery(); |
|
|
|
let sql = `${left} ${pt.operator} ${right}${colAlias}`; |
|
|
|
let sql = `${left} ${pt.operator} ${right}${colAlias}`; |
|
|
|
|
|
|
|
|
|
|
|
// comparing a date with empty string would throw
|
|
|
|
// comparing a date with empty string would throw
|
|
|
@ -759,8 +738,22 @@ async function _formulaQueryBuilder( |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// handle NULL values when calling CONCAT for sqlite3
|
|
|
|
|
|
|
|
if (pt.left.fnName === 'CONCAT' && knex.clientType() === 'sqlite3') { |
|
|
|
if (pt.left.fnName === 'CONCAT' && knex.clientType() === 'sqlite3') { |
|
|
|
|
|
|
|
// handle date format
|
|
|
|
|
|
|
|
left = await convertDateFormatForConcat( |
|
|
|
|
|
|
|
pt.left?.arguments?.[0], |
|
|
|
|
|
|
|
columnIdToUidt, |
|
|
|
|
|
|
|
left, |
|
|
|
|
|
|
|
knex.clientType() |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
right = await convertDateFormatForConcat( |
|
|
|
|
|
|
|
pt.right?.arguments?.[0], |
|
|
|
|
|
|
|
columnIdToUidt, |
|
|
|
|
|
|
|
right, |
|
|
|
|
|
|
|
knex.clientType() |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// handle NULL values when calling CONCAT for sqlite3
|
|
|
|
sql = `COALESCE(${left}, '') ${pt.operator} COALESCE(${right},'')${colAlias}`; |
|
|
|
sql = `COALESCE(${left}, '') ${pt.operator} COALESCE(${right},'')${colAlias}`; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|