sa_arg = t.translate(arg) fractional_second = sa.func.strftime('%f', sa_arg) return (fractional_second * 1000) % 1000 _operation_registry.update({ ops.Cast: _cast, ops.Substring: _substr, ops.StrRight: _string_right, ops.StringFind: _string_find, ops.StringLength: unary('length'), ops.Least: varargs(sa.func.min), ops.Greatest: varargs(sa.func.max), ops.IfNull: fixed_arity(sa.func.ifnull, 2), ops.Lowercase: unary('lower'), ops.Uppercase: unary('upper'), ops.Strip: unary('trim'), ops.LStrip: unary('ltrim'), ops.RStrip: unary('rtrim'), ops.StringReplace: fixed_arity(sa.func.replace, 3), ops.StringSQLLike: _infix_op('LIKE'), ops.RegexSearch: _infix_op('REGEXP'), ops.Strftime: _strftime,
return True else: left, right = map(t.translate, args) return left.op('IS NOT DISTINCT FROM')(right) _operation_registry.update({ # types ops.Cast: _cast, ops.TypeOf: _typeof, # miscellaneous varargs ops.Least: varargs(sa.func.least), ops.Greatest: varargs(sa.func.greatest), # null handling ops.IfNull: fixed_arity(sa.func.coalesce, 2), # boolean reductions ops.Any: fixed_arity(sa.func.bool_or, 1), ops.All: fixed_arity(sa.func.bool_and, 1), ops.NotAny: fixed_arity(lambda x: sa.not_(sa.func.bool_or(x)), 1), ops.NotAll:
( sa.func.textregexeq(string, pattern), sa.func.regex_extract(string, pattern, index + 1) ) ], else_='' ) _operation_registry.update({ # types ops.Cast: _cast, ops.TypeOf: _typeof, # miscellaneous varargs ops.Least: varargs(sa.func.least), ops.Greatest: varargs(sa.func.greatest), # null handling ops.IfNull: fixed_arity(sa.func.coalesce, 2), # boolean reductions ops.Any: fixed_arity(sa.func.bool_or, 1), ops.All: fixed_arity(sa.func.bool_and, 1), ops.NotAny: fixed_arity(lambda x: sa.not_(sa.func.bool_or(x)), 1), ops.NotAll: fixed_arity(lambda x: sa.not_(sa.func.bool_and(x)), 1), # strings ops.Substring: _substr, ops.StrRight: fixed_arity(sa.func.right, 2), ops.StringFind: _string_find,
def _rpad(t, expr): arg, length, pad = map(t.translate, expr.op().args) return arg + _generic_pad(arg, length, pad) _operation_registry.update({ ops.Cast: _cast, ops.Substring: _substr, ops.StrRight: _string_right, ops.StringFind: _string_find, ops.Least: varargs(sa.func.min), ops.Greatest: varargs(sa.func.max), ops.IfNull: fixed_arity(sa.func.ifnull, 2), ops.DateTruncate: _truncate(sa.func.date), ops.TimestampTruncate: _truncate(sa.func.datetime), ops.Strftime: _strftime, ops.ExtractYear: _strftime_int('%Y'), ops.ExtractMonth: _strftime_int('%m'), ops.ExtractDay:
# is a multiple of the array's length, then the index is the array's length index_expression = series_column % array_length index = sa.func.coalesce(sa.func.nullif(index_expression, 0), array_length) # tie it all together in a scalar subquery and collapse that into an ARRAY selected = sa.select([array[index]]).select_from(series) return sa.func.array(selected.as_scalar()) _operation_registry.update({ # types ops.Cast: _cast, ops.TypeOf: _typeof, # miscellaneous varargs ops.Least: varargs(sa.func.least), ops.Greatest: varargs(sa.func.greatest), # null handling ops.IfNull: fixed_arity(sa.func.coalesce, 2), # boolean reductions ops.Any: fixed_arity(sa.func.bool_or, 1), ops.All: fixed_arity(sa.func.bool_and, 1), ops.NotAny: fixed_arity(lambda x: sa.not_(sa.func.bool_or(x)), 1), ops.NotAll: fixed_arity(lambda x: sa.not_(sa.func.bool_and(x)), 1), # strings ops.Substring: _substr, ops.StrRight: fixed_arity(sa.func.right, 2), ops.StringFind: _string_find,