# Buggy code
def _make_table_aliases(self, expr):
    ctx = self.context
    node = expr.op()
    if isinstance(node, ops.Join):
        for arg in node.args:
            if not isinstance(arg, ir.TableExpr):
                continue
            self._make_table_aliases(arg)
    else:
        if not ctx.is_extracted(expr):
            ctx.make_alias(expr)


# Traceback (HiveServer2Error)
SELECT `movieid`
FROM (
SELECT t1.*
FROM (
SELECT t4.*, t2.`title`
FROM (
SELECT `userid`, `movieid`, `rating`,
CAST(`timestamp` AS timestamp) AS `datetime`
FROM default.`rating_parquet`
) t4
INNER JOIN default.`movie_parquet` t2
ON t4.`movieid` = t2.`movieid`
) t1
WHERE t1.`userid` = 118205 AND
extract(t1.`datetime`, 'year') > 2001 AND
t1.`userid` = 118205 AND
extract(t1.`datetime`, 'year') > 2001 AND
extract(t1.`datetime`, 'year') < 2009
) t0
--------------
WITH t0 AS (
SELECT `userid`, `movieid`, `rating`,
CAST(`timestamp` AS timestamp) AS `datetime`
FROM default.`rating_parquet`
),
t1 AS (
SELECT *, `title`
FROM t0
INNER JOIN default.`movie_parquet`
ON `movieid` = `movieid`
),
t2 AS (
SELECT t1.*
FROM t1
WHERE t1.`userid` = 118205 AND
extract(t1.`datetime`, 'year') > 2001
)
SELECT t2.*
FROM t2
WHERE t2.`movieid` IN (
SELECT `movieid`
FROM (
SELECT t1.*
FROM t1
WHERE t1.`userid` = 118205 AND
extract(t1.`datetime`, 'year') > 2001 AND
t1.`userid` = 118205 AND
extract(t1.`datetime`, 'year') > 2001 AND
extract(t1.`datetime`, 'year') < 2009
) t4
)
---------------------------------------------------------------------------
HiveServer2Error                          Traceback (most recent call last)
/Users/ariga/.virtualenvs/ibis/lib/python3.5/site-packages/IPython/core/formatters.py in __call__(self, obj)
697                 type_pprinters=self.type_printers,
698                 deferred_pprinters=self.deferred_printers)
--> 699             printer.pretty(obj)
700             printer.flush()
701             return stream.getvalue()

/Users/ariga/.virtualenvs/ibis/lib/python3.5/site-packages/IPython/lib/pretty.py in pretty(self, obj)
381                             if callable(meth):
382                                 return meth(obj, self, cycle)
--> 383             return _default_pprint(obj, self, cycle)
384         finally:
385             self.end_group()

/Users/ariga/.virtualenvs/ibis/lib/python3.5/site-packages/IPython/lib/pretty.py in _default_pprint(obj, p, cycle)
501     if _safe_getattr(klass, '__repr__', None) not in _baseclass_reprs:
502         # A user-provided repr. Find newlines and replace them with p.break_()
--> 503         _repr_pprint(obj, p, cycle)
504         return
505     p.begin_group(1, '<')

/Users/ariga/.virtualenvs/ibis/lib/python3.5/site-packages/IPython/lib/pretty.py in _repr_pprint(obj, p, cycle)
692     """A pprint that just redirects to the normal repr function."""
693     # Find newlines and replace them with p.break_()
--> 694     output = repr(obj)
695     for idx,output_line in enumerate(output.splitlines()):
696         if idx:

/Users/ariga/.virtualenvs/ibis/lib/python3.5/site-packages/ibis/expr/types.py in __repr__(self)
48         if config.options.interactive:
49             try:
---> 50                 result = self.execute()
51                 return repr(result)
52             except com.TranslationError as e:

