예제 #1
0
def _multi_to_es_script(self,
                        schema,
                        not_null=False,
                        boolean=False,
                        many=True):
    op, unit = _painless_operators[self.op]
    if self.nulls:
        calc = op.join(
            "((" + Painless[t.missing()].to_es_script(schema).expr + ") ? " +
            unit + " : (" +
            Painless[NumberOp(t)].partial_eval().to_es_script(schema).expr +
            "))" for t in self.terms)
        return (WhenOp(
            AndOp([t.missing() for t in self.terms]), **{
                "then": self.default,
                "else": EsScript(type=NUMBER,
                                 expr=calc,
                                 frum=self,
                                 schema=schema),
            }).partial_eval().to_es_script(schema))
    else:
        calc = op.join("(" + NumberOp(t).to_es_script(schema).expr + ")"
                       for t in self.terms)
        return (WhenOp(
            OrOp([t.missing() for t in self.terms]), **{
                "then": self.default,
                "else": EsScript(type=NUMBER,
                                 expr=calc,
                                 frum=self,
                                 schema=schema),
            }).partial_eval().to_es_script(schema))
예제 #2
0
 def to_es_script(self, schema, not_null=False, boolean=False, many=True):
     if is_op(self.expr, Variable_):
         if self.expr.var == "_id":
             return EsScript(type=BOOLEAN, expr="false", frum=self, schema=schema)
         else:
             columns = schema.leaves(self.expr.var)
             return (
                 AndOp(
                     [
                         EsScript(
                             type=BOOLEAN,
                             expr="doc[" + quote(c.es_column) + "].empty",
                             frum=self,
                             schema=schema,
                         )
                         for c in columns
                     ]
                 )
                 .partial_eval()
                 .to_es_script(schema)
             )
     elif is_literal(self.expr):
         return self.expr.missing().to_es_script(schema)
     else:
         return self.expr.missing().partial_eval().to_es_script(schema)
    def to_es_script(self, schema, not_null=False, boolean=False, many=True):
        if self.simplified:
            when = Painless[self.when].to_es_script(schema)
            then = Painless[self.then].to_es_script(schema)
            els_ = Painless[self.els_].to_es_script(schema)

            if when is true_script:
                return then
            elif when is false_script:
                return els_
            elif then.miss is TRUE:
                return EsScript(
                    miss=self.missing(),
                    type=els_.type,
                    expr=els_.expr,
                    frum=self,
                    schema=schema,
                )
            elif els_.miss is TRUE:
                return EsScript(
                    miss=self.missing(),
                    type=then.type,
                    expr=then.expr,
                    frum=self,
                    schema=schema,
                )

            elif then.miss is TRUE or els_.miss is FALSE or then.type == els_.type:
                return EsScript(
                    miss=self.missing(),
                    type=then.type if els_.miss is TRUE else els_.type,
                    expr="("
                    + when.expr
                    + ") ? ("
                    + then.expr
                    + ") : ("
                    + els_.expr
                    + ")",
                    frum=self,
                    schema=schema,
                )
            elif then.type in NUMBER_TYPES and els_.type in NUMBER_TYPES:
                return EsScript(
                    miss=self.missing(),
                    type=NUMBER,
                    expr="("
                    + when.expr
                    + ") ? ("
                    + then.expr
                    + ") : ("
                    + els_.expr
                    + ")",
                    frum=self,
                    schema=schema,
                )
            else:
                Log.error("do not know how to handle: {{self}}", self=self.__data__())
        else:
            return self.partial_eval().to_es_script(schema)
