def __new__(cls, term, *args): Expression.__new__(cls, *args) field, comparisons = term # comparisons IS A Literal() return AndOp([ getattr(cls.lang, operators[op])([field, Literal(value)]) for op, value in comparisons.value.items() ])
def missing(self, lang): return AndOp([ self.default.missing(lang), OrOp([ self.lhs.missing(lang), self.rhs.missing(lang), EqOp([self.rhs, ZERO]), ]), ]).partial_eval(lang)
def missing(self): return self.lang[AndOp([ self.default.missing(), OrOp([ self.lhs.missing(), self.rhs.missing(), EqOp([self.rhs, ZERO]) ]), ])].partial_eval()
def partial_eval(self): lhs = self.lang[self.lhs].partial_eval() rhs = self.lang[self.rhs].partial_eval() if is_op(lhs, NestedOp): return self.lang[NestedOp( path=lhs.frum.partial_eval(), select=IDENTITY, where=AndOp([lhs.where, NeOp([lhs.select, rhs])]).partial_eval(), sort=lhs.sort.partial_eval(), limit=lhs.limit.partial_eval() )].partial_eval() output = self.lang[AndOp([ lhs.exists(), rhs.exists(), NotOp(BasicEqOp([lhs, rhs])) ])].partial_eval() return output
def partial_eval(self, lang): lhs = (self.lhs).partial_eval(lang) rhs = (self.rhs).partial_eval(lang) if is_op(lhs, NestedOp): return NestedOp( path=lhs.path.partial_eval(lang), select=IDENTITY, where=AndOp([lhs.where, NeOp([lhs.select, rhs])]).partial_eval(lang), sort=lhs.sort.partial_eval(lang), limit=lhs.limit.partial_eval(lang), ).partial_eval(lang) output =AndOp([ lhs.exists(), rhs.exists(), NotOp(BasicEqOp([lhs, rhs])), ]).partial_eval(lang) return output
def missing(self, lang): if self.nulls: if self.default is NULL: return AndOp([t.missing(lang) for t in self.terms]) else: return TRUE else: if self.default is NULL: return OrOp([t.missing(lang) for t in self.terms]) else: return FALSE
def missing(self): if self.nulls: if self.default is NULL: return self.lang[AndOp([t.missing() for t in self.terms])] else: return TRUE else: if self.default is NULL: return self.lang[OrOp([t.missing() for t in self.terms])] else: return FALSE
def partial_eval(self): acc = None terms = [] for t in self.terms: simple = t.partial_eval() if simple is NULL: pass elif is_literal(simple): if acc is None: acc = simple.value else: acc = builtin_ops[self.op](acc, simple.value) else: terms.append(simple) lang = self.lang if len(terms) == 0: if acc == None: return self.default.partial_eval() else: return lang[Literal(acc)] elif self.nulls: # DECISIVE if acc is not None: terms.append(Literal(acc)) output = lang[ WhenOp( AndOp([t.missing() for t in terms]), **{ "then": self.default, "else": operators["basic." + self.op]( [CoalesceOp([t, _jx_identity[self.op]]) for t in terms] ), } ) ].partial_eval() else: # CONSERVATIVE if acc is not None: terms.append(lang[Literal(acc)]) output = lang[ WhenOp( lang[OrOp([t.missing() for t in terms])], **{ "then": self.default, "else": operators["basic." + self.op](terms), } ) ].partial_eval() return output
def missing(self): m = self.whens[-1].missing() for w in reversed(self.whens[0:-1]): when = w.when.partial_eval() if when is FALSE: pass elif when is TRUE: m = w.then.partial_eval().missing() else: m = self.lang[OrOp( [AndOp([when, w.then.partial_eval().missing()]), m])] return m.partial_eval()
def partial_eval(self, lang): value = self.value.partial_eval(lang) superset = self.superset.partial_eval(lang) if superset is NULL: return FALSE elif value is NULL: return NULL elif is_literal(value) and is_literal(superset): return Literal(value() in superset()) elif is_op(value, NestedOp): return NestedOp(value.path, None, AndOp([BasicInOp([value.select, superset]), value.where])).exists().partial_eval(lang) else: return lang.BasicInOp([value, superset])
def missing(self): v = self.value.to_es_script(not_null=True) find = self.find.to_es_script(not_null=True) index = v + ".indexOf(" + find + ", " + self.start.to_es_script() + ")" return self.lang[AndOp([ self.default.missing(), OrOp([ self.value.missing(), self.find.missing(), EqOp([ScriptOp(index), Literal(-1)]), ]), ])]
def missing(self, lang): m = self.whens[-1].missing(lang) for w in reversed(self.whens[0:-1]): when = w.when.partial_eval(lang) if when is FALSE: pass elif when is TRUE: m = w.then.partial_eval(lang).missing(lang) else: m = OrOp([ AndOp([when, w.then.partial_eval(lang).missing(lang)]), m, ]) return m.partial_eval(lang)
def inverse(term): if term is TRUE: return FALSE elif term is FALSE: return TRUE elif term is NULL: return TRUE elif is_literal(term): Log.error("`not` operator expects a Boolean term") elif is_op(term, WhenOp): output = self.lang[ WhenOp( term.when, **{"then": inverse(term.then), "else": inverse(term.els_)} ) ].partial_eval() elif is_op(term, CaseOp): # REWRITING output = self.lang[ CaseOp( [ WhenOp(w.when, **{"then": inverse(w.then)}) if is_op(w, WhenOp) else inverse(w) for w in term.whens ] ) ].partial_eval() elif is_op(term, AndOp): output = self.lang[ OrOp([inverse(t) for t in term.terms]) ].partial_eval() elif is_op(term, OrOp): output = self.lang[ AndOp([inverse(t) for t in term.terms]) ].partial_eval() elif is_op(term, MissingOp): output = self.lang[NotOp(term.expr.missing())] elif is_op(term, ExistsOp): output = term.field.missing().partial_eval() elif is_op(term, NotOp): output = self.lang[term.term].partial_eval() elif is_op(term, NeOp): output = self.lang[EqOp([term.lhs, term.rhs])].partial_eval() elif is_op(term, BasicIndexOfOp) or is_op(term, BasicSubstringOp): return FALSE else: output = self.lang[NotOp(term)] return output
def partial_eval(self): if self.expr is None: return TRUE if not is_literal(self.suffix) and self.suffix.type == STRING: Log.error("can only hanlde literal suffix ") return WhenOp( self.lang[AndOp([self.expr.exists(), self.suffix.exists()])], **{ "then": self.lang[ RegExpOp([self.expr, Literal(".*" + re.escape(self.suffix.value))]) ], "else": FALSE, } ).partial_eval()
def __new__(cls, terms): if is_many(terms): return object.__new__(cls) items = terms.items() if len(items) == 1: if is_many(items[0][1]): return cls.lang[InOp(items[0])] else: return cls.lang[EqOp(items[0])] else: acc = [] for lhs, rhs in items: if rhs.json.startswith("["): acc.append(cls.lang[InOp([Variable(lhs), rhs])]) else: acc.append(cls.lang[EqOp([Variable(lhs), rhs])]) return cls.lang[AndOp(acc)]
def partial_eval(self): lhs = ES52[self.lhs].partial_eval() rhs = ES52[self.rhs].partial_eval() if is_literal(lhs): if is_literal(rhs): return FALSE if value_compare(lhs.value, rhs.value) else TRUE else: lhs, rhs = rhs, lhs # FLIP SO WE CAN USE TERMS FILTER if is_literal(rhs) and same_json_type(lhs.type, BOOLEAN): # SPECIAL CASE true == "T" rhs = string2boolean(rhs.value) if rhs is None: return FALSE rhs = Literal(rhs) return EqOp([lhs, rhs]) if is_op(lhs, NestedOp): return self.lang[NestedOp(path=lhs.frum, where=AndOp( [lhs.where, EqOp([lhs.select, rhs])]))] return EqOp([lhs, rhs])
def missing(self, lang): return AndOp([t.missing(lang) for t in self.terms] + [self.default.missing(lang)]).partial_eval(lang)
def missing(self): return self.lang[AndOp([t.missing() for t in self.terms] + [self.default.missing()])].partial_eval()
def invert(self): return self.lang[AndOp([t.invert() for t in self.terms])].partial_eval()
def exists(self): if self.nulls: return self.lang[OrOp([t.exists() for t in self.terms])] else: return self.lang[AndOp([t.exists() for t in self.terms])]
def invert(self, lang): return AndOp([t.invert(lang) for t in self.terms]).partial_eval(lang)
def exists(self): if self.nulls: return OrOp([t.exists() for t in self.terms]) else: return AndOp([t.exists() for t in self.terms])
def missing(self, lang): # RETURN true FOR RECORDS THE WOULD RETURN NULL return AndOp([v.missing(lang) for v in self.terms])
def missing(self): # RETURN true FOR RECORDS THE WOULD RETURN NULL return self.lang[AndOp([v.missing() for v in self.terms])]
def invert(self, lang): return OrOp([ AndOp([self.when, self.then.invert(lang)]), AndOp([NotOp(self.when), self.els_.invert(lang)]), ]).partial_eval(lang)
def missing(self): return self.lang[OrOp([ AndOp([self.when, self.then.missing()]), AndOp([NotOp(self.when), self.els_.missing()]), ])].partial_eval()
def missing(self, lang): return OrOp([ AndOp([self.when, self.then.missing(lang)]), AndOp([NotOp(self.when), self.els_.missing(lang)]), ]).partial_eval(lang)