diff --git a/hana/lib/HANAService.js b/hana/lib/HANAService.js index 312f3fb38..70046672d 100644 --- a/hana/lib/HANAService.js +++ b/hana/lib/HANAService.js @@ -866,6 +866,7 @@ class HANAService extends SQLService { if (up in caseOperators) break continue } + if (cur.func?.toUpperCase() === 'CONTAINS' && cur.args?.length > 2) return true if ('_internal' in cur) return true if ('xpr' in cur) return this.is_comparator(cur) } @@ -1255,6 +1256,9 @@ const compareOperators = { 'IS NOT': 1, 'EXISTS': 1, 'BETWEEN': 1, + 'CONTAINS': 1, + 'MEMBER OF': 1, + 'LIKE_REGEXPR': 1, } module.exports = HANAService diff --git a/hana/lib/cql-functions.js b/hana/lib/cql-functions.js index 1bc2a65be..2aa962c4f 100644 --- a/hana/lib/cql-functions.js +++ b/hana/lib/cql-functions.js @@ -21,7 +21,7 @@ const StandardFunctions = { count: x => `count(${x || '*'})`, countdistinct: x => `count(distinct ${x || '*'})`, average: x => `avg(${x})`, - contains: (...args) => `(CASE WHEN coalesce(locate(${args}),0)>0 THEN TRUE ELSE FALSE END)`, + contains: (...args) => args.length > 2 ? `CONTAINS(${args})` : `(CASE WHEN coalesce(locate(${args}),0)>0 THEN TRUE ELSE FALSE END)`, search: function (ref, arg) { if (!('val' in arg)) throw `HANA only supports single value arguments for $search` const refs = ref.list || [ref], diff --git a/hana/test/fuzzy.cds b/hana/test/fuzzy.cds new file mode 100644 index 000000000..977c4458a --- /dev/null +++ b/hana/test/fuzzy.cds @@ -0,0 +1 @@ +using {sap.capire.bookshop.Books as Books} from '../../test/bookshop/db/schema.cds'; diff --git a/hana/test/fuzzy.test.js b/hana/test/fuzzy.test.js new file mode 100644 index 000000000..857717c8f --- /dev/null +++ b/hana/test/fuzzy.test.js @@ -0,0 +1,19 @@ +const cds = require('../../test/cds') + +describe('Fuzzy search', () => { + const { expect } = cds.test(__dirname, 'fuzzy.cds') + + test('select', async () => { + const { Books } = cds.entities('sap.capire.bookshop') + const res = await SELECT.from(Books).where({ + func: 'contains', + args: [ + { list: [{ ref: ['title'] }, { ref: ['descr'] }] }, + { val: 'poem' }, + { func: 'FUZZY', args: [{ val: 0.8 }, { val: 'similarCalculationMode=searchCompare' }] } + ] + }) + + expect(res).to.have.property('length').to.be.eq(1) + }) +}) \ No newline at end of file