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
7 changes: 7 additions & 0 deletions changelog.rst
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@

Unreleased
==========

Bug fixes:
----------
* Include relation type/name titles in `\d` and `\d+` describe output so wildcard describe results retain per-relation context.

2.2.1 (2025-04-27)
==================

Expand Down
18 changes: 17 additions & 1 deletion pgspecial/dbcommands.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,19 @@
],
)

_RELKIND_TO_NAME = {
"r": "Table",
"p": "Partitioned table",
"v": "View",
"m": "Materialized view",
"i": "Index",
"I": "Partitioned index",
"S": "Sequence",
"f": "Foreign table",
"c": "Composite type",
"t": "TOAST table",
}

log = logging.getLogger(__name__)


Expand Down Expand Up @@ -1805,7 +1818,10 @@ def describe_one_table_details(cur, schema_name, relation_name, oid, verbose):
if verbose and tableinfo.reloptions:
status.append(f"Options: {tableinfo.reloptions}\n")

return (None, cells, headers, "".join(status))
relkind_name = _RELKIND_TO_NAME.get(tableinfo.relkind, "Relation")
title = f'{relkind_name} "{schema_name}.{relation_name}"'

return (title, cells, headers, "".join(status))


def sql_name_pattern(pattern):
Expand Down
32 changes: 25 additions & 7 deletions tests/test_specials.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ def test_slash_d_verbose(executor):
@dbtest
def test_slash_d_table_1(executor):
results = executor(r"\d tbl1")
title = None
title = 'Table "public.tbl1"'
rows = [
["id1", "integer", " not null"],
["txt1", "text", " not null"],
Expand All @@ -173,7 +173,7 @@ def test_slash_d_table_1(executor):
@dbtest
def test_slash_d_table_2(executor):
results = executor(r"\d tbl2")
title = None
title = 'Table "public.tbl2"'
rows = [
["id2", "integer", " not null default nextval('tbl2_id2_seq'::regclass)"],
["txt2", "text", ""],
Expand All @@ -184,6 +184,22 @@ def test_slash_d_table_2(executor):
assert results == expected


@dbtest
def test_slash_d_wildcard(executor):
results = executor(r"\d tbl*")
# tbl* matches tbl1, tbl2, tbl2_id2_seq (sequence), tbl3, tbl3_c3_excl (index)
# executor flattens each block as [title, rows, headers, status]
# so titles appear at indices 0, 4, 8, ...
titles = results[0::4]
assert titles == [
'Table "public.tbl1"',
'Table "public.tbl2"',
'Sequence "public.tbl2_id2_seq"',
'Table "public.tbl3"',
'Index "public.tbl3_c3_excl"',
]


@dbtest
def test_slash_d_test_generated_default(executor):
results = executor(r"\d schema3.test_generated_default")
Expand All @@ -200,10 +216,10 @@ def test_slash_d_test_generated_default(executor):

@dbtest
def test_slash_d_table_verbose_1(executor):
title = None
headers = ["Column", "Type", "Modifiers", "Storage", "Stats target", "Description"]

results = executor(r"\d+ tbl1")
title = 'Table "public.tbl1"'
rows = [
["id1", "integer", " not null", "plain", None, None],
["txt1", "text", " not null", "extended", None, None],
Expand All @@ -213,6 +229,7 @@ def test_slash_d_table_verbose_1(executor):
assert results == expected

results = executor(r'\d+ "Inh1"')
title = 'Table "public.Inh1"'
rows = [
["id1", "integer", " not null", "plain", None, None],
["txt1", "text", " not null", "extended", None, None],
Expand All @@ -225,10 +242,10 @@ def test_slash_d_table_verbose_1(executor):

@dbtest
def test_slash_d_table_verbose_2(executor):
title = None
headers = ["Column", "Type", "Modifiers", "Storage", "Stats target", "Description"]

results = executor(r"\d+ tbl2")
title = 'Table "public.tbl2"'
rows = [
[
"id2",
Expand All @@ -245,6 +262,7 @@ def test_slash_d_table_verbose_2(executor):
assert results == expected

results = executor(r"\d+ inh2")
title = 'Table "public.inh2"'
rows = [
["id1", "integer", " not null", "plain", None, None],
["txt1", "text", " not null", "extended", None, None],
Expand All @@ -266,7 +284,7 @@ def test_slash_d_table_verbose_2(executor):

@dbtest
def test_slash_d_view_verbose(executor):
title = None
title = 'View "public.vw1"'
headers = ["Column", "Type", "Modifiers", "Storage", "Description"]

results = executor(r"\d+ vw1")
Expand All @@ -283,7 +301,7 @@ def test_slash_d_view_verbose(executor):
@dbtest
def test_slash_d_table_with_exclusion(executor):
results = executor(r"\d tbl3")
title = None
title = 'Table "public.tbl3"'
rows = [["c3", "circle", ""]]
headers = ["Column", "Type", "Modifiers"]
status = 'Indexes:\n "tbl3_c3_excl" EXCLUDE USING gist (c3 WITH &&)\n'
Expand All @@ -294,7 +312,7 @@ def test_slash_d_table_with_exclusion(executor):
@dbtest
def test_slash_d_table_2_in_schema(executor):
results = executor(r"\d schema2.tbl2")
title = None
title = 'Table "schema2.tbl2"'
rows = [
[
"id2",
Expand Down