Implement CASE operator

This also modifies the behavior of AND/OR operators to strictly return
true/false/null whereas previously they could return the value of the
first truthy/false operand. The purpose of this change is to maintain
expression equivalency before and after minimization.
This commit is contained in:
Zaid Abdulla committed 2020-08-15 14:07:45 -07:00
1 parent e3ef177842
commit 6cbd59c6ec
8 files changed
+598 -273

No files matched your search

+13 -4
View File
@@ -24,6 +24,7 @@ import Autocomplete from "./autocomplete-compnent";
import * as smartQuery from "./smart-query";
import { filterToMongoQuery } from "../lib/mongodb-functions";
import { Expression } from "../lib/types";
import { normalize } from "../lib/common/boolean-expression";
const getAutocomplete = memoize((resource) => {
const labels = smartQuery.getLabels(resource);
@@ -41,6 +42,12 @@ const getAutocomplete = memoize((resource) => {
return autocomplete;
});
function validateQuery(q: Expression): void {
q = normalize(q);
if (Array.isArray(q) && q[0] === "CASE") q = ["AND", ...q.slice(1)];
filterToMongoQuery(q);
}
function parseFilter(resource, f): Expression {
let exp;
if (/^[\s0-9a-zA-Z]+:/.test(f)) {
@@ -51,11 +58,13 @@ function parseFilter(resource, f): Expression {
exp = parse(f);
}
// Throw exception if invalid Mongo query
filterToMongoQuery(
// Throws exception if invalid Mongo query
validateQuery(
map(exp, (e) => {
if (Array.isArray(e) && e[0] === "FUNC" && e[1] === "Q")
return smartQuery.unpack(resource, e[2], e[3]);
if (Array.isArray(e) && e[0] === "FUNC") {
if (e[1] === "Q") return smartQuery.unpack(resource, e[2], e[3]);
else if (e[1] === "NOW") return Date.now();
}
return e;
})
);