Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions pgcli/packages/parseutils/meta.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,10 +151,13 @@ def fields(self):

if self.return_type.lower() == "void":
return []
elif not self.arg_modes:
# For functions without output parameters, the function name
# is used as the name of the output column.
elif not self.arg_modes or not self.arg_names or not self.arg_types:
# For functions without output parameters, the function name is
# used as the name of the output column.
# E.g. 'SELECT unnest FROM unnest(...);'
# arg_names/arg_types can also be None (e.g. an unnamed variadic
# argument), which args() already guards against; without this the
# zip() below raised 'NoneType is not iterable'.
return [ColumnMetadata(self.func_name, self.return_type, [])]

return [
Expand Down
11 changes: 11 additions & 0 deletions tests/parseutils/test_function_metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,14 @@ def test_function_metadata_eq():
assert not (f1 == f3)
assert hash(f1) == hash(f2)
assert hash(f1) != hash(f3)


def test_function_metadata_fields_with_unnamed_variadic_arg():
# A variadic argument can arrive with no name, so arg_names is None while
# arg_modes is set. fields() used to raise 'NoneType is not iterable' on
# the zip() (issue #1204); it now falls back to the function-name column.
f = FunctionMetadata(
'public', 'labels', None, ['text[]'], ['v'], 'hstore',
False, False, False, False, None,
)
assert [(c.name, c.datatype) for c in f.fields()] == [('labels', 'hstore')]
Loading