Exemple #1
0
 def partial_eval(self):
     lhs = self.lhs.partial_eval()
     rhs = self.rhs.partial_eval()
     default = self.default.partial_eval()
     if is_literal(lhs) and is_literal(rhs):
         return Literal(builtin_ops[self.op](lhs.value, rhs.value))
     return self.__class__([lhs, rhs], default=default)
Exemple #2
0
    def to_bq(self, schema, not_null=False, boolean=False):
        lhs = BQLang[self.lhs].partial_eval()
        rhs = BQLang[self.rhs].partial_eval()
        lhs_sql = lhs.to_bq(schema, not_null=True)
        rhs_sql = rhs.to_bq(schema, not_null=True)
        if is_literal(rhs) and lhs_sql[0].sql.b != None and rhs.value in ("T",
                                                                          "F"):
            rhs_sql = BooleanOp(rhs).to_bq(schema)
        if is_literal(lhs) and rhs_sql[0].sql.b != None and lhs.value in ("T",
                                                                          "F"):
            lhs_sql = BooleanOp(lhs).to_bq(schema)

        if len(lhs_sql) != len(rhs_sql):
            Log.error("lhs and rhs have different dimensionality!?")

        acc = []
        for l, r in zip(lhs_sql, rhs_sql):
            for t in "bsnj":
                if r.sql[t] == None:
                    if l.sql[t] == None:
                        pass
                    else:
                        acc.append(ConcatSQL(l.sql[t], SQL_IS_NULL))
                elif l.sql[t] == None:
                    acc.append(ConcatSQL(r.sql[t], SQL_IS_NULL))
                else:
                    acc.append(
                        ConcatSQL(sql_iso(l.sql[t]), SQL_EQ,
                                  sql_iso(r.sql[t])))
        if not acc:
            return FALSE.to_bq(schema)
        else:
            return wrap([{"name": ".", "sql": {"b": JoinSQL(SQL_OR, acc)}}])
    def partial_eval(self, lang):
        lhs = self.lhs.partial_eval(lang)
        rhs = self.rhs.partial_eval(lang)

        if is_literal(lhs) and is_literal(rhs):
            return Literal(builtin_ops[self.op](lhs, rhs))

        return self.__class__([lhs, rhs])
Exemple #4
0
 def partial_eval(self, lang):
     default = self.default.partial_eval(lang)
     rhs = self.rhs.partial_eval(lang)
     if rhs is ZERO:
         return default
     lhs = self.lhs.partial_eval(lang)
     if is_literal(lhs) and is_literal(rhs):
         return Literal(builtin_ops[self.op](lhs.value, rhs.value))
     return self.__class__([lhs, rhs], default=default)
Exemple #5
0
 def __data__(self):
     if is_literal(self.var) and len(self.offsets) == 1 and is_literal(
             self.offset):
         return {"get": {self.var.json, self.offsets[0].value}}
     else:
         return {
             "get":
             [self.var.__data__()] + [o.__data__() for o in self.offsets]
         }
Exemple #6
0
 def partial_eval(self):
     value = self.value.partial_eval()
     superset = self.superset.partial_eval()
     if superset is NULL:
         return FALSE
     elif is_literal(value) and is_literal(superset):
         return self.lang[Literal(self())]
     else:
         return self.lang[InOp([value, superset])]
 def partial_eval(self, lang):
     lhs = self.lhs.partial_eval(lang)
     rhs = self.rhs.partial_eval(lang)
     default = self.default.partial_eval(lang)
     if is_literal(lhs) and is_literal(rhs):
         if lhs is NULL or rhs is NULL:
             return NULL
         return Literal(builtin_ops[self.op](lhs.value, rhs.value))
     return self.__class__([lhs, rhs], default=default)
