1
0
Fork 0

Remove some functions completions (#982)

Remove extension and private functions from completer.
This commit is contained in:
Irina Truong 2019-01-02 16:15:59 -08:00 committed by GitHub
parent 2a1de91292
commit 0cae7e2036
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 60 additions and 34 deletions

View File

@ -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:
---------

View File

@ -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"""

View File

@ -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')

View File

@ -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
'''

View File

@ -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

View File

@ -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

View File

@ -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',)]
)

View File

@ -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'),