Re: Showing parallel status in \df+

Поиск
Список
Период
Сортировка
От Tom Lane
Тема Re: Showing parallel status in \df+
Дата
Msg-id 19480.1468429315@sss.pgh.pa.us
обсуждение исходный текст
Ответ на Re: Showing parallel status in \df+  (Peter Eisentraut <peter.eisentraut@2ndquadrant.com>)
Ответы Re: Showing parallel status in \df+  (Pavel Stehule <pavel.stehule@gmail.com>)
Список pgsql-hackers
Peter Eisentraut <peter.eisentraut@2ndquadrant.com> writes:
> On 7/12/16 7:11 PM, Stephen Frost wrote:
>> I'm curious how it's useful and in what way \sf does not accomplish what
>> you use \df+ for.

> One main use is to see multiple related functions next to each other and
> compare their source code.  But also because one is used to \df and
> wants to see everything there and not in a different format like \sf.

Well, how about my suggestion of moving source code to a footer?
I had just been experimenting to see how painful that would be, and
it doesn't seem awful --- see attached.

            regards, tom lane

diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index 27be102..f5dfd83 100644
*** a/src/bin/psql/describe.c
--- b/src/bin/psql/describe.c
*************** describeFunctions(const char *functypes,
*** 294,308 ****
      bool        showNormal = strchr(functypes, 'n') != NULL;
      bool        showTrigger = strchr(functypes, 't') != NULL;
      bool        showWindow = strchr(functypes, 'w') != NULL;
      bool        have_where;
      PQExpBufferData buf;
      PGresult   *res;
      printQueryOpt myopt = pset.popt;
      static const bool translate_columns[] = {false, false, false, false, true, true, true, false, true, false, false,
false,false}; 

-     /* No "Parallel" column before 9.6 */
-     static const bool translate_columns_pre_96[] = {false, false, false, false, true, true, false, true, false,
false,false, false}; 
-
      if (strlen(functypes) != strspn(functypes, "antwS+"))
      {
          psql_error("\\df only takes [antwS+] as options\n");
--- 294,316 ----
      bool        showNormal = strchr(functypes, 'n') != NULL;
      bool        showTrigger = strchr(functypes, 't') != NULL;
      bool        showWindow = strchr(functypes, 'w') != NULL;
+     bool        have_parallel;
      bool        have_where;
      PQExpBufferData buf;
      PGresult   *res;
+     printTableContent cont;
      printQueryOpt myopt = pset.popt;
+     int            nfields,
+                 r,
+                 c;
+     const int    schema_col = 0;
+     const int    proname_col = 1;
+     const int    proargs_col = 3;
+     const int    parallel_col = 6;
+     const int    lanname_col = 10;
+     const int    prosrc_col = 11;
      static const bool translate_columns[] = {false, false, false, false, true, true, true, false, true, false, false,
false,false}; 

      if (strlen(functypes) != strspn(functypes, "antwS+"))
      {
          psql_error("\\df only takes [antwS+] as options\n");
*************** describeFunctions(const char *functypes,
*** 323,328 ****
--- 331,344 ----
              showWindow = true;
      }

+     /*
+      * proparallel only exists in server versions >= 9.6.  Before that, we
+      * retrieve a null "parallel" column so as to keep column numbering
+      * consistent in the query result, and then skip adding that column to the
+      * printed table.
+      */
+     have_parallel = (pset.sversion >= 90600);
+
      initPQExpBuffer(&buf);

      printfPQExpBuffer(&buf,
*************** describeFunctions(const char *functypes,
*** 424,430 ****
                            gettext_noop("stable"),
                            gettext_noop("volatile"),
                            gettext_noop("Volatility"));
!         if (pset.sversion >= 90600)
              appendPQExpBuffer(&buf,
                                ",\n CASE\n"
                                "  WHEN p.proparallel = 'r' THEN '%s'\n"
--- 440,446 ----
                            gettext_noop("stable"),
                            gettext_noop("volatile"),
                            gettext_noop("Volatility"));
!         if (have_parallel)
              appendPQExpBuffer(&buf,
                                ",\n CASE\n"
                                "  WHEN p.proparallel = 'r' THEN '%s'\n"
*************** describeFunctions(const char *functypes,
*** 435,440 ****
--- 451,459 ----
                                gettext_noop("safe"),
                                gettext_noop("unsafe"),
                                gettext_noop("Parallel"));
+         else
+             appendPQExpBufferStr(&buf,
+                                  ",\n NULL as \"Parallel\"");
          appendPQExpBuffer(&buf,
                         ",\n pg_catalog.pg_get_userbyid(p.proowner) as \"%s\""
                   ",\n CASE WHEN prosecdef THEN '%s' ELSE '%s' END AS \"%s\"",
*************** describeFunctions(const char *functypes,
*** 449,455 ****
                            ",\n p.prosrc as \"%s\""
                  ",\n pg_catalog.obj_description(p.oid, 'pg_proc') as \"%s\"",
                            gettext_noop("Language"),
!                           gettext_noop("Source code"),
                            gettext_noop("Description"));
      }

--- 468,474 ----
                            ",\n p.prosrc as \"%s\""
                  ",\n pg_catalog.obj_description(p.oid, 'pg_proc') as \"%s\"",
                            gettext_noop("Language"),
!                           gettext_noop("Internal name"),
                            gettext_noop("Description"));
      }

*************** describeFunctions(const char *functypes,
*** 543,569 ****
      appendPQExpBufferStr(&buf, "ORDER BY 1, 2, 4;");

      res = PSQLexec(buf.data);
-     termPQExpBuffer(&buf);
      if (!res)
          return false;

!     myopt.nullPrint = NULL;
!     myopt.title = _("List of functions");
!     myopt.translate_header = true;
!     if (pset.sversion >= 90600)
      {
!         myopt.translate_columns = translate_columns;
!         myopt.n_translate_columns = lengthof(translate_columns);
      }
!     else
      {
!         myopt.translate_columns = translate_columns_pre_96;
!         myopt.n_translate_columns = lengthof(translate_columns_pre_96);
      }

!     printQuery(res, &myopt, pset.queryFout, false, pset.logfile);

      PQclear(res);
      return true;
  }

--- 562,634 ----
      appendPQExpBufferStr(&buf, "ORDER BY 1, 2, 4;");

      res = PSQLexec(buf.data);
      if (!res)
+     {
+         termPQExpBuffer(&buf);
          return false;
+     }

!     nfields = PQnfields(res);
!     Assert(lengthof(translate_columns) >= nfields);
!
!     printTableInit(&cont, &myopt.topt, _("List of functions"),
!                    (have_parallel || !verbose) ? nfields : nfields - 1,
!                    PQntuples(res));
!
!     for (c = 0; c < nfields; c++)
      {
!         if (c == parallel_col && !have_parallel)
!             continue;
!         printTableAddHeader(&cont, PQfname(res, c), true,
!                             column_type_alignment(PQftype(res, c)));
      }
!
!     /* set cells */
!     for (r = 0; r < cont.nrows; r++)
      {
!         for (c = 0; c < nfields; c++)
!         {
!             char       *cell;
!
!             if (c == parallel_col && !have_parallel)
!                 continue;
!
!             if (PQgetisnull(res, r, c))
!                 cell = "";
!             else
!                 cell = PQgetvalue(res, r, c);
!
!             if (c == prosrc_col)
!             {
!                 const char *lanname = PQgetvalue(res, r, lanname_col);
!
!                 if (strcmp(lanname, "internal") == 0 ||
!                     strcmp(lanname, "c") == 0)
!                      /* keep prosrc in the "Internal name" column */ ;
!                 else
!                 {
!                     /* put prosrc in a footer, instead */
!                     printfPQExpBuffer(&buf,
!                                       _("Source code of function %s.%s(%s):"),
!                                       PQgetvalue(res, r, schema_col),
!                                       PQgetvalue(res, r, proname_col),
!                                       PQgetvalue(res, r, proargs_col));
!                     printTableAddFooter(&cont, buf.data);
!                     printTableAddFooter(&cont, cell);
!                     cell = "";
!                 }
!             }
!
!             printTableAddCell(&cont, cell, translate_columns[c], false);
!         }
      }

!     printTable(&cont, pset.queryFout, false, pset.logfile);
!     printTableCleanup(&cont);

      PQclear(res);
+     termPQExpBuffer(&buf);
+
      return true;
  }


В списке pgsql-hackers по дате отправления:

Предыдущее
От: Peter Eisentraut
Дата:
Сообщение: Re: Showing parallel status in \df+
Следующее
От: Peter Geoghegan
Дата:
Сообщение: Re: UPSERT/RETURNING -> ON CONFLICT SELECT?