<s> import operator <EOL> import six <EOL> import sqlalchemy as sa <EOL> import sqlalchemy . sql as sql <EOL> from ibis . client import SQLClient , AsyncQuery , Query <EOL> from ibis . sql . compiler import Select , Union , TableSetFormatter <EOL> import ibis . common as com <EOL> import ibis . expr . datatypes as dt <EOL> import ibis . expr . operations as ops <EOL> import ibis . expr . types as ir <EOL> import ibis . sql . compiler as comp <EOL> import ibis . sql . transforms as transforms <EOL> import ibis . util as util <EOL> import ibis <EOL> _ibis_type_to_sqla = { <EOL> dt . Int8 : sa . types . SmallInteger , <EOL> dt . Int16 : sa . types . SmallInteger , <EOL> dt . Int32 : sa . types . Integer , <EOL> dt . Int64 : sa . types . BigInteger , <EOL> dt . Float : sa . types . Float ( precision = <NUM_LIT> ) , <EOL> dt . Double : sa . types . Float ( precision = <NUM_LIT> ) , <EOL> dt . Boolean : sa . types . Boolean , <EOL> dt . String : sa . types . String , <EOL> dt . Timestamp : sa . types . DateTime , <EOL> dt . Decimal : sa . types . NUMERIC , <EOL> } <EOL> _sqla_type_mapping = { <EOL> sa . types . SmallInteger : dt . Int16 , <EOL> sa . types . INTEGER : dt . Int64 , <EOL> sa . types . BOOLEAN : dt . Boolean , <EOL> sa . types . BIGINT : dt . Int64 , <EOL> sa . types . FLOAT : dt . Double , <EOL> sa . types . REAL : dt . Double , <EOL> sa . types . TEXT : dt . String , <EOL> sa . types . NullType : dt . String , <EOL> sa . types . Text : dt . String , <EOL> } <EOL> _sqla_type_to_ibis = dict ( ( v , k ) for k , v in <EOL> _ibis_type_to_sqla . items ( ) ) <EOL> _sqla_type_to_ibis . update ( _sqla_type_mapping ) <EOL> def schema_from_table ( table ) : <EOL> names = table . columns . keys ( ) <EOL> types = [ ] <EOL> for c in table . columns . values ( ) : <EOL> type_class = type ( c . type ) <EOL> if isinstance ( c . type , sa . types . NUMERIC ) : <EOL> t = dt . Decimal ( c . type . precision , <EOL> c . type . scale , <EOL> nullable = c . nullable ) <EOL> else : <EOL> if c . type in _sqla_type_to_ibis : <EOL> ibis_class = _sqla_type_to_ibis [ c . type ] <EOL> elif type_class in _sqla_type_to_ibis : <EOL> ibis_class = _sqla_type_to_ibis [ type_class ] <EOL> else : <EOL> raise NotImplementedError ( c . type ) <EOL> t = ibis_class ( c . nullable ) <EOL> types . append ( t ) <EOL> return dt . Schema ( names , types ) <EOL> def table_from_schema ( name , meta , schema ) : <EOL> sqla_cols = [ ] <EOL> for cname , itype in zip ( schema . names , schema . types ) : <EOL> ctype = _to_sqla_type ( itype ) <EOL> col = sa . Column ( cname , ctype , nullable = itype . nullable ) <EOL> sqla_cols . append ( col ) <EOL> return sa . Table ( name , meta , * sqla_cols ) <EOL> def _to_sqla_type ( itype ) : <EOL> if isinstance ( itype , dt . Decimal ) : <EOL> return sa . types . NUMERIC ( itype . precision , itype . scale ) <EOL> else : <EOL> return _ibis_type_to_sqla [ type ( itype ) ] <EOL> def fixed_arity ( sa_func , arity ) : <EOL> if isinstance ( sa_func , six . string_types ) : <EOL> sa_func = getattr ( sa . func , sa_func ) <EOL> def formatter ( t , expr ) : <EOL> if arity != len ( expr . op ( ) . args ) : <EOL> raise com . IbisError ( '<STR_LIT>' ) <EOL> return _varargs_call ( sa_func , t , expr ) <EOL> return formatter <EOL> def varargs ( sa_func ) : <EOL> def formatter ( t , expr ) : <EOL> op = expr . op ( ) <EOL> trans_args = [ t . translate ( arg ) for arg in op . args ] <EOL> return sa_func ( * trans_args ) <EOL> return formatter <EOL> def _varargs_call ( sa_func , t , expr ) : <EOL> op = expr . op ( ) <EOL> trans_args = [ t . translate ( arg ) for arg in op . args ] <EOL> return sa_func ( * trans_args ) <EOL> def _table_column ( t , expr ) : <EOL> op = expr . op ( ) <EOL> ctx = t . context <EOL> table = op . table <EOL> sa_table = _get_sqla_table ( ctx , table ) <EOL> out_expr = getattr ( sa_table . c , op . name ) <EOL> if t . permit_subquery and ctx . is_foreign_expr ( table ) : <EOL> return sa . select ( [ out_expr ] ) <EOL> return out_expr <EOL> def _get_sqla_table ( ctx , table ) : <EOL> if ctx . has_ref ( table ) : <EOL> ctx_level = ctx <EOL> sa_table = ctx_level . get_table ( table ) <EOL> while sa_table is None and ctx_level . parent is not ctx_level : <EOL> ctx_level = ctx_level . parent <EOL> sa_table = ctx_level . get_table ( table ) <EOL> else : <EOL> op = table . op ( ) <EOL> if isinstance ( op , AlchemyTable ) : <EOL> sa_table = op . sqla_table <EOL> else : <EOL> sa_table = ctx . get_compiled_expr ( table ) <EOL> return sa_table <EOL> def _table_array_view ( t , expr ) : <EOL> ctx = t . context <EOL> table = ctx . get_compiled_expr ( expr . op ( ) . table ) <EOL> return table <EOL> def _exists_subquery ( t , expr ) : <EOL> op = expr . op ( ) <EOL> ctx = t . context <EOL> filtered = ( op . foreign_table . filter ( op . predicates ) <EOL> . projection ( [ ir . literal ( <NUM_LIT:1> ) . name ( ir . unnamed ) ] ) ) <EOL> sub_ctx = ctx . subcontext ( ) <EOL> clause = to_sqlalchemy ( filtered , context = sub_ctx , exists = True ) <EOL> if isinstance ( op , transforms . NotExistsSubquery ) : <EOL> clause = sa . not_ ( clause ) <EOL> return clause <EOL> def _cast ( t , expr ) : <EOL> op = expr . op ( ) <EOL> arg , target_type = op . args <EOL> sa_arg = t . translate ( arg ) <EOL> sa_type = t . get_sqla_type ( target_type ) <EOL> if isinstance ( arg , ir . CategoryValue ) and target_type == '<STR_LIT>' : <EOL> return sa_arg <EOL> else : <EOL> return sa . cast ( sa_arg , sa_type ) <EOL> def _contains ( t , expr ) : <EOL> op = expr . op ( ) <EOL> left , right = [ t . translate ( arg ) for arg in op . args ] <EOL> return left . in_ ( right ) <EOL> def _reduction ( sa_func ) : <EOL> def formatter ( t , expr ) : <EOL> op = expr . op ( ) <EOL> arg , where = op . args [ : <NUM_LIT:2> ] <EOL> return _reduction_format ( t , sa_func , arg , where ) <EOL> return formatter <EOL> def _reduction_format ( t , sa_func , arg , where ) : <EOL> if where is not None : <EOL> case = where . ifelse ( arg , ibis . NA ) <EOL> arg = t . translate ( case ) <EOL> else : <EOL> arg = t . translate ( arg ) <EOL> return sa_func ( arg ) <EOL> def _literal ( t , expr ) : <EOL> return sa . literal ( expr . op ( ) . value ) <EOL> def _value_list ( t , expr ) : <EOL> return [ t . translate ( x ) for x in expr . op ( ) . values ] <EOL> def _is_null ( t , expr ) : <EOL> arg = t . translate ( expr . op ( ) . args [ <NUM_LIT:0> ] ) <EOL> return arg . is_ ( sa . null ( ) ) <EOL> def _not_null ( t , expr ) : <EOL> arg = t . translate ( expr . op ( ) . args [ <NUM_LIT:0> ] ) <EOL> return arg . isnot ( sa . null ( ) ) <EOL> def _round ( t , expr ) : <EOL> op = expr . op ( ) <EOL> arg , digits = op . args <EOL> sa_arg = t . translate ( arg ) <EOL> f = sa . func . round <EOL> if digits is not None : <EOL> sa_digits = t . translate ( digits ) <EOL> return f ( sa_arg , sa_digits ) <EOL> else : <EOL> return f ( sa_arg ) <EOL> def _count_distinct ( t , expr ) : <EOL> arg , = expr . op ( ) . args <EOL> sa_arg = t . translate ( arg ) <EOL> return sa . func . count ( sa_arg . distinct ( ) ) <EOL> def _simple_case ( t , expr ) : <EOL> op = expr . op ( ) <EOL> cases = [ op . base == case for case in op . cases ] <EOL> return _translate_case ( t , cases , op . results , op . default ) <EOL> def _searched_case ( t , expr ) : <EOL> op = expr . op ( ) <EOL> return _translate_case ( t , op . cases , op . results , op . default ) <EOL> def _translate_case ( t , cases , results , default ) : <EOL> case_args = [ t . translate ( arg ) for arg in cases ] <EOL> result_args = [ t . translate ( arg ) for arg in results ] <EOL> whens = zip ( case_args , result_args ) <EOL> default = t . translate ( default ) <EOL> return sa . case ( whens , else_ = default ) <EOL> def unary ( sa_func ) : <EOL> return fixed_arity ( sa_func , <NUM_LIT:1> ) <EOL> _operation_registry = { <EOL> ops . And : fixed_arity ( sql . and_ , <NUM_LIT:2> ) , <EOL> ops . Or : fixed_arity ( sql . or_ , <NUM_LIT:2> ) , <EOL> ops . Abs : unary ( sa . func . abs ) , <EOL> ops . Cast : _cast , <EOL> ops . Coalesce : varargs ( sa . func . coalesce ) , <EOL> ops . NullIf : fixed_arity ( sa . func . nullif , <NUM_LIT:2> ) , <EOL> ops . Contains : _contains , <EOL> ops . Count : _reduction ( sa . func . count ) , <EOL> ops . Sum : _reduction ( sa . func . sum ) , <EOL> ops . Mean : _reduction ( sa . func . avg ) , <EOL> ops . Min : _reduction ( sa . func . min ) , <EOL> ops . Max : _reduction ( sa . func . max ) , <EOL> ops . CountDistinct : _count_distinct , <EOL> ops . GroupConcat : fixed_arity ( sa . func . group_concat , <NUM_LIT:2> ) , <EOL> ops . Between : fixed_arity ( sa . between , <NUM_LIT:3> ) , <EOL> ops . IsNull : _is_null , <EOL> ops . NotNull : _not_null , <EOL> ops . Negate : unary ( sa . not_ ) , <EOL> ops . Round : _round , <EOL> ops . TypeOf : unary ( sa . func . typeof ) , <EOL> ir . Literal : _literal , <EOL> ir . ValueList : _value_list , <EOL> ir . NullLiteral : lambda * args : sa . null ( ) , <EOL> ops . SimpleCase : _simple_case , <EOL> ops . SearchedCase : _searched_case , <EOL> ops . TableColumn : _table_column , <EOL> ops . TableArrayView : _table_array_view , <EOL> transforms . ExistsSubquery : _exists_subquery , <EOL> transforms . NotExistsSubquery : _exists_subquery , <EOL> } <EOL> _binary_ops = { <EOL> ops . Add : operator . add , <EOL> ops . Subtract : operator . sub , <EOL> ops . Multiply : operator . mul , <EOL> ops . Divide : operator . truediv , <EOL> ops . Power : operator . pow , <EOL> ops . Modulus : operator . mod , <EOL> ops . Equals : operator . eq , <EOL> ops . NotEquals : operator . ne , <EOL> ops . Less : operator . lt , <EOL> ops . LessEqual : operator . le , <EOL> ops . Greater : operator . gt , <EOL> ops . GreaterEqual : operator . ge , <EOL> } <EOL> for _k , _v in _binary_ops . items ( ) : <EOL> _operation_registry [ _k ] = fixed_arity ( _v , <NUM_LIT:2> ) <EOL> class AlchemySelectBuilder ( comp . SelectBuilder ) : <EOL> @ property <EOL> def _select_class ( self ) : <EOL> return AlchemySelect <EOL> def _convert_group_by ( self , exprs ) : <EOL> return exprs <EOL> class AlchemyContext ( comp . QueryContext ) : <EOL> def __init__ ( self , * args , ** kwargs ) : <EOL> self . _table_objects = { } <EOL> self . dialect = kwargs . pop ( '<STR_LIT>' , AlchemyDialect ) <EOL> comp . QueryContext . __init__ ( self , * args , ** kwargs ) <EOL> def subcontext ( self ) : <EOL> return type ( self ) ( dialect = self . dialect , parent = self ) <EOL> def _to_sql ( self , expr , ctx ) : <EOL> return to_sqlalchemy ( expr , context = ctx ) <EOL> def _compile_subquery ( self , expr ) : <EOL> sub_ctx = self . subcontext ( ) <EOL> return self . _to_sql ( expr , sub_ctx ) <EOL> def has_table ( self , expr , parent_contexts = False ) : <EOL> key = self . _get_table_key ( expr ) <EOL> return self . _key_in ( key , '<STR_LIT>' , <EOL> parent_contexts = parent_contexts ) <EOL> def set_table ( self , expr , obj ) : <EOL> key = self . _get_table_key ( expr ) <EOL> self . _table_objects [ key ] = obj <EOL> def get_table ( self , expr ) : <EOL> """<STR_LIT>""" <EOL> return self . _get_table_item ( '<STR_LIT>' , expr ) <EOL> class AlchemyQueryBuilder ( comp . QueryBuilder ) : <EOL> select_builder = AlchemySelectBuilder <EOL> def __init__ ( self , expr , context = None , dialect = None ) : <EOL> if dialect is None : <EOL> dialect = AlchemyDialect <EOL> self . dialect = dialect <EOL> comp . QueryBuilder . __init__ ( self , expr , context = context ) <EOL> def _make_context ( self ) : <EOL> return AlchemyContext ( dialect = self . dialect ) <EOL> @ property <EOL> def _union_class ( self ) : <EOL> return AlchemyUnion <EOL> def to_sqlalchemy ( expr , context = None , exists = False , dialect = None ) : <EOL> if context is not None : <EOL> dialect = dialect or context . dialect <EOL> ast = build_ast ( expr , context = context , dialect = dialect ) <EOL> query = ast . queries [ <NUM_LIT:0> ] <EOL> if exists : <EOL> query . exists = exists <EOL> return query . compile ( ) <EOL> def build_ast ( expr , context = None , dialect = None ) : <EOL> builder = AlchemyQueryBuilder ( expr , context = context , dialect = dialect ) <EOL> return builder . get_result ( ) <EOL> class AlchemyTable ( ops . DatabaseTable ) : <EOL> def __init__ ( self , table , source ) : <EOL> self . sqla_table = table <EOL> schema = schema_from_table ( table ) <EOL> name = table . name <EOL> ops . TableNode . __init__ ( self , [ name , schema , source ] ) <EOL> ops . HasSchema . __init__ ( self , schema , name = name ) <EOL> class AlchemyExprTranslator ( comp . ExprTranslator ) : <EOL> _registry = _operation_registry <EOL> _rewrites = comp . ExprTranslator . _rewrites . copy ( ) <EOL> _type_map = _ibis_type_to_sqla <EOL> def name ( self , translated , name , force = True ) : <EOL> return translated . label ( name ) <EOL> @ property <EOL> def _context_class ( self ) : <EOL> return AlchemyContext <EOL> def get_sqla_type ( self , data_type ) : <EOL> return self . _type_map [ type ( data_type ) ] <EOL> rewrites = AlchemyExprTranslator . rewrites <EOL> compiles = AlchemyExprTranslator . compiles <EOL> class AlchemyQuery ( Query ) : <EOL> def _fetch ( self , cursor ) : <EOL> import pandas as pd <EOL> proxy = cursor . proxy <EOL> rows = proxy . fetchall ( ) <EOL> colnames = proxy . keys ( ) <EOL> return pd . DataFrame . from_records ( rows , columns = colnames , <EOL> coerce_float = True ) <EOL> class AlchemyAsyncQuery ( AsyncQuery ) : <EOL> pass <EOL> class AlchemyDialect ( object ) : <EOL> translator = AlchemyExprTranslator <EOL> class AlchemyClient ( SQLClient ) : <EOL> dialect = AlchemyDialect <EOL> sync_query = AlchemyQuery <EOL> @ property <EOL> def async_query ( self ) : <EOL> raise NotImplementedError <EOL> def create_table ( self , name , expr = None , schema = None , database = None ) : <EOL> pass <EOL> def list_tables ( self , like = None , database = None ) : <EOL> """<STR_LIT>""" <EOL> if database is None : <EOL> database = self . current_database <EOL> names = self . con . table_names ( schema = database ) <EOL> if like is not None : <EOL> names = [ x for x in names if like in x ] <EOL> return names <EOL> def _execute ( self , query , results = True ) : <EOL> return AlchemyProxy ( self . con . execute ( query ) ) <EOL> def _build_ast ( self , expr ) : <EOL> return build_ast ( expr , dialect = self . dialect ) <EOL> def _get_sqla_table ( self , name ) : <EOL> return sa . Table ( name , self . meta , autoload = True ) <EOL> def _sqla_table_to_expr ( self , table ) : <EOL> node = AlchemyTable ( table , self ) <EOL> return self . _table_expr_klass ( node ) <EOL> class AlchemySelect ( Select ) : <EOL> def __init__ ( self , * args , ** kwargs ) : <EOL> self . exists = kwargs . pop ( '<STR_LIT>' , False ) <EOL> Select . __init__ ( self , * args , ** kwargs ) <EOL> def compile ( self ) : <EOL> self . context . set_query ( self ) <EOL> self . _compile_subqueries ( ) <EOL> frag = self . _compile_table_set ( ) <EOL> steps = [ self . _add_select , <EOL> self . _add_groupby , <EOL> self . _add_where , <EOL> self . _add_order_by , <EOL> self . _add_limit ] <EOL> for step in steps : <EOL> frag = step ( frag ) <EOL> return frag <EOL> def _compile_subqueries ( self ) : <EOL> if len ( self . subqueries ) == <NUM_LIT:0> : <EOL> return <EOL> for expr in self . subqueries : <EOL> result = self . context . get_compiled_expr ( expr ) <EOL> alias = self . context . get_ref ( expr ) <EOL> result = result . cte ( alias ) <EOL> self . context . set_table ( expr , result ) <EOL> def _compile_table_set ( self ) : <EOL> if self . table_set is not None : <EOL> helper = _AlchemyTableSet ( self , self . table_set ) <EOL> return helper . get_result ( ) <EOL> else : <EOL> return None <EOL> def _add_select ( self , table_set ) : <EOL> to_select = [ ] <EOL> has_select_star = False <EOL> for expr in self . select_set : <EOL> if isinstance ( expr , ir . ValueExpr ) : <EOL> arg = self . _translate ( expr , named = True ) <EOL> elif isinstance ( expr , ir . TableExpr ) : <EOL> if expr . equals ( self . table_set ) : <EOL> cached_table = self . context . get_table ( expr ) <EOL> if cached_table is None : <EOL> has_select_star = True <EOL> continue <EOL> else : <EOL> arg = table_set <EOL> else : <EOL> arg = self . context . get_table ( expr ) <EOL> if arg is None : <EOL> raise ValueError ( expr ) <EOL> to_select . append ( arg ) <EOL> if has_select_star : <EOL> if table_set is None : <EOL> raise ValueError ( '<STR_LIT>' ) <EOL> clauses = [ table_set ] + to_select <EOL> else : <EOL> clauses = to_select <EOL> if self . exists : <EOL> result = sa . exists ( clauses ) <EOL> else : <EOL> result = sa . select ( clauses ) <EOL> if self . distinct : <EOL> result = result . distinct ( ) <EOL> if not has_select_star : <EOL> if table_set is not None : <EOL> return result . select_from ( table_set ) <EOL> else : <EOL> return result <EOL> else : <EOL> return result <EOL> def _add_groupby ( self , fragment ) : <EOL> if not len ( self . group_by ) : <EOL> return fragment <EOL> group_keys = [ self . _translate ( arg ) for arg in self . group_by ] <EOL> fragment = fragment . group_by ( * group_keys ) <EOL> if len ( self . having ) > <NUM_LIT:0> : <EOL> having_args = [ self . _translate ( arg ) for arg in self . having ] <EOL> having_clause = _and_all ( having_args ) <EOL> fragment = fragment . having ( having_clause ) <EOL> return fragment <EOL> def _add_where ( self , fragment ) : <EOL> if not len ( self . where ) : <EOL> return fragment <EOL> args = [ self . _translate ( pred , permit_subquery = True ) <EOL> for pred in self . where ] <EOL> clause = _and_all ( args ) <EOL> return fragment . where ( clause ) <EOL> def _add_order_by ( self , fragment ) : <EOL> if not len ( self . order_by ) : <EOL> return fragment <EOL> clauses = [ ] <EOL> for expr in self . order_by : <EOL> key = expr . op ( ) <EOL> sort_expr = key . expr <EOL> if _can_lower_sort_column ( self . table_set , sort_expr ) : <EOL> arg = sort_expr . get_name ( ) <EOL> else : <EOL> arg = self . _translate ( sort_expr ) <EOL> if not key . ascending : <EOL> arg = sa . desc ( arg ) <EOL> clauses . append ( arg ) <EOL> return fragment . order_by ( * clauses ) <EOL> def _among_select_set ( self , expr ) : <EOL> for other in self . select_set : <EOL> if expr . equals ( other ) : <EOL> return True <EOL> return False <EOL> def _add_limit ( self , fragment ) : <EOL> if self . limit is None : <EOL> return fragment <EOL> n , offset = self . limit [ '<STR_LIT:n>' ] , self . limit [ '<STR_LIT>' ] <EOL> fragment = fragment . limit ( n ) <EOL> if offset is not None and offset != <NUM_LIT:0> : <EOL> fragment = fragment . offset ( offset ) <EOL> return fragment <EOL> @ property <EOL> def translator ( self ) : <EOL> return self . dialect . translator <EOL> @ property <EOL> def dialect ( self ) : <EOL> return self . context . dialect <EOL> class _AlchemyTableSet ( TableSetFormatter ) : <EOL> def get_result ( self ) : <EOL> op = self . expr . op ( ) <EOL> if isinstance ( op , ops . Join ) : <EOL> self . _walk_join_tree ( op ) <EOL> else : <EOL> self . join_tables . append ( self . _format_table ( self . expr ) ) <EOL> result = self . join_tables [ <NUM_LIT:0> ] <EOL> for jtype , table , preds in zip ( self . join_types , <EOL> self . join_tables [ <NUM_LIT:1> : ] , <EOL> self . join_predicates ) : <EOL> if len ( preds ) : <EOL> sqla_preds = [ self . _translate ( pred ) for pred in preds ] <EOL> onclause = _and_all ( sqla_preds ) <EOL> else : <EOL> onclause = None <EOL> if jtype in ( ops . InnerJoin , ops . CrossJoin ) : <EOL> result = result . join ( table , onclause ) <EOL> elif jtype is ops . LeftJoin : <EOL> result = result . join ( table , onclause , isouter = True ) <EOL> elif jtype is ops . RightJoin : <EOL> result = table . join ( result , onclause , isouter = True ) <EOL> elif jtype is ops . OuterJoin : <EOL> result = result . outerjoin ( table , onclause ) <EOL> else : <EOL> raise NotImplementedError ( jtype ) <EOL> return result <EOL> def _get_join_type ( self , op ) : <EOL> return type ( op ) <EOL> def _format_table ( self , expr ) : <EOL> ctx = self . context <EOL> ref_expr = expr <EOL> op = ref_op = expr . op ( ) <EOL> if isinstance ( op , ops . SelfReference ) : <EOL> ref_expr = op . table <EOL> ref_op = ref_expr . op ( ) <EOL> alias = ctx . get_ref ( expr ) <EOL> if isinstance ( ref_op , AlchemyTable ) : <EOL> result = ref_op . sqla_table <EOL> else : <EOL> if ctx . is_extracted ( ref_expr ) : <EOL> alias = ctx . get_ref ( expr ) <EOL> if isinstance ( op , ops . SelfReference ) : <EOL> table = ctx . get_table ( ref_expr ) <EOL> self_ref = table . alias ( alias ) <EOL> ctx . set_table ( expr , self_ref ) <EOL> return self_ref <EOL> else : <EOL> return ctx . get_table ( expr ) <EOL> result = ctx . get_compiled_expr ( expr ) <EOL> alias = ctx . get_ref ( expr ) <EOL> result = result . alias ( alias ) <EOL> ctx . set_table ( expr , result ) <EOL> return result <EOL> def _can_lower_sort_column ( table_set , expr ) : <EOL> bases = ops . find_all_base_tables ( expr ) <EOL> if len ( bases ) > <NUM_LIT:1> : <EOL> return False <EOL> base = list ( bases . values ( ) ) [ <NUM_LIT:0> ] <EOL> base_op = base . op ( ) <EOL> if isinstance ( base_op , ops . Aggregation ) : <EOL> return base_op . table . equals ( table_set ) <EOL> elif isinstance ( base_op , ops . Selection ) : <EOL> return base . equals ( table_set ) <EOL> else : <EOL> return False <EOL> def _and_all ( clauses ) : <EOL> result = clauses [ <NUM_LIT:0> ] <EOL> for clause in clauses [ <NUM_LIT:1> : ] : <EOL> result = sql . and_ ( result , clause ) <EOL> return result <EOL> class AlchemyUnion ( Union ) : <EOL> def compile ( self ) : <EOL> context = self . context <EOL> if self . distinct : <EOL> sa_func = sa . union <EOL> else : <EOL> sa_func = sa . union_all <EOL> left_set = context . get_compiled_expr ( self . left ) <EOL> right_set = context . get_compiled_expr ( self . right ) <EOL> return sa_func ( left_set , right_set ) <EOL> class AlchemyProxy ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , proxy ) : <EOL> self . proxy = proxy <EOL> def __del__ ( self ) : <EOL> self . _close_cursor ( ) <EOL> def _close_cursor ( self ) : <EOL> self . proxy . close ( ) <EOL> def __enter__ ( self ) : <EOL> return self <EOL> def __exit__ ( self , type , value , tb ) : <EOL> self . _close_cursor ( ) <EOL> def fetchall ( self ) : <EOL> return self . proxy . fetchall ( ) <EOL> @ rewrites ( ops . NullIfZero ) <EOL> def _nullifzero ( expr ) : <EOL> arg = expr . op ( ) . args [ <NUM_LIT:0> ] <EOL> return ( arg == <NUM_LIT:0> ) . ifelse ( ibis . NA , arg ) <EOL> @ compiles ( ops . Divide ) <EOL> def _true_divide ( t , expr ) : <EOL> op = expr . op ( ) <EOL> left , right = op . args <EOL> if util . all_of ( op . args , ir . IntegerValue ) : <EOL> new_expr = left . div ( right . cast ( '<STR_LIT>' ) ) <EOL> return t . translate ( new_expr ) <EOL> return fixed_arity ( lambda x , y : x / y , <NUM_LIT:2> ) ( t , expr ) <EOL> @ compiles ( ops . FloorDivide ) <EOL> def _floor_divide ( t , expr ) : <EOL> op = expr . op ( ) <EOL> left , right = op . args <EOL> if util . any_of ( op . args , ir . FloatingValue ) : <EOL> new_expr = expr . floor ( ) <EOL> return t . translate ( new_expr ) <EOL> return fixed_arity ( lambda x , y : x / y , <NUM_LIT:2> ) ( t , expr ) </s>
