Пример #1
0
    def partial_eval(self):
        term = self.lang[FirstOp(self.term)].partial_eval()

        if is_literal(term):
            if term is NULL:
                return NULL
            elif term is FALSE:
                return ZERO
            elif term is TRUE:
                return ONE

            v = term.value
            if isinstance(v, (text, Date)):
                return self.lang[Literal(float(v))]
            elif isinstance(v, (int, float)):
                return term
            else:
                Log.error("can not convert {{value|json}} to number",
                          value=term.value)
        elif is_op(term, CaseOp):  # REWRITING
            return self.lang[CaseOp([
                WhenOp(t.when, **{"then": NumberOp(t.then)})
                for t in term.whens[:-1]
            ] + [NumberOp(term.whens[-1])])].partial_eval()
        elif is_op(term, WhenOp):  # REWRITING
            return self.lang[WhenOp(
                term.when, **{
                    "then": NumberOp(term.then),
                    "else": NumberOp(term.els_)
                })].partial_eval()
        elif is_op(term, CoalesceOp):
            return self.lang[CoalesceOp([NumberOp(t) for t in term.terms])]
        return self.lang[NumberOp(term)]
Пример #2
0
    def partial_eval(self, lang):
        if self.type == BOOLEAN:
            nots = []
            ors = []
            for w in self.whens[:-1]:
                ors.append(AndOp(nots + [w.when, w.then]))
                nots.append(NotOp(w.when))
            ors.append(AndOp(nots + [self.whens[-1]]))
            return (OrOp(ors)).partial_eval(lang)

        whens = []
        for w in self.whens[:-1]:
            when = (w.when).partial_eval(lang)
            if when is TRUE:
                whens.append((w.then).partial_eval(lang))
                break
            elif when is FALSE:
                pass
            else:
                whens.append(
                    WhenOp(when, **{"then": w.then.partial_eval(lang)}))
        else:
            whens.append((self.whens[-1]).partial_eval(lang))

        if len(whens) == 1:
            return whens[0]
        elif len(whens) == 2:
            return WhenOp(whens[0].when, **{
                "then": whens[0].then,
                "else": whens[1]
            })
        else:
            return CaseOp(whens)
Пример #3
0
    def partial_eval(self):
        if self.type == BOOLEAN:
            nots = []
            ors = []
            for w in self.whens[:-1]:
                ors.append(AndOp(nots + [w.when, w.then]))
                nots.append(NotOp(w.when))
            ors.append(AndOp(nots + [self.whens[-1]]))
            return self.lang[OrOp(ors)].partial_eval()

        whens = []
        for w in self.whens[:-1]:
            when = self.lang[w.when].partial_eval()
            if when is TRUE:
                whens.append(self.lang[w.then].partial_eval())
                break
            elif when is FALSE:
                pass
            else:
                whens.append(self.lang[WhenOp(
                    when, **{"then": w.then.partial_eval()})])
        else:
            whens.append(self.lang[self.whens[-1]].partial_eval())

        if len(whens) == 1:
            return whens[0]
        elif len(whens) == 2:
            return self.lang[WhenOp(
                whens[0].when, **{
                    "then": whens[0].then,
                    "else": whens[1]
                })]
        else:
            return self.lang[CaseOp(whens)]
Пример #4
0
 def partial_eval(self):
     return self.lang[
         CaseOp(
             [
                 WhenOp(self.prefix.missing(), then=TRUE),
                 WhenOp(self.expr.missing(), then=FALSE),
                 BasicStartsWithOp([self.expr, self.prefix]),
             ]
         )
     ].partial_eval()
Пример #5
0
    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
