def to_sql(self, schema, not_null=False, boolean=False): lhs = SQLang[self.lhs].partial_eval() rhs = SQLang[self.rhs].partial_eval() lhs_sql = lhs.to_sql(schema, not_null=True) rhs_sql = rhs.to_sql(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_sql(schema) if is_literal(lhs) and rhs_sql[0].sql.b != None and lhs.value in ("T", "F"): lhs_sql = BooleanOp(lhs).to_sql(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_sql(schema) else: return wrap([{"name": ".", "sql": {"b": JoinSQL(SQL_OR, acc)}}])
def to_sql(self, schema, not_null=False, boolean=False): lhs = self.lhs.to_sql(schema) rhs = self.rhs.to_sql(schema) acc = [] if len(lhs) != len(rhs): Log.error("lhs and rhs have different dimensionality!?") for l, r in zip(lhs, rhs): for t in "bsnj": if l.sql[t] == None: if r.sql[t] == None: pass else: acc.append(sql_iso(r.sql[t]) + " IS " + SQL_NULL) else: if r.sql[t] == None: acc.append(sql_iso(l.sql[t]) + " IS " + SQL_NULL) else: acc.append("(" + sql_iso(l.sql[t]) + " = " + sql_iso(r.sql[t]) + " OR (" + sql_iso(l.sql[t]) + " IS" + SQL_NULL + SQL_AND + "(" + r.sql[t] + ") IS NULL))") if not acc: return FALSE.to_sql(schema) else: return wrap([{"name": ".", "sql": {"b": SQL_OR.join(acc)}}])
def to_esfilter(self, schema): if is_op(self.lhs, Variable_) and is_literal(self.rhs): rhs = self.rhs.value lhs = self.lhs.var cols = schema.leaves(lhs) if not cols: Log.warning( "{{col}} does not exist while processing {{expr}}", col=lhs, expr=self.__data__(), ) if is_container(rhs): if len(rhs) == 1: rhs = rhs[0] else: types = Data() # MAP JSON TYPE TO LIST OF LITERALS for r in rhs: types[python_type_to_json_type[r.__class__]] += [r] if len(types) == 1: jx_type, values = first(types.items()) for c in cols: if jx_type == c.jx_type or (jx_type in NUMBER_TYPES and c.jx_type in NUMBER_TYPES): return {"terms": {c.es_column: values}} return FALSE.to_esfilter(schema) else: return (OrOp([ EqOp([self.lhs, values]) for t, values in types.items() ]).partial_eval().to_esfilter(schema)) for c in cols: if c.jx_type == BOOLEAN: rhs = pull_functions[c.jx_type](rhs) rhs_type = python_type_to_json_type[rhs.__class__] if rhs_type == c.jx_type or (rhs_type in NUMBER_TYPES and c.jx_type in NUMBER_TYPES): return {"term": {c.es_column: rhs}} return FALSE.to_esfilter(schema) else: return (ES52[CaseOp([ WhenOp(self.lhs.missing(), **{"then": self.rhs.missing()}), WhenOp(self.rhs.missing(), **{"then": FALSE}), BasicEqOp([self.lhs, self.rhs]), ]).partial_eval()].to_esfilter(schema))
def to_bq(self, schema, not_null=False, boolean=False): term = BQLang[self.term].partial_eval() if term.type == "boolean": sql = term.to_bq(schema) return sql elif is_literal(term) and term.value in ("T", "F"): if term.value == "T": return TRUE.to_bq(schema) else: return FALSE.to_bq(schema) else: sql = term.exists().partial_eval().to_bq(schema) return sql
def to_esfilter(self, schema): if is_op(self.lhs, Variable_) and is_literal(self.rhs): rhs = self.rhs.value lhs = self.lhs.var cols = schema.leaves(lhs) if is_list(rhs): if len(rhs) == 1: rhs = rhs[0] else: types = Data() # MAP JSON TYPE TO LIST OF LITERALS for r in rhs: types[python_type_to_json_type[rhs.__class__]] += [r] if len(types) == 1: jx_type, values = first(types.items()) for c in cols: if jx_type == c.jx_type: return {"terms": {c.es_column: values}} return FALSE.to_esfilter(schema) else: return (OrOp([ EqOp([self.lhs, values]) for t, values in types.items() ]).partial_eval().to_esfilter(schema)) for c in cols: if c.jx_type == BOOLEAN: rhs = pull_functions[c.jx_type](rhs) if python_type_to_json_type[rhs.__class__] == c.jx_type: return {"term": {c.es_column: rhs}} return FALSE.to_esfilter(schema) else: return (ES52[CaseOp([ WhenOp(self.lhs.missing(), **{"then": self.rhs.missing()}), WhenOp(self.rhs.missing(), **{"then": FALSE}), BasicEqOp([self.lhs, self.rhs]), ])].partial_eval().to_esfilter(schema))
def to_bq(self, schema, not_null=False, boolean=False): value = BQLang[self.expr].partial_eval() missing_value = value.missing().partial_eval() if not is_op(missing_value, MissingOp): return missing_value.to_bq(schema) value_sql = value.to_bq(schema) if value_sql.type == OBJECT: return FALSE.to_bq(schema) return BQLScript( data_type=BOOLEAN, expr=ConcatSQL(sql_iso(value_sql), SQL_IS_NULL), frum=self, miss=FALSE, many=False, schema=schema )
def to_bq(self, schema, not_null=False, boolean=False): lhs = BQLang[self.lhs].to_bq(schema) rhs = BQLang[self.rhs].to_bq(schema) acc = [] if len(lhs) != len(rhs): Log.error("lhs and rhs have different dimensionality!?") for l, r in zip(lhs, rhs): for t in "bsnj": if l.sql[t] == None: if r.sql[t] == None: pass else: acc.append(sql_iso(r.sql[t]) + SQL_IS_NULL) elif l.sql[t] is ZERO: if r.sql[t] == None: acc.append(SQL_FALSE) elif r.sql[t] is ZERO: Log.error( "Expecting expression to have been simplified already" ) else: acc.append(r.sql[t]) else: if r.sql[t] == None: acc.append(sql_iso(l.sql[t]) + SQL_IS_NULL) elif r.sql[t] is ZERO: acc.append(l.sql[t]) else: acc.append( sql_iso(l.sql[t]) + " = " + sql_iso(r.sql[t])) if not acc: return FALSE.to_bq(schema) else: return BQLScript( expr=SQL_OR.join(acc), frum=self, data_type=BOOLEAN, miss=FALSE, schema=schema, )
def to_es_script(self, schema, not_null=False, boolean=False, many=True): simple_rhs = Painless[self.rhs].partial_eval() lhs = Painless[self.lhs].partial_eval().to_es_script(schema) rhs = simple_rhs.to_es_script(schema) if lhs.many: if rhs.many: return AndOp([ EsScript( type=BOOLEAN, expr="(" + lhs.expr + ").size()==(" + rhs.expr + ").size()", frum=self, schema=schema, ), EsScript( type=BOOLEAN, expr="(" + rhs.expr + ").containsAll(" + lhs.expr + ")", frum=self, schema=schema, ), ]).to_es_script(schema) else: if lhs.type == BOOLEAN: if is_literal(simple_rhs) and simple_rhs.value in ("F", False): return EsScript(type=BOOLEAN, expr="!" + lhs.expr, frum=self, schema=schema) elif is_literal(simple_rhs) and simple_rhs.value in ("T", True): return EsScript(type=BOOLEAN, expr=lhs.expr, frum=self, schema=schema) else: return EsScript( type=BOOLEAN, expr="(" + lhs.expr + ")==(" + rhs.expr + ")", frum=self, schema=schema, ) elif lhs.type == rhs.type: return EsScript( type=BOOLEAN, expr="(" + lhs.expr + ").contains(" + rhs.expr + ")", frum=self, schema=schema, ) elif lhs.type == NUMBER and rhs.type == INTEGER: return EsScript( type=BOOLEAN, expr="(" + lhs.expr + ").contains((double)" + rhs.expr + ")", frum=self, schema=schema, ) else: Log.error( "type mismatch not expected while converting to painless" ) elif rhs.many: return EsScript( type=BOOLEAN, expr="(" + rhs.expr + ").contains(" + lhs.expr + ")", frum=self, schema=schema, ) else: if lhs is null_script: if rhs is null_script: return TRUE.to_es_script(schema) return FALSE.to_es_script(schema) elif lhs.type == BOOLEAN: if is_literal(simple_rhs) and simple_rhs.value in ("F", False): return EsScript(type=BOOLEAN, expr="!" + lhs.expr, frum=self, schema=schema) elif is_literal(simple_rhs) and simple_rhs.value in ("T", True): return EsScript(type=BOOLEAN, expr=lhs.expr, frum=self, schema=schema) else: return EsScript( type=BOOLEAN, expr="(" + lhs.expr + ")==(" + rhs.expr + ")", frum=self, schema=schema, ) else: return EsScript( type=BOOLEAN, expr="(" + lhs.expr + ")==(" + rhs.expr + ")", frum=self, schema=schema, )