diff --git a/AUTHORS b/AUTHORS index 92045428c..c5a2fdec7 100644 --- a/AUTHORS +++ b/AUTHORS @@ -158,6 +158,7 @@ Contributors: * VXNCXNX * jackwalkerlabs (Codex-assisted) + * youdie006 Creator: -------- diff --git a/changelog.rst b/changelog.rst index 81fbefe78..2f9e32872 100644 --- a/changelog.rst +++ b/changelog.rst @@ -6,6 +6,10 @@ Features: * Add a ``\service`` prompt token for connections made using ``service=...`` or ``PGSERVICE``. For example, set ``prompt = '\service> '``. +Bug fixes: +---------- +* Fix ``NoneType`` crash when completing functions with unnamed (variadic) arguments (#1204). + 4.7.1 (2026-09-20) ================== diff --git a/pgcli/packages/parseutils/meta.py b/pgcli/packages/parseutils/meta.py index df41cf4ee..4eded3d79 100644 --- a/pgcli/packages/parseutils/meta.py +++ b/pgcli/packages/parseutils/meta.py @@ -151,7 +151,7 @@ def fields(self): if self.return_type.lower() == "void": return [] - elif not self.arg_modes: + elif not any(mode in ("o", "b", "t") for mode in self.arg_modes or []): # For functions without output parameters, the function name # is used as the name of the output column. # E.g. 'SELECT unnest FROM unnest(...);' @@ -159,6 +159,6 @@ def fields(self): return [ ColumnMetadata(name, typ, []) - for name, typ, mode in zip(self.arg_names, self.arg_types, self.arg_modes) + for name, typ, mode in zip(self.arg_names or [], self.arg_types or [], self.arg_modes) if mode in ("o", "b", "t") ] # OUT, INOUT, TABLE diff --git a/tests/parseutils/test_function_metadata.py b/tests/parseutils/test_function_metadata.py index c4000ab1c..f6ddb6f2f 100644 --- a/tests/parseutils/test_function_metadata.py +++ b/tests/parseutils/test_function_metadata.py @@ -1,4 +1,4 @@ -from pgcli.packages.parseutils.meta import FunctionMetadata +from pgcli.packages.parseutils.meta import ColumnMetadata, FunctionMetadata def test_function_metadata_eq(): @@ -11,3 +11,22 @@ 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_variadic_and_no_arg_names(): + # Issue #1204: labels(variadic text[]) RETURNS hstore has arg_modes but no arg_names. + f = FunctionMetadata( + "public", + "labels", + None, # arg_names: variadic arg has no name + ["text[]"], + ["v"], # VARIADIC + "hstore", + False, + False, + False, + False, + None, + ) + # No OUT/INOUT/TABLE columns, so the function name is the output column. + assert f.fields() == [ColumnMetadata("labels", "hstore", [])]