예제 #1
0
def to_esfilter(self, schema):
    output = OrOp("or", [
        AndOp("and", [self.when, BooleanOp("boolean", self.then)]),
        AndOp("and", [NotOp("not", self.when), BooleanOp("boolean", self.els_)])
    ]).partial_eval()

    return output.to_esfilter(schema)
예제 #2
0
def to_ruby(self, schema):
    lhs = self.lhs.partial_eval().to_ruby(schema)
    rhs = self.rhs.partial_eval().to_ruby(schema)

    if lhs.many:
        if rhs.many:
            return AndOp("and", [
                Ruby(type=BOOLEAN,
                     expr="(" + lhs.expr + ").size()==(" + rhs.expr +
                     ").size()",
                     frum=self),
                Ruby(type=BOOLEAN,
                     expr="(" + rhs.expr + ").containsAll(" + lhs.expr + ")",
                     frum=self)
            ]).to_ruby(schema)
        else:
            return Ruby(type=BOOLEAN,
                        expr="(" + lhs.expr + ").contains(" + rhs.expr + ")",
                        frum=self)
    elif rhs.many:
        return Ruby(type=BOOLEAN,
                    expr="(" + rhs.expr + ").contains(" + lhs.expr + ")",
                    frum=self)
    else:
        return Ruby(type=BOOLEAN,
                    expr="(" + lhs.expr + "==" + rhs.expr + ")",
                    frum=self)
예제 #3
0
def to_ruby(self, schema):
    if not self.terms:
        return NULL.to_ruby(schema)

    v = self.terms[-1]
    acc = FirstOp("first", v).partial_eval().to_ruby(schema)
    for v in reversed(self.terms[:-1]):
        m = v.missing().partial_eval()
        e = NotOp("not", m).partial_eval().to_ruby(schema)
        r = FirstOp("first", v).partial_eval().to_ruby(schema)

        if r.miss is TRUE:
            continue
        elif r.miss is FALSE:
            acc = r
            continue
        elif acc.type == r.type:
            new_type = r.type
        elif acc.type == NUMBER and r.type == INTEGER:
            new_type = NUMBER
        elif acc.type == INTEGER and r.type == NUMBER:
            new_type = NUMBER
        else:
            new_type = OBJECT

        acc = Ruby(miss=AndOp("and", [acc.miss, m]).partial_eval(),
                   type=new_type,
                   expr="(" + e.expr + ") ? (" + r.expr + ") : (" + acc.expr +
                   ")",
                   frum=self)
    return acc
예제 #4
0
def to_ruby(self, schema):
    acc = NumberOp("number", self.terms[-1]).partial_eval().to_ruby(schema).expr
    for t in reversed(self.terms[0:-1]):
        acc = "Math.min(" + NumberOp("number", t).partial_eval().to_ruby(schema).expr + " , " + acc + ")"
    return Ruby(
        miss=AndOp("or", [t.missing() for t in self.terms]),
        type=NUMBER,
        expr=acc,
        frum=self
    )
def to_es14_script(self, schema, not_null=False, boolean=False, many=True):
    acc = NumberOp("number", self.terms[-1]).partial_eval().to_es14_script(schema).expr
    for t in reversed(self.terms[0:-1]):
        acc = "Math.min(" + NumberOp("number", t).partial_eval().to_es14_script(schema).expr + " , " + acc + ")"
    return EsScript(
        miss=AndOp("or", [t.missing() for t in self.terms]),
        type=NUMBER,
        expr=acc,
        frum=self
    )