Exemple #8
0
 def __init__(self, value, prefix, suffix, default=NULL, start=NULL):
     Expression.__init__(self, [])
     self.value = value
     self.prefix = prefix
     self.suffix = suffix
     self.default = default
     self.start = start
     if is_literal(self.prefix) and is_literal(self.suffix):
         pass
     else:
         Log.error("Expecting literal prefix and suffix only")
Exemple #9
0
 def __init__(self, value, prefix, suffix, default=NULL, start=NULL):
     Expression.__init__(self, [])
     self.value = value
     self.prefix = coalesce(prefix, NULL)
     self.suffix = coalesce(suffix, NULL)
     self.default = coalesce(default, NULL)
     self.start = coalesce(start, NULL)
     if is_literal(self.prefix) and is_literal(self.suffix):
         pass
     else:
         Log.error("Expecting literal prefix and suffix only")
Exemple #10
0
    def partial_eval(self):
        lhs = self.lang[self.lhs].partial_eval()
        rhs = self.lang[self.rhs].partial_eval()

        if is_literal(lhs) and is_literal(rhs):
            return FALSE if value_compare(lhs.value, rhs.value) else TRUE
        else:
            return self.lang[self.lang[CaseOp([
                WhenOp(lhs.missing(), **{"then": rhs.missing()}),
                WhenOp(rhs.missing(), **{"then": FALSE}),
                BasicEqOp([lhs, rhs]),
            ])]].partial_eval()
Exemple #11
0
    def partial_eval(self, lang):
        lhs = (self.lhs).partial_eval(lang)
        rhs = (self.rhs).partial_eval(lang)

        if is_literal(lhs) and is_literal(rhs):
            return FALSE if value_compare(lhs.value, rhs.value) else TRUE
        else:
            return CaseOp([
                WhenOp(lhs.missing(lang), **{"then": rhs.missing(lang)}),
                WhenOp(rhs.missing(lang), **{"then": FALSE}),
                BasicEqOp([lhs, rhs]),
            ]).partial_eval(lang)
Exemple #12
0
 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])
Exemple #13
0
 def __data__(self):
     if not self.expr:
         return {"prefix": {}}
     elif is_op(self.expr, Variable) and is_literal(self.prefix):
         return {"prefix": {self.expr.var: self.prefix.value}}
     else:
         return {"prefix": [self.expr.__data__(), self.prefix.__data__()]}
Exemple #14
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)]
Exemple #15
0
 def __data__(self):
     if self.expr is None:
         return {"suffix": {}}
     elif is_op(self.expr, Variable) and is_literal(self.suffix):
         return {"suffix": {self.expr.var: self.suffix.value}}
     else:
         return {"suffix": [self.expr.__data__(), self.suffix.__data__()]}
Exemple #16
0
 def partial_eval(self):
     term = self.lang[self.term].partial_eval()
     if is_op(term, FirstOp):
         return term
     elif is_op(term, CaseOp):  # REWRITING
         return self.lang[
             CaseOp(
                 [
                     WhenOp(t.when, **{"then": FirstOp(t.then)})
                     for t in term.whens[:-1]
                 ]
                 + [FirstOp(term.whens[-1])]
             )
         ].partial_eval()
     elif is_op(term, WhenOp):
         return self.lang[
             WhenOp(
                 term.when,
                 **{"then": FirstOp(term.then), "else": FirstOp(term.els_)}
             )
         ].partial_eval()
     elif term.type != OBJECT and not term.many:
         return term
     elif is_literal(term):
         Log.error("not handled yet")
     else:
         return self.lang[FirstOp(term)]
Exemple #17
0
 def __data__(self):
     if is_op(self.value, Variable) and is_literal(self.length):
         return {"not_right": {self.value.var: self.length.value}}
     else:
         return {
             "not_right": [self.value.__data__(),
                           self.length.__data__()]
         }
 def __data__(self):
     if is_op(self.lhs, Variable) and is_literal(self.rhs):
         return {self.op: {self.lhs.var, self.rhs.value}, "default": self.default}
     else:
         return {
             self.op: [self.lhs.__data__(), self.rhs.__data__()],
             "default": self.default,
         }
