Skip to content

Commit 4f214f6

Browse files
authored
Bugfix alias_map_file not being used for table aliases (#1492)
* Add failing test for using configured alias map The test demonstrates a bug in the PGCompleter class where a configured alias map file is not used to generate aliases. * Use configured alias map in PGCompleter Fixes a bug where this configuration was ignored. * Update generate_alias docstring Clarify the behaviour of generate_alias when an alias_map argument is passed. * Add "no match in map" test case for generate_alias Test demonstrates passing an alias_map to generate_alias does not break generation of aliases for tables not covered within the map file. * Update AUTHORS file Credit where credit is due ;)
1 parent 16333ac commit 4f214f6

File tree

4 files changed

+41
-8
lines changed

4 files changed

+41
-8
lines changed

AUTHORS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ Contributors:
137137
* Chris Rose (offbyone/offby1)
138138
* Mathieu Dupuy (deronnax)
139139
* Chris Novakovic
140+
* Josh Lynch (josh-lynch)
140141

141142
Creator:
142143
--------

changelog.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ Features
99
Bug fixes:
1010
----------
1111
* Avoid raising `NameError` when exiting unsuccessfully in some cases
12+
* Use configured `alias_map_file` to generate table aliases if available.
1213

1314
Internal:
1415
---------

pgcli/pgcompleter.py

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,17 @@ def Candidate(
6363

6464

6565
def generate_alias(tbl, alias_map=None):
66-
"""Generate a table alias, consisting of all upper-case letters in
67-
the table name, or, if there are no upper-case letters, the first letter +
68-
all letters preceded by _
69-
param tbl - unescaped name of the table to alias
66+
"""Generate a table alias.
67+
68+
Given a table name will return an alias for that table using the first of
69+
the following options there's a match for.
70+
71+
1. The predefined alias for table defined in the alias_map.
72+
2. All upper-case letters in the table name.
73+
3. The first letter of the table name and all letters preceded by _
74+
75+
:param tbl: unescaped name of the table to alias
76+
:param alias_map: optional mapping of predefined table aliases
7077
"""
7178
if alias_map and tbl in alias_map:
7279
return alias_map[tbl]
@@ -528,7 +535,7 @@ def get_column_matches(self, suggestion, word_before_cursor):
528535
scoped_cols = self.populate_scoped_cols(tables, suggestion.local_tables)
529536

530537
def make_cand(name, ref):
531-
synonyms = (name, generate_alias(self.case(name)))
538+
synonyms = (name, generate_alias(self.case(name), alias_map=self.alias_map))
532539
return Candidate(qualify(name, ref), 0, "column", synonyms)
533540

534541
def flat_cols():
@@ -601,7 +608,7 @@ def alias(self, tbl, tbls):
601608
tbl = self.case(tbl)
602609
tbls = {normalize_ref(t.ref) for t in tbls}
603610
if self.generate_aliases:
604-
tbl = generate_alias(self.unescape_name(tbl))
611+
tbl = generate_alias(self.unescape_name(tbl), alias_map=self.alias_map)
605612
if normalize_ref(tbl) not in tbls:
606613
return tbl
607614
elif tbl[0] == '"':
@@ -644,7 +651,7 @@ def get_join_matches(self, suggestion, word_before_cursor):
644651
join = "{0} ON {0}.{1} = {2}.{3}".format(
645652
c(left.tbl), c(left.col), rtbl.ref, c(right.col)
646653
)
647-
alias = generate_alias(self.case(left.tbl))
654+
alias = generate_alias(self.case(left.tbl), alias_map=self.alias_map)
648655
synonyms = [
649656
join,
650657
"{0} ON {0}.{1} = {2}.{3}".format(
@@ -845,7 +852,7 @@ def _make_cand(self, tbl, do_alias, suggestion, arg_mode=None):
845852
cased_tbl = self.case(tbl.name)
846853
if do_alias:
847854
alias = self.alias(cased_tbl, suggestion.table_refs)
848-
synonyms = (cased_tbl, generate_alias(cased_tbl))
855+
synonyms = (cased_tbl, generate_alias(cased_tbl, alias_map=self.alias_map))
849856
maybe_alias = (" " + alias) if do_alias else ""
850857
maybe_schema = (self.case(tbl.schema) + ".") if tbl.schema else ""
851858
suffix = self._arg_list_cache[arg_mode][tbl.meta] if arg_mode else ""

tests/test_pgcompleter.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
import json
12
import pytest
23
from pgcli import pgcompleter
4+
import tempfile
35

46

57
def test_load_alias_map_file_missing_file():
@@ -47,12 +49,34 @@ def test_generate_alias_uses_first_char_and_every_preceded_by_underscore(
4749
"table_name, alias_map, alias",
4850
[
4951
("some_table", {"some_table": "my_alias"}, "my_alias"),
52+
pytest.param(
53+
"some_other_table", {"some_table": "my_alias"}, "sot", id="no_match_in_map"
54+
),
5055
],
5156
)
5257
def test_generate_alias_can_use_alias_map(table_name, alias_map, alias):
5358
assert pgcompleter.generate_alias(table_name, alias_map) == alias
5459

5560

61+
@pytest.mark.parametrize(
62+
"table_name, alias_map, alias",
63+
[
64+
("some_table", {"some_table": "my_alias"}, "my_alias"),
65+
],
66+
)
67+
def test_pgcompleter_alias_uses_configured_alias_map(table_name, alias_map, alias):
68+
with tempfile.NamedTemporaryFile(mode="w", suffix=".json") as alias_map_file:
69+
alias_map_file.write(json.dumps(alias_map))
70+
alias_map_file.seek(0)
71+
completer = pgcompleter.PGCompleter(
72+
settings={
73+
"generate_aliases": True,
74+
"alias_map_file": alias_map_file.name,
75+
}
76+
)
77+
assert completer.alias(table_name, []) == alias
78+
79+
5680
@pytest.mark.parametrize(
5781
"table_name, alias_map, alias",
5882
[

0 commit comments

Comments
 (0)