op = expr.op() arg, digits = op.args arg_formatted = translator.translate(arg) if digits is not None: digits_formatted = translator.translate(digits) return 'bround({}, {})'.format(arg_formatted, digits_formatted) return 'bround({})'.format(arg_formatted) _operation_registry = {**operation_registry} _operation_registry.update({ ops.IsNan: unary('isnan'), ops.IfNull: fixed_arity('ifnull', 2), ops.StructField: _struct_field, ops.MapValueForKey: _map_value_for_key, ops.ArrayLength: unary('size'), ops.Round: _round, ops.HLLCardinality: reduction('approx_count_distinct'), ops.StrRight: fixed_arity('right', 2), ops.StringSplit:
def _extract_epoch_seconds(translator, expr): return 'CAST({} AS BIGINT)'.format( unary('unix_timestamp')(translator, expr))
ops.RegexSearch: _regex_search, ops.RegexExtract: _regex_extract, ops.RegexReplace: _regex_replace, ops.GroupConcat: reduction('STRING_AGG'), ops.IfNull: fixed_arity('IFNULL', 2), ops.Cast: _cast, ops.StructField: _struct_field, ops.ArrayCollect: unary('ARRAY_AGG'), ops.ArrayConcat: _array_concat, ops.ArrayIndex: _array_index, ops.ArrayLength: unary('ARRAY_LENGTH'), ops.HLLCardinality: reduction('APPROX_COUNT_DISTINCT'), ops.Log: _log, ops.Sign: unary('SIGN'), ops.Modulus: fixed_arity('MOD', 2), ops.Date:
op = expr.op() arg, digits = op.args arg_formatted = translator.translate(arg) if digits is not None: digits_formatted = translator.translate(digits) return 'bround({}, {})'.format(arg_formatted, digits_formatted) return 'bround({})'.format(arg_formatted) _operation_registry = {**operation_registry} _operation_registry.update( { ops.IsNan: unary('isnan'), ops.IfNull: fixed_arity('ifnull', 2), ops.StructField: _struct_field, ops.MapValueForKey: _map_value_for_key, ops.ArrayLength: unary('size'), ops.Round: _round, ops.HLLCardinality: reduction('approx_count_distinct'), ops.StrRight: fixed_arity('right', 2), ops.StringSplit: fixed_arity('SPLIT', 2), ops.RegexSearch: fixed_arity('rlike', 2), ops.StringConcat: _string_concat, ops.ArrayConcat: fixed_arity('concat', 2), ops.GroupConcat: _group_concat, ops.Cast: _cast, ops.ExtractYear: unary('year'), ops.ExtractMonth: unary('month'),
ops.DenseRank: _subtract_one, ops.MinRank: _subtract_one, ops.NTile: _subtract_one, } def _string_like(translator, expr): arg, pattern, _ = expr.op().args return '{} LIKE {}'.format(translator.translate(arg), translator.translate(pattern)) _operation_registry = { # string operations ops.StringLength: unary('length'), ops.StringAscii: unary('ascii'), ops.Lowercase: unary('lower'), ops.Uppercase: unary('upper'), ops.Reverse: unary('reverse'), ops.Strip: unary('trim'), ops.LStrip: unary('ltrim'), ops.RStrip: unary('rtrim'), ops.Capitalize:
ops.RegexSearch: _regex_search, ops.RegexExtract: _regex_extract, ops.RegexReplace: _regex_replace, ops.GroupConcat: reduction("STRING_AGG"), ops.IfNull: fixed_arity("NVL", 2), ops.Cast: _cast, ops.StructField: _struct_field, ops.ArrayCollect: unary("ARRAY_AGG"), ops.ArrayConcat: _array_concat, ops.ArrayIndex: _array_index, ops.ArrayLength: unary("ARRAY_LENGTH"), ops.HLLCardinality: reduction("APPROX_COUNT_DISTINCT"), ops.Log: _log, ops.Sign: unary("SIGN"), ops.Modulus: fixed_arity("MOD", 2), ops.Date:
_operation_registry.update({ # aggregate methods ops.Count: _reduction_count(sa.func.count), ops.Max: _reduction('max'), ops.Min: _reduction('min'), ops.Sum: _reduction('sum'), ops.Mean: _reduction('avg', 'float64'), # string methods ops.LStrip: unary(sa.func.ltrim), ops.Lowercase: unary(sa.func.lower), ops.RStrip: unary(sa.func.rtrim), ops.Repeat: fixed_arity(sa.func.replicate, 2), ops.Reverse: unary(sa.func.reverse), ops.StringFind: _string_find, ops.StringLength: unary(sa.func.length), ops.StringReplace: fixed_arity(sa.func.replace, 3), ops.Strip:
_operation_registry.update( { ops.Literal: _literal, # We override this here to support time zones ops.TableColumn: _table_column, # types ops.Cast: _cast, ops.TypeOf: _typeof, # Floating ops.IsNan: _is_nan, ops.IsInf: _is_inf, # null handling ops.IfNull: fixed_arity(sa.func.coalesce, 2), # boolean reductions ops.Any: unary(sa.func.bool_or), ops.All: unary(sa.func.bool_and), ops.NotAny: unary(lambda x: sa.not_(sa.func.bool_or(x))), ops.NotAll: unary(lambda x: sa.not_(sa.func.bool_and(x))), # strings ops.Substring: _substr, ops.StringFind: _string_find, ops.GroupConcat: _string_agg, ops.Capitalize: unary(sa.func.initcap), ops.RegexSearch: _regex_search, ops.RegexReplace: _regex_replace, ops.RegexExtract: _regex_extract, ops.Translate: fixed_arity('translate', 3), ops.StringSplit: fixed_arity(sa.func.string_to_array, 2), ops.StringJoin: _string_join, ops.FindInSet: _find_in_set,
ops.StringReplace: fixed_arity('REPLACE', 3), ops.StringSplit: fixed_arity('SPLIT', 2), ops.StringConcat: _string_concat, ops.StringJoin: _string_join, ops.StringAscii: _string_ascii, ops.StringFind: _string_find, ops.StrRight: _string_right, ops.Repeat: fixed_arity('REPEAT', 2), ops.RegexSearch: _regex_search, ops.RegexExtract: _regex_extract, ops.RegexReplace: _regex_replace, ops.GroupConcat: reduction('STRING_AGG'), ops.IfNull: fixed_arity('IFNULL', 2), ops.Cast: _cast, ops.StructField: _struct_field, ops.ArrayCollect: unary('ARRAY_AGG'), ops.ArrayConcat: _array_concat, ops.ArrayIndex: _array_index, ops.ArrayLength: unary('ARRAY_LENGTH'), ops.HLLCardinality: reduction('APPROX_COUNT_DISTINCT'), ops.Log: _log, ops.Sign: unary('SIGN'), ops.Modulus: fixed_arity('MOD', 2), ops.Date: unary('DATE'), # BigQuery doesn't have these operations built in. # ops.ArrayRepeat: _array_repeat, # ops.ArraySlice: _array_slice, ops.Literal: _literal, ops.Arbitrary: _arbitrary, ops.TimestampTruncate: _truncate('TIMESTAMP', _timestamp_units), ops.DateTruncate: _truncate('DATE', _date_units),