From c950640ba1e562679ea0b6c56163ee7ac636cef1 Mon Sep 17 00:00:00 2001 From: Nitish Kumar Date: Thu, 19 Oct 2023 19:29:59 +0530 Subject: [PATCH 1/2] fix ast for subquery --- src/pg/filter/getAst.js | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/src/pg/filter/getAst.js b/src/pg/filter/getAst.js index 703f931..ecb7b9f 100644 --- a/src/pg/filter/getAst.js +++ b/src/pg/filter/getAst.js @@ -33,6 +33,22 @@ export default function getAst(filter) { return simplify(construct(filter)); } +function isValidSubQuery(node) { + if (!node || typeof node !== 'object') return false; + + const keys = Object.keys(node); + for (const key of keys) { + if (key[0] === '$' && !['$and', '$or', '$not'].includes(key)) return false; + if (key[0] !== '$') return true; + } + + for (const key in node) { + if (!isValidSubQuery(node[key])) return false; + } + + return false; +} + function construct(node, prop, op) { if (!node || typeof node !== 'object' || (prop && op)) { if (op && prop) return [op, prop, node]; @@ -42,6 +58,11 @@ function construct(node, prop, op) { if (Array.isArray(node)) { return ['$or', node.map((item) => construct(item, prop, op))]; } + + if (prop && isValidSubQuery(node)) { + return ['$sub', prop, construct(node)]; + } + return [ '$and', Object.entries(node).map(([key, val]) => { @@ -58,9 +79,6 @@ function construct(node, prop, op) { if (!prop) throw Error(`pgast.expected_prop_before:${key}`); return construct(val, prop, key); } - if (prop) { - return ['$sub', prop, construct({ [key]: val })]; - } return construct(val, key); }), ]; From a9d7e81d93a0f74f08748f3a7aa88dfa3b6eb41b Mon Sep 17 00:00:00 2001 From: Nitish Kumar Date: Thu, 19 Oct 2023 19:34:08 +0530 Subject: [PATCH 2/2] added test case --- src/pg/filter/getAst.js | 2 +- src/pg/test/filter/getSql.test.js | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/pg/filter/getAst.js b/src/pg/filter/getAst.js index ecb7b9f..7ea24bc 100644 --- a/src/pg/filter/getAst.js +++ b/src/pg/filter/getAst.js @@ -46,7 +46,7 @@ function isValidSubQuery(node) { if (!isValidSubQuery(node[key])) return false; } - return false; + return false; } function construct(node, prop, op) { diff --git a/src/pg/test/filter/getSql.test.js b/src/pg/test/filter/getSql.test.js index d47e4a7..e4cc99e 100644 --- a/src/pg/test/filter/getSql.test.js +++ b/src/pg/test/filter/getSql.test.js @@ -115,6 +115,27 @@ test('join', () => { ); }); +test('join with multiple col', () => { + expect( + getSql( + { posts: { category: 'programming', authorId: 'id1' } }, + { + idCol: 'id', + schema: { types: { id: 'uuid' } }, + joins: { + posts: { + table: 'posts', + refCol: 'authorId', + schema: { types: { category: 'text', authorId: 'text' } }, + }, + }, + }, + ), + ).toEqual( + sql`"id" IN (SELECT "authorId"::uuid FROM "posts" WHERE ("category" = ${'programming'}) AND ("authorId" = ${'id1'}))`, + ); +}); + test('keycts', () => { const value = ['foo@bar.com', 'foo@baz.com']; expect(