예제 #4
0
    def to_es_script(self, schema, not_null=False, boolean=False, many=True):
        term = FirstOp(self.term).partial_eval()

        value = term.to_es_script(schema)

        if is_op(value.frum, CoalesceOp_):
            return CoalesceOp([
                NumberOp(t).partial_eval().to_es_script(schema)
                for t in value.frum.terms
            ]).to_es_script(schema)

        if value is null_script:
            return Literal(0).to_es_script(schema)
        if value is false_script:
            return Literal(0).to_es_script(schema)
        if value is true_script:
            return Literal(1).to_es_script(schema)
        elif value.type == BOOLEAN:
            return EsScript(
                miss=term.missing().partial_eval(),
                type=NUMBER,
                expr="(" + value.expr + ") ? 1 : 0",
                frum=self,
                schema=schema,
            )
        elif value.type == INTEGER:
            return EsScript(
                miss=term.missing().partial_eval(),
                type=NUMBER,
                expr=value.expr,
                frum=self,
                schema=schema,
            )
        elif value.type == NUMBER:
            return EsScript(
                miss=term.missing().partial_eval(),
                type=NUMBER,
                expr=value.expr,
                frum=self,
                schema=schema,
            )
        elif value.type == STRING:
            return EsScript(
                miss=term.missing().partial_eval(),
                type=NUMBER,
                expr="Double.parseDouble(" + value.expr + ")",
                frum=self,
                schema=schema,
            )
        elif value.type == OBJECT:
            return EsScript(
                miss=term.missing().partial_eval(),
                type=NUMBER,
                expr="((" + value.expr +
                ") instanceof String) ? Double.parseDouble(" + value.expr +
                ") : (" + value.expr + ")",
                frum=self,
                schema=schema,
            )
예제 #5
0
    def to_es_script(self, schema, not_null=False, boolean=False, many=True):
        if len(self.terms) == 0:
            return self.default.to_es_script(schema)

        acc = []
        separator = StringOp(self.separator).partial_eval()
        sep = separator.to_es_script(schema).expr
        for t in self.terms:
            val = WhenOp(
                t.missing(),
                **{
                    "then": Literal(""),
                    "else": EsScript(
                        type=STRING,
                        expr=sep
                        + "+"
                        + StringOp(t).partial_eval().to_es_script(schema).expr,
                        frum=t,
                        schema=schema,
                    )
                    # "else": ConcatOp([sep, t])
                }
            )
            acc.append("(" + val.partial_eval().to_es_script(schema).expr + ")")
        expr_ = (
            "("
            + "+".join(acc)
            + ").substring("
            + LengthOp(separator).to_es_script(schema).expr
            + ")"
        )

        if self.default is NULL:
            return EsScript(
                miss=self.missing(), type=STRING, expr=expr_, frum=self, schema=schema
            )
        else:
            return EsScript(
                miss=self.missing(),
                type=STRING,
                expr="(("
                + expr_
                + ").length==0) ? ("
                + self.default.to_es_script(schema).expr
                + ") : ("
                + expr_
                + ")",
                frum=self,
            )
예제 #6
0
    def to_es_script(self, schema, not_null=False, boolean=False, many=True):
        if is_op(self.term, Variable_):
            columns = schema.values(self.term.var)
            if len(columns) == 0:
                return null_script
            elif len(columns) == 1:
                return self.term.to_es_script(schema, many=False)
            # else:
            #     return CoalesceOp(
            #         [
            #             FirstOp(Variable(c.es_column))
            #             for c in columns
            #         ]
            #     ).to_es_script(schema)

        term = Painless[self.term].to_es_script(schema)

        if is_op(term.frum, CoalesceOp_):
            return CoalesceOp(
                [
                    FirstOp(t.partial_eval().to_es_script(schema))
                    for t in term.frum.terms
                ]
            ).to_es_script(schema)

        if term.many:
            return EsScript(
                miss=term.miss,
                type=term.type,
                expr="(" + term.expr + ")[0]",
                frum=term.frum,
                schema=schema,
            ).to_es_script(schema)
        else:
            return term
