summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--pgcli/packages/parseutils.py33
-rw-r--r--tests/test_smart_completion_multiple_schemata.py31
-rw-r--r--tests/test_smart_completion_public_schema_only.py31
3 files changed, 86 insertions, 9 deletions
diff --git a/pgcli/packages/parseutils.py b/pgcli/packages/parseutils.py
index fd78eec3..d099c02f 100644
--- a/pgcli/packages/parseutils.py
+++ b/pgcli/packages/parseutils.py
@@ -125,6 +125,28 @@ def extract_from_part(parsed, stop_at_punctuation=True):
def extract_table_identifiers(token_stream, allow_functions=True):
"""yields tuples of TableReference namedtuples"""
+ # We need to do some massaging of the names because postgres is case-
+ # insensitive and '"Foo"' is not the same table as 'Foo' (while 'foo' is)
+ def getnames(item):
+ name = item.get_real_name()
+ schema_name = item.get_parent_name()
+ alias = item.get_alias()
+ if not name:
+ schema_name = None
+ name = item.get_name()
+ alias = alias or name
+ schemaisquoted = schema_name and item.value[0] == '"'
+ if schema_name and not schemaisquoted:
+ schema_name = schema_name.lower()
+ quotecount = item.value.count('"')
+ nameisquoted = quotecount > 2 or (quotecount and not schemaisquoted)
+ if name and not nameisquoted and name != name.lower():
+ if not alias:
+ alias = name
+ name = name.lower()
+ return schema_name, name, alias
+
+
for item in token_stream:
if isinstance(item, IdentifierList):
for identifier in item.get_identifiers():
@@ -141,17 +163,10 @@ def extract_table_identifiers(token_stream, allow_functions=True):
yield TableReference(schema_name, real_name,
identifier.get_alias(), is_function)
elif isinstance(item, Identifier):
- real_name = item.get_real_name()
- schema_name = item.get_parent_name()
+ schema_name, real_name, alias = getnames(item)
is_function = allow_functions and _identifier_is_function(item)
- if real_name:
- yield TableReference(schema_name, real_name, item.get_alias(),
- is_function)
- else:
- name = item.get_name()
- yield TableReference(None, name, item.get_alias() or name,
- is_function)
+ yield TableReference(schema_name, real_name, alias, is_function)
elif isinstance(item, Function):
yield TableReference(None, item.get_real_name(), item.get_alias(),
allow_functions)
diff --git a/tests/test_smart_completion_multiple_schemata.py b/tests/test_smart_completion_multiple_schemata.py
index fbe79ac0..a7eb7834 100644
--- a/tests/test_smart_completion_multiple_schemata.py
+++ b/tests/test_smart_completion_multiple_schemata.py
@@ -13,6 +13,7 @@ metadata = {
},
'custom': {
'users': ['id', 'phone_number'],
+ 'Users': ['userid', 'username'],
'products': ['id', 'product_name', 'price'],
'shipments': ['id', 'address', 'user_id']
}},
@@ -185,6 +186,7 @@ def test_suggested_table_names_with_schema_dot(completer, complete_event,
assert set(result) == set([
Completion(text='func3', start_position=start_pos, display_meta='function'),
Completion(text='users', start_position=start_pos, display_meta='table'),
+ Completion(text='"Users"', start_position=start_pos, display_meta='table'),
Completion(text='products', start_position=start_pos, display_meta='table'),
Completion(text='shipments', start_position=start_pos, display_meta='table'),
Completion(text='set_returning_func', start_position=start_pos, display_meta='function'),
@@ -309,6 +311,7 @@ def test_schema_qualified_type_name(text, completer, complete_event):
Completion(text='typ3', display_meta='datatype'),
Completion(text='typ4', display_meta='datatype'),
Completion(text='users', display_meta='table'),
+ Completion(text='"Users"', display_meta='table'),
Completion(text='products', display_meta='table'),
Completion(text='shipments', display_meta='table'),
])
@@ -390,3 +393,31 @@ def test_wildcard_column_expansion_with_two_tables_and_parent(completer, complet
display='*', display_meta='columns')]
assert expected == completions
+
+@pytest.mark.parametrize('text', [
+ 'SELECT U. FROM custom.Users U',
+ 'SELECT U. FROM custom.USERS U',
+ 'SELECT U. FROM custom.users U',
+ 'SELECT U. FROM "custom".Users U',
+ 'SELECT U. FROM "custom".USERS U',
+ 'SELECT U. FROM "custom".users U'
+])
+def test_suggest_columns_from_unquoted_table(completer, complete_event, text):
+ pos = len('SELECT U.')
+ result = completer.get_completions(Document(text=text, cursor_position=pos),
+ complete_event)
+ assert set(result) == set([
+ Completion(text='id', start_position=0, display_meta='column'),
+ Completion(text='phone_number', start_position=0, display_meta='column')])
+
+@pytest.mark.parametrize('text', [
+ 'SELECT U. FROM custom."Users" U',
+ 'SELECT U. FROM "custom"."Users" U'
+])
+def test_suggest_columns_from_quoted_table(completer, complete_event, text):
+ pos = len('SELECT U.')
+ result = completer.get_completions(Document(text=text, cursor_position=pos),
+ complete_event)
+ assert set(result) == set([
+ Completion(text='userid', start_position=0, display_meta='column'),
+ Completion(text='username', start_position=0, display_meta='column')])
diff --git a/tests/test_smart_completion_public_schema_only.py b/tests/test_smart_completion_public_schema_only.py
index cbd0d96b..4dd1127c 100644
--- a/tests/test_smart_completion_public_schema_only.py
+++ b/tests/test_smart_completion_public_schema_only.py
@@ -7,6 +7,7 @@ from pgcli.packages.function_metadata import FunctionMetadata
metadata = {
'tables': {
'users': ['id', 'email', 'first_name', 'last_name'],
+ 'Users': ['userid', 'username'],
'orders': ['id', 'ordered_date', 'status', 'email'],
'select': ['id', 'insert', 'ABC']},
'views': {
@@ -92,6 +93,7 @@ def test_schema_or_visible_table_completion(completer, complete_event):
assert set(result) == set([
Completion(text='public', start_position=0, display_meta='schema'),
Completion(text='users', start_position=0, display_meta='table'),
+ Completion(text='"Users"', start_position=0, display_meta='table'),
Completion(text='"select"', start_position=0, display_meta='table'),
Completion(text='orders', start_position=0, display_meta='table'),
Completion(text='user_emails', start_position=0, display_meta='view'),
@@ -374,6 +376,7 @@ def test_table_names_after_from(completer, complete_event):
assert set(result) == set([
Completion(text='public', start_position=0, display_meta='schema'),
Completion(text='users', start_position=0, display_meta='table'),
+ Completion(text='"Users"', start_position=0, display_meta='table'),
Completion(text='orders', start_position=0, display_meta='table'),
Completion(text='"select"', start_position=0, display_meta='table'),
Completion(text='user_emails', start_position=0, display_meta='view'),
@@ -389,6 +392,7 @@ def test_table_names_after_from_are_lexical_ordered_by_text(completer, complete_
Document(text=text, cursor_position=position),
complete_event)
assert [c.text for c in result] == [
+ '"Users"',
'custom_func1',
'custom_func2',
'orders',
@@ -443,6 +447,7 @@ def test_suggest_datatype(text, completer, complete_event):
Completion(text='custom_type2', start_position=0, display_meta='datatype'),
Completion(text='public', start_position=0, display_meta='schema'),
Completion(text='users', start_position=0, display_meta='table'),
+ Completion(text='"Users"', start_position=0, display_meta='table'),
Completion(text='orders', start_position=0, display_meta='table'),
Completion(text='"select"', start_position=0, display_meta='table')] +
list(map(lambda f: Completion(f, display_meta='datatype'), completer.datatypes)))
@@ -612,3 +617,29 @@ def test_wildcard_column_expansion_with_two_tables_and_parent(completer, complet
display='*', display_meta='columns')]
assert expected == completions
+
+
+@pytest.mark.parametrize('text', [
+ 'SELECT U. FROM Users U',
+ 'SELECT U. FROM USERS U',
+ 'SELECT U. FROM users U'
+])
+def test_suggest_columns_from_unquoted_table(completer, complete_event, text):
+ pos = len('SELECT U.')
+ result = completer.get_completions(Document(text=text, cursor_position=pos),
+ complete_event)
+ assert set(result) == set([
+ Completion(text='id', start_position=0, display_meta='column'),
+ Completion(text='email', start_position=0, display_meta='column'),
+ Completion(text='first_name', start_position=0, display_meta='column'),
+ Completion(text='last_name', start_position=0, display_meta='column')])
+
+
+def test_suggest_columns_from_quoted_table(completer, complete_event):
+ text = 'SELECT U. FROM "Users" U'
+ pos = len('SELECT U.')
+ result = completer.get_completions(Document(text=text, cursor_position=pos),
+ complete_event)
+ assert set(result) == set([
+ Completion(text='userid', start_position=0, display_meta='column'),
+ Completion(text='username', start_position=0, display_meta='column')])