In psql's \d commands, don't truncate attribute default values.
authorTom Lane <[email protected]>
Wed, 25 Nov 2020 21:19:25 +0000 (16:19 -0500)
committerTom Lane <[email protected]>
Wed, 25 Nov 2020 21:19:25 +0000 (16:19 -0500)
Historically, psql has truncated the text of a column's default
expression at 128 characters.  This is unlike any other behavior
in describe.c, and it's become particularly confusing now that
the limit is only applied to the expression proper and not to
the "generated always as (...) stored" text that may get wrapped
around it.

Excavation in our git history suggests that the original motivation
for this limit was not really to limit the display width (as I'd long
supposed), but to make it safe to use a fixed-width output buffer to
store the result.  That implementation restriction is long gone of
course, but the limit remained.  Let's just get rid of it.

While here, rearrange the logic about when to free the output string
so that it's not so dependent on unstated assumptions about the
possible values of attidentity and attgenerated.

Per bug #16743 from David Turon.  Back-patch to v12 where GENERATED
came in.  (Arguably we could take it back further, but I'm hesitant
to change the behavior of long-stable branches for this.)

Discussion: https://postgr.es/m/16743-7b1bacc4af76e7ad@postgresql.org

src/bin/psql/describe.c

index 07d640021c276bcc31bfeabdba64dd9d44bf20ac..14150d05a988db13b72ca3b8e88f71a581949a55 100644 (file)
@@ -1842,7 +1842,7 @@ describeOneTableDetails(const char *schemaname,
    {
        /* use "pretty" mode for expression to avoid excessive parentheses */
        appendPQExpBufferStr(&buf,
-                            ",\n  (SELECT substring(pg_catalog.pg_get_expr(d.adbin, d.adrelid, true) for 128)"
+                            ",\n  (SELECT pg_catalog.pg_get_expr(d.adbin, d.adrelid, true)"
                             "\n   FROM pg_catalog.pg_attrdef d"
                             "\n   WHERE d.adrelid = a.attrelid AND d.adnum = a.attnum AND a.atthasdef)"
                             ",\n  a.attnotnull");
@@ -2045,7 +2045,8 @@ describeOneTableDetails(const char *schemaname,
        {
            char       *identity;
            char       *generated;
-           char       *default_str = "";
+           char       *default_str;
+           bool        mustfree = false;
 
            printTableAddCell(&cont, PQgetvalue(res, i, attcoll_col), false, false);
 
@@ -2061,12 +2062,15 @@ describeOneTableDetails(const char *schemaname,
            else if (identity[0] == ATTRIBUTE_IDENTITY_BY_DEFAULT)
                default_str = "generated by default as identity";
            else if (generated[0] == ATTRIBUTE_GENERATED_STORED)
-               default_str = psprintf("generated always as (%s) stored", PQgetvalue(res, i, attrdef_col));
+           {
+               default_str = psprintf("generated always as (%s) stored",
+                                      PQgetvalue(res, i, attrdef_col));
+               mustfree = true;
+           }
            else
-               /* (note: above we cut off the 'default' string at 128) */
                default_str = PQgetvalue(res, i, attrdef_col);
 
-           printTableAddCell(&cont, default_str, false, generated[0] ? true : false);
+           printTableAddCell(&cont, default_str, false, mustfree);
        }
 
        /* Info for index columns */