예제 #7
0
    def to_es_script(self, schema, not_null=False, boolean=False, many=True):
        if not self.terms:
            return NULL.to_es_script(schema)
        # acc.miss WILL SAY IF THIS COALESCE RETURNS NULL,
        # acc.expr WILL ASSUMED TO BE A VALUE, SO THE LAST TERM IS ASSUMED NOT NULL
        v = self.terms[-1]
        acc = FirstOp(v).partial_eval().to_es_script(schema)
        for v in reversed(self.terms[:-1]):
            m = v.missing().partial_eval()
            e = NotOp(m).partial_eval().to_es_script(schema)
            r = FirstOp(v).partial_eval().to_es_script(schema)

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

            acc = EsScript(
                miss=AndOp([acc.miss, m]).partial_eval(),
                type=new_type,
                expr="(" + e.expr + ") ? (" + r.expr + ") : (" + acc.expr +
                ")",
                frum=self,
                schema=schema,
            )
        return acc
    def to_es_script(self, schema, not_null=False, boolean=False, many=True):
        lhs = FirstOp(self.lhs).partial_eval()
        rhs = FirstOp(self.rhs).partial_eval()

        if rhs == ONE:
            script = "(int)Math.floor(" + lhs.to_es_script(schema).expr + ")"
        else:
            rhs = rhs.to_es_script(schema)
            script = ("Math.floor((" + lhs.to_es_script(schema).expr +
                      ") / (" + rhs.expr + "))*(" + rhs.expr + ")")

        output = WhenOp(
            OrOp([lhs.missing(),
                  rhs.missing(),
                  EqOp([self.rhs, ZERO])]), **{
                      "then":
                      self.default,
                      "else":
                      EsScript(type=NUMBER,
                               expr=script,
                               frum=self,
                               miss=FALSE,
                               schema=schema),
                  }).partial_eval().to_es_script(schema)
        return output
예제 #9
0
 def to_es_script(self, schema, not_null=False, boolean=False, many=True):
     value = Painless[self.term].to_es_script(schema)
     if value.many:
         return IntegerOp(
             EsScript(
                 miss=value.missing(),
                 type=value.type,
                 expr="(" + value.expr + ")[0]",
                 frum=value.frum,
                 schema=schema,
             )).to_es_script(schema)
     elif value.type == BOOLEAN:
         return EsScript(
             miss=value.missing(),
             type=INTEGER,
             expr=value.expr + " ? 1 : 0",
             frum=self,
             schema=schema,
         )
     elif value.type == INTEGER:
         return value
     elif value.type == NUMBER:
         return EsScript(
             miss=value.missing(),
             type=INTEGER,
             expr="(int)(" + value.expr + ")",
             frum=self,
             schema=schema,
         )
     elif value.type == STRING:
         return EsScript(
             miss=value.missing(),
             type=INTEGER,
             expr="Integer.parseInt(" + value.expr + ")",
             frum=self,
             schema=schema,
         )
     else:
         return EsScript(
             miss=value.missing(),
             type=INTEGER,
             expr="((" + value.expr +
             ") instanceof String) ? Integer.parseInt(" + value.expr +
             ") : (int)(" + value.expr + ")",
             frum=self,
             schema=schema,
         )
예제 #10
0
 def to_es_script(self, schema, not_null=False, boolean=False, many=True):
     return EsScript(
         type=BOOLEAN,
         expr=" || ".join("(" + Painless[t].to_es_script(schema).expr + ")"
                          for t in self.terms if t),
         frum=self,
         schema=schema,
     )
