def visit_string_op()

in odps/df/backends/sqlalchemy/compiler.py [0:0]


    def visit_string_op(self, expr):
        if isinstance(expr, strings.Capitalize):
            input = self._expr_to_sqlalchemy[expr._input]
            tp = types.df_type_to_sqlalchemy_type(expr.dtype)
            sa_expr = func.upper(func.substr(input, 1, 1)).cast(tp) + \
                      func.lower(func.substr(input, 2)).cast(tp)
        elif isinstance(expr, strings.Contains) and not expr.regex:
            sa_expr = self._expr_to_sqlalchemy[expr._input].contains(
                self._expr_to_sqlalchemy[expr._pat])
        elif isinstance(expr, strings.Endswith):
            sa_expr = self._expr_to_sqlalchemy[expr._input].endswith(
                self._expr_to_sqlalchemy[expr._pat])
        elif isinstance(expr, strings.Startswith):
            sa_expr = self._expr_to_sqlalchemy[expr._input].startswith(
                self._expr_to_sqlalchemy[expr._pat])
        elif isinstance(expr, strings.Replace) and not expr.regex:
            sa_expr = func.replace(self._expr_to_sqlalchemy[expr._input],
                                   self._expr_to_sqlalchemy[expr._pat],
                                   self._expr_to_sqlalchemy[expr._repl])
        elif isinstance(expr, strings.Get):
            sa_expr = func.substr(self._expr_to_sqlalchemy[expr._input],
                                  self._expr_to_sqlalchemy[expr._index] + 1, 1)
        elif isinstance(expr, strings.Len):
            sa_expr = func.length(self._expr_to_sqlalchemy[expr._input])
        elif isinstance(expr, (strings.Ljust, strings.Rjust, strings.Pad)):
            if isinstance(expr, strings.Pad):
                if expr.side == 'both':
                    raise NotImplementedError
                op = func.lpad if expr.side == 'left' else func.rpad
            else:
                op = func.lpad if isinstance(expr, strings.Ljust) else func.rpad
            sa_expr = op(self._expr_to_sqlalchemy[expr._input],
                         self._expr_to_sqlalchemy[expr._width],
                         self._expr_to_sqlalchemy[expr._fillchar])
        elif isinstance(expr, (strings.Lower, strings.Upper)):
            op = func.lower if isinstance(expr, strings.Lower) else func.upper
            sa_expr = op(self._expr_to_sqlalchemy[expr._input])
        elif isinstance(expr, (strings.Lstrip, strings.Rstrip, strings.Strip)):
            if expr._to_strip is None:
                raise NotImplementedError
            op = func.ltrim if isinstance(expr, strings.Lstrip) else (
                func.rtrim if isinstance(expr, strings.Rstrip) else func.btrim
            )
            sa_expr = op(self._expr_to_sqlalchemy[expr._input],
                         self._expr_to_sqlalchemy[expr._to_strip])
        elif isinstance(expr, strings.Repeat):
            sa_expr = func.repeat(self._expr_to_sqlalchemy[expr._input],
                                  self._expr_to_sqlalchemy[expr._repeats])
        elif isinstance(expr, strings.Slice):
            if expr.end is None and expr.step is None:
                sa_expr = func.substr(self._expr_to_sqlalchemy[expr._input],
                                      self._expr_to_sqlalchemy[expr._start] + 1)
            elif isinstance(expr.start, six.integer_types) and \
                    isinstance(expr.end, six.integer_types) and \
                    expr.step is None and expr.start > 0 and expr.end > 0:
                length = expr.end - expr.start
                sa_expr = func.substr(self._expr_to_sqlalchemy[expr._input],
                                      expr.start + 1, length)
            else:
                raise NotImplementedError
        elif isinstance(expr, strings.Title):
            sa_expr = func.initcap(self._expr_to_sqlalchemy[expr._input])
        else:
            raise NotImplementedError

        self._add(expr, sa_expr)