Thread

  1. fetch_search_path() and elog.c

    Ferruccio Zamuner <nonsolosoft@diff.org> — 2005-07-11T07:53:37Z

    Hi,
    
    I need to have in the log_line_prefix the search_path where the query 
    has run.
    So last week I've started to read elog.c and I was thinking about a 
    small patch there using a new "%S" option.
    
    First I've introduced a small code:
          case 'S':
            {
                List *search_path = fetch_search_path(false);
                if (search_path != NIL) {
                    ListCell   *l;
                    foreach(l, search_path)
                       {
                           char       *nspname;
    
                           nspname = get_namespace_name(lfirst_oid(l));
                           if (nspname)                    /* watch out for 
    deleted namespace */
                               {
                                    appendStringInfo(buf, "%s ", nspname);
                                    pfree(nspname);
                              }
                      }
                    list_free(search_path);
                }
                break;
            }
    
    but in this way postgres was starting with a core dump writing on log.
    
    Then I've add some code, and now it starts but it kills the postgres 
    process as soon as a query has sent to log:
    
    $ diff -u elog.c elog_new.c
    --- elog.c      Sat Mar 12 02:55:15 2005
    +++ elog_new.c  Sun Jul 10 10:16:35 2005
    @@ -67,7 +67,8 @@
     #include "tcop/tcopprot.h"
     #include "utils/memutils.h"
     #include "utils/guc.h"
    -
    +#include "catalog/namespace.h"
    +#include "catalog/pg_type.h"
    
     /* Global variables */
     ErrorContextCallback *error_context_stack = NULL;
    @@ -1444,6 +1445,32 @@
                            case '%':
                                    appendStringInfoChar(buf, '%');
                                    break;
    +                               /* */
    +                       case 'S':
    +                               /* estrae il search_path */
    +                         if (MyProcPort && (MyProcPort->commandTag != 
    NULL)) {
    +                           char *cmd=MyProcPort->commandTag;
    +                           if ((strcasecmp(cmd,"SELECT")== 0) || 
    (strcasecmp(cmd,"INSERT")== 0) || (strcasecmp(cmd,"UPDATE")== 0) || 
    (strcasecmp(cmd,"DELETE")== 0)) {
    +                            
    +                           }
    +                         }
    +                         break;
    +List *search_path = fetch_search_path(false);
    +                             if (search_path != NIL) {
    +                               ListCell   *l;
    +                               foreach(l, search_path)
    +                                 {
    +                                   char       *nspname;
    +
    +                                   nspname = 
    get_namespace_name(lfirst_oid(l));
    +                                   if (nspname)                    /* 
    watch out for deleted namespace */
    +                                     {
    +                                       appendStringInfo(buf, "%s ", 
    nspname);
    +                                       pfree(nspname);
    +                                     }
    +                                 }
    +                               list_free(search_path);
    +                             }
                            default:
                                    /* format error - ignore it */
                                    break;
    
    And here there is the client output:
    
    bash-2.05a$ psql prova -U pgsql
    Welcome to psql 8.0.3, the PostgreSQL interactive terminal.
    
    Type:  \copyright for distribution terms
           \h for help with SQL commands
           \? for help with psql commands
           \g or terminate with semicolon to execute query
           \q to quit
    
    prova=# select * from prova;
    server closed the connection unexpectedly
            This probably means the server terminated abnormally
            before or while processing the request.
    The connection to the server was lost. Attempting reset: Failed.
    !>
    
    Where can I start to understand which checks I've missed and how to gain 
    the output I need?
    
    
    Thank you in advance,                \ferz
    ---
    NonSoLoSoft - http://www.nonsolosoft.com/
    
    
  2. Re: fetch_search_path() and elog.c

    Tom Lane <tgl@sss.pgh.pa.us> — 2005-07-11T13:25:30Z

    Ferruccio Zamuner <nonsolosoft@diff.org> writes:
    > I need to have in the log_line_prefix the search_path where the query 
    > has run.
    > So last week I've started to read elog.c and I was thinking about a 
    > small patch there using a new "%S" option.
    
    There's no chance of that code working when not inside a transaction;
    which means that in most of the scenarios where you really want a log
    entry to be made, it will fail.
    
    			regards, tom lane
    
    
  3. Re: fetch_search_path() and elog.c

    Ferruccio Zamuner <nonsolosoft@diff.org> — 2005-07-11T16:22:26Z

    Tom Lane wrote:
    
    >Ferruccio Zamuner <nonsolosoft@diff.org> writes:
    >  
    >
    >>I need to have in the log_line_prefix the search_path where the query 
    >>has run.
    >>So last week I've started to read elog.c and I was thinking about a 
    >>small patch there using a new "%S" option.
    >>    
    >>
    >
    >There's no chance of that code working when not inside a transaction;
    >which means that in most of the scenarios where you really want a log
    >entry to be made, it will fail.
    >
    >			regards, tom lane
    >  
    >
    Now I've found a simpler solution:
    
    case 'S':
                        /* estrae il search_path */
                  if (namespace_search_path != NULL)
                    appendStringInfo(buf, "%s ", namespace_search_path);
                  break;
    
    It seems to work.
    
    But I would like to understand why previous code was wrong.
    
    
  4. Re: fetch_search_path() and elog.c

    Alvaro Herrera <alvherre@alvh.no-ip.org> — 2005-07-11T17:04:37Z

    On Mon, Jul 11, 2005 at 06:22:26PM +0200, Ferruccio Zamuner wrote:
    
    > Now I've found a simpler solution:
    > 
    > case 'S':
    >                    /* estrae il search_path */
    >              if (namespace_search_path != NULL)
    >                appendStringInfo(buf, "%s ", namespace_search_path);
    >              break;
    > 
    > It seems to work.
    > 
    > But I would like to understand why previous code was wrong.
    
    I think it was because you were doing catalog lookups (the
    get_namespace_name() function, etc), and these don't work outside a
    transaction.
    
    -- 
    Alvaro Herrera (<alvherre[a]alvh.no-ip.org>)
    "¿Cómo puedes confiar en algo que pagas y que no ves,
    y no confiar en algo que te dan y te lo muestran?" (Germán Poo)