예제 #11
0
    def to_es_script(self, schema, not_null=False, boolean=False, many=True):
        if self.var == ".":
            return EsScript(type=OBJECT, expr="_source", frum=self)
        else:
            if self.var == "_id":
                return EsScript(
                    type=STRING,
                    expr=
                    'doc["_uid"].value.substring(doc["_uid"].value.indexOf(\'#\')+1)',
                    frum=self,
                    schema=schema,
                )

            columns = schema.values(self.var)
            acc = []
            for c in columns:
                varname = c.es_column
                frum = Variable(c.es_column)
                q = quote(varname)
                if c.multi > 1:
                    acc.append(
                        EsScript(
                            miss=frum.missing(),
                            type=c.jx_type,
                            expr="doc[" + q + "].values",
                            frum=frum,
                            schema=schema,
                            many=True,
                        ))
                else:
                    acc.append(
                        EsScript(
                            miss=frum.missing(),
                            type=c.jx_type,
                            expr="doc[" + q + "].value",
                            frum=frum,
                            schema=schema,
                            many=False,
                        ))

            if len(acc) == 0:
                return NULL.to_es_script(schema)
            elif len(acc) == 1:
                return acc[0]
            else:
                return CoalesceOp(acc).to_es_script(schema)
    def to_es_script(self, schema, not_null=False, boolean=False, many=True):
        term = FirstOp(self.term).partial_eval()
        value = term.to_es_script(schema)

        if is_op(value.frum, CoalesceOp_):
            return CoalesceOp([
                StringOp(t).partial_eval() for t in value.frum.terms
            ]).to_es_script(schema)

        if value.miss is TRUE:
            return empty_string_script
        elif value.type == BOOLEAN:
            return EsScript(
                miss=self.term.missing().partial_eval(),
                type=STRING,
                expr=value.expr + ' ? "T" : "F"',
                frum=self,
                schema=schema,
            )
        elif value.type == INTEGER:
            return EsScript(
                miss=self.term.missing().partial_eval(),
                type=STRING,
                expr="String.valueOf(" + value.expr + ")",
                frum=self,
                schema=schema,
            )
        elif value.type == NUMBER:
            return EsScript(
                miss=self.term.missing().partial_eval(),
                type=STRING,
                expr=expand_template(NUMBER_TO_STRING, {"expr": value.expr}),
                frum=self,
                schema=schema,
            )
        elif value.type == STRING:
            return value
        else:
            return EsScript(
                miss=self.term.missing().partial_eval(),
                type=STRING,
                expr=expand_template(NUMBER_TO_STRING, {"expr": value.expr}),
                frum=self,
                schema=schema,
            )
 def to_es_script(self, schema, not_null=False, boolean=False, many=True):
     expr = ("new Object[]{" + ",".join(
         text(FirstOp(t).partial_eval().to_es_script(schema))
         for t in self.terms) + "}")
     return EsScript(type=OBJECT,
                     expr=expr,
                     many=FALSE,
                     frum=self,
                     schema=schema)
예제 #14
0
 def to_es_script(self, schema, not_null=False, boolean=False, many=True):
     superset = Painless[self.superset].to_es_script(schema)
     value = Painless[self.value].to_es_script(schema)
     return EsScript(
         type=BOOLEAN,
         expr="(" + superset.expr + ").contains(" + value.expr + ")",
         frum=self,
         schema=schema,
     )
 def to_es_script(self, schema, not_null=False, boolean=False, many=True):
     value = StringOp(self.term).to_es_script(schema)
     missing = self.term.missing().partial_eval()
     return EsScript(
         miss=missing,
         type=INTEGER,
         expr="(" + value.expr + ").length()",
         frum=self,
         schema=schema,
     )
예제 #16
0
def _binary_to_es_script(self, schema, not_null=False, boolean=False, many=True):
    op, identity = _painless_operators[self.op]
    lhs = NumberOp(self.lhs).partial_eval().to_es_script(schema)
    rhs = NumberOp(self.rhs).partial_eval().to_es_script(schema)
    script = "(" + lhs.expr + ") " + op + " (" + rhs.expr + ")"
    missing = OrOp([self.lhs.missing(), self.rhs.missing()])

    return EsScript(
        type=NUMBER, miss=missing, frum=self, expr=script, schema=schema, many=False
    )
    def to_es_script(self, schema, not_null=False, boolean=False, many=True):
        v = StringOp(self.value).to_es_script(schema).expr
        find = StringOp(self.find).to_es_script(schema).expr
        start = IntegerOp(self.start).to_es_script(schema).expr

        return EsScript(
            miss=FALSE,
            type=INTEGER,
            expr="(" + v + ").indexOf(" + find + ", " + start + ")",
            frum=self,
            schema=schema,
        )
 def to_es_script(self, schema, not_null=False, boolean=False, many=True):
     value = self.term.to_es_script(schema)
     if value.expr or value.i:
         return 3
     else:
         return EsScript(
             miss=FALSE,
             type=BOOLEAN,
             expr="(" + value.expr + ") instanceof java.lang.Double",
             frum=self,
             schema=schema,
         )
