summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAmjith Ramanujam <amjith.r@gmail.com>2017-08-06 21:16:08 -0600
committerGitHub <noreply@github.com>2017-08-06 21:16:08 -0600
commit887a8264150ee813242a0861cce2cddc787fd237 (patch)
treefa4149fad8a380407619d556123e62fe010742c1
parent4dc68b846ba18715fd9894efe50f78248188e746 (diff)
parent99c9040c3dad802fd0825dc10a6b09b0e3beb017 (diff)
Merge branch 'master' into koljonen/array_formatting
-rw-r--r--changelog.rst3
-rw-r--r--pgcli/packages/pgliterals/pgliterals.json103
-rw-r--r--pgcli/packages/sqlcompletion.py4
-rw-r--r--pgcli/pgcompleter.py10
-rw-r--r--tests/metadata.py2
-rw-r--r--tests/test_pgspecial.py4
-rw-r--r--tests/test_smart_completion_multiple_schemata.py8
-rw-r--r--tests/test_smart_completion_public_schema_only.py16
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