summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIrina Truong <i.chernyavska@gmail.com>2019-01-02 16:15:59 -0800
committerGitHub <noreply@github.com>2019-01-02 16:15:59 -0800
commit0cae7e20361dbee41fb8f79d7ee9c763d17d51e1 (patch)
tree2f5c4054233777bc420d2b9f24dc769f1377ac10
parent2a1de91292e1996f0fff0407ca147c5894be8042 (diff)
Remove some functions completions (#982)
Remove extension and private functions from completer.
-rw-r--r--changelog.rst1
-rw-r--r--pgcli/packages/parseutils/meta.py16
-rw-r--r--pgcli/pgcompleter.py18
-rw-r--r--pgcli/pgexecute.py16
-rw-r--r--tests/parseutils/test_function_metadata.py9
-rw-r--r--tests/test_pgexecute.py4
-rw-r--r--tests/test_smart_completion_multiple_schemata.py20
-rw-r--r--tests/test_smart_completion_public_schema_only.py10
8 files changed, 60 insertions, 34 deletions
diff --git a/changelog.rst b/changelog.rst
index 67256658..a34c95bd 100644
--- a/changelog.rst
+++ b/changelog.rst
@@ -5,6 +5,7 @@ Features:
---------
* Allows passing the ``-u`` flag to specify a username. (Thanks: `Ignacio Campabadal`_)
+* Fix for lag in v2 (#979). (Thanks: `Irina Truong`_)
Internal:
---------
diff --git a/pgcli/packages/parseutils/meta.py b/pgcli/packages/parseutils/meta.py
index 16a49676..32dd0aff 100644
--- a/pgcli/packages/parseutils/meta.py
+++ b/pgcli/packages/parseutils/meta.py
@@ -51,7 +51,8 @@ class FunctionMetadata(object):
def __init__(
self, schema_name, func_name, arg_names, arg_types, arg_modes,
- return_type, is_aggregate, is_window, is_set_returning, arg_defaults
+ return_type, is_aggregate, is_window, is_set_returning, is_extension,
+ arg_defaults
):
"""Class for describing a postgresql function"""
@@ -79,6 +80,8 @@ class FunctionMetadata(object):
self.is_aggregate = is_aggregate
self.is_window = is_window
self.is_set_returning = is_set_returning
+ self.is_extension = bool(is_extension)
+ self.is_public = (self.schema_name and self.schema_name == 'public')
def __eq__(self, other):
return (isinstance(other, self.__class__)
@@ -89,9 +92,9 @@ class FunctionMetadata(object):
def _signature(self):
return (
- self.schema_name, self.func_name, self.arg_names, self.arg_types,
- self.arg_modes, self.return_type, self.is_aggregate,
- self.is_window, self.is_set_returning, self.arg_defaults
+ self.schema_name, self.func_name, self.arg_names,
+ self.arg_types, self.arg_modes, self.return_type, self.is_aggregate,
+ self.is_window, self.is_set_returning, self.is_extension, self.arg_defaults
)
def __hash__(self):
@@ -102,8 +105,8 @@ class FunctionMetadata(object):
(
'%s(schema_name=%r, func_name=%r, arg_names=%r, '
'arg_types=%r, arg_modes=%r, return_type=%r, is_aggregate=%r, '
- 'is_window=%r, is_set_returning=%r, arg_defaults=%r)'
- ) % (self.__class__.__name__,) + self._signature()
+ 'is_window=%r, is_set_returning=%r, is_extension=%r, arg_defaults=%r)'
+ ) % ((self.__class__.__name__,) + self._signature())
)
def has_variadic(self):
@@ -132,7 +135,6 @@ class FunctionMetadata(object):
return [arg(name, typ, num) for num, (name, typ) in enumerate(args)]
-
def fields(self):
"""Returns a list of output-field ColumnMetadata namedtuples"""
diff --git a/pgcli/pgcompleter.py b/pgcli/pgcompleter.py
index 2ec0ac5a..a4c3724d 100644
--- a/pgcli/pgcompleter.py
+++ b/pgcli/pgcompleter.py
@@ -50,6 +50,7 @@ arg_default_type_strip_regex = re.compile(r'::[\w\.]+(\[\])?$')
normalize_ref = lambda ref: ref if ref[0] == '"' else '"' + ref.lower() + '"'
+
def generate_alias(tbl):
""" 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 +
@@ -636,22 +637,33 @@ class PGCompleter(Completer):
return self.find_matches(word_before_cursor, conds, meta='join')
def get_function_matches(self, suggestion, word_before_cursor, alias=False):
+
if suggestion.usage == 'from':
# Only suggest functions allowed in FROM clause
- def filt(f): return not f.is_aggregate and not f.is_window
+
+ def filt(f):
+ return (not f.is_aggregate and
+ not f.is_window and
+ not f.is_extension and
+ (f.is_public or f.schema_name == suggestion.schema))
else:
alias = False
- def filt(f): return True
+ def filt(f):
+ return (not f.is_extension and
+ (f.is_public or f.schema_name == suggestion.schema))
+
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
+ all_functions = self.populate_functions(suggestion.schema, filt)
funcs = set(
self._make_cand(f, alias, suggestion, arg_mode)
- for f in self.populate_functions(suggestion.schema, filt)
+ for f in all_functions
)
matches = self.find_matches(word_before_cursor, funcs, meta='function')
diff --git a/pgcli/pgexecute.py b/pgcli/pgexecute.py
index 8bcc5c63..2e9a441f 100644
--- a/pgcli/pgexecute.py
+++ b/pgcli/pgexecute.py
@@ -629,10 +629,12 @@ class PGExecute(object):
p.prokind = 'a' is_aggregate,
p.prokind = 'w' is_window,
p.proretset is_set_returning,
+ d.deptype = 'e' is_extension,
pg_get_expr(proargdefaults, 0) AS arg_defaults
FROM pg_catalog.pg_proc p
INNER JOIN pg_catalog.pg_namespace n
ON n.oid = p.pronamespace
+ LEFT JOIN pg_depend d ON d.objid = p.oid and d.deptype = 'e'
WHERE p.prorettype::regtype != 'trigger'::regtype
ORDER BY 1, 2
'''
@@ -647,10 +649,12 @@ class PGExecute(object):
p.proisagg is_aggregate,
p.proiswindow is_window,
p.proretset is_set_returning,
+ d.deptype = 'e' is_extension,
pg_get_expr(proargdefaults, 0) AS arg_defaults
FROM pg_catalog.pg_proc p
INNER JOIN pg_catalog.pg_namespace n
ON n.oid = p.pronamespace
+ LEFT JOIN pg_depend d ON d.objid = p.oid and d.deptype = 'e'
WHERE p.prorettype::regtype != 'trigger'::regtype
ORDER BY 1, 2
'''
@@ -665,10 +669,12 @@ class PGExecute(object):
p.proisagg is_aggregate,
false is_window,
p.proretset is_set_returning,
+ d.deptype = 'e' is_extension,
NULL AS arg_defaults
FROM pg_catalog.pg_proc p
- INNER JOIN pg_catalog.pg_namespace n
- ON n.oid = p.pronamespace
+ INNER JOIN pg_catalog.pg_namespace n
+ ON n.oid = p.pronamespace
+ LEFT JOIN pg_depend d ON d.objid = p.oid and d.deptype = 'e'
WHERE p.prorettype::regtype != 'trigger'::regtype
ORDER BY 1, 2
'''
@@ -683,10 +689,12 @@ class PGExecute(object):
p.proisagg is_aggregate,
false is_window,
p.proretset is_set_returning,
+ d.deptype = 'e' is_extension,
NULL AS arg_defaults
FROM pg_catalog.pg_proc p
- INNER JOIN pg_catalog.pg_namespace n
- ON n.oid = p.pronamespace
+ INNER JOIN pg_catalog.pg_namespace n
+ ON n.oid = p.pronamespace
+ LEFT JOIN pg_depend d ON d.objid = p.oid and d.deptype = 'e'
WHERE p.prorettype::regtype != 'trigger'::regtype
ORDER BY 1, 2
'''
diff --git a/tests/parseutils/test_function_metadata.py b/tests/parseutils/test_function_metadata.py
index 1f9c6930..1d0b72b7 100644
--- a/tests/parseutils/test_function_metadata.py
+++ b/tests/parseutils/test_function_metadata.py
@@ -3,13 +3,16 @@ from pgcli.packages.parseutils.meta import FunctionMetadata
def test_function_metadata_eq():
f1 = FunctionMetadata(
- 's', 'f', ['x'], ['integer'], [], 'int', False, False, False, None
+ 's', 'f', ['x'], ['integer'], [
+ ], 'int', False, False, False, False, None
)
f2 = FunctionMetadata(
- 's', 'f', ['x'], ['integer'], [], 'int', False, False, False, None
+ 's', 'f', ['x'], ['integer'], [
+ ], 'int', False, False, False, False, None
)
f3 = FunctionMetadata(
- 's', 'g', ['x'], ['integer'], [], 'int', False, False, False, None
+ 's', 'g', ['x'], ['integer'], [
+ ], 'int', False, False, False, False, None
)
assert f1 == f2
assert f1 != f3
diff --git a/tests/test_pgexecute.py b/tests/test_pgexecute.py
index 559ac5a3..a2340547 100644
--- a/tests/test_pgexecute.py
+++ b/tests/test_pgexecute.py
@@ -13,11 +13,11 @@ from pgcli.main import PGCli
def function_meta_data(
func_name, schema_name='public', arg_names=None, arg_types=None,
arg_modes=None, return_type=None, is_aggregate=False, is_window=False,
- is_set_returning=False, arg_defaults=None
+ is_set_returning=False, is_extension=False, arg_defaults=None
):
return FunctionMetadata(
schema_name, func_name, arg_names, arg_types, arg_modes, return_type,
- is_aggregate, is_window, is_set_returning, arg_defaults
+ is_aggregate, is_window, is_set_returning, is_extension, arg_defaults
)
@dbtest
diff --git a/tests/test_smart_completion_multiple_schemata.py b/tests/test_smart_completion_multiple_schemata.py
index fd92c373..c332cf74 100644
--- a/tests/test_smart_completion_multiple_schemata.py
+++ b/tests/test_smart_completion_multiple_schemata.py
@@ -30,20 +30,20 @@ metadata = {
},
'functions': {
'public': [
- ['func1', [], [], [], '', False, False, False],
- ['func2', [], [], [], '', False, False, False]],
+ ['func1', [], [], [], '', False, False, False, False],
+ ['func2', [], [], [], '', False, False, False, False]],
'custom': [
- ['func3', [], [], [], '', False, False, False],
+ ['func3', [], [], [], '', False, False, False, False],
['set_returning_func', ['x'], ['integer'], ['o'],
- 'integer', False, False, True]],
+ 'integer', False, False, True, False]],
'Custom': [
- ['func4', [], [], [], '', False, False, False]],
+ ['func4', [], [], [], '', False, False, False, False]],
'blog': [
['extract_entry_symbols', ['_entryid', 'symbol'],
- ['integer', 'text'], ['i', 'o'], '', False, False, True],
+ ['integer', 'text'], ['i', 'o'], '', False, False, True, False],
['enter_entry', ['_title', '_text', 'entryid'],
['text', 'text', 'integer'], ['i', 'i', 'o'],
- '', False, False, False]],
+ '', False, False, False, False]],
},
'datatypes': {
'public': ['typ1', 'typ2'],
@@ -579,7 +579,7 @@ def test_all_schema_objects(completer):
result = result_set(completer, text)
assert result >= set(
[table(x) for x in ('orders', '"select"', 'custom.shipments')]
- + [function(x+'()') for x in ('func2', 'custom.func3')]
+ + [function(x + '()') for x in ('func2',)]
)
@@ -589,7 +589,7 @@ def test_all_schema_objects_with_casing(completer):
result = result_set(completer, text)
assert result >= set(
[table(x) for x in ('Orders', '"select"', 'CUSTOM.shipments')]
- + [function(x+'()') for x in ('func2', 'CUSTOM.func3')]
+ + [function(x + '()') for x in ('func2',)]
)
@@ -599,7 +599,7 @@ def test_all_schema_objects_with_aliases(completer):
result = result_set(completer, text)
assert result >= set(
[table(x) for x in ('orders o', '"select" s', 'custom.shipments s')]
- + [function(x) for x in ('func2() f', 'custom.func3() f')]
+ + [function(x) for x in ('func2() f',)]
)
diff --git a/tests/test_smart_completion_public_schema_only.py b/tests/test_smart_completion_public_schema_only.py
index 3ccac9e5..0b8fbcc4 100644
--- a/tests/test_smart_completion_public_schema_only.py
+++ b/tests/test_smart_completion_public_schema_only.py
@@ -17,12 +17,12 @@ metadata = {
'functions': ['function'],
},
'functions': [
- ['custom_fun', [], [], [], '', False, False, False],
- ['_custom_fun', [], [], [], '', False, False, False],
- ['custom_func1', [], [], [], '', False, False, False],
- ['custom_func2', [], [], [], '', False, False, False],
+ ['custom_fun', [], [], [], '', False, False, False, False],
+ ['_custom_fun', [], [], [], '', False, False, False, False],
+ ['custom_func1', [], [], [], '', False, False, False, False],
+ ['custom_func2', [], [], [], '', False, False, False, False],
['set_returning_func', ['x', 'y'], ['integer', 'integer'],
- ['b', 'b'], '', False, False, True]],
+ ['b', 'b'], '', False, False, True, False]],
'datatypes': ['custom_type1', 'custom_type2'],
'foreignkeys': [
('public', 'users', 'id', 'public', 'users', 'parentid'),