def infer_columns(selectx,tables_dict):
  """infer the columns for a subselect that creates an implicit table.
  the output of this *can* contain duplicate names, fingers crossed that downstream code uses the first.
  (Look up SQL spec on dupe names.)
  todo(refactor): I think there's common logic here and inside NameIndexer that can be merged.
  todo(ugly): this is a beast
  """
  # todo: support CTEs -- with all this plumbing, might as well
  table2fields = {}
  table_order = []
  for t in selectx.tables:
    if isinstance(t,basestring):
      table2fields[t]=tables_dict[t].fields
      table_order.append(t)
    elif isinstance(t,sqparse2.AliasX):
      if isinstance(t.name,basestring):
        table2fields[t]=tables_dict[t]
        table_order.append(t.name)
      elif isinstance(t.name,sqparse2.SelectX): raise NotImplementedError('todo: inner subquery')
      else: raise TypeError('AliasX.name',type(t.name))
    else: raise TypeError('table',type(t))
  # the forms are: *, x.*, x.y, y. expressions are anonymous unless they have an 'as' (which I don't support)
  table_order=uniqify(table_order)
  cols=[]
  used_name_collision = collections.Counter()
  for col in selectx.cols.children:
    if isinstance(col,sqparse2.AsterX):
      for t in table_order:
        cols.extend(table2fields[t])
    elif isinstance(col,sqparse2.BaseX):
      all_paths = treepath.sub_slots(col, lambda x:isinstance(x,(sqparse2.AttrX,sqparse2.NameX,sqparse2.AliasX)), match=True)
      paths = eliminate_sequential_children(all_paths) # this eliminates NameX under AttrX
      for p in paths:
        x = col[p]
        if isinstance(x,sqparse2.AttrX):
          if not isinstance(x.parent,sqparse2.NameX): raise TypeError('parent_not_name',type(x.parent))
          if isinstance(x.attr,sqparse2.NameX): raise NotImplementedError # todo
          elif isinstance(x.attr,sqparse2.AsterX): cols.extend(table2fields[x.parent.name])
          else: raise TypeError('attr_unk_type',type(x.attr))
        elif isinstance(x,sqparse2.NameX):
          matching_fields = filter(None,(next((f for f in table2fields[t] if f.name==x.name),None) for t in table_order))
          if len(matching_fields)!=1: raise sqparse2.SQLSyntaxError('missing_or_dupe_field',x,matching_fields)
          cols.append(matching_fields[0])
        elif isinstance(x,sqparse2.AliasX): cols.append(sqparse2.ColX(x.alias,None,None,None,None,None))
        else: raise TypeError('unk_item_type',type(x)) # pragma: no cover
    else: raise TypeError('unk_col_type',type(col)) # pragma: no cover
  return cols
infer the columns for a subselect that creates an implicit table.
  the output of this *can* contain duplicate names, fingers crossed that downstream code uses the first.
  (Look up SQL spec on dupe names.)
  todo(refactor): I think there's common logic here and inside NameIndexer that can be merged.
  todo(ugly): this is a beast