/Users/ariga/.virtualenvs/ibis/lib/python3.5/site-packages/ibis/expr/types.py in execute(self, limit, async)
143         """
144         from ibis.client import execute
--> 145         return execute(self, limit=limit, async=async)
146
147     def compile(self, limit=None):

/Users/ariga/.virtualenvs/ibis/lib/python3.5/site-packages/ibis/client.py in execute(expr, limit, async)
312 def execute(expr, limit='default', async=False):
313     backend = find_backend(expr)
--> 314     return backend.execute(expr, limit=limit, async=async)
315
316

/Users/ariga/.virtualenvs/ibis/lib/python3.5/site-packages/ibis/client.py in execute(self, expr, params, limit, async)
228             raise NotImplementedError
229         else:
--> 230             return self._execute_query(ast.queries[0], async=async)
231
232     def _execute_query(self, ddl, async=False):

/Users/ariga/.virtualenvs/ibis/lib/python3.5/site-packages/ibis/client.py in _execute_query(self, ddl, async)
232     def _execute_query(self, ddl, async=False):
233         klass = self.async_query if async else self.sync_query
--> 234         return klass(self, ddl).execute()
235
236     def compile(self, expr, params=None, limit=None):

/Users/ariga/.virtualenvs/ibis/lib/python3.5/site-packages/ibis/client.py in execute(self)
47     def execute(self):
48         # synchronous by default
---> 49         with self.client._execute(self.compiled_ddl, results=True) as cur:
50             result = self._fetch(cur)
51

/Users/ariga/.virtualenvs/ibis/lib/python3.5/site-packages/ibis/client.py in _execute(self, query, results)
152
153     def _execute(self, query, results=False):
--> 154         cur = self.con.execute(query)
155         if results:
156             return cur

/Users/ariga/.virtualenvs/ibis/lib/python3.5/site-packages/ibis/impala/client.py in execute(self, query, async)
117
118         try:
--> 119             cursor.execute(query, async=async)
120         except:
121             cursor.release()

/Users/ariga/.virtualenvs/ibis/lib/python3.5/site-packages/ibis/impala/client.py in execute(self, stmt, async)
225
226     def execute(self, stmt, async=False):
--> 227         self._cursor.execute_async(stmt)
228         if async:
229             return

/Users/ariga/.virtualenvs/ibis/lib/python3.5/site-packages/impala/hiveserver2.py in execute_async(self, operation, parameters, configuration)
287             self._last_operation = op
288
--> 289         self._execute_async(op)
290
291     def _debug_log_state(self):

/Users/ariga/.virtualenvs/ibis/lib/python3.5/site-packages/impala/hiveserver2.py in _execute_async(self, operation_fn)
306         self._reset_state()
307         self._debug_log_state()
--> 308         operation_fn()
309         self._last_operation_active = True
310         self._debug_log_state()

/Users/ariga/.virtualenvs/ibis/lib/python3.5/site-packages/impala/hiveserver2.py in op()
284             op = self.session.execute(self._last_operation_string,
285                                       configuration,
--> 286                                       async=True)
287             self._last_operation = op
288

/Users/ariga/.virtualenvs/ibis/lib/python3.5/site-packages/impala/hiveserver2.py in execute(self, statement, configuration, async)
917                                    confOverlay=configuration,
918                                    runAsync=async)
--> 919         return self._operation('ExecuteStatement', req)
920
921     def get_databases(self, schema='.*'):

/Users/ariga/.virtualenvs/ibis/lib/python3.5/site-packages/impala/hiveserver2.py in _operation(self, kind, request)
847
848     def _operation(self, kind, request):
--> 849         resp = self._rpc(kind, request)
850         return self._get_operation(resp.operationHandle)
851

/Users/ariga/.virtualenvs/ibis/lib/python3.5/site-packages/impala/hiveserver2.py in _rpc(self, func_name, request)
815         response = self._execute(func_name, request)
816         self._log_response(func_name, response)
--> 817         err_if_rpc_not_ok(response)
818         return response
819

/Users/ariga/.virtualenvs/ibis/lib/python3.5/site-packages/impala/hiveserver2.py in err_if_rpc_not_ok(resp)
602             resp.status.statusCode != TStatusCode.SUCCESS_WITH_INFO_STATUS and
603             resp.status.statusCode != TStatusCode.STILL_EXECUTING_STATUS):
--> 604         raise HiveServer2Error(resp.status.errorMessage)
605
606

HiveServer2Error: AnalysisException: Column/field reference is ambiguous: 'movieid'

# Fixed code
def _make_table_aliases(self, expr):
    ctx = self.context
    node = expr.op()
    if isinstance(node, ops.Join):
        for arg in node.args:
            if isinstance(arg, ir.TableExpr):
                self._make_table_aliases(arg)
    else:
        if not ctx.is_extracted(expr):
            ctx.make_alias(expr)
        else:
            # The compiler will apply a prefix only if the current context
            # contains two or more table references. So, if we've extracted
            # a subquery into a CTE, we need to propagate that reference
            # down to child contexts so that they aren't missing any refs.
            ctx.set_ref(expr, ctx.top_context.get_ref(expr))