docs: 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