Exemple #19
0
 def __init__(self, terms, separator=Literal(""), default=NULL):
     if not is_many(terms):
         Log.error("Expecting many terms")
     if not is_literal(separator):
         Log.error("Expecting a literal separator")
     Expression.__init__(self, terms + [separator, default])
     self.terms = terms
     self.separator = separator
     self.default = default
Exemple #20
0
 def __data__(self):
     f, s = self.terms[0], self.terms[1]
     if is_op(f, Variable) and is_literal(s):
         output = {"concat": {f.var: s.value}}
     else:
         output = {"concat": [t.__data__() for t in self.terms]}
     if self.separator.json != '""':
         output["separator"] = self.separator.__data__()
     return output
Exemple #21
0
 def partial_eval(self, lang):
     term = self.term.partial_eval(lang)
     if is_literal(term):
         if is_text(term.value):
             return (Literal(len(term.value)))
         else:
             return NULL
     else:
         return (LengthOp(term))
Exemple #22
0
 def partial_eval(self):
     term = self.lang[self.term].partial_eval()
     if is_literal(term):
         if is_text(term.value):
             return self.lang[Literal(len(term.value))]
         else:
             return NULL
     else:
         return self.lang[LengthOp(term)]
Exemple #23
0
    def __init__(self, term):
        Expression.__init__(self, term)
        if is_data(term):
            self.value, self.length = term.items()[0]
        else:
            self.value, self.length = term

        if is_literal(self.value):
            Log.note("")
Exemple #24
0
 def __init__(self, terms, **clauses):
     Expression.__init__(self, terms)
     if is_data(terms):
         self.terms = first(terms.items())
     else:
         self.terms = terms
     self.separator = clauses.get(str("separator"), Literal(""))
     self.default = clauses.get(str("default"), NULL)
     if not is_literal(self.separator):
         Log.error("Expecting a literal separator")
Exemple #25
0
 def partial_eval(self):
     term = self.term.partial_eval()
     if is_op(self.term, LastOp):
         return term
     elif term.type != OBJECT and not term.many:
         return term
     elif term is NULL:
         return term
     elif is_literal(term):
         return last(term)
     else:
         return self.lang[LastOp(term)]
Exemple #26
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
Exemple #27
0
 def __data__(self):
     terms = self.terms
     if len(terms) == 0:
         return self.default.__data__()
     if len(terms) == 2 and is_op(terms[0], Variable) and is_literal(
             terms[1]):
         output = {"concat": {terms[0].var: terms[1].value}}
     else:
         output = {"concat": [t.__data__() for t in terms]}
     if self.separator.json != '""':
         output["separator"] = self.separator.__data__()
     return output
Exemple #28
0
 def __data__(self):
     if (is_op(self.value, Variable) and is_literal(self.prefix)
             and is_literal(self.suffix)):
         output = wrap({
             "between": {
                 self.value.var: [self.prefix.value, self.suffix.value]
             }
         })
     else:
         output = wrap({
             "between": [
                 self.value.__data__(),
                 self.prefix.__data__(),
                 self.suffix.__data__(),
             ]
         })
     if self.start:
         output.start = self.start.__data__()
     if self.default:
         output.default = self.default.__data__()
     return output
Exemple #29
0
 def to_bq(self, schema, not_null=False, boolean=False):
     term = BQLang[self.term].partial_eval()
     if is_literal(term):
         val = term.value
         if isinstance(val, text):
             sql = quote_value(len(val))
         elif isinstance(val, (float, int)):
             sql = quote_value(len(value2json(val)))
         else:
             return Null
     else:
         value = term.to_bq(schema, not_null=not_null)[0].sql.s
         sql = ConcatSQL(SQL("LENGTH"), sql_iso(value))
     return wrap([{"name": ".", "sql": {"n": sql}}])
Exemple #30
0
        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