fetch_search_path() and elog.c

Started by Ferruccio Zamunerover 20 years ago4 messages
#1Ferruccio Zamuner
nonsolosoft@diff.org

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/

#2Tom Lane
tgl@sss.pgh.pa.us
In reply to: Ferruccio Zamuner (#1)
Re: fetch_search_path() and elog.c

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

#3Ferruccio Zamuner
nonsolosoft@diff.org
In reply to: Tom Lane (#2)
Re: fetch_search_path() and elog.c

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.

#4Alvaro Herrera
alvherre@alvh.no-ip.org
In reply to: Ferruccio Zamuner (#3)
Re: fetch_search_path() and elog.c

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)