def add_cond(lcol, rcol, rref, prio, meta): prefix = '' if suggestion.parent else ltbl.ref + '.' case = self.case cond = prefix + case(lcol) + ' = ' + rref + '.' + case(rcol) if cond not in found_conds: found_conds.add(cond) conds.append(Candidate(cond, prio + ref_prio[rref], meta))
def _make_cand(self, tbl, do_alias, suggestion): cased_tbl = self.case(tbl.name) if do_alias: alias = self.alias(cased_tbl, suggestion.table_refs) synonyms = (cased_tbl, generate_alias(cased_tbl)) maybe_parens = '()' if tbl.function else '' maybe_alias = (' ' + alias) if do_alias else '' maybe_schema = (self.case(tbl.schema) + '.') if tbl.schema else '' item = maybe_schema + cased_tbl + maybe_parens + maybe_alias prio2 = 0 if tbl.schema else 1 return Candidate(item, synonyms=synonyms, prio2=prio2)
def get_join_matches(self, suggestion, word_before_cursor): tbls = suggestion.table_refs cols = self.populate_scoped_cols(tbls) # Set up some data structures for efficient access qualified = dict((normalize_ref(t.ref), t.schema) for t in tbls) ref_prio = dict((normalize_ref(t.ref), n) for n, t in enumerate(tbls)) refs = set(normalize_ref(t.ref) for t in tbls) other_tbls = set((t.schema, t.name) for t in list(cols)[:-1]) joins = [] # Iterate over FKs in existing tables to find potential joins fks = ((fk, rtbl, rcol) for rtbl, rcols in cols.items() for rcol in rcols for fk in rcol.foreignkeys) col = namedtuple('col', 'schema tbl col') for fk, rtbl, rcol in fks: right = col(rtbl.schema, rtbl.name, rcol.name) child = col(fk.childschema, fk.childtable, fk.childcolumn) parent = col(fk.parentschema, fk.parenttable, fk.parentcolumn) left = child if parent == right else parent if suggestion.schema and left.schema != suggestion.schema: continue c = self.case if self.generate_aliases or normalize_ref(left.tbl) in refs: lref = self.alias(left.tbl, suggestion.table_refs) join = '{0} {4} ON {4}.{1} = {2}.{3}'.format( c(left.tbl), c(left.col), rtbl.ref, c(right.col), lref) else: join = '{0} ON {0}.{1} = {2}.{3}'.format( c(left.tbl), c(left.col), rtbl.ref, c(right.col)) alias = generate_alias(self.case(left.tbl)) synonyms = [ join, '{0} ON {0}.{1} = {2}.{3}'.format(alias, c(left.col), rtbl.ref, c(right.col)) ] # Schema-qualify if (1) new table in same schema as old, and old # is schema-qualified, or (2) new in other schema, except public if not suggestion.schema and (qualified[normalize_ref( rtbl.ref)] and left.schema == right.schema or left.schema not in (right.schema, 'default')): join = left.schema + '.' + join prio = ref_prio[normalize_ref(rtbl.ref)] * 2 + (0 if ( left.schema, left.tbl) in other_tbls else 1) joins.append(Candidate(join, prio, 'join', synonyms=synonyms)) return self.find_matches(word_before_cursor, joins, meta='join')
def make_cand(name, ref): synonyms = (name, generate_alias(self.case(name))) return Candidate(qualify(name, ref), 0, 'column', synonyms)