예제 #19
0
 def to_es_script(self, schema, not_null=False, boolean=False, many=True):
     if not self.expr:
         return true_script
     else:
         return EsScript(
             type=BOOLEAN,
             expr="(" + self.expr.to_es_script(schema).script(schema) +
             ").startsWith(" +
             self.prefix.to_es_script(schema).script(schema) + ")",
             frum=self,
             schema=schema,
         )
예제 #20
0
    def to_es_script(self, schema, not_null=False, boolean=False, many=True):
        v = StringOp(self.value).partial_eval().to_es_script(schema).expr
        start = IntegerOp(self.start).partial_eval().to_es_script(schema).expr
        end = IntegerOp(self.end).partial_eval().to_es_script(schema).expr

        return EsScript(
            miss=FALSE,
            type=STRING,
            expr="(" + v + ").substring(" + start + ", " + end + ")",
            frum=self,
            schema=schema,
        )
예제 #21
0
 def to_es_script(self, schema, not_null=False, boolean=False, many=True):
     acc = NumberOp(self.terms[-1]).partial_eval().to_es_script(schema).expr
     for t in reversed(self.terms[0:-1]):
         acc = ("Math.max(" +
                NumberOp(t).partial_eval().to_es_script(schema).expr +
                " , " + acc + ")")
     return EsScript(
         miss=AndOp([t.missing() for t in self.terms]),
         type=NUMBER,
         expr=acc,
         frum=self,
         schema=schema,
     )
예제 #22
0
 def to_es_script(self, schema, not_null=False, boolean=False, many=True):
     if not self.suffix:
         return true_script
     else:
         return EsScript(
             miss=OrOp([
                 MissingOp(self.expr),
                 MissingOp(self.suffix),
             ]).partial_eval(),
             expr="(" + self.expr.to_es_script(schema) + ").endsWith(" +
             self.suffix.to_es_script(schema) + ")",
             frum=self,
             schema=schema,
         )
    def to_es_script(self, schema, not_null=False, boolean=False, many=True):
        v = StringOp(self.value).partial_eval().to_es_script(schema).expr
        l = NumberOp(self.length).partial_eval().to_es_script(schema).expr

        expr = ("(" + v + ").substring((int)Math.max(0, (int)Math.min(" + v +
                ".length(), " + l + ")))")
        return EsScript(
            miss=OrOp([self.value.missing(),
                       self.length.missing()]),
            type=STRING,
            expr=expr,
            frum=self,
            schema=schema,
        )
예제 #24
0
    def to_es_script(self, schema, not_null=False, boolean=False, many=True):
        expr = Painless[FirstOp(
            self.value)].partial_eval().to_es_script(schema)
        if expr is empty_string_script:
            return false_script

        prefix = Painless[self.prefix].to_es_script(schema).partial_eval()
        return EsScript(
            miss=FALSE,
            type=BOOLEAN,
            expr="(" + expr.expr + ").startsWith(" + prefix.expr + ")",
            frum=self,
            schema=schema,
        )