예제 #6
0
def to_esfilter(self, schema):
    if self.type == BOOLEAN:
        return OrOp("or",
                    [AndOp("and", [w.when, w.then]) for w in self.whens[:-1]] +
                    self.whens[-1:]).partial_eval().to_esfilter(schema)
    else:
        Log.error("do not know how to handle")
        return ScriptOp(
            "script",
            self.to_es_script(schema).script(schema)).to_esfilter(schema)
    def __and__(self, other):
        """
        MERGE TWO  NestedOp
        """
        if not is_op(other, NestedOp):
            return AndOp([self, other])

        # MERGE
        elif self.path == other.frum:
            return NestedOp(
                self.path,
                listwrap(self.select) + listwrap(other.select),
                AndOp([self.where, other.where]),
                coalesce(self.sort, other.sort),
                coalesce(self.limit, other.limit),
            )

        # NEST
        elif startswith_field(other.frum.var, self.path.var):
            # WE ACHIEVE INTERSECTION BY LIMITING OURSELF TO ONLY THE DEEP OBJECTS
            # WE ASSUME frum SELECTS WHOLE DOCUMENT, SO self.select IS POSSIBLE
            return NestedOp(
                other,
                self.select,
                self.where,
                self.sort,
                self.limit,
            )

        elif startswith_field(self.path.var, other.frum.var):
            return NestedOp(
                self,
                other.select,
                other.where,
                other.sort,
                other.limit,
            )
        else:
            return AndOp([self, other])
예제 #8
0
 def partial_eval(self):
     if is_op(self.lhs, NestedOp):
         return self.lang[NestedOp(
             path=self.lhs.frum.partial_eval(),
             select=IDENTITY,
             where=AndOp([
                 self.lhs.where,
                 BasicEqOp(self.lhs.select, self.rhs),
             ]).partial_eval(),
             sort=self.lhs.sort.partial_eval(),
             limit=self.limit.partial_eval(),
         )]
     return self.lang[BasicEqOp(
         [self.lhs.partial_eval(),
          self.rhs.partial_eval()])]
예제 #9
0
def es_query_proto(path, selects, wheres, schema):
    """
    RETURN TEMPLATE AND PATH-TO-FILTER AS A 2-TUPLE
    :param path: THE NESTED PATH (NOT INCLUDING TABLE NAME)
    :param wheres: MAP FROM path TO LIST OF WHERE CONDITIONS
    :return: (es_query, filters_map) TUPLE
    """
    output = None
    last_where = MATCH_ALL
    for p in reversed(sorted( wheres.keys() | set(selects.keys()))):
        where = wheres.get(p)
        select = selects.get(p)

        if where:
            where = AndOp("and", where).partial_eval().to_esfilter(schema)
            if output:
                where = es_or([es_and([output, where]), where])
        else:
            if output:
                if last_where is MATCH_ALL:
                    where = es_or([output, MATCH_ALL])
                else:
                    where = output
            else:
                where = MATCH_ALL

        if p == ".":
            output = set_default(
                {
                    "from": 0,
                    "size": 0,
                    "sort": [],
                    "query": where
                },
                select.to_es()
            )
        else:
            output = {"nested": {
                "path": p,
                "inner_hits": set_default({"size": 100000}, select.to_es()) if select else None,
                "query": where
            }}

        last_where = where
    return output
예제 #10
0
def to_ruby(self, schema):
    value = self.term.to_ruby(schema)

    if isinstance(self.term, Variable):
        if value.many:
            expr = "!" + value.expr + ".isEmpty() && " + value.expr + "[0]==\"T\""
        else:
            expr = value.expr + "==\"T\""
        return Ruby(miss=FALSE, type=BOOLEAN, expr=expr, frum=self)

    if value.type == BOOLEAN:
        return AndOp(
            "and",
            [ExistsOp("exists", self.term),
             FirstOp("first", self.term)]).partial_eval().to_ruby()

    else:
        return ExistsOp("exists", self.term).partial_eval().to_ruby()
예제 #11
0
def to_ruby(self, schema, not_null=False, boolean=True):
    if isinstance(self.expr, Variable):
        if self.expr.var == "_id":
            return Ruby(type=BOOLEAN, expr="false", frum=self)
        else:
            columns = schema.leaves(self.expr.var)
            if len(columns) == 1:
                return Ruby(type=BOOLEAN,
                            expr="doc[" + quote(columns[0].es_column) +
                            "].isEmpty()",
                            frum=self)
            else:
                return AndOp("and", [
                    Ruby(type=BOOLEAN,
                         expr="doc[" + quote(c.es_column) + "].isEmpty()",
                         frum=self) for c in columns
                ]).partial_eval().to_ruby(schema)
    else:
        return self.expr.missing().partial_eval().to_ruby(schema)
