Fix bug in Mongo query construction

This commit is contained in:
Zaid Humaimidi committed 2024-04-18 11:51:29 -07:00
1 parent 0f6604ffbd
commit 307b9f57b0
1 file changed
+19 -7
+19 -7
View File
@@ -578,6 +578,8 @@ class MongoSynthContext extends SynthContextBase<Clause, MongoClause> {
toQuery(minterms: Minterm[]): Filter<unknown> { toQuery(minterms: Minterm[]): Filter<unknown> {
const or = []; const or = [];
const ejsonOps = ["$oid", "$date", "$regularExpression"];
for (const minterm of minterms) { for (const minterm of minterms) {
const query = {}; const query = {};
loop: for (const clause of minterm) { loop: for (const clause of minterm) {
@@ -588,8 +590,6 @@ class MongoSynthContext extends SynthContextBase<Clause, MongoClause> {
if (Object.keys(q).length !== 1) if (Object.keys(q).length !== 1)
throw new Error("Invalid query expression"); throw new Error("Invalid query expression");
const [param, value] = Object.entries(q)[0]; const [param, value] = Object.entries(q)[0];
if (Object.getPrototypeOf(value).constructor !== Object)
throw new Error("Invalid query expression");
const dests = [query, ...(query["$and"] ?? [])]; const dests = [query, ...(query["$and"] ?? [])];
for (const dest of dests) { for (const dest of dests) {
if (!(param in dest)) { if (!(param in dest)) {
@@ -599,16 +599,28 @@ class MongoSynthContext extends SynthContextBase<Clause, MongoClause> {
let src = value; let src = value;
let dst = dest[param]; let dst = dest[param];
if (Object.getPrototypeOf(src).constructor !== Object) continue;
if (Object.getPrototypeOf(dst).constructor !== Object) continue;
let srcKeys = Object.keys(src);
let dstKeys = Object.keys(dst);
if (src["$not"] && dst["$not"]) { if ([...srcKeys, ...dstKeys].every((k) => k === "$not")) {
src = src["$not"]; src = src["$not"];
dst = dst["$not"]; dst = dst["$not"];
if (Object.getPrototypeOf(src).constructor !== Object) continue;
if (Object.getPrototypeOf(dst).constructor !== Object) continue;
srcKeys = Object.keys(src);
dstKeys = Object.keys(dst);
} }
if (!Object.keys(src).some((k) => k in dst)) { if (srcKeys.some((k) => dstKeys.includes(k))) continue;
Object.assign(dst, src);
continue loop; // Don't mix regular operators with EJSON special operators
} if (srcKeys.some((k) => ejsonOps.includes(k))) continue;
if (dstKeys.some((k) => ejsonOps.includes(k))) continue;
Object.assign(dst, src);
continue loop;
} }
query["$and"] ??= []; query["$and"] ??= [];