ref is a NameX or AttrX. return (canonical_table_name, column_name).

def resolve_column(self, ref):
    "ref is a NameX or AttrX. return (canonical_table_name, column_name)."
    if isinstance(ref, sqparse2.AttrX):
      if ref.parent.name not in self:
        raise ScopeUnkError('unk table or table alias', ref.parent.name)
      return ref.parent.name, ref.attr.name
    elif isinstance(ref, sqparse2.NameX):
      matches = set()
      for name, target in self.names.items():
        if isinstance(target, SyntheticTable):
          if ref.name in target.columns(self):
            matches.add(name)
        elif isinstance(target, table.Table):
          try: target.get_column(ref.name)
          except KeyError: pass
          else: matches.add(name)
        else:
          raise TypeError('expected SyntheticTable', type(target), target)
      if not matches: raise ScopeUnkError(ref)
      elif len(matches) > 1: raise ScopeCollisionError(matches, ref)
      else: return list(matches)[0], ref.name
    else:
      raise TypeError('unexpected', type(ref), ref)