Пример #6
0
    def partial_eval(self):
        value = self.value.partial_eval()

        start_index = self.lang[CaseOp([
            WhenOp(self.prefix.missing(), **{"then": ZERO}),
            WhenOp(IsNumberOp(self.prefix),
                   **{"then": MaxOp([ZERO, self.prefix])}),
            FindOp([value, self.prefix], start=self.start),
        ])].partial_eval()

        len_prefix = self.lang[CaseOp([
            WhenOp(self.prefix.missing(), **{"then": ZERO}),
            WhenOp(IsNumberOp(self.prefix), **{"then": ZERO}),
            LengthOp(self.prefix),
        ])].partial_eval()

        end_index = self.lang[CaseOp([
            WhenOp(start_index.missing(), **{"then": NULL}),
            WhenOp(self.suffix.missing(), **{"then": LengthOp(value)}),
            WhenOp(IsNumberOp(self.suffix),
                   **{"then": MinOp([self.suffix, LengthOp(value)])}),
            FindOp([value, self.suffix],
                   start=AddOp([start_index, len_prefix])),
        ])].partial_eval()

        start_index = AddOp([start_index, len_prefix]).partial_eval()
        substring = BasicSubstringOp([value, start_index,
                                      end_index]).partial_eval()

        between = self.lang[WhenOp(end_index.missing(), **{
            "then": self.default,
            "else": substring
        })].partial_eval()

        return between
Пример #7
0
    def partial_eval(self):
        value = self.lang[self.value].partial_eval()
        length = self.lang[self.length].partial_eval()
        max_length = LengthOp(value)

        return self.lang[WhenOp(
            self.missing(), **{
                "else":
                BasicSubstringOp(
                    [value, ZERO,
                     MaxOp([ZERO, MinOp([length, max_length])])])
            })].partial_eval()
Пример #8
0
    def partial_eval(self, lang):
        value = (self.value).partial_eval(lang)
        length = (self.length).partial_eval(lang)
        max_length = LengthOp(value)

        return WhenOp(
            self.missing(lang),
            **{"else": BasicSubstringOp([
                value,
                MaxOp([ZERO, MinOp([max_length, SubOp([max_length, length])])]),
                max_length,
            ])}
        ).partial_eval(lang)
Пример #9
0
    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()
Пример #10
0
    def partial_eval(self):
        value = self.lang[self.value].partial_eval()
        length = self.length.partial_eval()

        if length is ZERO:
            return value

        max_length = LengthOp(value)
        part = BasicSubstringOp([
            value,
            ZERO,
            MaxOp([ZERO,
                   MinOp([max_length, SubOp([max_length, length])])]),
        ])
        return self.lang[WhenOp(self.missing(), **{"else":
                                                   part})].partial_eval()
Пример #11
0
    def partial_eval(self, lang):
        value = (self.value).partial_eval(lang)
        length = self.length.partial_eval(lang)

        if length is ZERO:
            return value

        max_length = LengthOp(value)
        part = BasicSubstringOp([
            value,
            ZERO,
            MaxOp([ZERO,
                   MinOp([max_length, SubOp([max_length, length])])]),
        ])
        return (WhenOp(self.missing(lang), **{"else":
                                              part})).partial_eval(lang)
Пример #12
0
    def partial_eval(self, lang):
        value = (self.value).partial_eval(lang)
        length = self.length.partial_eval(lang)

        if length is ZERO:
            return value

        max_length = LengthOp(value)
        output = WhenOp(
            self.missing(lang),
            **{"else": BasicSubstringOp([
                value,
                MaxOp([ZERO, MinOp([length, max_length])]),
                max_length,
            ])}
        ).partial_eval(lang)
        return output
Пример #13
0
    def partial_eval(self):
        value = self.lang[self.value].partial_eval()
        length = self.length.partial_eval()

        if length is ZERO:
            return value

        max_length = LengthOp(value)
        output = self.lang[WhenOp(
            self.missing(), **{
                "else":
                BasicSubstringOp([
                    value,
                    MaxOp([ZERO, MinOp([length, max_length])]), max_length
                ])
            })].partial_eval()
        return output
Пример #14
0
 def partial_eval(self, lang):
     return CaseOp([
         WhenOp(self.prefix.missing(lang), then=TRUE),
         WhenOp(self.expr.missing(lang), then=FALSE),
         BasicStartsWithOp([self.expr, self.prefix]),
     ]).partial_eval(lang)