diff options
author | Amjith Ramanujam <amjith.r@gmail.com> | 2017-08-06 21:16:08 -0600 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-08-06 21:16:08 -0600 |
commit | 887a8264150ee813242a0861cce2cddc787fd237 (patch) | |
tree | fa4149fad8a380407619d556123e62fe010742c1 | |
parent | 4dc68b846ba18715fd9894efe50f78248188e746 (diff) | |
parent | 99c9040c3dad802fd0825dc10a6b09b0e3beb017 (diff) |
Merge branch 'master' into koljonen/array_formatting
-rw-r--r-- | changelog.rst | 3 | ||||
-rw-r--r-- | pgcli/packages/pgliterals/pgliterals.json | 103 | ||||
-rw-r--r-- | pgcli/packages/sqlcompletion.py | 4 | ||||
-rw-r--r-- | pgcli/pgcompleter.py | 10 | ||||
-rw-r--r-- | tests/metadata.py | 2 | ||||
-rw-r--r-- | tests/test_pgspecial.py | 4 | ||||
-rw-r--r-- | tests/test_smart_completion_multiple_schemata.py | 8 | ||||
-rw-r--r-- | tests/test_smart_completion_public_schema_only.py | 16 |
8 files changed, 134 insertions, 16 deletions
diff --git a/changelog.rst b/changelog.rst index b3c795c5..98050104 100644 --- a/changelog.rst +++ b/changelog.rst @@ -6,12 +6,15 @@ Features: * Add fish-style auto-suggestion from history. (Thanks: `Amjith Ramanujam`_) * Improved formatting of arrays in output (Thanks: `Joakim Koljonen`_) +* Don't quote identifiers that are non-reserved keywords. (Thanks: `Joakim Koljonen`_) * Remove the ``...`` in the continuation prompt and use empty space instead. (Thanks: `Amjith Ramanujam`_) Bug Fixes: ---------- * Fix the way we get host when using DSN (issue #765) (Thanks: `François Pietka`_) +* Add missing keyword COLUMN after DROP (issue #769) (Thanks: `François Pietka`_) +* Don't include arguments in function suggestions for backslash commands (Thanks: `Joakim Koljonen`_) 1.7.0 ===== diff --git a/pgcli/packages/pgliterals/pgliterals.json b/pgcli/packages/pgliterals/pgliterals.json index 4b70f86b..4a699fe9 100644 --- a/pgcli/packages/pgliterals/pgliterals.json +++ b/pgcli/packages/pgliterals/pgliterals.json @@ -110,6 +110,7 @@ "AGGREGATE", "CAST", "COLLATION", + "COLUMN", "CONVERSION", "DATABASE", "DOMAIN", @@ -288,5 +289,107 @@ "TEXT", "VARCHAR", "VOID" + ], + "reserved": [ + "ALL", + "ANALYSE", + "ANALYZE", + "AND", + "ANY", + "ARRAY", + "AS", + "ASC", + "ASYMMETRIC", + "BOTH", + "CASE", + "CAST", + "CHECK", + "COLLATE", + "COLUMN", + "CONSTRAINT", + "CREATE", + "CURRENT_CATALOG", + "CURRENT_DATE", + "CURRENT_ROLE", + "CURRENT_TIME", + "CURRENT_TIMESTAMP", + "CURRENT_USER", + "DEFAULT", + "DEFERRABLE", + "DESC", + "DISTINCT", + "DO", + "ELSE", + "END", + "EXCEPT", + "FALSE", + "FETCH", + "FOR", + "FOREIGN", + "FROM", + "GRANT", + "GROUP", + "HAVING", + "IN", + "INITIALLY", + "INTERSECT", + "INTO", + "LATERAL", + "LEADING", + "LIMIT", + "LOCALTIME", + "LOCALTIMESTAMP", + "NOT", + "NULL", + "OFFSET", + "ON", + "ONLY", + "OR", + "ORDER", + "PLACING", + "PRIMARY", + "REFERENCES", + "RETURNING", + "SELECT", + "SESSION_USER", + "SOME", + "SYMMETRIC", + "TABLE", + "THEN", + "TO", + "TRAILING", + "TRUE", + "UNION", + "UNIQUE", + "USER", + "USING", + "VARIADIC", + "WHEN", + "WHERE", + "WINDOW", + "WITH", + "AUTHORIZATION", + "BINARY", + "COLLATION", + "CONCURRENTLY", + "CROSS", + "CURRENT_SCHEMA", + "FREEZE", + "FULL", + "ILIKE", + "INNER", + "IS", + "ISNULL", + "JOIN", + "LEFT", + "LIKE", + "NATURAL", + "NOTNULL", + "OUTER", + "OVERLAPS", + "RIGHT", + "SIMILAR", + "TABLESAMPLE", + "VERBOSE" ] } diff --git a/pgcli/packages/sqlcompletion.py b/pgcli/packages/sqlcompletion.py index bb3a3680..f92a8a71 100644 --- a/pgcli/packages/sqlcompletion.py +++ b/pgcli/packages/sqlcompletion.py @@ -279,8 +279,12 @@ def suggest_special(text): elif cmd[1:] in SPECIALS_SUGGESTION: rel_type = SPECIALS_SUGGESTION[cmd[1:]] if schema: + if rel_type == Function: + return (Function(schema=schema, usage='special'),) return (rel_type(schema=schema),) else: + if rel_type == Function: + return (Schema(), Function(schema=None, usage='special'),) return (Schema(), rel_type(schema=None)) if cmd in ['\\n', '\\ns', '\\nd']: diff --git a/pgcli/pgcompleter.py b/pgcli/pgcompleter.py index 8613d6f9..5378f43c 100644 --- a/pgcli/pgcompleter.py +++ b/pgcli/pgcompleter.py @@ -74,6 +74,7 @@ class PGCompleter(Completer): keywords = tuple(set(chain(keywords_tree.keys(), *keywords_tree.values()))) functions = get_literals('functions') datatypes = get_literals('datatypes') + reserved_words = set(get_literals('reserved')) def __init__(self, smart_completion=True, pgspecial=None, settings=None): super(PGCompleter, self).__init__() @@ -110,10 +111,6 @@ class PGCompleter(Completer): if keyword_casing not in ('upper', 'lower', 'auto'): keyword_casing = 'upper' self.keyword_casing = keyword_casing - - self.reserved_words = set() - for x in self.keywords: - self.reserved_words.update(x.split()) self.name_pattern = re.compile(r"^[_a-z][_a-z0-9\$]*$") self.databases = [] @@ -653,7 +650,10 @@ class PGCompleter(Completer): alias = False def filt(f): return True - arg_mode = 'signature' if suggestion.usage == 'signature' else 'call' + arg_mode = { + 'signature': 'signature', + 'special': None, + }.get(suggestion.usage, 'call') # Function overloading means we way have multiple functions of the same # name at this point, so keep unique names only funcs = set( diff --git a/tests/metadata.py b/tests/metadata.py index 91832162..9aa95953 100644 --- a/tests/metadata.py +++ b/tests/metadata.py @@ -13,7 +13,7 @@ no_qual = ['if_more_than_one_table', 'never'] def escape(name): - if not name.islower() or name in ('select', 'insert'): + if not name.islower() or name in ('select', 'localtimestamp'): return '"' + name + '"' return name diff --git a/tests/test_pgspecial.py b/tests/test_pgspecial.py index 1802d1d4..b08fa029 100644 --- a/tests/test_pgspecial.py +++ b/tests/test_pgspecial.py @@ -56,12 +56,12 @@ def test_d_dot_suggests_schema_qualified_tables_or_views(): def test_df_suggests_schema_or_function(): suggestions = suggest_type('\\df xxx', '\\df xxx') assert set(suggestions) == set([ - Function(schema=None), + Function(schema=None, usage='special'), Schema(), ]) suggestions = suggest_type('\\df myschema.xxx', '\\df myschema.xxx') - assert suggestions == (Function(schema='myschema'),) + assert suggestions == (Function(schema='myschema', usage='special'),) def test_leading_whitespace_ok(): diff --git a/tests/test_smart_completion_multiple_schemata.py b/tests/test_smart_completion_multiple_schemata.py index dba95ad2..5935af99 100644 --- a/tests/test_smart_completion_multiple_schemata.py +++ b/tests/test_smart_completion_multiple_schemata.py @@ -9,7 +9,7 @@ metadata = { 'public': { 'users': ['id', 'email', 'first_name', 'last_name'], 'orders': ['id', 'ordered_date', 'status', 'datestamp'], - 'select': ['id', 'insert', 'ABC'] + 'select': ['id', 'localtime', 'ABC'] }, 'custom': { 'users': ['id', 'phone_number'], @@ -364,7 +364,7 @@ def test_wildcard_column_expansion_with_table_qualifier(completer): completions = get_result(completer, text, position) - col_list = 'id, "select"."insert", "select"."ABC"' + col_list = 'id, "select"."localtime", "select"."ABC"' expected = [wildcard_expansion(col_list)] assert expected == completions @@ -377,7 +377,7 @@ def test_wildcard_column_expansion_with_two_tables(completer): completions = get_result(completer, text, position) - cols = ('"select".id, "select"."insert", "select"."ABC", ' + cols = ('"select".id, "select"."localtime", "select"."ABC", ' 'users.id, users.phone_number') expected = [wildcard_expansion(cols)] assert completions == expected @@ -390,7 +390,7 @@ def test_wildcard_column_expansion_with_two_tables_and_parent(completer): completions = get_result(completer, text, position) - col_list = 'id, "select"."insert", "select"."ABC"' + col_list = 'id, "select"."localtime", "select"."ABC"' expected = [wildcard_expansion(col_list)] assert expected == completions diff --git a/tests/test_smart_completion_public_schema_only.py b/tests/test_smart_completion_public_schema_only.py index a8130b1b..0e676065 100644 --- a/tests/test_smart_completion_public_schema_only.py +++ b/tests/test_smart_completion_public_schema_only.py @@ -35,13 +35,13 @@ testdata = MetaData(metadata) cased_users_col_names = ['ID', 'PARENTID', 'Email', 'First_Name', 'last_name'] cased_users2_col_names = ['UserID', 'UserName'] -cased_funcs = [ +cased_func_names = [ 'Custom_Fun', '_custom_fun', 'Custom_Func1', 'custom_func2', 'set_returning_func' ] cased_tbls = ['Users', 'Orders'] cased_views = ['User_Emails', 'Functions'] casing = ( - ['SELECT', 'PUBLIC'] + cased_funcs + cased_tbls + cased_views + ['SELECT', 'PUBLIC'] + cased_func_names + cased_tbls + cased_views + cased_users_col_names + cased_users2_col_names ) # Lists for use in assertions @@ -147,6 +147,14 @@ def test_user_function_name_completion_matches_anywhere(completer): function('custom_func2()', -2)]) +@parametrize('completer', completers(casing=True)) +def test_list_functions_for_special(completer): + result = result_set(completer, r'\df ') + assert result == set( + [schema('PUBLIC')] + [function(f) for f in cased_func_names] + ) + + @parametrize('completer', completers(casing=False, qualify=no_qual)) def test_suggested_column_names_from_visible_table(completer): result = result_set(completer, 'SELECT from users', len('SELECT ')) @@ -724,7 +732,7 @@ def test_wildcard_column_expansion_with_two_tables(completer): completions = get_result(completer, text, position) - cols = ('"select".id, "select"."insert", "select"."ABC", ' + cols = ('"select".id, "select".insert, "select"."ABC", ' 'u.id, u.parentid, u.email, u.first_name, u.last_name') expected = [wildcard_expansion(cols)] assert completions == expected @@ -737,7 +745,7 @@ def test_wildcard_column_expansion_with_two_tables_and_parent(completer): completions = get_result(completer, text, position) - col_list = 'id, "select"."insert", "select"."ABC"' + col_list = 'id, "select".insert, "select"."ABC"' expected = [wildcard_expansion(col_list)] assert expected == completions |