From 6fa307f3f263d74de4aed7983ba3b1c3c5be88f1 Mon Sep 17 00:00:00 2001 From: josh-lynch Date: Tue, 25 Feb 2025 15:32:29 +0100 Subject: [PATCH 1/5] 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. --- tests/test_pgcompleter.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/tests/test_pgcompleter.py b/tests/test_pgcompleter.py index 909fa0b7e..aff21abf5 100644 --- a/tests/test_pgcompleter.py +++ b/tests/test_pgcompleter.py @@ -1,5 +1,7 @@ +import json import pytest from pgcli import pgcompleter +import tempfile def test_load_alias_map_file_missing_file(): @@ -53,6 +55,26 @@ def test_generate_alias_can_use_alias_map(table_name, alias_map, alias): assert pgcompleter.generate_alias(table_name, alias_map) == alias +@pytest.mark.xfail +@pytest.mark.parametrize( + "table_name, alias_map, alias", + [ + ("some_table", {"some_table": "my_alias"}, "my_alias"), + ], +) +def test_pgcompleter_alias_uses_configured_alias_map(table_name, alias_map, alias): + with tempfile.NamedTemporaryFile(mode="w", suffix=".json") as alias_map_file: + alias_map_file.write(json.dumps(alias_map)) + alias_map_file.seek(0) + completer = pgcompleter.PGCompleter( + settings={ + "generate_aliases": True, + "alias_map_file": alias_map_file.name, + } + ) + assert completer.alias(table_name, []) == alias + + @pytest.mark.parametrize( "table_name, alias_map, alias", [ From 0f93378523987a53a321f85b6331b545ef50fc9c Mon Sep 17 00:00:00 2001 From: josh-lynch Date: Tue, 25 Feb 2025 15:35:18 +0100 Subject: [PATCH 2/5] Use configured alias map in PGCompleter Fixes a bug where this configuration was ignored. --- changelog.rst | 1 + pgcli/pgcompleter.py | 8 ++++---- tests/test_pgcompleter.py | 1 - 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/changelog.rst b/changelog.rst index ce991a390..62c1faeaa 100644 --- a/changelog.rst +++ b/changelog.rst @@ -9,6 +9,7 @@ Features Bug fixes: ---------- * Avoid raising `NameError` when exiting unsuccessfully in some cases +* Use configured `alias_map_file` to generate table aliases if available. Internal: --------- diff --git a/pgcli/pgcompleter.py b/pgcli/pgcompleter.py index 17fc54055..51c34e864 100644 --- a/pgcli/pgcompleter.py +++ b/pgcli/pgcompleter.py @@ -528,7 +528,7 @@ def get_column_matches(self, suggestion, word_before_cursor): scoped_cols = self.populate_scoped_cols(tables, suggestion.local_tables) def make_cand(name, ref): - synonyms = (name, generate_alias(self.case(name))) + synonyms = (name, generate_alias(self.case(name), alias_map=self.alias_map)) return Candidate(qualify(name, ref), 0, "column", synonyms) def flat_cols(): @@ -601,7 +601,7 @@ def alias(self, tbl, tbls): tbl = self.case(tbl) tbls = {normalize_ref(t.ref) for t in tbls} if self.generate_aliases: - tbl = generate_alias(self.unescape_name(tbl)) + tbl = generate_alias(self.unescape_name(tbl), alias_map=self.alias_map) if normalize_ref(tbl) not in tbls: return tbl elif tbl[0] == '"': @@ -644,7 +644,7 @@ def get_join_matches(self, suggestion, word_before_cursor): 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)) + alias = generate_alias(self.case(left.tbl), alias_map=self.alias_map) synonyms = [ join, "{0} ON {0}.{1} = {2}.{3}".format( @@ -845,7 +845,7 @@ def _make_cand(self, tbl, do_alias, suggestion, arg_mode=None): cased_tbl = self.case(tbl.name) if do_alias: alias = self.alias(cased_tbl, suggestion.table_refs) - synonyms = (cased_tbl, generate_alias(cased_tbl)) + synonyms = (cased_tbl, generate_alias(cased_tbl, alias_map=self.alias_map)) maybe_alias = (" " + alias) if do_alias else "" maybe_schema = (self.case(tbl.schema) + ".") if tbl.schema else "" suffix = self._arg_list_cache[arg_mode][tbl.meta] if arg_mode else "" diff --git a/tests/test_pgcompleter.py b/tests/test_pgcompleter.py index aff21abf5..d39ed5f19 100644 --- a/tests/test_pgcompleter.py +++ b/tests/test_pgcompleter.py @@ -55,7 +55,6 @@ def test_generate_alias_can_use_alias_map(table_name, alias_map, alias): assert pgcompleter.generate_alias(table_name, alias_map) == alias -@pytest.mark.xfail @pytest.mark.parametrize( "table_name, alias_map, alias", [ From 91f5dd0a7ea14a03d78f24a4eda520d8adb7223e Mon Sep 17 00:00:00 2001 From: josh-lynch Date: Tue, 25 Feb 2025 15:17:00 +0100 Subject: [PATCH 3/5] Update generate_alias docstring Clarify the behaviour of generate_alias when an alias_map argument is passed. --- pgcli/pgcompleter.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/pgcli/pgcompleter.py b/pgcli/pgcompleter.py index 51c34e864..8df2958e0 100644 --- a/pgcli/pgcompleter.py +++ b/pgcli/pgcompleter.py @@ -63,10 +63,17 @@ def Candidate( def generate_alias(tbl, alias_map=None): - """Generate a table alias, consisting of all upper-case letters in - the table name, or, if there are no upper-case letters, the first letter + - all letters preceded by _ - param tbl - unescaped name of the table to alias + """Generate a table alias. + + Given a table name will return an alias for that table using the first of + the following options there's a match for. + + 1. The predefined alias for table defined in the alias_map. + 2. All upper-case letters in the table name. + 3. The first letter of the table name and all letters preceded by _ + + :param tbl: unescaped name of the table to alias + :param alias_map: optional mapping of predefined table aliases """ if alias_map and tbl in alias_map: return alias_map[tbl] From 922865e6f64aa34a05f029cb51f4267ddf7ab930 Mon Sep 17 00:00:00 2001 From: josh-lynch Date: Tue, 25 Feb 2025 15:39:33 +0100 Subject: [PATCH 4/5] 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. --- tests/test_pgcompleter.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/test_pgcompleter.py b/tests/test_pgcompleter.py index d39ed5f19..4b2d9d0dc 100644 --- a/tests/test_pgcompleter.py +++ b/tests/test_pgcompleter.py @@ -49,6 +49,9 @@ def test_generate_alias_uses_first_char_and_every_preceded_by_underscore( "table_name, alias_map, alias", [ ("some_table", {"some_table": "my_alias"}, "my_alias"), + pytest.param( + "some_other_table", {"some_table": "my_alias"}, "sot", id="no_match_in_map" + ), ], ) def test_generate_alias_can_use_alias_map(table_name, alias_map, alias): From 37f56e3305e57659c50a5f9c6009303a729632c6 Mon Sep 17 00:00:00 2001 From: josh-lynch Date: Tue, 25 Feb 2025 15:56:52 +0100 Subject: [PATCH 5/5] Update AUTHORS file Credit where credit is due ;) --- AUTHORS | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS b/AUTHORS index ca943548e..4bbaba26c 100644 --- a/AUTHORS +++ b/AUTHORS @@ -137,6 +137,7 @@ Contributors: * Chris Rose (offbyone/offby1) * Mathieu Dupuy (deronnax) * Chris Novakovic + * Josh Lynch (josh-lynch) Creator: --------