예제 #25
0
def _inequality_to_es_script(self, schema, not_null=False, boolean=False, many=True):
    op, identity = _painless_operators[self.op]
    lhs = NumberOp(self.lhs).partial_eval().to_es_script(schema).expr
    rhs = NumberOp(self.rhs).partial_eval().to_es_script(schema).expr
    script = "(" + lhs + ") " + op + " (" + rhs + ")"

    output = WhenOp(
        OrOp([self.lhs.missing(), self.rhs.missing()]),
        **{
            "then": FALSE,
            "else": EsScript(type=BOOLEAN, expr=script, frum=self, schema=schema),
        }
    ).partial_eval().to_es_script(schema)
    return output
예제 #26
0
    def to_es_script(self, schema, not_null=False, boolean=False, many=True):
        ands = [Painless[t].to_es_script(schema) for t in self.terms]

        # TODO: WE SHOULD NOT BE SIMPLIFYING AT THIS POINT
        if all(a is true_script for a in ands):
            return true_script
        elif any(a is false_script for a in ands):
            return false_script

        return EsScript(
            type=BOOLEAN,
            expr=" && ".join("(" + a + ")" for a in ands),
            frum=self,
            schema=schema,
        )
예제 #27
0
        def _convert(v):
            if v is None:
                return null_script
            if v is True:
                return true_script
            if v is False:
                return false_script
            class_ = v.__class__
            if class_ is text:
                return EsScript(type=STRING,
                                expr=quote(v),
                                frum=self,
                                schema=schema)
            if class_ in integer_types:
                if MIN_INT32 <= v <= MAX_INT32:
                    return EsScript(type=INTEGER,
                                    expr=text(v),
                                    frum=self,
                                    schema=schema)
                else:
                    return EsScript(type=INTEGER,
                                    expr=text(v) + "L",
                                    frum=self,
                                    schema=schema)

            if class_ is float:
                return EsScript(type=NUMBER,
                                expr=text(v) + "D",
                                frum=self,
                                schema=schema)
            if class_ in data_types:
                return EsScript(
                    type=OBJECT,
                    expr="[" + ", ".join(
                        quote(k) + ": " + _convert(vv)
                        for k, vv in v.items()) + "]",
                    frum=self,
                    schema=schema,
                )
            if class_ in (FlatList, list, tuple):
                return EsScript(
                    type=OBJECT,
                    expr="[" + ", ".join(_convert(vv).expr for vv in v) + "]",
                    frum=self,
                    schema=schema,
                )
            if class_ is Date:
                return EsScript(type=NUMBER,
                                expr=text(v.unix),
                                frum=self,
                                schema=schema)
예제 #28
0
    def to_es_script(self, schema, not_null=False, boolean=False, many=True):
        value = Painless[self.term].partial_eval().to_es_script(schema)

        if value is false_script:
            return true_script
        elif value is true_script:
            return false_script
        elif value is null_script:
            return null_script

        return EsScript(
            type=BOOLEAN,
            expr="!(" + value.expr + ")",
            frum=self,
            schema=schema,
        )
 def to_es_script(self, schema, not_null=False, boolean=False, many=True):
     code = """
     HashSet output = new HashSet();
     {{LOOPS}}
     return output.toArray();
     """
     parts = [
         Painless[t].partial_eval().to_es_script(schema, many=True)
         for t in self.terms
     ]
     loops = ["for (v in " + p.expr + ") output.add(v);" for p in parts]
     return EsScript(
         type=merge_types(p.type for p in parts),
         expr=code.replace("{{LOOPS}}", "\n".join(loops)),
         many=True,
         frum=self,
         schema=schema,
     )
예제 #30
0
def _basic_binary_op_to_es_script(self,
                                  schema,
                                  not_null=False,
                                  boolean=False,
                                  many=True):
    op, identity = _painless_operators[self.op]
    if len(self.terms) == 0:
        return Literal(identity).to_es_script(schema)
    elif len(self.terms) == 1:
        return self.terms[0].to_esscript()
    else:
        return EsScript(
            type=NUMBER,
            expr=op.join("(" + Painless[t].to_es_script(
                schema, not_null=True, many=False).expr + ")"
                         for t in self.terms),
            frum=self,
            schema=schema,
        )