예제 #12
0
def to_ruby(self, schema):
    op, unit = MultiOp.operators[self.op]
    if self.nulls:
        calc = op.join(
            "((" + t.missing().to_ruby(schema).expr + ") ? " + unit + " : (" +
            NumberOp("number", t).partial_eval().to_ruby(schema).expr + "))"
            for t in self.terms)
        return WhenOp(
            "when", AndOp("and", [t.missing() for t in self.terms]), **{
                "then": self.default,
                "else": Ruby(type=NUMBER, expr=calc, frum=self)
            }).partial_eval().to_ruby(schema)
    else:
        calc = op.join("(" + NumberOp("number", t).to_ruby(schema).expr + ")"
                       for t in self.terms)
        return WhenOp(
            "when", OrOp("or", [t.missing() for t in self.terms]), **{
                "then": self.default,
                "else": Ruby(type=NUMBER, expr=calc, frum=self)
            }).partial_eval().to_ruby(schema)
def to_es14_script(self, schema, not_null=False, boolean=False, many=True):
    if isinstance(self.expr, Variable):
        if self.expr.var == "_id":
            return EsScript(type=BOOLEAN, expr="false", frum=self)
        else:
            columns = schema.leaves(self.expr.var)
            if len(columns) == 1:
                return EsScript(type=BOOLEAN, expr="doc[" + quote(first(columns).es_column) + "].isEmpty()", frum=self)
            else:
                return AndOp("and", [
                    EsScript(
                        type=BOOLEAN,
                        expr="doc[" + quote(c.es_column) + "].isEmpty()",
                        frum=self
                    )
                    for c in columns
                ]).partial_eval().to_es14_script(schema)
    elif isinstance(self.expr, Literal):
        return self.expr.missing().to_es14_script(schema)
    else:
        return self.expr.missing().partial_eval().to_es14_script(schema)
def to_es14_script(self, schema, not_null=False, boolean=False, many=True):
    op, unit = _painless_operators[self.op]
    if self.nulls:
        calc = op.join(
            "((" + t.missing().to_es14_script(schema).expr + ") ? " + unit + " : (" + NumberOp("number", t).partial_eval().to_es14_script(schema).expr + "))"
            for t in self.terms
        )
        return WhenOp(
            "when",
            AndOp("and", [t.missing() for t in self.terms]),
            **{"then": self.default, "else": EsScript(type=NUMBER, expr=calc, frum=self)}
        ).partial_eval().to_es14_script(schema)
    else:
        calc = op.join(
            "(" + NumberOp("number", t).to_es14_script(schema).expr + ")"
            for t in self.terms
        )
        return WhenOp(
            "when",
            OrOp("or", [t.missing() for t in self.terms]),
            **{"then": self.default, "else": EsScript(type=NUMBER, expr=calc, frum=self)}
        ).partial_eval().to_es14_script(schema)
def to_es14_script(self, schema, not_null=False, boolean=False, many=True):
    lhs = self.lhs.partial_eval().to_es14_script(schema)
    rhs = self.rhs.partial_eval().to_es14_script(schema)

    if lhs.many:
        if rhs.many:
            return AndOp("and", [
                EsScript(type=BOOLEAN, expr="(" + lhs.expr + ").size()==(" + rhs.expr + ").size()", frum=self),
                EsScript(type=BOOLEAN, expr="(" + rhs.expr + ").containsAll(" + lhs.expr + ")", frum=self)
            ]).to_es14_script(schema)
        else:
            return EsScript(type=BOOLEAN, expr="(" + lhs.expr + ").contains(" + rhs.expr + ")", frum=self)
    elif rhs.many:
        return EsScript(
            type=BOOLEAN,
            expr="(" + rhs.expr + ").contains(" + lhs.expr + ")",
            frum=self
        )
    else:
        return EsScript(
            type=BOOLEAN,
            expr="(" + lhs.expr + "==" + rhs.expr + ")",
            frum=self
        )